@luma.gl/engine 9.0.11 → 9.1.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/LICENSE +34 -0
- 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/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 +43 -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 +77 -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 +1291 -648
- package/dist/dist.min.js +30 -28
- 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 +491 -244
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/lib/clip-space.d.ts.map +1 -1
- package/dist/lib/clip-space.js +3 -0
- 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 +65 -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 +2 -3
- package/dist/shader-inputs.d.ts.map +1 -1
- package/dist/shader-inputs.js +7 -5
- 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/request-animation-frame.ts +19 -0
- package/src/application-utils/load-file.ts +53 -0
- package/src/application-utils/random.ts +18 -0
- package/src/async-texture/async-texture.ts +140 -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 +15 -0
- package/src/lib/clip-space.ts +4 -0
- package/src/lib/pipeline-factory.ts +17 -16
- package/src/lib/shader-factory.ts +13 -6
- package/src/model/model.ts +71 -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 +8 -6
- 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
package/src/model/model.ts
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
// A lot of imports, but then Model is where it all comes together...
|
|
6
|
-
import type {TypedArray
|
|
6
|
+
import type {TypedArray} from '@math.gl/types';
|
|
7
|
+
import type {RenderPipelineProps, RenderPipelineParameters} from '@luma.gl/core';
|
|
7
8
|
import type {BufferLayout, Shader, VertexArray, TransformFeedback} from '@luma.gl/core';
|
|
8
9
|
import type {AttributeInfo, Binding, UniformValue, PrimitiveTopology} from '@luma.gl/core';
|
|
9
10
|
import {Device, DeviceFeature, Buffer, Texture, TextureView, Sampler} from '@luma.gl/core';
|
|
10
11
|
import {RenderPipeline, RenderPass, UniformStore} from '@luma.gl/core';
|
|
11
|
-
import {log
|
|
12
|
+
import {log} from '@luma.gl/core';
|
|
12
13
|
import {getTypedArrayFromDataType, getAttributeInfosFromLayouts} from '@luma.gl/core';
|
|
13
14
|
|
|
14
15
|
import type {ShaderModule, PlatformInfo} from '@luma.gl/shadertools';
|
|
@@ -16,16 +17,22 @@ import {ShaderAssembler, getShaderLayoutFromWGSL} from '@luma.gl/shadertools';
|
|
|
16
17
|
|
|
17
18
|
import type {Geometry} from '../geometry/geometry';
|
|
18
19
|
import {GPUGeometry, makeGPUGeometry} from '../geometry/gpu-geometry';
|
|
19
|
-
import {ShaderInputs} from '../shader-inputs';
|
|
20
20
|
import {PipelineFactory} from '../lib/pipeline-factory';
|
|
21
21
|
import {ShaderFactory} from '../lib/shader-factory';
|
|
22
22
|
import {getDebugTableForShaderLayout} from '../debug/debug-shader-layout';
|
|
23
23
|
import {debugFramebuffer} from '../debug/debug-framebuffer';
|
|
24
|
+
import {deepEqual} from '../utils/deep-equal';
|
|
25
|
+
import {uid} from '../utils/uid';
|
|
26
|
+
import {splitUniformsAndBindings} from './split-uniforms-and-bindings';
|
|
27
|
+
|
|
28
|
+
import {ShaderInputs} from '../shader-inputs';
|
|
29
|
+
// import type {AsyncTextureProps} from '../async-texture/async-texture';
|
|
30
|
+
import {AsyncTexture} from '../async-texture/async-texture';
|
|
24
31
|
|
|
25
32
|
const LOG_DRAW_PRIORITY = 2;
|
|
26
33
|
const LOG_DRAW_TIMEOUT = 10000;
|
|
27
34
|
|
|
28
|
-
export type ModelProps = Omit<RenderPipelineProps, 'vs' | 'fs'> & {
|
|
35
|
+
export type ModelProps = Omit<RenderPipelineProps, 'vs' | 'fs' | 'bindings'> & {
|
|
29
36
|
source?: string;
|
|
30
37
|
vs: string | null;
|
|
31
38
|
fs: string | null;
|
|
@@ -39,7 +46,7 @@ export type ModelProps = Omit<RenderPipelineProps, 'vs' | 'fs'> & {
|
|
|
39
46
|
/** Shader inputs, used to generated uniform buffers and bindings */
|
|
40
47
|
shaderInputs?: ShaderInputs;
|
|
41
48
|
/** Bindings */
|
|
42
|
-
bindings?: Record<string, Binding>;
|
|
49
|
+
bindings?: Record<string, Binding | AsyncTexture>;
|
|
43
50
|
/** Parameters that are built into the pipeline */
|
|
44
51
|
parameters?: RenderPipelineParameters;
|
|
45
52
|
|
|
@@ -92,7 +99,7 @@ export type ModelProps = Omit<RenderPipelineProps, 'vs' | 'fs'> & {
|
|
|
92
99
|
export class Model {
|
|
93
100
|
static defaultProps: Required<ModelProps> = {
|
|
94
101
|
...RenderPipeline.defaultProps,
|
|
95
|
-
source:
|
|
102
|
+
source: undefined!,
|
|
96
103
|
vs: null,
|
|
97
104
|
fs: null,
|
|
98
105
|
id: 'unnamed',
|
|
@@ -114,7 +121,7 @@ export class Model {
|
|
|
114
121
|
shaderInputs: undefined!,
|
|
115
122
|
pipelineFactory: undefined!,
|
|
116
123
|
shaderFactory: undefined!,
|
|
117
|
-
transformFeedback: undefined
|
|
124
|
+
transformFeedback: undefined!,
|
|
118
125
|
shaderAssembler: ShaderAssembler.getDefaultShaderAssembler(),
|
|
119
126
|
|
|
120
127
|
debugShaders: undefined!,
|
|
@@ -123,8 +130,11 @@ export class Model {
|
|
|
123
130
|
|
|
124
131
|
readonly device: Device;
|
|
125
132
|
readonly id: string;
|
|
133
|
+
// @ts-expect-error assigned in function called from constructor
|
|
126
134
|
readonly source: string;
|
|
135
|
+
// @ts-expect-error assigned in function called from constructor
|
|
127
136
|
readonly vs: string;
|
|
137
|
+
// @ts-expect-error assigned in function called from constructor
|
|
128
138
|
readonly fs: string;
|
|
129
139
|
readonly pipelineFactory: PipelineFactory;
|
|
130
140
|
readonly shaderFactory: ShaderFactory;
|
|
@@ -156,7 +166,7 @@ export class Model {
|
|
|
156
166
|
/** Constant-valued attributes */
|
|
157
167
|
constantAttributes: Record<string, TypedArray> = {};
|
|
158
168
|
/** Bindings (textures, samplers, uniform buffers) */
|
|
159
|
-
bindings: Record<string, Binding> = {};
|
|
169
|
+
bindings: Record<string, Binding | AsyncTexture> = {};
|
|
160
170
|
/** Sets uniforms @deprecated Use uniform buffers and setBindings() for portability*/
|
|
161
171
|
uniforms: Record<string, UniformValue> = {};
|
|
162
172
|
|
|
@@ -174,8 +184,9 @@ export class Model {
|
|
|
174
184
|
pipeline: RenderPipeline;
|
|
175
185
|
|
|
176
186
|
/** ShaderInputs instance */
|
|
187
|
+
// @ts-expect-error Assigned in function called by constructor
|
|
177
188
|
shaderInputs: ShaderInputs;
|
|
178
|
-
|
|
189
|
+
// @ts-expect-error Assigned in function called by constructor
|
|
179
190
|
_uniformStore: UniformStore;
|
|
180
191
|
|
|
181
192
|
_attributeInfos: Record<string, AttributeInfo> = {};
|
|
@@ -202,6 +213,7 @@ export class Model {
|
|
|
202
213
|
const moduleMap = Object.fromEntries(
|
|
203
214
|
this.props.modules?.map(module => [module.name, module]) || []
|
|
204
215
|
);
|
|
216
|
+
// @ts-expect-error Fix typings
|
|
205
217
|
this.setShaderInputs(props.shaderInputs || new ShaderInputs(moduleMap));
|
|
206
218
|
|
|
207
219
|
// Setup shader assembler
|
|
@@ -209,6 +221,7 @@ export class Model {
|
|
|
209
221
|
|
|
210
222
|
// Extract modules from shader inputs if not supplied
|
|
211
223
|
const modules =
|
|
224
|
+
// @ts-expect-error shaderInputs is assigned in setShaderInputs above.
|
|
212
225
|
(this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || [];
|
|
213
226
|
|
|
214
227
|
const isWebGPU = this.device.type === 'webgpu';
|
|
@@ -219,16 +232,17 @@ export class Model {
|
|
|
219
232
|
if (isWebGPU && this.props.source) {
|
|
220
233
|
// WGSL
|
|
221
234
|
this.props.shaderLayout ||= getShaderLayoutFromWGSL(this.props.source);
|
|
222
|
-
const {source, getUniforms} = this.props.shaderAssembler.
|
|
235
|
+
const {source, getUniforms} = this.props.shaderAssembler.assembleWGSLShader({
|
|
223
236
|
platformInfo,
|
|
224
237
|
...this.props,
|
|
225
238
|
modules
|
|
226
239
|
});
|
|
227
240
|
this.source = source;
|
|
241
|
+
// @ts-expect-error
|
|
228
242
|
this._getModuleUniforms = getUniforms;
|
|
229
243
|
} else {
|
|
230
244
|
// GLSL
|
|
231
|
-
const {vs, fs, getUniforms} = this.props.shaderAssembler.
|
|
245
|
+
const {vs, fs, getUniforms} = this.props.shaderAssembler.assembleGLSLShaderPair({
|
|
232
246
|
platformInfo,
|
|
233
247
|
...this.props,
|
|
234
248
|
modules
|
|
@@ -236,6 +250,7 @@ export class Model {
|
|
|
236
250
|
|
|
237
251
|
this.vs = vs;
|
|
238
252
|
this.fs = fs;
|
|
253
|
+
// @ts-expect-error
|
|
239
254
|
this._getModuleUniforms = getUniforms;
|
|
240
255
|
}
|
|
241
256
|
|
|
@@ -358,7 +373,11 @@ export class Model {
|
|
|
358
373
|
|
|
359
374
|
// Set pipeline state, we may be sharing a pipeline so we need to set all state on every draw
|
|
360
375
|
// Any caching needs to be done inside the pipeline functions
|
|
361
|
-
this
|
|
376
|
+
// TODO this is a busy initialized check for all bindings every frame
|
|
377
|
+
const syncBindings = this._getBindings();
|
|
378
|
+
this.pipeline.setBindings(syncBindings, {
|
|
379
|
+
disableWarnings: this.props.disableWarnings
|
|
380
|
+
});
|
|
362
381
|
if (!isObjectEmpty(this.uniforms)) {
|
|
363
382
|
this.pipeline.setUniformsWebGL(this.uniforms);
|
|
364
383
|
}
|
|
@@ -512,7 +531,7 @@ export class Model {
|
|
|
512
531
|
/**
|
|
513
532
|
* Sets bindings (textures, samplers, uniform buffers)
|
|
514
533
|
*/
|
|
515
|
-
setBindings(bindings: Record<string, Binding>): void {
|
|
534
|
+
setBindings(bindings: Record<string, Binding | AsyncTexture>): void {
|
|
516
535
|
Object.assign(this.bindings, bindings);
|
|
517
536
|
this.setNeedsRedraw('bindings');
|
|
518
537
|
}
|
|
@@ -625,6 +644,21 @@ export class Model {
|
|
|
625
644
|
|
|
626
645
|
// Internal methods
|
|
627
646
|
|
|
647
|
+
/** Get texture / texture view from any async textures */
|
|
648
|
+
_getBindings(): Record<string, Binding> {
|
|
649
|
+
// Extract actual textures from async textures. If not loaded, null
|
|
650
|
+
return Object.entries(this.bindings).reduce<Record<string, Binding>>((acc, [name, binding]) => {
|
|
651
|
+
if (binding instanceof AsyncTexture) {
|
|
652
|
+
if (binding.isReady) {
|
|
653
|
+
acc[name] = binding.texture;
|
|
654
|
+
}
|
|
655
|
+
} else {
|
|
656
|
+
acc[name] = binding;
|
|
657
|
+
}
|
|
658
|
+
return acc;
|
|
659
|
+
}, {});
|
|
660
|
+
}
|
|
661
|
+
|
|
628
662
|
/** Get the timestamp of the latest updated bound GPU memory resource (buffer/texture). */
|
|
629
663
|
_getBindingsUpdateTimestamp(): number {
|
|
630
664
|
let timestamp = 0;
|
|
@@ -633,6 +667,11 @@ export class Model {
|
|
|
633
667
|
timestamp = Math.max(timestamp, binding.texture.updateTimestamp);
|
|
634
668
|
} else if (binding instanceof Buffer || binding instanceof Texture) {
|
|
635
669
|
timestamp = Math.max(timestamp, binding.updateTimestamp);
|
|
670
|
+
} else if (binding instanceof AsyncTexture) {
|
|
671
|
+
timestamp = binding.texture
|
|
672
|
+
? Math.max(timestamp, binding.texture.updateTimestamp)
|
|
673
|
+
: // The texture will become available in the future
|
|
674
|
+
Infinity;
|
|
636
675
|
} else if (!(binding instanceof Sampler)) {
|
|
637
676
|
timestamp = Math.max(timestamp, binding.buffer.updateTimestamp);
|
|
638
677
|
}
|
|
@@ -712,6 +751,9 @@ export class Model {
|
|
|
712
751
|
bufferLayout: this.bufferLayout,
|
|
713
752
|
topology: this.topology,
|
|
714
753
|
parameters: this.parameters,
|
|
754
|
+
// TODO - why set bindings here when we reset them every frame?
|
|
755
|
+
// Should we expose a BindGroup abstraction?
|
|
756
|
+
bindings: this._getBindings(),
|
|
715
757
|
vs,
|
|
716
758
|
fs
|
|
717
759
|
});
|
|
@@ -787,13 +829,13 @@ export class Model {
|
|
|
787
829
|
_getAttributeDebugTable(): Record<string, Record<string, unknown>> {
|
|
788
830
|
const table: Record<string, Record<string, unknown>> = {};
|
|
789
831
|
for (const [name, attributeInfo] of Object.entries(this._attributeInfos)) {
|
|
832
|
+
const values = this.vertexArray.attributes[attributeInfo.location];
|
|
790
833
|
table[attributeInfo.location] = {
|
|
791
834
|
name,
|
|
792
835
|
type: attributeInfo.shaderType,
|
|
793
|
-
values:
|
|
794
|
-
this.
|
|
795
|
-
|
|
796
|
-
)
|
|
836
|
+
values: values
|
|
837
|
+
? this._getBufferOrConstantValues(values, attributeInfo.bufferDataType)
|
|
838
|
+
: 'null'
|
|
797
839
|
};
|
|
798
840
|
}
|
|
799
841
|
if (this.vertexArray.indexBuffer) {
|
|
@@ -854,3 +896,15 @@ function getAttributeNames(bufferLayout: BufferLayout): string[] {
|
|
|
854
896
|
? bufferLayout.attributes?.map(layout => layout.attribute)
|
|
855
897
|
: [bufferLayout.name];
|
|
856
898
|
}
|
|
899
|
+
|
|
900
|
+
/** Returns true if given object is empty, false otherwise. */
|
|
901
|
+
function isObjectEmpty(obj: object): boolean {
|
|
902
|
+
let isEmpty = true;
|
|
903
|
+
// @ts-ignore key is unused
|
|
904
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
905
|
+
for (const key in obj) {
|
|
906
|
+
isEmpty = false;
|
|
907
|
+
break;
|
|
908
|
+
}
|
|
909
|
+
return isEmpty;
|
|
910
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {UniformValue, Binding} from '@luma.gl/core';
|
|
6
|
+
import {isNumericArray} from '@math.gl/types';
|
|
7
|
+
|
|
8
|
+
export function isUniformValue(value: unknown): boolean {
|
|
9
|
+
return isNumericArray(value) !== null || typeof value === 'number' || typeof value === 'boolean';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type UniformsAndBindings = {
|
|
13
|
+
bindings: Record<string, Binding>;
|
|
14
|
+
uniforms: Record<string, UniformValue>;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function splitUniformsAndBindings(
|
|
18
|
+
uniforms: Record<string, Binding | UniformValue>
|
|
19
|
+
): UniformsAndBindings {
|
|
20
|
+
const result: UniformsAndBindings = {bindings: {}, uniforms: {}};
|
|
21
|
+
Object.keys(uniforms).forEach(name => {
|
|
22
|
+
const uniform = uniforms[name];
|
|
23
|
+
if (isUniformValue(uniform)) {
|
|
24
|
+
result.uniforms[name] = uniform as UniformValue;
|
|
25
|
+
} else {
|
|
26
|
+
result.bindings[name] = uniform as Binding;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
1
5
|
import {RenderPass} from '@luma.gl/core';
|
|
2
6
|
import {ScenegraphNode, ScenegraphNodeProps} from './scenegraph-node';
|
|
3
7
|
import {Model} from '../model/model';
|
|
@@ -28,10 +32,6 @@ export class ModelNode extends ScenegraphNode {
|
|
|
28
32
|
this.setProps(props);
|
|
29
33
|
}
|
|
30
34
|
|
|
31
|
-
override getBounds(): [number[], number[]] | null {
|
|
32
|
-
return this.bounds;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
35
|
override destroy(): void {
|
|
36
36
|
if (this.model) {
|
|
37
37
|
this.model.destroy();
|
|
@@ -42,8 +42,12 @@ export class ModelNode extends ScenegraphNode {
|
|
|
42
42
|
this.managedResources = [];
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
override getBounds(): [number[], number[]] | null {
|
|
46
|
+
return this.bounds;
|
|
47
|
+
}
|
|
48
|
+
|
|
45
49
|
// Expose model methods
|
|
46
|
-
draw(renderPass
|
|
50
|
+
draw(renderPass: RenderPass) {
|
|
47
51
|
// Return value indicates if something was actually drawn
|
|
48
52
|
return this.model.draw(renderPass);
|
|
49
53
|
}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {Vector3, Matrix4, NumericArray} from '@math.gl/core';
|
|
6
|
+
import {uid} from '../utils/uid';
|
|
3
7
|
|
|
4
8
|
/** Properties for creating a new Scenegraph */
|
|
5
9
|
export type ScenegraphNodeProps = {
|
|
6
10
|
id?: string;
|
|
7
11
|
/** whether to display the object at all */
|
|
8
12
|
display?: boolean;
|
|
9
|
-
matrix?:
|
|
10
|
-
position?:
|
|
11
|
-
rotation?:
|
|
12
|
-
scale?:
|
|
13
|
+
matrix?: NumericArray;
|
|
14
|
+
position?: NumericArray;
|
|
15
|
+
rotation?: NumericArray;
|
|
16
|
+
scale?: NumericArray;
|
|
13
17
|
update?: boolean;
|
|
14
18
|
};
|
|
15
19
|
|
|
@@ -53,19 +57,19 @@ export class ScenegraphNode {
|
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
setPosition(position: any): this {
|
|
56
|
-
assert(position.length === 3, 'setPosition requires vector argument');
|
|
60
|
+
// assert(position.length === 3, 'setPosition requires vector argument');
|
|
57
61
|
this.position = position;
|
|
58
62
|
return this;
|
|
59
63
|
}
|
|
60
64
|
|
|
61
65
|
setRotation(rotation: any): this {
|
|
62
|
-
assert(rotation.length === 3, 'setRotation requires vector argument');
|
|
66
|
+
// assert(rotation.length === 3, 'setRotation requires vector argument');
|
|
63
67
|
this.rotation = rotation;
|
|
64
68
|
return this;
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
setScale(scale: any): this {
|
|
68
|
-
assert(scale.length === 3, 'setScale requires vector argument');
|
|
72
|
+
// assert(scale.length === 3, 'setScale requires vector argument');
|
|
69
73
|
this.scale = scale;
|
|
70
74
|
return this;
|
|
71
75
|
}
|
|
@@ -140,7 +144,7 @@ export class ScenegraphNode {
|
|
|
140
144
|
} {
|
|
141
145
|
// TODO - solve multiple class problem
|
|
142
146
|
// assert(viewMatrix instanceof Matrix4);
|
|
143
|
-
assert(viewMatrix);
|
|
147
|
+
// assert(viewMatrix);
|
|
144
148
|
modelMatrix = modelMatrix || this.matrix;
|
|
145
149
|
const worldMatrix = new Matrix4(viewMatrix).multiplyRight(modelMatrix);
|
|
146
150
|
const worldInverse = worldMatrix.invert();
|
|
@@ -180,9 +184,9 @@ export class ScenegraphNode {
|
|
|
180
184
|
*/
|
|
181
185
|
|
|
182
186
|
_setScenegraphNodeProps(props: ScenegraphNodeProps): void {
|
|
183
|
-
if ('display' in props) {
|
|
184
|
-
|
|
185
|
-
}
|
|
187
|
+
// if ('display' in props) {
|
|
188
|
+
// this.display = props.display;
|
|
189
|
+
// }
|
|
186
190
|
|
|
187
191
|
if ('position' in props) {
|
|
188
192
|
this.setPosition(props.position);
|
package/src/shader-inputs.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import type {UniformValue, Texture, Sampler} from '@luma.gl/core';
|
|
6
6
|
import {log} from '@luma.gl/core';
|
|
7
7
|
// import type {ShaderUniformType, UniformValue, UniformFormat, UniformInfoDevice, Texture, Sampler} from '@luma.gl/core';
|
|
8
|
-
import {
|
|
8
|
+
import {getShaderModuleDependencies, ShaderModule} from '@luma.gl/shadertools';
|
|
9
9
|
|
|
10
10
|
/** Minimal ShaderModule subset, we don't need shader code etc */
|
|
11
11
|
export type ShaderModuleInputs<
|
|
@@ -46,6 +46,7 @@ export class ShaderInputs<
|
|
|
46
46
|
* The map of modules
|
|
47
47
|
* @todo should should this include the resolved dependencies?
|
|
48
48
|
*/
|
|
49
|
+
// @ts-expect-error Fix typings
|
|
49
50
|
modules: Readonly<{[P in keyof ShaderPropsT]: ShaderModuleInputs<ShaderPropsT[P]>}>;
|
|
50
51
|
|
|
51
52
|
/** Stores the uniform values for each module */
|
|
@@ -53,15 +54,16 @@ export class ShaderInputs<
|
|
|
53
54
|
/** Stores the uniform bindings for each module */
|
|
54
55
|
moduleBindings: Record<keyof ShaderPropsT, Record<string, Texture | Sampler>>;
|
|
55
56
|
/** Tracks if uniforms have changed */
|
|
56
|
-
moduleUniformsChanged: Record<keyof ShaderPropsT, false | string>;
|
|
57
|
+
// moduleUniformsChanged: Record<keyof ShaderPropsT, false | string>;
|
|
57
58
|
|
|
58
59
|
/**
|
|
59
60
|
* Create a new UniformStore instance
|
|
60
61
|
* @param modules
|
|
61
62
|
*/
|
|
63
|
+
// @ts-expect-error Fix typings
|
|
62
64
|
constructor(modules: {[P in keyof ShaderPropsT]: ShaderModuleInputs<ShaderPropsT[P]>}) {
|
|
63
65
|
// TODO - get all dependencies from modules
|
|
64
|
-
const allModules =
|
|
66
|
+
const allModules = getShaderModuleDependencies(Object.values(modules));
|
|
65
67
|
log.log(
|
|
66
68
|
1,
|
|
67
69
|
'Creating ShaderInputs with modules',
|
|
@@ -92,7 +94,7 @@ export class ShaderInputs<
|
|
|
92
94
|
setProps(props: Partial<{[P in keyof ShaderPropsT]?: Partial<ShaderPropsT[P]>}>): void {
|
|
93
95
|
for (const name of Object.keys(props)) {
|
|
94
96
|
const moduleName = name as keyof ShaderPropsT;
|
|
95
|
-
const moduleProps = props[moduleName];
|
|
97
|
+
const moduleProps = props[moduleName] || {};
|
|
96
98
|
const module = this.modules[moduleName];
|
|
97
99
|
if (!module) {
|
|
98
100
|
// Ignore props for unregistered modules
|
|
@@ -105,7 +107,7 @@ export class ShaderInputs<
|
|
|
105
107
|
module.getUniforms?.(moduleProps, this.moduleUniforms[moduleName]) || (moduleProps as any);
|
|
106
108
|
// console.error(uniforms)
|
|
107
109
|
this.moduleUniforms[moduleName] = {...oldUniforms, ...uniforms};
|
|
108
|
-
// this.moduleUniformsChanged ||= moduleName;
|
|
110
|
+
// // this.moduleUniformsChanged ||= moduleName;
|
|
109
111
|
|
|
110
112
|
// console.log(`setProps(${String(moduleName)}`, moduleName, this.moduleUniforms[moduleName])
|
|
111
113
|
|
|
@@ -124,7 +126,7 @@ export class ShaderInputs<
|
|
|
124
126
|
* Return the map of modules
|
|
125
127
|
* @todo should should this include the resolved dependencies?
|
|
126
128
|
*/
|
|
127
|
-
getModules():
|
|
129
|
+
getModules(): ShaderModule[] {
|
|
128
130
|
return Object.values(this.modules);
|
|
129
131
|
}
|
|
130
132
|
|
|
@@ -2,14 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
Device,
|
|
7
|
-
Buffer,
|
|
8
|
-
BufferRange,
|
|
9
|
-
TransformFeedback,
|
|
10
|
-
assert,
|
|
11
|
-
RenderPassProps
|
|
12
|
-
} from '@luma.gl/core';
|
|
5
|
+
import {Device, Buffer, BufferRange, TransformFeedback, RenderPassProps} from '@luma.gl/core';
|
|
13
6
|
import {getPassthroughFS} from '@luma.gl/shadertools';
|
|
14
7
|
import {Model} from '../model/model';
|
|
15
8
|
import type {ModelProps} from '../model/model';
|
|
@@ -38,7 +31,9 @@ export class BufferTransform {
|
|
|
38
31
|
}
|
|
39
32
|
|
|
40
33
|
constructor(device: Device, props: BufferTransformProps = Model.defaultProps) {
|
|
41
|
-
|
|
34
|
+
if (!BufferTransform.isSupported(device)) {
|
|
35
|
+
throw new Error('BufferTransform not yet implemented on WebGPU');
|
|
36
|
+
}
|
|
42
37
|
|
|
43
38
|
this.device = device;
|
|
44
39
|
|
|
@@ -51,6 +46,7 @@ export class BufferTransform {
|
|
|
51
46
|
|
|
52
47
|
this.transformFeedback = this.device.createTransformFeedback({
|
|
53
48
|
layout: this.model.pipeline.shaderLayout,
|
|
49
|
+
// @ts-expect-error TODO
|
|
54
50
|
buffers: props.feedbackBuffers
|
|
55
51
|
});
|
|
56
52
|
|
|
@@ -93,6 +89,9 @@ export class BufferTransform {
|
|
|
93
89
|
|
|
94
90
|
readAsync(varyingName: string): Promise<Uint8Array> {
|
|
95
91
|
const result = this.getBuffer(varyingName);
|
|
92
|
+
if (!result) {
|
|
93
|
+
throw new Error('BufferTransform#getBuffer');
|
|
94
|
+
}
|
|
96
95
|
if (result instanceof Buffer) {
|
|
97
96
|
return result.readAsync();
|
|
98
97
|
}
|
|
@@ -111,7 +111,7 @@ export class TextureTransform {
|
|
|
111
111
|
return targetTexture;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
getFramebuffer(): Framebuffer {
|
|
114
|
+
getFramebuffer(): Framebuffer | undefined {
|
|
115
115
|
const currentResources = this.bindings[this.currentIndex];
|
|
116
116
|
return currentResources.framebuffer;
|
|
117
117
|
}
|
|
@@ -134,6 +134,7 @@ export class TextureTransform {
|
|
|
134
134
|
binding = {
|
|
135
135
|
sourceBuffers: {},
|
|
136
136
|
sourceTextures: {},
|
|
137
|
+
// @ts-expect-error
|
|
137
138
|
targetTexture: null
|
|
138
139
|
};
|
|
139
140
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Fast partial deep equal for prop.
|
|
7
|
+
*
|
|
8
|
+
* @param a Prop
|
|
9
|
+
* @param b Prop to compare against `a`
|
|
10
|
+
* @param depth Depth to which to recurse in nested Objects/Arrays. Use 0 (default) for shallow comparison, -1 for infinite depth
|
|
11
|
+
*/
|
|
12
|
+
/* eslint-disable complexity */
|
|
13
|
+
export function deepEqual(a: any, b: any, depth: number): boolean {
|
|
14
|
+
if (a === b) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (!depth || !a || !b) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
if (Array.isArray(a)) {
|
|
21
|
+
if (!Array.isArray(b) || a.length !== b.length) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
for (let i = 0; i < a.length; i++) {
|
|
25
|
+
if (!deepEqual(a[i], b[i], depth - 1)) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
if (Array.isArray(b)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
if (typeof a === 'object' && typeof b === 'object') {
|
|
35
|
+
const aKeys = Object.keys(a);
|
|
36
|
+
const bKeys = Object.keys(b);
|
|
37
|
+
if (aKeys.length !== bKeys.length) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
for (const key of aKeys) {
|
|
41
|
+
if (!b.hasOwnProperty(key)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (!deepEqual(a[key], b[key], depth - 1)) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
package/src/utils/uid.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
const uidCounters: Record<string, number> = {};
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Returns a UID.
|
|
9
|
+
* @param id= - Identifier base name
|
|
10
|
+
* @return uid
|
|
11
|
+
**/
|
|
12
|
+
export function uid(id: string = 'id'): string {
|
|
13
|
+
uidCounters[id] = uidCounters[id] || 1;
|
|
14
|
+
const count = uidCounters[id]++;
|
|
15
|
+
return `${id}-${count}`;
|
|
16
|
+
}
|