Пример #1
0
        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);
        }