Skip to content

Commit

Permalink
chore: update reactivity for expression hook
Browse files Browse the repository at this point in the history
  • Loading branch information
Zaehiel committed Sep 6, 2023
1 parent 0add006 commit 9bfdd95
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 34 deletions.
61 changes: 32 additions & 29 deletions src/services/Models.service.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import React, { useEffect, useCallback, useRef } from 'react';
import {
LinearFilter,
MeshStandardMaterial,
Expand Down Expand Up @@ -320,59 +320,62 @@ export const expressions = {
};

/**
* Animates avatars facial expressions when morphTargets=Default,ARKit is provided with the avatar.
* Animates avatars facial expressions when morphTargets=ARKit,Eyes Extra is provided with the avatar.
*/
export const useIdleExpression = (expression: keyof typeof expressions, nodes: Nodes) => {
const headMesh = (nodes.Wolf3D_Head || nodes.Wolf3D_Avatar) as unknown as SkinnedMeshProps;
const selectedExpression = expression in expressions ? expressions[expression] : undefined;
let duration = Number.POSITIVE_INFINITY;
let timeout: NodeJS.Timeout;
const timeout = useRef<NodeJS.Timeout>();
const duration = useRef<number>(Number.POSITIVE_INFINITY);

useEffect(() => {
if (headMesh.morphTargetDictionary && selectedExpression) {
for (let i = 0; i < selectedExpression.length; i++) {
selectedExpression[i].morphTargetIndex = headMesh.morphTargetDictionary[selectedExpression[i].morphTarget];
}
}
}, [selectedExpression]);

const animateExpression = (delta: number) => {
if (headMesh?.morphTargetInfluences && selectedExpression) {
duration += delta;

for (let i = 0; i < selectedExpression.length; i++) {
const section = selectedExpression[i];

if (duration < section.duration + section.offset) {
if (duration > section.offset) {
const pivot = ((duration - section.offset) / section.duration) * Math.PI;
const morphInfluence = Math.sin(pivot);
headMesh.morphTargetInfluences[section.morphTargetIndex] = morphInfluence;
}, [selectedExpression?.length]);

Check warning on line 337 in src/services/Models.service.tsx

View workflow job for this annotation

GitHub Actions / Linting

React Hook useEffect has missing dependencies: 'headMesh.morphTargetDictionary' and 'selectedExpression'. Either include them or remove the dependency array

const animateExpression = useCallback(
(delta: number) => {
if (headMesh?.morphTargetInfluences && selectedExpression) {
duration.current += delta;

for (let i = 0; i < selectedExpression.length; i++) {
const section = selectedExpression[i];

if (duration.current < section.duration + section.offset) {
if (duration.current > section.offset) {
const pivot = ((duration.current - section.offset) / section.duration) * Math.PI;
const morphInfluence = Math.sin(pivot);
headMesh.morphTargetInfluences[section.morphTargetIndex] = morphInfluence;
}
} else {
headMesh.morphTargetInfluences[section.morphTargetIndex] = 0;
}
} else {
headMesh.morphTargetInfluences[section.morphTargetIndex] = 0;
}
}
}
};
},
[headMesh?.morphTargetInfluences, selectedExpression, duration.current, timeout.current]

Check warning on line 359 in src/services/Models.service.tsx

View workflow job for this annotation

GitHub Actions / Linting

React Hook useCallback has unnecessary dependencies: 'duration.current' and 'timeout.current'. Either exclude them or remove the dependency array. Mutable values like 'duration.current' aren't valid dependencies because mutating them doesn't re-render the component
);

const setNextInterval = () => {
duration = 0;
const delay = Math.random() * 5000 + 3000;
duration.current = 0;
const delay = Math.random() * 3000 + 3000;

clearTimeout(timeout);
timeout = setTimeout(setNextInterval, delay);
clearTimeout(timeout.current);
timeout.current = setTimeout(setNextInterval, delay);
};

useEffect(() => {
if (selectedExpression) {
timeout = setTimeout(setNextInterval, 3000);
timeout.current = setTimeout(setNextInterval, 3000);
}

return () => {
clearTimeout(timeout);
clearTimeout(timeout.current);
};
});
}, [selectedExpression]);

useFrame((_, delta) => {
if (headMesh && selectedExpression) {
Expand Down
10 changes: 5 additions & 5 deletions src/services/Stories.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ export const ignoreArgTypesOnExamples = keysToIgnore.reduce(
);

export const modelPresets = {
one: 'https://models.readyplayer.me/64d61e9e17883fd73ebe5eb7.glb?lod=0&morphTargets=Default,ARKit&textureAtlas=none',
two: 'https://models.readyplayer.me/64d61f67f0367d07504924be.glb?lod=0&morphTargets=Default,ARKit&textureAtlas=none',
one: 'https://models.readyplayer.me/64d61e9e17883fd73ebe5eb7.glb?morphTargets=ARKit,Eyes Extra&textureAtlas=none&lod=0',
two: 'https://models.readyplayer.me/64d61f67f0367d07504924be.glb?morphTargets=ARKit,Eyes Extra&textureAtlas=none&lod=0',
three:
'https://models.readyplayer.me/64d62255f0367d0750492913.glb?lod=0&morphTargets=Default,ARKit&textureAtlas=none',
five: 'https://models.readyplayer.me/64d6235e2d3bea6e4267b01d.glb?lod=0&morphTargets=Default,ARKit&textureAtlas=none',
six: 'https://models.readyplayer.me/64d5d4eb651a0d350005c672.glb?lod=0&morphTargets=Default,ARKit&textureAtlas=none'
'https://models.readyplayer.me/64d62255f0367d0750492913.glb?lod=0&morphTargets=ARKit,Eyes Extra&textureAtlas=none',
five: 'https://models.readyplayer.me/64d6235e2d3bea6e4267b01d.glb?lod=0&morphTargets=ARKit,Eyes Extra&textureAtlas=none',
six: 'https://models.readyplayer.me/64d5d4eb651a0d350005c672.glb?lod=0&morphTargets=ARKit,Eyes Extra&textureAtlas=none'
};

export const animationPresets = {
Expand Down

0 comments on commit 9bfdd95

Please sign in to comment.