// the following functions can be used to parse MAvatarDescriptions from a bvh-like file. These functions // are currently not maintained and might be outdated. #region parsing of MAvatarPosture files private static MJoint ParseJoint(string[] mos, ref int line_counter, ref List <MJoint> mjointList) { // parse lines for current joint // Todo: Improve parser to consider empty lines and comments string name = mos[line_counter].Split(' ')[1]; float[] off = parseFloatParameter(mos[line_counter + 2].Split(' '), 3); MVector3 offset = new MVector3(off[0], off[1], off[2]); float[] quat = parseFloatParameter(mos[line_counter + 3].Split(' '), 4); MQuaternion rotation = new MQuaternion(quat[1], quat[2], quat[3], quat[0]); string[] channels = mos[line_counter + 4].Replace("CHANNELS", "").Split(' '); List <MChannel> mchannels = MapChannels(channels); MJoint mjoint = new MJoint(name, MJointTypeMap[name], offset, rotation); mjoint.Channels = mchannels; mjointList.Add(mjoint); line_counter += 5; while (!mos[line_counter].Contains("}")) { MJoint child = ParseJoint(mos, ref line_counter, ref mjointList); child.Parent = mjoint.ID; } line_counter += 1; return(mjoint); }
/// <summary> /// Creates an MJOint based on the given transform /// </summary> /// <param name="transform"></param> /// <param name="useGlobalPosition"></param> /// <returns></returns> public static MJoint ToJointTransform(this Transform transform, bool useGlobalPosition = false) { ///Create a new joint transform MJoint jointTransform = new MJoint { ID = transform.name, Type = MJointType.Undefined }; if (useGlobalPosition) { jointTransform.Position = transform.position.ToMVector3(); jointTransform.Rotation = transform.rotation.ToMQuaternion(); } else { jointTransform.Position = transform.localPosition.ToMVector3(); jointTransform.Rotation = transform.localRotation.ToMQuaternion(); } if (transform.parent != null) { jointTransform.Parent = transform.parent.name; } return(jointTransform); }
/// <summary> /// Generates a list of joints with global coordinates /// </summary> /// <param name="t"></param> /// <param name="map"></param> /// <param name="list"></param> public static void GenerateGlobalJoints(this Transform t, Dictionary <string, MJointType> map, List <MJoint> list) { if (t.name.Contains("vis123bone")) { return; } //Create a new joint MJoint j = new MJoint { ID = t.name }; if (map != null && map.ContainsKey(t.name)) { j.Type = map[t.name]; } else { j.Type = MJointType.Undefined; } j.Position = t.position.ToMVector3(); j.Rotation = t.rotation.ToMQuaternion(); j.Parent = t.parent != null ? t.parent.name : null; list.Add(j); for (int i = 0; i < t.childCount; i++) { t.GetChild(i).GenerateGlobalJoints(map, list); } }
private static MJoint NewMJoint(string id, MJointType type, MVector3 offset, MQuaternion rotation, string parentID, List <MChannel> channels) { MJoint j = new MJoint(id, type, offset, rotation); j.Parent = parentID; j.Channels = channels; return(j); }
/// <summary> /// Returns an interaction pose representing the current hand transform /// To do return root Bone as global coordinates /// </summary> /// <returns></returns> public MHandPose GetPose() { //Create a new hand pose MHandPose handPose = new MHandPose { Joints = new List <MJoint>() }; //Get all bones in hierarchy UnityBone[] bones = this.GetComponentsInChildren <UnityBone>(); int depth = 0; foreach (UnityBone bone in bones) { //Add the first bone in global space if (depth == 0) { handPose.Joints.Add(new MJoint(bone.ID, bone.Type, bone.transform.position.ToMVector3(), bone.transform.rotation.ToMQuaternion())); } //Add all other using the local space else { MJoint mjoint = new MJoint(bone.ID, bone.Type, bone.transform.localPosition.ToMVector3(), bone.transform.localRotation.ToMQuaternion()); if (bone.transform.parent != null) { var parentBone = bone.transform.parent.GetComponent <UnityBone>(); if (parentBone != null) { mjoint.Parent = parentBone.ID; } } handPose.Joints.Add(mjoint); } depth++; } //Use the handpose directly if (bones.Length == 0) { handPose.Joints.Add(new MJoint(Guid.NewGuid().ToString(), this.HandType == HandType.Left ? MJointType.LeftWrist : MJointType.RightWrist, this.transform.GetLocalPositionScaleIndependent().ToMVector3(), this.transform.localRotation.ToMQuaternion())); } //To do return(handPose); }
public void TestSkeletonGeneration() { MAvatarDescription desc = IntermediateSkeleton.GenerateFromDescriptionFile("TestAvatar"); Assert.AreEqual(desc.AvatarID, "TestAvatar"); Assert.AreEqual(desc.ZeroPosture.Joints.Count, 19); IntermediateSkeleton skeleton = new IntermediateSkeleton(); skeleton.InitializeAnthropometry(desc); Assert.AreEqual(desc, skeleton.GetAvatarDescription(desc.AvatarID)); string[] jointnames = new string[] { "S1L5Joint", "T12L12Joint", "T1T2Joint", "C4C5Joint", "HeadJoint", "LeftShoulder", "LeftElbow", "LeftWrist", "RightShoulder", "RightElbow", "RightWrist", "LeftHip", "LeftKnee", "LeftAnkle", "LeftBall", "RightHip", "RightKnee", "RightAnkle", "RightBall" }; for (int i = 0; i < desc.ZeroPosture.Joints.Count; i++) { MJoint joint = desc.ZeroPosture.Joints[i]; Assert.AreEqual(joint.ID.ToString(), jointnames[i]); } }
/// <summary> /// Returns the current posture of the avatarID in a global MAvatarPosture representation. /// (Each joint contains translation and rotation in global coordinate system) /// </summary> /// <param name="avatarID"></param> /// <returns></returns> public MAvatarPosture GetCurrentGlobalPosture(string avatarID) { MAvatarPosture globalPosture = new MAvatarPosture { AvatarID = avatarID, Joints = new List <MJoint>() }; if (this.hierarchies.ContainsKey(avatarID)) { MAvatarPosture zeroPosture = this.avatarDescriptions[avatarID].ZeroPosture; foreach (MJoint j in zeroPosture.Joints) { Joint refJoint = this.hierarchies[avatarID].GetChild(j.Type); MJoint globalJoint = new MJoint(j.ID, j.Type, refJoint.GetGlobalPosition(), refJoint.GetGlobalRotation()); globalPosture.Joints.Add(globalJoint); } } return(globalPosture); }
/// <summary> /// Generates a list of joints with global coordinates /// </summary> /// <param name="t"></param> /// <param name="map"></param> /// <param name="list"></param> public static void GenerateLocalJoints(this Transform t, Transform rootJoint, Dictionary <string, MJointType> map, List <MJoint> list) { if (t.name.Contains("vis123bone")) { return; } //Create a new joint MJoint j = new MJoint { ID = t.name }; if (map != null && map.ContainsKey(t.name)) { j.Type = map[t.name]; } else { j.Type = MJointType.Undefined; } //Only use the global coordinates for the root joint if (t == rootJoint) { j.Position = t.position.ToMVector3(); j.Rotation = t.rotation.ToMQuaternion(); } else { j.Position = t.localPosition.ToMVector3(); j.Rotation = t.localRotation.ToMQuaternion(); } list.Add(j); for (int i = 0; i < t.childCount; i++) { t.GetChild(i).GenerateGlobalJoints(map, list); } }
public Joint(MJoint j) { this.joint = j; }
public RJoint(MJoint j) : base(j) { }
public MAvatarPosture RetargetToTarget(MAvatarPostureValues intermediatePostureValues) { string id = intermediatePostureValues.AvatarID; RJoint root = ((RJoint)this.skeleton.GetRoot(id)); root.SetAvatarPostureValues(intermediatePostureValues); MAvatarPosture targetOut = new MAvatarPosture(); targetOut.AvatarID = id; targetOut.Joints = new List <MJoint>(); foreach (MJoint j in this.basePostures[id].Joints) { MJoint outJ = new MJoint(); outJ.ID = j.ID; outJ.Type = j.Type; outJ.Parent = j.Parent; if (outJ.Type != MJointType.Undefined) { RJoint rj = (RJoint)root.GetChild(j.Type); outJ.Position = (rj).RetargetPositionToTarget(); outJ.Rotation = (rj).RetargetRotationToTarget(); } else { outJ.Position = j.Position; outJ.Rotation = j.Rotation; } targetOut.Joints.Add(outJ); } Dictionary <string, string> _children = this.children[id]; for (int i = 0; i < targetOut.Joints.Count; i++) { MJoint outJ = targetOut.Joints[i]; if (outJ.Type == MJointType.Undefined) { bool setRot = false; bool setPos = false; Console.WriteLine("no jointtype " + outJ.ID); if (i == 0) { // find first joint that is mapped foreach (MJoint j in targetOut.Joints) { if (j.Type != MJointType.Undefined) { outJ.Position = new MVector3(j.Position.X, 0, j.Position.Z); //j.Position.X = 0; //j.Position.Z = 0; MVector3 forward = outJ.Rotation.Multiply(new MVector3(0, 0, 1)); forward.Y = 0; forward.Normalize(); MVector3 currentForward = j.Rotation.Multiply(new MVector3(0, 0, 1)); MQuaternion drot = MVector3Extensions.FromToRotation(currentForward, forward); outJ.Rotation = drot.Multiply(j.Rotation); //outJ.Rotation = MQuaternionExtensions.Inverse(drot).Multiply(outJ.Rotation); setPos = true; setRot = true; break; } } } else { /* * This is disabled for now, as it was not working propperly. * * if(_children.ContainsKey(outJ.ID) && _children[outJ.ID] != "") * { * for(int jID = i+1; jID < targetOut.Joints.Count; jID ++) * { * MJoint j = targetOut.Joints[jID]; * if (j.ID == _children[outJ.ID]) * { * * MVector3 srcDir = new MVector3(0, 1, 0);//outJ.Rotation.Multiply(new MVector3(0, 1, 0)).Normalize * MVector3 trgDir = null; * MQuaternion parentRot = null; * if(outJ.Parent != null) * { * for(int pID = i-1; pID > 0; pID--) * { * if(targetOut.Joints[pID].ID == outJ.Parent) * { * if(targetOut.Joints[pID].Type != MJointType.Undefined) * { * parentRot = targetOut.Joints[pID].Rotation; * trgDir = MQuaternionExtensions.Inverse(parentRot).Multiply(j.Position.Subtract(outJ.Position).Normalize()); * } * } * } * } * if(trgDir != null) * { * MQuaternion rot = MVector3Extensions.FromToRotation(srcDir, trgDir); * outJ.Rotation = parentRot.Multiply(rot); * outJ.Position = null; * setRot = true; * break; * * } * * * } * } * }*/ } if (!setRot) { outJ.Rotation = null; } if (!setPos) { outJ.Position = null; } } } return(targetOut); }