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, ref Vector3 hitNormal ) { const float RadiusThreshold = 0.0001f; if ((linkedRenderer != null && !linkedRenderer.enabled) || radius <= RadiusThreshold) { return(SpringBone.CollisionStatus.NoCollision); } var worldToLocal = transform.worldToLocalMatrix; var radiusScale = worldToLocal.MultiplyVector(new Vector3(1f, 0f, 0f)).magnitude; // 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, moverIsAboveTop ? height : 0f, 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 var localHitNormal = (localMoverPosition - sphereOrigin).normalized; localMoverPosition = sphereOrigin + localHitNormal * combinedRadius; moverPosition = transform.TransformPoint(localMoverPosition); hitNormal = transform.TransformDirection(localHitNormal).normalized; 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); var localHitNormal = (localMoverPosition - sphereOrigin).normalized; hitNormal = transform.TransformDirection(localHitNormal).normalized; } return(SpringBone.CollisionStatus.TailCollision); } // Cylinder var collisionStatus = CheckForCylinderCollisionAndReact( localHeadPosition, ref moverPosition, localMoverRadius, localMoverPosition, ref hitNormal); return(collisionStatus); }