void MakeHierarchy() { QJoint walker = animation.hierarchy; int hLen = GetHierarchySize(walker); hierarchy = new List <int>(hLen); Queue <QJoint> remaining = new Queue <QJoint>(); remaining.Enqueue(walker); List <List <int> > pieces = new List <List <int> >(numJoints); for (int i = 0; i < numJoints; i++) { pieces.Add(new List <int>()); } while (remaining.Count > 0) { QJoint joint = remaining.Dequeue(); pieces[joint.index].Add(joint.children.Count); foreach (QJoint child in joint.children) { pieces[joint.index].Add(child.index); remaining.Enqueue(child); } } for (int i = 0; i < numJoints; i++) { List <int> piece = pieces[i]; hierarchy.AddRange(piece); } }
void ApplyPoseTransform(QJoint child, QJoint parent) { boneXForms[child.index] = boneXForms[parent.index] * boneXForms[child.index]; foreach (QJoint childChild in child.children) { ApplyPoseTransform(childChild, child); } boneXForms[child.index] = boneXForms[child.index] * child.inverseBindTransform; }
void GenerateChildren(QJoint parent) { foreach (QJoint child in parent.children) { bonePlaceholders[child.index] = GameObject.CreatePrimitive(PrimitiveType.Cube); //bonePlaceholders[child.index].transform.SetParent(bonePlaceholders[parent.index].transform); bonePlaceholders[child.index].name = child.index.ToString(); GenerateChildren(child); } }
// Update is called once per frame void Update() { timeFrame += Time.deltaTime; if (timeFrame >= animation.length) { timeFrame %= animation.length; } for (int i = 0; i < boneXForms.Length; i++) { TransformData tData = animation.GetTransformAt(i, timeFrame); /* * debugs[i].SetRow(0, new Vector4(tData.position.x, tData.position.y, tData.position.z)); * debugs[i].SetRow(1, new Vector4(tData.rotation.x, tData.rotation.y, tData.rotation.z, tData.rotation.w)); * debugs[i].SetRow(2, new Vector4(tData.scale.x, tData.scale.y, tData.scale.z)); */ tDat[i] = tData; boneXForms[i] = Matrix4x4.TRS(tData.position, tData.rotation, tData.scale); debugs[i] = boneXForms[i]; } QJoint joint = animation.hierarchy; foreach (QJoint child in joint.children) { ApplyPoseTransform(child, joint); } boneXForms[0] = joint.inverseBindTransform * boneXForms[0]; /* * for(int i = 0; i < boneXForms.Length; i++) * { * QJoint joint = animation.FindJointByIndex(i); * * foreach(QJoint child in joint.children) * { * boneXForms[child.index] = boneXForms[child.index] * boneXForms[joint.index]; * } * * boneXForms[joint.index] *= joint.inverseBindTransform; * } */ xFormBuf.SetData(boneXForms); mat.SetBuffer("xforms", xFormBuf); for (int i = 0; i < boneXForms.Length; i++) { Quaternion rot = boneXForms[i].rotation; bonePlaceholders[i].transform.position = new Vector3(boneXForms[i].m03, boneXForms[i].m13, boneXForms[i].m23); bonePlaceholders[i].transform.rotation = rot; //bonePlaceholders[i].transform.localPosition = tDat[i].position; //bonePlaceholders[i].transform.localRotation = tDat[i].rotation; } }
int GetHierarchySize(QJoint walker) { int result = 1; if (walker.children.Count > 0) { result += walker.children.Count; foreach (QJoint child in walker.children) { result += GetHierarchySize(child); } } return(result); }
QJoint FindJointByName(string name) { Queue <QJoint> remaining = new Queue <QJoint>(); remaining.Enqueue(animation.hierarchy); while (remaining.Count > 0) { QJoint result = remaining.Dequeue(); if (result.name == name) { return(result); } foreach (var child in result.children) { remaining.Enqueue(child); } } return(null); }
// Use this for initialization void Start() { mat = GetComponent <Renderer>().material; BagelLoader bagelLoader = new BagelLoader(model); animation = bagelLoader.LoadBagel(path); tDat = new TransformData[animation.jointNames.Count]; bonePlaceholders = new GameObject[tDat.Length]; QJoint hierarchy = animation.hierarchy; bonePlaceholders[0] = GameObject.CreatePrimitive(PrimitiveType.Cube); GenerateChildren(hierarchy); boneXForms = new Matrix4x4[animation.jointNames.Count]; debugs = new Matrix4x4[boneXForms.Length]; xFormBuf = new ComputeBuffer(boneXForms.Length, sizeof(float) * 16); var wghts = model.boneWeights; boneIdxBuf = new ComputeBuffer(wghts.Length, sizeof(float) * 4); boneWeightBuf = new ComputeBuffer(wghts.Length, sizeof(float) * 4); Vector4[] boneIndices = new Vector4[wghts.Length]; Vector4[] boneWeights = new Vector4[wghts.Length]; for (int i = 0; i < wghts.Length; i++) { BoneWeight w = wghts[i]; boneIndices[i] = new Vector4(w.boneIndex0, w.boneIndex1, w.boneIndex2, w.boneIndex3); boneWeights[i] = new Vector4(w.weight0, w.weight1, w.weight2, w.weight3); } boneIdxBuf.SetData(boneIndices); boneWeightBuf.SetData(boneWeights); mat.SetBuffer("boneIndices", boneIdxBuf); mat.SetBuffer("weights", boneWeightBuf); }
void MakeKeyFramesAndJointData() { var keyBlobs = animation.keyFrames; keyframes = new List <List <KeyFrame> >(10); for (int i = 0; i < 10; i++) { keyframes.Add(new List <KeyFrame>()); } jointData = new JointData[numJoints]; List <QJoint> indexedJoints = new List <QJoint>(numJoints); for (int i = 0; i < numJoints; i++) { indexedJoints.Add(null); } foreach (KeyValuePair <string, KeyBlob> kv in keyBlobs) { QJoint curJoint = FindJointByName(kv.Key); int curIdx = curJoint.index; indexedJoints[curIdx] = curJoint; } for (int i = 0; i < numJoints; i++) { QJoint joint = indexedJoints[i]; KeyBlob blob = keyBlobs[joint.name]; int[] jointDataArgs = new int[20]; for (int j = 0; j < 10; j++) { string attribName = "m_LocalPosition.x"; switch (j) { case (1): attribName = "m_LocalPosition.y"; break; case (2): attribName = "m_LocalPosition.z"; break; case (3): attribName = "m_LocalRotation.x"; break; case (4): attribName = "m_LocalRotation.y"; break; case (5): attribName = "m_LocalRotation.z"; break; case (6): attribName = "m_LocalRotation.w"; break; case (7): attribName = "m_LocalScale.x"; break; case (8): attribName = "m_LocalScale.y"; break; case (9): attribName = "m_LocalScale.z"; break; } SortedList <float, ScalarFrame> frames = blob.keyedAttributes[attribName].values; jointDataArgs[j * 2] = keyframes[j].Count; jointDataArgs[j * 2 + 1] = frames.Count; for (int k = 0; k < frames.Count; k++) { float time = frames.Keys[k]; ScalarFrame frame = frames.Values[k]; KeyFrame newFrame = new KeyFrame(time, frame.value, frame.inTangent, frame.outTangent); keyframes[j].Add(newFrame); } } int numChildren = NumChildren(i); Matrix4x4 bindPose = bindTransforms[i];//.inverse; jointData[i] = new JointData(jointDataArgs, numChildren, bindPose); } }
public AnimationData MakeKeyFramesAndJointData(Mesh model) { int numJoints = animation.jointNames.Count; var keyBlobs = animation.keyFrames; AnimationData result = new AnimationData(); result.jointData = new JointData[numJoints]; result.keyframes = new List <KeyFrame> [10]; for (int i = 0; i < 10; i++) { result.keyframes[i] = new List <KeyFrame>(); } List <QJoint> indexedJoints = new List <QJoint>(numJoints); for (int i = 0; i < numJoints; i++) { indexedJoints.Add(null); } foreach (KeyValuePair <string, KeyBlob> kv in keyBlobs) { QJoint curJoint = FindJointByName(kv.Key); int curidx = curJoint.index; indexedJoints[curidx] = curJoint; } for (int i = 0; i < numJoints; i++) { QJoint joint = indexedJoints[i]; KeyBlob blob = keyBlobs[joint.name]; int[] jointDataArgs = new int[20]; for (int j = 0; j < 10; j++) { string attribName = "m_LocalPosition.x"; switch (j) { case (1): attribName = "m_LocalPosition.y"; break; case (2): attribName = "m_LocalPosition.z"; break; case (3): attribName = "m_LocalRotation.x"; break; case (4): attribName = "m_LocalRotation.y"; break; case (5): attribName = "m_LocalRotation.z"; break; case (6): attribName = "m_LocalRotation.w"; break; case (7): attribName = "m_LocalScale.x"; break; case (8): attribName = "m_LocalScale.y"; break; case (9): attribName = "m_LocalScale.z"; break; } SortedList <float, ScalarFrame> frames = blob.keyedAttributes[attribName].values; jointDataArgs[j * 2] = result.keyframes[j].Count; jointDataArgs[j * 2 + 1] = frames.Count; for (int k = 0; k < frames.Count; k++) { float time = frames.Keys[k]; ScalarFrame frame = frames.Values[k]; KeyFrame newFrame = new KeyFrame(time, frame.value); result.keyframes[j].Add(newFrame); } } int numChildren = NumChildren(i); Matrix4x4 bindPose = model.bindposes[i]; result.jointData[i] = new JointData(jointDataArgs, numChildren, bindPose); } return(result); }