예제 #1
0
 public override void Collide(ref Vector3 position, float spacing)
 {
     if (referenceCollider is SphereCollider)
     {
         SphereCollider collider = referenceCollider as SphereCollider;
         if (insideMode)
         {
             EZPhysicsBoneUtility.PointInsideSphere(ref position, collider, spacing + margin);
         }
         else
         {
             EZPhysicsBoneUtility.PointOutsideSphere(ref position, collider, spacing + margin);
         }
     }
     else if (referenceCollider is CapsuleCollider)
     {
         CapsuleCollider collider = referenceCollider as CapsuleCollider;
         if (insideMode)
         {
             EZPhysicsBoneUtility.PointInsideCapsule(ref position, collider, spacing + margin);
         }
         else
         {
             EZPhysicsBoneUtility.PointOutsideCapsule(ref position, collider, spacing + margin);
         }
     }
     else if (referenceCollider is BoxCollider)
     {
         BoxCollider collider = referenceCollider as BoxCollider;
         if (insideMode)
         {
             EZPhysicsBoneUtility.PointInsideBox(ref position, collider, spacing + margin);
         }
         else
         {
             EZPhysicsBoneUtility.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;
         }
         EZPhysicsBoneUtility.PointOutsideCollider(ref position, referenceCollider, spacing + margin);
     }
 }
예제 #2
0
        private void UpdateNode(TreeNode node, float deltaTime)
        {
            if (node.depth > startDepth)
            {
                Vector3 position = node.position;

                // Damping (inertia attenuation)
                if (node.speed.sqrMagnitude < sleepThreshold)
                {
                    node.speed = Vector3.zero;
                }
                else
                {
                    position += node.speed * deltaTime * (1 - node.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(node.normalizedLength);
                }
                force.x  *= transform.localScale.x;
                force.y  *= transform.localScale.y;
                force.z  *= transform.localScale.z;
                position += force * (1 - node.resistance) / iterations;

                // Stiffness (shape keeper)
                Vector3 parentOffset = node.parent.position - node.parent.transform.position;
                Vector3 expectedPos  = node.parent.transform.TransformPoint(node.originalLocalPosition) + parentOffset;
                position = Vector3.Lerp(position, expectedPos, node.stiffness / iterations);

                // Slackness (length keeper)
                Vector3 nodeDir    = (position - node.parent.position).normalized;
                float   nodeLength = node.parent.transform.TransformVector(node.originalLocalPosition).magnitude;
                nodeDir = node.parent.position + nodeDir * nodeLength;
                // Siblings
                if (siblingConstraints != SiblingConstraints.None)
                {
                    int constraints = 1;
                    if (node.leftSibling != null)
                    {
                        Vector3 leftDir    = (position - node.leftSibling.position).normalized;
                        float   leftLength = node.transform.TransformVector(node.positionToLeft).magnitude;
                        leftDir  = node.leftSibling.position + leftDir * leftLength;
                        nodeDir += leftDir;
                        constraints++;
                    }
                    if (node.rightSibling != null)
                    {
                        Vector3 rightDir    = (position - node.rightSibling.position).normalized;
                        float   rightLength = node.transform.TransformVector(node.positionToRight).magnitude;
                        rightDir = node.rightSibling.position + rightDir * rightLength;
                        nodeDir += rightDir;
                        constraints++;
                    }
                    nodeDir /= constraints;
                }
                position = Vector3.Lerp(nodeDir, position, node.slackness / iterations);

                // Collision
                if (node.radius > 0)
                {
                    foreach (EZPBColliderBase collider in EZPBColliderBase.EnabledColliders)
                    {
                        if (node.transform != collider.transform && collisionLayers.Contains(collider.gameObject.layer))
                        {
                            collider.Collide(ref position, node.radius);
                        }
                    }
                    foreach (Collider collider in extraColliders)
                    {
                        if (node.transform != collider.transform && collider.enabled)
                        {
                            EZPhysicsBoneUtility.PointOutsideCollider(ref position, collider, node.radius);
                        }
                    }
                }

                node.speed    = (position - node.position) / deltaTime;
                node.position = position;
            }
            else
            {
                node.transform.localPosition = node.originalLocalPosition;
                node.position = node.transform.position;
            }

            for (int i = 0; i < node.children.Count; i++)
            {
                UpdateNode(node.children[i], deltaTime);
            }
        }