|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using System.Collections;
|
|
|
|
|
|
|
|
|
|
|
|
namespace RootMotion.Dynamics {
|
|
|
|
|
|
|
|
|
|
|
|
public static class PuppetMasterTools {
|
|
|
|
|
|
|
|
|
|
|
|
public static void PositionRagdoll(PuppetMaster puppetMaster) {
|
|
|
|
|
|
Rigidbody[] rigidbodies = puppetMaster.transform.GetComponentsInChildren<Rigidbody>();
|
|
|
|
|
|
if (rigidbodies.Length == 0) return;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Muscle m in puppetMaster.muscles) if (m.joint == null || m.target == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
Vector3[] swingAxes = new Vector3[rigidbodies.Length];
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < rigidbodies.Length; i++) {
|
|
|
|
|
|
if (rigidbodies[i].transform.childCount == 1) {
|
|
|
|
|
|
swingAxes[i] = rigidbodies[i].transform.InverseTransformDirection(rigidbodies[i].transform.GetChild(0).position - rigidbodies[i].transform.position);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Rigidbody r in rigidbodies) {
|
|
|
|
|
|
foreach (Muscle m in puppetMaster.muscles) {
|
|
|
|
|
|
if (m.joint.GetComponent<Rigidbody>() == r) {
|
|
|
|
|
|
r.transform.position = m.target.position;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < rigidbodies.Length; i++) {
|
|
|
|
|
|
if (rigidbodies[i].transform.childCount == 1) {
|
|
|
|
|
|
Vector3 childPosition = rigidbodies[i].transform.GetChild(0).position;
|
|
|
|
|
|
|
|
|
|
|
|
rigidbodies[i].transform.rotation = Quaternion.FromToRotation(rigidbodies[i].transform.rotation * swingAxes[i], childPosition - rigidbodies[i].transform.position) * rigidbodies[i].transform.rotation;
|
|
|
|
|
|
rigidbodies[i].transform.GetChild(0).position = childPosition;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void RealignRagdoll(PuppetMaster puppetMaster) {
|
|
|
|
|
|
foreach (Muscle m in puppetMaster.muscles) {
|
|
|
|
|
|
if (m.joint == null || m.joint.transform == null || m.target == null) {
|
|
|
|
|
|
Debug.LogWarning("Muscles incomplete, can not realign ragdoll.");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Muscle m in puppetMaster.muscles) {
|
|
|
|
|
|
if (m.target != null) {
|
|
|
|
|
|
Transform[] children = new Transform[m.joint.transform.childCount];
|
|
|
|
|
|
for (int c = 0 ; c < children.Length; c++) {
|
|
|
|
|
|
children[c] = m.joint.transform.GetChild(c);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Transform c in children) c.parent = null;
|
|
|
|
|
|
|
|
|
|
|
|
BoxCollider box = m.joint.GetComponent<BoxCollider>();
|
|
|
|
|
|
Vector3 boxSizeWorldSpace = Vector3.zero;
|
|
|
|
|
|
Vector3 boxCenterWorldSpace = Vector3.zero;
|
|
|
|
|
|
|
|
|
|
|
|
if (box != null) {
|
|
|
|
|
|
boxSizeWorldSpace = box.transform.TransformVector(box.size);
|
|
|
|
|
|
boxCenterWorldSpace = box.transform.TransformVector(box.center);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CapsuleCollider capsule = m.joint.GetComponent<CapsuleCollider>();
|
|
|
|
|
|
Vector3 capsuleCenterWorldSpace = Vector3.zero;
|
|
|
|
|
|
Vector3 capsuleDirectionWorldSpace = Vector3.zero;
|
|
|
|
|
|
|
|
|
|
|
|
if (capsule != null) {
|
|
|
|
|
|
capsuleCenterWorldSpace = capsule.transform.TransformVector(capsule.center);
|
|
|
|
|
|
capsuleDirectionWorldSpace = capsule.transform.TransformVector(DirectionIntToVector3(capsule.direction));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SphereCollider sphere = m.joint.GetComponent<SphereCollider>();
|
|
|
|
|
|
Vector3 sphereCenterWorldSpace = Vector3.zero;
|
|
|
|
|
|
|
|
|
|
|
|
if (sphere != null) {
|
|
|
|
|
|
sphereCenterWorldSpace = sphere.transform.TransformVector(sphere.center);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Vector3 jointAxisWorldSpace = m.joint.transform.TransformVector(m.joint.axis);
|
|
|
|
|
|
Vector3 jointSecondaryAxisWorldSpace = m.joint.transform.TransformVector(m.joint.secondaryAxis);
|
|
|
|
|
|
|
|
|
|
|
|
// Rotate the bone
|
|
|
|
|
|
m.joint.transform.rotation = m.target.rotation;
|
|
|
|
|
|
|
|
|
|
|
|
if (box != null) {
|
|
|
|
|
|
box.size = box.transform.InverseTransformVector(boxSizeWorldSpace);
|
|
|
|
|
|
box.center = box.transform.InverseTransformVector(boxCenterWorldSpace);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (capsule != null) {
|
|
|
|
|
|
capsule.center = capsule.transform.InverseTransformVector(capsuleCenterWorldSpace);
|
|
|
|
|
|
Vector3 directionLocalSpace = capsule.transform.InverseTransformDirection(capsuleDirectionWorldSpace);
|
|
|
|
|
|
capsule.direction = DirectionVector3ToInt(directionLocalSpace);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (sphere != null) {
|
|
|
|
|
|
sphere.center = sphere.transform.InverseTransformVector(sphereCenterWorldSpace);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m.joint.axis = m.joint.transform.InverseTransformVector(jointAxisWorldSpace);
|
|
|
|
|
|
m.joint.secondaryAxis = m.joint.transform.InverseTransformVector(jointSecondaryAxisWorldSpace);
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Transform c in children) c.parent = m.joint.transform;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static Vector3 DirectionIntToVector3(int dir) {
|
|
|
|
|
|
if (dir == 0) return Vector3.right;
|
|
|
|
|
|
if (dir == 1) return Vector3.up;
|
|
|
|
|
|
return Vector3.forward;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static int DirectionVector3ToInt(Vector3 dir) {
|
|
|
|
|
|
float dotX = Vector3.Dot(dir, Vector3.right);
|
|
|
|
|
|
float dotY = Vector3.Dot(dir, Vector3.up);
|
|
|
|
|
|
float dotZ = Vector3.Dot(dir, Vector3.forward);
|
|
|
|
|
|
|
|
|
|
|
|
float absDotX = Mathf.Abs(dotX);
|
|
|
|
|
|
float absDotY = Mathf.Abs(dotY);
|
|
|
|
|
|
float absDotZ = Mathf.Abs(dotZ);
|
|
|
|
|
|
|
|
|
|
|
|
int rotatedDirection = 0;
|
|
|
|
|
|
if (absDotY > absDotX && absDotY > absDotZ) rotatedDirection = 1;
|
|
|
|
|
|
if (absDotZ > absDotX && absDotZ > absDotY) rotatedDirection = 2;
|
|
|
|
|
|
return rotatedDirection;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|