@luma.gl/engine 9.0.17 → 9.1.0-alpha.10
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/key-frames.d.ts.map +1 -1
- package/dist/animation/key-frames.js +3 -0
- package/dist/animation-loop/animation-loop-template.d.ts.map +1 -1
- package/dist/animation-loop/animation-loop-template.js +3 -0
- package/dist/animation-loop/animation-loop.d.ts +1 -1
- package/dist/animation-loop/animation-loop.d.ts.map +1 -1
- package/dist/animation-loop/animation-loop.js +5 -4
- package/dist/animation-loop/animation-props.d.ts.map +1 -1
- package/dist/animation-loop/animation-props.js +3 -0
- package/dist/animation-loop/make-animation-loop.js +1 -1
- package/dist/animation-loop/request-animation-frame.d.ts +3 -0
- package/dist/animation-loop/request-animation-frame.d.ts.map +1 -0
- package/dist/animation-loop/request-animation-frame.js +16 -0
- package/dist/application-utils/load-file.d.ts +22 -0
- package/dist/application-utils/load-file.d.ts.map +1 -0
- package/dist/application-utils/load-file.js +42 -0
- package/dist/application-utils/random.d.ts +3 -0
- package/dist/application-utils/random.d.ts.map +1 -0
- package/dist/application-utils/random.js +16 -0
- package/dist/async-texture/async-texture.d.ts +50 -0
- package/dist/async-texture/async-texture.d.ts.map +1 -0
- package/dist/async-texture/async-texture.js +83 -0
- package/dist/computation.d.ts +4 -3
- package/dist/computation.d.ts.map +1 -1
- package/dist/computation.js +14 -6
- package/dist/debug/copy-texture-to-image.d.ts.map +1 -1
- package/dist/debug/copy-texture-to-image.js +4 -1
- package/dist/debug/debug-framebuffer.d.ts.map +1 -1
- package/dist/debug/debug-framebuffer.js +17 -12
- package/dist/debug/pixel-data-utils.d.ts +1 -1
- package/dist/dist.dev.js +728 -555
- package/dist/dist.min.js +57 -41
- package/dist/geometries/cone-geometry.d.ts.map +1 -1
- package/dist/geometries/cone-geometry.js +4 -1
- package/dist/geometries/cube-geometry.d.ts.map +1 -1
- package/dist/geometries/cube-geometry.js +4 -1
- package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
- package/dist/geometries/cylinder-geometry.js +4 -1
- package/dist/geometries/ico-sphere-geometry.d.ts.map +1 -1
- package/dist/geometries/ico-sphere-geometry.js +4 -1
- package/dist/geometries/plane-geometry.d.ts.map +1 -1
- package/dist/geometries/plane-geometry.js +4 -1
- package/dist/geometries/sphere-geometry.d.ts.map +1 -1
- package/dist/geometries/sphere-geometry.js +4 -1
- package/dist/geometries/truncated-cone-geometry.d.ts.map +1 -1
- package/dist/geometries/truncated-cone-geometry.js +4 -1
- package/dist/geometry/geometry-table.d.ts +2 -1
- package/dist/geometry/geometry-table.d.ts.map +1 -1
- package/dist/geometry/geometry-utils.d.ts.map +1 -1
- package/dist/geometry/geometry-utils.js +3 -1
- package/dist/geometry/geometry.d.ts +5 -4
- package/dist/geometry/geometry.d.ts.map +1 -1
- package/dist/geometry/geometry.js +9 -5
- package/dist/geometry/gpu-geometry.d.ts +1 -1
- package/dist/geometry/gpu-geometry.d.ts.map +1 -1
- package/dist/geometry/gpu-geometry.js +18 -6
- package/dist/geometry/gpu-table.js +3 -0
- package/dist/index.cjs +514 -258
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/lib/clip-space.d.ts.map +1 -1
- package/dist/lib/clip-space.js +10 -7
- package/dist/lib/pipeline-factory.d.ts +3 -2
- package/dist/lib/pipeline-factory.d.ts.map +1 -1
- package/dist/lib/pipeline-factory.js +12 -8
- package/dist/lib/shader-factory.d.ts +3 -2
- package/dist/lib/shader-factory.d.ts.map +1 -1
- package/dist/lib/shader-factory.js +11 -4
- package/dist/model/model.d.ts +10 -6
- package/dist/model/model.d.ts.map +1 -1
- package/dist/model/model.js +64 -8
- package/dist/model/split-uniforms-and-bindings.d.ts +9 -0
- package/dist/model/split-uniforms-and-bindings.d.ts.map +1 -0
- package/dist/model/split-uniforms-and-bindings.js +20 -0
- package/dist/scenegraph/group-node.d.ts +1 -1
- package/dist/scenegraph/group-node.d.ts.map +1 -1
- package/dist/scenegraph/group-node.js +3 -0
- package/dist/scenegraph/model-node.d.ts +2 -2
- package/dist/scenegraph/model-node.d.ts.map +1 -1
- package/dist/scenegraph/model-node.js +6 -3
- package/dist/scenegraph/scenegraph-node.d.ts +5 -6
- package/dist/scenegraph/scenegraph-node.d.ts.map +1 -1
- package/dist/scenegraph/scenegraph-node.js +11 -8
- package/dist/shader-inputs.d.ts +21 -8
- package/dist/shader-inputs.d.ts.map +1 -1
- package/dist/shader-inputs.js +11 -6
- package/dist/transform/buffer-transform.d.ts.map +1 -1
- package/dist/transform/buffer-transform.js +8 -2
- package/dist/transform/texture-transform.d.ts +2 -2
- package/dist/transform/texture-transform.d.ts.map +1 -1
- package/dist/transform/texture-transform.js +1 -0
- package/dist/utils/deep-equal.d.ts +9 -0
- package/dist/utils/deep-equal.d.ts.map +1 -0
- package/dist/utils/deep-equal.js +50 -0
- package/dist/utils/uid.d.ts +7 -0
- package/dist/utils/uid.d.ts.map +1 -0
- package/dist/utils/uid.js +14 -0
- package/package.json +7 -6
- package/src/animation/key-frames.ts +4 -0
- package/src/animation-loop/animation-loop-template.ts +4 -0
- package/src/animation-loop/animation-loop.ts +6 -4
- package/src/animation-loop/animation-props.ts +4 -0
- package/src/animation-loop/make-animation-loop.ts +1 -1
- package/src/animation-loop/request-animation-frame.ts +19 -0
- package/src/application-utils/load-file.ts +51 -0
- package/src/application-utils/random.ts +18 -0
- package/src/async-texture/async-texture.ts +146 -0
- package/src/computation.ts +17 -9
- package/src/debug/copy-texture-to-image.ts +4 -1
- package/src/debug/debug-framebuffer.ts +18 -12
- package/src/debug/pixel-data-utils.ts +1 -1
- package/src/geometries/cone-geometry.ts +5 -1
- package/src/geometries/cube-geometry.ts +5 -1
- package/src/geometries/cylinder-geometry.ts +5 -1
- package/src/geometries/ico-sphere-geometry.ts +5 -1
- package/src/geometries/plane-geometry.ts +5 -1
- package/src/geometries/sphere-geometry.ts +5 -1
- package/src/geometries/truncated-cone-geometry.ts +5 -1
- package/src/geometry/geometry-table.ts +2 -1
- package/src/geometry/geometry-utils.ts +3 -1
- package/src/geometry/geometry.ts +16 -19
- package/src/geometry/gpu-geometry.ts +20 -14
- package/src/geometry/gpu-table.ts +4 -0
- package/src/index.ts +16 -0
- package/src/lib/clip-space.ts +6 -2
- package/src/lib/pipeline-factory.ts +17 -16
- package/src/lib/shader-factory.ts +13 -6
- package/src/model/model.ts +70 -17
- package/src/model/split-uniforms-and-bindings.ts +31 -0
- package/src/scenegraph/group-node.ts +4 -0
- package/src/scenegraph/model-node.ts +9 -5
- package/src/scenegraph/scenegraph-node.ts +17 -13
- package/src/shader-inputs.ts +47 -18
- package/src/transform/buffer-transform.ts +8 -9
- package/src/transform/texture-transform.ts +2 -1
- package/src/utils/deep-equal.ts +51 -0
- package/src/utils/uid.ts +16 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// luma.gl, MIT license
|
|
2
|
+
// Copyright (c) vis.gl contributors
|
|
3
|
+
|
|
4
|
+
import type {Texture, TextureProps, Sampler, TextureView, Device} from '@luma.gl/core';
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
Texture1DData,
|
|
8
|
+
Texture2DData,
|
|
9
|
+
Texture3DData,
|
|
10
|
+
TextureArrayData,
|
|
11
|
+
TextureCubeData,
|
|
12
|
+
TextureCubeArrayData
|
|
13
|
+
} from '@luma.gl/core';
|
|
14
|
+
|
|
15
|
+
import {loadImageBitmap} from '../application-utils/load-file';
|
|
16
|
+
|
|
17
|
+
export type AsyncTextureProps = Omit<TextureProps, 'data'> & AsyncTextureDataProps;
|
|
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 TextureData = TextureProps['data'];
|
|
44
|
+
type AsyncTextureData = AsyncTextureProps['data'];
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* It is very convenient to be able to initialize textures with promises
|
|
48
|
+
* This can add considerable complexity to the Texture class, and doesn't
|
|
49
|
+
* fit with the immutable nature of WebGPU resources.
|
|
50
|
+
* Instead, luma.gl offers async textures as a separate class.
|
|
51
|
+
*/
|
|
52
|
+
export class AsyncTexture {
|
|
53
|
+
readonly device: Device;
|
|
54
|
+
|
|
55
|
+
// TODO - should we type these as possibly `null`? It will make usage harder?
|
|
56
|
+
// @ts-expect-error
|
|
57
|
+
texture: Texture;
|
|
58
|
+
// @ts-expect-error
|
|
59
|
+
sampler: Sampler;
|
|
60
|
+
// @ts-expect-error
|
|
61
|
+
view: TextureView;
|
|
62
|
+
|
|
63
|
+
readonly ready: Promise<void>;
|
|
64
|
+
isReady: boolean = false;
|
|
65
|
+
destroyed: boolean = false;
|
|
66
|
+
|
|
67
|
+
protected resolveReady: () => void = () => {};
|
|
68
|
+
protected rejectReady: (error: Error) => void = () => {};
|
|
69
|
+
|
|
70
|
+
constructor(device: Device, props: AsyncTextureProps) {
|
|
71
|
+
this.device = device;
|
|
72
|
+
|
|
73
|
+
// Signature: new AsyncTexture(device, {data: url})
|
|
74
|
+
if (typeof props?.data === 'string' && props.dimension === '2d') {
|
|
75
|
+
props = {...props, data: loadImageBitmap(props.data)};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.ready = new Promise<void>((resolve, reject) => {
|
|
79
|
+
this.resolveReady = () => {
|
|
80
|
+
this.isReady = true;
|
|
81
|
+
resolve();
|
|
82
|
+
};
|
|
83
|
+
this.rejectReady = reject;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
this.initAsync(props);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async initAsync(props: AsyncTextureProps): Promise<void> {
|
|
90
|
+
let resolveReady;
|
|
91
|
+
let rejectReady;
|
|
92
|
+
|
|
93
|
+
const asyncData: AsyncTextureData = props.data;
|
|
94
|
+
const data: TextureData = await awaitAllPromises(asyncData).then(resolveReady, rejectReady);
|
|
95
|
+
|
|
96
|
+
// Check that we haven't been destroyed while waiting for texture data to load
|
|
97
|
+
if (this.destroyed) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Now we can actually create the texture
|
|
102
|
+
// @ts-expect-error Discriminated union
|
|
103
|
+
const syncProps: TextureProps = {...props, data};
|
|
104
|
+
|
|
105
|
+
this.texture = this.device.createTexture(syncProps);
|
|
106
|
+
this.sampler = this.texture.sampler;
|
|
107
|
+
this.view = this.texture.view;
|
|
108
|
+
this.isReady = true;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
destroy(): void {
|
|
112
|
+
if (this.texture) {
|
|
113
|
+
this.texture.destroy();
|
|
114
|
+
// @ts-expect-error
|
|
115
|
+
this.texture = null;
|
|
116
|
+
}
|
|
117
|
+
this.destroyed = true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// We could implement resize by replacing the texture
|
|
121
|
+
// resize(width: number, height: number): boolean {
|
|
122
|
+
// throw new Error('Not implemented');
|
|
123
|
+
// // return false;
|
|
124
|
+
// }
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// HELPERS
|
|
128
|
+
|
|
129
|
+
/** Resolve all promises in a nested data structure */
|
|
130
|
+
async function awaitAllPromises(x: any): Promise<any> {
|
|
131
|
+
x = await x;
|
|
132
|
+
if (Array.isArray(x)) {
|
|
133
|
+
return await Promise.all(x.map(awaitAllPromises));
|
|
134
|
+
}
|
|
135
|
+
if (x && typeof x === 'object' && x.constructor === Object) {
|
|
136
|
+
const object: Record<string, any> = x;
|
|
137
|
+
const values = await Promise.all(Object.values(object));
|
|
138
|
+
const keys = Object.keys(object);
|
|
139
|
+
const resolvedObject: Record<string, any> = {};
|
|
140
|
+
for (let i = 0; i < keys.length; i++) {
|
|
141
|
+
resolvedObject[keys[i]] = values[i];
|
|
142
|
+
}
|
|
143
|
+
return resolvedObject;
|
|
144
|
+
}
|
|
145
|
+
return x;
|
|
146
|
+
}
|
package/src/computation.ts
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import type {TypedArray} from '@luma.gl/core';
|
|
6
5
|
import type {DeviceFeature, ComputePipelineProps, Shader, Binding} from '@luma.gl/core';
|
|
7
6
|
import {Device, Buffer, ComputePipeline, ComputePass, UniformStore} from '@luma.gl/core';
|
|
8
|
-
import {log
|
|
7
|
+
import {log} from '@luma.gl/core';
|
|
9
8
|
import {getTypedArrayFromDataType} from '@luma.gl/core';
|
|
10
9
|
import type {ShaderModule, PlatformInfo} from '@luma.gl/shadertools';
|
|
11
10
|
import {ShaderAssembler, getShaderLayoutFromWGSL} from '@luma.gl/shadertools';
|
|
11
|
+
import {TypedArray, isNumericArray} from '@math.gl/types';
|
|
12
12
|
import {ShaderInputs} from './shader-inputs';
|
|
13
13
|
import {PipelineFactory} from './lib/pipeline-factory';
|
|
14
14
|
import {ShaderFactory} from './lib/shader-factory';
|
|
15
|
+
import {uid} from './utils/uid';
|
|
15
16
|
// import {getDebugTableForShaderLayout} from '../debug/debug-shader-layout';
|
|
16
17
|
|
|
17
18
|
const LOG_DRAW_PRIORITY = 2;
|
|
@@ -69,7 +70,7 @@ export class Computation {
|
|
|
69
70
|
shaderFactory: undefined!,
|
|
70
71
|
shaderAssembler: ShaderAssembler.getDefaultShaderAssembler(),
|
|
71
72
|
|
|
72
|
-
debugShaders: undefined
|
|
73
|
+
debugShaders: undefined!
|
|
73
74
|
};
|
|
74
75
|
|
|
75
76
|
readonly device: Device;
|
|
@@ -83,15 +84,18 @@ export class Computation {
|
|
|
83
84
|
/** Bindings (textures, samplers, uniform buffers) */
|
|
84
85
|
bindings: Record<string, Binding> = {};
|
|
85
86
|
|
|
86
|
-
/** The underlying GPU
|
|
87
|
+
/** The underlying GPU pipeline. */
|
|
87
88
|
pipeline: ComputePipeline;
|
|
89
|
+
/** Assembled compute shader source */
|
|
90
|
+
source: string;
|
|
88
91
|
/** the underlying compiled compute shader */
|
|
92
|
+
// @ts-ignore Set in function called from constructor
|
|
89
93
|
shader: Shader;
|
|
90
|
-
source: string;
|
|
91
94
|
|
|
92
95
|
/** ShaderInputs instance */
|
|
93
96
|
shaderInputs: ShaderInputs;
|
|
94
97
|
|
|
98
|
+
// @ts-ignore Set in function called from constructor
|
|
95
99
|
_uniformStore: UniformStore;
|
|
96
100
|
|
|
97
101
|
_pipelineNeedsUpdate: string | false = 'newly created';
|
|
@@ -117,7 +121,9 @@ export class Computation {
|
|
|
117
121
|
const moduleMap = Object.fromEntries(
|
|
118
122
|
this.props.modules?.map(module => [module.name, module]) || []
|
|
119
123
|
);
|
|
120
|
-
|
|
124
|
+
// @ts-ignore TODO - fix up typing?
|
|
125
|
+
this.shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap);
|
|
126
|
+
this.setShaderInputs(this.shaderInputs);
|
|
121
127
|
|
|
122
128
|
// Support WGSL shader layout introspection
|
|
123
129
|
// TODO - Don't modify props!!
|
|
@@ -134,14 +140,14 @@ export class Computation {
|
|
|
134
140
|
props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
135
141
|
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
136
142
|
|
|
137
|
-
const {source, getUniforms} = this.props.shaderAssembler.
|
|
143
|
+
const {source, getUniforms} = this.props.shaderAssembler.assembleWGSLShader({
|
|
138
144
|
platformInfo,
|
|
139
145
|
...this.props,
|
|
140
146
|
modules
|
|
141
147
|
});
|
|
142
148
|
|
|
143
149
|
this.source = source;
|
|
144
|
-
|
|
150
|
+
// @ts-ignore
|
|
145
151
|
this._getModuleUniforms = getUniforms;
|
|
146
152
|
|
|
147
153
|
// Create the pipeline
|
|
@@ -233,7 +239,9 @@ export class Computation {
|
|
|
233
239
|
// TODO better way to extract bindings
|
|
234
240
|
const keys = Object.keys(uniforms).filter(k => {
|
|
235
241
|
const uniform = uniforms[k];
|
|
236
|
-
return
|
|
242
|
+
return (
|
|
243
|
+
!isNumericArray(uniform) && typeof uniform !== 'number' && typeof uniform !== 'boolean'
|
|
244
|
+
);
|
|
237
245
|
});
|
|
238
246
|
const bindings: Record<string, Binding> = {};
|
|
239
247
|
for (const k of keys) {
|
|
@@ -60,9 +60,12 @@ export function copyTextureToDataUrl(
|
|
|
60
60
|
canvas.width = width;
|
|
61
61
|
canvas.height = height;
|
|
62
62
|
const context = canvas.getContext('2d');
|
|
63
|
+
if (!context) {
|
|
64
|
+
throw new Error('Failed to create context');
|
|
65
|
+
}
|
|
63
66
|
|
|
64
67
|
// Copy the pixels to a 2D canvas
|
|
65
|
-
const imageData = context
|
|
68
|
+
const imageData = context?.createImageData(width, height);
|
|
66
69
|
imageData.data.set(data);
|
|
67
70
|
context.putImageData(imageData, 0, 0);
|
|
68
71
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
1
5
|
import type {Framebuffer, Texture} from '@luma.gl/core';
|
|
2
6
|
// import {copyTextureToImage} from '../debug/copy-texture-to-image';
|
|
3
7
|
|
|
@@ -54,17 +58,19 @@ export function debugFramebuffer(
|
|
|
54
58
|
// ctx.drawImage(image, 0, 0);
|
|
55
59
|
|
|
56
60
|
const color = fbo.device.readPixelsToArrayWebGL(fbo);
|
|
57
|
-
const imageData = ctx
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
const imageData = ctx?.createImageData(fbo.width, fbo.height);
|
|
62
|
+
if (imageData) {
|
|
63
|
+
// Full map
|
|
64
|
+
const offset = 0;
|
|
65
|
+
// if (color.some((v) => v > 0)) {
|
|
66
|
+
// console.error('THERE IS NON-ZERO DATA IN THE FBO!');
|
|
67
|
+
// }
|
|
68
|
+
for (let i = 0; i < color.length; i += 4) {
|
|
69
|
+
imageData.data[offset + i + 0] = color[i + 0] * rgbaScale;
|
|
70
|
+
imageData.data[offset + i + 1] = color[i + 1] * rgbaScale;
|
|
71
|
+
imageData.data[offset + i + 2] = color[i + 2] * rgbaScale;
|
|
72
|
+
imageData.data[offset + i + 3] = opaque ? 255 : color[i + 3] * rgbaScale;
|
|
73
|
+
}
|
|
74
|
+
ctx?.putImageData(imageData, 0, 0);
|
|
68
75
|
}
|
|
69
|
-
ctx.putImageData(imageData, 0, 0);
|
|
70
76
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
2
5
|
import {TruncatedConeGeometry} from './truncated-cone-geometry';
|
|
6
|
+
import {uid} from '../utils/uid';
|
|
3
7
|
|
|
4
8
|
export type ConeGeometryProps = {
|
|
5
9
|
id?: string;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
2
5
|
import {Geometry} from '../geometry/geometry';
|
|
6
|
+
import {uid} from '../utils/uid';
|
|
3
7
|
// import type {GeometryType} from '../geometry/geometry-type';
|
|
4
8
|
|
|
5
9
|
export type CubeGeometryProps = {
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
2
5
|
import {TruncatedConeGeometry} from './truncated-cone-geometry';
|
|
6
|
+
import {uid} from '../utils/uid';
|
|
3
7
|
|
|
4
8
|
export type CylinderGeometryProps = {
|
|
5
9
|
id?: string;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
2
5
|
import {Vector3} from '@math.gl/core';
|
|
3
6
|
import {Geometry} from '../geometry/geometry';
|
|
7
|
+
import {uid} from '../utils/uid';
|
|
4
8
|
|
|
5
9
|
/* eslint-disable comma-spacing, max-statements, complexity */
|
|
6
10
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
2
5
|
import {Geometry} from '../geometry/geometry';
|
|
3
6
|
import {unpackIndexedGeometry} from '../geometry/geometry-utils';
|
|
7
|
+
import {uid} from '../utils/uid';
|
|
4
8
|
|
|
5
9
|
export type PlaneGeometryProps = {
|
|
6
10
|
id?: string;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
2
5
|
import {Geometry} from '../geometry/geometry';
|
|
6
|
+
import {uid} from '../utils/uid';
|
|
3
7
|
|
|
4
8
|
export type SphereGeometryProps = {
|
|
5
9
|
id?: string;
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import type {TypedArray
|
|
5
|
+
import type {TypedArray} from '@math.gl/core';
|
|
6
|
+
import type {VertexFormat} from '@luma.gl/core';
|
|
6
7
|
|
|
7
8
|
/** Holds one geometry */
|
|
8
9
|
export type GeometryTable = {
|
package/src/geometry/geometry.ts
CHANGED
|
@@ -2,23 +2,17 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import type {
|
|
6
|
-
import {
|
|
5
|
+
import type {TypedArray} from '@math.gl/core';
|
|
6
|
+
import type {PrimitiveTopology} from '@luma.gl/core';
|
|
7
|
+
import {uid} from '../utils/uid';
|
|
7
8
|
|
|
8
9
|
export type GeometryProps = {
|
|
9
10
|
id?: string;
|
|
10
11
|
/** Determines how vertices are read from the 'vertex' attributes */
|
|
11
|
-
topology:
|
|
12
|
-
| 'point-list'
|
|
13
|
-
| 'line-list'
|
|
14
|
-
| 'line-strip'
|
|
15
|
-
| 'line-loop-webgl'
|
|
16
|
-
| 'triangle-list'
|
|
17
|
-
| 'triangle-strip'
|
|
18
|
-
| 'triangle-fan-webgl';
|
|
12
|
+
topology: 'point-list' | 'line-list' | 'line-strip' | 'triangle-list' | 'triangle-strip';
|
|
19
13
|
/** Auto calculated from attributes if not provided */
|
|
20
14
|
vertexCount?: number;
|
|
21
|
-
attributes
|
|
15
|
+
attributes: Record<string, GeometryAttribute | TypedArray>;
|
|
22
16
|
indices?: GeometryAttribute | TypedArray;
|
|
23
17
|
};
|
|
24
18
|
|
|
@@ -71,10 +65,11 @@ export class Geometry {
|
|
|
71
65
|
? {value: attributeValue}
|
|
72
66
|
: attributeValue;
|
|
73
67
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
68
|
+
if (!ArrayBuffer.isView(attribute.value)) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
`${this._print(attributeName)}: must be typed array or object with value as typed array`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
78
73
|
|
|
79
74
|
if ((attributeName === 'POSITION' || attributeName === 'positions') && !attribute.size) {
|
|
80
75
|
attribute.size = 3;
|
|
@@ -82,7 +77,9 @@ export class Geometry {
|
|
|
82
77
|
|
|
83
78
|
// Move indices to separate field
|
|
84
79
|
if (attributeName === 'indices') {
|
|
85
|
-
|
|
80
|
+
if (this.indices) {
|
|
81
|
+
throw new Error('Multiple indices detected');
|
|
82
|
+
}
|
|
86
83
|
this.indices = attribute;
|
|
87
84
|
} else {
|
|
88
85
|
this.attributes[attributeName] = attribute;
|
|
@@ -130,19 +127,19 @@ export class Geometry {
|
|
|
130
127
|
return this;
|
|
131
128
|
}
|
|
132
129
|
|
|
133
|
-
_calculateVertexCount(attributes: GeometryAttributes, indices
|
|
130
|
+
_calculateVertexCount(attributes: GeometryAttributes, indices?: GeometryAttribute): number {
|
|
134
131
|
if (indices) {
|
|
135
132
|
return indices.value.length;
|
|
136
133
|
}
|
|
137
134
|
let vertexCount = Infinity;
|
|
138
135
|
for (const attribute of Object.values(attributes)) {
|
|
139
136
|
const {value, size, constant} = attribute;
|
|
140
|
-
if (!constant && value && size >= 1) {
|
|
137
|
+
if (!constant && value && size !== undefined && size >= 1) {
|
|
141
138
|
vertexCount = Math.min(vertexCount, value.length / size);
|
|
142
139
|
}
|
|
143
140
|
}
|
|
144
141
|
|
|
145
|
-
assert(Number.isFinite(vertexCount));
|
|
142
|
+
// assert(Number.isFinite(vertexCount));
|
|
146
143
|
return vertexCount;
|
|
147
144
|
}
|
|
148
145
|
}
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
1
5
|
import type {PrimitiveTopology, BufferLayout} from '@luma.gl/core';
|
|
2
|
-
import {Device, Buffer,
|
|
6
|
+
import {Device, Buffer, getVertexFormatFromAttribute} from '@luma.gl/core';
|
|
3
7
|
import type {Geometry} from '../geometry/geometry';
|
|
8
|
+
import {uid} from '../utils/uid';
|
|
4
9
|
|
|
5
10
|
export type GPUGeometryProps = {
|
|
6
11
|
id?: string;
|
|
7
12
|
/** Determines how vertices are read from the 'vertex' attributes */
|
|
8
|
-
topology:
|
|
9
|
-
| 'point-list'
|
|
10
|
-
| 'line-list'
|
|
11
|
-
| 'line-strip'
|
|
12
|
-
| 'line-loop-webgl'
|
|
13
|
-
| 'triangle-list'
|
|
14
|
-
| 'triangle-strip'
|
|
15
|
-
| 'triangle-fan-webgl';
|
|
13
|
+
topology: 'point-list' | 'line-list' | 'line-strip' | 'triangle-list' | 'triangle-strip';
|
|
16
14
|
/** Auto calculated from attributes if not provided */
|
|
17
15
|
vertexCount: number;
|
|
18
16
|
bufferLayout: BufferLayout[];
|
|
@@ -43,7 +41,9 @@ export class GPUGeometry {
|
|
|
43
41
|
this.bufferLayout = props.bufferLayout || [];
|
|
44
42
|
|
|
45
43
|
if (this.indices) {
|
|
46
|
-
|
|
44
|
+
if (!(this.indices.usage & Buffer.INDEX)) {
|
|
45
|
+
throw new Error('Index buffer must have INDEX usage');
|
|
46
|
+
}
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -63,7 +63,7 @@ export class GPUGeometry {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
getIndexes(): Buffer | null {
|
|
66
|
-
return this.indices;
|
|
66
|
+
return this.indices || null;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
_calculateVertexCount(positions: Buffer): number {
|
|
@@ -121,9 +121,15 @@ export function getAttributeBuffersFromGeometry(
|
|
|
121
121
|
name = 'colors';
|
|
122
122
|
break;
|
|
123
123
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
if (attribute) {
|
|
125
|
+
attributes[name] = device.createBuffer({
|
|
126
|
+
data: attribute.value,
|
|
127
|
+
id: `${attributeName}-buffer`
|
|
128
|
+
});
|
|
129
|
+
const {value, size, normalized} = attribute;
|
|
130
|
+
// @ts-expect-error
|
|
131
|
+
bufferLayout.push({name, format: getVertexFormatFromAttribute(value, size, normalized)});
|
|
132
|
+
}
|
|
127
133
|
}
|
|
128
134
|
|
|
129
135
|
const vertexCount = geometry._calculateVertexCount(geometry.attributes, geometry.indices);
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
1
5
|
// luma.gl Engine API
|
|
2
6
|
|
|
3
7
|
// Animation
|
|
@@ -56,7 +60,19 @@ export {SphereGeometry} from './geometries/sphere-geometry';
|
|
|
56
60
|
export type {TruncatedConeGeometryProps} from './geometries/truncated-cone-geometry';
|
|
57
61
|
export {TruncatedConeGeometry} from './geometries/truncated-cone-geometry';
|
|
58
62
|
|
|
63
|
+
// Application Utilities
|
|
64
|
+
export {makeRandomGenerator} from './application-utils/random';
|
|
65
|
+
export {setPathPrefix, loadImage, loadImageBitmap} from './application-utils/load-file';
|
|
66
|
+
|
|
59
67
|
// EXPERIMENTAL
|
|
68
|
+
export type {ShaderModuleInputs} from './shader-inputs';
|
|
60
69
|
export {ShaderInputs as _ShaderInputs} from './shader-inputs';
|
|
61
70
|
export type {ComputationProps} from './computation';
|
|
62
71
|
export {Computation} from './computation';
|
|
72
|
+
export {
|
|
73
|
+
requestAnimationFrame,
|
|
74
|
+
cancelAnimationFrame
|
|
75
|
+
} from './animation-loop/request-animation-frame';
|
|
76
|
+
|
|
77
|
+
export type {AsyncTextureProps} from './async-texture/async-texture';
|
|
78
|
+
export {AsyncTexture} from './async-texture/async-texture';
|
package/src/lib/clip-space.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
1
5
|
// ClipSpace
|
|
2
|
-
import {Device
|
|
6
|
+
import {Device} from '@luma.gl/core';
|
|
3
7
|
import {Model, ModelProps} from '../model/model';
|
|
4
8
|
import {Geometry} from '../geometry/geometry';
|
|
5
9
|
|
|
6
|
-
const CLIPSPACE_VERTEX_SHADER = glsl`\
|
|
10
|
+
const CLIPSPACE_VERTEX_SHADER = /* glsl */ `\
|
|
7
11
|
#version 300 es
|
|
8
12
|
in vec2 aClipSpacePosition;
|
|
9
13
|
in vec2 aTexCoord;
|
|
@@ -7,25 +7,15 @@ import {Device, RenderPipeline, ComputePipeline} from '@luma.gl/core';
|
|
|
7
7
|
|
|
8
8
|
export type PipelineFactoryProps = RenderPipelineProps;
|
|
9
9
|
|
|
10
|
+
type RenderPipelineCacheItem = {pipeline: RenderPipeline; useCount: number};
|
|
11
|
+
type ComputePipelineCacheItem = {pipeline: ComputePipeline; useCount: number};
|
|
12
|
+
|
|
10
13
|
/**
|
|
11
14
|
* Efficiently creates / caches pipelines
|
|
12
15
|
*/
|
|
13
16
|
export class PipelineFactory {
|
|
14
17
|
static defaultProps: Required<PipelineFactoryProps> = {...RenderPipeline.defaultProps};
|
|
15
18
|
|
|
16
|
-
readonly device: Device;
|
|
17
|
-
|
|
18
|
-
private _hashCounter: number = 0;
|
|
19
|
-
private readonly _hashes: Record<string, number> = {};
|
|
20
|
-
private readonly _renderPipelineCache: Record<
|
|
21
|
-
string,
|
|
22
|
-
{pipeline: RenderPipeline; useCount: number}
|
|
23
|
-
> = {};
|
|
24
|
-
private readonly _computePipelineCache: Record<
|
|
25
|
-
string,
|
|
26
|
-
{pipeline: ComputePipeline; useCount: number}
|
|
27
|
-
> = {};
|
|
28
|
-
|
|
29
19
|
/** Get the singleton default pipeline factory for the specified device */
|
|
30
20
|
static getDefaultPipelineFactory(device: Device): PipelineFactory {
|
|
31
21
|
device._lumaData.defaultPipelineFactory =
|
|
@@ -33,8 +23,17 @@ export class PipelineFactory {
|
|
|
33
23
|
return device._lumaData.defaultPipelineFactory as PipelineFactory;
|
|
34
24
|
}
|
|
35
25
|
|
|
26
|
+
readonly device: Device;
|
|
27
|
+
readonly destroyPolicy: 'unused' | 'never';
|
|
28
|
+
|
|
29
|
+
private _hashCounter: number = 0;
|
|
30
|
+
private readonly _hashes: Record<string, number> = {};
|
|
31
|
+
private readonly _renderPipelineCache: Record<string, RenderPipelineCacheItem> = {};
|
|
32
|
+
private readonly _computePipelineCache: Record<string, ComputePipelineCacheItem> = {};
|
|
33
|
+
|
|
36
34
|
constructor(device: Device) {
|
|
37
35
|
this.device = device;
|
|
36
|
+
this.destroyPolicy = device.props._factoryDestroyPolicy;
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
/** Return a RenderPipeline matching props. Reuses a similar pipeline if already created. */
|
|
@@ -80,8 +79,10 @@ export class PipelineFactory {
|
|
|
80
79
|
pipeline instanceof ComputePipeline ? this._computePipelineCache : this._renderPipelineCache;
|
|
81
80
|
cache[hash].useCount--;
|
|
82
81
|
if (cache[hash].useCount === 0) {
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
if (this.destroyPolicy === 'unused') {
|
|
83
|
+
cache[hash].pipeline.destroy();
|
|
84
|
+
delete cache[hash];
|
|
85
|
+
}
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
|
|
@@ -93,7 +94,7 @@ export class PipelineFactory {
|
|
|
93
94
|
|
|
94
95
|
/** Calculate a hash based on all the inputs for a render pipeline */
|
|
95
96
|
private _hashRenderPipeline(props: RenderPipelineProps): string {
|
|
96
|
-
const vsHash = this._getHash(props.vs.source);
|
|
97
|
+
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
97
98
|
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
98
99
|
|
|
99
100
|
// WebGL specific
|