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