Skip to content

Commit 37c8784

Browse files
committed
docs(examples): update aquarium and backdrop routes
1 parent 558f4fd commit 37c8784

File tree

16 files changed

+899
-7
lines changed

16 files changed

+899
-7
lines changed

apps/kitchen-sink-new/src/app/app.routes.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ export const appRoutes: Route[] = [
1313
loadChildren: () => import('./postprocessing/postprocessing.routes'),
1414
title: 'Postprocessing - Angular Three Demo',
1515
},
16-
// {
17-
// path: 'soba',
18-
// loadComponent: () => import('./soba/soba'),
19-
// loadChildren: () => import('./soba/soba.routes'),
20-
// title: 'Soba - Angular Three Demo',
21-
// },
16+
{
17+
path: 'soba',
18+
loadComponent: () => import('./soba/soba'),
19+
loadChildren: () => import('./soba/soba.routes'),
20+
title: 'Soba - Angular Three Demo',
21+
},
2222
{
2323
path: 'rapier',
2424
loadComponent: () => import('./rapier/rapier'),
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { ChangeDetectionStrategy, Component } from '@angular/core';
2+
import { NgtCanvas, NgtCanvasContent } from 'angular-three/dom';
3+
import { SceneGraph } from './scene';
4+
5+
@Component({
6+
template: `
7+
<ngt-canvas shadows [camera]="{ position: [30, 0, -3], fov: 35, near: 1, far: 50 }" [gl]="{ stencil: true }">
8+
<app-scene-graph *canvasContent />
9+
</ngt-canvas>
10+
`,
11+
changeDetection: ChangeDetectionStrategy.OnPush,
12+
host: { class: 'aquarium' },
13+
imports: [NgtCanvas, NgtCanvasContent, SceneGraph],
14+
})
15+
export default class Aquarium {}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
2+
import { NgtArgs } from 'angular-three';
3+
import { NgtsCameraControls } from 'angular-three-soba/controls';
4+
import {
5+
NgtsAccumulativeShadows,
6+
NgtsEnvironment,
7+
NgtsFloat,
8+
NgtsLightformer,
9+
NgtsRandomizedLights,
10+
} from 'angular-three-soba/staging';
11+
import { Spheres } from './spheres';
12+
import { Tank } from './tank';
13+
import { Turtle } from './turtle';
14+
15+
@Component({
16+
selector: 'app-scene-graph',
17+
template: `
18+
<ngt-color *args="['#c6e5db']" attach="background" />
19+
20+
<!-- fish tank -->
21+
<app-tank [position]="[0, 0.25, 0]">
22+
<ngts-float [options]="{ rotationIntensity: 2, floatIntensity: 10, speed: 2 }">
23+
<app-turtle [position]="[0, -0.5, -1]" [rotation]="[0, Math.PI, 0]" [scale]="23" />
24+
</ngts-float>
25+
26+
<app-spheres />
27+
</app-tank>
28+
29+
<!-- soft shadows -->
30+
<ngts-accumulative-shadows
31+
[options]="{
32+
temporal: true,
33+
frames: 100,
34+
color: 'lightblue',
35+
colorBlend: 2,
36+
opacity: 0.7,
37+
alphaTest: 0.65,
38+
scale: 60,
39+
position: [0, -5, 0],
40+
}"
41+
>
42+
<ngts-randomized-lights
43+
[options]="{ amount: 8, radius: 15, ambient: 0.5, intensity: Math.PI, position: [-5, 10, -5], size: 20 }"
44+
/>
45+
</ngts-accumulative-shadows>
46+
47+
<!-- custom env map -->
48+
<ngts-environment [options]="{ resolution: 1024 }">
49+
<ngt-group * [rotation]="[-Math.PI / 3, 0, 0]">
50+
<ngts-lightformer
51+
[options]="{ intensity: 4, rotation: [Math.PI / 2, 0, 0], position: [0, 5, -9], scale: [10, 10, 1] }"
52+
/>
53+
54+
@for (x of lightPositions; track $index) {
55+
<ngts-lightformer
56+
[options]="{
57+
form: 'circle',
58+
intensity: 4,
59+
rotation: [Math.PI / 2, 0, 0],
60+
position: [x, 4, $index * 4],
61+
scale: [4, 1, 1],
62+
}"
63+
/>
64+
}
65+
66+
<ngts-lightformer
67+
[options]="{ intensity: 2, rotation: [Math.PI / 2, 0, 0], position: [-5, 1, -1], scale: [50, 2, 1] }"
68+
/>
69+
<ngts-lightformer
70+
[options]="{ intensity: 2, rotation: [-Math.PI / 2, 0, 0], position: [10, 1, 0], scale: [50, 2, 1] }"
71+
/>
72+
</ngt-group>
73+
</ngts-environment>
74+
75+
<ngts-camera-controls [options]="{ minPolarAngle: 0, maxPolarAngle: Math.PI / 2, truckSpeed: 0, dollySpeed: 0 }" />
76+
`,
77+
imports: [
78+
NgtArgs,
79+
Tank,
80+
NgtsFloat,
81+
Turtle,
82+
Spheres,
83+
NgtsAccumulativeShadows,
84+
NgtsRandomizedLights,
85+
NgtsEnvironment,
86+
NgtsLightformer,
87+
NgtsCameraControls,
88+
],
89+
changeDetection: ChangeDetectionStrategy.OnPush,
90+
host: { class: 'aquarium-soba-experience' },
91+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
92+
})
93+
export class SceneGraph {
94+
protected readonly Math = Math;
95+
protected lightPositions = [2, 0, 2, 0, 2, 0, 2, 0];
96+
}
Binary file not shown.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
2+
import { NgtArgs } from 'angular-three';
3+
import { NgtsInstance, NgtsInstances } from 'angular-three-soba/performances';
4+
import { NgtsFloat } from 'angular-three-soba/staging';
5+
6+
@Component({
7+
selector: 'app-spheres',
8+
template: `
9+
<ngts-instances [options]="{ renderOrder: -1000 }">
10+
<ngt-sphere-geometry *args="[1, 64, 64]" />
11+
<ngt-mesh-basic-material [depthTest]="false" />
12+
13+
@for (sphere of spheres; track $index) {
14+
@let scale = sphere[0];
15+
@let color = sphere[1];
16+
@let speed = sphere[2];
17+
@let position = sphere[3];
18+
19+
<ngts-float [options]="{ rotationIntensity: 40, floatIntensity: 20, speed: speed / 2 }">
20+
<ngts-instance [options]="{ position, color, scale }" />
21+
</ngts-float>
22+
}
23+
</ngts-instances>
24+
`,
25+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
26+
changeDetection: ChangeDetectionStrategy.OnPush,
27+
imports: [NgtsInstances, NgtArgs, NgtsFloat, NgtsInstance],
28+
})
29+
export class Spheres {
30+
protected spheres = [
31+
[1, 'orange', 0.05, [-4, -1, -1]],
32+
[0.75, 'hotpink', 0.1, [-4, 2, -2]],
33+
[1.25, 'aquamarine', 0.2, [4, -3, 2]],
34+
[1.5, 'lightblue', 0.3, [-4, -2, -3]],
35+
[2, 'pink', 0.3, [-4, 2, -4]],
36+
[2, 'skyblue', 0.3, [-4, 2, -4]],
37+
[1.5, 'orange', 0.05, [-4, -1, -1]],
38+
[2, 'hotpink', 0.1, [-4, 2, -2]],
39+
[1.5, 'aquamarine', 0.2, [4, -3, 2]],
40+
[1.25, 'lightblue', 0.3, [-4, -2, -3]],
41+
[1, 'pink', 0.3, [-4, 2, -4]],
42+
[1, 'skyblue', 0.3, [-4, 2, -4]],
43+
] as const;
44+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import {
2+
ChangeDetectionStrategy,
3+
Component,
4+
CUSTOM_ELEMENTS_SCHEMA,
5+
effect,
6+
ElementRef,
7+
input,
8+
viewChild,
9+
} from '@angular/core';
10+
import { getInstanceState, NgtVector3 } from 'angular-three';
11+
import { injectGLTF } from 'angular-three-soba/loaders';
12+
import { NgtsMeshTransmissionMaterial } from 'angular-three-soba/materials';
13+
import { mask } from 'angular-three-soba/staging';
14+
import { Group, Mesh } from 'three';
15+
import { GLTF } from 'three-stdlib';
16+
17+
import shapesGLB from './shapes-transformed.glb';
18+
19+
interface ShapesGLTF extends GLTF {
20+
nodes: { Cube: Mesh };
21+
}
22+
23+
@Component({
24+
selector: 'app-tank',
25+
template: `
26+
@if (gltf(); as gltf) {
27+
@let nodes = gltf.nodes;
28+
29+
<ngt-group [position]="position()" [dispose]="null">
30+
<ngt-mesh castShadow [scale]="[0.61 * 6, 0.8 * 6, 6]" [geometry]="nodes.Cube.geometry">
31+
<ngts-mesh-transmission-material
32+
[options]="{
33+
backside: true,
34+
samples: 4,
35+
thickness: 3,
36+
anisotropy: 0.1,
37+
iridescence: 1,
38+
iridescenceIOR: 1,
39+
iridescenceThicknessRange: [0, 1400],
40+
}"
41+
/>
42+
</ngt-mesh>
43+
<ngt-group #group>
44+
<ng-content />
45+
</ngt-group>
46+
</ngt-group>
47+
}
48+
`,
49+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
50+
changeDetection: ChangeDetectionStrategy.OnPush,
51+
imports: [NgtsMeshTransmissionMaterial],
52+
})
53+
export class Tank {
54+
position = input<NgtVector3>([0, 0, 0]);
55+
56+
private groupRef = viewChild<ElementRef<Group>>('group');
57+
58+
protected gltf = injectGLTF<ShapesGLTF>(() => shapesGLB);
59+
60+
private stencilParameters = mask(() => 1);
61+
62+
constructor() {
63+
effect(() => {
64+
const gltf = this.gltf();
65+
if (!gltf) return;
66+
67+
const group = this.groupRef()?.nativeElement;
68+
if (!group) return;
69+
70+
const instanceState = getInstanceState(group);
71+
if (!instanceState) return;
72+
73+
// track all children
74+
instanceState.objects();
75+
76+
// Apply stencil to all contents
77+
group.traverse((child) => {
78+
if (child instanceof Mesh) {
79+
Object.assign(child.material, { ...this.stencilParameters() });
80+
}
81+
});
82+
});
83+
}
84+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, effect, input } from '@angular/core';
2+
import { injectBeforeRender, NgtArgs, NgtEuler, NgtVector3 } from 'angular-three';
3+
import { injectGLTF } from 'angular-three-soba/loaders';
4+
import { injectAnimations, NgtsAnimationClips } from 'angular-three-soba/misc';
5+
import { GLTF } from 'three-stdlib';
6+
7+
import turtleGLB from './model_52a_-_kemps_ridley_sea_turtle_no_id-transformed.glb';
8+
9+
/*
10+
Author: DigitalLife3D (https://sketchfab.com/DigitalLife3D)
11+
License: CC-BY-NC-4.0 (http://creativecommons.org/licenses/by-nc/4.0/)
12+
Source: https://sketchfab.com/3d-models/model-52a-kemps-ridley-sea-turtle-no-id-7aba937dfbce480fb3aca47be3a9740b
13+
Title: Model 52A - Kemps Ridley Sea Turtle (no ID)
14+
*/
15+
@Component({
16+
selector: 'app-turtle',
17+
template: `
18+
@let parameters = { position: position(), rotation: rotation(), scale: scale() };
19+
<ngt-primitive *args="[gltf.scene()]" [parameters]="parameters" />
20+
`,
21+
imports: [NgtArgs],
22+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
23+
changeDetection: ChangeDetectionStrategy.OnPush,
24+
})
25+
export class Turtle {
26+
position = input<NgtVector3>([0, 0, 0]);
27+
rotation = input<NgtEuler>([0, 0, 0]);
28+
scale = input(1);
29+
30+
protected gltf = injectGLTF<GLTF & { animations: NgtsAnimationClips<'Swim Cycle'>[] }>(() => turtleGLB);
31+
32+
private animations = injectAnimations(this.gltf, this.gltf.scene);
33+
34+
constructor() {
35+
effect(() => {
36+
if (!this.animations.isReady) return;
37+
38+
this.animations.mixer.timeScale = 0.5;
39+
this.animations.actions['Swim Cycle'].play();
40+
});
41+
42+
injectBeforeRender(({ clock }) => {
43+
const scene = this.gltf.scene();
44+
if (!scene) return;
45+
46+
scene.rotation.z = Math.sin(clock.elapsedTime / 4) / 2;
47+
});
48+
}
49+
}

0 commit comments

Comments
 (0)