Skip to content

Commit 9b16937

Browse files
Chau TranChau Tran
authored andcommitted
feat(soba): migrate performance
1 parent 0d3245d commit 9b16937

File tree

17 files changed

+436
-6
lines changed

17 files changed

+436
-6
lines changed

libs/angular-three/src/lib/loader.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ injectNgtLoader['preload'] = <
140140
TLoaderConstructor extends NgtLoaderProto<TData>
141141
>(
142142
loaderConstructorFactory: (inputs: string[]) => TLoaderConstructor,
143-
inputs: Signal<TUrl>,
143+
inputs: () => TUrl,
144144
extensions?: NgtLoaderExtensions<TLoaderConstructor>
145145
) => {
146146
Promise.all(load(loaderConstructorFactory, inputs, { extensions })());

libs/soba/controls/src/orbit-controls/orbit-controls.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,18 @@ export class NgtsOrbitControls extends NgtSignalStore<NgtsOrbitControlsState> {
154154
#setEvents() {
155155
const trigger = computed(() => {
156156
const invalidate = this.#store.select('invalidate');
157-
const performance = this.#store.get('performance');
158-
return { invalidate: invalidate(), performance, controls: this.controlsRef.nativeElement };
157+
const performance = this.#store.select('performance');
158+
const regress = this.select('regress');
159+
return {
160+
invalidate: invalidate(),
161+
performance: performance(),
162+
regress: regress(),
163+
controls: this.controlsRef.nativeElement,
164+
};
159165
});
160166
effect((onCleanup) => {
161-
const { controls, invalidate, performance } = trigger();
167+
const { controls, invalidate, performance, regress } = trigger();
162168
if (!controls) return;
163-
const regress = this.get('regress');
164169
const changeCallback: (e: THREE.Event) => void = (e) => {
165170
invalidate();
166171
if (regress) performance.regress();

libs/soba/loaders/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# angular-three-soba/loaders
2+
3+
Secondary entry point of `angular-three-soba`. It can be used by importing from `angular-three-soba/loaders`.

libs/soba/loaders/ng-package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"lib": {
3+
"entryFile": "src/index.ts"
4+
}
5+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { Injector, Signal } from '@angular/core';
2+
import { injectNgtLoader, type NgtLoaderResults, type NgtObjectMap } from 'angular-three';
3+
// @ts-ignore
4+
import { MeshoptDecoder } from 'three-stdlib';
5+
import { DRACOLoader } from 'three-stdlib/loaders/DRACOLoader';
6+
import { GLTF, GLTFLoader } from 'three-stdlib/loaders/GLTFLoader';
7+
8+
let dracoLoader: DRACOLoader | null = null;
9+
10+
function _extensions(useDraco: boolean | string, useMeshOpt: boolean, extensions?: (loader: GLTFLoader) => void) {
11+
return (loader: THREE.Loader) => {
12+
if (extensions) {
13+
extensions(loader as GLTFLoader);
14+
}
15+
16+
if (useDraco) {
17+
if (!dracoLoader) {
18+
dracoLoader = new DRACOLoader();
19+
}
20+
21+
dracoLoader.setDecoderPath(
22+
typeof useDraco === 'string' ? useDraco : 'https://www.gstatic.com/draco/versioned/decoders/1.4.3/'
23+
);
24+
(loader as GLTFLoader).setDRACOLoader(dracoLoader);
25+
}
26+
27+
if (useMeshOpt) {
28+
(loader as GLTFLoader).setMeshoptDecoder(
29+
typeof MeshoptDecoder === 'function' ? MeshoptDecoder() : MeshoptDecoder
30+
);
31+
}
32+
};
33+
}
34+
35+
export function injectNgtsGLTFLoader<TUrl extends string | string[] | Record<string, string>>(
36+
path: () => TUrl,
37+
{
38+
useDraco = true,
39+
useMeshOpt = true,
40+
injector,
41+
extensions,
42+
}: {
43+
useDraco?: boolean | string;
44+
useMeshOpt?: boolean;
45+
injector?: Injector;
46+
extensions?: (loader: GLTFLoader) => void;
47+
} = {}
48+
): Signal<NgtLoaderResults<TUrl, GLTF & NgtObjectMap>> {
49+
return injectNgtLoader(() => GLTFLoader, path, {
50+
extensions: _extensions(useDraco, useMeshOpt, extensions),
51+
injector,
52+
});
53+
}
54+
55+
injectNgtsGLTFLoader['preload'] = <TUrl extends string | string[] | Record<string, string>>(
56+
path: () => TUrl,
57+
{
58+
useDraco = true,
59+
useMeshOpt = true,
60+
extensions,
61+
}: {
62+
useDraco?: boolean | string;
63+
useMeshOpt?: boolean;
64+
extensions?: (loader: GLTFLoader) => void;
65+
}
66+
) => {
67+
injectNgtLoader.preload(() => GLTFLoader, path, _extensions(useDraco, useMeshOpt, extensions));
68+
};

libs/soba/loaders/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './gltf-loader/gltf-loader';

libs/soba/performance/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# angular-three-soba/performance
2+
3+
Secondary entry point of `angular-three-soba`. It can be used by importing from `angular-three-soba/performance`.

libs/soba/performance/ng-package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"lib": {
3+
"entryFile": "src/index.ts"
4+
}
5+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Directive, effect, inject, Input, signal, untracked } from '@angular/core';
2+
import { NgtStore } from 'angular-three';
3+
4+
@Directive({
5+
selector: 'ngts-adaptive-dpr',
6+
standalone: true,
7+
})
8+
export class NgtsAdaptiveDpr {
9+
#pixelated = signal(false);
10+
@Input() set pixelated(pixelated: boolean) {
11+
this.#pixelated.set(pixelated);
12+
}
13+
14+
constructor() {
15+
const store = inject(NgtStore);
16+
effect(
17+
(onCleanup) => {
18+
const domElement = store.get('gl', 'domElement');
19+
onCleanup(() => {
20+
const active = store.get('internal', 'active');
21+
const setDpr = store.get('setDpr');
22+
const initialDpr = store.get('viewport', 'initialDpr');
23+
if (active) setDpr(initialDpr);
24+
if (untracked(this.#pixelated) && domElement) domElement.style.imageRendering = 'auto';
25+
});
26+
},
27+
{ allowSignalWrites: true }
28+
);
29+
30+
effect(
31+
() => {
32+
const performanceCurrent = store.select('performance', 'current');
33+
const { gl, viewport, setDpr } = store.get();
34+
setDpr(performanceCurrent() * viewport.initialDpr);
35+
if (untracked(this.#pixelated) && gl.domElement)
36+
gl.domElement.style.imageRendering = performanceCurrent() === 1 ? 'auto' : 'pixelated';
37+
},
38+
{ allowSignalWrites: true }
39+
);
40+
}
41+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Directive, effect, inject } from '@angular/core';
2+
import { NgtStore } from 'angular-three';
3+
4+
@Directive({
5+
selector: 'ngts-adaptive-events',
6+
standalone: true,
7+
})
8+
export class NgtsAdaptiveEvents {
9+
constructor() {
10+
const store = inject(NgtStore);
11+
effect(
12+
(onCleanup) => {
13+
const enabled = store.get('events', 'enabled');
14+
onCleanup(() => {
15+
const setEvents = store.get('setEvents');
16+
setEvents({ enabled });
17+
});
18+
},
19+
{ allowSignalWrites: true }
20+
);
21+
22+
effect(
23+
() => {
24+
const performanceCurrent = store.select('performance', 'current')();
25+
const setEvents = store.get('setEvents');
26+
setEvents({ enabled: performanceCurrent === 1 });
27+
},
28+
{ allowSignalWrites: true }
29+
);
30+
}
31+
}

0 commit comments

Comments
 (0)