Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eadbf53

Browse files
committed
refactor(soba/staging): use environmentResource in injectEnvironment
1 parent 9ee7ed4 commit eadbf53

File tree

3 files changed

+16
-234
lines changed

3 files changed

+16
-234
lines changed

libs/soba/staging/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export * from './lib/caustics';
77
export * from './lib/center';
88
export * from './lib/contact-shadows';
99
export * from './lib/environment/environment';
10+
export * from './lib/environment/environment-resource';
1011
export * from './lib/environment/inject-environment';
1112
export * from './lib/float';
1213
export * from './lib/lightformer';

libs/soba/staging/src/lib/environment/environment-resource.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,9 @@ export function environmentResource(
141141
});
142142
}
143143

144-
environmentResource.preload = (options: () => Partial<NgtsEnvironmentResourceOptions> = () => ({})) => {
145-
const _options = options();
146-
let { files, path } = _options;
147-
const { preset, extensions } = _options;
144+
environmentResource.preload = (options: Partial<NgtsEnvironmentResourceOptions> = {}) => {
145+
let { files, path } = options;
146+
const { preset, extensions } = options;
148147

149148
if (files == null) {
150149
files = defaultFiles;
Lines changed: 12 additions & 230 deletions
Original file line numberDiff line numberDiff line change
@@ -1,247 +1,29 @@
1-
import { computed, effect, Injector, signal, untracked } from '@angular/core';
2-
import { GainMapLoader, HDRJPGLoader } from '@monogrid/gainmap-js';
3-
import { injectLoader, injectStore, is, pick } from 'angular-three';
1+
import { Injector } from '@angular/core';
42
import { assertInjector } from 'ngxtension/assert-injector';
5-
import * as THREE from 'three';
6-
import { EXRLoader, RGBELoader } from 'three-stdlib';
7-
8-
export const ENVIRONMENT_PRESETS = {
9-
apartment: 'lebombo_1k.hdr',
10-
city: 'potsdamer_platz_1k.hdr',
11-
dawn: 'kiara_1_dawn_1k.hdr',
12-
forest: 'forest_slope_1k.hdr',
13-
lobby: 'st_fagans_interior_1k.hdr',
14-
night: 'dikhololo_night_1k.hdr',
15-
park: 'rooitou_park_1k.hdr',
16-
studio: 'studio_small_03_1k.hdr',
17-
sunset: 'venice_sunset_1k.hdr',
18-
warehouse: 'empty_warehouse_01_1k.hdr',
19-
};
20-
21-
export type NgtsEnvironmentPresets = keyof typeof ENVIRONMENT_PRESETS;
22-
23-
const CUBEMAP_ROOT = 'https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/';
24-
25-
export interface NgtsInjectEnvironmentOptions {
26-
files: string | string[];
27-
path: string;
28-
preset?: NgtsEnvironmentPresets;
29-
extensions?: (loader: THREE.Loader) => void;
30-
colorSpace?: THREE.ColorSpace;
31-
}
32-
33-
const defaultFiles = ['/px.png', '/nx.png', '/py.png', '/ny.png', '/pz.png', '/nz.png'];
3+
import {
4+
environmentResource,
5+
type NgtsEnvironmentPresets,
6+
type NgtsEnvironmentResourceOptions,
7+
} from './environment-resource';
348

359
/**
3610
* @deprecated use environmentResource instead. Will be removed in v5.0.0
3711
* @since v4.0.0
3812
*/
3913
export function injectEnvironment(
40-
options: () => Partial<NgtsInjectEnvironmentOptions> = () => ({}),
14+
options: () => Partial<NgtsEnvironmentResourceOptions> = () => ({}),
4115
{ injector }: { injector?: Injector } = {},
4216
) {
4317
return assertInjector(injectEnvironment, injector, () => {
44-
const adjustedOptions = computed(() => {
45-
const { preset, extensions, colorSpace, ...rest } = options();
46-
let { files, path } = rest;
47-
48-
if (files == null) {
49-
files = defaultFiles;
50-
}
51-
52-
if (path == null) {
53-
path = '';
54-
}
55-
56-
if (preset) {
57-
validatePreset(preset);
58-
files = ENVIRONMENT_PRESETS[preset];
59-
path = CUBEMAP_ROOT;
60-
}
61-
62-
return { files, preset, colorSpace, path, extensions };
63-
});
64-
65-
const files = pick(adjustedOptions, 'files');
66-
const multiFile = computed(() => Array.isArray(files()));
67-
const resultOptions = computed(() => getExtension(files()));
68-
const extension = pick(resultOptions, 'extension');
69-
const loader = computed(() => getLoader(extension()));
70-
71-
const store = injectStore();
72-
73-
const texture = signal<THREE.Texture | THREE.CubeTexture | null>(null);
74-
75-
effect(() => {
76-
const [_extension, _multiFile, _files] = [untracked(extension), untracked(multiFile), files()];
77-
78-
if (_extension !== 'webp' && _extension !== 'jpg' && _extension !== 'jpeg') return;
79-
80-
store.gl().domElement.addEventListener(
81-
'webglcontextlost',
82-
() => {
83-
// @ts-expect-error - files is correctly passed
84-
injectLoader.clear(multiFile ? [_files] : _files);
85-
},
86-
{ once: true },
87-
);
88-
});
89-
90-
const result = injectLoader(
91-
loader,
92-
// @ts-expect-error - ensure the files is an array
93-
() => {
94-
const { files } = adjustedOptions();
95-
return Array.isArray(files) ? [files] : files;
96-
},
97-
{
98-
extensions: (loader) => {
99-
const { extensions, path } = adjustedOptions();
100-
const { extension } = resultOptions();
101-
if (extension === 'webp' || extension === 'jpg' || extension === 'jpeg') {
102-
// @ts-expect-error - Gainmap requires a renderer
103-
loader.setRenderer(store.gl());
104-
}
105-
106-
loader.setPath?.(path);
107-
if (extensions) extensions(loader);
108-
},
109-
},
110-
);
111-
112-
effect(() => {
113-
const loaderResult = result();
114-
if (!loaderResult) return;
115-
116-
const { extension, isCubeMap } = untracked(resultOptions);
117-
const _multiFile = untracked(multiFile);
118-
const { colorSpace } = untracked(adjustedOptions);
119-
120-
// @ts-expect-error - ensure textureResult is a Texture or CubeTexture
121-
let textureResult = (_multiFile ? loaderResult[0] : loaderResult) as Texture | CubeTexture;
122-
123-
// NOTE: racing condition, we can skip this
124-
// we just said above that if multiFile is false, it is a single Texture
125-
if (
126-
!_multiFile &&
127-
Array.isArray(textureResult) &&
128-
is.three<THREE.CubeTexture>(textureResult[0], 'isCubeTexture')
129-
) {
130-
return;
131-
}
132-
133-
if (
134-
!is.three<THREE.CubeTexture>(textureResult, 'isCubeTexture') &&
135-
(extension === 'jpg' || extension === 'jpeg' || extension === 'webp')
136-
) {
137-
textureResult = (textureResult as any).renderTarget?.texture;
138-
}
139-
140-
textureResult.mapping = isCubeMap ? THREE.CubeReflectionMapping : THREE.EquirectangularReflectionMapping;
141-
textureResult.colorSpace = colorSpace ?? (isCubeMap ? 'srgb' : 'srgb-linear');
142-
143-
texture.set(textureResult);
144-
});
145-
146-
return texture.asReadonly();
18+
const resource = environmentResource(options, { injector });
19+
return resource.texture;
14720
});
14821
}
14922

150-
injectEnvironment.preload = (options: () => Partial<NgtsInjectEnvironmentOptions> = () => ({})) => {
151-
const _options = options();
152-
let { files, path } = _options;
153-
const { preset, extensions } = _options;
154-
155-
if (files == null) {
156-
files = defaultFiles;
157-
}
158-
159-
if (path == null) {
160-
path = '';
161-
}
162-
163-
if (preset) {
164-
validatePreset(preset);
165-
files = ENVIRONMENT_PRESETS[preset];
166-
path = CUBEMAP_ROOT;
167-
}
168-
169-
const { extension } = getExtension(files);
170-
171-
if (extension === 'webp' || extension === 'jpg' || extension === 'jpeg') {
172-
throw new Error('injectEnvironment: Preloading gainmaps is not supported');
173-
}
174-
175-
const loader = getLoader(extension);
176-
if (!loader) throw new Error('injectEnvironment: Unrecognized file extension: ' + files);
177-
178-
injectLoader.preload(
179-
() => loader,
180-
// @ts-expect-error - files is correctly passed
181-
() => (Array.isArray(files) ? [files] : files),
182-
(loader) => {
183-
loader.setPath?.(path);
184-
if (extensions) extensions(loader);
185-
},
186-
);
23+
injectEnvironment.preload = (options: () => Partial<NgtsEnvironmentResourceOptions> = () => ({})) => {
24+
environmentResource.preload(options());
18725
};
18826

18927
injectEnvironment.clear = (clearOptions: { files?: string | string[]; preset?: NgtsEnvironmentPresets }) => {
190-
const options = { files: defaultFiles, ...clearOptions };
191-
let { files } = options;
192-
const preset = options.preset;
193-
194-
if (preset) {
195-
validatePreset(preset);
196-
files = ENVIRONMENT_PRESETS[preset];
197-
}
198-
199-
injectLoader.clear(files);
28+
environmentResource.clear(clearOptions);
20029
};
201-
202-
function validatePreset(preset: string) {
203-
if (!(preset in ENVIRONMENT_PRESETS))
204-
throw new Error('Preset must be one of: ' + Object.keys(ENVIRONMENT_PRESETS).join(', '));
205-
}
206-
207-
function getExtension(files: string | string[]) {
208-
const isCubeMap = Array.isArray(files) && files.length === 6;
209-
const isGainmap = Array.isArray(files) && files.length === 3 && files.some((file) => file.endsWith('json'));
210-
const firstEntry = Array.isArray(files) ? files[0] : files;
211-
212-
// Everything else
213-
const extension: string | false | undefined = isCubeMap
214-
? 'cube'
215-
: isGainmap
216-
? 'webp'
217-
: firstEntry.startsWith('data:application/exr')
218-
? 'exr'
219-
: firstEntry.startsWith('data:application/hdr')
220-
? 'hdr'
221-
: firstEntry.startsWith('data:image/jpeg')
222-
? 'jpg'
223-
: firstEntry.split('.').pop()?.split('?')?.shift()?.toLowerCase();
224-
225-
return { extension, isCubeMap, isGainmap };
226-
}
227-
228-
function getLoader(extension: string | undefined) {
229-
const loader =
230-
extension === 'cube'
231-
? THREE.CubeTextureLoader
232-
: extension === 'hdr'
233-
? RGBELoader
234-
: extension === 'exr'
235-
? EXRLoader
236-
: extension === 'jpg' || extension === 'jpeg'
237-
? (HDRJPGLoader as unknown as typeof THREE.Loader)
238-
: extension === 'webp'
239-
? (GainMapLoader as unknown as typeof THREE.Loader)
240-
: null;
241-
242-
if (!loader) {
243-
throw new Error('injectEnvironment: Unrecognized file extension: ' + extension);
244-
}
245-
246-
return loader as typeof THREE.Loader;
247-
}

0 commit comments

Comments
 (0)