Modified the way OpenSeeVRMDriver animates the jaw bone.
This commit is contained in:
parent
95d698a7ce
commit
e2d2ed700f
3 changed files with 8299 additions and 17 deletions
8243
Examples/Animations/JawOpen.anim
Normal file
8243
Examples/Animations/JawOpen.anim
Normal file
File diff suppressed because it is too large
Load diff
8
Examples/Animations/JawOpen.anim.meta
Normal file
8
Examples/Animations/JawOpen.anim.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 697b139e69dcb414498dcd93210620ff
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -22,8 +22,12 @@ public class OpenSeeVRMDriver : MonoBehaviour {
|
|||
public OpenSeeIKTarget openSeeIKTarget;
|
||||
[Tooltip("This is the target VRM avatar's blend shape proxy.")]
|
||||
public VRMBlendShapeProxy vrmBlendShapeProxy;
|
||||
[Tooltip("When this is enabled, no blend shapes are applied.")]
|
||||
[Tooltip("When this is enabled, no blendshapes are applied.")]
|
||||
public bool skipApply = false;
|
||||
[Tooltip("When this is enabled, no gaze tracking (bone or blendshape) is applied.")]
|
||||
public bool skipApplyEyes = false;
|
||||
[Tooltip("When this is enabled, no jaw bone animation is applied.")]
|
||||
public bool skipApplyJaw = false;
|
||||
[Tooltip("When this is enabled in addition to skipApply, expressions from hotkeys or expression detection are still applied.")]
|
||||
public bool stillApplyExpressions = false;
|
||||
[Tooltip("This needs to be enabled when tracking with the fast 30 point model.")]
|
||||
|
|
@ -106,6 +110,8 @@ public class OpenSeeVRMDriver : MonoBehaviour {
|
|||
public bool maximizeLipSync = false;
|
||||
[Tooltip("When enabled and the animator of the avatar has a float parameter called JawMovement, this parameter will be set to values from 0 to 1, corresponding to a closed to open mouth. This can be used for animating jaw bones.")]
|
||||
public bool animateJawBone = false;
|
||||
[Tooltip("This should be set to the included mecanim animation, which sets the jaw bone to closed on the first frame and to open on the second frame.")]
|
||||
public AnimationClip jawBoneAnimation;
|
||||
[Tooltip("This is the mouth tracking smoothing factor, with 0 being no smoothing and 1 being a fixed mouth.")]
|
||||
[Range(0, 1)]
|
||||
public float mouthSmoothing = 0.6f;
|
||||
|
|
@ -210,7 +216,11 @@ public class OpenSeeVRMDriver : MonoBehaviour {
|
|||
|
||||
private OpenSeeBlendShapeProxy proxy = new OpenSeeBlendShapeProxy();
|
||||
private Animator animator;
|
||||
private bool haveJawParameter;
|
||||
private Transform jawBone;
|
||||
private Quaternion jawRotation = Quaternion.identity;
|
||||
private HumanBodyBones[] humanBodyBones;
|
||||
private Transform[] humanBodyBoneTransforms;
|
||||
private Quaternion[] humanBodyBoneRotations;
|
||||
|
||||
private VRMBlendShapeProxy lastAvatar = null;
|
||||
private int eyebrowIsMoving = 0;
|
||||
|
|
@ -511,16 +521,31 @@ public class OpenSeeVRMDriver : MonoBehaviour {
|
|||
else
|
||||
proxy.AccumulateValue(visemePresetMap[i], result);
|
||||
}
|
||||
if (i == lastIdx && haveJawParameter) {
|
||||
if (i == lastIdx) {
|
||||
if (animateJawBone)
|
||||
animator.SetFloat("JawMovement", result * 0.99999f);
|
||||
SetJaw(result * 0.99999f);
|
||||
else
|
||||
animator.SetFloat("JawMovement", 0f);
|
||||
SetJaw(0f);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetJaw(float v) {
|
||||
if (jawBoneAnimation == null || jawBone == null)
|
||||
return;
|
||||
for (int i = 0; i < humanBodyBones.Length; i++) {
|
||||
if (humanBodyBoneTransforms[i] != null)
|
||||
humanBodyBoneRotations[i] = humanBodyBoneTransforms[i].localRotation;
|
||||
}
|
||||
jawBoneAnimation.SampleAnimation(lastAvatar.gameObject, v / jawBoneAnimation.frameRate);
|
||||
jawRotation = jawBone.localRotation;
|
||||
for (int i = 0; i < humanBodyBones.Length; i++) {
|
||||
if (humanBodyBoneTransforms[i] != null)
|
||||
humanBodyBoneTransforms[i].localRotation = humanBodyBoneRotations[i];
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyMouthShape(bool fadeOnly) {
|
||||
if (vrmBlendShapeProxy == null)
|
||||
return;
|
||||
|
|
@ -550,11 +575,11 @@ public class OpenSeeVRMDriver : MonoBehaviour {
|
|||
float result = interpolated * expressionFactor * visemeFactor;
|
||||
if (i < 5 && result > 0f)
|
||||
proxy.AccumulateValue(visemePresetMap[i], result);
|
||||
if (i == 5 && haveJawParameter) {
|
||||
if (i == 5) {
|
||||
if (animateJawBone)
|
||||
animator.SetFloat("JawMovement", result * 0.99999f);
|
||||
SetJaw(result * 0.99999f);
|
||||
else
|
||||
animator.SetFloat("JawMovement", 0f);
|
||||
SetJaw(0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -750,19 +775,19 @@ public class OpenSeeVRMDriver : MonoBehaviour {
|
|||
InitCatsData();
|
||||
lastAvatar = vrmBlendShapeProxy;
|
||||
animator = lastAvatar.gameObject.GetComponent<Animator>();
|
||||
|
||||
proxy.UpdateAvatar(lastAvatar, animator);
|
||||
|
||||
haveJawParameter = false;
|
||||
if (animator != null) {
|
||||
for (int i = 0; i < animator.parameterCount; i++) {
|
||||
if (animator.parameters[i].name == "JawMovement") {
|
||||
haveJawParameter = true;
|
||||
break;
|
||||
}
|
||||
jawBone = animator.GetBoneTransform(HumanBodyBones.Jaw);
|
||||
for (int i = 0; i < humanBodyBones.Length; i++) {
|
||||
if (humanBodyBones[i] >= 0 && humanBodyBones[i] < HumanBodyBones.LastBone)
|
||||
humanBodyBoneTransforms[i] = animator.GetBoneTransform(humanBodyBones[i]);
|
||||
else
|
||||
humanBodyBoneTransforms[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
proxy.UpdateAvatar(lastAvatar, animator);
|
||||
|
||||
faceMesh = null;
|
||||
faceType = -1;
|
||||
browUpIndex = -1;
|
||||
|
|
@ -1628,6 +1653,9 @@ public class OpenSeeVRMDriver : MonoBehaviour {
|
|||
|
||||
void Start() {
|
||||
InitExpressionMap();
|
||||
humanBodyBones = (HumanBodyBones[])Enum.GetValues(typeof(HumanBodyBones));
|
||||
humanBodyBoneTransforms = new Transform[humanBodyBones.Length];
|
||||
humanBodyBoneRotations = new Quaternion[humanBodyBones.Length];
|
||||
}
|
||||
|
||||
void RunUpdates() {
|
||||
|
|
@ -1661,10 +1689,13 @@ public class OpenSeeVRMDriver : MonoBehaviour {
|
|||
}
|
||||
|
||||
void LateUpdate() {
|
||||
if (!skipApply && gazeTracking && !only30Points) {
|
||||
if (!skipApplyEyes && gazeTracking && !only30Points) {
|
||||
UpdateGaze();
|
||||
proxy.Apply();
|
||||
}
|
||||
if (!skipApplyJaw && jawBone != null && jawBoneAnimation != null) {
|
||||
jawBone.localRotation = jawRotation;
|
||||
}
|
||||
// If blendshapes are received over VMC, apply expressions afterwards if they should be applied
|
||||
if (skipApply && stillApplyExpressions) {
|
||||
proxy.SetSkip(false);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue