public static void ApplyRelativedSkeleton(ref SkeletonV1 targetPose, Animator animator, Transform container, SkeletonV1 tpose, JointMask mask, float deltaTime) { for (int i = 0; i < targetPose.joints.Length - 1; i++) { var j = targetPose.joints[i]; var bone = animator.GetBoneTransform((HumanBodyBones)j.type); if (bone == null) { //Debug.LogFormat("Model {0} doesn't have bone {1}", animator.gameObject.name, (HumanBodyBones)j.type); continue; } /* * SKIP If TPoseRot doesn't contain the joint * Means we don't have startup data for that bone * We'll get incorrect rotation anyway */ if (tpose.HasJoint(j.type) == false) { continue; } var def = tpose.GetJoint(j.type); /* * If mask out UpperBody */ if (mask.HasFlag(JointMask.UpperBody) == false) { if (Chiron.Skeleton.Utility.IsUpperBody((HumanBodyBones)j.type)) { continue; } } /* * If mask out LowerBody */ if (mask.HasFlag(JointMask.LowerBody) == false) { if (Chiron.Skeleton.Utility.IsLowerBody((HumanBodyBones)j.type)) { continue; } } /* * If mask out Hip */ if (mask.HasFlag(JointMask.Hip) == false) { if (Chiron.Skeleton.Utility.IsHip((HumanBodyBones)j.type)) { continue; } } var t = animator.transform; var rlt = t ? Quaternion.Inverse(t.rotation) * j.rot : j.rot; var rot = rlt * def.rot; //rot.x *= flip.x; //rot.y *= flip.y; //rot.z *= flip.z; //rot.w *= flip.w; var pos = j.pos + def.pos; //bone.rotation = Quaternion.Lerp(bone.rotation, rot, normalize); bone.rotation = Quaternion.Lerp(bone.rotation, rot, deltaTime); var posDiff = pos - bone.localPosition; bone.localPosition = Vector3.Lerp(bone.localPosition, pos, deltaTime); //Guessing root transform var ch = container; ch.localPosition = Vector3.Lerp(ch.localPosition, targetPose.centerOffset, deltaTime); } }
public static SkeletonV1 CreateRelativedSkeleton(Animator animator, SkeletonV1 tpose, string name) { var sk = new SkeletonV1(); var upperConf = 0f; var upperNum = 0; var lowerConf = 0f; var lowerNum = 0; var overallConf = 0f; sk.variation = Chiron.Skeleton.SkeletonV1.Variation.skeletonv1default; sk.name = name; sk.hasSkeleton = true; sk.joints = new SkeletonV1.Joint[tpose.joints.Length]; Transform lShoulder = animator.GetBoneTransform(HumanBodyBones.LeftShoulder); Transform rShoulder = animator.GetBoneTransform(HumanBodyBones.RightShoulder); var distShoulder = lShoulder.position - rShoulder.position; Transform hip = animator.GetBoneTransform(HumanBodyBones.Hips); var index = 0; /* * Length of VNect joint * Because VNect bone not always existing in Avatar * Meaning you can't get correct length on VNectModel, length of 28 is incorrect * So we need to count it base on Avatar, then cross reference with VNectModel */ var vcount = 0; foreach (var i in tpose.joints) { if (i.type == -1) { continue; } var joint = animator.GetBoneTransform((HumanBodyBones)i.type); if (joint) { var jt = new SkeletonV1.Joint(); jt.type = i.type; jt.pos = joint.localPosition - tpose.GetJoint(i.type).pos; jt.rot = joint.rotation * Quaternion.Inverse(tpose.GetJoint(i.type).rot); sk.joints[index] = jt; if (IsUpperBody(i.type)) { upperConf += 1f; upperNum++; } else if (IsLowerBody(i.type)) { lowerConf += 1f; lowerNum++; } overallConf += 1f; vcount++; } index++; } var root = new SkeletonV1.Joint(); root.type = -1; root.pos = animator.transform.localPosition; root.rot = animator.transform.rotation; sk.joints[sk.joints.Length - 1] = root; sk.upperConf = upperConf / (float)upperNum; sk.lowerConf = lowerConf / (float)lowerNum; sk.overallConf = overallConf / (float)vcount; sk.distanceShoulder = distShoulder; return(sk); }