Skip to content

Commit 6579f9e

Browse files
sohailshafiiWkfacebook-github-bot
authored andcommitted
fix(Runtime): Allow controlling blendshape example's constraints via skeletal state
Summary: The blendshape mapping character has constraints that constantly add an offset to the head and neck bones per frame to make the character look better. During each frame: 1. OVRSkeleton updates the bone positions. 2. Two constraints move the head up and neck down so that the character does not look so compressed. This is done using a per-frame offset. The problem is that if the user takes the headset off, #1 does not run, but the constraints from #2 will continue to affect the bones. They will continue to add offsets to the head and neck bones for each new frame, causing a strange stretch. Their existence depends on the skeleton updating the bone position *first* so that they can tweak it via an offset. The constraints should not run if the skeletal data is not valid or not initialized. This will prevent the constraints from running when the user's positions are not being set. Reviewed By: andkim-meta Differential Revision: D49867991 fbshipit-source-id: 59562b742253a1a694b270f99433b7e37f9c5969
1 parent a606c96 commit 6579f9e

File tree

5 files changed

+288
-0
lines changed

5 files changed

+288
-0
lines changed

Runtime/Scripts/Tooltips.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,4 +1634,13 @@ public static class OVRBodyTrackingStateListenerTooltips
16341634
public const string MaxWaitTimeForBodyTracking =
16351635
"How many seconds before body tracking times out and is considered disconnected";
16361636
}
1637+
1638+
public static class ToggleConstraintsSkeletonStateTooltips
1639+
{
1640+
public const string Constraints =
1641+
"Constraints to control the weight of.";
1642+
1643+
public const string Skeleton =
1644+
"The skeleton object that needs to be tracked.";
1645+
}
16371646
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) Meta Platforms, Inc. and affiliates.
2+
3+
using Oculus.Interaction;
4+
using UnityEngine;
5+
using UnityEngine.Animations.Rigging;
6+
using UnityEngine.Assertions;
7+
8+
namespace Oculus.Movement.Utils
9+
{
10+
/// <summary>
11+
/// If the bones are not valid then turn off constraints specified.
12+
/// This is useful if a constraint depends on the skeleton code to set the
13+
/// value of a bone every frame. Like a multi-position constraint that applies
14+
/// an offset.
15+
/// </summary>
16+
public class ToggleConstraintsSkeletonState : MonoBehaviour
17+
{
18+
/// <summary>
19+
/// Constraints to control the weight of.
20+
/// </summary>
21+
[SerializeField, Interface(typeof(IRigConstraint))]
22+
[Tooltip(ToggleConstraintsSkeletonStateTooltips.Constraints)]
23+
private MonoBehaviour[] _constraints;
24+
25+
/// <summary>
26+
/// The skeleton object that needs to be tracked.
27+
/// </summary>
28+
[SerializeField]
29+
[Tooltip(ToggleConstraintsSkeletonStateTooltips.Skeleton)]
30+
private OVRSkeleton _skeleton;
31+
32+
private IRigConstraint[] _iRigConstraints;
33+
private float[] _originalConstraintWeights;
34+
35+
private void Awake()
36+
{
37+
Assert.IsTrue(_constraints != null && _constraints.Length > 0);
38+
Assert.IsNotNull(_skeleton);
39+
40+
_iRigConstraints = new IRigConstraint[_constraints.Length];
41+
_originalConstraintWeights = new float[_constraints.Length];
42+
for (int i = 0; i < _constraints.Length; i++)
43+
{
44+
_iRigConstraints[i] = _constraints[i] as IRigConstraint;
45+
_originalConstraintWeights[i] = _iRigConstraints[i].weight;
46+
Assert.IsNotNull(_iRigConstraints[i]);
47+
}
48+
}
49+
50+
private void Update()
51+
{
52+
bool skeletonValid = _skeleton.IsInitialized && _skeleton.IsDataValid;
53+
for (int i = 0; i < _iRigConstraints.Length; i++)
54+
{
55+
_iRigConstraints[i].weight = skeletonValid ? _originalConstraintWeights[i] : 0.0f;
56+
}
57+
}
58+
}
59+
}

Runtime/Scripts/Utils/ToggleConstraintsSkeletonState.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Samples/Prefabs/BlendshapeMappingExample/BlendshapeMappingExampleARKITFirstPerson.prefab

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,22 @@ MonoBehaviour:
825825
_rigToggleOnFocus: 1
826826
_retargetingLayer: {fileID: 0}
827827
_checkSkeletalUpdatesByProxy: 0
828+
--- !u!114 &5895253470718524380
829+
MonoBehaviour:
830+
m_ObjectHideFlags: 0
831+
m_CorrespondingSourceObject: {fileID: 0}
832+
m_PrefabInstance: {fileID: 0}
833+
m_PrefabAsset: {fileID: 0}
834+
m_GameObject: {fileID: 607326578965322257}
835+
m_Enabled: 1
836+
m_EditorHideFlags: 0
837+
m_Script: {fileID: 11500000, guid: a87c462fa9931da4b872f37c96a3102a, type: 3}
838+
m_Name:
839+
m_EditorClassIdentifier:
840+
_constraints:
841+
- {fileID: 1123534316221971162}
842+
- {fileID: 4031897247645224307}
843+
_skeleton: {fileID: 3946535142790877676}
828844
--- !u!4 &1122422457210726926 stripped
829845
Transform:
830846
m_CorrespondingSourceObject: {fileID: 4131856439344247223, guid: acf265753b6022246b6834742c70714f, type: 3}

Samples/Scenes/MovementBlendshapeMappingExample.unity

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,38 @@ NavMeshSettings:
123123
debug:
124124
m_Flags: 0
125125
m_NavMeshData: {fileID: 0}
126+
--- !u!1 &11866984
127+
GameObject:
128+
m_ObjectHideFlags: 0
129+
m_CorrespondingSourceObject: {fileID: 0}
130+
m_PrefabInstance: {fileID: 0}
131+
m_PrefabAsset: {fileID: 0}
132+
serializedVersion: 6
133+
m_Component:
134+
- component: {fileID: 11866985}
135+
m_Layer: 0
136+
m_Name: RightControllerInHandAnchor
137+
m_TagString: Untagged
138+
m_Icon: {fileID: 0}
139+
m_NavMeshLayer: 0
140+
m_StaticEditorFlags: 0
141+
m_IsActive: 1
142+
--- !u!4 &11866985
143+
Transform:
144+
m_ObjectHideFlags: 0
145+
m_CorrespondingSourceObject: {fileID: 0}
146+
m_PrefabInstance: {fileID: 0}
147+
m_PrefabAsset: {fileID: 0}
148+
m_GameObject: {fileID: 11866984}
149+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
150+
m_LocalPosition: {x: 0, y: 0, z: 0}
151+
m_LocalScale: {x: 1, y: 1, z: 1}
152+
m_ConstrainProportionsScale: 0
153+
m_Children:
154+
- {fileID: 2123792917}
155+
m_Father: {fileID: 2097346132}
156+
m_RootOrder: 2
157+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
126158
--- !u!1 &23275527
127159
GameObject:
128160
m_ObjectHideFlags: 0
@@ -797,6 +829,37 @@ Transform:
797829
m_CorrespondingSourceObject: {fileID: 2747730224568278618, guid: 70c1ec55e63be294f92b377695e53302, type: 3}
798830
m_PrefabInstance: {fileID: 1844149371}
799831
m_PrefabAsset: {fileID: 0}
832+
--- !u!1 &893696617
833+
GameObject:
834+
m_ObjectHideFlags: 0
835+
m_CorrespondingSourceObject: {fileID: 0}
836+
m_PrefabInstance: {fileID: 0}
837+
m_PrefabAsset: {fileID: 0}
838+
serializedVersion: 6
839+
m_Component:
840+
- component: {fileID: 893696618}
841+
m_Layer: 0
842+
m_Name: RightHandAnchorDetached
843+
m_TagString: Untagged
844+
m_Icon: {fileID: 0}
845+
m_NavMeshLayer: 0
846+
m_StaticEditorFlags: 0
847+
m_IsActive: 1
848+
--- !u!4 &893696618
849+
Transform:
850+
m_ObjectHideFlags: 0
851+
m_CorrespondingSourceObject: {fileID: 0}
852+
m_PrefabInstance: {fileID: 0}
853+
m_PrefabAsset: {fileID: 0}
854+
m_GameObject: {fileID: 893696617}
855+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
856+
m_LocalPosition: {x: 0, y: 0, z: 0}
857+
m_LocalScale: {x: 1, y: 1, z: 1}
858+
m_ConstrainProportionsScale: 0
859+
m_Children: []
860+
m_Father: {fileID: 1328425359}
861+
m_RootOrder: 7
862+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
800863
--- !u!4 &903951107 stripped
801864
Transform:
802865
m_CorrespondingSourceObject: {fileID: 2055742801895016221, guid: 4f6634390b1d87c488b90ffe9aa5d702, type: 3}
@@ -1093,6 +1156,11 @@ Transform:
10931156
m_CorrespondingSourceObject: {fileID: 7449292010121941889, guid: 70c1ec55e63be294f92b377695e53302, type: 3}
10941157
m_PrefabInstance: {fileID: 1844149371}
10951158
m_PrefabAsset: {fileID: 0}
1159+
--- !u!4 &1328425359 stripped
1160+
Transform:
1161+
m_CorrespondingSourceObject: {fileID: 459718, guid: 126d619cf4daa52469682f85c1378b4a, type: 3}
1162+
m_PrefabInstance: {fileID: 2097346129}
1163+
m_PrefabAsset: {fileID: 0}
10961164
--- !u!1001 &1404505943
10971165
PrefabInstance:
10981166
m_ObjectHideFlags: 0
@@ -1622,11 +1690,74 @@ Transform:
16221690
m_CorrespondingSourceObject: {fileID: 8082333127555231696, guid: 4f6634390b1d87c488b90ffe9aa5d702, type: 3}
16231691
m_PrefabInstance: {fileID: 1561311111}
16241692
m_PrefabAsset: {fileID: 0}
1693+
--- !u!1 &1762506789
1694+
GameObject:
1695+
m_ObjectHideFlags: 0
1696+
m_CorrespondingSourceObject: {fileID: 0}
1697+
m_PrefabInstance: {fileID: 0}
1698+
m_PrefabAsset: {fileID: 0}
1699+
serializedVersion: 6
1700+
m_Component:
1701+
- component: {fileID: 1762506790}
1702+
m_Layer: 0
1703+
m_Name: LeftHandOnControllerAnchor
1704+
m_TagString: Untagged
1705+
m_Icon: {fileID: 0}
1706+
m_NavMeshLayer: 0
1707+
m_StaticEditorFlags: 0
1708+
m_IsActive: 1
1709+
--- !u!4 &1762506790
1710+
Transform:
1711+
m_ObjectHideFlags: 0
1712+
m_CorrespondingSourceObject: {fileID: 0}
1713+
m_PrefabInstance: {fileID: 0}
1714+
m_PrefabAsset: {fileID: 0}
1715+
m_GameObject: {fileID: 1762506789}
1716+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
1717+
m_LocalPosition: {x: 0, y: 0, z: 0}
1718+
m_LocalScale: {x: 1, y: 1, z: 1}
1719+
m_ConstrainProportionsScale: 0
1720+
m_Children: []
1721+
m_Father: {fileID: 1779134144}
1722+
m_RootOrder: 0
1723+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
16251724
--- !u!4 &1776024879 stripped
16261725
Transform:
16271726
m_CorrespondingSourceObject: {fileID: 5244368838297366373, guid: 4f6634390b1d87c488b90ffe9aa5d702, type: 3}
16281727
m_PrefabInstance: {fileID: 1561311111}
16291728
m_PrefabAsset: {fileID: 0}
1729+
--- !u!1 &1779134143
1730+
GameObject:
1731+
m_ObjectHideFlags: 0
1732+
m_CorrespondingSourceObject: {fileID: 0}
1733+
m_PrefabInstance: {fileID: 0}
1734+
m_PrefabAsset: {fileID: 0}
1735+
serializedVersion: 6
1736+
m_Component:
1737+
- component: {fileID: 1779134144}
1738+
m_Layer: 0
1739+
m_Name: LeftControllerInHandAnchor
1740+
m_TagString: Untagged
1741+
m_Icon: {fileID: 0}
1742+
m_NavMeshLayer: 0
1743+
m_StaticEditorFlags: 0
1744+
m_IsActive: 1
1745+
--- !u!4 &1779134144
1746+
Transform:
1747+
m_ObjectHideFlags: 0
1748+
m_CorrespondingSourceObject: {fileID: 0}
1749+
m_PrefabInstance: {fileID: 0}
1750+
m_PrefabAsset: {fileID: 0}
1751+
m_GameObject: {fileID: 1779134143}
1752+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
1753+
m_LocalPosition: {x: 0, y: 0, z: 0}
1754+
m_LocalScale: {x: 1, y: 1, z: 1}
1755+
m_ConstrainProportionsScale: 0
1756+
m_Children:
1757+
- {fileID: 1762506790}
1758+
m_Father: {fileID: 2097346131}
1759+
m_RootOrder: 2
1760+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
16301761
--- !u!4 &1785405832 stripped
16311762
Transform:
16321763
m_CorrespondingSourceObject: {fileID: 1990495893587582008, guid: 70c1ec55e63be294f92b377695e53302, type: 3}
@@ -2693,6 +2824,37 @@ Transform:
26932824
m_CorrespondingSourceObject: {fileID: 1502899699220297356, guid: 70c1ec55e63be294f92b377695e53302, type: 3}
26942825
m_PrefabInstance: {fileID: 1844149371}
26952826
m_PrefabAsset: {fileID: 0}
2827+
--- !u!1 &1954411104
2828+
GameObject:
2829+
m_ObjectHideFlags: 0
2830+
m_CorrespondingSourceObject: {fileID: 0}
2831+
m_PrefabInstance: {fileID: 0}
2832+
m_PrefabAsset: {fileID: 0}
2833+
serializedVersion: 6
2834+
m_Component:
2835+
- component: {fileID: 1954411105}
2836+
m_Layer: 0
2837+
m_Name: LeftHandAnchorDetached
2838+
m_TagString: Untagged
2839+
m_Icon: {fileID: 0}
2840+
m_NavMeshLayer: 0
2841+
m_StaticEditorFlags: 0
2842+
m_IsActive: 1
2843+
--- !u!4 &1954411105
2844+
Transform:
2845+
m_ObjectHideFlags: 0
2846+
m_CorrespondingSourceObject: {fileID: 0}
2847+
m_PrefabInstance: {fileID: 0}
2848+
m_PrefabAsset: {fileID: 0}
2849+
m_GameObject: {fileID: 1954411104}
2850+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
2851+
m_LocalPosition: {x: 0, y: 0, z: 0}
2852+
m_LocalScale: {x: 1, y: 1, z: 1}
2853+
m_ConstrainProportionsScale: 0
2854+
m_Children: []
2855+
m_Father: {fileID: 1328425359}
2856+
m_RootOrder: 6
2857+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
26962858
--- !u!4 &1964776331 stripped
26972859
Transform:
26982860
m_CorrespondingSourceObject: {fileID: 1292583167331237465, guid: 4f6634390b1d87c488b90ffe9aa5d702, type: 3}
@@ -3121,6 +3283,37 @@ MonoBehaviour:
31213283
m_Script: {fileID: 11500000, guid: 13b3318f5d2f2d54393fdd91b1970751, type: 3}
31223284
m_Name:
31233285
m_EditorClassIdentifier:
3286+
--- !u!1 &2123792916
3287+
GameObject:
3288+
m_ObjectHideFlags: 0
3289+
m_CorrespondingSourceObject: {fileID: 0}
3290+
m_PrefabInstance: {fileID: 0}
3291+
m_PrefabAsset: {fileID: 0}
3292+
serializedVersion: 6
3293+
m_Component:
3294+
- component: {fileID: 2123792917}
3295+
m_Layer: 0
3296+
m_Name: RightHandOnControllerAnchor
3297+
m_TagString: Untagged
3298+
m_Icon: {fileID: 0}
3299+
m_NavMeshLayer: 0
3300+
m_StaticEditorFlags: 0
3301+
m_IsActive: 1
3302+
--- !u!4 &2123792917
3303+
Transform:
3304+
m_ObjectHideFlags: 0
3305+
m_CorrespondingSourceObject: {fileID: 0}
3306+
m_PrefabInstance: {fileID: 0}
3307+
m_PrefabAsset: {fileID: 0}
3308+
m_GameObject: {fileID: 2123792916}
3309+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
3310+
m_LocalPosition: {x: 0, y: 0, z: 0}
3311+
m_LocalScale: {x: 1, y: 1, z: 1}
3312+
m_ConstrainProportionsScale: 0
3313+
m_Children: []
3314+
m_Father: {fileID: 11866985}
3315+
m_RootOrder: 0
3316+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
31243317
--- !u!4 &2132290614 stripped
31253318
Transform:
31263319
m_CorrespondingSourceObject: {fileID: 3684499879929461753, guid: 70c1ec55e63be294f92b377695e53302, type: 3}

0 commit comments

Comments
 (0)