GOT IT
Turns out the neutral pose that drew pasted has some bad rotations in it. This is all super hacked together but is a good starting point. Using this index map:
enum JointIndices
{
Invalid = -1,
Root = 0, // parent: Invalid
Hips = 1, // parent: Root
LeftUpLeg = 2, // parent: Hips
LeftLeg = 3, // parent: LeftUpLeg
LeftFoot = 4, // parent: LeftLeg
LeftToes = 5, // parent: LeftFoot
LeftToesEnd = 6, // parent: LeftToes
RightUpLeg = 7, // parent: Hips
RightLeg = 8, // parent: RightUpLeg
RightFoot = 9, // parent: RightLeg
RightToes = 10, // parent: RightFoot
RightToesEnd = 11, // parent: RightToes
Spine1 = 12, // parent: Hips
Spine2 = 13, // parent: Spine1
Spine3 = 14, // parent: Spine2
Spine4 = 15, // parent: Spine3
Spine5 = 16, // parent: Spine4
Spine6 = 17, // parent: Spine5
Spine7 = 18, // parent: Spine6
RightShoulder1 = 19, // parent: Spine7
RightShoulder2 = 20, // parent: RightShoulder1
RightArm = 21, // parent: RightShoulder2
RightForearm = 22, // parent: RightArm
RightHand = 23, // parent: RightForearm
RightHandThumbStart = 24, // parent: RightHand
RightHandThumb1 = 25, // parent: RightHandThumbStart
RightHandThumb2 = 26, // parent: RightHandThumb1
RightHandThumbEnd = 27, // parent: RightHandThumb2
RightHandIndexStart = 28, // parent: RightHand
RightHandIndex1 = 29, // parent: RightHandIndexStart
RightHandIndex2 = 30, // parent: RightHandIndex1
RightHandIndex3 = 31, // parent: RightHandIndex2
RightHandIndexEnd = 32, // parent: RightHandIndex3
RightHandMidStart = 33, // parent: RightHand
RightHandMid1 = 34, // parent: RightHandMidStart
RightHandMid2 = 35, // parent: RightHandMid1
RightHandMid3 = 36, // parent: RightHandMid2
RightHandMidEnd = 37, // parent: RightHandMid3
RightHandRingStart = 38, // parent: RightHand
RightHandRing1 = 39, // parent: RightHandRingStart
RightHandRing2 = 40, // parent: RightHandRing1
RightHandRing3 = 41, // parent: RightHandRing2
RightHandRingEnd = 42, // parent: RightHandRing3
RightHandPinkyStart = 43, // parent: RightHand
RightHandPinky1 = 44, // parent: RightHandPinkyStart
RightHandPinky2 = 45, // parent: RightHandPinky1
RightHandPinky3 = 46, // parent: RightHandPinky2
RightHandPinkyEnd = 47, // parent: RightHandPinky3
LeftShoulder1 = 48, // parent: Spine7
LeftShoulder2 = 49, // parent: LeftShoulder1
LeftArm = 50, // parent: LeftShoulder2
LeftForearm = 51, // parent: LeftArm
LeftHand = 52, // parent: LeftForearm
LeftHandThumbStart = 53, // parent: LeftHand
LeftHandThumb1 = 54, // parent: LeftHandThumbStart
LeftHandThumb2 = 55, // parent: LeftHandThumb1
LeftHandThumbEnd = 56, // parent: LeftHandThumb2
LeftHandIndexStart = 57, // parent: LeftHand
LeftHandIndex1 = 58, // parent: LeftHandIndexStart
LeftHandIndex2 = 59, // parent: LeftHandIndex1
LeftHandIndex3 = 60, // parent: LeftHandIndex2
LeftHandIndexEnd = 61, // parent: LeftHandIndex3
LeftHandMidStart = 62, // parent: LeftHand
LeftHandMid1 = 63, // parent: LeftHandMidStart
LeftHandMid2 = 64, // parent: LeftHandMid1
LeftHandMid3 = 65, // parent: LeftHandMid2
LeftHandMidEnd = 66, // parent: LeftHandMid3
LeftHandRingStart = 67, // parent: LeftHand
LeftHandRing1 = 68, // parent: LeftHandRingStart
LeftHandRing2 = 69, // parent: LeftHandRing1
LeftHandRing3 = 70, // parent: LeftHandRing2
LeftHandRingEnd = 71, // parent: LeftHandRing3
LeftHandPinkyStart = 72, // parent: LeftHand
LeftHandPinky1 = 73, // parent: LeftHandPinkyStart
LeftHandPinky2 = 74, // parent: LeftHandPinky1
LeftHandPinky3 = 75, // parent: LeftHandPinky2
LeftHandPinkyEnd = 76, // parent: LeftHandPinky3
Neck1 = 77, // parent: Spine7
Neck2 = 78, // parent: Neck1
Neck3 = 79, // parent: Neck2
Neck4 = 80, // parent: Neck3
Head = 81, // parent: Neck4
Jaw = 82, // parent: Head
Chin = 83, // parent: Jaw
Nose = 84, // parent: Head
RightEye = 85, // parent: Head
RightEyeUpperLid = 86, // parent: RightEye
RightEyeLowerLid = 87, // parent: RightEye
RightEyeBall = 88, // parent: RightEye
LeftEye = 89, // parent: Head
LeftEyeUpperLid = 90, // parent: LeftEye
LeftEyeLowerLid = 91, // parent: LeftEye
LeftEyeBall = 92, // parent: LeftEye
}
I dumped the T pose of the robot into a dictionary IN WORLD COORDINATES:
private Dictionary<JointIndices, Quaternion> ROBOTPOSE = new Dictionary<JointIndices, Quaternion>
{
{ JointIndices.Root, new Quaternion(0f, 0f, 0f, 1f) },{ JointIndices.Hips, new Quaternion(0f, 0f, 0f, 1f) },{ JointIndices.LeftUpLeg, new Quaternion(-0.5251914f, 0.4729119f, 0.5257655f, -0.4733909f) },{ JointIndices.RightUpLeg, new Quaternion(-0.4731499f, -0.5254809f, 0.4731455f, 0.5254829f) },{ JointIndices.Spine1, new Quaternion(-0.5f, -0.5f, 0.5f, 0.5f) },{ JointIndices.LeftLeg, new Quaternion(-0.4589739f, 0.5374146f, 0.4594831f, -0.5379627f) },{ JointIndices.RightLeg, new Quaternion(-0.5376937f, -0.4592238f, 0.5376896f, 0.4592263f) },{ JointIndices.Spine2, new Quaternion(-0.5f, -0.5f, 0.5f, 0.5f) },{ JointIndices.LeftFoot, new Quaternion(-0.6927235f, 0.1400152f, 0.6934642f, -0.1401326f) },{ JointIndices.RightFoot, new Quaternion(-0.1400807f, -0.6930928f, 0.1400763f, 0.6930935f) },{ JointIndices.Spine3, new Quaternion(-0.5f, -0.5f, 0.5f, 0.5f) },{ JointIndices.LeftToes, new Quaternion(-0.7067051f, 0.006181896f, 0.7074544f, -0.006156165f) },{ JointIndices.RightToes, new Quaternion(-0.006176293f, -0.7070798f, 0.006170991f, 0.7070799f) },{ JointIndices.Spine4, new Quaternion(-0.5f, -0.5f, 0.5f, 0.5f) },{ JointIndices.LeftToesEnd, new Quaternion(-0.7067052f, 0.006181717f, 0.7074544f, -0.006156351f) },{ JointIndices.RightToesEnd, new Quaternion(-0.00617677f, -0.7070798f, 0.006170507f, 0.7070799f) },{ JointIndices.Spine5, new Quaternion(-0.4925276f, -0.5073624f, 0.4925276f, 0.5073624f) },{ JointIndices.Spine6, new Quaternion(-0.4925276f, -0.5073624f, 0.4925276f, 0.5073624f) },{ JointIndices.Spine7, new Quaternion(-0.4925276f, -0.5073624f, 0.4925276f, 0.5073624f) },{ JointIndices.RightShoulder1, new Quaternion(-0.7004818f, -0.08645806f, 0.09656784f, 0.7018013f) },{ JointIndices.LeftShoulder1, new Quaternion(-0.7017999f, 0.09655666f, 0.08646959f, -0.7004833f) },{ JointIndices.Neck1, new Quaternion(-0.5572078f, -0.4353384f, 0.5572078f, 0.4353384f) },{ JointIndices.RightShoulder2, new Quaternion(-0.7004818f, -0.08645806f, 0.09656784f, 0.7018013f) },{ JointIndices.LeftShoulder2, new Quaternion(-0.7017999f, 0.09655666f, 0.08646959f, -0.7004833f) },{ JointIndices.Neck2, new Quaternion(-0.5572078f, -0.4353384f, 0.5572078f, 0.4353384f) },{ JointIndices.RightArm, new Quaternion(-0.7072251f, -4.330277E-05f, -0.0008040965f, 0.706988f) },{ JointIndices.LeftArm, new Quaternion(-0.7069915f, -0.0008285469f, 7.144874E-05f, -0.7072218f) },{ JointIndices.Neck3, new Quaternion(-0.5572078f, -0.4353384f, 0.5572078f, 0.4353384f) },{ JointIndices.RightForearm, new Quaternion(-0.706572f, -0.03035438f, -0.03110623f, 0.7063052f) },{ JointIndices.LeftForearm, new Quaternion(-0.7063079f, -0.03109138f, 0.03034304f, -0.7065705f) },{ JointIndices.Neck4, new Quaternion(-0.5572078f, -0.4353384f, 0.5572078f, 0.4353384f) },{ JointIndices.RightHand, new Quaternion(-0.0001886487f, -0.04345921f, -0.0005316734f, 0.9990551f) },{ JointIndices.LeftHand, new Quaternion(-0.999056f, -0.0005290508f, 0.04344079f, -0.0001838654f) },{ JointIndices.Head, new Quaternion(-0.4956177f, -0.5043442f, 0.4956177f, 0.5043442f) },{ JointIndices.RightHandThumbStart, new Quaternion(-0.563176f, -0.450308f, -0.1651125f, 0.6728995f) },{ JointIndices.RightHandIndexStart, new Quaternion(-0.001846135f, -0.1037805f, -0.0003555566f, 0.9945986f) },{ JointIndices.RightHandMidStart, new Quaternion(-0.001781464f, -0.04345801f, -0.0004611611f, 0.9990537f) },{ JointIndices.RightHandRingStart, new Quaternion(-0.001758099f, 0.006566688f, -0.0005474091f, 0.9999769f) },{ JointIndices.RightHandPinkyStart, new Quaternion(-0.00176309f, 0.05727234f, -0.0006380975f, 0.9983569f) },{ JointIndices.LeftHandThumbStart, new Quaternion(-0.6729128f, -0.16509f, 0.4503065f, -0.5631677f) },{ JointIndices.LeftHandIndexStart, new Quaternion(-0.9946009f, -0.0003358126f, 0.1037586f, -0.00184305f) },{ JointIndices.LeftHandMidStart, new Quaternion(-0.9990543f, -0.000755012f, 0.04344012f, -0.001763821f) },{ JointIndices.LeftHandRingStart, new Quaternion(-0.9999767f, -0.0005270988f, -0.006585166f, -0.001753271f) },{ JointIndices.LeftHandPinkyStart, new Quaternion(-0.9983559f, -0.0006175488f, -0.05729078f, -0.001757562f) },{ JointIndices.Jaw, new Quaternion(-0.4956177f, -0.5043442f, 0.4956177f, 0.5043442f) },{ JointIndices.Nose, new Quaternion(-0.5000001f, -0.5000001f, 0.5000001f, 0.5000001f) },{ JointIndices.RightEye, new Quaternion(-0.4999974f, -0.5000026f, 0.4999974f, 0.5000026f) },{ JointIndices.LeftEye, new Quaternion(-0.4999974f, -0.5000026f, 0.4999974f, 0.5000026f) },{ JointIndices.RightHandThumb1, new Quaternion(-0.6383249f, -0.3353892f, -0.0345653f, 0.691998f) },{ JointIndices.RightHandIndex1, new Quaternion(-0.141001f, -0.06067762f, 0.1492173f, 0.976817f) },{ JointIndices.RightHandMid1, new Quaternion(-0.001823545f, -0.01739544f, 0.08677565f, 0.9960744f) },{ JointIndices.RightHandRing1, new Quaternion(0.0863688f, 0.043634f, 0.0978535f, 0.9904854f) },{ JointIndices.RightHandPinky1, new Quaternion(0.1280032f, 0.08536577f, 0.1233153f, 0.980368f) },{ JointIndices.LeftHandThumb1, new Quaternion(-0.6920068f, -0.03454062f, 0.3353892f, -0.6383165f) },{ JointIndices.LeftHandIndex1, new Quaternion(-0.9768156f, 0.1492398f, 0.06065904f, -0.1409955f) },{ JointIndices.LeftHandMid1, new Quaternion(-0.9961001f, 0.08648346f, 0.01738015f, -0.001796693f) },{ JointIndices.LeftHandRing1, new Quaternion(-0.9904823f, 0.09787226f, -0.04365361f, 0.08637467f) },{ JointIndices.LeftHandPinky1, new Quaternion(-0.980363f, 0.1233332f, -0.08538568f, 0.1280103f) },{ JointIndices.Chin, new Quaternion(-0.4956177f, -0.5043442f, 0.4956177f, 0.5043442f) },{ JointIndices.RightEyeUpperLid, new Quaternion(-0.4999974f, -0.5000026f, 0.4999974f, 0.5000026f) },{ JointIndices.RightEyeLowerLid, new Quaternion(-0.4999974f, -0.5000026f, 0.4999974f, 0.5000026f) },{ JointIndices.RightEyeBall, new Quaternion(-0.4999974f, -0.5000026f, 0.4999974f, 0.5000026f) },{ JointIndices.LeftEyeUpperLid, new Quaternion(-0.4999974f, -0.5000026f, 0.4999974f, 0.5000026f) },{ JointIndices.LeftEyeLowerLid, new Quaternion(-0.4999974f, -0.5000026f, 0.4999974f, 0.5000026f) },{ JointIndices.LeftEyeBall, new Quaternion(-0.4999974f, -0.5000026f, 0.4999974f, 0.5000026f) },{ JointIndices.RightHandThumb2, new Quaternion(-0.6677005f, -0.2722507f, 0.03234765f, 0.692105f) },{ JointIndices.RightHandIndex2, new Quaternion(-0.1477825f, -0.0415144f, 0.2769809f, 0.9485351f) },{ JointIndices.RightHandMid2, new Quaternion(-0.004873842f, -0.01679799f, 0.2617181f, 0.964986f) },{ JointIndices.RightHandRing2, new Quaternion(0.0938583f, 0.02353925f, 0.3136097f, 0.9446088f) },{ JointIndices.RightHandPinky2, new Quaternion(0.1357787f, 0.07236205f, 0.2191423f, 0.9634857f) },{ JointIndices.LeftHandThumb2, new Quaternion(-0.6921116f, 0.03237311f, 0.2722515f, -0.6676922f) },{ JointIndices.LeftHandIndex2, new Quaternion(-0.9485307f, 0.277003f, 0.04149672f, -0.1477744f) },{ JointIndices.LeftHandMid2, new Quaternion(-0.965063f, 0.2614351f, 0.01678771f, -0.004844725f) },{ JointIndices.LeftHandRing2, new Quaternion(-0.9446015f, 0.3136272f, -0.0235571f, 0.09386835f) },{ JointIndices.LeftHandPinky2, new Quaternion(-0.963479f, 0.2191598f, -0.07238111f, 0.1357878f) },{ JointIndices.RightHandThumbEnd, new Quaternion(-0.6677005f, -0.2722507f, 0.03234762f, 0.692105f) },{ JointIndices.RightHandIndex3, new Quaternion(-0.1494033f, -0.03523868f, 0.3167771f, 0.9359966f) },{ JointIndices.RightHandMid3, new Quaternion(-0.005977005f, -0.01643786f, 0.325129f, 0.945508f) },{ JointIndices.RightHandRing3, new Quaternion(0.09519702f, 0.01735026f, 0.3747187f, 0.9220752f) },{ JointIndices.RightHandPinky3, new Quaternion(0.1402616f, 0.06323615f, 0.2822996f, 0.9469081f) },{ JointIndices.LeftHandThumbEnd, new Quaternion(-0.6921116f, 0.03237309f, 0.2722515f, -0.6676922f) },{ JointIndices.LeftHandIndex3, new Quaternion(-0.9358417f, 0.3172399f, 0.03515086f, -0.1494111f) },{ JointIndices.LeftHandMid3, new Quaternion(-0.9456036f, 0.3248518f, 0.01642954f, -0.005947292f) },{ JointIndices.LeftHandRing3, new Quaternion(-0.9446015f, 0.3136272f, -0.0235571f, 0.09386835f) },{ JointIndices.LeftHandPinky3, new Quaternion(-0.9469005f, 0.2823165f, -0.06325462f, 0.1402719f) },{ JointIndices.RightHandIndexEnd, new Quaternion(-0.1494033f, -0.03523868f, 0.3167771f, 0.9359965f) },{ JointIndices.RightHandMidEnd, new Quaternion(-0.005977005f, -0.01643786f, 0.325129f, 0.945508f) },{ JointIndices.RightHandRingEnd, new Quaternion(0.09519702f, 0.01735026f, 0.3747187f, 0.9220752f) },{ JointIndices.RightHandPinkyEnd, new Quaternion(0.1402616f, 0.06323615f, 0.2822996f, 0.9469081f) },{ JointIndices.LeftHandIndexEnd, new Quaternion(-0.9358417f, 0.3172399f, 0.03515095f, -0.1494111f) },{ JointIndices.LeftHandMidEnd, new Quaternion(-0.9456036f, 0.3248518f, 0.01642954f, -0.005947292f) },{ JointIndices.LeftHandRingEnd, new Quaternion(-0.9446015f, 0.3136272f, -0.0235571f, 0.09386835f) },{ JointIndices.LeftHandPinkyEnd, new Quaternion(-0.9469005f, 0.2823165f, -0.06325462f, 0.1402719f) },
};
At initialization - I compare my character’s T pose to the robot’s T pose - create a rotation that will convert from “robot joint space” to “my joint’s space” - and store that value for later:
foreach (var jointKeyValuePair in MyRigJoints)
{
//current world rotation of the joint in my rig
Quaternion startingRot = jointKeyValuePair.Value.rotation;
//arkit t pose
Quaternion robotJointRotation = Quaternion.identity;
JointIndices index = jointKeyValuePair.Key;
if (!ROBOTPOSE.TryGetValue(index, out robotJointRotation))
{
Debug.LogError("key missing is " + jointKeyValuePair.Key.ToString());
continue;
}
//conversionRotation can convert ARKit rotations to somewthing we can apply to our rig
var conversionRotation = Quaternion.Inverse(robotJointRotation) * startingRot;
RotationCompensations[index] = compensate;
}
Then later when you get the updated human body pose from ARKit, you apply that stored compensation to the arkit rotations:
myjointTransform.rotation = ARHumanBody.joints[index].anchorPose.rotation * RotationCompensations[index];
The closer your character’s T pose is to the reference T pose - the more accurate your animations will be.
Since all of this is in world space - you’ll still need to account for any parent transforms. Eventually I’d like to get this working in local space…but really I just want to move on at this point.
Hope that helps and fixes everyone else’s issues. Thanks again for all the help folks.