123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636 |
- #if UNITY_EDITOR
- using UnityEngine;
- using UnityEditor;
- using System;
- using System.Collections.Generic;
- namespace O3DWB
- {
- public struct Box
- {
- #region Private Variables
- private Vector3 _min;
- private Vector3 _max;
- #endregion
- #region Public Properties
- public Vector3 Min { get { return _min; } set { _min = value; } }
- public Vector3 Max { get { return _max; } set { _max = value; } }
- public Vector3 Extents { get { return Size * 0.5f; } }
- public Vector3 Size
- {
- get { return _max - _min; }
- set
- {
- Vector3 currentCenter = Center;
- Vector3 extents = (value * 0.5f).GetVectorWithPositiveComponents();
- _max = currentCenter + extents;
- _min = currentCenter - extents;
- }
- }
- public Vector3 Center
- {
- get { return (_min + _max) * 0.5f; }
- set
- {
- Vector3 extents = Extents;
- _max = value + extents;
- _min = value - extents;
- }
- }
- #endregion
- #region Constructors
- public Box(Bounds bounds)
- {
- _min = bounds.min;
- _max = bounds.max;
- }
- public Box(Vector3 center, Vector3 size)
- {
- _min = Vector3.zero;
- _max = Vector3.zero;
- Size = size;
- Center = center;
- }
- public Box(Box source)
- {
- _min = source.Min;
- _max = source.Max;
- }
- #endregion
- #region Public Static Functions
- public static Box GetInvalid()
- {
- var box = new Box();
- box.MakeInvalid();
- return box;
- }
- public static Box FromObjectWorldAABB(IEnumerable<GameObject> gameObjects)
- {
- if (gameObjects == null) return Box.GetInvalid();
- Box finalAABB = Box.GetInvalid();
- foreach(var gameObject in gameObjects)
- {
- Box worldAABB = gameObject.GetWorldBox();
- if(worldAABB.IsValid())
- {
- if (finalAABB.IsValid()) finalAABB.Encapsulate(worldAABB);
- else finalAABB = worldAABB;
- }
- }
- return finalAABB;
- }
- public static Box FromPoints(List<Vector3> points, float sizeScale = 1.0f)
- {
- if (points.Count == 0) return GetInvalid();
- Vector3 min = points[0];
- Vector3 max = points[0];
- for(int pointIndex = 1; pointIndex < points.Count; ++pointIndex)
- {
- Vector3 point = points[pointIndex];
- min = Vector3.Min(min, point);
- max = Vector3.Max(max, point);
- }
- Vector3 center = (min + max) * 0.5f;
- Vector3 size = (max - min) * sizeScale;
- return new Box(center, size);
- }
- public static Box FromMinMax(Vector3 min, Vector3 max)
- {
- Vector3 center = (min + max) * 0.5f;
- Vector3 size = (max - min);
- return new Box(center, size);
- }
- #endregion
- #region Public Methods
- public Bounds ToBounds()
- {
- return new Bounds(Center, Size);
- }
- public void MoveInFrontOfPlane(Plane plane)
- {
- List<Vector3> boxPts = GetCornerPoints();
- int ptIndex = plane.GetIndexOfFurthestPointBehind(boxPts);
- if (ptIndex < 0) ptIndex = plane.GetIndexOfClosestPointInFrontOrOnPlane(boxPts);
- if (ptIndex >= 0)
- {
- float distToPt = plane.GetDistanceToPoint(boxPts[ptIndex]);
- Center -= plane.normal * distToPt;
- }
- }
- public OrientedBox ToOrientedBox()
- {
- Box modelSpaceBox = new Box(Vector3.zero, Size);
- OrientedBox orientedBox = new OrientedBox(modelSpaceBox, Quaternion.identity);
- orientedBox.Center = Center;
- return orientedBox;
- }
- public Sphere GetEncpasulatingSphere()
- {
- return new Sphere(Center, Extents.magnitude);
- }
- public void Encapsulate(Bounds bounds)
- {
- Encapsulate(new Box(bounds));
- }
- public void Encapsulate(Box box)
- {
- AddPoint(box.Min);
- AddPoint(box.Max);
- }
- public void AddPoint(Vector3 point)
- {
- if (point.x < _min.x) _min.x = point.x;
- if (point.y < _min.y) _min.y = point.y;
- if (point.z < _min.z) _min.z = point.z;
- if (point.x > _max.x) _max.x = point.x;
- if (point.y > _max.y) _max.y = point.y;
- if (point.z > _max.z) _max.z = point.z;
- }
- public bool IntersectsBox(Box box, bool allowFacesToTouch = false, float intersectionEpsilon = 1e-5f)
- {
- Vector3 center = Center;
- Vector3 radius = Extents;
- Vector3 secondBoxRadius = box.Extents;
- Vector3 secondBoxCenter = box.Center;
- float distanceBetweenCentersOnX = Mathf.Abs(center.x - secondBoxCenter.x);
- float distanceBetweenCentersOnY = Mathf.Abs(center.y - secondBoxCenter.y);
- float distanceBetweenCentersOnZ = Mathf.Abs(center.z - secondBoxCenter.z);
- float radiiSumOnX = radius.x + secondBoxRadius.x;
- float radiiSumOnY = radius.y + secondBoxRadius.y;
- float radiiSumOnZ = radius.z + secondBoxRadius.z;
- // 2 boxes intersect if they intersect on all 3 axes. If the distance between the 2 bounds' centers
- // is greater than the 2 radii along any of the 3 axes, it means the 2 bounds don't intersect.
- if (!allowFacesToTouch)
- {
- // Note: We use the equal sign because we don't want to return true if the boxes are touching
- // faces when 'allowFacesToTouch' is set to false.
- if (distanceBetweenCentersOnX >= radiiSumOnX) return false;
- if (distanceBetweenCentersOnY >= radiiSumOnY) return false;
- if (distanceBetweenCentersOnZ >= radiiSumOnZ) return false;
- }
- else
- {
- // Note: We will add 'intersectionEpsilon' to the distance between centers.
- if (distanceBetweenCentersOnX + intersectionEpsilon > radiiSumOnX) return false;
- if (distanceBetweenCentersOnY + intersectionEpsilon > radiiSumOnY) return false;
- if (distanceBetweenCentersOnZ + intersectionEpsilon > radiiSumOnZ) return false;
- }
- return true;
- }
- public bool TouchesFacesWith(Box box)
- {
- Vector3 firstBoxRadius = Extents;
- Vector3 secondBoxRadius = box.Extents;
- Vector3 firstBoxCenter = Center;
- Vector3 secondBoxCenter = box.Center;
- float distanceBetweenCentersX = Mathf.Abs(firstBoxCenter.x - secondBoxCenter.x);
- float distanceBetweenCentersY = Mathf.Abs(firstBoxCenter.y - secondBoxCenter.y);
- float distanceBetweenCentersZ = Mathf.Abs(firstBoxCenter.z - secondBoxCenter.z);
- float radiiSumX = firstBoxRadius.x + secondBoxRadius.x;
- float radiiSumY = firstBoxRadius.y + secondBoxRadius.y;
- float radiiSumZ = firstBoxRadius.z + secondBoxRadius.z;
- // In order to detect if 2 faces are touching, we will first have to check for each axis if the
- // difference between the center distance and the sum of the radii is close enough to 0. If it
- // is, we only have to make sure that the distance between the bounds' centers on the remaining
- // 2 axes does not exceed the sum of the radii in which case it would mean that the faces touch
- // outside of the permitted area. If the faces are not close enough on a certain axis, we will
- // also check if the distance between the centers along the same axis is greater than the sum
- // of the radii along that axis. If it is, we return false because it means the 2 AABBs are not
- // close enough to be touching in any way.
- const float epsilon = 1e-4f;
- if (Mathf.Abs(distanceBetweenCentersX - radiiSumX) < epsilon)
- {
- // Note: We have to make sure the faces touch in the permitted area. If the distance between the 2 centers
- // on the remaining 2 axis is greater or equal (with epsilon) to the corresponding radii sum, it means
- // the faces touch outside the permitted area.
- if (distanceBetweenCentersY > radiiSumY || Mathf.Abs(distanceBetweenCentersY - radiiSumY) < epsilon) return false;
- if (distanceBetweenCentersZ > radiiSumZ || Mathf.Abs(distanceBetweenCentersZ - radiiSumZ) < epsilon) return false;
- return true;
- }
- else if (distanceBetweenCentersX > radiiSumX) return false;
- if (Mathf.Abs(distanceBetweenCentersY - radiiSumY) < epsilon)
- {
- if (distanceBetweenCentersX > radiiSumX || Mathf.Abs(distanceBetweenCentersX - radiiSumX) < epsilon) return false;
- if (distanceBetweenCentersZ > radiiSumZ || Mathf.Abs(distanceBetweenCentersZ - radiiSumZ) < epsilon) return false;
- return true;
- }
- else if (distanceBetweenCentersY > radiiSumY) return false;
- if (Mathf.Abs(distanceBetweenCentersZ - radiiSumZ) < epsilon)
- {
- if (distanceBetweenCentersX > radiiSumX || Mathf.Abs(distanceBetweenCentersX - radiiSumX) < epsilon) return false;
- if (distanceBetweenCentersY > radiiSumY || Mathf.Abs(distanceBetweenCentersY - radiiSumY) < epsilon) return false;
- return true;
- }
- else if (distanceBetweenCentersZ > radiiSumZ) return false;
- return false;
- }
- public bool ContainsPoint(Vector3 point)
- {
- return point.x >= _min.x && point.x <= _max.x &&
- point.y >= _min.y && point.y <= _max.y &&
- point.z >= _min.z && point.z <= _max.z;
- }
- public List<Vector3> GetCenterAndCornerPoints()
- {
- Vector3[] points = new Vector3[BoxPoints.Count];
- points[(int)BoxPoint.Center] = GetBoxPoint(BoxPoint.Center);
- points[(int)BoxPoint.FrontTopLeft] = GetBoxPoint(BoxPoint.FrontTopLeft);
- points[(int)BoxPoint.FrontTopRight] = GetBoxPoint(BoxPoint.FrontTopRight);
- points[(int)BoxPoint.FrontBottomRight] = GetBoxPoint(BoxPoint.FrontBottomRight);
- points[(int)BoxPoint.FrontBottomLeft] = GetBoxPoint(BoxPoint.FrontBottomLeft);
- points[(int)BoxPoint.BackTopLeft] = GetBoxPoint(BoxPoint.BackTopLeft);
- points[(int)BoxPoint.BackTopRight] = GetBoxPoint(BoxPoint.BackTopRight);
- points[(int)BoxPoint.BackBottomRight] = GetBoxPoint(BoxPoint.BackBottomRight);
- points[(int)BoxPoint.BackBottomLeft] = GetBoxPoint(BoxPoint.BackBottomLeft);
- return new List<Vector3>(points);
- }
- public List<Vector3> GetCornerPoints()
- {
- Vector3[] points = new Vector3[BoxCornerPoints.Count];
- points[(int)BoxCornerPoint.FrontTopLeft] = GetBoxPoint(BoxPoint.FrontTopLeft);
- points[(int)BoxCornerPoint.FrontTopRight] = GetBoxPoint(BoxPoint.FrontTopRight);
- points[(int)BoxCornerPoint.FrontBottomRight] = GetBoxPoint(BoxPoint.FrontBottomRight);
- points[(int)BoxCornerPoint.FrontBottomLeft] = GetBoxPoint(BoxPoint.FrontBottomLeft);
- points[(int)BoxCornerPoint.BackTopLeft] = GetBoxPoint(BoxPoint.BackTopLeft);
- points[(int)BoxCornerPoint.BackTopRight] = GetBoxPoint(BoxPoint.BackTopRight);
- points[(int)BoxCornerPoint.BackBottomRight] = GetBoxPoint(BoxPoint.BackBottomRight);
- points[(int)BoxCornerPoint.BackBottomLeft] = GetBoxPoint(BoxPoint.BackBottomLeft);
- return new List<Vector3>(points);
- }
- public Vector3 GetBoxPoint(BoxPoint boxPoint)
- {
- Vector3 center = Center;
- Vector3 extents = Extents;
- switch (boxPoint)
- {
- case BoxPoint.Center:
- return center;
- case BoxPoint.FrontTopLeft:
- return center - BoxFaces.GetFaceRightAxis(BoxFace.Front) * extents.x +
- BoxFaces.GetFaceLookAxis(BoxFace.Front) * extents.y +
- BoxFaces.GetFaceNormal(BoxFace.Front) * extents.z;
- case BoxPoint.FrontTopRight:
- return center + BoxFaces.GetFaceRightAxis(BoxFace.Front) * extents.x +
- BoxFaces.GetFaceLookAxis(BoxFace.Front) * extents.y +
- BoxFaces.GetFaceNormal(BoxFace.Front) * extents.z;
- case BoxPoint.FrontBottomRight:
- return center + BoxFaces.GetFaceRightAxis(BoxFace.Front) * extents.x -
- BoxFaces.GetFaceLookAxis(BoxFace.Front) * extents.y +
- BoxFaces.GetFaceNormal(BoxFace.Front) * extents.z;
- case BoxPoint.FrontBottomLeft:
- return center - BoxFaces.GetFaceRightAxis(BoxFace.Front) * extents.x -
- BoxFaces.GetFaceLookAxis(BoxFace.Front) * extents.y +
- BoxFaces.GetFaceNormal(BoxFace.Front) * extents.z;
- case BoxPoint.BackTopLeft:
- return center - BoxFaces.GetFaceRightAxis(BoxFace.Back) * extents.x +
- BoxFaces.GetFaceLookAxis(BoxFace.Back) * extents.y +
- BoxFaces.GetFaceNormal(BoxFace.Back) * extents.z;
- case BoxPoint.BackTopRight:
- return center + BoxFaces.GetFaceRightAxis(BoxFace.Back) * extents.x +
- BoxFaces.GetFaceLookAxis(BoxFace.Back) * extents.y +
- BoxFaces.GetFaceNormal(BoxFace.Back) * extents.z;
- case BoxPoint.BackBottomRight:
- return center + BoxFaces.GetFaceRightAxis(BoxFace.Back) * extents.x -
- BoxFaces.GetFaceLookAxis(BoxFace.Back) * extents.y +
- BoxFaces.GetFaceNormal(BoxFace.Back) * extents.z;
- case BoxPoint.BackBottomLeft:
- return center - BoxFaces.GetFaceRightAxis(BoxFace.Back) * extents.x -
- BoxFaces.GetFaceLookAxis(BoxFace.Back) * extents.y +
- BoxFaces.GetFaceNormal(BoxFace.Back) * extents.z;
- default:
- return Vector3.zero;
- }
- }
- public BoxFace GetBoxFaceClosestToPoint(Vector3 point)
- {
- List<Plane> facePlanes = GetBoxFacePlanes();
- float minAbsDistanceFromPlane = float.MaxValue;
- BoxFace closestFace = BoxFace.Back;
- for(int faceIndex = 0; faceIndex < facePlanes.Count; ++faceIndex)
- {
- float absDistanceFromPlane = Mathf.Abs(facePlanes[faceIndex].GetDistanceToPoint(point));
- if(absDistanceFromPlane < minAbsDistanceFromPlane)
- {
- minAbsDistanceFromPlane = absDistanceFromPlane;
- closestFace = (BoxFace)faceIndex;
- }
- }
- return closestFace;
- }
- public List<Plane> GetBoxFacePlanes()
- {
- Plane[] facePlanes = new Plane[Enum.GetValues(typeof(BoxFace)).Length];
- facePlanes[(int)BoxFace.Back] = GetBoxFacePlane(BoxFace.Back);
- facePlanes[(int)BoxFace.Front] = GetBoxFacePlane(BoxFace.Front);
- facePlanes[(int)BoxFace.Left] = GetBoxFacePlane(BoxFace.Left);
- facePlanes[(int)BoxFace.Right] = GetBoxFacePlane(BoxFace.Right);
- facePlanes[(int)BoxFace.Top] = GetBoxFacePlane(BoxFace.Top);
- facePlanes[(int)BoxFace.Bottom] = GetBoxFacePlane(BoxFace.Bottom);
- return new List<Plane>(facePlanes);
- }
- public CoordinateSystem GetBoxFaceCoordinateSystem(BoxFace boxFace)
- {
- var coordSystem = new CoordinateSystem();
- Vector3 origin = GetBoxFaceCenter(boxFace);
- Vector3 boxFaceUp = BoxFaces.GetFaceNormal(boxFace);
- Vector3 boxFaceLook = BoxFaces.GetFaceLookAxis(boxFace);
- coordSystem.SetOriginPosition(origin);
- coordSystem.SetRotation(Quaternion.LookRotation(boxFaceLook, boxFaceUp));
-
- return coordSystem;
- }
- public List<Vector3> GetBoxFaceCenterAndCornerPoints(BoxFace boxFace)
- {
- var points = new Vector3[BoxFacePoints.Count];
- Vector3 boxFaceCenter = GetBoxFaceCenter(boxFace);
- Vector2 boxFaceXZSize = GetBoxFaceSizeAlongFaceLocalXZAxes(boxFace, Vector3.one);
- Vector2 halfXZSize = boxFaceXZSize * 0.5f;
- points[(int)BoxFacePoint.Center] = boxFaceCenter;
- points[(int)BoxFacePoint.TopLeft] = boxFaceCenter - BoxFaces.GetFaceRightAxis(boxFace) * halfXZSize.x + BoxFaces.GetFaceLookAxis(boxFace) * halfXZSize.y;
- points[(int)BoxFacePoint.TopRight] = boxFaceCenter + BoxFaces.GetFaceRightAxis(boxFace) * halfXZSize.x + BoxFaces.GetFaceLookAxis(boxFace) * halfXZSize.y;
- points[(int)BoxFacePoint.BottomRight] = boxFaceCenter + BoxFaces.GetFaceRightAxis(boxFace) * halfXZSize.x - BoxFaces.GetFaceLookAxis(boxFace) * halfXZSize.y;
- points[(int)BoxFacePoint.BottomLeft] = boxFaceCenter - BoxFaces.GetFaceRightAxis(boxFace) * halfXZSize.x - BoxFaces.GetFaceLookAxis(boxFace) * halfXZSize.y;
- return new List<Vector3>(points);
- }
- public List<Vector3> GetBoxFaceCornerPoints(BoxFace boxFace)
- {
- var points = new Vector3[BoxFaceCornerPoints.Count];
-
- Vector3 boxFaceCenter = GetBoxFaceCenter(boxFace);
- Vector2 boxFaceXZSize = GetBoxFaceSizeAlongFaceLocalXZAxes(boxFace, Vector3.one);
- Vector2 halfXZSize = boxFaceXZSize * 0.5f;
- points[(int)BoxFaceCornerPoint.TopLeft] = boxFaceCenter - BoxFaces.GetFaceRightAxis(boxFace) * halfXZSize.x + BoxFaces.GetFaceLookAxis(boxFace) * halfXZSize.y;
- points[(int)BoxFaceCornerPoint.TopRight] = boxFaceCenter + BoxFaces.GetFaceRightAxis(boxFace) * halfXZSize.x + BoxFaces.GetFaceLookAxis(boxFace) * halfXZSize.y;
- points[(int)BoxFaceCornerPoint.BottomRight] = boxFaceCenter + BoxFaces.GetFaceRightAxis(boxFace) * halfXZSize.x - BoxFaces.GetFaceLookAxis(boxFace) * halfXZSize.y;
- points[(int)BoxFaceCornerPoint.BottomLeft] = boxFaceCenter - BoxFaces.GetFaceRightAxis(boxFace) * halfXZSize.x - BoxFaces.GetFaceLookAxis(boxFace) * halfXZSize.y;
- return new List<Vector3>(points);
- }
- public Plane GetBoxFacePlane(BoxFace boxFace)
- {
- switch(boxFace)
- {
- case BoxFace.Back:
- return new Plane(BoxFaces.GetFaceNormal(BoxFace.Back), GetBoxPoint(BoxPoint.BackBottomLeft));
- case BoxFace.Front:
- return new Plane(BoxFaces.GetFaceNormal(BoxFace.Front), GetBoxPoint(BoxPoint.FrontBottomLeft));
- case BoxFace.Left:
- return new Plane(BoxFaces.GetFaceNormal(BoxFace.Left), GetBoxPoint(BoxPoint.FrontBottomLeft));
- case BoxFace.Right:
- return new Plane(BoxFaces.GetFaceNormal(BoxFace.Right), GetBoxPoint(BoxPoint.FrontBottomRight));
- case BoxFace.Top:
- return new Plane(BoxFaces.GetFaceNormal(BoxFace.Top), GetBoxPoint(BoxPoint.FrontTopLeft));
- case BoxFace.Bottom:
- return new Plane(BoxFaces.GetFaceNormal(BoxFace.Bottom), GetBoxPoint(BoxPoint.FrontBottomLeft));
- default:
- return new Plane();
- }
- }
- public Vector2 GetBoxFaceSizeAlongFaceLocalXZAxes(BoxFace boxFace, Vector3 boxXYZScale)
- {
- Vector3 size = Size;
- switch(boxFace)
- {
- case BoxFace.Front:
- case BoxFace.Back:
- return new Vector2(size.x * boxXYZScale.x, size.y * boxXYZScale.y);
- case BoxFace.Left:
- case BoxFace.Right:
- return new Vector2(size.z * boxXYZScale.z, size.y * boxXYZScale.y);
- case BoxFace.Top:
- case BoxFace.Bottom:
- return new Vector2(size.x * boxXYZScale.x, size.z * boxXYZScale.z);
- default:
- return Vector2.zero;
- }
- }
- public Vector3 GetBoxFaceCenter(BoxFace boxFace)
- {
- Vector3 center = Center;
- Vector3 extents = Extents;
- switch(boxFace)
- {
- case BoxFace.Back:
- return center + BoxFaces.GetFaceNormal(BoxFace.Back) * extents.z;
- case BoxFace.Front:
- return center + BoxFaces.GetFaceNormal(BoxFace.Front) * extents.z;
- case BoxFace.Left:
- return center + BoxFaces.GetFaceNormal(BoxFace.Left) * extents.x;
- case BoxFace.Right:
- return center + BoxFaces.GetFaceNormal(BoxFace.Right) * extents.x;
- case BoxFace.Top:
- return center + BoxFaces.GetFaceNormal(BoxFace.Top) * extents.y;
- case BoxFace.Bottom:
- return center + BoxFaces.GetFaceNormal(BoxFace.Bottom) * extents.y;
- default:
- return Vector3.zero;
- }
- }
- public List<Vector2> GetScreenCornerPoints(Camera camera)
- {
- Vector3 boxCenter = Center;
- Vector3 boxExtents = Extents;
- return new List<Vector2>
- {
- Vector3Extensions.WorldToScreenPoint(new Vector3(boxCenter.x - boxExtents.x, boxCenter.y - boxExtents.y, boxCenter.z - boxExtents.z)),
- Vector3Extensions.WorldToScreenPoint(new Vector3(boxCenter.x + boxExtents.x, boxCenter.y - boxExtents.y, boxCenter.z - boxExtents.z)),
- Vector3Extensions.WorldToScreenPoint(new Vector3(boxCenter.x + boxExtents.x, boxCenter.y + boxExtents.y, boxCenter.z - boxExtents.z)),
- Vector3Extensions.WorldToScreenPoint(new Vector3(boxCenter.x - boxExtents.x, boxCenter.y + boxExtents.y, boxCenter.z - boxExtents.z)),
- Vector3Extensions.WorldToScreenPoint(new Vector3(boxCenter.x - boxExtents.x, boxCenter.y - boxExtents.y, boxCenter.z + boxExtents.z)),
- Vector3Extensions.WorldToScreenPoint(new Vector3(boxCenter.x + boxExtents.x, boxCenter.y - boxExtents.y, boxCenter.z + boxExtents.z)),
- Vector3Extensions.WorldToScreenPoint(new Vector3(boxCenter.x + boxExtents.x, boxCenter.y + boxExtents.y, boxCenter.z + boxExtents.z)),
- Vector3Extensions.WorldToScreenPoint(new Vector3(boxCenter.x - boxExtents.x, boxCenter.y + boxExtents.y, boxCenter.z + boxExtents.z)),
- };
- }
- public Rect GetScreenRectangle(Camera camera)
- {
- List<Vector2> screenPoints = GetScreenCornerPoints(camera);
- Vector2 minScreenPoint = screenPoints[0];
- Vector2 maxScreenPoint = screenPoints[0];
- foreach (Vector2 point in screenPoints)
- {
- minScreenPoint = Vector2.Min(minScreenPoint, point);
- maxScreenPoint = Vector2.Max(maxScreenPoint, point);
- }
- return new Rect(minScreenPoint.x, minScreenPoint.y, maxScreenPoint.x - minScreenPoint.x, maxScreenPoint.y - minScreenPoint.y);
- }
- public bool Raycast(Ray ray, out float t)
- {
- Bounds bounds = ToBounds();
- return bounds.IntersectRay(ray, out t);
- }
- public Box Transform(TransformMatrix transformMatrix)
- {
- Vector3 rightAxis = transformMatrix.GetNormalizedRightAxisNoScaleSign();
- Vector3 upAxis = transformMatrix.GetNormalizedUpAxisNoScaleSign();
- Vector3 lookAxis = transformMatrix.GetNormalizedLookAxisNoScaleSign();
- Vector3 scale = transformMatrix.Scale;
- Vector3 newCenter = transformMatrix.MultiplyPoint(Center);
- Vector3 boxExtents = Extents;
- Vector3 newExtentsRight = rightAxis * boxExtents.x * scale.x;
- Vector3 newExtentsUp = upAxis * boxExtents.y * scale.y;
- Vector3 newExtentsLook = lookAxis * boxExtents.z * scale.z;
- float newExtentsX = Mathf.Abs(newExtentsRight.x) + Mathf.Abs(newExtentsUp.x) + Mathf.Abs(newExtentsLook.x);
- float newExtentsY = Mathf.Abs(newExtentsRight.y) + Mathf.Abs(newExtentsUp.y) + Mathf.Abs(newExtentsLook.y);
- float newExtentsZ = Mathf.Abs(newExtentsRight.z) + Mathf.Abs(newExtentsUp.z) + Mathf.Abs(newExtentsLook.z);
- Vector3 newSize = new Vector3(newExtentsX, newExtentsY, newExtentsZ) * 2.0f;
- return new Box(newCenter, newSize);
- }
- public void MakeInvalid()
- {
- _min = Vector3.one;
- _max = -Vector3.one;
- }
- public bool IsValid()
- {
- return _min.x <= _max.x && _min.y <= _max.y && _min.z <= _max.z;
- }
- public bool IsInvalid()
- {
- return !IsValid();
- }
- #endregion
- }
- }
- #endif
|