From 66bd4ef9f693d18d7bec4bc2aec0dd6a23475229 Mon Sep 17 00:00:00 2001 From: Chau Tran Date: Fri, 31 Mar 2023 14:33:06 -0500 Subject: [PATCH] fix: adjust inject animations --- .../misc/src/lib/animations/animations.ts | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/libs/angular-three-soba/misc/src/lib/animations/animations.ts b/libs/angular-three-soba/misc/src/lib/animations/animations.ts index b7e3219..73c93ef 100644 --- a/libs/angular-three-soba/misc/src/lib/animations/animations.ts +++ b/libs/angular-three-soba/misc/src/lib/animations/animations.ts @@ -1,7 +1,7 @@ import { injectBeforeRender, injectNgtDestroy, injectNgtRef, NgtInjectedRef } from 'angular-three'; -import { Observable, takeUntil } from 'rxjs'; +import { map, Observable, switchMap, takeUntil } from 'rxjs'; import * as THREE from 'three'; -import { GLTF } from 'three-stdlib'; +import { AnimationClip } from 'three'; type Api = { ref: NgtInjectedRef; @@ -12,10 +12,19 @@ type Api = { }; export function injectNgtsAnimations( - gltf$: Observable, - modelSelector: (gltf: GLTF) => THREE.Object3D = (gltf) => gltf.scene + animations$: Observable, + ref?: NgtInjectedRef | THREE.Object3D ): Api { - const ref = injectNgtRef(); + let actualRef = injectNgtRef(); + + if (ref) { + if (ref instanceof THREE.Object3D) { + actualRef.nativeElement = ref; + } else { + actualRef = ref; + } + } + const mixer = new THREE.AnimationMixer(null!); const actions = {} as Record; let cached = {} as Record; @@ -28,8 +37,8 @@ export function injectNgtsAnimations( cached = {}; // uncache actions Object.values(actions).forEach((action) => { - if (ref.nativeElement) { - mixer.uncacheAction(action as unknown as THREE.AnimationClip, ref.nativeElement); + if (actualRef.nativeElement) { + mixer.uncacheAction(action as unknown as THREE.AnimationClip, actualRef.nativeElement); } }); // stop all actions @@ -38,28 +47,27 @@ export function injectNgtsAnimations( injectBeforeRender(({ delta }) => mixer.update(delta)); - gltf$.pipe(takeUntil(destroy$)).subscribe((gltf) => { - const model = modelSelector(gltf); - ref.nativeElement = model; - - for (let i = 0; i < gltf.animations.length; i++) { - const clip = gltf.animations[i]; + actualRef.$.pipe(takeUntil(destroy$)) + .pipe(switchMap((object) => animations$.pipe(map((animations) => [object, animations] as const)))) + .subscribe(([object, animations]) => { + for (let i = 0; i < animations.length; i++) { + const clip = animations[i]; - names.push(clip.name); - clips.push(clip); + names.push(clip.name); + clips.push(clip); - Object.defineProperty(actions, clip.name, { - enumerable: true, - get: () => { - return cached[clip.name] || (cached[clip.name] = mixer.clipAction(clip, model)); - }, - }); + Object.defineProperty(actions, clip.name, { + enumerable: true, + get: () => { + return cached[clip.name] || (cached[clip.name] = mixer.clipAction(clip, object)); + }, + }); - if (i === 0) { - actions[clip.name].play(); + if (i === 0) { + actions[clip.name].play(); + } } - } - }); + }); - return { ref, actions, mixer, names, clips }; + return { ref: actualRef, actions, mixer, names, clips }; }