Closed4
アニメーション作成記録
TODO
- Next.js プロジェクトの作成
- アニメーションモデル
- FBXのロード
- FBXのアニメーションを実行
- T-pose モデルに、アニメーションをブレンドする
- 複数アニメーションを登録する
- ボタンを追加して、アニメーションの切り替えを行う
- 段階的にデータをロードする
FIX
- GET500エラー
参考サイト
Three.js
FBXモデルのロード
import { FBXLoader } from 'three/examples/jsm/Addons.js';
...省略...
const fbxloader: FBXLoader = new FBXLoader();
fbxloader_thinking.load('models/example.fbx', (fbx) => {
fbx_model_thinking = fbx;
scene.add(fbx_model_thinking);
fbx_model_thinking.position.set(0, 0, 0);
fbx_model_thinking.scale.set(1, 1, 1);
});
FBX アニメーションの実行
//model loader
const fbxloader: FBXLoader = new FBXLoader();
let mixer: THREE.AnimationMixer;
fbxloader.load('models/Samba Dancing.fbx', (object) => {
object.position.set(0, 0, 0);
object.scale.set(.05,.05,.05);
mixer = new THREE.AnimationMixer(object);
const action = mixer.clipAction( object.animations[ 0 ] );
action.play();
scene.add(object);
});
T-pose モデルにアニメーションをブレンドする。
const fbxloader: FBXLoader = new FBXLoader();
let mixer: THREE.AnimationMixer;
fbxloader.load('models/vanguard_t_choonyung.fbx', (object) => {
object.position.set(0, 0, 0);
object.scale.set(.05,.05,.05);
const anim = new FBXLoader();
anim.load('models/Vanguard@Sitting.fbx', (anim) => {
mixer = new THREE.AnimationMixer(object);
const action = mixer.clipAction(anim.animations[0]);
action.play();
});
scene.add(object);
公式サンプルを確認すると、すでにアニメーションが登録されているモデルがほとんどっぽい?
複数モーションの登録
const animationActions: THREE.AnimationAction[] = []; // ここにアニメーションを追加していく
const fbxloader: FBXLoader = new FBXLoader();
let mixer: THREE.AnimationMixer;
let activeAction: THREE.AnimationAction;
let lastAction: THREE.AnimationAction;
fbxloader.load('/models/Vanguard.fbx', (object) => {
object.position.set(0, 0, 0);
object.scale.set(.05,.05,.05);
mixer = new THREE.AnimationMixer(object);
const animationAction_tpose = mixer.clipAction(object.animations[0]); //t-pose action
animationActions.push(animationAction_tpose);
const anim_sitting = new FBXLoader();
anim_sitting.load('/models/Sitting.fbx', (anim: THREE.Group<THREE.Object3DEventMap>) => {
const animationAction_Sit = mixer.clipAction(anim.animations[0]); //sitting action
animationActions.push(animationAction_Sit);
const anim_running = new FBXLoader();
anim_running.load('/models/Running.fbx', (anim: THREE.Group<THREE.Object3DEventMap>) => {
anim.animations[0].tracks.shift(); //走行中にオブジェクトを前進させる特定のトラックを削除する。
const animationAction_Run = mixer.clipAction(anim.animations[0]); //running action
animationActions.push(animationAction_Run);
activeAction = animationActions[0];
lastAction = animationActions[0];
},
(error) => {
console.log(error, 'failed to Load Run');
});
},
(error) => {
console.log(error, 'failed to Load Sit');
});
scene.add(object);
},
(error) => {
console.log(error, 'failed to Load Model');
});
ボタンにアクションを紐づけする
return (
<main className='h-screen'>
<canvas ref={ref}/>
<button onClick={animations.default} className='mx-4 my-2'>TPose</button>
<button onClick={animations.sit} className='mx-4 my-2'>Sitting</button>
<button onClick={animations.run} className='mx-4 my-2'>Running</button>
</main>
);
const animations = {
default: function () {
setAction(animationActions[0])
},
sit: function () {
setAction(animationActions[1])
},
run: function () {
setAction(animationActions[2])
},
}
const setAction = (toAction: THREE.AnimationAction) => {
if (toAction != activeAction) {
lastAction = activeAction
activeAction = toAction
lastAction.stop()
activeAction.reset()
activeAction.play()
}
}
Next.js+Three.js TypeError: Failed to parse URL from /models/xxx.fbx
⨯ TypeError: Failed to parse URL from /models/Vanguard.fbx
at eval (./app/page.tsx:105:11)
at (ssr)/./app/page.tsx (/workspaces/typescript-node/model_description/.next/server/app/page.js:140:1)
at Object.__webpack_require__ [as require] (/workspaces/typescript-node/model_description/.next/server/webpack-runtime.js:33:42)
at JSON.parse (<anonymous>)
digest: "3080107415"
Cause: TypeError: Invalid URL
at new URL (node:internal/url:796:36)
at new Request (node:internal/deps/undici/undici:6108:25)
at FileLoader.load (webpack-internal:///(ssr)/./node_modules/three/build/three.module.js:43846:15)
at FBXLoader.load (webpack-internal:///(ssr)/./node_modules/three/examples/jsm/loaders/FBXLoader.js:52:10)
at eval (webpack-internal:///(ssr)/./app/page.tsx:105:11)
at (ssr)/./app/page.tsx (/workspaces/typescript-node/model_description/.next/server/app/page.js:140:1)
at Object.__webpack_require__ [as require] (/workspaces/typescript-node/model_description/.next/server/webpack-runtime.js:33:42)
at require (/workspaces/typescript-node/model_description/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:39:19604)
at /workspaces/typescript-node/model_description/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:108279
at eo (/workspaces/typescript-node/model_description/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:108464)
at /workspaces/typescript-node/model_description/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:110693
at Object._fromJSON (/workspaces/typescript-node/model_description/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:111249)
at JSON.parse (<anonymous>)
at eu (/workspaces/typescript-node/model_description/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:108958)
at en (/workspaces/typescript-node/model_description/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:108026)
at /workspaces/typescript-node/model_description/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:115168
at /workspaces/typescript-node/model_description/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:115185
at /workspaces/typescript-node/model_description/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:115218
at /workspaces/typescript-node/model_description/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:115235
at t (/workspaces/typescript-node/model_description/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:115458) {
code: 'ERR_INVALID_URL',
input: '/models/Vanguard.fbx'
}
GET / 500 in 107ms
-> モデルのロードをSSRでレンダリングする際に、発生する模様。
-> Dynamic importなるもので、解決できるらしい?
-> 応急処置として、useEffectの中に、モデルロードを突っ込んでみる。
-> エラーは発生しなくなったが、イベントを起こした時に、表示がバグってしまう。
-> 最近、またNext.jsのキャッシュ周りが変更されるらしいので、この辺りは静観
useEffectによるモデルロードの制御
発火タイミング
useEffect(setup, dependencies?)
setup : 処理の内容
dependencies : 監視する値
dependencis
に設定できる
レンダリングする際に毎回更新する。
useEffect(() => {
なんか処理する。
});
画面生成時に一回だけ実行する。
useEffect(() => {
なんか処理する。
}, []);
監視対象の値がレンダリングされた場合に更新される。
useEffect(() => {
なんか処理する。
}, [value]);
このスクラップは5ヶ月前にクローズされました