Skip to content

Commit abbacfd

Browse files
sohailshafiiWkfacebook-github-bot
authored andcommitted
feat(Editor): Add CorrectivesFace menu
Summary: Adds a nice menu to allow adding `CorrectivesFace` to a skinned mesh renderer. Unfortunately we can't access the duplicates field from OVRCustomFace, which means we must address the visibility of it in the future. Reviewed By: andkim-meta Differential Revision: D46157712 fbshipit-source-id: 96c559aeac2ccd2b330bfd4c398ecf2fabedde58
1 parent a0f6a92 commit abbacfd

File tree

2 files changed

+91
-6
lines changed

2 files changed

+91
-6
lines changed

Editor/Utils/HelperMenus.cs

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// Copyright (c) Meta Platforms, Inc. and affiliates.
22

33
using Oculus.Movement.AnimationRigging;
4+
using Oculus.Movement.Tracking;
45
using System;
56
using UnityEditor;
7+
using UnityEditor.SceneManagement;
68
using UnityEngine;
79
using UnityEngine.Animations.Rigging;
810

@@ -15,18 +17,28 @@ namespace Oculus.Movement.Utils
1517
internal static class HelperMenus
1618
{
1719
private const string _MOVEMENT_SAMPLES_MENU =
20+
1821
"GameObject/Movement Samples/";
1922
private const string _MOVEMENT_SAMPLES_BT_MENU =
2023
"Body Tracking/";
2124
private const string _ANIM_RIGGING_RETARGETING_MENU =
2225
"Animation Rigging Retargeting";
2326

27+
private const string _MOVEMENT_SAMPLES_FT_MENU =
28+
"Face Tracking/";
29+
private const string _CORRECTIVES_FACE_MENU =
30+
"Correctives Face";
31+
private const string _CORRECTIVES_FACE_DUPLICATE_MENU =
32+
"Correctives Face (allow duplicate mapping)";
33+
2434
[MenuItem(_MOVEMENT_SAMPLES_MENU + _MOVEMENT_SAMPLES_BT_MENU + _ANIM_RIGGING_RETARGETING_MENU)]
2535
private static void SetupCharacterForAnimationRiggingRetargeting()
2636
{
37+
var activeGameObject = Selection.activeGameObject;
38+
2739
try
2840
{
29-
ValidGameObjectForAnimationRigging(Selection.activeGameObject);
41+
ValidGameObjectForAnimationRigging(activeGameObject);
3042
}
3143
catch (InvalidOperationException e)
3244
{
@@ -36,25 +48,41 @@ private static void SetupCharacterForAnimationRiggingRetargeting()
3648

3749
Undo.IncrementCurrentGroup();
3850

39-
var mainParent = Selection.activeGameObject;
40-
4151
// Add the retargeting and body tracking components at root first.
42-
RetargetingLayer retargetingLayer = AddMainRetargetingComponents(mainParent);
52+
RetargetingLayer retargetingLayer = AddMainRetargetingComponents(activeGameObject);
4353

4454
GameObject rigObject;
4555
RigBuilder rigBuilder;
46-
(rigBuilder, rigObject) = AddBasicAnimationRiggingComponents(mainParent);
56+
(rigBuilder, rigObject) = AddBasicAnimationRiggingComponents(activeGameObject);
4757

4858
RetargetingAnimationConstraint retargetConstraint =
4959
AddRetargetingConstraint(rigObject, retargetingLayer);
5060

5161
// Add final components to tie everything together.
52-
AddAnimationRiggingLayer(mainParent, retargetingLayer, rigBuilder,
62+
AddAnimationRiggingLayer(activeGameObject, retargetingLayer, rigBuilder,
5363
retargetConstraint, retargetingLayer);
5464

5565
Undo.SetCurrentGroupName("Setup Animation Rigging Retargeting");
5666
}
5767

68+
[MenuItem(_MOVEMENT_SAMPLES_MENU + _MOVEMENT_SAMPLES_FT_MENU + _CORRECTIVES_FACE_MENU)]
69+
private static void SetupCharacterForCorrectivesFace()
70+
{
71+
var activeGameObject = Selection.activeGameObject;
72+
73+
try
74+
{
75+
ValidateGameObjectForFaceMapping(activeGameObject);
76+
}
77+
catch (InvalidOperationException e)
78+
{
79+
EditorUtility.DisplayDialog("Face Tracking setup error.", e.Message, "Ok");
80+
return;
81+
}
82+
83+
SetUpCharacterForCorrectivesFace(activeGameObject);
84+
}
85+
5886
private static RetargetingLayer AddMainRetargetingComponents(GameObject mainParent)
5987
{
6088
RetargetingLayer retargetingLayer = mainParent.GetComponent<RetargetingLayer>();
@@ -170,5 +198,48 @@ private static void ValidGameObjectForAnimationRigging(GameObject go)
170198
}
171199
}
172200

201+
public static void ValidateGameObjectForFaceMapping(GameObject go)
202+
{
203+
var renderer = go.GetComponent<SkinnedMeshRenderer>();
204+
if (renderer == null || renderer.sharedMesh == null || renderer.sharedMesh.blendShapeCount == 0)
205+
{
206+
throw new InvalidOperationException(
207+
$"Adding a Face Tracking component requires a {nameof(SkinnedMeshRenderer)} " +
208+
$"that contains blendshapes.");
209+
}
210+
}
211+
212+
private static void SetUpCharacterForCorrectivesFace(GameObject gameObject)
213+
{
214+
Undo.IncrementCurrentGroup();
215+
216+
var faceExpressions = gameObject.GetComponentInParent<OVRFaceExpressions>();
217+
if (!faceExpressions)
218+
{
219+
faceExpressions = gameObject.AddComponent<OVRFaceExpressions>();
220+
Undo.RegisterCreatedObjectUndo(faceExpressions, "Create OVRFaceExpressions component");
221+
}
222+
223+
var face = gameObject.GetComponent<CorrectivesFace>();
224+
if (!face)
225+
{
226+
face = gameObject.AddComponent<CorrectivesFace>();
227+
face.FaceExpressions = faceExpressions;
228+
Undo.RegisterCreatedObjectUndo(face, "Create CorrectivesFace component");
229+
}
230+
231+
if (face.BlendshapeModifier == null)
232+
{
233+
face.BlendshapeModifier = gameObject.GetComponentInParent<BlendshapeModifier>();
234+
Undo.RecordObject(face, "Assign to BlendshapeModifier field");
235+
}
236+
237+
Undo.RegisterFullObjectHierarchyUndo(face, "Auto-map Correcives blendshapes");
238+
face.AutoMapBlendshapes();
239+
EditorUtility.SetDirty(face);
240+
EditorSceneManager.MarkSceneDirty(face.gameObject.scene);
241+
242+
Undo.SetCurrentGroupName($"Setup Character for CorrecivesFace Tracking");
243+
}
173244
}
174245
}

Runtime/Scripts/Tracking/FaceTrackingData/CorrectivesFace.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ public class CorrectivesFace : OVRCustomFace
3535
[Tooltip(CorrectivesFaceTooltips.BlendshapeModifier)]
3636
protected BlendshapeModifier _blendshapeModifier;
3737

38+
/// <inheritdoc cref="_blendshapeModifier"/>
39+
public BlendshapeModifier BlendshapeModifier
40+
{
41+
get { return _blendshapeModifier; }
42+
set { _blendshapeModifier = value; }
43+
}
44+
3845
/// <summary>
3946
/// The json file containing the in-betweens and combinations data.
4047
/// </summary>
@@ -43,6 +50,13 @@ public class CorrectivesFace : OVRCustomFace
4350
[Tooltip(CorrectivesFaceTooltips.CombinationShapesTextAsset)]
4451
protected TextAsset _combinationShapesTextAsset;
4552

53+
/// <inheritdoc cref="_combinationShapesTextAsset"/>
54+
public TextAsset CombinationShapesTextAsset
55+
{
56+
get { return _combinationShapesTextAsset; }
57+
set { _combinationShapesTextAsset = value; }
58+
}
59+
4660
/// <summary>
4761
/// Cached mesh blendshape values.
4862
/// </summary>

0 commit comments

Comments
 (0)