#if UNITY_EDITOR using UnityEngine; using System.Collections.Generic; namespace O3DWB { public struct Ellipse2D { #region Private Variables private Vector2 _center; private Vector2 _radii; #endregion #region Public Properties public Vector2 Center { get { return _center; } set { _center = value; } } public Vector2 Radii { get { return _radii; } set { _radii = value; } } public float RadiusX { get { return _radii.x; } set { _radii.x = value; } } public float RadiusY { get { return _radii.y; } set { _radii.y = value; } } #endregion #region Constructors public Ellipse2D(Vector2 center, Vector2 radii) { _center = center; _radii = radii; } public Ellipse2D(Vector2 center, float radiusX, float radiusY) { _center = center; _radii = new Vector2(radiusX, radiusY); } public Ellipse2D(Rect enclosingRectangle) { _center = enclosingRectangle.center; _radii = new Vector2(enclosingRectangle.width * 0.5f, enclosingRectangle.height * 0.5f); } public Ellipse2D(Circle2D circle) { _center = circle.Center; _radii = new Vector2(circle.Radius, circle.Radius); } #endregion #region Public Methods public bool OverlapsRectangle(Rect rectangle) { if (ContainsAnyPoint(rectangle.GetCenterAndCornerPoints())) return true; if (rectangle.ContainsAnyPoint(GetExtentsPoints())) return true; if (IntersectsAnyRay(rectangle.GetEdgeRays())) return true; return false; } public bool ContainsRectangle(Rect rectangle) { return ContainsAllPoints(rectangle.GetCornerPoints()); } public bool ContainsAllPoints(List points) { Vector2 invRadii = new Vector2(1.0f / Radii.x, 1.0f / Radii.y); Circle2D circle = new Circle2D(Vector2.Scale(Center, invRadii), 1.0f); foreach (Vector2 point in points) { Vector2 adjustedPoint = Vector2.Scale(point, invRadii); if (!circle.ContainsPoint(adjustedPoint)) return false; } return true; } public bool ContainsAnyPoint(List points) { Vector2 invRadii = new Vector2(1.0f / Radii.x, 1.0f / Radii.y); Circle2D circle = new Circle2D(Vector2.Scale(Center, invRadii), 1.0f); foreach (Vector2 point in points) { Vector2 adjustedPoint = Vector2.Scale(point, invRadii); if (circle.ContainsPoint(adjustedPoint)) return true; } return false; } public bool ContainsPoint(Vector2 point) { Vector2 invRadii = new Vector2(1.0f / Radii.x, 1.0f / Radii.y); Circle2D circle = new Circle2D(Vector2.Scale(Center, invRadii), 1.0f); Vector2 adjustedPoint = Vector2.Scale(point, invRadii); return circle.ContainsPoint(adjustedPoint); } public bool IntersectsAnyRay(List rays) { foreach(Ray2D ray in rays) { if (IntersectsRay(ray)) return true; } return false; } public bool IntersectsRay(Ray2D ray, out float t) { Vector2 invRadii = new Vector2(1.0f / Radii.x, 1.0f / Radii.y); Ray2D adjustedRay = new Ray2D(Vector2.Scale(ray.Origin, invRadii), Vector2.Scale(ray.Direction, invRadii)); Circle2D circle = new Circle2D(Vector2.Scale(Center, invRadii), 1.0f); return circle.Raycast(adjustedRay, out t); } public bool IntersectsRay(Ray2D ray) { float t; return IntersectsRay(ray, out t); } public List GetExtentsPoints() { // Return the extent points in the following format: top, right, bottom, left. return new List { _center + new Vector2(0.0f, _radii.y), _center + new Vector2(_radii.x, 0.0f), _center + new Vector2(0.0f, -_radii.y), _center + new Vector2(-_radii.x, 0.0f) }; } public Vector3 GetWorldCenterPointInFrontOfCamera(Camera camera, float distanceFromCamNearPlane) { return _center.GetWorldPointInFrontOfCamera(camera, distanceFromCamNearPlane); } public List GetWorldExtentPointsInFrontOfCamera(Camera camera, float distanceFromCamNearPlane) { List extentPoints = GetExtentsPoints(); return Vector2Extensions.GetWorldPointsInFrontOfCamera(extentPoints, camera, distanceFromCamNearPlane); } public List GetWorldBorderLinesInFrontOfCamera(Camera camera, float distanceFromCamNearPlane, int numberOfEllipseSlices) { List worldExtentPoints = GetWorldExtentPointsInFrontOfCamera(camera, distanceFromCamNearPlane); Vector3 worldCenterPoint = GetWorldCenterPointInFrontOfCamera(camera, distanceFromCamNearPlane); Vector3 ellipseUp = worldExtentPoints[0] - worldCenterPoint; Vector3 ellipseRight = worldExtentPoints[1] - worldCenterPoint; float radiusX = ellipseRight.magnitude; float radiusY = ellipseUp.magnitude; ellipseUp.Normalize(); ellipseRight.Normalize(); return Vector3Extensions.Get3DEllipseCircumferencePoints(radiusX, radiusY, ellipseRight, ellipseUp, worldCenterPoint, numberOfEllipseSlices); } public bool FullyContainsOrientedBoxCenterAndCornerPointsInScreenSpace(OrientedBox orientedBox, Camera camera) { List boxCenterAndCornerScreenPoints = orientedBox.GetScreenCenterAndCornerPoints(camera); return ContainsAllPoints(boxCenterAndCornerScreenPoints); } #endregion } } #endif