|
| 1 | +import { afterNextRender, computed, Directive, ElementRef, model } from '@angular/core'; |
| 2 | +import { injectStore, resolveRef } from 'angular-three'; |
| 3 | +import { Camera, CubeCamera, Object3D, WebGLCubeRenderTarget } from 'three'; |
| 4 | + |
| 5 | +@Directive({ selector: 'ngts-preload', standalone: true }) |
| 6 | +export class NgtsPreload { |
| 7 | + all = model<boolean>(); |
| 8 | + scene = model<Object3D | ElementRef<Object3D>>(); |
| 9 | + camera = model<Camera | ElementRef<Camera>>(); |
| 10 | + |
| 11 | + private store = injectStore(); |
| 12 | + private gl = this.store.select('gl'); |
| 13 | + private defaultScene = this.store.select('scene'); |
| 14 | + private defaultCamera = this.store.select('camera'); |
| 15 | + |
| 16 | + private trueScene = computed(() => { |
| 17 | + const scene = this.scene(); |
| 18 | + if (scene) return resolveRef(scene); |
| 19 | + return this.defaultScene(); |
| 20 | + }); |
| 21 | + private trueCamera = computed(() => { |
| 22 | + const camera = this.camera(); |
| 23 | + if (camera) return resolveRef(camera); |
| 24 | + return this.defaultCamera(); |
| 25 | + }); |
| 26 | + |
| 27 | + constructor() { |
| 28 | + afterNextRender(() => { |
| 29 | + const invisible: Object3D[] = []; |
| 30 | + |
| 31 | + const [all, scene, camera, gl] = [this.all(), this.trueScene(), this.trueCamera(), this.gl()]; |
| 32 | + |
| 33 | + if (!scene || !camera) return; |
| 34 | + |
| 35 | + if (all) { |
| 36 | + // Find all invisible objects, store and then flip them |
| 37 | + scene.traverse((object) => { |
| 38 | + if (!object.visible) { |
| 39 | + invisible.push(object); |
| 40 | + object.visible = true; |
| 41 | + } |
| 42 | + }); |
| 43 | + } |
| 44 | + |
| 45 | + // Now compile the scene |
| 46 | + gl.compile(scene, camera); |
| 47 | + |
| 48 | + // And for good measure, hit it with a cube camera |
| 49 | + const cubeRenderTarget = new WebGLCubeRenderTarget(128); |
| 50 | + const cubeCamera = new CubeCamera(0.01, 100000, cubeRenderTarget); |
| 51 | + cubeCamera.update(gl, scene); |
| 52 | + cubeRenderTarget.dispose(); |
| 53 | + |
| 54 | + // Flips these objects back |
| 55 | + invisible.forEach((object) => (object.visible = false)); |
| 56 | + }); |
| 57 | + } |
| 58 | +} |
0 commit comments