public void DrawGizmos() { if (force == null || !isActiveAndEnabled) { return; } Gizmos.matrix = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one); if (Application.isPlaying) { Vector3 forceVector = force.GetForce(Time.time); float width = forceVector.magnitude * 0.2f; EZSoftBoneUtility.DrawGizmosArrow(Vector3.zero, forceVector, width, Vector3.up); EZSoftBoneUtility.DrawGizmosArrow(Vector3.zero, forceVector, width, Vector3.right); Gizmos.DrawRay(Vector3.zero, forceVector); } else { Vector3 forceVector = new Vector3(0, 0, force.force); float width = force.force * 0.2f; EZSoftBoneUtility.DrawGizmosArrow(Vector3.zero, forceVector, width, Vector3.up); EZSoftBoneUtility.DrawGizmosArrow(Vector3.zero, forceVector, width, Vector3.right); Gizmos.DrawRay(Vector3.zero, forceVector); } Gizmos.DrawWireCube(new Vector3(0, 0, force.force), force.turbulence * 2); }
private void OnDrawGizmosSelected() { Vector3 force0 = GetForce(0) * 50; float width = force0.magnitude * 0.2f; Gizmos.DrawRay(transform.position, force0); EZSoftBoneUtility.DrawGizmosArrow(transform.position, force0, width, transform.up); EZSoftBoneUtility.DrawGizmosArrow(transform.position, force0, width, transform.right); }
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); } }
public override void Collide(ref Vector3 position, float spacing) { if (insideMode) { EZSoftBoneUtility.PointInsideCylinder(ref position, transform, spacing + margin); } else { EZSoftBoneUtility.PointOutsideCylinder(ref position, transform, spacing + margin); } }
public void DrawGizmos(Transform gizmosReference, Transform forceSpace) { Vector3 force0 = GetForce(0, forceSpace) * UnityEditor.HandleUtility.GetHandleSize(gizmosReference.position); float width = force0.magnitude * 0.2f; if (forceSpace == null) { Gizmos.DrawRay(gizmosReference.position, force0); EZSoftBoneUtility.DrawGizmosArrow(gizmosReference.position, force0, width, Vector3.up); EZSoftBoneUtility.DrawGizmosArrow(gizmosReference.position, force0, width, Vector3.right); } else { Gizmos.DrawRay(gizmosReference.position, force0); EZSoftBoneUtility.DrawGizmosArrow(gizmosReference.position, force0, width, gizmosReference.up); EZSoftBoneUtility.DrawGizmosArrow(gizmosReference.position, force0, width, gizmosReference.right); } }
private void OnDrawGizmosSelected() { Vector3 center, direction; float radius, height; EZSoftBoneUtility.GetCylinderParams(transform, out center, out direction, out radius, out height); UnityEditor.Handles.color = Color.red; UnityEditor.Handles.matrix = Matrix4x4.identity; Vector3 p0 = center + direction * height; Vector3 p1 = center - direction * height; UnityEditor.Handles.DrawWireDisc(p0, transform.up, radius); UnityEditor.Handles.DrawWireDisc(p1, transform.up, radius); UnityEditor.Handles.matrix *= Matrix4x4.Translate(transform.forward * radius); UnityEditor.Handles.DrawLine(p0, p1); UnityEditor.Handles.matrix *= Matrix4x4.Translate(-transform.forward * 2 * radius); UnityEditor.Handles.DrawLine(p0, p1); UnityEditor.Handles.matrix *= Matrix4x4.Translate((transform.right + transform.forward) * radius); UnityEditor.Handles.DrawLine(p0, p1); UnityEditor.Handles.matrix *= Matrix4x4.Translate(-transform.right * 2 * radius); UnityEditor.Handles.DrawLine(p0, p1); }
public void DrawGizmos(Vector3 gizmosPosition, Transform forceSpace, float scale) { Vector3 forceVector, turbulenceVector; if (forceSpace != null) { forceVector = forceSpace.TransformDirection(direction) * scale; turbulenceVector = forceSpace.TransformDirection(turbulence) * scale; float width = forceVector.magnitude * 0.2f; EZSoftBoneUtility.DrawGizmosArrow(gizmosPosition, forceVector, width, forceSpace.up); EZSoftBoneUtility.DrawGizmosArrow(gizmosPosition, forceVector, width, forceSpace.right); } else { forceVector = direction * scale; turbulenceVector = turbulence * scale; float width = forceVector.magnitude * 0.2f; EZSoftBoneUtility.DrawGizmosArrow(gizmosPosition, forceVector, width, Vector3.up); EZSoftBoneUtility.DrawGizmosArrow(gizmosPosition, forceVector, width, Vector3.right); } Gizmos.DrawRay(gizmosPosition, forceVector); Gizmos.DrawWireCube(gizmosPosition + forceVector + turbulenceVector * 0.5f, turbulenceVector); }
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]); } }
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); } }