예제 #1
0
    void UpdateScales(BoneTriplet root)
    {
        root.blendedTransform.localScale = root.mecanimTransform.localScale = root.kinectTransform.localScale;

        foreach (BoneTriplet childTriplet in root.children)
        {
            UpdateScales(childTriplet);
        }
    }
예제 #2
0
    void Blend(BoneTriplet boneTriplet)
    {
        float blendWeight = GetBlendWeight(boneTriplet.bodypartClassification);

        boneTriplet.blendedTransform.localPosition = Vector3.Lerp(boneTriplet.kinectTransform.localPosition, boneTriplet.mecanimTransform.localPosition, blendWeight);
        boneTriplet.blendedTransform.localRotation = Quaternion.Slerp(boneTriplet.kinectTransform.localRotation, boneTriplet.mecanimTransform.localRotation, blendWeight);
        //boneTriplet.blendedTransform.localScale = boneTriplet.kinectTransform.localScale;

        if (applyTorsoCounteringRotations && IsLimbRoot(boneTriplet))
        {
            ApplyCounteringRotationToLimbRoot(torsoRoot, boneTriplet);
        }

        foreach (BoneTriplet childTriplet in boneTriplet.children)
        {
            Blend(childTriplet);
        }
    }
    private void AddChildren(ref BoneTriplet triplet, BodypartClassification parentBodypartClassification)
    {
        for (int i = 0; i < triplet.kinectTransform.childCount; i++)
        {
            BoneTriplet childTriplet = new BoneTriplet(triplet.kinectTransform.GetChild(i),
                                                       triplet.mecanimTransform.GetChild(i),
                                                       triplet.blendedTransform.GetChild(i),
                                                       GetBodypartClassification(triplet.kinectTransform.GetChild(i), triplet.bodypartClassification));

            if (parentBodypartClassification != childTriplet.bodypartClassification)
            {
                RegisterRootBone(childTriplet);
            }

            if (childTriplet.kinectTransform == skeletonController.neck)
            {
                neckRoot = childTriplet;
            }

            triplet.children.Add(childTriplet);
            AddChildren(ref childTriplet, childTriplet.bodypartClassification);
        }
    }
    void Start()
    {
        if (!childrenInstantiated)
        {
            childrenInstantiated = true;

            kinectGameObject = Instantiate(gameObject, transform.position, transform.rotation) as GameObject;
            kinectGameObject.name = name + "Kinect";
            kinectGameObject.transform.parent = transform.parent;
            //kinectGameObject.GetComponent<RUISKinectAndMecanimCombiner>().childrenInstantiated = true;
            Destroy(kinectGameObject.GetComponent<RUISKinectAndMecanimCombiner>());
            Destroy(kinectGameObject.GetComponent<Animator>());
            Destroy(kinectGameObject.GetComponent<RUISCharacterAnimationController>());
            foreach (Collider collider in kinectGameObject.GetComponentsInChildren<Collider>())
            {
                Destroy(collider);
            }
            foreach (Renderer meshRenderer in kinectGameObject.GetComponentsInChildren<Renderer>())
            {
                Destroy(meshRenderer);
            }

            mecanimGameObject = Instantiate(gameObject, transform.position, transform.rotation) as GameObject;
            mecanimGameObject.name = name + "Mecanim";
            mecanimGameObject.transform.parent = transform.parent;
            Destroy(mecanimGameObject.GetComponent<RUISKinectAndMecanimCombiner>());
            Destroy(mecanimGameObject.GetComponent<RUISCharacterAnimationController>());

            Destroy(mecanimGameObject.GetComponent<RUISSkeletonController>());
            foreach (Collider collider in mecanimGameObject.GetComponentsInChildren<Collider>())
            {
                Destroy(collider);
            }
            foreach (Renderer meshRenderer in mecanimGameObject.GetComponentsInChildren<Renderer>())
            {
                Destroy(meshRenderer);
            }

            Destroy(GetComponent<RUISSkeletonController>());
            Destroy(GetComponent<Animator>());
            GetComponent<RUISCharacterAnimationController>().animator = mecanimGameObject.GetComponent<Animator>();

            skeletonController = kinectGameObject.GetComponent<RUISSkeletonController>();
            mecanimAnimator = mecanimGameObject.GetComponent<Animator>();

            torsoIsRoot = skeletonController.root == skeletonController.torso;

            Transform kinectRootBone = skeletonController.root;
            Transform mecanimRootBone = FindBone(mecanimAnimator.transform, kinectRootBone.name);
            Transform blendedRootBone = FindBone(transform, kinectRootBone.name);
            skeletonRoot = new BoneTriplet(kinectRootBone, mecanimRootBone, blendedRootBone, BodypartClassification.Root);

            if (torsoIsRoot)
            {
                torsoRoot = skeletonRoot;
                AddChildren(ref torsoRoot, BodypartClassification.Torso);
            }
            else
            {
                AddChildren(ref skeletonRoot, BodypartClassification.Root);
            }
        }
    }
    void UpdateScales(BoneTriplet root)
    {
        root.blendedTransform.localScale = root.mecanimTransform.localScale = root.kinectTransform.localScale;

        foreach (BoneTriplet childTriplet in root.children)
        {
            UpdateScales(childTriplet);
        }
    }
 private bool IsPartOfLimb(BoneTriplet bone)
 {
     return bone.bodypartClassification == BodypartClassification.RightLeg ||
            bone.bodypartClassification == BodypartClassification.LeftLeg;
 }
 private void RegisterRootBone(BoneTriplet triplet)
 {
     switch (triplet.bodypartClassification)
     {
         case BodypartClassification.Torso:
             torsoRoot = triplet;
             return;
         case BodypartClassification.Head:
             headRoot = triplet;
             return;
         case BodypartClassification.RightArm:
             rightArmRoot = triplet;
             return;
         case BodypartClassification.LeftArm:
             leftArmRoot = triplet;
             return;
         case BodypartClassification.RightLeg:
             rightLegRoot = triplet;
             return;
         case BodypartClassification.LeftLeg:
             leftLegRoot = triplet;
             return;
     }
 }
    void Blend(BoneTriplet boneTriplet)
    {
        float blendWeight = GetBlendWeight(boneTriplet.bodypartClassification);
        boneTriplet.blendedTransform.localPosition = Vector3.Lerp(boneTriplet.kinectTransform.localPosition, boneTriplet.mecanimTransform.localPosition, blendWeight);
        boneTriplet.blendedTransform.localRotation = Quaternion.Slerp(boneTriplet.kinectTransform.localRotation, boneTriplet.mecanimTransform.localRotation, blendWeight);
        //boneTriplet.blendedTransform.localScale = boneTriplet.kinectTransform.localScale;

        if(applyTorsoCounteringRotations && IsLimbRoot(boneTriplet))
        {
            ApplyCounteringRotationToLimbRoot(torsoRoot, boneTriplet);
        }

        foreach (BoneTriplet childTriplet in boneTriplet.children)
        {
            Blend(childTriplet);
        }
    }
 private bool IsLimbRoot(BoneTriplet bone)
 {
     return bone == headRoot || bone == rightArmRoot || bone == leftArmRoot || bone == rightLegRoot || bone == leftLegRoot;
 }
    private void ApplyCounteringRotationToLimbRoot(BoneTriplet torsoBone, BoneTriplet limbRootBone)
    {
        //boneTriplet.blendedTransform.localRotation = Quaternion.Slerp(boneTriplet.kinectTransform.localRotation, boneTriplet.mecanimTransform.localRotation, blendWeight);

        float limbRootBlendWeight = GetBlendWeight(limbRootBone.bodypartClassification);

        //first set the global rotation so that it matches
        limbRootBone.blendedTransform.rotation = Quaternion.Slerp(limbRootBone.kinectTransform.rotation, limbRootBone.mecanimTransform.rotation, limbRootBlendWeight);

        //then apply the yaw to turn the limb to the same general direction as the torso
        Quaternion kinectToMecanimYaw = CalculateKinectToMecanimYaw();
        kinectToMecanimYaw = Quaternion.Slerp(Quaternion.identity, kinectToMecanimYaw, limbRootBlendWeight);

        Vector3 rotatedForward = kinectToMecanimYaw * Vector3.forward;
        float angles = -Mathf.Atan2(rotatedForward.y, rotatedForward.z) * Mathf.Rad2Deg;
        //float angles = Vector3.Angle(Vector3.up, kinectToMecanimYaw * Vector3.up);
        // That doesn't work right, Vector3.Angle seems to return only values between [0, 180], and the leg animation came up wrong when facing left

        //print(angles);

        limbRootBone.blendedTransform.rotation = limbRootBone.blendedTransform.rotation * Quaternion.AngleAxis(angles, limbRootBone.blendedTransform.InverseTransformDirection(transform.up));//* newLocalRotation * Quaternion.Inverse(limbRootBone.blendedTransform.rotation) * limbRootBone.blendedTransform.rotation;
    }
    void Start()
    {
        Vector3 initialLocalScale = transform.localScale;

        skeletonManager = FindObjectOfType(typeof(RUISSkeletonManager)) as RUISSkeletonManager;

        skeletonController = GetComponent <RUISSkeletonController>();
        //		if (	!inputManager.enableKinect && !inputManager.enableKinect2
        //		    &&  (skeletonController.bodyTrackingDevice != RUISSkeletonController.bodyTrackingDeviceType.GenericMotionTracker))
        if (skeletonController != null && (skeletonController.followHmdPosition || inputManager == null ||
                                           (skeletonController.followMoveController &&
                                            ((skeletonController.bodyTrackingDeviceID == RUISSkeletonManager.kinect1SensorID && !inputManager.enableKinect) ||
                                             (skeletonController.bodyTrackingDeviceID == RUISSkeletonManager.kinect2SensorID && !inputManager.enableKinect2)))))
        {
            // Without the below if-clause the legs will twist with PS Move head tracker (when Move is enabled but Kinect is not)
            //if(!inputManager.enablePSMove)
            torsoBlendWeight    = 1;
            headBlendWeight     = 1;
            rightArmBlendWeight = 1;
            leftArmBlendWeight  = 1;
            rightLegBlendWeight = 1;
            leftLegBlendWeight  = 1;
//			forceArmStartPosition = false;
//			forceLegStartPosition = false;
        }

        if (!childrenInstantiated)
        {
            childrenInstantiated = true;

            kinectGameObject                      = Instantiate(gameObject, transform.position, transform.rotation) as GameObject;
            kinectGameObject.name                 = name + "Kinect";
            kinectGameObject.transform.parent     = transform.parent;
            kinectGameObject.transform.localScale = initialLocalScale;
            //kinectGameObject.GetComponent<RUISKinectAndMecanimCombiner>().childrenInstantiated = true;
            Destroy(kinectGameObject.GetComponent <RUISKinectAndMecanimCombiner>());
            Destroy(kinectGameObject.GetComponent <Animator>());
            Destroy(kinectGameObject.GetComponent <RUISCharacterAnimationController>());
            foreach (Collider collider in kinectGameObject.GetComponentsInChildren <Collider>())
            {
                Destroy(collider);
            }
            foreach (Renderer meshRenderer in kinectGameObject.GetComponentsInChildren <Renderer>())
            {
                Destroy(meshRenderer);
            }


            mecanimGameObject                      = Instantiate(gameObject, transform.position, transform.rotation) as GameObject;
            mecanimGameObject.name                 = name + "Mecanim";
            mecanimGameObject.transform.parent     = transform.parent;
            mecanimGameObject.transform.localScale = initialLocalScale;
            Destroy(mecanimGameObject.GetComponent <RUISKinectAndMecanimCombiner>());
            Destroy(mecanimGameObject.GetComponent <RUISCharacterAnimationController>());

            Destroy(mecanimGameObject.GetComponent <RUISSkeletonController>());
            foreach (Collider collider in mecanimGameObject.GetComponentsInChildren <Collider>())
            {
                Destroy(collider);
            }
            foreach (Renderer meshRenderer in mecanimGameObject.GetComponentsInChildren <Renderer>())
            {
                Destroy(meshRenderer);
            }


            Destroy(GetComponent <RUISSkeletonController>());
            Destroy(GetComponent <Animator>());
            GetComponent <RUISCharacterAnimationController>().animator = mecanimGameObject.GetComponent <Animator>();

            skeletonController = kinectGameObject.GetComponent <RUISSkeletonController>();
            mecanimAnimator    = mecanimGameObject.GetComponent <Animator>();

            if (!skeletonController)
            {
                Debug.LogError("Script " + typeof(RUISSkeletonController) + " is not found by " + this.GetType().Name + "!");
            }

            torsoIsRoot = skeletonController.root == skeletonController.torso;

            Transform kinectRootBone  = skeletonController.root;
            Transform mecanimRootBone = FindBone(mecanimAnimator.transform, kinectRootBone.name);
            Transform blendedRootBone = FindBone(transform, kinectRootBone.name);
            skeletonRoot = new BoneTriplet(kinectRootBone, mecanimRootBone, blendedRootBone, BodypartClassification.Root);

            if (torsoIsRoot)
            {
                torsoRoot = skeletonRoot;
                AddChildren(ref torsoRoot, BodypartClassification.Torso);
            }
            else
            {
                AddChildren(ref skeletonRoot, BodypartClassification.Root);
            }
        }
    }
    private void ApplyCounteringRotationToLimbRoot(BoneTriplet torsoBone, BoneTriplet limbRootBone)
    {
        //boneTriplet.blendedTransform.localRotation = Quaternion.Slerp(boneTriplet.kinectTransform.localRotation, boneTriplet.mecanimTransform.localRotation, blendWeight);

        if (skeletonController == null)
        {
            return;
        }

        float limbRootBlendWeight = GetBlendWeight(limbRootBone.bodypartClassification);

        //first set the global rotation so that it matches
        limbRootBone.blendedTransform.rotation = Quaternion.Slerp(limbRootBone.kinectTransform.rotation, limbRootBone.mecanimTransform.rotation, limbRootBlendWeight);

        bool headRotates               = false;
        bool headRotatesBody           = false;
        bool headRotatesWalking        = false;
        bool headRotatesBodyAndWalking = false;

        if (skeletonController.characterController &&
            (skeletonController.followMoveController || skeletonController.followHmdPosition))
        {
            headRotatesBodyAndWalking = skeletonController.characterController.headRotatesBody && skeletonController.characterController.headPointsWalkingDirection;
            headRotatesWalking        = !skeletonController.characterController.headRotatesBody && skeletonController.characterController.headPointsWalkingDirection;
            headRotatesBody           = skeletonController.characterController.headRotatesBody && !skeletonController.characterController.headPointsWalkingDirection;
            headRotates = !skeletonController.characterController.headRotatesBody && !skeletonController.characterController.headPointsWalkingDirection;
        }

        //then apply the yaw to turn the limb to the same general direction as the torso
        Quaternion kinectToMecanimYaw = CalculateKinectToMecanimYaw(skeletonController.characterController &&
                                                                    (skeletonController.followMoveController || skeletonController.followHmdPosition) &&
                                                                    (headRotatesBodyAndWalking ||
                                                                     (headRotatesWalking && limbRootBone.bodypartClassification != BodypartClassification.LeftArm &&
                                                                      limbRootBone.bodypartClassification != BodypartClassification.RightArm) ||
                                                                     (headRotatesBody && limbRootBone.bodypartClassification != BodypartClassification.LeftLeg &&
                                                                      limbRootBone.bodypartClassification != BodypartClassification.RightLeg) ||
                                                                     (headRotates && limbRootBone.bodypartClassification == BodypartClassification.Head && skeletonController.HmdRotatesHead))
                                                                    );

        kinectToMecanimYaw = Quaternion.Slerp(Quaternion.identity, kinectToMecanimYaw, limbRootBlendWeight);

        Vector3 rotatedForward = kinectToMecanimYaw * Vector3.forward;
        float   angles         = -Mathf.Atan2(rotatedForward.y, rotatedForward.z) * Mathf.Rad2Deg;

        //float angles = Vector3.Angle(Vector3.up, kinectToMecanimYaw * Vector3.up);
        // That doesn't work right, Vector3.Angle seems to return only values between [0, 180], and the leg animation came up wrong when facing left

        //print(angles);

        // TODO fix arm twisting when skeletonController.followMoveController == true || skeletonController.followMoveController == true

        if ((!skeletonController.followHmdPosition && !skeletonController.followMoveController) ||
            (skeletonController.characterController ||
             (headRotatesBodyAndWalking &&
              (limbRootBone.bodypartClassification == BodypartClassification.LeftLeg || limbRootBone.bodypartClassification == BodypartClassification.RightLeg)) ||
             (headRotatesWalking &&
              (limbRootBone.bodypartClassification == BodypartClassification.LeftLeg || limbRootBone.bodypartClassification == BodypartClassification.RightLeg)) ||
             headRotatesBody ||
             headRotates))
        {
            limbRootBone.blendedTransform.rotation = limbRootBone.blendedTransform.rotation * Quaternion.AngleAxis(angles, limbRootBone.blendedTransform.InverseTransformDirection(transform.up));
        }
    }
    void Start()
	{
		Vector3 initialLocalScale = transform.localScale;
		skeletonManager = FindObjectOfType(typeof(RUISSkeletonManager)) as RUISSkeletonManager;
		
		skeletonController = GetComponent<RUISSkeletonController>();
		//		if (	!inputManager.enableKinect && !inputManager.enableKinect2 
		//		    &&  (skeletonController.bodyTrackingDevice != RUISSkeletonController.bodyTrackingDeviceType.GenericMotionTracker))
		if(skeletonController != null && (   skeletonController.followOculusController || inputManager == null
		                                  || (	   skeletonController.followMoveController 
		    									&& (   (skeletonController.bodyTrackingDeviceID == RUISSkeletonManager.kinect1SensorID && !inputManager.enableKinect )
		    										|| (skeletonController.bodyTrackingDeviceID == RUISSkeletonManager.kinect2SensorID && !inputManager.enableKinect2)))))
		{
			// Without the below if-clause the legs will twist with PS Move head tracker (when Move is enabled but Kinect is not)
			//if(!inputManager.enablePSMove)
			torsoBlendWeight = 1;
			headBlendWeight = 1;		
			rightArmBlendWeight = 1;
			leftArmBlendWeight = 1;
			rightLegBlendWeight = 1;
			leftLegBlendWeight = 1;
//			forceArmStartPosition = false;
//			forceLegStartPosition = false;
		}

        if (!childrenInstantiated)
        {
            childrenInstantiated = true;

            kinectGameObject = Instantiate(gameObject, transform.position, transform.rotation) as GameObject;
            kinectGameObject.name = name + "Kinect";
			kinectGameObject.transform.parent = transform.parent;
			kinectGameObject.transform.localScale = initialLocalScale;
            //kinectGameObject.GetComponent<RUISKinectAndMecanimCombiner>().childrenInstantiated = true;
            Destroy(kinectGameObject.GetComponent<RUISKinectAndMecanimCombiner>());
            Destroy(kinectGameObject.GetComponent<Animator>());
            Destroy(kinectGameObject.GetComponent<RUISCharacterAnimationController>());
            foreach (Collider collider in kinectGameObject.GetComponentsInChildren<Collider>())
            {
                Destroy(collider);
            }
            foreach (Renderer meshRenderer in kinectGameObject.GetComponentsInChildren<Renderer>())
            {
                Destroy(meshRenderer);
            }


            mecanimGameObject = Instantiate(gameObject, transform.position, transform.rotation) as GameObject;
            mecanimGameObject.name = name + "Mecanim";
            mecanimGameObject.transform.parent = transform.parent;
			mecanimGameObject.transform.localScale = initialLocalScale;
            Destroy(mecanimGameObject.GetComponent<RUISKinectAndMecanimCombiner>());
            Destroy(mecanimGameObject.GetComponent<RUISCharacterAnimationController>());

            Destroy(mecanimGameObject.GetComponent<RUISSkeletonController>());
            foreach (Collider collider in mecanimGameObject.GetComponentsInChildren<Collider>())
            {
                Destroy(collider);
            }
            foreach (Renderer meshRenderer in mecanimGameObject.GetComponentsInChildren<Renderer>())
            {
                Destroy(meshRenderer);
            }


            Destroy(GetComponent<RUISSkeletonController>());
            Destroy(GetComponent<Animator>());
            GetComponent<RUISCharacterAnimationController>().animator = mecanimGameObject.GetComponent<Animator>();

            skeletonController = kinectGameObject.GetComponent<RUISSkeletonController>();
            mecanimAnimator = mecanimGameObject.GetComponent<Animator>();

			if(!skeletonController)
				Debug.LogError("Script " + typeof(RUISSkeletonController) + " is not found by " + this.GetType().Name + "!");

            torsoIsRoot = skeletonController.root == skeletonController.torso;

            Transform kinectRootBone = skeletonController.root;
            Transform mecanimRootBone = FindBone(mecanimAnimator.transform, kinectRootBone.name);
            Transform blendedRootBone = FindBone(transform, kinectRootBone.name);
            skeletonRoot = new BoneTriplet(kinectRootBone, mecanimRootBone, blendedRootBone, BodypartClassification.Root);

            if (torsoIsRoot)
            {
                torsoRoot = skeletonRoot;
                AddChildren(ref torsoRoot, BodypartClassification.Torso);
            }
            else
            {
                AddChildren(ref skeletonRoot, BodypartClassification.Root);
            }
        }
    }
    private void ApplyCounteringRotationToLimbRoot(BoneTriplet torsoBone, BoneTriplet limbRootBone)
    {
        //boneTriplet.blendedTransform.localRotation = Quaternion.Slerp(boneTriplet.kinectTransform.localRotation, boneTriplet.mecanimTransform.localRotation, blendWeight);

		if(skeletonController == null)
			return;

        float limbRootBlendWeight = GetBlendWeight(limbRootBone.bodypartClassification);
        
        //first set the global rotation so that it matches
        limbRootBone.blendedTransform.rotation = Quaternion.Slerp(limbRootBone.kinectTransform.rotation, limbRootBone.mecanimTransform.rotation, limbRootBlendWeight);

		bool headRotates = false;
		bool headRotatesBody = false;
		bool headRotatesWalking = false;
		bool headRotatesBodyAndWalking = false;

		if(   skeletonController.characterController 
		   && (skeletonController.followMoveController || skeletonController.followOculusController))
		{
			headRotatesBodyAndWalking =  skeletonController.characterController.headRotatesBody &&  skeletonController.characterController.headPointsWalkingDirection;
			headRotatesWalking        = !skeletonController.characterController.headRotatesBody &&  skeletonController.characterController.headPointsWalkingDirection;
			headRotatesBody           =  skeletonController.characterController.headRotatesBody && !skeletonController.characterController.headPointsWalkingDirection;
			headRotates               = !skeletonController.characterController.headRotatesBody && !skeletonController.characterController.headPointsWalkingDirection;
		}

        //then apply the yaw to turn the limb to the same general direction as the torso
		Quaternion kinectToMecanimYaw = CalculateKinectToMecanimYaw(   skeletonController.characterController 
		                                                            && (skeletonController.followMoveController || skeletonController.followOculusController)
		                                                            && (    headRotatesBodyAndWalking
		                                                                || (headRotatesWalking && limbRootBone.bodypartClassification != BodypartClassification.LeftArm 
		    																				   && limbRootBone.bodypartClassification != BodypartClassification.RightArm)
			                                                            || (headRotatesBody && limbRootBone.bodypartClassification != BodypartClassification.LeftLeg 
			                        														&& limbRootBone.bodypartClassification != BodypartClassification.RightLeg)
		    															|| (headRotates && limbRootBone.bodypartClassification == BodypartClassification.Head))
		                                                            );

        kinectToMecanimYaw = Quaternion.Slerp(Quaternion.identity, kinectToMecanimYaw, limbRootBlendWeight);   
		
		Vector3 rotatedForward = kinectToMecanimYaw * Vector3.forward;
        float angles = -Mathf.Atan2(rotatedForward.y, rotatedForward.z) * Mathf.Rad2Deg;
		//float angles = Vector3.Angle(Vector3.up, kinectToMecanimYaw * Vector3.up);
		// That doesn't work right, Vector3.Angle seems to return only values between [0, 180], and the leg animation came up wrong when facing left
		
		//print(angles); 
	
		// TODO fix arm twisting when skeletonController.followMoveController == true || skeletonController.followMoveController == true

		if(   (!skeletonController.followOculusController && !skeletonController.followMoveController)
		   || (    skeletonController.characterController 
		    	|| (    headRotatesBodyAndWalking
		    		&& (limbRootBone.bodypartClassification == BodypartClassification.LeftLeg || limbRootBone.bodypartClassification == BodypartClassification.RightLeg))
		    	|| (    headRotatesWalking
			    	&& (   limbRootBone.bodypartClassification == BodypartClassification.LeftLeg || limbRootBone.bodypartClassification == BodypartClassification.RightLeg))
		    	||      headRotatesBody
		    	||      headRotates ))
			limbRootBone.blendedTransform.rotation = limbRootBone.blendedTransform.rotation * Quaternion.AngleAxis(angles, limbRootBone.blendedTransform.InverseTransformDirection(transform.up));


        
    }