using UnityEngine;
using System.Collections;
public class BodyDeform : MonoBehaviour {
float lowerbody = 1f;
public float Lowerbody = 1f;
float upperbody = 1f;
public float Upperbody = 1f;
float fatness = 1f;
public float Fatness = 1f;
float height = 1f;
public float Height = 1f;
float shoulders = 1f;
public float Shoulders = 1f;
float head = 1f;
public float Head = 1f;
Mesh mesh = null;
Matrix4x4[] original = null;
Matrix4x4[] poses = null;
Matrix4x4[] bonepos = null;
Matrix4x4 localToWorld = Matrix4x4.identity;
// Use this for initialization
void Awake () {
SkinnedMeshRenderer smr = GetComponent<SkinnedMeshRenderer>();
mesh = smr.sharedMesh;
poses = new Matrix4x4[mesh.bindposes.Length];
original = new Matrix4x4[mesh.bindposes.Length];
bonepos = new Matrix4x4[mesh.bindposes.Length];
for (int i = 0; i < mesh.bindposes.Length; i++) {
bonepos[i] = smr.bones[i].worldToLocalMatrix;
}
localToWorld = transform.localToWorldMatrix;
mesh = new Mesh();
smr.sharedMesh = this.mesh;
//SetMesh(smr.sharedMesh);
}
void OnApplicationQuit() {
if (this.mesh != null)
mesh.bindposes = original;
}
public void SetMesh (Mesh mesh) {
if (this.mesh != null) {
//Destroy(this.mesh);
//this.mesh.bindposes = original;
}
this.mesh.vertices = mesh.vertices;
this.mesh.triangles = mesh.triangles;
this.mesh.uv = mesh.uv;
this.mesh.colors = mesh.colors;
this.mesh.bindposes = mesh.bindposes;
this.mesh.boneWeights = mesh.boneWeights;
this.mesh.colors32 = mesh.colors32;
this.mesh.normals = mesh.normals;
SkinnedMeshRenderer smr = GetComponent<SkinnedMeshRenderer>();
smr.sharedMesh = this.mesh;
//smr.sharedMesh = this.mesh = Instantiate(mesh) as Mesh;
//AssetDatabase.CreateAsset(this.mesh, AssetDatabase.GetAssetPath(mesh) + “ copy.asset“);
Debug.Log(“Bind Poses: “ + this.mesh.bindposes.Length);
//Debug.Log(this.name);
for (int i = 0; i < this.mesh.bindposes.Length; i++) {
poses[i] = mesh.bindposes[i];
original[i] = mesh.bindposes[i];
}
ApplyMeshDeform();
}
void ApplyMeshDeform () {
height = Mathf.Clamp(Height, 0.2f, 5f);
fatness = Mathf.Clamp(Fatness, 0.8f, 2.0f);
float dFat = fatness – 1f;
lowerbody = Mathf.Clamp(Lowerbody * fatness, 0.6f, 1.6f);
upperbody = Mathf.Clamp(Upperbody * fatness, 0.6f, 2.0f);
shoulders = Mathf.Clamp(Shoulders, 0.8f, 1.4f);
head = Mathf.Clamp(Head, 0.5f, 01.5f);
transform.parent.localScale = Vector3.one * height;
UpdateSkeleton();
}
void UpdateSkeleton() {
float delta = 1f;
// LOWER BODY (up, wide, out)
delta = lowerbody – 1f;
SetSkin(“LegUpper“, new Vector3(1f, 1f+delta*0.8f, 1f+delta*0.8f));
SetSkin(“LegLower“, new Vector3(1f, 1f+delta*0.6f, 1f+delta*0.6f));
SetSkin(“Hip“, new Vector3(1f, 1f+delta*0.6f, 1f+hippiness*0.6f));
// UPPER BODY (up, wide, out)
delta = upperbody – 1f;
SetSkin(“ArmUpper“, new Vector3(1f, 1f+delta, 1f+delta));
SetSkin(“ArmLower“, new Vector3(1f, 1f+delta*0.5f, 1f+delta*0.5f));
SetSkin(“Hand“, new Vector3(1f, 1f+delta*0.2f, 1f+delta*0.2f));
SetSkin(“BackUpper“, new Vector3(1f, 1f+delta*0.2f, 1f+delta*0.2f));
SetBone(“Shoulder“, new Vector3(1f, shoulders, 1f));
// down, wide, out
SetSkin(“Chest“, new Vector3(1f+delta*0.1f, 1f+delta*0.4f, 1f+delta*0.4f));
// CENTER BODY (up, wide, out)
delta = fatness – 1f;
SetSkin(“BackLower“, new Vector3(1f+delta*0.2f, 1f+delta*0.4f, 1f+delta*0.7f));
//SetSkin(“BackMiddle“, new Vector3(1f+delta*0.2f, 1f+delta*0.7f, 1f+delta*1.0f));
//SetSkin(“BackUpper“, new Vector3(1f+delta*0.2f, 1f+delta*0.7f, 1f+delta*1.0f));
//SetSkin(“Chest“, new Vector3(1f+delta*0.2f, 1f+delta*0.7f, 1f+delta*1.0f));
//SetSkin(“Stomach“, new Vector3(1f+delta*0.3f, 1f+delta*0.5f, 1f+delta*1.0f));
SetSkin(“BackMiddle“, new Vector3(1f+delta*0.2f, 1f+delta*0.2f, 1f+delta*0.7f));
SetSkin(“Pelvis“, new Vector3(1f+delta*0.4f, 1f+delta*0.3f, 1f+delta*0.3f));
// HEAD
delta = head – 1f;
SetSkin(“Head“, new Vector3(1f+delta, 1f+delta, 1f+delta));
SetSkin(“Hair“, new Vector3(1f+delta, 1f+delta, 1f+delta));
SetSkin(“Jaw“, new Vector3(1f+delta, 1f+delta, 1f+delta));
mesh.bindposes = poses;
}
public bool _SetSkin(string name, Vector3 scale) {
SkinnedMeshRenderer smr = GetComponent<SkinnedMeshRenderer>();
Transform[] bones = smr.bones;
int i = 0;
for (i = 0; i < bones.Length; i++) {
if (bones[i].name == name)
break;
}
if (i == bones.Length) {
//Debug.Log(“Did not find: “ + name + “ in object “ + this.name);
return false;
}
//Debug.Log(“Found “ + name + “ at index: “ + i + “ for scale: “ + scale);
Matrix4x4 r = Matrix4x4.identity;
r.SetTRS(Vector3.zero,
Quaternion.AngleAxis(90f, Vector3.left),
Vector3.one);
Matrix4x4 s = Matrix4x4.Scale(scale);
//Debug.Log(“Pose: “ + poses + “ Bone: “ + bonepos);
poses[i] = s * bonepos[i] * localToWorld * r;
return true;
}
public bool _SetBone(string name, Vector3 scale) {
Transform bone = FindBone(transform.parent, name);
if (bone != null) {
bone.localScale = scale;
//Debug.Log(“Overriding local scale for: “ + name + “ to: “ + scale) ;
return true;
}
//Debug.Log(“Unable to find: “ + name);
return false;
}
public void SetBone(string name, Vector3 scale) {
if (!_SetBone(name, scale)) {
_SetBone(name+“_L“, scale);
_SetBone(name+“_R“, scale);
}
}
public void SetSkin(string name, Vector3 scale) {
if (!_SetSkin(name, scale)) {
_SetSkin(name+“_L“, scale);
_SetSkin(name+“_R“, scale);
}
}
public Transform FindBone (Transform transform, string name)
{
foreach (Transform child in transform)
{
if (child.name == name)
return child;
else
{
Transform test = FindBone(child, name);
if (test != null)
return test;
}
}
return null;
}
}