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); } }
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); } }