1+ import { NgTemplateOutlet } from '@angular/common' ;
12import {
23 ChangeDetectionStrategy ,
34 Component ,
@@ -8,33 +9,29 @@ import {
89 signal ,
910 viewChild ,
1011} from '@angular/core' ;
11- import { extend , injectBeforeRender , injectStore } from 'angular-three' ;
12+ import { extend , injectBeforeRender , injectLoader , injectStore } from 'angular-three' ;
1213import { NgtsPerspectiveCamera } from 'angular-three-soba/cameras' ;
1314import { NgtsOrbitControls } from 'angular-three-soba/controls' ;
1415import { injectGLTF } from 'angular-three-soba/loaders' ;
16+ import { NgtTweakCheckbox , NgtTweakColor , NgtTweakNumber , NgtTweakPane } from 'angular-three-tweakpane' ;
17+ import { GLTF , RGBELoader } from 'three-stdlib' ;
1518import * as THREE from 'three/webgpu' ;
19+ import { DirectionalLight , MeshPhysicalNodeMaterial } from 'three/webgpu' ;
20+ import { SliceMaterial } from './slice-material' ;
1621
17- import { NgTemplateOutlet } from '@angular/common' ;
18- import { NgtsEnvironment } from 'angular-three-soba/staging' ;
19- import { NgtTweakCheckbox , NgtTweakColor , NgtTweakNumber , NgtTweakPane } from 'angular-three-tweakpane' ;
20- import { GLTF } from 'three-stdlib' ;
2122import gearsGLB from './gears.glb' with { loader : 'file' } ;
22- import { SliceMaterial } from './slice-material' ;
23+ import royalHDR from './royal_esplanade_1k.hdr' with { loader : 'file' } ;
2324
2425injectGLTF . preload ( ( ) => gearsGLB ) ;
2526
2627interface GearsGLB extends GLTF {
27- nodes : {
28- axle : THREE . Mesh ;
29- gears : THREE . Mesh ;
30- outerHull : THREE . Mesh ;
31- } ;
28+ nodes : { axle : THREE . Mesh ; gears : THREE . Mesh ; outerHull : THREE . Mesh } ;
3229}
3330
3431@Component ( {
3532 selector : 'app-scene-graph' ,
3633 template : `
37- <ngts-perspective-camera [options]="{ makeDefault: true, position: [-5, 5, 12 ] }" />
34+ <ngts-perspective-camera [options]="{ makeDefault: true, position: [-5, 5, 5 ] }" />
3835
3936 <ngt-directional-light
4037 castShadow
@@ -64,7 +61,7 @@ interface GearsGLB extends GLTF {
6461 </ngt-mesh>
6562 </ng-template>
6663
67- <ngt-group #gears [position]="gearsPosition" >
64+ <ngt-group #gears>
6865 @if (gltf(); as gltf) {
6966 @let gears = gltf.nodes.gears;
7067 @let axle = gltf.nodes.axle;
@@ -86,19 +83,18 @@ interface GearsGLB extends GLTF {
8683 [arcAngle]="arcAngle()"
8784 [startAngle]="startAngle()"
8885 [sliceColor]="sliceColor()"
89- [parameters]="{ metalness, roughness, envMapIntensity, color, side: DoubleSide }"
86+ [parameters]="{ metalness, roughness, envMapIntensity, color }"
9087 />
9188 </ngt-mesh>
9289 }
9390 </ngt-group>
9491
95- <ngt-mesh #plane [position]="[-4, -3, -4]" [scale]="10" receiveShadow>
92+ <ngt-mesh [position]="[-4, -3, -4]" [scale]="10" receiveShadow (updated)="$event.lookAt(0, 0, 0)" >
9693 <ngt-plane-geometry />
9794 <ngt-mesh-standard-material color="#aaaaaa" />
9895 </ngt-mesh>
9996
100- <ngts-environment [options]="{ preset: 'warehouse', background: true, blur: 0.5 }" />
101- <ngts-orbit-controls />
97+ <ngts-orbit-controls [options]="{ zoomSpeed: 0.2 }" />
10298
10399 <ngt-tweak-pane title="Slice Material" left="8px">
104100 <ngt-tweak-checkbox [(value)]="rotate" label="rotate" />
@@ -120,7 +116,6 @@ interface GearsGLB extends GLTF {
120116 imports : [
121117 NgtsPerspectiveCamera ,
122118 NgtsOrbitControls ,
123- NgtsEnvironment ,
124119 NgTemplateOutlet ,
125120 SliceMaterial ,
126121 NgtTweakPane ,
@@ -132,21 +127,21 @@ interface GearsGLB extends GLTF {
132127 schemas : [ CUSTOM_ELEMENTS_SCHEMA ] ,
133128} )
134129export class SceneGraph {
135- protected readonly DoubleSide = THREE . DoubleSide ;
136-
137130 private gearsRef = viewChild . required < ElementRef < THREE . Group > > ( 'gears' ) ;
138- private planeRef = viewChild . required < ElementRef < THREE . Mesh > > ( 'plane' ) ;
139131
132+ protected environmentMap = injectLoader (
133+ ( ) => RGBELoader ,
134+ ( ) => royalHDR ,
135+ ) ;
140136 protected gltf = injectGLTF < GearsGLB > ( ( ) => gearsGLB ) ;
137+
141138 private store = injectStore ( ) ;
142139
143140 protected metalness = 0.5 ;
144141 protected roughness = 0.25 ;
145142 protected envMapIntensity = 0.5 ;
146143 protected color = '#858080' ;
147144
148- protected gearsPosition = new THREE . Vector3 ( ) ;
149-
150145 protected rotate = signal ( true ) ;
151146 protected sliceColor = signal ( '#9370DB' ) ;
152147 protected startAngleDegrees = signal ( 60 ) ;
@@ -156,29 +151,33 @@ export class SceneGraph {
156151 protected startAngle = computed ( ( ) => THREE . MathUtils . DEG2RAD * this . startAngleDegrees ( ) ) ;
157152
158153 constructor ( ) {
159- extend ( THREE ) ;
154+ extend ( { MeshPhysicalNodeMaterial , DirectionalLight } ) ;
160155
161156 injectBeforeRender ( ( { delta } ) => {
162- const [ gears , plane ] = [ this . gearsRef ( ) . nativeElement , this . planeRef ( ) . nativeElement ] ;
163- plane . lookAt ( gears . position ) ;
164-
165157 if ( ! this . rotate ( ) ) return ;
166-
167- gears . rotation . y += 0.1 * delta ;
158+ this . gearsRef ( ) . nativeElement . rotation . y += 0.1 * delta ;
168159 } ) ;
169160
170161 effect ( ( onCleanup ) => {
171- const [ scene , gl ] = [ this . store . scene ( ) , this . store . gl ( ) ] ;
162+ const environmentMap = this . environmentMap ( ) ;
163+ if ( ! environmentMap ) return ;
164+
165+ const scene = this . store . scene ( ) ;
172166
167+ const oldBackground = scene . background ;
168+ const oldEnvironment = scene . environment ;
173169 const blurriness = scene . backgroundBlurriness ;
174- const lastToneMapping = gl . toneMapping ;
175170
171+ environmentMap . mapping = THREE . EquirectangularReflectionMapping ;
172+
173+ scene . background = environmentMap ;
176174 scene . backgroundBlurriness = 0.5 ;
177- gl . toneMapping = THREE . ACESFilmicToneMapping ;
175+ scene . environment = environmentMap ;
178176
179177 onCleanup ( ( ) => {
178+ scene . background = oldBackground ;
179+ scene . environment = oldEnvironment ;
180180 scene . backgroundBlurriness = blurriness ;
181- gl . toneMapping = lastToneMapping ;
182181 } ) ;
183182 } ) ;
184183 }
0 commit comments