|
@@ -126,6 +126,9 @@
|
|
|
|
|
|
// Face
|
|
// Face
|
|
|
|
|
|
|
|
+ let face, eyeL, eyeR;
|
|
|
|
+ const eyeRotationLimit = THREE.MathUtils.degToRad( 30 );
|
|
|
|
+
|
|
const ktx2Loader = new KTX2Loader()
|
|
const ktx2Loader = new KTX2Loader()
|
|
.setTranscoderPath( 'jsm/libs/basis/' )
|
|
.setTranscoderPath( 'jsm/libs/basis/' )
|
|
.detectSupport( renderer );
|
|
.detectSupport( renderer );
|
|
@@ -141,6 +144,10 @@
|
|
const head = mesh.getObjectByName( 'mesh_2' );
|
|
const head = mesh.getObjectByName( 'mesh_2' );
|
|
head.material = new THREE.MeshNormalMaterial();
|
|
head.material = new THREE.MeshNormalMaterial();
|
|
|
|
|
|
|
|
+ face = mesh.getObjectByName( 'mesh_2' );
|
|
|
|
+ eyeL = mesh.getObjectByName( 'eyeLeft' );
|
|
|
|
+ eyeR = mesh.getObjectByName( 'eyeRight' );
|
|
|
|
+
|
|
// GUI
|
|
// GUI
|
|
|
|
|
|
const gui = new GUI();
|
|
const gui = new GUI();
|
|
@@ -233,18 +240,24 @@
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- if ( results.faceBlendshapes.length > 0 ) {
|
|
|
|
-
|
|
|
|
- const face = scene.getObjectByName( 'mesh_2' );
|
|
|
|
-
|
|
|
|
|
|
+ if ( results.faceBlendshapes.length > 0 ) {
|
|
|
|
+
|
|
const faceBlendshapes = results.faceBlendshapes[ 0 ].categories;
|
|
const faceBlendshapes = results.faceBlendshapes[ 0 ].categories;
|
|
|
|
+
|
|
|
|
+ // Morph values does not exist on the eye meshes, so we map the eyes blendshape score into rotation values
|
|
|
|
+ const eyeScore = {
|
|
|
|
+ leftHorizontal: 0,
|
|
|
|
+ rightHorizontal: 0,
|
|
|
|
+ leftVertical: 0,
|
|
|
|
+ rightVertical: 0,
|
|
|
|
+ };
|
|
|
|
|
|
for ( const blendshape of faceBlendshapes ) {
|
|
for ( const blendshape of faceBlendshapes ) {
|
|
|
|
|
|
const categoryName = blendshape.categoryName;
|
|
const categoryName = blendshape.categoryName;
|
|
const score = blendshape.score;
|
|
const score = blendshape.score;
|
|
|
|
|
|
- const index = face.morphTargetDictionary[ blendshapesMap[ categoryName ] ];
|
|
|
|
|
|
+ const index = face.morphTargetDictionary[ blendshapesMap[ categoryName ] ];
|
|
|
|
|
|
if ( index !== undefined ) {
|
|
if ( index !== undefined ) {
|
|
|
|
|
|
@@ -252,8 +265,44 @@
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // There are two blendshape for movement on each axis (up/down , in/out)
|
|
|
|
+ // Add one and subtract the other to get the final score in -1 to 1 range
|
|
|
|
+ switch ( categoryName ) {
|
|
|
|
+
|
|
|
|
+ case 'eyeLookInLeft':
|
|
|
|
+ eyeScore.leftHorizontal += score;
|
|
|
|
+ break;
|
|
|
|
+ case 'eyeLookOutLeft':
|
|
|
|
+ eyeScore.leftHorizontal -= score;
|
|
|
|
+ break;
|
|
|
|
+ case 'eyeLookInRight':
|
|
|
|
+ eyeScore.rightHorizontal -= score;
|
|
|
|
+ break;
|
|
|
|
+ case 'eyeLookOutRight':
|
|
|
|
+ eyeScore.rightHorizontal += score;
|
|
|
|
+ break;
|
|
|
|
+ case 'eyeLookUpLeft':
|
|
|
|
+ eyeScore.leftVertical -= score;
|
|
|
|
+ break;
|
|
|
|
+ case 'eyeLookDownLeft':
|
|
|
|
+ eyeScore.leftVertical += score;
|
|
|
|
+ break;
|
|
|
|
+ case 'eyeLookUpRight':
|
|
|
|
+ eyeScore.rightVertical -= score;
|
|
|
|
+ break;
|
|
|
|
+ case 'eyeLookDownRight':
|
|
|
|
+ eyeScore.rightVertical += score;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ eyeL.rotation.z = eyeScore.leftHorizontal * eyeRotationLimit;
|
|
|
|
+ eyeR.rotation.z = eyeScore.rightHorizontal * eyeRotationLimit;
|
|
|
|
+ eyeL.rotation.x = eyeScore.leftVertical * eyeRotationLimit;
|
|
|
|
+ eyeR.rotation.x = eyeScore.rightVertical * eyeRotationLimit;
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|