-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
extract useAnimation from motion-file-mode of camera
- Loading branch information
Showing
3 changed files
with
48 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import useGlobalStore from "@/app/stores/useGlobalStore"; | ||
import usePresetStore from "@/app/stores/usePresetStore"; | ||
import { onProgress } from "@/app/utils/base"; | ||
import { useFrame } from "@react-three/fiber"; | ||
import { use, useEffect } from "react"; | ||
import { AnimationMixer, Camera, SkinnedMesh } from "three"; | ||
|
||
function useAnimation(target: Camera | SkinnedMesh, mixer: AnimationMixer, vmdFile: string, callback?: Function) { | ||
const loader = useGlobalStore(state => state.loader) | ||
const clip = use(loader.loadAnimation(vmdFile, target, onProgress)) | ||
|
||
const player = useGlobalStore(state => state.player) | ||
const isMotionUpdating = useGlobalStore(state => state.isMotionUpdating) | ||
|
||
const setTime = (currentTime: number) => { | ||
mixer.setTime(currentTime) | ||
callback(currentTime) | ||
} | ||
useEffect(() => { | ||
const savedCurrentTime = usePresetStore.getState().currentTime | ||
|
||
const action = mixer.clipAction(clip) | ||
action.play() | ||
if(callback) setTime(savedCurrentTime) | ||
return () => { | ||
mixer.stopAllAction() | ||
mixer.uncacheRoot(target) | ||
} | ||
}, [target, vmdFile, callback]) | ||
|
||
useFrame(() => { | ||
if (isMotionUpdating.current) setTime(player.currentTime) | ||
}, 1) | ||
} | ||
|
||
export default useAnimation; |
56 changes: 11 additions & 45 deletions
56
app/components/three-world/camera/helper/motion-file-mode/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,23 @@ | ||
import useGlobalStore from "@/app/stores/useGlobalStore"; | ||
import usePresetStore from "@/app/stores/usePresetStore"; | ||
import { onProgress } from "@/app/utils/base"; | ||
import { useFrame, useThree } from "@react-three/fiber"; | ||
import { Suspense, use, useEffect, useMemo } from "react"; | ||
import { AnimationClip, AnimationMixer } from "three"; | ||
import { useThree } from "@react-three/fiber"; | ||
import { useCallback, useMemo } from "react"; | ||
import { AnimationMixer } from "three"; | ||
import useAnimation from "../../../animation/useAnimation"; | ||
import WithSuspense from "@/app/components/suspense"; | ||
|
||
|
||
function MotionFileMode({ animationPromise }: { animationPromise: Promise<AnimationClip> }) { | ||
const cameraName = usePresetStore(state => state.camera) | ||
|
||
const clip = use(animationPromise) | ||
|
||
const player = useGlobalStore(state => state.player) | ||
const isMotionUpdating = useGlobalStore(state => state.isMotionUpdating) | ||
|
||
function MotionFileMode() { | ||
const camera = useThree(state => state.camera) | ||
const cameraMixer = useMemo(() => new AnimationMixer(camera), [camera]) | ||
|
||
const setTime = (time: number) => { | ||
cameraMixer.setTime(time) | ||
|
||
const cameraFile = usePresetStore(state => state.cameraFile) | ||
const setTimeCb = useCallback(() => { | ||
camera.up.set(0, 1, 0); | ||
camera.up.applyQuaternion(camera.quaternion); | ||
camera.lookAt(camera.getObjectByName("target").position); | ||
camera.updateProjectionMatrix(); | ||
} | ||
|
||
useEffect(() => { | ||
const savedCurrentTime = usePresetStore.getState().currentTime | ||
|
||
const action = cameraMixer.clipAction(clip) | ||
action.play() | ||
setTime(savedCurrentTime) | ||
return () => cameraMixer.stopAllAction() && cameraMixer.uncacheRoot(camera) | ||
}, [camera, cameraName]) | ||
|
||
useFrame(() => { | ||
if (isMotionUpdating.current) setTime(player.currentTime) | ||
}, 1) | ||
}, [camera, cameraMixer]) | ||
useAnimation(camera, cameraMixer, cameraFile, setTimeCb) | ||
return <></>; | ||
} | ||
|
||
function SetupMotionFile() { | ||
const cameraFile = usePresetStore(state => state.cameraFile) | ||
const loader = useGlobalStore(state => state.loader) | ||
const camera = useThree(state => state.camera) | ||
|
||
const animationPromise = loader.loadAnimation(cameraFile, camera, onProgress) | ||
return ( | ||
<Suspense fallback={null}> | ||
<MotionFileMode animationPromise={animationPromise}></MotionFileMode> | ||
</Suspense> | ||
); | ||
} | ||
|
||
export default SetupMotionFile; | ||
export default WithSuspense(MotionFileMode); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters