public static Vector3 CalculateSitOnSurfaceOffset(OBB obb, Plane surfacePlane, float offsetFromSurface)
        {
            List <Vector3> obbCorners      = obb.GetCornerPoints();
            int            pivotPointIndex = surfacePlane.GetFurthestPtBehind(obbCorners);

            if (pivotPointIndex < 0)
            {
                pivotPointIndex = surfacePlane.GetClosestPtInFrontOrOnPlane(obbCorners);
            }

            if (pivotPointIndex >= 0)
            {
                Vector3 pivotPt = obbCorners[pivotPointIndex];
                Vector3 prjPt   = surfacePlane.ProjectPoint(pivotPt);
                return((prjPt - pivotPt) + surfacePlane.normal * offsetFromSurface);
            }

            return(Vector3.zero);
        }
        public bool OverlapBox(OBB obb, List <GameObject> gameObjects)
        {
            if (Settings.PhysicsMode == ScenePhysicsMode.UnityColliders)
            {
                gameObjects.Clear();

                // Retrieve the overlapped 3D objects and store them inside the output list
                Collider[] overlapped3DColliders = Physics.OverlapBox(obb.Center, obb.Extents, obb.Rotation);
                foreach (var collider in overlapped3DColliders)
                {
                    gameObjects.Add(collider.gameObject);
                }

                // Retrieve the overlapped 2D objects. This requires some further calculations
                // because colliders of 2D sprites exist in the XY plane, so we must project the
                // OBB onto the XY plane, and use the min and max projected points to build an
                // overlap area.
                Plane          xyPlane          = new Plane(Vector3.forward, 0.0f);
                List <Vector3> projectedCorners = xyPlane.ProjectAllPoints(obb.GetCornerPoints());
                AABB           projectedPtsAABB = new AABB(projectedCorners);

                // The OBB has been projected onto the sprite XY plane. We can now use the AABB's min and max
                // extents to construct the overlap area and use the 'OverlapAreaAll' function to retrieve the
                // overlapped 2D colliders.
                Collider2D[] overlapped2DColliders = Physics2D.OverlapAreaAll(projectedPtsAABB.Min, projectedPtsAABB.Max);
                foreach (var collider in overlapped2DColliders)
                {
                    gameObjects.Add(collider.gameObject);
                }

                return(gameObjects.Count != 0);
            }
            else
            {
                return(_sceneTree.OverlapBox(obb, gameObjects));
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Renders a wire box with lines meeting at corners.
        /// </summary>
        /// <param name="wireCornerLinePercentage">
        /// Can have values in the [0, 1] interval and it controls the length of the
        /// corner lines. A value of 0 draws lines of length 0 and a value of 1
        /// draws lines of length equal to half the box length along a certain axis.
        /// </param>
        public static void DrawWireCornerBox(OBB box, float wireCornerLinePercentage)
        {
            // Store these for easy access
            Mesh           wireCornerLineMesh = MeshPool.Get.UnitCoordSystem;
            List <Vector3> boxCorners         = box.GetCornerPoints();

            // Clamp percentage
            wireCornerLinePercentage = Mathf.Clamp(wireCornerLinePercentage, 0.0f, 1.0f);

            // Front bottom left point
            Vector3   originalScale   = box.Extents * wireCornerLinePercentage;
            Vector3   scale           = originalScale;
            Vector3   position        = boxCorners[(int)BoxCorner.FrontBottomLeft];
            Matrix4x4 transformMatrix = Matrix4x4.TRS(position, box.Rotation, scale);

            Graphics.DrawMeshNow(wireCornerLineMesh, transformMatrix);

            // Front bottom right point
            position        = boxCorners[(int)BoxCorner.FrontBottomRight];
            scale.x        *= -1.0f;
            transformMatrix = Matrix4x4.TRS(position, box.Rotation, scale);
            Graphics.DrawMeshNow(wireCornerLineMesh, transformMatrix);

            // Front top right point
            position        = boxCorners[(int)BoxCorner.FrontTopRight];
            scale.y        *= -1.0f;
            transformMatrix = Matrix4x4.TRS(position, box.Rotation, scale);
            Graphics.DrawMeshNow(wireCornerLineMesh, transformMatrix);

            // Front top left point
            position        = boxCorners[(int)BoxCorner.FrontTopLeft];
            scale           = originalScale;
            scale.y        *= -1.0f;
            transformMatrix = Matrix4x4.TRS(position, box.Rotation, scale);
            Graphics.DrawMeshNow(wireCornerLineMesh, transformMatrix);

            // Back bottom left point
            position        = boxCorners[(int)BoxCorner.BackBottomLeft];
            scale.y         = originalScale.y;
            scale.x        *= -1.0f;
            scale.z        *= -1.0f;
            transformMatrix = Matrix4x4.TRS(position, box.Rotation, scale);
            Graphics.DrawMeshNow(wireCornerLineMesh, transformMatrix);

            // Back bottom right point
            position        = boxCorners[(int)BoxCorner.BackBottomRight];
            scale.x         = originalScale.x;
            transformMatrix = Matrix4x4.TRS(position, box.Rotation, scale);
            Graphics.DrawMeshNow(wireCornerLineMesh, transformMatrix);

            // Back top right point
            position        = boxCorners[(int)BoxCorner.BackTopRight];
            scale.y        *= -1.0f;
            transformMatrix = Matrix4x4.TRS(position, box.Rotation, scale);
            Graphics.DrawMeshNow(wireCornerLineMesh, transformMatrix);

            // Back top left point
            position        = boxCorners[(int)BoxCorner.BackTopLeft];
            scale.x        *= -1.0f;
            transformMatrix = Matrix4x4.TRS(position, box.Rotation, scale);
            Graphics.DrawMeshNow(wireCornerLineMesh, transformMatrix);
        }