Skip to content

Commit 40bfb0e

Browse files
sohailshafiiWkfacebook-github-bot
authored andcommitted
fix(Runtime): Allow multiple rotation adjustments for retargeting
Summary: Allow a joint to be affected by multiple joint rotations. Eventually, this change would need to exist in `OVRUnityHumanoidSkeletonRetargeter`. Reviewed By: andkim-meta Differential Revision: D48768146 fbshipit-source-id: e03c4918caea42f1251466f6d4305c4087155c09
1 parent fd8e15b commit 40bfb0e

File tree

3 files changed

+151
-10
lines changed

3 files changed

+151
-10
lines changed

Runtime/Scripts/AnimationRigging/RetargetingLayer.cs

Lines changed: 138 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,25 @@ public Vector3 GetPositionOffset()
6262
}
6363
}
6464

65+
/// <summary>
66+
/// Allows one to adjust the per-joint rotation offsets computed between
67+
/// source (OVRBody) and target characters. To avoid gimbal lock,
68+
/// a series of rotations are permitted.
69+
/// </summary>
70+
[System.Serializable]
71+
public class JointRotationTweaks
72+
{
73+
/// <summary>
74+
/// Joint to affect.
75+
/// </summary>
76+
public HumanBodyBones Joint;
77+
78+
/// <summary>
79+
/// A series of rotation tweaks.
80+
/// </summary>
81+
public Quaternion[] RotationTweaks;
82+
}
83+
6584
/// <summary>
6685
/// The array of joint position adjustments.
6786
/// </summary>
@@ -160,6 +179,25 @@ public RetargetingAnimationConstraint RetargetingConstraint
160179
set { _retargetingAnimationConstraint = value; }
161180
}
162181

182+
/// <summary>
183+
/// Joint rotation tweaks array.
184+
/// </summary>
185+
[SerializeField]
186+
[Tooltip(RetargetingLayerTooltips.JointRotationTweaks)]
187+
protected JointRotationTweaks[] _jointRotationTweaks;
188+
public JointRotationTweaks[] JointRotationTweaksArray
189+
{
190+
get => _jointRotationTweaks;
191+
set => _jointRotationTweaks = value;
192+
}
193+
/// <summary>
194+
/// Pre-compute these values each time the editor changes for the purposes
195+
/// of efficiency.
196+
/// </summary>
197+
private Dictionary<HumanBodyBones, Quaternion> _humanBoneToAccumulatedRotationTweaks =
198+
new Dictionary<HumanBodyBones, Quaternion>();
199+
private List<HumanBodyBones> _bonesToRemove = new List<HumanBodyBones> ();
200+
163201
private Pose[] _defaultPoses;
164202
private IJointConstraint[] _jointConstraints;
165203
private ProxyTransformLogic _proxyTransformLogic = new ProxyTransformLogic();
@@ -220,6 +258,8 @@ protected override void Start()
220258
CacheJointConstraints();
221259

222260
ValidateHumanoid();
261+
262+
PrecomputeJointRotationTweaks();
223263
}
224264

225265
private void ConstructDefaultPoseInformation()
@@ -305,6 +345,78 @@ protected virtual void OnApplicationFocus(bool hasFocus)
305345
_isFocusedWhileInBuild = hasFocus;
306346
}
307347

348+
protected virtual void OnValidate()
349+
{
350+
PrecomputeJointRotationTweaks();
351+
}
352+
353+
/// <summary>
354+
/// When the object's properties are modified, accumulate joint rotations
355+
/// and cache those values. This saves on computation when the tweaks field is used.
356+
/// </summary>
357+
protected void PrecomputeJointRotationTweaks()
358+
{
359+
#if UNITY_EDITOR
360+
if (!UnityEditor.EditorApplication.isPlaying)
361+
{
362+
return;
363+
}
364+
#endif
365+
366+
foreach (var rotationTweak in _jointRotationTweaks)
367+
{
368+
var allRotations = rotationTweak.RotationTweaks;
369+
var joint = rotationTweak.Joint;
370+
371+
Quaternion accumulatedRotation = Quaternion.identity;
372+
foreach (var rotationValue in allRotations)
373+
{
374+
// Make sure the quaternion is valid. Quaternions are initialized to all
375+
// zeroes by default, which makes them invalid.
376+
if (rotationValue.w < Mathf.Epsilon && rotationValue.x < Mathf.Epsilon &&
377+
rotationValue.y < Mathf.Epsilon && rotationValue.z < Mathf.Epsilon)
378+
{
379+
continue;
380+
}
381+
382+
accumulatedRotation *= rotationValue;
383+
}
384+
385+
if (!_humanBoneToAccumulatedRotationTweaks.ContainsKey(joint))
386+
{
387+
_humanBoneToAccumulatedRotationTweaks.Add(joint, accumulatedRotation);
388+
}
389+
else
390+
{
391+
_humanBoneToAccumulatedRotationTweaks[joint] = accumulatedRotation;
392+
}
393+
}
394+
395+
_bonesToRemove.Clear();
396+
// If the user removed bones from the UI, remove those from the dictionary.
397+
foreach (var bone in _humanBoneToAccumulatedRotationTweaks.Keys)
398+
{
399+
bool boneFound = false;
400+
foreach (var rotationTweak in _jointRotationTweaks)
401+
{
402+
if (rotationTweak.Joint == bone)
403+
{
404+
boneFound = true;
405+
break;
406+
}
407+
}
408+
409+
if (!boneFound)
410+
{
411+
_bonesToRemove.Add(bone);
412+
}
413+
}
414+
foreach(var boneToRemove in _bonesToRemove)
415+
{
416+
_humanBoneToAccumulatedRotationTweaks.Remove(boneToRemove);
417+
}
418+
}
419+
308420
/// <inheritdoc />
309421
protected override void Update()
310422
{
@@ -419,7 +531,7 @@ private void CorrectBones()
419531
targetJoint.rotation =
420532
Quaternion.Slerp(targetJoint.rotation,
421533
Bones[i].Transform.rotation *
422-
targetData.CorrectionQuaternion.Value,
534+
targetData.CorrectionQuaternion.Value * GetRotationTweak(humanBodyBone),
423535
handWeight);
424536
}
425537
if (_correctPositionsLateUpdate)
@@ -438,7 +550,7 @@ private void CorrectBones()
438550
targetJoint.rotation =
439551
Quaternion.Slerp(targetJoint.rotation,
440552
Bones[i].Transform.rotation *
441-
targetData.CorrectionQuaternion.Value,
553+
targetData.CorrectionQuaternion.Value * GetRotationTweak(humanBodyBone),
442554
handWeight);
443555
}
444556

@@ -455,6 +567,18 @@ private void CorrectBones()
455567
}
456568
}
457569

570+
protected Quaternion GetRotationTweak(HumanBodyBones humanBody)
571+
{
572+
Quaternion rotation;
573+
574+
if (!_humanBoneToAccumulatedRotationTweaks.TryGetValue(humanBody, out rotation))
575+
{
576+
rotation = Quaternion.identity;
577+
}
578+
579+
return rotation;
580+
}
581+
458582
protected virtual bool ShouldUpdatePositionOfBone(HumanBodyBones humanBodyBone)
459583
{
460584
var bodySectionOfJoint = OVRHumanBodyBonesMappings.BoneToBodySection[humanBodyBone];
@@ -516,7 +640,8 @@ public void FillTransformArrays(List<Transform> sourceTransforms,
516640
targetTransforms.Add(targetBoneData.OriginalJoint);
517641
shouldUpdatePositions.Add(false);
518642
shouldUpdateRotations.Add(false);
519-
rotationOffsets.Add(targetBoneData.CorrectionQuaternion.Value);
643+
rotationOffsets.Add(targetBoneData.CorrectionQuaternion.Value *
644+
GetRotationTweak(targetHumanBodyBone));
520645
rotationAdjustments.Add(Quaternion.identity);
521646
}
522647
}
@@ -582,14 +707,16 @@ public void UpdateAdjustments(Quaternion[] rotationOffsets,
582707

583708
if (adjustment == null)
584709
{
585-
SetUpDefaultAdjustment(rotationOffsets, shouldUpdatePositions,
710+
SetUpDefaultAdjustment(targetHumanBodyBone,
711+
rotationOffsets, shouldUpdatePositions,
586712
shouldUpdateRotations, rotationAdjustments, arrayId,
587713
targetBoneData, bodySectionInPositionArray,
588714
jointFailsMask);
589715
}
590716
else
591717
{
592-
SetUpCustomAdjustment(rotationOffsets, shouldUpdatePositions,
718+
SetUpCustomAdjustment(targetHumanBodyBone,
719+
rotationOffsets, shouldUpdatePositions,
593720
shouldUpdateRotations,
594721
rotationAdjustments, adjustment, arrayId,
595722
targetBoneData, bodySectionInPositionArray,
@@ -600,26 +727,28 @@ public void UpdateAdjustments(Quaternion[] rotationOffsets,
600727
}
601728
}
602729

603-
private void SetUpDefaultAdjustment(Quaternion[] rotationOffsets,
730+
private void SetUpDefaultAdjustment(HumanBodyBones humanBodyBone, Quaternion[] rotationOffsets,
604731
bool[] shouldUpdatePositions, bool[] shouldUpdateRotations,
605732
Quaternion[] rotationAdjustments, int arrayId,
606733
OVRSkeletonMetadata.BoneData targetBoneData,
607734
bool bodySectionInPositionArray, bool jointFailsMask)
608735
{
609-
rotationOffsets[arrayId] = targetBoneData.CorrectionQuaternion.Value;
736+
rotationOffsets[arrayId] = targetBoneData.CorrectionQuaternion.Value *
737+
GetRotationTweak(humanBodyBone);
610738
shouldUpdatePositions[arrayId] = !jointFailsMask && bodySectionInPositionArray;
611739
shouldUpdateRotations[arrayId] = !jointFailsMask;
612740
rotationAdjustments[arrayId] = Quaternion.identity;
613741
}
614742

615-
private void SetUpCustomAdjustment(Quaternion[] rotationOffsets,
743+
private void SetUpCustomAdjustment(HumanBodyBones humanBodyBone, Quaternion[] rotationOffsets,
616744
bool[] shouldUpdatePositions, bool[] shouldUpdateRotations,
617745
Quaternion[] rotationAdjustments,
618746
JointAdjustment adjustment, int arrayId,
619747
OVRSkeletonMetadata.BoneData targetBoneData,
620748
bool bodySectionInPositionArray, bool jointFailsMask)
621749
{
622-
rotationOffsets[arrayId] = targetBoneData.CorrectionQuaternion.Value;
750+
rotationOffsets[arrayId] = targetBoneData.CorrectionQuaternion.Value *
751+
GetRotationTweak(humanBodyBone);
623752
shouldUpdatePositions[arrayId] =
624753
!adjustment.DisablePositionTransform &&
625754
bodySectionInPositionArray &&

Runtime/Scripts/Tooltips.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,9 @@ public static class RetargetingLayerTooltips
12341234

12351235
public const string RetargetingAnimationContraint =
12361236
"Related retargeting constraint.";
1237+
1238+
public const string JointRotationTweaks =
1239+
"Joint rotation tweaks array.";
12371240
}
12381241

12391242
public static class LateMirroredObjectTooltips

Samples/Prefabs/Retargeting/ArmatureSkinningUpdateRetarget.prefab

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,7 @@ PrefabInstance:
885885
objectReference: {fileID: 0}
886886
- target: {fileID: 9121803696401781268, guid: 4d1160b6537bb3e42802d3a5219e72c4, type: 3}
887887
propertyPath: m_Name
888-
value: ArmatureSkinningUpdateRetarget
888+
value: ArmatureSkinningUpdateRetargetUser
889889
objectReference: {fileID: 0}
890890
m_RemovedComponents: []
891891
m_SourcePrefab: {fileID: 100100000, guid: 4d1160b6537bb3e42802d3a5219e72c4, type: 3}
@@ -1038,6 +1038,15 @@ MonoBehaviour:
10381038
_applyAnimationConstraintsToCorrectedPositions: 1
10391039
_enableTrackingByProxy: 0
10401040
_retargetingAnimationConstraint: {fileID: 318886850}
1041+
_jointRotationTweaks:
1042+
- Joint: 17
1043+
RotationTweaks:
1044+
- {x: 0, y: 0.42261827, z: 0, w: 0.90630776}
1045+
- {x: 0, y: 0, z: 0.1736483, w: -0.9848077}
1046+
- Joint: 18
1047+
RotationTweaks:
1048+
- {x: 0, y: 0.42261827, z: 0, w: 0.90630776}
1049+
- {x: 0, y: 0, z: 0.1736483, w: -0.9848077}
10411050
--- !u!114 &208026093
10421051
MonoBehaviour:
10431052
m_ObjectHideFlags: 0

0 commit comments

Comments
 (0)