Skip to content

Commit fc81399

Browse files
committed
more docs
1 parent faa55a6 commit fc81399

File tree

23 files changed

+1175
-130
lines changed

23 files changed

+1175
-130
lines changed
424 KB
Binary file not shown.

src/components/scenes/gltf-demo-home/scene-graph.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { injectMatcapTexture } from 'angular-three-soba/staging';
77
import * as THREE from 'three';
88
import { SkeletonUtils, type GLTF } from 'three-stdlib';
99

10-
import botGLB from './ybot.glb' with { loader: 'file' };
10+
import botGLB from '@common-assets/ybot.glb' with { loader: 'file' };
1111

1212
type BotGLTF = GLTF & {
1313
animations: NgtsAnimationClips<'Dance'>[];

src/components/soba/abstractions/text/scene-graph.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,19 @@ export class Cloud {
7979
protected words = computed(() => {
8080
const [count, radius] = [this.count(), this.radius()];
8181

82-
const temp: { position: NgtVector3; text: string }[] = [];
82+
const words: { position: NgtVector3; text: string }[] = [];
8383
const spherical = new THREE.Spherical();
8484
const phiSpan = Math.PI / (count + 1);
8585
const thetaSpan = (Math.PI * 2) / count;
8686
for (let i = 1; i < count + 1; i++) {
8787
for (let j = 0; j < count; j++) {
88-
temp.push({
88+
words.push({
8989
position: new THREE.Vector3().setFromSpherical(spherical.set(radius, phiSpan * i, thetaSpan * j)),
9090
text: generateWord(),
9191
});
9292
}
9393
}
94-
return temp;
94+
return words;
9595
});
9696
}
9797

src/components/soba/abstractions/text/text.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ export default class Text {
2727

2828
protected host = inject(ElementRef);
2929

30-
count = signal(8);
31-
radius = signal(20);
30+
protected count = signal(8);
31+
protected radius = signal(20);
3232
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { ChangeDetectionStrategy, Component, ElementRef, inject, signal } from '@angular/core';
2+
import { SobaWrapper } from '@soba/wrapper.ts';
3+
import { NgtTweakList, NgtTweakPane } from 'angular-three-tweakpane';
4+
import { NgtCanvas, provideNgtRenderer } from 'angular-three/dom';
5+
import { SceneGraph } from './scene-graph';
6+
7+
@Component({
8+
selector: 'app-soba-animations',
9+
template: `
10+
<ngt-canvas [camera]="{ position: [0, 2, 4] }">
11+
<app-soba-wrapper *canvasContent>
12+
<app-scene-graph [animation]="animation()" />
13+
</app-soba-wrapper>
14+
</ngt-canvas>
15+
16+
<ngt-tweak-pane title="Animations" [container]="host">
17+
<ngt-tweak-list [(value)]="animation" label="animation" [options]="['Dance', 'Idle', 'Strut']" />
18+
</ngt-tweak-pane>
19+
`,
20+
imports: [NgtCanvas, SobaWrapper, SceneGraph, NgtTweakList, NgtTweakPane],
21+
changeDetection: ChangeDetectionStrategy.OnPush,
22+
host: { class: 'animations-demo relative block h-full' },
23+
})
24+
export default class Animations {
25+
static clientProviders = [provideNgtRenderer()];
26+
27+
protected host = inject(ElementRef);
28+
protected animation = signal<'Dance' | 'Idle' | 'Strut'>('Strut');
29+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import {
2+
ChangeDetectionStrategy,
3+
Component,
4+
computed,
5+
CUSTOM_ELEMENTS_SCHEMA,
6+
effect,
7+
type ElementRef,
8+
input,
9+
viewChild,
10+
} from '@angular/core';
11+
import { injectGLTF } from 'angular-three-soba/loaders';
12+
import { injectAnimations, type NgtsAnimationClips } from 'angular-three-soba/misc';
13+
import { injectMatcapTexture } from 'angular-three-soba/staging';
14+
import * as THREE from 'three';
15+
import type { GLTF } from 'three-stdlib';
16+
17+
import botGLB from '@common-assets/ybot.glb' with { loader: 'file' };
18+
import { NgtArgs } from 'angular-three';
19+
20+
type BotGLTF = GLTF & {
21+
animations: NgtsAnimationClips<'Dance' | 'Idle' | 'Strut'>[];
22+
nodes: {
23+
'Y-Bot': THREE.Object3D;
24+
YB_Body: THREE.SkinnedMesh;
25+
YB_Joints: THREE.SkinnedMesh;
26+
mixamorigHips: THREE.Bone;
27+
};
28+
materials: { YB_Body: THREE.MeshStandardMaterial; YB_Joints: THREE.MeshStandardMaterial };
29+
};
30+
31+
@Component({
32+
selector: 'app-scene-graph',
33+
template: `
34+
@if (gltf(); as gltf) {
35+
<ngt-group #group [dispose]="null">
36+
<ngt-group [rotation]="[Math.PI / 2, 0, 0]" [scale]="0.01">
37+
<ngt-primitive #bone *args="[gltf.nodes.mixamorigHips]" />
38+
<ngt-skinned-mesh [geometry]="gltf.nodes.YB_Body.geometry" [skeleton]="gltf.nodes.YB_Body.skeleton">
39+
<ngt-mesh-matcap-material [matcap]="matcapBody.texture()" />
40+
</ngt-skinned-mesh>
41+
<ngt-skinned-mesh
42+
[geometry]="gltf.nodes.YB_Joints.geometry"
43+
[skeleton]="gltf.nodes.YB_Joints.skeleton"
44+
>
45+
<ngt-mesh-matcap-material [matcap]="matcapJoints.texture()" />
46+
</ngt-skinned-mesh>
47+
</ngt-group>
48+
</ngt-group>
49+
}
50+
`,
51+
changeDetection: ChangeDetectionStrategy.OnPush,
52+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
53+
imports: [NgtArgs],
54+
})
55+
export class SceneGraph {
56+
animation = input<'Dance' | 'Idle' | 'Strut'>('Strut');
57+
58+
private boneRef = viewChild<ElementRef<THREE.Bone>>('bone');
59+
private groupRef = viewChild.required<ElementRef<THREE.Group>>('group');
60+
61+
protected gltf = injectGLTF<BotGLTF>(() => botGLB);
62+
protected matcapBody = injectMatcapTexture(() => '293534_B2BFC5_738289_8A9AA7', {
63+
onLoad: (textures) => {
64+
textures[0].colorSpace = THREE.SRGBColorSpace;
65+
},
66+
});
67+
protected matcapJoints = injectMatcapTexture(() => '3A2412_A78B5F_705434_836C47', {
68+
onLoad: (textures) => {
69+
textures[0].colorSpace = THREE.SRGBColorSpace;
70+
},
71+
});
72+
protected readonly Math = Math;
73+
74+
private animationHost = computed(() => (this.boneRef() ? this.groupRef() : null));
75+
private animations = injectAnimations(this.gltf, this.animationHost);
76+
77+
constructor() {
78+
effect((onCleanup) => {
79+
if (!this.animations.isReady) return;
80+
81+
const action = this.animations.actions[this.animation()];
82+
action.reset().fadeIn(0.5).play();
83+
onCleanup(() => action.fadeOut(0.5));
84+
});
85+
}
86+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { ChangeDetectionStrategy, Component, ElementRef, inject, signal } from '@angular/core';
2+
import { SobaWrapper } from '@soba/wrapper.ts';
3+
import { NgtTweakCheckbox, NgtTweakPane } from 'angular-three-tweakpane';
4+
import { NgtCanvas, provideNgtRenderer } from 'angular-three/dom';
5+
import { SceneGraph } from './scene-graph';
6+
7+
@Component({
8+
selector: 'app-adaptive-soba',
9+
template: `
10+
<ngt-canvas [camera]="{ position: [0, 0, 30], fov: 50 }" [performance]="{ min: 0.2 }">
11+
<app-soba-wrapper *canvasContent [grid]="false" [controls]="null" [lights]="false">
12+
<app-scene-graph [pixelated]="pixelated()" />
13+
</app-soba-wrapper>
14+
</ngt-canvas>
15+
16+
<ngt-tweak-pane title="Adaptive" [container]="host">
17+
<ngt-tweak-checkbox [(value)]="pixelated" label="pixelated" />
18+
</ngt-tweak-pane>
19+
`,
20+
host: { class: 'adaptive-demo relative block h-full' },
21+
changeDetection: ChangeDetectionStrategy.OnPush,
22+
imports: [NgtCanvas, SobaWrapper, SceneGraph, NgtTweakPane, NgtTweakCheckbox],
23+
})
24+
export default class Adaptive {
25+
static clientProviders = [provideNgtRenderer()];
26+
27+
protected host = inject(ElementRef);
28+
protected pixelated = signal(true);
29+
}
Binary file not shown.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, input } from '@angular/core';
2+
import { NgtsOrbitControls } from 'angular-three-soba/controls';
3+
import { injectGLTF } from 'angular-three-soba/loaders';
4+
import { NgtsAdaptiveDpr, NgtsAdaptiveEvents } from 'angular-three-soba/performances';
5+
import * as THREE from 'three';
6+
import type { GLTF } from 'three-stdlib';
7+
8+
import archerGLB from '@common-assets/archer.glb' with { loader: 'file' };
9+
10+
interface ArcherGLTF extends GLTF {
11+
materials: { material_0: THREE.MeshStandardMaterial };
12+
nodes: Record<'mesh_0' | 'mesh_1' | 'mesh_2', THREE.Mesh>;
13+
}
14+
15+
@Component({
16+
selector: 'app-adaptive-archer',
17+
template: `
18+
@if (gltf(); as gltf) {
19+
@let material = gltf.materials.material_0;
20+
@let nodes = gltf.nodes;
21+
22+
<ngt-group [dispose]="null">
23+
<ngt-group [rotation]="[-Math.PI / 2, 0, 0]">
24+
<ngt-group [position]="[0, 0, 2]">
25+
<ngt-mesh castShadow receiveShadow [material]="material" [geometry]="nodes.mesh_0.geometry" />
26+
<ngt-mesh castShadow receiveShadow [geometry]="nodes.mesh_1.geometry" [material]="material" />
27+
<ngt-mesh castShadow receiveShadow [material]="material" [geometry]="nodes.mesh_2.geometry" />
28+
</ngt-group>
29+
</ngt-group>
30+
</ngt-group>
31+
}
32+
`,
33+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
34+
changeDetection: ChangeDetectionStrategy.OnPush,
35+
})
36+
class Archer {
37+
protected readonly Math = Math;
38+
protected gltf = injectGLTF<ArcherGLTF>(() => archerGLB);
39+
}
40+
41+
@Component({
42+
selector: 'app-scene-graph',
43+
template: `
44+
<app-adaptive-archer />
45+
<ngt-directional-light
46+
castShadow
47+
[intensity]="0.2 * Math.PI"
48+
[position]="[10, 10, 5]"
49+
[shadow.mapSize]="[64, 64]"
50+
[shadow.bias]="-0.001"
51+
/>
52+
53+
<ngts-adaptive-dpr [pixelated]="pixelated()" />
54+
<ngts-adaptive-events />
55+
<ngts-orbit-controls [options]="{ regress: true }" />
56+
`,
57+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
58+
changeDetection: ChangeDetectionStrategy.OnPush,
59+
imports: [Archer, NgtsAdaptiveDpr, NgtsAdaptiveEvents, NgtsOrbitControls],
60+
})
61+
export class SceneGraph {
62+
pixelated = input(true);
63+
64+
protected readonly Math = Math;
65+
}

0 commit comments

Comments
 (0)