public static CapsuleShape ToLocalOfUniformScale(CapsuleShape capsuleShape, Transform transform) { Vector3 localSegment0 = transform.InverseTransformPoint(capsuleShape.top); Vector3 localSegment1 = transform.InverseTransformPoint(capsuleShape.bottom); float difference = capsuleShape.pointsDistance / Vector3.Distance(localSegment0, localSegment1); return(new CapsuleShape((localSegment0 + localSegment1) * .5f, localSegment1 - localSegment0, capsuleShape.height / difference, capsuleShape.radius / difference)); }
public static AABB CreateCapsuleAABB(Vector3 origin, Vector3 direction, float height, float radius, bool normalizeParameter = true) { if (normalizeParameter) { direction.Normalize(); } CapsuleShape capsulePoints = new CapsuleShape(origin, direction, height, radius); return(CreateCapsuleAABB(capsulePoints.top, capsulePoints.bottom, radius)); }
public ContactInfo ClosestPointOnSurface(Vector3 segment0, Vector3 segment1, float radius) { trianglesBufferSingleCaps.Clear(); CapsuleShape capsule = CapsuleShape.ToLocalOfUniformScale(new CapsuleShape(segment0, segment1, radius), transform); Vector3 localSegment0 = capsule.top; Vector3 localSegment1 = capsule.bottom; radius = capsule.radius; AABB aabb = AABB.CreateCapsuleAABB(localSegment0, localSegment1, radius + .001f); tree.FindClosestTriangles(tree.rootNode, aabb, trianglesBufferSingleCaps, infoDebug); Vector3 p1, p2, p3; IntersectPoints near; IntersectPoints nearest = new IntersectPoints(); float radiusSqrd = radius * radius; float shortestDistance = float.MaxValue; int shortestTriangleIndex = -1; HashSet <int> .Enumerator enumerator = trianglesBufferSingleCaps.GetEnumerator(); while (enumerator.MoveNext()) { tree.GetTriangleVertices(enumerator.Current, out p1, out p2, out p3); near = Geometry.ClosestPointOnTriangleToLine(localSegment0, localSegment1, p1, p2, p3, true); float distance = (near.second - near.first).sqrMagnitude; if (PointIsBetter(distance, shortestDistance, nearest.first, nearest.second, near.first, near.second, shortestTriangleIndex, enumerator.Current, radiusSqrd)) { shortestDistance = distance; nearest = near; shortestTriangleIndex = enumerator.Current; } } if (nearest.second == Vector3.zero) { return(new ContactInfo()); } return(new ContactInfo(transform.TransformPoint(nearest.second), transform.TransformDirection(tree.GetTriangleNormal(shortestTriangleIndex)))); }
public List <ContactInfo> ClosestPointsOnSurface(Vector3 segment0, Vector3 segment1, float radius, List <ContactInfo> resultsBuffer) { resultsBuffer.Clear(); trianglesBufferMultiCaps.Clear(); closestPointsBufferMultiCaps.Clear(); CapsuleShape capsule = CapsuleShape.ToLocalOfUniformScale(new CapsuleShape(segment0, segment1, radius), transform); Vector3 localSegment0 = capsule.top; Vector3 localSegment1 = capsule.bottom; radius = capsule.radius; AABB aabb = AABB.CreateCapsuleAABB(localSegment0, localSegment1, radius + .001f); //We add a small radius increase due to float point precision issues that rarely happen. tree.FindClosestTriangles(tree.rootNode, aabb, trianglesBufferMultiCaps, infoDebug); Vector3 p1, p2, p3; IntersectPoints nearest; float radiusSqrd = radius * radius; float distance = 0; HashSet <int> .Enumerator enumerator = trianglesBufferMultiCaps.GetEnumerator(); while (enumerator.MoveNext()) { tree.GetTriangleVertices(enumerator.Current, out p1, out p2, out p3); nearest = Geometry.ClosestPointOnTriangleToLine(localSegment0, localSegment1, p1, p2, p3, true); distance = (nearest.second - nearest.first).sqrMagnitude; if (distance <= radiusSqrd) { closestPointsBufferMultiCaps.Add(new ClosestTrianglePoint(nearest.second, distance, enumerator.Current, nearest.first, this)); } } CleanUp(closestPointsBufferMultiCaps, resultsBuffer); return(resultsBuffer); }
public static CapsuleShape ToLocalOfUniformScale(CapsuleShape capsuleShape, Transform transform) { Vector3 localSegment0 = transform.InverseTransformPoint(capsuleShape.top); Vector3 localSegment1 = transform.InverseTransformPoint(capsuleShape.bottom); float distance = Vector3.Distance(localSegment0, localSegment1); float difference = capsuleShape.pointsDistance / distance; //If distance is zero, then the capsule is probably like a sphere. //Not sure if we should just always do it the way that can handle zero. if (Mathf.Approximately(distance, 0f) || Mathf.Approximately(difference, 0f)) { float minimumScale = ExtVector3.Minimum(ExtVector3.Abs(transform.lossyScale)); float height = capsuleShape.height / minimumScale; float radius = capsuleShape.radius / minimumScale; return(new CapsuleShape((localSegment0 + localSegment1) * .5f, localSegment1 - localSegment0, height, radius)); } else { return(new CapsuleShape((localSegment0 + localSegment1) * .5f, localSegment1 - localSegment0, capsuleShape.height / difference, capsuleShape.radius / difference)); } }
float CapsulePointsDistance() { return(CapsuleShape.PointsDistance(capsuleHeight, capsuleRadius)); }
public static IList <Collider> OverlapCapsule(Vector3 origin, Vector3 direction, float height, float radius, IList <Collider> resultBuffer, int layerMask = Physics.AllLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal) { CapsuleShape points = new CapsuleShape(origin, direction, height, radius); return(OverlapCapsule(points.bottom, points.top, radius, resultBuffer, layerMask, queryTriggerInteraction)); }
public static bool CheckCapsule(Vector3 origin, Vector3 direction, float height, float radius, int layerMask = Physics.AllLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal) { CapsuleShape points = new CapsuleShape(origin, direction, height, radius); return(CheckCapsule(points.bottom, points.top, radius, layerMask, queryTriggerInteraction)); }
public static List <SphereCollisionInfo> DetectCollisions(Vector3 origin, Vector3 directionUp, float height, float radius, int mask, IList <Component> ignoreColliders, List <SphereCollisionInfo> resultBuffer, float checkOffset = 0f, bool multipleContactsPerCollider = true) { CapsuleShape points = new CapsuleShape(origin, directionUp, height, radius, checkOffset); return(DetectCollisions(points.top, points.bottom, radius, mask, ignoreColliders, resultBuffer, checkOffset, multipleContactsPerCollider)); }
//Below taken from free asset on unity asset store - https://www.assetstore.unity3d.com/en/#!/content/11396 public static void DrawCapsule(Vector3 origin, Vector3 direction, float height, float radius, Color color, float duration = .001f, bool depthTest = true) { CapsuleShape points = new CapsuleShape(origin, direction, height, radius); DrawCapsule(points.top, points.bottom, radius, color, duration, depthTest); }