private static bool ComputeCylinderIntersection ( Vector3 localFixedPoint, Vector3 localMovingPoint, float combinedRadius, ref Vector3 intersectionPoint ) { float t1; float t2; var projectedFixedPoint = new Vector2(localFixedPoint.x, localFixedPoint.z); var projectedMovingPoint = new Vector2(localMovingPoint.x, localMovingPoint.z); if (!SpringSphereCollider.FindLineSegmentIntersection( new Vector2(0f, 0f), combinedRadius, projectedFixedPoint, projectedMovingPoint, out t1, out t2) || t1 >= 1f || t2 <= 0f) { return(false); } intersectionPoint = localFixedPoint + t1 * (localMovingPoint - localFixedPoint); return(true); }
private bool IntersectsLineSegment ( Vector3 pointA, Vector3 pointB, float segmentRadius ) { if (SpringSphereCollider.IntersectsLineSegment( transform, new Vector3(0f, 0f, 0f), radius, pointA, pointB, segmentRadius)) { return(true); } if (SpringSphereCollider.IntersectsLineSegment( transform, new Vector3(0f, height, 0f), radius, pointA, pointB, segmentRadius)) { return(true); } var localPointA = transform.InverseTransformPoint(pointA); var localPointB = transform.InverseTransformPoint(pointB); var otherRadius = transform.InverseTransformDirection(segmentRadius, 0f, 0f).magnitude; var combinedRadius = radius + otherRadius; var intersectionPoint = new Vector3(0f, 0f, 0f); return(ComputeCylinderIntersection(localPointA, localPointB, combinedRadius, ref intersectionPoint) && intersectionPoint.y > 0f && intersectionPoint.y < height); }
private static SphereColliderSerializer SphereColliderToSerializer(SpringSphereCollider sourceCollider) { return(new SphereColliderSerializer { baseInfo = TransformToColliderSerializerBaseInfo(sourceCollider.transform, SphereColliderToken), radius = sourceCollider.radius, linkedRenderer = GetComponentName(sourceCollider.linkedRenderer) }); }
public SpringBone.CollisionStatus CheckForCollisionAndReact ( Vector3 moverHeadPosition, ref Vector3 moverPosition, float moverRadius ) { if ((linkedRenderer != null && !linkedRenderer.enabled) || radius <= 0.0001f) { return(SpringBone.CollisionStatus.NoCollision); } if (needToCacheTransform) { CacheTransform(); } // Lower than start cap var localHeadPosition = worldToLocal.MultiplyPoint3x4(moverHeadPosition); var localMoverPosition = worldToLocal.MultiplyPoint3x4(moverPosition); var localMoverRadius = moverRadius * radiusScale; var moverIsAboveTop = localMoverPosition.y >= height; var useSphereCheck = (localMoverPosition.y <= 0f) | moverIsAboveTop; if (useSphereCheck) { var sphereOrigin = new Vector3(0f, 0f, 0f); sphereOrigin.y = moverIsAboveTop ? height : 0f; var combinedRadius = localMoverRadius + radius; if ((localMoverPosition - sphereOrigin).sqrMagnitude >= combinedRadius * combinedRadius) { // Not colliding return(SpringBone.CollisionStatus.NoCollision); } var originToHead = localHeadPosition - sphereOrigin; var isHeadEmbedded = originToHead.sqrMagnitude <= radius * radius; #if UNITY_EDITOR RecordSphereCollision( sphereOrigin, localMoverPosition, moverRadius, isHeadEmbedded ? SpringBone.CollisionStatus.HeadIsEmbedded : SpringBone.CollisionStatus.TailCollision); #endif if (isHeadEmbedded) { // The head is inside the sphere, so just try to push the tail out localMoverPosition = sphereOrigin + (localMoverPosition - sphereOrigin).normalized * combinedRadius; moverPosition = transform.TransformPoint(localMoverPosition); return(SpringBone.CollisionStatus.HeadIsEmbedded); } var localHeadRadius = (localMoverPosition - localHeadPosition).magnitude; var intersection = new Circle3(); if (SpringSphereCollider.ComputeIntersection( localHeadPosition, localHeadRadius, sphereOrigin, combinedRadius, ref intersection)) { localMoverPosition = SpringSphereCollider.ComputeNewTailPosition(intersection, localMoverPosition); moverPosition = transform.TransformPoint(localMoverPosition); } return(SpringBone.CollisionStatus.TailCollision); } // Cylinder var collisionStatus = CheckForCylinderCollisionAndReact( localHeadPosition, ref moverPosition, localMoverRadius, localMoverPosition); return(collisionStatus); }