/// <summary> /// Performs a blending based on the from posture and the to posture. In particular a blending weight and an additional blending mask is utilized. If the blending mask is set to null, all bones with position + rotation will be used for blending. /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="weight"></param> /// <param name="blendingMask"></param> /// <returns></returns> public static MAvatarPostureValues PerformBlend(IntermediateSkeleton skeleton, MAvatarPostureValues from, MAvatarPostureValues to, float weight, Dictionary <MJointType, BlendProperty> blendingMask = null) { //MAvatarPosture result = from.Clone(); MAvatarPosture zero = skeleton.GetAvatarDescription(from.AvatarID).ZeroPosture; skeleton.SetChannelData(from); List <MQuaternion> fromRot = skeleton.GetLocalJointRotations(from.AvatarID); skeleton.SetChannelData(to); List <MQuaternion> toRot = skeleton.GetLocalJointRotations(to.AvatarID); for (int i = 0; i < zero.Joints.Count; i++) { //By default belnd both position and rotation BlendProperty blendProperty = new BlendProperty(1.0f, 1.0f); MJointType joint = zero.Joints[i].Type; if (blendingMask != null && blendingMask.ContainsKey(joint)) { //Get the bone weight blendingMask.TryGetValue(joint, out blendProperty); } //Perform a linear interpolation of the position // Does not correspond to intermediate skeleton representation. // result.Joints[i].Position = result.Joints[i].Position.Lerp(to.Joints[i].Position, weight * blendProperty.PositionWeight); //Perform a slerp of the rotation skeleton.SetLocalJointRotation(to.AvatarID, joint, fromRot[i].Slerp(toRot[i], weight * blendProperty.RotationWeight)); } return(skeleton.RecomputeCurrentPostureValues(to.AvatarID)); }
/// <summary> /// Performs a blending based on the from posture and the to posture. /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="weight"></param> /// <param name="rootTransform">Specifies whether the root transform is blended as well</param> /// <returns></returns> public static MAvatarPostureValues PerformBlend(IntermediateSkeleton skeleton, MAvatarPostureValues from, MAvatarPostureValues to, float weight, bool rootTransform = true) { MAvatarPosture zero = skeleton.GetAvatarDescription(from.AvatarID).ZeroPosture; skeleton.SetChannelData(from); List <MQuaternion> fromRot = skeleton.GetLocalJointRotations(from.AvatarID); skeleton.SetChannelData(to); List <MQuaternion> toRot = skeleton.GetLocalJointRotations(to.AvatarID); for (int i = 0; i < zero.Joints.Count; i++) { //By default belnd both position and rotation MJointType joint = zero.Joints[i].Type; //Perform a linear interpolation of the position // Does not correspond to intermediate skeleton representation. // result.Joints[i].Position = result.Joints[i].Position.Lerp(to.Joints[i].Position, weight * blendProperty.PositionWeight); //Perform a slerp of the rotation skeleton.SetLocalJointRotation(to.AvatarID, joint, fromRot[i].Slerp(toRot[i], weight)); } return(skeleton.RecomputeCurrentPostureValues(to.AvatarID)); /* * MAvatarPosture result = from.Clone(); * * for (int i = 0; i < result.Joints.Count; i++) * { * //Skip if root transform should be ignored * if (i == 0 && rootTransform) * result.Joints[i].Position = result.Joints[i].Position.Lerp(to.Joints[i].Position, weight); * * //Perform a slerp of the rotation * result.Joints[i].Rotation = result.Joints[i].Rotation.Slerp(to.Joints[i].Rotation, weight); * } * * return result; */ }
/// <summary> /// Assigns the pose to the avatar. /// </summary> /// <param name="pose"></param> /// <param name="assignLocalPositions">Specifies whether the local positions are assigned as well</param> public virtual void AssignPostureValues(MAvatarPostureValues pose, bool assignLocalPositions = true) { //Perform a retargeting to the specific skeleton using the retargeting service MAvatarPosture p = this.retargetingService.RetargetToTarget(pose); //Update the values of the skeletal representation skeleton.SetChannelData(pose); //Compute the root transformation if defined /* * if (this.AutoComputeRootTransform) * { * MVector3 globalRootBonePosition = skeleton.GetRootPosition(this.AvatarID); * MQuaternion globalRootBoneRotation = skeleton.GetRootRotation(this.AvatarID); * * * //Compute the root transform * this.RootTransform.position = new Vector3((float)globalRootBonePosition.X, this.RootTransform.position.y, (float)globalRootBonePosition.Z); * //this.RootBone.transform.position = globalRootBonePosition.ToVector3(); * * * Vector3 currentEulerRoot = this.RootTransform.eulerAngles; * this.RootTransform.rotation = Quaternion.Euler(currentEulerRoot.x, globalRootBoneRotation.ToQuaternion().eulerAngles.y - 90.0f, currentEulerRoot.z); * //this.RootBone.transform.rotation = globalRootBoneRotation.ToQuaternion(); * * MTransform CharTransform = new MTransform("tmp", this.RootTransform.position.ToMVector3(), this.RootTransform.rotation.ToMQuaternion()); * } */ // Update root transform this.RootTransform.transform.position = p.Joints[0].Position.ToVector3(); this.RootTransform.transform.rotation = p.Joints[0].Rotation.ToQuaternion(); //Update the transforms/visualization by applying the global transformations this.Pelvis.ApplyGlobalJoints(p.Joints); //Update the skeleton visualization if enabled if (this.skelVis != null) { this.skelVis.root.ApplyPostureValues(); } }
public void TestRootPosition() { MAvatarDescription desc = IntermediateSkeleton.GenerateFromDescriptionFile("TestAvatar"); IntermediateSkeleton skeleton = new IntermediateSkeleton(); skeleton.InitializeAnthropometry(desc); List <double> rotationValues = new List <double>() { 0, 0, 0, 0.86041, -0.01303, 0.50383, 0.07533, //S1L5 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, // T12L12 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, // T1T2 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, //C4C5 0.00000, 0.00000, 0.00000, 0.98890, 0.04908, -0.13945, -0.01508, // Head 0.00000, 0.00000, 0.00000, 0.74914, -0.35251, 0.02895, 0.56007, // LeftShoulder 0.98560, 0.11136, -0.00962, 0.12689, // Left ELbow 0.96542, -0.01250, 0.25953, 0.02139, // Left Wrist 0.00000, 0.00000, 0.00000, 0.74411, 0.10420, 0.26279, -0.60530, 0.95158, 0.28073, 0.07735, -0.09850, // Right Elbow 0.99256, -0.00379, 0.11897, -0.02548, // right wrist 0.94999, -0.28306, 0.12805, 0.03154, // Left hip 0.97503, 0.22205, 0.00000, -0.00001, // Knee 0.99439, -0.07404, 0.06580, 0.03709, // Ankle 1.00000, 0.00000, 0.00000, 0.00000, // Toes 0.99694, 0.07053, -0.02371, 0.02406, // Right Hip 0.91716, 0.39852, 0.00000, 0.00000, // Knee 0.99076, -0.12976, 0.02501, 0.03048, // Ankle 1.00000, 0.00000, 0.00000, 0.00000 }; // Toes MAvatarPostureValues values = new MAvatarPostureValues(desc.AvatarID, rotationValues); skeleton.SetChannelData(values); MVector3 pos = skeleton.GetGlobalJointPosition(desc.AvatarID, MJointType.S1L5Joint); MVector3 gt = skeleton.GetRoot(desc.AvatarID).GetMJoint().Position; gt = new MVector3(gt.X + rotationValues[0], gt.Y + rotationValues[1], gt.Z + rotationValues[2]); System.Console.WriteLine("pos: {0}, {1}, {2}", pos.X, pos.Y, pos.Z); System.Console.WriteLine("gt: {0}, {1}, {2}", gt.X, gt.Y, gt.Z); Assert.IsTrue(System.Math.Abs(pos.X - gt.X) < 0.001); Assert.IsTrue(System.Math.Abs(pos.Y - gt.Y) < 0.001); Assert.IsTrue(System.Math.Abs(pos.Z - gt.Z) < 0.001); }