@luma.gl/engine 9.2.5 → 9.3.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation-loop/animation-loop.d.ts +3 -1
- package/dist/animation-loop/animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/animation-loop.js +10 -4
- package/dist/animation-loop/animation-loop.js.map +1 -1
- package/dist/compute/computation.d.ts.map +1 -1
- package/dist/compute/computation.js +3 -2
- package/dist/compute/computation.js.map +1 -1
- package/dist/compute/swap.d.ts +2 -0
- package/dist/compute/swap.d.ts.map +1 -1
- package/dist/compute/swap.js +10 -5
- package/dist/compute/swap.js.map +1 -1
- package/dist/dist.dev.js +554 -358
- package/dist/dist.min.js +59 -50
- package/dist/dynamic-texture/dynamic-texture.d.ts +95 -0
- package/dist/dynamic-texture/dynamic-texture.d.ts.map +1 -0
- package/dist/dynamic-texture/dynamic-texture.js +356 -0
- package/dist/dynamic-texture/dynamic-texture.js.map +1 -0
- package/dist/dynamic-texture/texture-data.d.ts +137 -0
- package/dist/dynamic-texture/texture-data.d.ts.map +1 -0
- package/dist/dynamic-texture/texture-data.js +183 -0
- package/dist/dynamic-texture/texture-data.js.map +1 -0
- package/dist/factories/pipeline-factory.d.ts.map +1 -1
- package/dist/factories/pipeline-factory.js +3 -3
- package/dist/factories/pipeline-factory.js.map +1 -1
- package/dist/factories/shader-factory.d.ts.map +1 -1
- package/dist/factories/shader-factory.js +3 -2
- package/dist/factories/shader-factory.js.map +1 -1
- package/dist/index.cjs +566 -370
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/model/model.d.ts +31 -10
- package/dist/model/model.d.ts.map +1 -1
- package/dist/model/model.js +34 -14
- package/dist/model/model.js.map +1 -1
- package/dist/models/billboard-texture-model.d.ts +8 -5
- package/dist/models/billboard-texture-model.d.ts.map +1 -1
- package/dist/models/billboard-texture-model.js +70 -18
- package/dist/models/billboard-texture-model.js.map +1 -1
- package/dist/passes/get-fragment-shader.js +15 -11
- package/dist/passes/get-fragment-shader.js.map +1 -1
- package/dist/passes/shader-pass-renderer.d.ts +5 -5
- package/dist/passes/shader-pass-renderer.d.ts.map +1 -1
- package/dist/passes/shader-pass-renderer.js +13 -12
- package/dist/passes/shader-pass-renderer.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +4 -4
- package/src/animation-loop/animation-loop.ts +11 -4
- package/src/compute/computation.ts +3 -2
- package/src/compute/swap.ts +13 -7
- package/src/dynamic-texture/dynamic-texture.ts +451 -0
- package/src/dynamic-texture/texture-data.ts +301 -0
- package/src/factories/pipeline-factory.ts +4 -3
- package/src/factories/shader-factory.ts +4 -2
- package/src/index.ts +9 -4
- package/src/model/model.ts +37 -18
- package/src/models/billboard-texture-model.ts +81 -22
- package/src/passes/get-fragment-shader.ts +15 -11
- package/src/passes/shader-pass-renderer.ts +22 -16
- package/src/types.ts +11 -0
- package/dist/async-texture/async-texture.d.ts +0 -166
- package/dist/async-texture/async-texture.d.ts.map +0 -1
- package/dist/async-texture/async-texture.js +0 -386
- package/dist/async-texture/async-texture.js.map +0 -1
- package/src/async-texture/async-texture.ts +0 -551
- /package/src/{async-texture/texture-setters.ts.disabled → dynamic-texture/texture-data.ts.disabled} +0 -0
|
@@ -1,551 +0,0 @@
|
|
|
1
|
-
// luma.gl, MIT license
|
|
2
|
-
// Copyright (c) vis.gl contributors
|
|
3
|
-
|
|
4
|
-
import type {
|
|
5
|
-
TextureProps,
|
|
6
|
-
SamplerProps,
|
|
7
|
-
TextureView,
|
|
8
|
-
Device,
|
|
9
|
-
TypedArray,
|
|
10
|
-
TextureFormat,
|
|
11
|
-
ExternalImage
|
|
12
|
-
} from '@luma.gl/core';
|
|
13
|
-
|
|
14
|
-
import {Texture, Sampler, log} from '@luma.gl/core';
|
|
15
|
-
|
|
16
|
-
import {loadImageBitmap} from '../application-utils/load-file';
|
|
17
|
-
import {uid} from '../utils/uid';
|
|
18
|
-
|
|
19
|
-
type AsyncTextureDataProps =
|
|
20
|
-
| AsyncTexture1DProps
|
|
21
|
-
| AsyncTexture2DProps
|
|
22
|
-
| AsyncTexture3DProps
|
|
23
|
-
| AsyncTextureArrayProps
|
|
24
|
-
| AsyncTextureCubeProps
|
|
25
|
-
| AsyncTextureCubeArrayProps;
|
|
26
|
-
|
|
27
|
-
type AsyncTexture1DProps = {dimension: '1d'; data: Promise<Texture1DData> | Texture1DData | null};
|
|
28
|
-
type AsyncTexture2DProps = {dimension?: '2d'; data: Promise<Texture2DData> | Texture2DData | null};
|
|
29
|
-
type AsyncTexture3DProps = {dimension: '3d'; data: Promise<Texture3DData> | Texture3DData | null};
|
|
30
|
-
type AsyncTextureArrayProps = {
|
|
31
|
-
dimension: '2d-array';
|
|
32
|
-
data: Promise<TextureArrayData> | TextureArrayData | null;
|
|
33
|
-
};
|
|
34
|
-
type AsyncTextureCubeProps = {
|
|
35
|
-
dimension: 'cube';
|
|
36
|
-
data: Promise<TextureCubeData> | TextureCubeData | null;
|
|
37
|
-
};
|
|
38
|
-
type AsyncTextureCubeArrayProps = {
|
|
39
|
-
dimension: 'cube-array';
|
|
40
|
-
data: Promise<TextureCubeArrayData> | TextureCubeArrayData | null;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
type AsyncTextureData = AsyncTextureProps['data'];
|
|
44
|
-
|
|
45
|
-
/** Names of cube texture faces */
|
|
46
|
-
export type TextureCubeFace = '+X' | '-X' | '+Y' | '-Y' | '+Z' | '-Z';
|
|
47
|
-
export const TextureCubeFaces: TextureCubeFace[] = ['+X', '-X', '+Y', '-Y', '+Z', '-Z'];
|
|
48
|
-
// prettier-ignore
|
|
49
|
-
export const TextureCubeFaceMap = {'+X': 0, '-X': 1, '+Y': 2, '-Y': 3, '+Z': 4, '-Z': 5};
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* One mip level
|
|
53
|
-
* Basic data structure is similar to `ImageData`
|
|
54
|
-
* additional optional fields can describe compressed texture data.
|
|
55
|
-
*/
|
|
56
|
-
export type TextureImageData = {
|
|
57
|
-
/** WebGPU style format string. Defaults to 'rgba8unorm' */
|
|
58
|
-
format?: TextureFormat;
|
|
59
|
-
data: TypedArray;
|
|
60
|
-
width: number;
|
|
61
|
-
height: number;
|
|
62
|
-
|
|
63
|
-
compressed?: boolean;
|
|
64
|
-
byteLength?: number;
|
|
65
|
-
hasAlpha?: boolean;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export type TextureLevelSource = TextureImageData | ExternalImage;
|
|
69
|
-
|
|
70
|
-
/** Texture data can be one or more mip levels */
|
|
71
|
-
export type TextureData = TextureImageData | ExternalImage | (TextureImageData | ExternalImage)[];
|
|
72
|
-
|
|
73
|
-
/** @todo - define what data type is supported for 1D textures */
|
|
74
|
-
export type Texture1DData = TypedArray | TextureImageData;
|
|
75
|
-
|
|
76
|
-
/** Texture data can be one or more mip levels */
|
|
77
|
-
export type Texture2DData =
|
|
78
|
-
| TypedArray
|
|
79
|
-
| TextureImageData
|
|
80
|
-
| ExternalImage
|
|
81
|
-
| (TextureImageData | ExternalImage)[];
|
|
82
|
-
|
|
83
|
-
/** 6 face textures */
|
|
84
|
-
export type TextureCubeData = Record<TextureCubeFace, TextureData>;
|
|
85
|
-
|
|
86
|
-
/** Array of textures */
|
|
87
|
-
export type Texture3DData = TextureData[];
|
|
88
|
-
|
|
89
|
-
/** Array of textures */
|
|
90
|
-
export type TextureArrayData = TextureData[];
|
|
91
|
-
|
|
92
|
-
/** Array of 6 face textures */
|
|
93
|
-
export type TextureCubeArrayData = Record<TextureCubeFace, TextureData>[];
|
|
94
|
-
|
|
95
|
-
export const CubeFaces: TextureCubeFace[] = ['+X', '-X', '+Y', '-Y', '+Z', '-Z'];
|
|
96
|
-
|
|
97
|
-
/** Properties for an async texture */
|
|
98
|
-
export type AsyncTextureProps = Omit<TextureProps, 'data' | 'mipLevels' | 'width' | 'height'> &
|
|
99
|
-
AsyncTextureDataProps & {
|
|
100
|
-
/** Generate mipmaps after creating textures and setting data */
|
|
101
|
-
mipmaps?: boolean;
|
|
102
|
-
/** nipLevels can be set to 'auto' to generate max number of mipLevels */
|
|
103
|
-
mipLevels?: number | 'auto';
|
|
104
|
-
/** Width - can be auto-calculated when initializing from ExternalImage */
|
|
105
|
-
width?: number;
|
|
106
|
-
/** Height - can be auto-calculated when initializing from ExternalImage */
|
|
107
|
-
height?: number;
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* It is very convenient to be able to initialize textures with promises
|
|
112
|
-
* This can add considerable complexity to the Texture class, and doesn't
|
|
113
|
-
* fit with the immutable nature of WebGPU resources.
|
|
114
|
-
* Instead, luma.gl offers async textures as a separate class.
|
|
115
|
-
*/
|
|
116
|
-
export class AsyncTexture {
|
|
117
|
-
readonly device: Device;
|
|
118
|
-
readonly id: string;
|
|
119
|
-
props: Required<Omit<AsyncTextureProps, 'data'>>;
|
|
120
|
-
|
|
121
|
-
// TODO - should we type these as possibly `null`? It will make usage harder?
|
|
122
|
-
// @ts-expect-error
|
|
123
|
-
texture: Texture;
|
|
124
|
-
// @ts-expect-error
|
|
125
|
-
sampler: Sampler;
|
|
126
|
-
// @ts-expect-error
|
|
127
|
-
view: TextureView;
|
|
128
|
-
|
|
129
|
-
readonly ready: Promise<void>;
|
|
130
|
-
isReady: boolean = false;
|
|
131
|
-
destroyed: boolean = false;
|
|
132
|
-
|
|
133
|
-
protected resolveReady: () => void = () => {};
|
|
134
|
-
protected rejectReady: (error: Error) => void = () => {};
|
|
135
|
-
|
|
136
|
-
get [Symbol.toStringTag]() {
|
|
137
|
-
return 'AsyncTexture';
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
toString(): string {
|
|
141
|
-
return `AsyncTexture:"${this.id}"(${this.isReady ? 'ready' : 'loading'})`;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
constructor(device: Device, props: AsyncTextureProps) {
|
|
145
|
-
this.device = device;
|
|
146
|
-
|
|
147
|
-
// TODO - if we support URL strings as data...
|
|
148
|
-
const id = uid('async-texture'); // typeof props?.data === 'string' ? props.data.slice(-20) : uid('async-texture');
|
|
149
|
-
this.props = {...AsyncTexture.defaultProps, id, ...props};
|
|
150
|
-
this.id = this.props.id;
|
|
151
|
-
|
|
152
|
-
props = {...props};
|
|
153
|
-
// Signature: new AsyncTexture(device, {data: url})
|
|
154
|
-
if (typeof props?.data === 'string' && props.dimension === '2d') {
|
|
155
|
-
props.data = loadImageBitmap(props.data);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// If mipmaps are requested, we need to allocate space for them
|
|
159
|
-
if (props.mipmaps) {
|
|
160
|
-
props.mipLevels = 'auto';
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
this.ready = new Promise<void>((resolve, reject) => {
|
|
164
|
-
this.resolveReady = () => {
|
|
165
|
-
this.isReady = true;
|
|
166
|
-
resolve();
|
|
167
|
-
};
|
|
168
|
-
this.rejectReady = reject;
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
this.initAsync(props);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
async initAsync(props: AsyncTextureProps): Promise<void> {
|
|
175
|
-
const asyncData: AsyncTextureData = props.data;
|
|
176
|
-
// @ts-expect-error not clear how to convince TS that null will be returned
|
|
177
|
-
const data: TextureData | null = await awaitAllPromises(asyncData).then(
|
|
178
|
-
undefined,
|
|
179
|
-
this.rejectReady
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
// Check that we haven't been destroyed while waiting for texture data to load
|
|
183
|
-
if (this.destroyed) {
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Now we can actually create the texture
|
|
188
|
-
|
|
189
|
-
// Auto-deduce width and height if not supplied
|
|
190
|
-
const size =
|
|
191
|
-
this.props.width && this.props.height
|
|
192
|
-
? {width: this.props.width, height: this.props.height}
|
|
193
|
-
: this.getTextureDataSize(data);
|
|
194
|
-
if (!size) {
|
|
195
|
-
throw new Error('Texture size could not be determined');
|
|
196
|
-
}
|
|
197
|
-
const syncProps: TextureProps = {...size, ...props, data: undefined, mipLevels: 1};
|
|
198
|
-
|
|
199
|
-
// Auto-calculate the number of mip levels as a convenience
|
|
200
|
-
// TODO - Should we clamp to 1-getMipLevelCount?
|
|
201
|
-
const maxMips = this.device.getMipLevelCount(syncProps.width, syncProps.height);
|
|
202
|
-
syncProps.mipLevels =
|
|
203
|
-
this.props.mipLevels === 'auto' ? maxMips : Math.min(maxMips, this.props.mipLevels);
|
|
204
|
-
|
|
205
|
-
this.texture = this.device.createTexture(syncProps);
|
|
206
|
-
this.sampler = this.texture.sampler;
|
|
207
|
-
this.view = this.texture.view;
|
|
208
|
-
|
|
209
|
-
if (props.data) {
|
|
210
|
-
switch (this.props.dimension) {
|
|
211
|
-
case '1d':
|
|
212
|
-
this._setTexture1DData(this.texture, data as Texture1DData);
|
|
213
|
-
break;
|
|
214
|
-
case '2d':
|
|
215
|
-
this._setTexture2DData(data as Texture2DData);
|
|
216
|
-
break;
|
|
217
|
-
case '3d':
|
|
218
|
-
this._setTexture3DData(this.texture, data as Texture3DData);
|
|
219
|
-
break;
|
|
220
|
-
case '2d-array':
|
|
221
|
-
this._setTextureArrayData(this.texture, data as TextureArrayData);
|
|
222
|
-
break;
|
|
223
|
-
case 'cube':
|
|
224
|
-
this._setTextureCubeData(this.texture, data as unknown as TextureCubeData);
|
|
225
|
-
break;
|
|
226
|
-
case 'cube-array':
|
|
227
|
-
this._setTextureCubeArrayData(this.texture, data as unknown as TextureCubeArrayData);
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Do we need to generate mipmaps?
|
|
233
|
-
if (this.props.mipmaps) {
|
|
234
|
-
this.generateMipmaps();
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
log.info(1, `${this} loaded`);
|
|
238
|
-
this.resolveReady();
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
destroy(): void {
|
|
242
|
-
if (this.texture) {
|
|
243
|
-
this.texture.destroy();
|
|
244
|
-
// @ts-expect-error
|
|
245
|
-
this.texture = null;
|
|
246
|
-
}
|
|
247
|
-
this.destroyed = true;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
generateMipmaps(): void {
|
|
251
|
-
// if (this.device.type === 'webgl') {
|
|
252
|
-
this.texture.generateMipmapsWebGL();
|
|
253
|
-
// }
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/** Set sampler or create and set new Sampler from SamplerProps */
|
|
257
|
-
setSampler(sampler: Sampler | SamplerProps = {}): void {
|
|
258
|
-
this.texture.setSampler(
|
|
259
|
-
sampler instanceof Sampler ? sampler : this.device.createSampler(sampler)
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Textures are immutable and cannot be resized after creation,
|
|
265
|
-
* but we can create a similar texture with the same parameters but a new size.
|
|
266
|
-
* @note Does not copy contents of the texture
|
|
267
|
-
* @note Mipmaps may need to be regenerated after resizing / setting new data
|
|
268
|
-
* @todo Abort pending promise and create a texture with the new size?
|
|
269
|
-
*/
|
|
270
|
-
resize(size: {width: number; height: number}): boolean {
|
|
271
|
-
if (!this.isReady) {
|
|
272
|
-
throw new Error('Cannot resize texture before it is ready');
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (size.width === this.texture.width && size.height === this.texture.height) {
|
|
276
|
-
return false;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (this.texture) {
|
|
280
|
-
const texture = this.texture;
|
|
281
|
-
this.texture = texture.clone(size);
|
|
282
|
-
texture.destroy();
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
return true;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/** Check if texture data is a typed array */
|
|
289
|
-
isTextureLevelData(data: TextureData): data is TextureImageData {
|
|
290
|
-
const typedArray = (data as TextureImageData)?.data;
|
|
291
|
-
return ArrayBuffer.isView(typedArray);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/** Get the size of the texture described by the provided TextureData */
|
|
295
|
-
getTextureDataSize(
|
|
296
|
-
data:
|
|
297
|
-
| TextureData
|
|
298
|
-
| TextureCubeData
|
|
299
|
-
| TextureArrayData
|
|
300
|
-
| TextureCubeArrayData
|
|
301
|
-
| TypedArray
|
|
302
|
-
| null
|
|
303
|
-
): {width: number; height: number} | null {
|
|
304
|
-
if (!data) {
|
|
305
|
-
return null;
|
|
306
|
-
}
|
|
307
|
-
if (ArrayBuffer.isView(data)) {
|
|
308
|
-
return null;
|
|
309
|
-
}
|
|
310
|
-
// Recurse into arrays (array of miplevels)
|
|
311
|
-
if (Array.isArray(data)) {
|
|
312
|
-
return this.getTextureDataSize(data[0]);
|
|
313
|
-
}
|
|
314
|
-
if (this.device.isExternalImage(data)) {
|
|
315
|
-
return this.device.getExternalImageSize(data);
|
|
316
|
-
}
|
|
317
|
-
if (data && typeof data === 'object' && data.constructor === Object) {
|
|
318
|
-
const textureDataArray = Object.values(data);
|
|
319
|
-
const untypedData = textureDataArray[0];
|
|
320
|
-
return {width: untypedData.width, height: untypedData.height};
|
|
321
|
-
}
|
|
322
|
-
throw new Error('texture size deduction failed');
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/** Convert luma.gl cubemap face constants to depth index */
|
|
326
|
-
getCubeFaceDepth(face: TextureCubeFace): number {
|
|
327
|
-
// prettier-ignore
|
|
328
|
-
switch (face) {
|
|
329
|
-
case '+X': return 0;
|
|
330
|
-
case '-X': return 1;
|
|
331
|
-
case '+Y': return 2;
|
|
332
|
-
case '-Y': return 3;
|
|
333
|
-
case '+Z': return 4;
|
|
334
|
-
case '-Z': return 5;
|
|
335
|
-
default: throw new Error(face);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// EXPERIMENTAL
|
|
340
|
-
|
|
341
|
-
setTextureData(data: TextureData) {}
|
|
342
|
-
|
|
343
|
-
/** Experimental: Set multiple mip levels */
|
|
344
|
-
_setTexture1DData(texture: Texture, data: Texture1DData): void {
|
|
345
|
-
throw new Error('setTexture1DData not supported in WebGL.');
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
/** Experimental: Set multiple mip levels */
|
|
349
|
-
_setTexture2DData(lodData: Texture2DData, depth = 0): void {
|
|
350
|
-
if (!this.texture) {
|
|
351
|
-
throw new Error('Texture not initialized');
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
const lodArray = this._normalizeTextureData(lodData);
|
|
355
|
-
|
|
356
|
-
// If the user provides multiple LODs, then automatic mipmap
|
|
357
|
-
// generation generateMipmap() should be disabled to avoid overwriting them.
|
|
358
|
-
if (lodArray.length > 1 && this.props.mipmaps !== false) {
|
|
359
|
-
log.warn(`Texture ${this.id} mipmap and multiple LODs.`)();
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
for (let mipLevel = 0; mipLevel < lodArray.length; mipLevel++) {
|
|
363
|
-
const imageData = lodArray[mipLevel];
|
|
364
|
-
if (this.device.isExternalImage(imageData)) {
|
|
365
|
-
this.texture.copyExternalImage({image: imageData, depth, mipLevel, flipY: true});
|
|
366
|
-
} else {
|
|
367
|
-
this.texture.copyImageData({data: imageData.data /* , depth */, mipLevel});
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Experimental: Sets 3D texture data: multiple depth slices, multiple mip levels
|
|
374
|
-
* @param data
|
|
375
|
-
*/
|
|
376
|
-
_setTexture3DData(texture: Texture, data: Texture3DData): void {
|
|
377
|
-
if (this.texture?.props.dimension !== '3d') {
|
|
378
|
-
throw new Error(this.id);
|
|
379
|
-
}
|
|
380
|
-
for (let depth = 0; depth < data.length; depth++) {
|
|
381
|
-
this._setTexture2DData(data[depth], depth);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Experimental: Set Cube texture data, multiple faces, multiple mip levels
|
|
387
|
-
* @todo - could support TextureCubeArray with depth
|
|
388
|
-
* @param data
|
|
389
|
-
* @param index
|
|
390
|
-
*/
|
|
391
|
-
_setTextureCubeData(texture: Texture, data: TextureCubeData): void {
|
|
392
|
-
if (this.texture?.props.dimension !== 'cube') {
|
|
393
|
-
throw new Error(this.id);
|
|
394
|
-
}
|
|
395
|
-
for (const [face, faceData] of Object.entries(data)) {
|
|
396
|
-
const faceDepth = CubeFaces.indexOf(face as TextureCubeFace);
|
|
397
|
-
this._setTexture2DData(faceData, faceDepth);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Experimental: Sets texture array data, multiple levels, multiple depth slices
|
|
403
|
-
* @param data
|
|
404
|
-
*/
|
|
405
|
-
_setTextureArrayData(texture: Texture, data: TextureArrayData): void {
|
|
406
|
-
if (this.texture?.props.dimension !== '2d-array') {
|
|
407
|
-
throw new Error(this.id);
|
|
408
|
-
}
|
|
409
|
-
for (let depth = 0; depth < data.length; depth++) {
|
|
410
|
-
this._setTexture2DData(data[depth], depth);
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* Experimental: Sets texture cube array, multiple faces, multiple levels, multiple mip levels
|
|
416
|
-
* @param data
|
|
417
|
-
*/
|
|
418
|
-
_setTextureCubeArrayData(texture: Texture, data: TextureCubeArrayData): void {
|
|
419
|
-
throw new Error('setTextureCubeArrayData not supported in WebGL2.');
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
/** Experimental */
|
|
423
|
-
_setTextureCubeFaceData(
|
|
424
|
-
texture: Texture,
|
|
425
|
-
lodData: Texture2DData,
|
|
426
|
-
face: TextureCubeFace,
|
|
427
|
-
depth: number = 0
|
|
428
|
-
): void {
|
|
429
|
-
// assert(this.props.dimension === 'cube');
|
|
430
|
-
|
|
431
|
-
// If the user provides multiple LODs, then automatic mipmap
|
|
432
|
-
// generation generateMipmap() should be disabled to avoid overwriting them.
|
|
433
|
-
if (Array.isArray(lodData) && lodData.length > 1 && this.props.mipmaps !== false) {
|
|
434
|
-
log.warn(`${this.id} has mipmap and multiple LODs.`)();
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
const faceDepth = TextureCubeFaces.indexOf(face);
|
|
438
|
-
this._setTexture2DData(lodData, faceDepth);
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Normalize TextureData to an array of TextureImageData / ExternalImages
|
|
443
|
-
* @param data
|
|
444
|
-
* @param options
|
|
445
|
-
* @returns array of TextureImageData / ExternalImages
|
|
446
|
-
*/
|
|
447
|
-
_normalizeTextureData(data: Texture2DData): (TextureImageData | ExternalImage)[] {
|
|
448
|
-
const options: {width: number; height: number; depth: number} = this.texture;
|
|
449
|
-
let mipLevelArray: (TextureImageData | ExternalImage)[];
|
|
450
|
-
if (ArrayBuffer.isView(data)) {
|
|
451
|
-
mipLevelArray = [
|
|
452
|
-
{
|
|
453
|
-
// ts-expect-error does data really need to be Uint8ClampedArray?
|
|
454
|
-
data,
|
|
455
|
-
width: options.width,
|
|
456
|
-
height: options.height
|
|
457
|
-
// depth: options.depth
|
|
458
|
-
}
|
|
459
|
-
];
|
|
460
|
-
} else if (!Array.isArray(data)) {
|
|
461
|
-
mipLevelArray = [data];
|
|
462
|
-
} else {
|
|
463
|
-
mipLevelArray = data;
|
|
464
|
-
}
|
|
465
|
-
return mipLevelArray;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
static defaultProps: Required<AsyncTextureProps> = {
|
|
469
|
-
...Texture.defaultProps,
|
|
470
|
-
data: null,
|
|
471
|
-
mipmaps: false
|
|
472
|
-
};
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// TODO - Remove when texture refactor is complete
|
|
476
|
-
|
|
477
|
-
/*
|
|
478
|
-
setCubeMapData(options: {
|
|
479
|
-
width: number;
|
|
480
|
-
height: number;
|
|
481
|
-
data: Record<GL, Texture2DData> | Record<TextureCubeFace, Texture2DData>;
|
|
482
|
-
format?: any;
|
|
483
|
-
type?: any;
|
|
484
|
-
/** @deprecated Use .data *
|
|
485
|
-
pixels: any;
|
|
486
|
-
}): void {
|
|
487
|
-
const {gl} = this;
|
|
488
|
-
|
|
489
|
-
const {width, height, pixels, data, format = GL.RGBA, type = GL.UNSIGNED_BYTE} = options;
|
|
490
|
-
|
|
491
|
-
// pixel data (imageDataMap) is an Object from Face to Image or Promise.
|
|
492
|
-
// For example:
|
|
493
|
-
// {
|
|
494
|
-
// GL.TEXTURE_CUBE_MAP_POSITIVE_X : Image-or-Promise,
|
|
495
|
-
// GL.TEXTURE_CUBE_MAP_NEGATIVE_X : Image-or-Promise,
|
|
496
|
-
// ... }
|
|
497
|
-
// To provide multiple level-of-details (LODs) this can be Face to Array
|
|
498
|
-
// of Image or Promise, like this
|
|
499
|
-
// {
|
|
500
|
-
// GL.TEXTURE_CUBE_MAP_POSITIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
|
|
501
|
-
// GL.TEXTURE_CUBE_MAP_NEGATIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
|
|
502
|
-
// ... }
|
|
503
|
-
|
|
504
|
-
const imageDataMap = this._getImageDataMap(pixels || data);
|
|
505
|
-
|
|
506
|
-
const resolvedFaces = WEBGLTexture.FACES.map(face => {
|
|
507
|
-
const facePixels = imageDataMap[face];
|
|
508
|
-
return Array.isArray(facePixels) ? facePixels : [facePixels];
|
|
509
|
-
});
|
|
510
|
-
this.bind();
|
|
511
|
-
|
|
512
|
-
WEBGLTexture.FACES.forEach((face, index) => {
|
|
513
|
-
if (resolvedFaces[index].length > 1 && this.props.mipmaps !== false) {
|
|
514
|
-
// If the user provides multiple LODs, then automatic mipmap
|
|
515
|
-
// generation generateMipmaps() should be disabled to avoid overwritting them.
|
|
516
|
-
log.warn(`${this.id} has mipmap and multiple LODs.`)();
|
|
517
|
-
}
|
|
518
|
-
resolvedFaces[index].forEach((image, lodLevel) => {
|
|
519
|
-
// TODO: adjust width & height for LOD!
|
|
520
|
-
if (width && height) {
|
|
521
|
-
gl.texImage2D(face, lodLevel, format, width, height, 0 /* border*, format, type, image);
|
|
522
|
-
} else {
|
|
523
|
-
gl.texImage2D(face, lodLevel, format, format, type, image);
|
|
524
|
-
}
|
|
525
|
-
});
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
this.unbind();
|
|
529
|
-
}
|
|
530
|
-
*/
|
|
531
|
-
|
|
532
|
-
// HELPERS
|
|
533
|
-
|
|
534
|
-
/** Resolve all promises in a nested data structure */
|
|
535
|
-
async function awaitAllPromises(x: any): Promise<any> {
|
|
536
|
-
x = await x;
|
|
537
|
-
if (Array.isArray(x)) {
|
|
538
|
-
return await Promise.all(x.map(awaitAllPromises));
|
|
539
|
-
}
|
|
540
|
-
if (x && typeof x === 'object' && x.constructor === Object) {
|
|
541
|
-
const object: Record<string, any> = x;
|
|
542
|
-
const values = await Promise.all(Object.values(object));
|
|
543
|
-
const keys = Object.keys(object);
|
|
544
|
-
const resolvedObject: Record<string, any> = {};
|
|
545
|
-
for (let i = 0; i < keys.length; i++) {
|
|
546
|
-
resolvedObject[keys[i]] = values[i];
|
|
547
|
-
}
|
|
548
|
-
return resolvedObject;
|
|
549
|
-
}
|
|
550
|
-
return x;
|
|
551
|
-
}
|
/package/src/{async-texture/texture-setters.ts.disabled → dynamic-texture/texture-data.ts.disabled}
RENAMED
|
File without changes
|