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)); } }
/// <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); }