예제 #1
0
        public MQuaternion RetargetRotationToIS(MQuaternion globalRot)
        {
            MQuaternion rot = globalRot.Multiply(this.invTargetGBR).Multiply(this.isGBR);

            this.globalRot = rot;
            return(rot);
        }
예제 #2
0
        public MQuaternion RetargetRotationToTarget()
        {
            MQuaternion globalRot = this.GetGlobalRotation();
            MQuaternion rot       = globalRot.Multiply(this.invIsGBR).Multiply(this.targetGBR);

            return(rot);
        }
예제 #3
0
        public MVector3 RetargetPositionToIS(MVector3 globalPos, MQuaternion globalRot)
        {
            MVector3 pos = globalPos.Add(globalRot.Multiply(this.targetOffset));

            this.globalPos = pos;
            return(pos);
        }
예제 #4
0
        public MVector3 GetGlobalPosition()
        {
            if (this.globalPos == null)
            {
                MQuaternion parentRotation = new MQuaternion(0, 0, 0, 1);
                MVector3    parentPosition = new MVector3(0, 0, 0);
                if (this.parentJoint != null)
                {
                    parentRotation = this.parentJoint.globalRot;
                    parentPosition = this.parentJoint.globalPos;
                }


                MVector3 rotatedOffset      = parentRotation.Multiply(this.joint.Position);
                MVector3 rotatedTranslation = parentRotation.Multiply(this.joint.Rotation).Multiply(this.translation);

                this.globalPos = rotatedTranslation.Add(rotatedOffset).Add(parentPosition);
            }
            return(this.globalPos);
        }
예제 #5
0
        public MQuaternion GetGlobalRotation()
        {
            if (this.globalRot == null)
            {
                MQuaternion parentRotation = new MQuaternion(0, 0, 0, 1);
                MVector3    parentPosition = new MVector3(0, 0, 0);
                if (this.parentJoint != null)
                {
                    parentRotation = this.parentJoint.globalRot;
                    parentPosition = this.parentJoint.globalPos;
                }

                this.globalRot = parentRotation.Multiply(this.joint.Rotation).Multiply(this.currentRotationValues);
            }


            return(this.globalRot);
        }
예제 #6
0
        public void RecomputeLocalTransformations()
        {
            MQuaternion parentRotation = new MQuaternion(0, 0, 0, 1);
            MVector3    parentPosition = new MVector3(0, 0, 0);

            if (this.parentJoint != null)
            {
                parentRotation = this.parentJoint.GetGlobalRotation();
                parentPosition = this.parentJoint.GetGlobalPosition();
            }
            MQuaternion inverseParentRot = MQuaternionExtensions.Inverse(parentRotation);

            if (!isMapped && this.parentJoint == null)
            {
                this.currentRotationValues = new MQuaternion(0, 0, 0, 1);
                this.translation           = this.globalPos;
            }
            else if (isMapped)
            {
                this.currentRotationValues = this.inverseOffsetRotation.Multiply(inverseParentRot).Multiply(this.globalRot);

                MVector3 rotatedOffset      = parentRotation.Multiply(this.joint.Position);
                MVector3 rotatedTranslation = this.globalPos.Subtract(parentPosition).Subtract(rotatedOffset);
                this.translation = this.inverseOffsetRotation.Multiply(inverseParentRot).Multiply(rotatedTranslation);
            }
            else
            {
                this.currentRotationValues = new MQuaternion(0, 0, 0, 1);
                this.translation           = new MVector3(0, 0, 0);
                this.globalPos             = null;
                this.globalRot             = null;
                this.GetGlobalPosition();
                this.GetGlobalRotation();
            }

            foreach (Joint c in this.children)
            {
                ((RJoint)c).RecomputeLocalTransformations();
            }
        }
예제 #7
0
        /// <summary>
        /// Rotates the current transform around the specific point and axis
        /// </summary>
        /// <param name="center">The rotation center</param>
        /// <param name="axis">The rotation axis</param>
        /// <param name="angle">The angle to rotate</param>
        private static MTransform RotateAround(MTransform transform, MVector3 center, MVector3 axis, float angle)
        {
            MTransform res = new MTransform()
            {
                ID = System.Guid.NewGuid().ToString()
            };

            MVector3 pos = transform.Position;

            MQuaternion rot = MQuaternionExtensions.FromEuler(axis.Multiply(angle)); // get the desired rotation
            MVector3    dir = pos.Subtract(center);                                  // find current direction relative to center

            dir = rot.Multiply(dir);                                                 // rotate the direction

            res.Position = center.Add(dir);                                          // define new position
            MQuaternion myRot = transform.Rotation;

            res.Rotation = transform.Rotation.Multiply(MQuaternionExtensions.Inverse(myRot).Multiply(rot).Multiply(myRot));


            return(res);
        }
예제 #8
0
        public static List <MJoint> GetDefaultJointList()
        {
            List <MJoint> defaultJoints = new List <MJoint>()
            {
                // 7 joints along the spine (6 animated, 39 channels)
                NewMJoint("Root", MJointType.Root, new MVector3(0, 0, 0), identityQ, null, defaultRootChannels),
                NewMJoint("PelvisCenter", MJointType.PelvisCentre, new MVector3(0, 0, 0), qRotY90, "Root", defaultRootChannels),
                NewMJoint("S1L5Joint", MJointType.S1L5Joint, new MVector3(0, 0.18, 0), identityQ, "PelvisCenter", defaultRootChannels),
                NewMJoint("T12L1Joint", MJointType.T12L1Joint, new MVector3(0, 0.15, 0), identityQ, "S1L5Joint", defaultRootChannels), // 0.33 - 0.18
                NewMJoint("T1T2Joint", MJointType.T1T2Joint, new MVector3(0, 0.43, 0), identityQ, "T12L1Joint", defaultRootChannels),  // 0.76 - 0.33
                NewMJoint("C4C5Joint", MJointType.C4C5Joint, new MVector3(0, 0.11, 0), identityQ, "T1T2Joint", defaultRootChannels),   // 0.87 - 0.76
                NewMJoint("HeadJoint", MJointType.HeadJoint, new MVector3(0, 0.13, 0), qRotYM180, "C4C5Joint", defaultJointChannels),  // 1.0 - 0.87
                NewMJoint("HeadTip", MJointType.HeadTip, new MVector3(0, 0.16, 0), identityQ, "HeadJoint", zeroChannels),


                // Left Arm: 3 joints (3 animated, 15 channels)
                NewMJoint("LeftShoulder", MJointType.LeftShoulder, new MVector3(0, 0, -1), qRotXM90.Multiply(qRotYM90), "T1T2Joint", defaultRootChannels),
                NewMJoint("LeftElbow", MJointType.LeftElbow, new MVector3(0, 1, 0), qRotY90, "LeftShoulder", defaultJointChannels),
                NewMJoint("LeftWrist", MJointType.LeftWrist, new MVector3(0, 1, 0), qRotY90, "LeftElbow", defaultJointChannels),

                //left hand: 20 joints (16 animated, 75 channels)
                NewMJoint("LeftMiddleProximal", MJointType.LeftMiddleProximal, new MVector3(0, 1, 0), identityQ, "LeftWrist", defaultRootChannels),
                NewMJoint("LeftMiddleMeta", MJointType.LeftMiddleMeta, new MVector3(0, 1, 0), identityQ, "LeftMiddleProximal", defaultJointChannels),
                NewMJoint("LeftMiddleDistal", MJointType.LeftMiddleDistal, new MVector3(0, 1, 0), identityQ, "LeftMiddleMeta", defaultJointChannels),
                NewMJoint("LeftMiddleTip", MJointType.LeftMiddleTip, new MVector3(0, 0.03, 0), identityQ, "LeftMiddleDistal", zeroChannels),

                NewMJoint("LeftIndexProximal", MJointType.LeftIndexProximal, new MVector3(0, 1, 0), identityQ, "LeftWrist", defaultRootChannels),
                NewMJoint("LeftIndexMeta", MJointType.LeftIndexMeta, new MVector3(0, 1, 0), identityQ, "LeftIndexProximal", defaultJointChannels),
                NewMJoint("LeftIndexDistal", MJointType.LeftIndexDistal, new MVector3(0, 1, 0), identityQ, "LeftIndexMeta", defaultJointChannels),
                NewMJoint("LeftIndexTip", MJointType.LeftIndexTip, new MVector3(0, 0.03, 0), identityQ, "LeftIndexDistal", zeroChannels),

                NewMJoint("LeftRingProximal", MJointType.LeftRingProximal, new MVector3(0, 1, 0), identityQ, "LeftWrist", defaultRootChannels),
                NewMJoint("LeftRingMeta", MJointType.LeftRingMeta, new MVector3(0, 1, 0), identityQ, "LeftRingProximal", defaultJointChannels),
                NewMJoint("LeftRingDistal", MJointType.LeftRingDistal, new MVector3(0, 1, 0), identityQ, "LeftRingMeta", defaultJointChannels),
                NewMJoint("LeftRingTip", MJointType.LeftRingTip, new MVector3(0, 0.03, 0), identityQ, "LeftRingDistal", zeroChannels),

                NewMJoint("LeftLittleProximal", MJointType.LeftLittleProximal, new MVector3(0, 1, 0), identityQ, "LeftWrist", defaultRootChannels),
                NewMJoint("LeftLittleMeta", MJointType.LeftLittleMeta, new MVector3(0, 1, 0), identityQ, "LeftLittleProximal", defaultJointChannels),
                NewMJoint("LeftLittleDistal", MJointType.LeftLittleDistal, new MVector3(0, 1, 0), identityQ, "LeftLittleMeta", defaultJointChannels),
                NewMJoint("LeftLittleTip", MJointType.LeftLittleTip, new MVector3(0, 0.03, 0), identityQ, "LeftLittleDistal", zeroChannels),

                NewMJoint("LeftThumbMid", MJointType.LeftThumbMid, new MVector3(0, 1, 0), new MQuaternion(-0.3826834559440613, 0, 0, 0.9238795042037964), "LeftWrist", defaultRootChannels),//0.53730, 0, 0, 0.84339
                NewMJoint("LeftThumbMeta", MJointType.LeftThumbMeta, new MVector3(0, 1, 0), identityQ, "LeftThumbMid", defaultJointChannels),
                NewMJoint("LeftThumbCarpal", MJointType.LeftThumbCarpal, new MVector3(0, 1, 0), identityQ, "LeftThumbMeta", defaultJointChannels),
                NewMJoint("LeftThumbTip", MJointType.LeftThumbTip, new MVector3(0, 0.03, 0), identityQ, "LeftThumbCarpal", zeroChannels),


                // Right Arm: 3 joints (3 animated, 15 channels)
                NewMJoint("RightShoulder", MJointType.RightShoulder, new MVector3(0, 0, 1), qRotX90.Multiply(qRotY90), "T1T2Joint", defaultRootChannels),
                NewMJoint("RightElbow", MJointType.RightElbow, new MVector3(0, 1, 0), qRotYM90, "RightShoulder", defaultJointChannels),
                NewMJoint("RightWrist", MJointType.RightWrist, new MVector3(0, 1, 0), qRotYM90, "RightElbow", defaultJointChannels),

                //left hand: 20 joints (16 animated, 75 channels)
                NewMJoint("RightMiddleProximal", MJointType.RightMiddleProximal, new MVector3(0, 1, 0), identityQ, "RightWrist", defaultRootChannels),
                NewMJoint("RightMiddleMeta", MJointType.RightMiddleMeta, new MVector3(0, 1, 0), identityQ, "RightMiddleProximal", defaultJointChannels),
                NewMJoint("RightMiddleDistal", MJointType.RightMiddleDistal, new MVector3(0, 1, 0), identityQ, "RightMiddleMeta", defaultJointChannels),
                NewMJoint("RightMiddleTip", MJointType.RightMiddleTip, new MVector3(0, 0.03, 0), identityQ, "RightMiddleDistal", zeroChannels),

                NewMJoint("RightIndexProximal", MJointType.RightIndexProximal, new MVector3(0, 1, 0), identityQ, "RightWrist", defaultRootChannels),
                NewMJoint("RightIndexMeta", MJointType.RightIndexMeta, new MVector3(0, 1, 0), identityQ, "RightIndexProximal", defaultJointChannels),
                NewMJoint("RightIndexDistal", MJointType.RightIndexDistal, new MVector3(0, 1, 0), identityQ, "RightIndexMeta", defaultJointChannels),
                NewMJoint("RightIndexTip", MJointType.RightIndexTip, new MVector3(0, 0.03, 0), identityQ, "RightIndexDistal", zeroChannels),

                NewMJoint("RightRingProximal", MJointType.RightRingProximal, new MVector3(0, 1, 0), identityQ, "RightWrist", defaultRootChannels),
                NewMJoint("RightRingMeta", MJointType.RightRingMeta, new MVector3(0, 1, 0), identityQ, "RightRingProximal", defaultJointChannels),
                NewMJoint("RightRingDistal", MJointType.RightRingDistal, new MVector3(0, 1, 0), identityQ, "RightRingMeta", defaultJointChannels),
                NewMJoint("RightRingTip", MJointType.RightRingTip, new MVector3(0, 0.03, 0), identityQ, "RightRingDistal", zeroChannels),

                NewMJoint("RightLittleProximal", MJointType.RightLittleProximal, new MVector3(0, 1, 0), identityQ, "RightWrist", defaultRootChannels),
                NewMJoint("RightLittleMeta", MJointType.RightLittleMeta, new MVector3(0, 1, 0), identityQ, "RightLittleProximal", defaultJointChannels),
                NewMJoint("RightLittleDistal", MJointType.RightLittleDistal, new MVector3(0, 1, 0), identityQ, "RightLittleMeta", defaultJointChannels),
                NewMJoint("RightLittleTip", MJointType.RightLittleTip, new MVector3(0, 0.03, 0), identityQ, "RightLittleDistal", zeroChannels),

                NewMJoint("RightThumbMid", MJointType.RightThumbMid, new MVector3(0, 1, 0), new MQuaternion(0.3826834559440613, 0, 0, 0.9238795042037964), "RightWrist", defaultRootChannels),//0.53730, 0, 0, 0.84339
                NewMJoint("RightThumbMeta", MJointType.RightThumbMeta, new MVector3(0, 1, 0), identityQ, "RightThumbMid", defaultJointChannels),
                NewMJoint("RightThumbCarpal", MJointType.RightThumbCarpal, new MVector3(0, 1, 0), identityQ, "RightThumbMeta", defaultJointChannels),
                NewMJoint("RightThumbTip", MJointType.RightThumbTip, new MVector3(0, 0.03, 0), identityQ, "RightThumbCarpal", zeroChannels),

                // Left leg: 5 joints (4 animated, 16 channels)
                NewMJoint("LeftHip", MJointType.LeftHip, new MVector3(0, 0, -1), qRotZ180, "PelvisCenter", defaultJointChannels),
                NewMJoint("LeftKnee", MJointType.LeftKnee, new MVector3(0, 1, 0), identityQ, "LeftHip", defaultJointChannels),
                NewMJoint("LeftAnkle", MJointType.LeftAnkle, new MVector3(0, 1, 0), new MQuaternion(0, 0, -0.53730, 0.84339), "LeftKnee", defaultJointChannels),
                NewMJoint("LeftBall", MJointType.LeftBall, new MVector3(0, 1, 0), new MQuaternion(0, 0, -0.2164396196603775, 0.9762960076332092), "LeftAnkle", defaultJointChannels),
                NewMJoint("LeftBallTip", MJointType.LeftBallTip, new MVector3(0, 0.08, 0), identityQ, "LeftBall", zeroChannels),

                // Right leg: 5 joints (4 animated, 16 channels)
                NewMJoint("RightHip", MJointType.RightHip, new MVector3(0, 0, 1), qRotZ180, "PelvisCenter", defaultJointChannels),
                NewMJoint("RightKnee", MJointType.RightKnee, new MVector3(0, 1, 0), identityQ, "RightHip", defaultJointChannels),
                NewMJoint("RightAnkle", MJointType.RightAnkle, new MVector3(0, 1, 0), new MQuaternion(0, 0, -0.53730, 0.84339), "RightKnee", defaultJointChannels),
                NewMJoint("RightBall", MJointType.RightBall, new MVector3(0, 1, 0), new MQuaternion(0, 0, -0.2164396196603775, 0.9762960076332092), "RightAnkle", defaultJointChannels),
                NewMJoint("RightBallTip", MJointType.RightBallTip, new MVector3(0, 0.08, 0), identityQ, "RightBall", zeroChannels)
            };

            return(defaultJoints);
        }
예제 #9
0
        private int SetAvatarPostureValues(MAvatarPostureValues values, int id, List <MJointType> animatedJoints)
        {
            if (animatedJoints == null || animatedJoints.Contains(this.joint.Type))
            {
                translation = new MVector3(0, 0, 0);

                this.currentRotationValues = new MQuaternion(0, 0, 0, 1);

                if (values != null)
                {
                    MVector3 translation = new MVector3(0, 0, 0);
                    for (int i = 0; i < this.joint.Channels.Count; i++)
                    {
                        switch (this.joint.Channels[i])
                        {
                        case MChannel.WRotation:
                            this.currentRotationValues.W = values.PostureData[id];
                            break;

                        case MChannel.XRotation:
                            this.currentRotationValues.X = values.PostureData[id];
                            break;

                        case MChannel.YRotation:
                            this.currentRotationValues.Y = values.PostureData[id];
                            break;

                        case MChannel.ZRotation:
                            this.currentRotationValues.Z = values.PostureData[id];
                            break;

                        case MChannel.XOffset:
                            translation.X = (float)values.PostureData[id];
                            break;

                        case MChannel.YOffset:
                            translation.Y = (float)values.PostureData[id];
                            break;

                        case MChannel.ZOffset:
                            translation.Z = (float)values.PostureData[id];
                            break;
                        }
                        id += 1;
                    }

                    this.translation = translation;
                }
            }



            MQuaternion parentRotation = new MQuaternion(0, 0, 0, 1);
            MVector3    parentPosition = new MVector3(0, 0, 0);

            if (this.parentJoint != null)
            {
                parentRotation = this.parentJoint.globalRot;
                parentPosition = this.parentJoint.globalPos;
            }


            MVector3 rotatedOffset      = parentRotation.Multiply(this.joint.Position);
            MVector3 rotatedTranslation = parentRotation.Multiply(this.joint.Rotation).Multiply(this.translation);

            this.globalPos = rotatedTranslation.Add(rotatedOffset).Add(parentPosition);

            this.globalRot = parentRotation.Multiply(this.joint.Rotation).Multiply(this.currentRotationValues);


            foreach (Joint c in this.children)
            {
                id = c.SetAvatarPostureValues(values, id, animatedJoints);
            }
            return(id);
        }
예제 #10
0
        /// <summary>
        /// Default do step routine
        /// </summary>
        /// <param name="time"></param>
        /// <param name="simulationState"></param>
        /// <returns></returns>
        public override MSimulationResult DoStep(double time, MSimulationState simulationState)
        {
            //Create a new simulation result
            MSimulationResult result = new MSimulationResult()
            {
                Events             = simulationState.Events ?? new List <MSimulationEvent>(),
                Constraints        = simulationState.Constraints ?? new List <MConstraint>(),
                SceneManipulations = simulationState.SceneManipulations ?? new List <MSceneManipulation>(),
                Posture            = simulationState.Current
            };

            //Set the channel data to reflect to current posture
            SkeletonAccess.SetChannelData(simulationState.Current);


            //Set the default rotation of the head and neck joints
            SkeletonAccess.SetLocalJointRotation(AvatarDescription.AvatarID, MJointType.HeadJoint, initialHeadRotation);
            SkeletonAccess.SetLocalJointRotation(AvatarDescription.AvatarID, MJointType.C4C5Joint, initialNeckRotation);


            //Create a transform representing the current head location
            MTransform currentTransform = new MTransform()
            {
                ID       = "",
                Position = SkeletonAccess.GetGlobalJointPosition(AvatarDescription.AvatarID, MJointType.HeadJoint),
                Rotation = SkeletonAccess.GetGlobalJointRotation(AvatarDescription.AvatarID, MJointType.HeadJoint)
            };

            //Create a transform representing the parent location (neck)
            MTransform parentTransform = new MTransform()
            {
                ID       = "",
                Position = SkeletonAccess.GetGlobalJointPosition(AvatarDescription.AvatarID, MJointType.C4C5Joint),
                Rotation = SkeletonAccess.GetGlobalJointRotation(AvatarDescription.AvatarID, MJointType.C4C5Joint)
            };

            //The current head forward vector
            MVector3 currentHeadForward = new MVector3(-1, 0, 0);



            //Compute the local position of the desired object (relative to the neck)
            MVector3 localPosition = parentTransform.InverseTransformPoint(this.gazeTarget.Position);

            //Get the xz distance in local space
            float distance = new MVector3(localPosition.X, 0, localPosition.Z).Magnitude();
            float height   = (float)localPosition.Y;

            //Compute the current angle
            float currentAngle = (float)(Math.Atan(height / distance) * 180 / Math.PI);

            //Limit if below lower limit
            if (currentAngle < lowerLimit)
            {
                localPosition.Y = Math.Tan(lowerLimit * Math.PI / 180) * distance;
            }

            //Limit if above upper angle limit
            if (currentAngle > upperLimit)
            {
                localPosition.Y = Math.Tan(upperLimit * Math.PI / 180) * distance;
            }


            float maxYAngle = 80f;

            //Limit xz position
            float yAngle = (float)MVector3Extensions.Angle(currentHeadForward, new MVector3(localPosition.X, 0, localPosition.Z));

            if (yAngle > maxYAngle)
            {
                //The interpolated direction
                MVector3 interpolatedDirection = MVector3Extensions.Lerp(currentHeadForward, new MVector3(localPosition.X, 0, localPosition.Z).Normalize(), (maxYAngle / yAngle)).Normalize();

                //Perform correction
                MVector3 newLocalPositionsXZ = interpolatedDirection.Multiply(distance);

                localPosition.X = newLocalPositionsXZ.X;
                localPosition.Z = newLocalPositionsXZ.Z;
            }


            //Compute the desired and current facing direction
            MVector3 desiredHeadForward = localPosition.Normalize();


            //Estimate the rotation that is required to rotate from the current head direction towards the desired one
            MQuaternion deltaRotation = FromToRotation(currentHeadForward, new MVector3(desiredHeadForward.X, -desiredHeadForward.Y, desiredHeadForward.Z));

            //Gather the current location rotation
            MQuaternion currentLocalRotation = SkeletonAccess.GetLocalJointRotation(AvatarDescription.AvatarID, MJointType.HeadJoint);

            //Update the local joint rotation to adjust the facing direction to the desired values

            SkeletonAccess.SetLocalJointRotation(AvatarDescription.AvatarID, MJointType.HeadJoint, currentLocalRotation.Multiply(deltaRotation));

            //Set the updated postures
            result.Posture = SkeletonAccess.RecomputeCurrentPostureValues(AvatarDescription.AvatarID);

            //Return the simulation results
            return(result);
        }
예제 #11
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);
        }