// Transforms BVHJoint according to the keyframe channel data, and recursively transforms its children private void TransformJoint(BVHJoint joint, Matrix4x4 parentTransform, float[] keyframe) { Matrix4x4 localRMatrix = Matrix4x4.identity; if (!joint.isEndSite) { Matrix4x4[] rMatrices = new Matrix4x4[3]; rMatrices[joint.rotationOrder.x] = MatrixUtils.RotateX(keyframe[joint.rotationChannels.x]); rMatrices[joint.rotationOrder.y] = MatrixUtils.RotateY(keyframe[joint.rotationChannels.y]); rMatrices[joint.rotationOrder.z] = MatrixUtils.RotateZ(keyframe[joint.rotationChannels.z]); localRMatrix = rMatrices[0] * rMatrices[1] * rMatrices[2]; } Matrix4x4 localTMatrix = MatrixUtils.Translate(joint.offset); Matrix4x4 localTRS = localTMatrix * localRMatrix; Matrix4x4 globalTransform = parentTransform * localTRS; MatrixUtils.ApplyTransform(joint.gameObject, globalTransform); foreach (BVHJoint childJoint in joint.children) { TransformJoint(childJoint, globalTransform, keyframe); } }
// Creates a GameObject representing a given BVHJoint and recursively creates GameObjects for it's child joints GameObject CreateJoint(BVHJoint joint, Vector3 parentPosition) { joint.gameObject = new GameObject(); joint.gameObject.name = joint.name; var translateMatrix = MatrixUtils.Translate(parentPosition + joint.offset); if (joint == data.rootJoint) { Debug.Log(translateMatrix + " " + joint.offset); } var scaleFactor = joint.name == "Head" ? new Vector3(8, 8, 8) : new Vector3(2, 2, 2); var scalingMatrix = MatrixUtils.Scale(scaleFactor); var newSphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); newSphere.transform.parent = joint.gameObject.transform; MatrixUtils.ApplyTransform(newSphere, scalingMatrix); MatrixUtils.ApplyTransform(joint.gameObject, translateMatrix); foreach (var child in joint.children) { var childJoint = CreateJoint(child, joint.gameObject.transform.position); var cylinder = CreateCylinderBetweenPoints(childJoint.gameObject.transform.position, joint.gameObject.transform.position, .5f); cylinder.transform.parent = joint.gameObject.transform; } return(joint.gameObject); }
// Creates a GameObject representing a given BVHJoint and recursively creates GameObjects for it's child joints GameObject CreateJoint(BVHJoint joint, Vector3 parentPosition) { joint.gameObject = new GameObject(joint.name); GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.transform.parent = joint.gameObject.transform; Vector3 scale; if (joint.name == "Head") { scale = new Vector3(8, 8, 8); } else { scale = new Vector3(2, 2, 2); } MatrixUtils.ApplyTransform(sphere, MatrixUtils.Scale(scale)); Matrix4x4 t = MatrixUtils.Translate(parentPosition + joint.offset); MatrixUtils.ApplyTransform(joint.gameObject, t); foreach (BVHJoint child in joint.children) { GameObject childObject = CreateJoint(child, joint.gameObject.transform.position); GameObject bone = CreateCylinderBetweenPoints(joint.gameObject.transform.position, childObject.transform.position, 0.5f); bone.transform.parent = joint.gameObject.transform; } return(joint.gameObject); }
// Transforms BVHJoint according to the keyframe channel data, and recursively transforms its children private void TransformJoint(BVHJoint joint, Matrix4x4 parentTransform, float[] keyframe) { Matrix4x4 t, m; if (joint == data.rootJoint) { Vector3 position = new Vector3(keyframe[joint.positionChannels[0]], keyframe[joint.positionChannels[1]], keyframe[joint.positionChannels[2]]); t = MatrixUtils.Translate(position); } else { t = MatrixUtils.Translate(joint.offset); } if (!joint.isEndSite) { Matrix4x4[] r_array = new Matrix4x4[3]; r_array[joint.rotationOrder[0]] = MatrixUtils.RotateX(keyframe[joint.rotationChannels[0]]); r_array[joint.rotationOrder[1]] = MatrixUtils.RotateY(keyframe[joint.rotationChannels[1]]); r_array[joint.rotationOrder[2]] = MatrixUtils.RotateZ(keyframe[joint.rotationChannels[2]]); Matrix4x4 r = r_array[0] * r_array[1] * r_array[2]; m = parentTransform * t * r; } else { m = parentTransform * t; } MatrixUtils.ApplyTransform(joint.gameObject, m); foreach (BVHJoint child in joint.children) { TransformJoint(child, m, keyframe); } }
private Quaternion getFrameQuat(BVHJoint joint, float[] frameVals) { var frameQuat = Quaternion.identity; for (int i = 0; i < joint.channels.Count; i++) { var c = joint.channels[i]; var v = frameVals[joint.id0 + i]; var q = Quaternion.identity; switch (c) { case BVHJoint.Channel.Xrotation: q = Quaternion.Euler(v, 0, 0); break; case BVHJoint.Channel.Yrotation: q = Quaternion.Euler(0, -v, 0); break; case BVHJoint.Channel.Zrotation: q = Quaternion.Euler(0, 0, -v); break; } frameQuat = frameQuat * q; } return(frameQuat); }
private Vector3 getFramePos(BVHJoint joint, float[] frameVals) { var framePos = Vector3.zero; for (int i = 0; i < joint.channels.Count; i++) { var c = joint.channels[i]; var v = frameVals[joint.id0 + i] / positionScale; var p = Vector3.zero; switch (c) { case BVHJoint.Channel.Xposition: p = new Vector3(-v, 0, 0); break; case BVHJoint.Channel.Yposition: p = new Vector3(0, v, 0); break; case BVHJoint.Channel.Zposition: p = new Vector3(0, 0, v); break; } framePos = framePos + p; } return(framePos); }
void parseHierarchy(string hierarchy) { CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; var channelNames = Enum.GetNames(typeof(BVHJoint.Channel)).Select(x => x.ToLower()).ToList(); Stack <BVHJoint> jointStack = new Stack <BVHJoint>(); int idn = 0; foreach (var line in hierarchy.Split('\n')) { var l = line.TrimStart().TrimEnd(); if (Regex.IsMatch(l, @"^(ROOT|JOINT|END)", RegexOptions.IgnoreCase)) { var name = Regex.Split(l, @"^(ROOT|JOINT|END)", RegexOptions.IgnoreCase)[2].Trim(); var joint = new BVHJoint(); if (jointStack.Count > 0) { var parent = jointStack.Peek(); parent.addChild(joint); } else { root = joint; } joint.id0 = idn; joint.name = Regex.IsMatch(l, "^END", RegexOptions.IgnoreCase) ? joint.parent.name + "_end" : name; jointStack.Push(joint); joints[joint.name] = joint; } else if (Regex.IsMatch(l, "OFFSET", RegexOptions.IgnoreCase)) { var offStr = Regex.Split(Regex.Split(l, @"OFFSET\s+", RegexOptions.IgnoreCase)[1], "\\s+"); var off = new Vector3(float.Parse(offStr[0]), float.Parse(offStr[1]), float.Parse(offStr[2])); jointStack.Peek().offset = off; } else if (Regex.IsMatch(l, "CHANNELS", RegexOptions.IgnoreCase)) { var channelCount = int.Parse(Regex.Split(l, @"CHANNELS\s+", RegexOptions.IgnoreCase)[1][0].ToString()); if (channelCount == 0) { continue; } var channelsStr = Regex.Split(Regex.Split(l, channelCount.ToString() + "\\s+")[1], "\\s+"); foreach (var channelstr in channelsStr) { var c = channelstr.ToLower(); var channel = (BVHJoint.Channel)channelNames.FindIndex(x => x == c); jointStack.Peek().channels.Add(channel); } idn += jointStack.Peek().channels.Count; } else if (Regex.IsMatch(l, @"\}", RegexOptions.IgnoreCase)) { jointStack.Pop(); } } }
public BVHJoint readJoint(int iit, int kCount) { BVHJointKey [] positions; BVHJoint pJoint = new BVHJoint(); pJoint.mOrder = wOrder[iit]; positions = readkeys(iit, kCount); pJoint.mPosRotKeys = positions; return(pJoint); }
private BVHJoint ParseJoint(string name, bool isEnd = false) { BVHJoint joint = new BVHJoint(name, isEnd); var line = getNextLine(); while (line[KEYWORD] != "}") { if (line[KEYWORD] == "OFFSET") { joint.offset = new Vector3(float.Parse(line[X], CultureInfo.InvariantCulture), float.Parse(line[Y], CultureInfo.InvariantCulture), float.Parse(line[Z], CultureInfo.InvariantCulture)); } else if (line[KEYWORD] == "CHANNELS") { var numChannels = int.Parse(line[NUM_CHANNELS]); int rotationIndex = 0; for (var c = 0; c < numChannels; c++) { var channelName = line[c + 2]; var axis = Array.IndexOf(AXES, channelName.Substring(0, 1)); if (channelName.Substring(1) == "rotation") { joint.rotationChannels[axis] = currChannelIndex; joint.rotationOrder[axis] = rotationIndex; rotationIndex++; } else if (channelName.Substring(1) == "position") { joint.positionChannels[axis] = currChannelIndex; } currChannelIndex++; } } else if (line[KEYWORD] == "JOINT") { joint.children.Add(ParseJoint(line[NAME])); } else if (line[KEYWORD] == "End") { joint.children.Add(ParseJoint("End", true)); } line = getNextLine(); } return(joint); }
// Gets the Rotation Matrix to the current animation frame private Matrix4x4 getRMatrix(BVHJoint joint, float[] keyframe) { var xRotation = keyframe[joint.rotationChannels.x]; var yRotation = keyframe[joint.rotationChannels.y]; var zRotation = keyframe[joint.rotationChannels.z]; Matrix4x4[] rotationMatrices = new Matrix4x4[3]; rotationMatrices[joint.rotationOrder.x] = MatrixUtils.RotateX(xRotation); rotationMatrices[joint.rotationOrder.y] = MatrixUtils.RotateY(yRotation); rotationMatrices[joint.rotationOrder.z] = MatrixUtils.RotateZ(zRotation); var R = rotationMatrices[0] * rotationMatrices[1] * rotationMatrices[2]; return(R); }
// Transforms BVHJoint according to the keyframe channel data, and recursively transforms its children private void TransformJoint(BVHJoint joint, Matrix4x4 parentTransform, float[] keyframe) { Matrix4x4[] order = new Matrix4x4[3]; order[joint.rotationOrder.x] = MatrixUtils.RotateX(keyframe[joint.rotationChannels.x]);; order[joint.rotationOrder.y] = MatrixUtils.RotateY(keyframe[joint.rotationChannels.y]); order[joint.rotationOrder.z] = MatrixUtils.RotateZ(keyframe[joint.rotationChannels.z]); Matrix4x4 R = order[0] * order[1] * order[2]; Matrix4x4 T = MatrixUtils.Translate(joint.offset); Matrix4x4 M = parentTransform * T * R; MatrixUtils.ApplyTransform(joint.gameObject, M); foreach (BVHJoint child in joint.children) { TransformJoint(child, M, keyframe); } }
// Transforms BVHJoint according to the keyframe channel data, and recursively transforms its children private void TransformJoint(BVHJoint joint, Matrix4x4 parentTransform, float[] keyframe) { var S = MatrixUtils.Scale(Vector3.one); var rootPos = new Vector3(keyframe[joint.positionChannels.x], keyframe[joint.positionChannels.y], keyframe[joint.positionChannels.z]); var T = joint != data.rootJoint ? MatrixUtils.Translate(joint.offset) : MatrixUtils.Translate(rootPos); var R = !joint.isEndSite ? getRMatrix(joint, keyframe) : Matrix4x4.identity; var M = T * R * S; var newTransform = parentTransform * M; MatrixUtils.ApplyTransform(joint.gameObject, newTransform); foreach (var child in joint.children) { TransformJoint(child, newTransform, keyframe); } }
public JointBVH(int kCount) { wOrder = new string[19] { "XZY", "XZY", "XZY", "XZY", "XZY", "YZX", "ZYX", "YZX", "ZYX", "YZX", "ZYX", "YZX", "ZYX", "XZY", "XZY", "XYZ", "XZY", "XZY", "XYZ" }; mFrameMatrix = new Quaternion((float)0.5, (float)0.5, (float)0.5, (float)0.5); mOffsetMatrix = new Quaternion((float)0, (float)0, (float)0, (float)1); mJoints = new BVHJoint[19]; for (int iter = 0; iter < 19; iter++) { BVHJoint joint = readJoint(iter, kCount); mJoints[iter] = joint; } }
// Creates a GameObject representing a given BVHJoint and recursively creates GameObjects for it's child joints GameObject CreateJoint(BVHJoint joint, Vector3 parentPosition) { joint.gameObject = new GameObject(joint.name); GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); Vector3 scalingVec = (joint.name == "Head") ? new Vector3(8, 8, 8) : new Vector3(2, 2, 2); Matrix4x4 s = MatrixUtils.Scale(scalingVec); MatrixUtils.ApplyTransform(sphere, s); Matrix4x4 t = MatrixUtils.Translate(parentPosition + joint.offset); sphere.gameObject.transform.parent = joint.gameObject.transform; MatrixUtils.ApplyTransform(joint.gameObject, t); foreach (BVHJoint childJoint in joint.children) { GameObject createdChildJoint = CreateJoint(childJoint, joint.gameObject.transform.position); GameObject cylinder = CreateCylinderBetweenPoints(sphere.transform.position, createdChildJoint.transform.position, 1); cylinder.transform.parent = joint.gameObject.transform; } return(joint.gameObject); }
private Vector3 getFramePos(BVHJoint joint, int frame) { CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; var splitArr = Regex.Split(valStrings[frame].TrimStart().TrimEnd(), @"\s+"); var frameVals = convertOnTheFly ? Array.ConvertAll(splitArr, float.Parse) : vals[frame]; var framePos = Vector3.zero; for (int i = 0; i < joint.channels.Count; i++) { var c = joint.channels[i]; var v = frameVals[joint.id0 + i] / positionScale; var p = Vector3.zero; switch (c) { case BVHJoint.Channel.Xposition: p = new Vector3(-v, 0, 0); break; case BVHJoint.Channel.Yposition: p = new Vector3(0, v, 0); break; case BVHJoint.Channel.Zposition: p = new Vector3(0, 0, v); break; } framePos = framePos + p; } return(framePos); }
public void addChild(BVHJoint joint) { children.Add(joint); joint.parent = this; }