예제 #1
0
        /// <summary>
        /// Generates a global posture containing the list of joints with position and rotation in global space
        /// Required to pass on to the retargeting service.
        /// </summary>
        /// <returns></returns>
        public virtual MAvatarPosture GenerateGlobalPosture()
        {
            List <MJoint> Joints = new List <MJoint>();

            if (this.UseVirtualRoot)
            {
                Joints = new List <MJoint>()
                {
                    new MJoint("_VirtualRoot", MJointType.Root, this.RootTransform.position.ToMVector3(), this.RootTransform.rotation.ToMQuaternion())
                };
            }
            //Create a new posture
            MAvatarPosture globalPosture = new MAvatarPosture
            {
                AvatarID = this.AvatarID,
                Joints   = Joints
            };


            //Determine the joint values and write it into the posture
            this.Pelvis.GenerateGlobalJoints(this.bonenameMap, globalPosture.Joints);

            //Return the generated posture
            return(globalPosture);
        }
예제 #2
0
        /// <summary>
        /// Basic initialization methid
        /// </summary>
        /// <param name="avatarDescription"></param>
        /// <param name="properties"></param>
        /// <returns></returns>
        public override MBoolResponse Initialize(MAvatarDescription avatarDescription, Dictionary <string, string> properties)
        {
            //Execute instructions on main thread
            this.ExecuteOnMainThread(() =>
            {
                //Call the base class initialization -> Retargeting is also set up in there
                base.Initialize(avatarDescription, properties);

                this.MotionType = "idle";
                this.animator   = this.GetComponent <Animator>();

                //Set animation mode to always animate (even if not visible)
                this.animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
                this.animator.enabled     = false;
                this.Name = "UnityIdleMMU";


                //Get the initial posture
                this.animator.Update(0.01f);

                //Get the initial posture
                this.initialPosture = this.GetZeroPosture();
            });
            return(new MBoolResponse(true));
        }
예제 #3
0
        /// <summary>
        /// Retargets the global posture to the intermediate skeleton
        /// </summary>
        /// <param name="globalTarget"></param>
        /// <returns></returns>
        public MAvatarPostureValues RetargetToIntermediate(MAvatarPosture globalTarget)
        {
            RJoint root      = ((RJoint)this.skeleton.GetRoot(globalTarget.AvatarID));
            bool   rootFound = false;

            foreach (MJoint j in globalTarget.Joints)
            {
                if (j.Type != MJointType.Undefined)
                {
                    RJoint rj = ((RJoint)root.GetChild(j.Type));
                    rj.RetargetPositionToIS(j.Position, j.Rotation);
                    rj.RetargetRotationToIS(j.Rotation);

                    if (!rootFound)
                    {
                        rootFound = true;
                        if (j.Type == MJointType.Root)
                        {
                        }
                        else
                        {
                            MVector3 globalPos = rj.GetGlobalPosManually();
                            root.SetGlobalPosManually(new MVector3(globalPos.X, 0, globalPos.Z));
                            //rj.SetGlobalPosManually(new MVector3(0, globalPos.Y, 0));
                        }
                    }
                }
            }

            root.RecomputeLocalTransformations();
            MAvatarPostureValues ret = new MAvatarPostureValues(globalTarget.AvatarID, root.GetAvatarPostureValues());

            return(ret);
        }
예제 #4
0
        /// <summary>
        /// Method sets up the retargeting of the specified avaatar using an initial posture
        /// </summary>
        /// <param name="id"></param>
        /// <param name="reference"></param>
        /// <returns></returns>
        public virtual MAvatarPosture SetupRetargeting(string id, MAvatarPosture reference)
        {
            this.AvatarID = id;
            Animator anim = this.GetComponent <Animator>();

            this.animatorReference = anim;

            if (reference != null)
            {
                this.bonenameMap = new Dictionary <string, MJointType>();
                foreach (MJoint j in reference.Joints)
                {
                    if (!this.bonenameMap.ContainsKey(j.ID))
                    {
                        this.bonenameMap.Add(j.ID, j.Type);
                    }
                }
            }
            if (this.bonenameMap == null)
            {
                this.bonenameMap = new Dictionary <string, MJointType>();

                foreach (MJointType b in humanbonemap.Keys)
                {
                    bonenameMap.Add(anim.GetBoneTransform(humanbonemap[b]).name, b);
                }
            }

            MAvatarPosture p;

            if (reference != null)
            {
                retargetingService.SetupRetargeting(reference);
                skeleton = retargetingService.GetSkeleton();
                p        = reference;
            }
            else
            {
                p = this.GenerateGlobalPosture();
                retargetingService.SetupRetargeting(p);
                skeleton = retargetingService.GetSkeleton();
            }



            //Create an empty joint object if not defined
            if (this.gameJointPrefab == null)
            {
                this.gameJointPrefab = new GameObject("emptyJoint");
            }

            if (UseSkeletonVisualization)
            {
                skelVis = new SkeletonVisualization(skeleton, retargetingService, this.Pelvis, this.bonenameMap, this.AvatarID, gameJointPrefab);
            }

            this.AssignPostureValues(this.GetPosture());

            return(p);
        }
예제 #5
0
        /// <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));
        }
예제 #6
0
        public MAvatarDescription SetupRetargeting(MAvatarPosture globalTarget)
        {
            Console.WriteLine("\nSetting up retargeting");
            string id = globalTarget.AvatarID;
            Dictionary <MJointType, string> joint_map = new Dictionary <MJointType, string>();
            Dictionary <string, string>     _children = new Dictionary <string, string>();

            foreach (MJoint j in globalTarget.Joints)
            {
                if (j.Type != MJointType.Undefined)
                {
                    joint_map.Add(j.Type, j.ID);
                }
                if (j.Parent != null && j.Parent != "")
                {
                    if (_children.ContainsKey(j.Parent))
                    {
                        // parent has multiple children and thus cannot be auto - aligned
                        _children[j.Parent] = "";
                    }
                    else
                    {
                        _children.Add(j.Parent, j.ID);
                    }
                }
            }
            this.children.Add(id, _children);
            if (joint_mappings.ContainsKey(id))
            {
                Console.WriteLine("Warning: Skeleton alread existing under ID " + id);
                this.joint_mappings[id] = joint_map;
            }
            else
            {
                this.joint_mappings.Add(id, joint_map);
            }
            if (basePostures.ContainsKey(id))
            {
                this.basePostures[id] = globalTarget;
            }
            else
            {
                this.basePostures.Add(id, globalTarget);
            }
            MAvatarDescription desc = IntermediateSkeleton.GenerateFromDescriptionFile(id);

            this.skeleton.InitializeAnthropometry(desc);

            Console.WriteLine("Scaling Skeleton");
            ((RJoint)this.skeleton.GetRoot(id)).ScaleSkeleton(globalTarget, joint_map);
            Console.WriteLine("Initializing Zero Posture");
            this.skeleton.GetRoot(id).SetAvatarPostureValues(null);
            Console.WriteLine("Setting Base Reference");
            ((RJoint)this.skeleton.GetRoot(id)).SetBaseReference(globalTarget);


            Console.WriteLine("Retargeting Successfully set up");

            return(desc);
        }
예제 #7
0
        /// <summary>
        /// Method to setup the actual retargeting
        /// </summary>
        protected virtual void SetupRetargeting()
        {
            //Only do the retargeting setup if not happened in before
            if (!setupRetargeting)
            {
                setupRetargeting = true;
                // find and load retargeting configuration file
                //Create a unique id for the avatar (only valid in the current session -> otherwise UUID required)
                string id = UnitySceneAccess.CreateAvatarID();

                //Only load the configuration if defined
                if (LoadRetargetingConfiguration)
                {
                    if (!System.IO.File.Exists(Application.dataPath + "/" + this.ConfigurationFilePath))
                    {
                        Debug.LogError($"Problem setting up retargeting: The required file: {Application.dataPath + "/" + this.ConfigurationFilePath} is not available");
                        return;
                    }

                    string skelConf = System.IO.File.ReadAllText(Application.dataPath + "/" + this.ConfigurationFilePath);



                    MAvatarPosture p = MMICSharp.Common.Communication.Serialization.FromJsonString <MAvatarPosture>(skelConf);//JsonConvert.DeserializeObject<MAvatarPosture>(skelConf);
                    p.AvatarID = id;

                    this.SetupRetargeting(id, p);
                    this.AssignPostureValues(retargetingService.RetargetToIntermediate(p));
                }

                //If not defined use the global posture
                else
                {
                    this.SetupRetargeting(id);
                }

                MAvatarDescription avatarDescription = this.GetSkeletonAccess().GetAvatarDescription(id);

                //Create a new MAvatar (the representation within MMI framework)
                MAvatarPostureValues zeroPosture = this.GetSkeletonAccess().GetCurrentPostureValues(id);

                //Create the avatar
                this.MAvatar = new MAvatar()
                {
                    Name          = this.name,
                    ID            = id,
                    Description   = avatarDescription,
                    PostureValues = zeroPosture,
                    Properties    = new Dictionary <string, string>(),
                    SceneObjects  = new List <string>()
                };

                //Add the avatar to the scene access
                UnitySceneAccess.AddAvatar(this.MAvatar);

                Debug.Log("Retargeting successfully set up");
            }
        }
예제 #8
0
        /// <summary>
        /// Draws the given avatar posture
        /// </summary>
        /// <param name="posture"></param>
        /// <returns></returns>
        public static GameObject DrawAvatarPosture(MAvatarPosture posture)
        {
            GameObject root = new GameObject();

            Dictionary <string, GameObject> transforms = new Dictionary <string, GameObject>();

            if (posture == null || posture.Joints == null)
            {
                return(root);
            }

            foreach (MJoint boneTransform in posture.Joints)
            {
                //Create an empty gameobject for each bone
                GameObject joint = new GameObject(boneTransform.ID);
                joint.transform.position = boneTransform.Position.ToVector3();
                joint.transform.rotation = boneTransform.Rotation.ToQuaternion();

                transforms.Add(joint.name, joint);
            }


            foreach (MJoint boneTransform in posture.Joints)
            {
                GameObject joint = transforms[boneTransform.ID];

                //Compute the global position
                if (boneTransform.Parent != null && transforms.ContainsKey(boneTransform.Parent))
                {
                    joint.transform.position = transforms[boneTransform.Parent].transform.TransformPoint(joint.transform.position);
                    joint.transform.rotation = transforms[boneTransform.Parent].transform.rotation * joint.transform.rotation;

                    joint.transform.parent = transforms[boneTransform.Parent].transform;
                }
                else
                {
                    joint.transform.parent = root.transform;
                }
            }

            foreach (GameObject gameObject in transforms.Values)
            {
                if (gameObject.transform.parent != null && transforms.ContainsKey(gameObject.transform.parent.name))
                {
                    var lr = gameObject.AddComponent <LineRenderer>();
                    lr.material.shader = Shader.Find("Particles/Standard Surface");
                    lr.SetPositions(new Vector3[] { gameObject.transform.parent.position, gameObject.transform.position });
                    lr.startWidth = 0.02f;
                    lr.endWidth   = 0.02f;
                    lr.startColor = Color.red;
                    lr.endColor   = Color.blue;
                }
            }

            return(root);
        }
예제 #9
0
 public void SetBaseReference(MAvatarPosture posture)
 {
     foreach (MJoint j in posture.Joints)
     {
         if (j.Type != MJointType.Undefined)
         {
             RJoint rj = (RJoint)this.GetChild(j.Type);
             rj.SetBaseReference(j.Rotation, j.Position);
         }
     }
 }
예제 #10
0
        private MVector3 GetFingerPosition(MAvatarPosture globalTarget, Dictionary <MJointType, string> joint_map, double z_shift)
        {
            MVector3 wristPos = getJointPosition(globalTarget, joint_map[this.parentJoint.GetMJoint().Type]);//this.parentJoint.GetGlobalPosition();
            MVector3 thisPos  = getJointPosition(globalTarget, joint_map[this.GetMJoint().Type]);

            thisPos.Y = wristPos.Y; // adjust height
            MVector3 newPos = new MTransform("tmp", wristPos, this.parentJoint.GetGlobalRotation()).InverseTransformPoint(thisPos);

            newPos.Z -= z_shift;
            return(newPos);
        }
예제 #11
0
 private static MVector3 getJointPosition(MAvatarPosture globalTarget, string joint)
 {
     foreach (MJoint j in globalTarget.Joints)
     {
         if (j.ID == joint)
         {
             return(new MVector3(j.Position.X, j.Position.Y, j.Position.Z));
         }
     }
     return(new MVector3(0, 0, 0));
 }
예제 #12
0
        /// <summary>
        /// Applies the transform manipulations to be reflected in the intermediate skeleton
        /// </summary>
        public virtual void ApplyTransformManipulations()
        {
            //Update the intermediate skeleton with the new values

            //Get the global posture
            MAvatarPosture globalPosture = this.GenerateGlobalPosture();

            //Perform a retargeting to the intermediate skeleton
            MAvatarPostureValues intermediatePostureValues = retargetingService.RetargetToIntermediate(globalPosture);

            //Apply the posture values
            this.skeleton.SetChannelData(intermediatePostureValues);
        }
예제 #13
0
        /// <summary>
        /// Returns the retargeted posture represented in the intermediate skeleton used in the MMI framework
        /// </summary>
        /// <returns></returns>
        public MAvatarPostureValues GetRetargetedPosture()
        {
            // Return retargeted posture from target Avatar to intermediate skeleton.
            MAvatarPosture p = this.GenerateGlobalPosture();

            MAvatarPostureValues vals = this.retargetingService.RetargetToIntermediate(p);

            if (this.skelVis != null)
            {
                this.skelVis.AssignPostureValues();
            }

            return(vals);
        }
예제 #14
0
        /// <summary>
        /// Method sets up the retargeting of the specified avatar using the defined configuration file
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual MAvatarPosture SetupRetargeting(string id)
        {
            MAvatarPosture p = null;

            if (System.IO.File.Exists(this.ConfigurationFilePath))
            {
                string s = System.IO.File.ReadAllText(this.ConfigurationFilePath);

                p          = MMICSharp.Common.Communication.Serialization.FromJsonString <MAvatarPosture>(s); //JsonConvert.DeserializeObject<MAvatarPosture>(s);
                p.AvatarID = id;
            }

            return(this.SetupRetargeting(id, p));
        }
예제 #15
0
 private static MVector3 GetRelativePositionToParent(MAvatarPosture globalTarget, string joint, string parent)
 {
     foreach (MJoint j in globalTarget.Joints)
     {
         if (j.ID == joint)
         {
             foreach (MJoint jP in globalTarget.Joints)
             {
                 if (jP.ID == parent)
                 {
                     return(new MTransform("tmp", jP.Position, jP.Rotation).InverseTransformPoint(j.Position));
                 }
             }
         }
     }
     return(new MVector3(0, 0, 0));
 }
예제 #16
0
        /// <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();
            }
        }
예제 #17
0
        /// <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;
             */
        }
예제 #18
0
        /// <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);
        }
예제 #19
0
        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);
        }
예제 #20
0
        public void ScaleSkeleton(MAvatarPosture globalTarget, Dictionary <MJointType, string> joint_map)
        {
            List <MJointType> spine = new List <MJointType>()
            {
                MJointType.S1L5Joint, MJointType.T12L1Joint, MJointType.T1T2Joint, MJointType.C4C5Joint, MJointType.HeadJoint
            };

            if (spine.Contains(this.GetMJoint().Type))
            {
                //float shoulder_height = getJointPosition(HumanBodyBones.LeftUpperArm, anim).y;
                double shoulder_height = getJointPosition(globalTarget, joint_map[MJointType.HeadJoint]).Y;
                double hip_height      = getJointPosition(globalTarget, joint_map[MJointType.PelvisCentre]).Y;
                double spine_length    = shoulder_height - hip_height;


                ((RJoint)this.parentJoint).boneLength = (this.GetOffsetPositions()).Multiply(spine_length).Magnitude();
                this.GetOffsetPositions().X           = 0;
                this.GetOffsetPositions().Y           = 1.0;
                this.GetOffsetPositions().Z           = 0;
            }
            if (this.joint.Type == MJointType.Root)
            {
                //MVector3 rootPos = getJointPosition(globalTarget, joint_map[MJointType.Root]);
                //this.SetOffsets(rootPos);
            }
            else if (this.joint.Type == MJointType.PelvisCentre)
            {
                MVector3 hips      = getJointPosition(globalTarget, joint_map[MJointType.PelvisCentre]).Clone();
                MVector3 shoulder  = getJointPosition(globalTarget, joint_map[MJointType.LeftShoulder]);
                MVector3 leftupleg = getJointPosition(globalTarget, joint_map[MJointType.LeftHip]);

                // find the average z axis position of shoulders and hips to find initial position of hip
                hips.Z = (shoulder.Z + leftupleg.Z) / 2;
                // raise hip to the hight of the target avatars hip height.
                hips.Y = leftupleg.Y;
                MVector3 root = new MVector3(hips.X, 0, hips.Z);
                ((RJoint)this.parentJoint).SetOffsets(root);
                hips.X = 0;
                hips.Z = 0;
                this.SetOffsets(hips);
            }
            else
            {
                double factor = 0.0d;
                if (this.parentJoint.children.Count == 3 && this.parentJoint.children[0] != this)
                {
                    // If there are two children (e.g. pelvis / upper spine), take the half distance between both children
                    factor = GetJointDistance(globalTarget, joint_map[this.parentJoint.children[1].GetMJoint().Type], joint_map[this.parentJoint.children[2].GetMJoint().Type]) / 2.0d;
                }
                else
                {
                    // If there is one child, take the parent bone length to scale target position
                    factor = ((RJoint)this.parentJoint).boneLength;
                }
                // scale offset to scale the skeleton to match bone lengths.
                this.SetOffsets(this.GetOffsetPositions().Multiply(factor));


                // handle special cases for shoulders and hands
                string jointID = this.GetMJoint().ID;

                if (jointID.Contains("Shoulder"))
                {
                    // in case of shoulders, they have to be raised in up direction.
                    double shoulder_height = getJointPosition(globalTarget, joint_map[this.GetMJoint().Type]).Y;
                    double current_Pos     = this.GetShoulderHeight();
                    shoulder_height             = shoulder_height - current_Pos;
                    this.GetOffsetPositions().Y = shoulder_height;
                }
            }
            if (this.children.Count > 0 && this.children[0].GetMJoint().ID.Contains("Tip"))
            {
                // Finger Tips
                MVector3 offsetVector = this.children[0].GetOffsetPositions();
                this.boneLength = offsetVector.Magnitude();
            }
            else
            {
                // if this is not the last joint in a sequence, scale depending on distance to child human bone
                if (joint_map.ContainsKey(this.children[0].GetMJoint().Type) && joint_map.ContainsKey(this.GetMJoint().Type))
                {
                    this.boneLength = GetJointDistance(globalTarget, joint_map[this.GetMJoint().Type], joint_map[this.children[0].GetMJoint().Type]);
                }
                else
                {
                    this.boneLength = 0.1;
                }
            }

            // recurse
            foreach (Joint child in this.children)
            {
                if (!child.GetMJoint().ID.Contains("Tip"))
                {
                    ((RJoint)(child)).ScaleSkeleton(globalTarget, joint_map);
                }
            }

            if (this.GetMJoint().ID.Contains("Wrist"))
            {
                MVector3   wristPos = this.GetGlobalPosition();//getJointPosition(globalTarget, joint_map[this.GetMJoint().Type]);
                MTransform Twrist   = new MTransform("tmp", this.GetGlobalPosition(), this.GetGlobalRotation());
                Joint      middle   = this.children[0];

                Joint index  = this.children[1];
                Joint ring   = this.children[2];
                Joint little = this.children[3];
                Joint thumb  = this.children[4];

                double middle_shift = 0.0;
                if (joint_map.ContainsKey(middle.GetMJoint().Type))
                {
                    MVector3 MiddlePos = ((RJoint)middle).GetFingerPosition(globalTarget, joint_map, 0);
                    middle_shift = MiddlePos.Z;
                    MiddlePos.Z  = 0;
                    ((RJoint)this.children[0]).SetOffsets(MiddlePos);
                }
                else
                {
                    ((RJoint)this.children[0]).SetOffsets(new MVector3(0, 0.1, 0));
                }

                if (joint_map.ContainsKey(index.GetMJoint().Type))
                {
                    MVector3 IndexPos = ((RJoint)index).GetFingerPosition(globalTarget, joint_map, middle_shift);
                    ((RJoint)this.children[1]).SetOffsets(IndexPos);
                }
                else
                {
                    ((RJoint)this.children[1]).SetOffsets(new MVector3(0, 0.1, 0.02));
                }

                if (joint_map.ContainsKey(ring.GetMJoint().Type))
                {
                    MVector3 RingPos = ((RJoint)ring).GetFingerPosition(globalTarget, joint_map, middle_shift);
                    ((RJoint)this.children[2]).SetOffsets(RingPos);
                }
                else
                {
                    ((RJoint)this.children[2]).SetOffsets(new MVector3(0, 0.1, -0.02));
                }
                if (joint_map.ContainsKey(little.GetMJoint().Type))
                {
                    MVector3 LittlePos = ((RJoint)little).GetFingerPosition(globalTarget, joint_map, middle_shift);
                    ((RJoint)this.children[3]).SetOffsets(LittlePos);
                }
                else
                {
                    ((RJoint)this.children[3]).SetOffsets(new MVector3(0, 0.1, -0.04));
                }

                if (joint_map.ContainsKey(thumb.GetMJoint().Type))
                {
                    MVector3 ThumbPos = ((RJoint)thumb).GetFingerPosition(globalTarget, joint_map, middle_shift);
                    ((RJoint)this.children[4]).SetOffsets(ThumbPos);
                }
                else
                {
                    ((RJoint)this.children[4]).SetOffsets(new MVector3(0, 0.02, 0.02));
                }
            }
        }
예제 #21
0
 private static double GetJointDistance(MAvatarPosture globalTarget, string joint1, string joint2)
 {
     return(getJointPosition(globalTarget, joint1).Subtract(getJointPosition(globalTarget, joint2)).Magnitude());
 }