Пример #1
0
 public override void Collide(ref Vector3 position, float spacing)
 {
     if (referenceCollider is SphereCollider)
     {
         SphereCollider collider = referenceCollider as SphereCollider;
         if (insideMode)
         {
             EZSoftBoneUtility.PointInsideSphere(ref position, collider, spacing + margin);
         }
         else
         {
             EZSoftBoneUtility.PointOutsideSphere(ref position, collider, spacing + margin);
         }
     }
     else if (referenceCollider is CapsuleCollider)
     {
         CapsuleCollider collider = referenceCollider as CapsuleCollider;
         if (insideMode)
         {
             EZSoftBoneUtility.PointInsideCapsule(ref position, collider, spacing + margin);
         }
         else
         {
             EZSoftBoneUtility.PointOutsideCapsule(ref position, collider, spacing + margin);
         }
     }
     else if (referenceCollider is BoxCollider)
     {
         BoxCollider collider = referenceCollider as BoxCollider;
         if (insideMode)
         {
             EZSoftBoneUtility.PointInsideBox(ref position, collider, spacing + margin);
         }
         else
         {
             EZSoftBoneUtility.PointOutsideBox(ref position, collider, spacing + margin);
         }
     }
     else if (referenceCollider is MeshCollider)
     {
         if (!CheckConvex(referenceCollider as MeshCollider))
         {
             Debug.LogError("Non-Convex Mesh Collider is not supported", this);
             enabled = false;
             return;
         }
         if (insideMode)
         {
             Debug.LogError("Inside Mode On Mesh Collider is not supported", this);
             insideMode = false;
             return;
         }
         EZSoftBoneUtility.PointOutsideCollider(ref position, referenceCollider, spacing + margin);
     }
 }
Пример #2
0
        private void UpdateNode(Bone bone)
        {
            if (bone.depth > startDepth)
            {
                Vector3 oldWorldPosition, newWorldPosition;
                oldWorldPosition = newWorldPosition = bone.worldPosition;

                // Damping (inertia attenuation)
                if (bone.speed.sqrMagnitude < sleepThreshold)
                {
                    bone.speed = Vector3.zero;
                }
                else
                {
                    newWorldPosition += bone.speed * Time.deltaTime * (1 - bone.damping);
                }

                // Resistance (force resistance)
                Vector3 force = gravity;
                if (gravityAligner != null)
                {
                    Vector3 alignedDir  = gravityAligner.TransformDirection(gravity).normalized;
                    Vector3 globalDir   = gravity.normalized;
                    float   attenuation = Mathf.Acos(Vector3.Dot(alignedDir, globalDir)) / Mathf.PI;
                    force *= attenuation;
                }
                if (forceModule != null)
                {
                    force += forceModule.GetForce(bone.normalizedLength, forceSpace);
                }
                force.x          *= transform.localScale.x;
                force.y          *= transform.localScale.y;
                force.z          *= transform.localScale.z;
                newWorldPosition += force * (1 - bone.resistance) / iterations;

                // Stiffness (shape keeper)
                Vector3 parentOffset = bone.parentBone.worldPosition - bone.parentBone.transform.position;
                Vector3 expectedPos  = bone.parentBone.transform.TransformPoint(bone.originalLocalPosition) + parentOffset;
                newWorldPosition = Vector3.Lerp(newWorldPosition, expectedPos, bone.stiffness / iterations);

                // Slackness (length keeper)
                Vector3 nodeDir    = (newWorldPosition - bone.parentBone.worldPosition).normalized;
                float   nodeLength = bone.parentBone.transform.TransformVector(bone.originalLocalPosition).magnitude;
                nodeDir = bone.parentBone.worldPosition + nodeDir * nodeLength;
                // Siblings
                if (siblingConstraints != UnificationMode.None)
                {
                    int constraints = 1;
                    if (bone.leftBone != null)
                    {
                        Vector3 leftDir    = (newWorldPosition - bone.leftBone.worldPosition).normalized;
                        float   leftLength = bone.transform.TransformVector(bone.positionToLeft).magnitude;
                        leftDir  = bone.leftBone.worldPosition + leftDir * leftLength;
                        nodeDir += leftDir;
                        constraints++;
                    }
                    if (bone.rightBone != null)
                    {
                        Vector3 rightDir    = (newWorldPosition - bone.rightBone.worldPosition).normalized;
                        float   rightLength = bone.transform.TransformVector(bone.positionToRight).magnitude;
                        rightDir = bone.rightBone.worldPosition + rightDir * rightLength;
                        nodeDir += rightDir;
                        constraints++;
                    }
                    nodeDir /= constraints;
                }
                newWorldPosition = Vector3.Lerp(nodeDir, newWorldPosition, bone.slackness / iterations * Time.deltaTime);

                // Collision
                if (bone.radius > 0)
                {
                    foreach (EZSoftBoneColliderBase collider in EZSoftBoneColliderBase.EnabledColliders)
                    {
                        if (bone.transform != collider.transform && collisionLayers.Contains(collider.gameObject.layer))
                        {
                            collider.Collide(ref newWorldPosition, bone.radius);
                        }
                    }
                    foreach (Collider collider in extraColliders)
                    {
                        if (bone.transform != collider.transform && collider.enabled)
                        {
                            EZSoftBoneUtility.PointOutsideCollider(ref newWorldPosition, collider, bone.radius);
                        }
                    }
                }

                bone.speed         = (newWorldPosition - oldWorldPosition) / Time.deltaTime; //
                bone.worldPosition = newWorldPosition;
            }
            else
            {
                bone.transform.localPosition = bone.originalLocalPosition;
                bone.worldPosition           = bone.transform.position;
            }

            for (int i = 0; i < bone.childBones.Count; i++)
            {
                UpdateNode(bone.childBones[i]);
            }
        }
Пример #3
0
        private void UpdateBones(Bone bone, float deltaTime)
        {
            if (bone.depth > startDepth)
            {
                Vector3 oldWorldPosition, newWorldPosition, expectedPosition;
                oldWorldPosition = newWorldPosition = bone.worldPosition;

                // Resistance (force resistance)
                Vector3 force = globalForce;
                if (forceModule != null && forceModule.isActiveAndEnabled)
                {
                    force += forceModule.GetForce(bone.normalizedLength) * forceScale;
                }
                if (customForce != null)
                {
                    force += customForce(bone.normalizedLength);
                }
                force.x    *= transform.localScale.x;
                force.y    *= transform.localScale.y;
                force.z    *= transform.localScale.z;
                bone.speed += force * (1 - bone.resistance) / iterations;

                // Damping (inertia attenuation)
                bone.speed *= 1 - bone.damping;
                if (bone.speed.sqrMagnitude > sleepThreshold)
                {
                    newWorldPosition += bone.speed * deltaTime;
                }

                // Stiffness (shape keeper)
                Vector3 parentMovement = bone.parentBone.worldPosition - bone.parentBone.transform.position;
                expectedPosition = bone.parentBone.transform.TransformPoint(bone.localPosition) + parentMovement;
                newWorldPosition = Vector3.Lerp(newWorldPosition, expectedPosition, bone.stiffness / iterations);

                // Slackness (length keeper)
                // Length needs to be calculated with TransformVector to match runtime scaling
                Vector3 dirToParent    = (newWorldPosition - bone.parentBone.worldPosition).normalized;
                float   lengthToParent = bone.parentBone.transform.TransformVector(bone.localPosition).magnitude;
                expectedPosition = bone.parentBone.worldPosition + dirToParent * lengthToParent;
                int lengthConstraints = 1;
                // Sibling constraints
                if (siblingConstraints != UnificationMode.None)
                {
                    if (bone.leftBone != null)
                    {
                        Vector3 dirToLeft    = (newWorldPosition - bone.leftBone.worldPosition).normalized;
                        float   lengthToLeft = bone.transform.TransformVector(bone.leftPosition).magnitude;
                        expectedPosition += bone.leftBone.worldPosition + dirToLeft * lengthToLeft;
                        lengthConstraints++;
                    }
                    if (bone.rightBone != null)
                    {
                        Vector3 dirToRight    = (newWorldPosition - bone.rightBone.worldPosition).normalized;
                        float   lengthToRight = bone.transform.TransformVector(bone.rightPosition).magnitude;
                        expectedPosition += bone.rightBone.worldPosition + dirToRight * lengthToRight;
                        lengthConstraints++;
                    }
                }
                expectedPosition /= lengthConstraints;
                newWorldPosition  = Vector3.Lerp(expectedPosition, newWorldPosition, bone.slackness / iterations);

                // Collision
                if (bone.radius > 0)
                {
                    foreach (EZSoftBoneColliderBase collider in EZSoftBoneColliderBase.EnabledColliders)
                    {
                        if (bone.transform != collider.transform && collisionLayers.Contains(collider.gameObject.layer))
                        {
                            collider.Collide(ref newWorldPosition, bone.radius);
                        }
                    }
                    foreach (Collider collider in extraColliders)
                    {
                        if (bone.transform != collider.transform && collider.enabled)
                        {
                            EZSoftBoneUtility.PointOutsideCollider(ref newWorldPosition, collider, bone.radius);
                        }
                    }
                }

                bone.speed         = (bone.speed + (newWorldPosition - oldWorldPosition) / deltaTime) * 0.5f;
                bone.worldPosition = newWorldPosition;
            }
            else
            {
                bone.worldPosition = bone.transform.position;
            }

            for (int i = 0; i < bone.childBones.Count; i++)
            {
                UpdateBones(bone.childBones[i], deltaTime);
            }
        }