void UpdateScales(BoneTriplet root) { root.blendedTransform.localScale = root.mecanimTransform.localScale = root.kinectTransform.localScale; foreach (BoneTriplet childTriplet in root.children) { UpdateScales(childTriplet); } }
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); } } }
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)); }