diff --git a/src/components/BaseCanvas/BaseCanvas.component.tsx b/src/components/BaseCanvas/BaseCanvas.component.tsx index 7769de3b..8f6194f8 100644 --- a/src/components/BaseCanvas/BaseCanvas.component.tsx +++ b/src/components/BaseCanvas/BaseCanvas.component.tsx @@ -17,7 +17,7 @@ export const BaseCanvas: FC = ({ fov = 50, position = new Vector3(0, 0, 5), style, - dpr = [1, 2], + dpr = [window.devicePixelRatio * 0.5, 2], className }) => ( = ({ const { scene } = useGltfLoader(modelSrc); const { nodes } = useGraph(scene); + const animationClip = useMemo(async () => loadAnimationClip(animationSrc), [animationSrc]); + const animationMixer = useMemo(async () => { const mixer = new AnimationMixer(nodes.Armature); if (animationRunning) { return mixer; } - const animationClip = await loadAnimationClip(animationSrc); - - const animation = mixer.clipAction(animationClip); + const animation = mixer.clipAction(await animationClip); animation.fadeIn(0.5); animation.play(); mixer.update(0); return mixer; - }, [animationRunning, animationSrc, nodes.Armature]); + }, [animationRunning, animationClip, nodes.Armature]); useFrame(async (state, delta) => { (await animationMixer)?.update(delta); diff --git a/src/components/Spawn/SpawnAnimation/SpawnAnimation.component.tsx b/src/components/Spawn/SpawnAnimation/SpawnAnimation.component.tsx index a4bb924a..d72df287 100644 --- a/src/components/Spawn/SpawnAnimation/SpawnAnimation.component.tsx +++ b/src/components/Spawn/SpawnAnimation/SpawnAnimation.component.tsx @@ -24,14 +24,15 @@ export const SpawnAnimation: FC = ({ avatar, onLoadedAnimat const { nodes: avatarNode } = useGraph(avatar); + const animationClip = useMemo(async () => loadAnimationClip(onLoadedAnimation?.src || ''), [onLoadedAnimation?.src]); + const animationMixerAvatar = useMemo(async () => { const mixer = new AnimationMixer(avatarNode.Armature); if (!avatarNode.Armature) { return mixer; } - const animationClip = await loadAnimationClip(onLoadedAnimation?.src || ''); - const animation = mixer.clipAction(animationClip); + const animation = mixer.clipAction(await animationClip); animation.setLoop(LoopRepeat, onLoadedAnimation?.loop || 1); animation.clampWhenFinished = true; @@ -44,7 +45,7 @@ export const SpawnAnimation: FC = ({ avatar, onLoadedAnimat }); return mixer; - }, [avatarNode.Armature, onLoadedAnimation?.loop, onLoadedAnimation?.src]); + }, [avatarNode.Armature, onLoadedAnimation?.loop, animationClip]); useFrame(async (state, delta) => { (await animationMixerAvatar)?.update(delta); diff --git a/src/components/Spawn/SpawnEffect/SpawnEffect.component.tsx b/src/components/Spawn/SpawnEffect/SpawnEffect.component.tsx index f19ab9d3..b946a34a 100644 --- a/src/components/Spawn/SpawnEffect/SpawnEffect.component.tsx +++ b/src/components/Spawn/SpawnEffect/SpawnEffect.component.tsx @@ -22,16 +22,21 @@ export const SpawnEffect: FC = ({ onLoadedEffect, onLoadedEffe } }, [onLoadedEffectFinish, effectRunning]); + const animationLoadedEffect = useMemo( + async () => loadAnimationClip(onLoadedEffect?.animationSrc || onLoadedEffect.src), + [onLoadedEffect?.animationSrc, onLoadedEffect.src] + ); + const spawnEffectMixer = useMemo(async () => { - const animationLoadedEffect = await loadAnimationClip(onLoadedEffect?.animationSrc || onLoadedEffect.src); const mixer = new AnimationMixer(mountEffectNode.Scene); + const loadedEffect = await animationLoadedEffect; - if (!animationLoadedEffect) { + if (!loadedEffect) { setEffectRunning(false); return mixer; } - const animation = mixer.clipAction(animationLoadedEffect); + const animation = mixer.clipAction(loadedEffect); animation.setLoop(LoopRepeat, onLoadedEffect?.loop || 1); animation.clampWhenFinished = true; @@ -44,7 +49,7 @@ export const SpawnEffect: FC = ({ onLoadedEffect, onLoadedEffe }); return mixer; - }, [mountEffectNode.Scene, onLoadedEffect?.animationSrc, onLoadedEffect?.loop, onLoadedEffect.src]); + }, [mountEffectNode.Scene, animationLoadedEffect, onLoadedEffect?.loop]); useFrame(async (state, delta) => { (await spawnEffectMixer)?.update(delta); diff --git a/src/services/Animation.service.ts b/src/services/Animation.service.ts index ffa207dc..9ead4803 100644 --- a/src/services/Animation.service.ts +++ b/src/services/Animation.service.ts @@ -10,6 +10,10 @@ interface ClipWithType { const MIXAMO_PREFIX = 'mixamorig'; const POSITION_SUFFIX = '.position'; const MIXAMO_SCALE = 0.01; + +const fbxLoader = new FBXLoader(); +const gltfLoader = new GLTFLoader(); + function normaliseFbxAnimation(fbx: Group, index: number = 0) { const { tracks } = fbx.animations[index]; @@ -31,9 +35,6 @@ function normaliseFbxAnimation(fbx: Group, index: number = 0) { } const loadBlobFile = async (blob: Blob): Promise => { - const fbxLoader = new FBXLoader(); - const gltfLoader = new GLTFLoader(); - try { const buffer = await blob.arrayBuffer(); return { @@ -49,9 +50,6 @@ const loadBlobFile = async (blob: Blob): Promise => { }; const loadPathFile = async (source: string): Promise => { - const fbxLoader = new FBXLoader(); - const gltfLoader = new GLTFLoader(); - try { return { group: (await gltfLoader.loadAsync(source)) as unknown as Group, diff --git a/src/services/Models.service.tsx b/src/services/Models.service.tsx index b1f9ed7f..68cda817 100644 --- a/src/services/Models.service.tsx +++ b/src/services/Models.service.tsx @@ -205,13 +205,13 @@ export const useEmotion = (nodes: ObjectMap['nodes'], emotion?: Emotion) => { }); }; +const loader = new GLTFLoader(); +const dracoLoader = new DRACOLoader(); +dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.5/'); +loader.setDRACOLoader(dracoLoader); + export const useGltfLoader = (source: Blob | string): GLTF => suspend(async () => { - const loader = new GLTFLoader(); - const dracoLoader = new DRACOLoader(); - dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.5/'); - loader.setDRACOLoader(dracoLoader); - if (source instanceof Blob) { const buffer = await source.arrayBuffer(); return (await loader.parseAsync(buffer, '')) as unknown as GLTF;