Torso/head bone detection without avatar

This commit is contained in:
Pascal Serrarens 2024-11-12 12:04:01 +01:00
parent 67126399e6
commit 40a8ef2e4d
10 changed files with 244 additions and 107 deletions

View File

@ -22,7 +22,7 @@ namespace Passer.Humanoid {
base.Start(humanoid, targetTransform); base.Start(humanoid, targetTransform);
target = targetTransform.GetComponent<FootTarget>(); target = targetTransform.GetComponent<FootTarget>();
if (Application.isPlaying) { if (Application.isPlaying && humanoid.leftFootTarget.foot.target.transform != null && humanoid.rightFootTarget.foot.target.transform != null) {
footSeparation = Vector3.Distance(humanoid.leftFootTarget.foot.target.transform.position, humanoid.rightFootTarget.foot.target.transform.position) / 2; footSeparation = Vector3.Distance(humanoid.leftFootTarget.foot.target.transform.position, humanoid.rightFootTarget.foot.target.transform.position) / 2;
} }

View File

@ -2,6 +2,7 @@ using System.Collections;
using UnityEngine; using UnityEngine;
namespace Passer.Humanoid { namespace Passer.Humanoid {
using System.ComponentModel;
using Tracking; using Tracking;
[System.Serializable] [System.Serializable]
@ -1308,8 +1309,9 @@ namespace Passer.Humanoid {
#endregion #endregion
#region Configuration #region Configuration
/// <summary> /// <summary>
/// Scans the humanoid to retrieve all bones /// Scans the humanoid using Mecanum to retrieve all bones
/// </summary> /// </summary>
public void RetrieveBones() { public void RetrieveBones() {
hipsTarget.RetrieveBones(); hipsTarget.RetrieveBones();
@ -1320,6 +1322,19 @@ namespace Passer.Humanoid {
leftFootTarget.RetrieveBones(); leftFootTarget.RetrieveBones();
rightFootTarget.RetrieveBones(); rightFootTarget.RetrieveBones();
} }
public void RetrieveBonesFrom(Transform rootBone) {
if (avatarRig != null) {
RetrieveBones();
return;
}
hipsTarget.RetrieveBonesWithoutAvatar(rootBone);
headTarget.RetrieveBonesWithoutAvatar(rootBone);
leftHandTarget.RetrieveBonesWithoutAvatar(rootBone);
}
#endregion #endregion
#region Update #region Update
@ -2476,8 +2491,13 @@ namespace Passer.Humanoid {
/// </summary> /// </summary>
/// <returns>The position of the humanoid</returns> /// <returns>The position of the humanoid</returns>
public Vector3 GetHumanoidPosition() { public Vector3 GetHumanoidPosition() {
Vector3 footPosition = (leftFootTarget.foot.target.transform.position + rightFootTarget.foot.target.transform.position) / 2; Vector3 footBase;
Vector3 footBase = new Vector3(footPosition.x, transform.position.y, footPosition.z); if (leftFootTarget.foot.target.transform != null && rightFootTarget.foot.target.transform != null) {
Vector3 footPosition = (leftFootTarget.foot.target.transform.position + rightFootTarget.foot.target.transform.position) / 2;
footBase = new Vector3(footPosition.x, transform.position.y, footPosition.z);
} else {
footBase = this.transform.position;
}
return footBase; return footBase;
} }
//public Vector3 GetHumanoidPosition2() { //public Vector3 GetHumanoidPosition2() {

View File

@ -24,7 +24,8 @@ namespace Passer.Humanoid {
if (humanoid.isRemote) if (humanoid.isRemote)
return; return;
grabSocket.handTarget = this; if (grabSocket != null)
grabSocket.handTarget = this;
// Gun Interaction pointer creates an Event System // Gun Interaction pointer creates an Event System
// First solve that before enabling this warning // First solve that before enabling this warning
@ -859,7 +860,7 @@ namespace Passer.Humanoid {
if (grabbedHandle != null) if (grabbedHandle != null)
LetGoHandle(grabbedHandle); LetGoHandle(grabbedHandle);
handRigidbody.mass = 1; handRigidbody.mass = 1;
} }
this.grabbedRigidbody = false; this.grabbedRigidbody = false;

View File

@ -75,9 +75,9 @@ namespace Passer.Humanoid {
distal.boneId = firstBoneId + 2; distal.boneId = firstBoneId + 2;
//metaCarpal.RetrieveBones(humanoid); //metaCarpal.RetrieveBones(humanoid);
proximal.RetrieveBones(humanoid); proximal.RetrieveBones();
intermediate.RetrieveBones(humanoid); intermediate.RetrieveBones();
distal.RetrieveBones(humanoid); distal.RetrieveBones();
} }
public void MatchTargetToAvatar() { public void MatchTargetToAvatar() {
@ -346,7 +346,7 @@ namespace Passer.Humanoid {
//private Quaternion localDefaultRotation; //private Quaternion localDefaultRotation;
public TargetedPhalanges(TargetedFinger finger, HumanoidTarget.TargetedBone nextBone) public TargetedPhalanges(TargetedFinger finger, HumanoidTarget.TargetedBone nextBone)
: base(nextBone) { : base(finger.fingers.handTarget.humanoid, nextBone) {
this.finger = finger; this.finger = finger;
} }

View File

@ -51,16 +51,29 @@ namespace Passer.Humanoid {
/// ///
[HelpURL("https://passervr.com/apis/HumanoidControl/Unity/class_passer_1_1_humanoid_1_1_foot_target.html")] [HelpURL("https://passervr.com/apis/HumanoidControl/Unity/class_passer_1_1_humanoid_1_1_foot_target.html")]
public class FootTarget : HumanoidTarget { public class FootTarget : HumanoidTarget {
public bool isLeft;
public Side side;
public FootTarget() { /// <summary>
/// Pseudo-constructor because Unity does not use real constructors with arguments
/// </summary>
/// <param name="humanoid">The humanoid for this foot target</param>
/// <param name="isLeft">Is this the left foot taget?</param>
public void Constructor(HumanoidControl humanoid, bool isLeft) {
this.humanoid = humanoid;
upperLeg = new TargetedUpperLegBone(this); upperLeg = new TargetedUpperLegBone(this);
lowerLeg = new TargetedLowerLegBone(this); lowerLeg = new TargetedLowerLegBone(this);
foot = new TargetedFootBone(this); foot = new TargetedFootBone(this);
toes = new TargetedToesBone(this); toes = new TargetedToesBone(this);
this.isLeft = isLeft;
this.side = isLeft ? Side.Left : Side.Right;
this.otherFoot = isLeft ? humanoid.rightFootTarget : humanoid.leftFootTarget;
this.InitSubTargets();
} }
public bool isLeft;
public Side side;
public FootTarget otherFoot; public FootTarget otherFoot;
public LegMovements legMovements = new LegMovements(); public LegMovements legMovements = new LegMovements();
@ -195,7 +208,7 @@ namespace Passer.Humanoid {
public class TargetedUpperLegBone : TargetedBone { public class TargetedUpperLegBone : TargetedBone {
private FootTarget footTarget; private FootTarget footTarget;
public TargetedUpperLegBone(FootTarget footTarget) : base(footTarget.lowerLeg) { public TargetedUpperLegBone(FootTarget footTarget) : base(footTarget.humanoid, footTarget.lowerLeg) {
this.footTarget = footTarget; this.footTarget = footTarget;
} }
@ -239,7 +252,7 @@ namespace Passer.Humanoid {
public class TargetedLowerLegBone : TargetedBone { public class TargetedLowerLegBone : TargetedBone {
private FootTarget footTarget; private FootTarget footTarget;
public TargetedLowerLegBone(FootTarget footTarget) : base(footTarget.foot) { public TargetedLowerLegBone(FootTarget footTarget) : base(footTarget.humanoid, footTarget.foot) {
this.footTarget = footTarget; this.footTarget = footTarget;
} }
@ -282,7 +295,7 @@ namespace Passer.Humanoid {
public class TargetedFootBone : TargetedBone { public class TargetedFootBone : TargetedBone {
private FootTarget footTarget; private FootTarget footTarget;
public TargetedFootBone(FootTarget footTarget) : base(footTarget.toes) { public TargetedFootBone(FootTarget footTarget) : base(footTarget.humanoid, footTarget.toes) {
this.footTarget = footTarget; this.footTarget = footTarget;
} }
@ -353,7 +366,7 @@ namespace Passer.Humanoid {
public class TargetedToesBone : TargetedBone { public class TargetedToesBone : TargetedBone {
private FootTarget footTarget; private FootTarget footTarget;
public TargetedToesBone(FootTarget footTarget) { public TargetedToesBone(FootTarget footTarget) : base(footTarget.humanoid) {
this.footTarget = footTarget; this.footTarget = footTarget;
} }
@ -488,7 +501,8 @@ namespace Passer.Humanoid {
targetTransform.position = oldTarget.transform.position; targetTransform.position = oldTarget.transform.position;
targetTransform.rotation = oldTarget.transform.rotation; targetTransform.rotation = oldTarget.transform.rotation;
FootTarget footTarget = Constructor(humanoid, oldTarget.isLeft, targetTransform); FootTarget footTarget = targetTransform.gameObject.AddComponent<FootTarget>();
footTarget.Constructor(humanoid, oldTarget.isLeft);
if (footTarget.isLeft) if (footTarget.isLeft)
humanoid.leftFootTarget = footTarget; humanoid.leftFootTarget = footTarget;
else else
@ -528,10 +542,10 @@ namespace Passer.Humanoid {
} }
public void RetrieveBones() { public void RetrieveBones() {
upperLeg.RetrieveBones(humanoid); upperLeg.RetrieveBones();
lowerLeg.RetrieveBones(humanoid); lowerLeg.RetrieveBones();
foot.RetrieveBones(humanoid); foot.RetrieveBones();
toes.RetrieveBones(humanoid); toes.RetrieveBones();
} }
#endregion #endregion
@ -705,17 +719,6 @@ namespace Passer.Humanoid {
#endif #endif
private static FootTarget Constructor(HumanoidControl humanoid, bool isLeft, Transform targetTransform) {
FootTarget footTarget = targetTransform.gameObject.AddComponent<FootTarget>();
footTarget.humanoid = humanoid;
footTarget.isLeft = isLeft;
footTarget.side = isLeft ? Side.Left : Side.Right;
footTarget.otherFoot = isLeft ? humanoid.rightFootTarget : humanoid.leftFootTarget;
footTarget.InitSubTargets();
return footTarget;
}
public override void NewComponent(HumanoidControl _humanoid) { public override void NewComponent(HumanoidControl _humanoid) {
humanoid = _humanoid; humanoid = _humanoid;
isLeft = (this == humanoid.leftFootTarget); isLeft = (this == humanoid.leftFootTarget);
@ -744,12 +747,12 @@ namespace Passer.Humanoid {
if (foot.bone.transform != null) if (foot.bone.transform != null)
soleThicknessFoot = foot.bone.transform.position.y - humanoid.transform.position.y; soleThicknessFoot = foot.bone.transform.position.y - humanoid.transform.position.y;
else else if (foot.target.transform != null)
soleThicknessFoot = foot.target.transform.position.y - humanoid.transform.position.y; soleThicknessFoot = foot.target.transform.position.y - humanoid.transform.position.y;
if (toes.bone.transform != null && ground != null) if (toes.bone.transform != null && ground != null)
soleThicknessToes = toes.bone.transform.position.y - humanoid.transform.position.y; soleThicknessToes = toes.bone.transform.position.y - humanoid.transform.position.y;
else else if (foot.target.transform != null)
soleThicknessToes = soleThicknessFoot; soleThicknessToes = soleThicknessFoot;
legMovements.Start(humanoid, this); legMovements.Start(humanoid, this);
@ -799,7 +802,8 @@ namespace Passer.Humanoid {
footTarget = footTargetTransform.GetComponent<FootTarget>(); footTarget = footTargetTransform.GetComponent<FootTarget>();
if (footTarget == null) { if (footTarget == null) {
footTarget = Constructor(humanoid, isLeft, footTargetTransform); footTarget = footTargetTransform.gameObject.AddComponent<FootTarget>();
footTarget.Constructor(humanoid, isLeft);
} }
} }

View File

@ -103,7 +103,13 @@ namespace Passer.Humanoid {
[System.Serializable] [System.Serializable]
[HelpURL("https://passervr.com/apis/HumanoidControl/Unity/class_passer_1_1_humanoid_1_1_hand_target.html")] [HelpURL("https://passervr.com/apis/HumanoidControl/Unity/class_passer_1_1_humanoid_1_1_hand_target.html")]
public partial class HandTarget : HumanoidTarget { public partial class HandTarget : HumanoidTarget {
public HandTarget() { /// <summary>
/// Pseudo-constructor because Unity does not use real constructors
/// </summary>
/// <param name="humanoid">The humanoid for this hand target</param>
/// <param name="isLeft">Is this the left hand target?</param>
public void Constructor(HumanoidControl humanoid, bool isLeft) {
this.humanoid = humanoid;
shoulder = new TargetedShoulderBone(this); shoulder = new TargetedShoulderBone(this);
upperArm = new TargetedUpperArmBone(this); upperArm = new TargetedUpperArmBone(this);
forearm = new TargetedForearmBone(this); forearm = new TargetedForearmBone(this);
@ -116,6 +122,11 @@ namespace Passer.Humanoid {
}; };
fingers = new FingersTarget(this); fingers = new FingersTarget(this);
this.isLeft = isLeft;
this.side = isLeft ? Side.Left : Side.Right;
this.outward = this.isLeft ? Vector3.left : Vector3.right;
InitSubTargets();
} }
#if pCEREBELLUM #if pCEREBELLUM
@ -379,7 +390,7 @@ namespace Passer.Humanoid {
get { return hand; } get { return hand; }
} }
public Transform stretchlessTarget; public Transform stretchlessTarget;
private readonly TargetedBone[] subTargets; private TargetedBone[] subTargets;
#region Shoulder #region Shoulder
@ -389,7 +400,7 @@ namespace Passer.Humanoid {
public class TargetedShoulderBone : TargetedBone { public class TargetedShoulderBone : TargetedBone {
private HandTarget handTarget; private HandTarget handTarget;
public TargetedShoulderBone(HandTarget handTarget) : base(handTarget.upperArm) { public TargetedShoulderBone(HandTarget handTarget) : base(handTarget.humanoid, handTarget.upperArm) {
this.handTarget = handTarget; this.handTarget = handTarget;
bone.jointLimitations = true; bone.jointLimitations = true;
} }
@ -417,6 +428,13 @@ namespace Passer.Humanoid {
} }
} }
public override Transform RetrieveBoneWithoutAvatar(Transform rootBone) {
bone.transform = FindTransformByPartialName(rootBone, "shoulder");
if (bone.transform == null)
bone.transform = FindTransformByPartialName(rootBone, "clavicle");
return bone.transform;
}
public override Quaternion DetermineRotation() { public override Quaternion DetermineRotation() {
Quaternion torsoRotation; Quaternion torsoRotation;
if (handTarget.humanoid.hipsTarget.chest.bone.transform != null) if (handTarget.humanoid.hipsTarget.chest.bone.transform != null)
@ -451,7 +469,7 @@ namespace Passer.Humanoid {
public class TargetedUpperArmBone : TargetedBone { public class TargetedUpperArmBone : TargetedBone {
private HandTarget handTarget; private HandTarget handTarget;
public TargetedUpperArmBone(HandTarget handTarget) : base(handTarget.forearm) { public TargetedUpperArmBone(HandTarget handTarget) : base(handTarget.humanoid, handTarget.forearm) {
this.handTarget = handTarget; this.handTarget = handTarget;
} }
@ -472,6 +490,11 @@ namespace Passer.Humanoid {
} }
} }
public override Transform RetrieveBoneWithoutAvatar(Transform rootBone) {
bone.transform = FindTransformByPartialName(rootBone, "up");
return bone.transform;
}
public override Quaternion DetermineRotation() { public override Quaternion DetermineRotation() {
Vector3 upperArmBoneDirection = (handTarget.forearm.bone.transform.position - bone.transform.position).normalized; Vector3 upperArmBoneDirection = (handTarget.forearm.bone.transform.position - bone.transform.position).normalized;
@ -502,7 +525,7 @@ namespace Passer.Humanoid {
public class TargetedForearmBone : TargetedBone { public class TargetedForearmBone : TargetedBone {
private HandTarget handTarget; private HandTarget handTarget;
public TargetedForearmBone(HandTarget handTarget) : base(handTarget.hand) { public TargetedForearmBone(HandTarget handTarget) : base(handTarget.humanoid, handTarget.hand) {
this.handTarget = handTarget; this.handTarget = handTarget;
} }
@ -564,7 +587,7 @@ namespace Passer.Humanoid {
public class TargetedHandBone : TargetedBone { public class TargetedHandBone : TargetedBone {
private HandTarget handTarget; private HandTarget handTarget;
public TargetedHandBone(HandTarget handTarget) { public TargetedHandBone(HandTarget handTarget) : base(handTarget.humanoid) {
this.handTarget = handTarget; this.handTarget = handTarget;
} }
@ -695,7 +718,10 @@ namespace Passer.Humanoid {
targetTransform.position = oldTarget.transform.position; targetTransform.position = oldTarget.transform.position;
targetTransform.rotation = oldTarget.transform.rotation; targetTransform.rotation = oldTarget.transform.rotation;
HandTarget handTarget = Constructor(humanoid, oldTarget.isLeft, targetTransform); //HandTarget handTarget = Constructor(humanoid, oldTarget.isLeft, targetTransform);
HandTarget handTarget = targetTransform.gameObject.AddComponent<HandTarget>();
handTarget.Constructor(humanoid, oldTarget.isLeft);
if (oldTarget.isLeft) { if (oldTarget.isLeft) {
humanoid.leftHandTarget = handTarget; humanoid.leftHandTarget = handTarget;
//handTarget.otherHand = humanoid.rightHandTarget; //handTarget.otherHand = humanoid.rightHandTarget;
@ -804,11 +830,22 @@ namespace Passer.Humanoid {
public void RetrieveBones() { public void RetrieveBones() {
foreach (TargetedBone subTarget in subTargets) foreach (TargetedBone subTarget in subTargets)
subTarget.RetrieveBones(humanoid); subTarget.RetrieveBones();
fingers.RetrieveBones(this); fingers.RetrieveBones(this);
} }
public void RetrieveBonesWithoutAvatar(Transform rootBone) {
Transform arm = HumanoidTarget.FindTransformByPartialName(humanoid.headTarget.neck.parent.bone.transform, isLeft ? "left" : "right");
if (arm == null)
arm = HumanoidTarget.FindTransformByPartialName(humanoid.headTarget.neck.parent.bone.transform, isLeft ? "_L" : "_R");
// This can still find the left side of the head....
shoulder.RetrieveBoneWithoutAvatar(arm);
upperArm.RetrieveBoneWithoutAvatar(arm);
forearm.RetrieveBoneWithoutAvatar(arm);
hand.RetrieveBoneWithoutAvatar(arm);
}
#endregion #endregion
#region Settings #region Settings
@ -1225,18 +1262,6 @@ namespace Passer.Humanoid {
#endif #endif
} }
// This function is called only when the humanoid is created
private static HandTarget Constructor(HumanoidControl humanoid, bool isLeft, Transform handTargetTransform) {
HandTarget handTarget = handTargetTransform.gameObject.AddComponent<HandTarget>();
handTarget.humanoid = humanoid;
handTarget.isLeft = isLeft;
handTarget.side = isLeft ? Side.Left : Side.Right;
handTarget.outward = handTarget.isLeft ? Vector3.left : Vector3.right;
handTarget.InitSubTargets();
return handTarget;
}
public override void NewComponent(HumanoidControl _humanoid) { public override void NewComponent(HumanoidControl _humanoid) {
humanoid = _humanoid; humanoid = _humanoid;
isLeft = (this == humanoid.leftHandTarget); isLeft = (this == humanoid.leftHandTarget);
@ -1347,8 +1372,10 @@ namespace Passer.Humanoid {
} }
handTarget = handTargetTransform.GetComponent<HandTarget>(); handTarget = handTargetTransform.GetComponent<HandTarget>();
if (handTarget == null) if (handTarget == null) {
handTarget = Constructor(humanoid, isLeft, handTargetTransform); handTarget = handTargetTransform.gameObject.AddComponent<HandTarget>();
handTarget.Constructor(humanoid, isLeft);
}
} }
if (isLeft) if (isLeft)

View File

@ -65,7 +65,12 @@ namespace Passer.Humanoid {
[HelpURL("https://passervr.com/apis/HumanoidControl/Unity/class_passer_1_1_humanoid_1_1_head_target.html")] [HelpURL("https://passervr.com/apis/HumanoidControl/Unity/class_passer_1_1_humanoid_1_1_head_target.html")]
public class HeadTarget : HumanoidTarget { public class HeadTarget : HumanoidTarget {
public HeadTarget() { /// <summary>
/// Pseudo-constructor because Unity does not use real constructors with arguments
/// </summary>
/// <param name="humanoid">The humanoid for this head target</param>
public void Constructor(HumanoidControl humanoid) {
this.humanoid = humanoid;
neck = new TargetedNeckBone(this); neck = new TargetedNeckBone(this);
head = new TargetedHeadBone(this); head = new TargetedHeadBone(this);
#if hFACE #if hFACE
@ -310,7 +315,7 @@ namespace Passer.Humanoid {
public class TargetedHeadBone : TargetedBone { public class TargetedHeadBone : TargetedBone {
private HeadTarget headTarget; private HeadTarget headTarget;
public TargetedHeadBone(HeadTarget headTarget) { public TargetedHeadBone(HeadTarget headTarget) : base(headTarget.humanoid) {
this.headTarget = headTarget; this.headTarget = headTarget;
boneId = Bone.Head; boneId = Bone.Head;
@ -325,6 +330,14 @@ namespace Passer.Humanoid {
nextBone = null; nextBone = null;
} }
public override Transform RetrieveBoneWithoutAvatar(Transform rootBone) {
if (parent.bone.transform != null)
bone.transform = FindTransformByPartialName(parent.bone.transform, "head");
else
bone.transform = FindTransformByPartialName(rootBone, "head");
return bone.transform;
}
public override Quaternion DetermineRotation() { public override Quaternion DetermineRotation() {
if (headTarget == null) if (headTarget == null)
return Quaternion.identity; return Quaternion.identity;
@ -386,13 +399,14 @@ namespace Passer.Humanoid {
#endregion #endregion
#region Neck #region Neck
public TargetedNeckBone neck = null; public TargetedNeckBone neck = null;
[System.Serializable] [System.Serializable]
public class TargetedNeckBone : TargetedBone { public class TargetedNeckBone : TargetedBone {
public HeadTarget headTarget; public HeadTarget headTarget;
public TargetedNeckBone(HeadTarget headTarget) { public TargetedNeckBone(HeadTarget headTarget) : base(headTarget.humanoid) {
this.headTarget = headTarget; this.headTarget = headTarget;
boneId = Bone.Neck; boneId = Bone.Neck;
@ -411,6 +425,15 @@ namespace Passer.Humanoid {
nextBone = headTarget.head; nextBone = headTarget.head;
} }
public override Transform RetrieveBoneWithoutAvatar(Transform rootBone) {
Init();
if (parent.bone.transform != null)
bone.transform = FindTransformByPartialName(parent.bone.transform, "neck");
else
bone.transform = FindTransformByPartialName(rootBone, "neck");
return bone.transform;
}
public override Quaternion DetermineRotation() { public override Quaternion DetermineRotation() {
if (headTarget == null) if (headTarget == null)
return Quaternion.identity; return Quaternion.identity;
@ -434,6 +457,7 @@ namespace Passer.Humanoid {
return tension; return tension;
} }
} }
#endregion #endregion
private void InitSubTargets() { private void InitSubTargets() {
@ -557,14 +581,19 @@ namespace Passer.Humanoid {
} }
public void RetrieveBones() { public void RetrieveBones() {
neck.RetrieveBones(humanoid); neck.RetrieveBones();
head.RetrieveBones(humanoid); head.RetrieveBones();
#if hFACE #if hFACE
face.InitComponent(); face.InitComponent();
face.RetrieveBones(this); face.RetrieveBones(this);
#endif #endif
} }
public void RetrieveBonesWithoutAvatar(Transform rootBone) {
neck.RetrieveBoneWithoutAvatar(rootBone);
head.RetrieveBoneWithoutAvatar(rootBone);
}
public static void GetDefaultNeck(Animator rig, ref Transform boneTransform) { public static void GetDefaultNeck(Animator rig, ref Transform boneTransform) {
GetDefaultBone(rig, ref boneTransform, HumanBodyBones.Neck, "Neck", "neck"); GetDefaultBone(rig, ref boneTransform, HumanBodyBones.Neck, "Neck", "neck");
if (boneTransform == null) { if (boneTransform == null) {
@ -826,7 +855,7 @@ namespace Passer.Humanoid {
headTarget = headTargetTransform.GetComponent<HeadTarget>(); headTarget = headTargetTransform.GetComponent<HeadTarget>();
if (headTarget == null) { if (headTarget == null) {
headTarget = headTargetTransform.gameObject.AddComponent<HeadTarget>(); headTarget = headTargetTransform.gameObject.AddComponent<HeadTarget>();
headTarget.humanoid = humanoid; headTarget.Constructor(humanoid);
} }
humanoid.headTarget = headTarget; humanoid.headTarget = headTarget;
} }

View File

@ -41,7 +41,12 @@ namespace Passer.Humanoid {
[HelpURL("https://passervr.com/apis/HumanoidControl/Unity/class_passer_1_1_humanoid_1_1_hips_target.html")] [HelpURL("https://passervr.com/apis/HumanoidControl/Unity/class_passer_1_1_humanoid_1_1_hips_target.html")]
public partial class HipsTarget : HumanoidTarget { public partial class HipsTarget : HumanoidTarget {
public HipsTarget() { /// <summary>
/// Pseudo-constructor because Unity does not use real constructors with arguments
/// </summary>
/// <param name="humanoid">The humanoid for this hips target</param>
public void Constructor(HumanoidControl humanoid) {
this.humanoid = humanoid;
chest = new TargetedChestBone(this); chest = new TargetedChestBone(this);
spine = new TargetedSpineBone(this); spine = new TargetedSpineBone(this);
hips = new TargetedHipsBone(this); hips = new TargetedHipsBone(this);
@ -165,7 +170,7 @@ namespace Passer.Humanoid {
public class TargetedChestBone : TargetedBone { public class TargetedChestBone : TargetedBone {
private HipsTarget hipsTarget; private HipsTarget hipsTarget;
public TargetedChestBone(HipsTarget hipsTarget) { public TargetedChestBone(HipsTarget hipsTarget) : base(hipsTarget.humanoid) {
this.hipsTarget = hipsTarget; this.hipsTarget = hipsTarget;
boneId = Bone.Chest; boneId = Bone.Chest;
} }
@ -178,6 +183,14 @@ namespace Passer.Humanoid {
boneId = Bone.Chest; boneId = Bone.Chest;
} }
public override Transform RetrieveBoneWithoutAvatar(Transform rootBone) {
bone.transform = FindTransformByPartialName(rootBone, "chest");
if (bone.transform == null)
bone.transform = FindTransformByPartialName(rootBone, "spine2");
return bone.transform;
}
public override Quaternion DetermineRotation() { public override Quaternion DetermineRotation() {
if (nextBone.bone.transform == null) if (nextBone.bone.transform == null)
return Quaternion.identity; return Quaternion.identity;
@ -211,7 +224,7 @@ namespace Passer.Humanoid {
public class TargetedSpineBone : TargetedBone { public class TargetedSpineBone : TargetedBone {
private HipsTarget hipsTarget; private HipsTarget hipsTarget;
public TargetedSpineBone(HipsTarget hipsTarget) { public TargetedSpineBone(HipsTarget hipsTarget) : base(hipsTarget.humanoid) {
this.hipsTarget = hipsTarget; this.hipsTarget = hipsTarget;
boneId = Bone.Spine; boneId = Bone.Spine;
} }
@ -225,6 +238,11 @@ namespace Passer.Humanoid {
boneId = Bone.Spine; boneId = Bone.Spine;
} }
public override Transform RetrieveBoneWithoutAvatar(Transform rootBone) {
bone.transform = FindTransformByPartialName(rootBone, "spine");
return bone.transform;
}
public override Quaternion DetermineRotation() { public override Quaternion DetermineRotation() {
Vector3 spineUpDirection = hipsTarget.humanoid.up; Vector3 spineUpDirection = hipsTarget.humanoid.up;
if (nextBone != null && nextBone.bone.transform != null) if (nextBone != null && nextBone.bone.transform != null)
@ -254,7 +272,7 @@ namespace Passer.Humanoid {
public class TargetedHipsBone : TargetedBone { public class TargetedHipsBone : TargetedBone {
public HipsTarget hipsTarget; public HipsTarget hipsTarget;
public TargetedHipsBone(HipsTarget hipsTarget) { public TargetedHipsBone(HipsTarget hipsTarget) : base(hipsTarget.humanoid) {
this.hipsTarget = hipsTarget; this.hipsTarget = hipsTarget;
boneId = Bone.Hips; boneId = Bone.Hips;
} }
@ -270,10 +288,11 @@ namespace Passer.Humanoid {
boneId = Bone.Hips; boneId = Bone.Hips;
} }
public override void RetrieveBones(HumanoidControl humanoid) { public override Transform RetrieveBoneWithoutAvatar(Transform rootBone) {
base.RetrieveBones(humanoid); bone.transform = FindTransformByPartialName(rootBone, "hips");
if (bone.transform == null) if (bone.transform == null)
HumanoidTarget.GetDefaultBone(humanoid.transform, ref bone.transform, "Default_simple|Hips"); bone.transform = FindTransformByPartialName(rootBone, "pelvis");
return bone.transform;
} }
public Vector3 GetForward() { public Vector3 GetForward() {
@ -430,9 +449,15 @@ namespace Passer.Humanoid {
} }
public void RetrieveBones() { public void RetrieveBones() {
hips.RetrieveBones(humanoid); hips.RetrieveBones();
spine.RetrieveBones(humanoid); spine.RetrieveBones();
chest.RetrieveBones(humanoid); chest.RetrieveBones();
}
public void RetrieveBonesWithoutAvatar(Transform rootBone) {
hips.RetrieveBoneWithoutAvatar(rootBone);
spine.RetrieveBoneWithoutAvatar(rootBone);
chest.RetrieveBoneWithoutAvatar(rootBone);
} }
#endregion #endregion
@ -530,7 +555,7 @@ namespace Passer.Humanoid {
// We need the neck.bone to measure the chest length. This can be null when the avatar is changed // We need the neck.bone to measure the chest length. This can be null when the avatar is changed
if (humanoid.headTarget.neck.bone.transform == null) if (humanoid.headTarget.neck.bone.transform == null)
humanoid.headTarget.neck.RetrieveBones(humanoid); humanoid.headTarget.neck.RetrieveBones();
//HeadTarget.GetDefaultNeck(humanoid.avatarRig, ref humanoid.headTarget.neck.bone.transform); //HeadTarget.GetDefaultNeck(humanoid.avatarRig, ref humanoid.headTarget.neck.bone.transform);
humanoid.headTarget.neck.SetTargetPositionToAvatar(); humanoid.headTarget.neck.SetTargetPositionToAvatar();
@ -598,7 +623,7 @@ namespace Passer.Humanoid {
hipsTarget = hipsTargetTransform.GetComponent<HipsTarget>(); hipsTarget = hipsTargetTransform.GetComponent<HipsTarget>();
if (hipsTarget == null) { if (hipsTarget == null) {
hipsTarget = hipsTargetTransform.gameObject.AddComponent<HipsTarget>(); hipsTarget = hipsTargetTransform.gameObject.AddComponent<HipsTarget>();
hipsTarget.humanoid = humanoid; hipsTarget.Constructor(humanoid);
} }
} }

View File

@ -213,34 +213,49 @@ namespace Passer.Humanoid {
// 1 = MCS / Morph3D // 1 = MCS / Morph3D
// 2 = AutoDesk // 2 = AutoDesk
public static void GetDefaultBone(Animator rig, ref Transform boneTransform, params string[] boneNames) { public static void GetDefaultBone(Animator rig, ref Transform boneTransform, params string[] boneNames) {
GetDefaultBoneByName(rig.transform, ref boneTransform, boneNames);
}
public static void GetDefaultBoneByName(Transform root, ref Transform boneTransform, params string[] boneNames) {
if (boneTransform != null) if (boneTransform != null)
// We already have found a bone
return; return;
for (int i = 0; i < boneNames.Length; i++) { foreach (string boneName in boneNames) {
if (boneNames[i] == null) if (string.IsNullOrEmpty(boneName))
continue; continue;
boneTransform = rig.transform.FindDeepChild(boneNames[i]); boneTransform = root.FindDeepChild(boneName);
if (boneTransform != null) if (boneTransform != null)
return; return;
} }
} }
public static void GetDefaultBone(Transform root, ref Transform boneTransform, params string[] boneNames) { /// <summary>
if (boneTransform != null) /// Recursively find a Transform whose name contains the partialName
return; /// </summary>
/// <param name="transform">The starting transform for the search</param>
/// <param name="partialName">The string which should be inside by the name</param>
/// <returns>The found Transform or null when no Transform has been found</returns>
/// <remarks>The search stops at transforms with more than 1 child</remarks>
public static Transform FindTransformByPartialName(Transform transform, string partialName) {
if (transform == null)
return null;
for (int i = 0; i < boneNames.Length; i++) { // Case-insensitive string.Contains
if (boneNames[i] == null) if (transform.name.IndexOf(partialName, System.StringComparison.OrdinalIgnoreCase) >= 0)
continue; return transform;
boneTransform = root.FindDeepChild(boneNames[i]); Transform foundTransform = null;
if (boneTransform != null) for (int childIx = 0; childIx < transform.childCount; childIx++) {
return; foundTransform = FindTransformByPartialName(transform.GetChild(childIx), partialName);
if (foundTransform != null)
return foundTransform;
} }
return null;
} }
public abstract void UpdateMovements(HumanoidControl humanoid); public abstract void UpdateMovements(HumanoidControl humanoid);
public abstract void MatchTargetsToAvatar(); public abstract void MatchTargetsToAvatar();
@ -396,9 +411,16 @@ namespace Passer.Humanoid {
[System.NonSerialized] [System.NonSerialized]
public TargetedBone nextBone; public TargetedBone nextBone;
public TargetedBone() { } protected HumanoidControl humanoid;
public TargetedBone(TargetedBone _nextBone) { public TargetedBone(HumanoidControl humanoid) {
if (humanoid == null)
throw new System.Exception("Humanoid may not be null");
this.humanoid = humanoid;
}
public TargetedBone(HumanoidControl humanoid, TargetedBone _nextBone) {
if (humanoid == null)
throw new System.Exception("Humanoid may not be null");
nextBone = _nextBone; nextBone = _nextBone;
} }
@ -415,19 +437,36 @@ namespace Passer.Humanoid {
return obj.transform; return obj.transform;
} }
public virtual void RetrieveBones(HumanoidControl humanoid) { public virtual void RetrieveBones() {
if (humanoid.targetsRig != null) if (this.humanoid == null)
GetDefaultTargetBone(humanoid.targetsRig, ref target.transform, boneId); return;
if (humanoid.avatarRig != null)
GetDefaultBone(humanoid.avatarRig, ref bone.transform, boneId); if (this.humanoid.targetsRig != null)
GetDefaultTargetBone(this.humanoid.targetsRig, ref target.transform, boneId);
if (this.humanoid.avatarRig != null)
GetDefaultBone(this.humanoid.avatarRig, ref bone.transform, boneId);
} }
public void RetrieveBone(HumanoidControl humanoid, HumanBodyBones boneID) { public void RetrieveBone(HumanBodyBones boneID) {
if ((bone.transform == null || bone.transform == null) && humanoid.avatarRig != null) { if ((bone.transform == null || bone.transform == null) && this.humanoid.avatarRig != null) {
bone.transform = humanoid.avatarRig.GetBoneTransform(boneID); bone.transform = this.humanoid.avatarRig.GetBoneTransform(boneID);
} }
} }
public virtual Transform RetrieveBoneWithoutAvatar(Transform rootBone) {
return null;
}
//public static Transform RetrieveBoneByName(Transform rootBone, string transformName) {
// Transform parentTransform;
// //if (this.parent != null && this.parent.bone.transform != null)
// // parentTransform = this.parent.bone.transform;
// //else
// parentTransform = rootBone;
// return HumanoidTarget.FindTransformByPartialName(parentTransform, transformName);
//}
public virtual Quaternion DetermineRotation() { public virtual Quaternion DetermineRotation() {
if (target.transform != null) if (target.transform != null)
return target.transform.rotation; return target.transform.rotation;

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 86153051f48cf8c488177d8f1b7aedaa
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: