@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.
Files changed (139) hide show
  1. package/dist/animation/key-frames.d.ts.map +1 -1
  2. package/dist/animation/key-frames.js +3 -0
  3. package/dist/animation-loop/animation-loop-template.d.ts.map +1 -1
  4. package/dist/animation-loop/animation-loop-template.js +3 -0
  5. package/dist/animation-loop/animation-loop.d.ts +1 -1
  6. package/dist/animation-loop/animation-loop.d.ts.map +1 -1
  7. package/dist/animation-loop/animation-loop.js +5 -4
  8. package/dist/animation-loop/animation-props.d.ts.map +1 -1
  9. package/dist/animation-loop/animation-props.js +3 -0
  10. package/dist/animation-loop/make-animation-loop.js +1 -1
  11. package/dist/animation-loop/request-animation-frame.d.ts +3 -0
  12. package/dist/animation-loop/request-animation-frame.d.ts.map +1 -0
  13. package/dist/animation-loop/request-animation-frame.js +16 -0
  14. package/dist/application-utils/load-file.d.ts +22 -0
  15. package/dist/application-utils/load-file.d.ts.map +1 -0
  16. package/dist/application-utils/load-file.js +42 -0
  17. package/dist/application-utils/random.d.ts +3 -0
  18. package/dist/application-utils/random.d.ts.map +1 -0
  19. package/dist/application-utils/random.js +16 -0
  20. package/dist/async-texture/async-texture.d.ts +50 -0
  21. package/dist/async-texture/async-texture.d.ts.map +1 -0
  22. package/dist/async-texture/async-texture.js +83 -0
  23. package/dist/computation.d.ts +4 -3
  24. package/dist/computation.d.ts.map +1 -1
  25. package/dist/computation.js +14 -6
  26. package/dist/debug/copy-texture-to-image.d.ts.map +1 -1
  27. package/dist/debug/copy-texture-to-image.js +4 -1
  28. package/dist/debug/debug-framebuffer.d.ts.map +1 -1
  29. package/dist/debug/debug-framebuffer.js +17 -12
  30. package/dist/debug/pixel-data-utils.d.ts +1 -1
  31. package/dist/dist.dev.js +728 -555
  32. package/dist/dist.min.js +57 -41
  33. package/dist/geometries/cone-geometry.d.ts.map +1 -1
  34. package/dist/geometries/cone-geometry.js +4 -1
  35. package/dist/geometries/cube-geometry.d.ts.map +1 -1
  36. package/dist/geometries/cube-geometry.js +4 -1
  37. package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
  38. package/dist/geometries/cylinder-geometry.js +4 -1
  39. package/dist/geometries/ico-sphere-geometry.d.ts.map +1 -1
  40. package/dist/geometries/ico-sphere-geometry.js +4 -1
  41. package/dist/geometries/plane-geometry.d.ts.map +1 -1
  42. package/dist/geometries/plane-geometry.js +4 -1
  43. package/dist/geometries/sphere-geometry.d.ts.map +1 -1
  44. package/dist/geometries/sphere-geometry.js +4 -1
  45. package/dist/geometries/truncated-cone-geometry.d.ts.map +1 -1
  46. package/dist/geometries/truncated-cone-geometry.js +4 -1
  47. package/dist/geometry/geometry-table.d.ts +2 -1
  48. package/dist/geometry/geometry-table.d.ts.map +1 -1
  49. package/dist/geometry/geometry-utils.d.ts.map +1 -1
  50. package/dist/geometry/geometry-utils.js +3 -1
  51. package/dist/geometry/geometry.d.ts +5 -4
  52. package/dist/geometry/geometry.d.ts.map +1 -1
  53. package/dist/geometry/geometry.js +9 -5
  54. package/dist/geometry/gpu-geometry.d.ts +1 -1
  55. package/dist/geometry/gpu-geometry.d.ts.map +1 -1
  56. package/dist/geometry/gpu-geometry.js +18 -6
  57. package/dist/geometry/gpu-table.js +3 -0
  58. package/dist/index.cjs +514 -258
  59. package/dist/index.cjs.map +4 -4
  60. package/dist/index.d.ts +6 -0
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +8 -1
  63. package/dist/lib/clip-space.d.ts.map +1 -1
  64. package/dist/lib/clip-space.js +10 -7
  65. package/dist/lib/pipeline-factory.d.ts +3 -2
  66. package/dist/lib/pipeline-factory.d.ts.map +1 -1
  67. package/dist/lib/pipeline-factory.js +12 -8
  68. package/dist/lib/shader-factory.d.ts +3 -2
  69. package/dist/lib/shader-factory.d.ts.map +1 -1
  70. package/dist/lib/shader-factory.js +11 -4
  71. package/dist/model/model.d.ts +10 -6
  72. package/dist/model/model.d.ts.map +1 -1
  73. package/dist/model/model.js +64 -8
  74. package/dist/model/split-uniforms-and-bindings.d.ts +9 -0
  75. package/dist/model/split-uniforms-and-bindings.d.ts.map +1 -0
  76. package/dist/model/split-uniforms-and-bindings.js +20 -0
  77. package/dist/scenegraph/group-node.d.ts +1 -1
  78. package/dist/scenegraph/group-node.d.ts.map +1 -1
  79. package/dist/scenegraph/group-node.js +3 -0
  80. package/dist/scenegraph/model-node.d.ts +2 -2
  81. package/dist/scenegraph/model-node.d.ts.map +1 -1
  82. package/dist/scenegraph/model-node.js +6 -3
  83. package/dist/scenegraph/scenegraph-node.d.ts +5 -6
  84. package/dist/scenegraph/scenegraph-node.d.ts.map +1 -1
  85. package/dist/scenegraph/scenegraph-node.js +11 -8
  86. package/dist/shader-inputs.d.ts +21 -8
  87. package/dist/shader-inputs.d.ts.map +1 -1
  88. package/dist/shader-inputs.js +11 -6
  89. package/dist/transform/buffer-transform.d.ts.map +1 -1
  90. package/dist/transform/buffer-transform.js +8 -2
  91. package/dist/transform/texture-transform.d.ts +2 -2
  92. package/dist/transform/texture-transform.d.ts.map +1 -1
  93. package/dist/transform/texture-transform.js +1 -0
  94. package/dist/utils/deep-equal.d.ts +9 -0
  95. package/dist/utils/deep-equal.d.ts.map +1 -0
  96. package/dist/utils/deep-equal.js +50 -0
  97. package/dist/utils/uid.d.ts +7 -0
  98. package/dist/utils/uid.d.ts.map +1 -0
  99. package/dist/utils/uid.js +14 -0
  100. package/package.json +7 -6
  101. package/src/animation/key-frames.ts +4 -0
  102. package/src/animation-loop/animation-loop-template.ts +4 -0
  103. package/src/animation-loop/animation-loop.ts +6 -4
  104. package/src/animation-loop/animation-props.ts +4 -0
  105. package/src/animation-loop/make-animation-loop.ts +1 -1
  106. package/src/animation-loop/request-animation-frame.ts +19 -0
  107. package/src/application-utils/load-file.ts +51 -0
  108. package/src/application-utils/random.ts +18 -0
  109. package/src/async-texture/async-texture.ts +146 -0
  110. package/src/computation.ts +17 -9
  111. package/src/debug/copy-texture-to-image.ts +4 -1
  112. package/src/debug/debug-framebuffer.ts +18 -12
  113. package/src/debug/pixel-data-utils.ts +1 -1
  114. package/src/geometries/cone-geometry.ts +5 -1
  115. package/src/geometries/cube-geometry.ts +5 -1
  116. package/src/geometries/cylinder-geometry.ts +5 -1
  117. package/src/geometries/ico-sphere-geometry.ts +5 -1
  118. package/src/geometries/plane-geometry.ts +5 -1
  119. package/src/geometries/sphere-geometry.ts +5 -1
  120. package/src/geometries/truncated-cone-geometry.ts +5 -1
  121. package/src/geometry/geometry-table.ts +2 -1
  122. package/src/geometry/geometry-utils.ts +3 -1
  123. package/src/geometry/geometry.ts +16 -19
  124. package/src/geometry/gpu-geometry.ts +20 -14
  125. package/src/geometry/gpu-table.ts +4 -0
  126. package/src/index.ts +16 -0
  127. package/src/lib/clip-space.ts +6 -2
  128. package/src/lib/pipeline-factory.ts +17 -16
  129. package/src/lib/shader-factory.ts +13 -6
  130. package/src/model/model.ts +70 -17
  131. package/src/model/split-uniforms-and-bindings.ts +31 -0
  132. package/src/scenegraph/group-node.ts +4 -0
  133. package/src/scenegraph/model-node.ts +9 -5
  134. package/src/scenegraph/scenegraph-node.ts +17 -13
  135. package/src/shader-inputs.ts +47 -18
  136. package/src/transform/buffer-transform.ts +8 -9
  137. package/src/transform/texture-transform.ts +2 -1
  138. package/src/utils/deep-equal.ts +51 -0
  139. 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
+ }
@@ -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, uid, isNumberArray} from '@luma.gl/core';
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 "program". @note May be recreated if parameters change */
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
- this.setShaderInputs(props.shaderInputs || new ShaderInputs(moduleMap));
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.assembleShader({
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 !isNumberArray(uniform) && typeof uniform !== 'number' && typeof uniform !== 'boolean';
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.createImageData(width, height);
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.createImageData(fbo.width, fbo.height);
58
- // Full map
59
- const offset = 0;
60
- // if (color.some((v) => v > 0)) {
61
- // console.error('THERE IS NON-ZERO DATA IN THE FBO!');
62
- // }
63
- for (let i = 0; i < color.length; i += 4) {
64
- imageData.data[offset + i + 0] = color[i + 0] * rgbaScale;
65
- imageData.data[offset + i + 1] = color[i + 1] * rgbaScale;
66
- imageData.data[offset + i + 2] = color[i + 2] * rgbaScale;
67
- imageData.data[offset + i + 3] = opaque ? 255 : color[i + 3] * rgbaScale;
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
  }
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {TypedArray} from '@luma.gl/core';
5
+ import {TypedArray} from '@math.gl/core';
6
6
 
7
7
  /**
8
8
  * Flip rows (can be used on arrays returned from `Framebuffer.readPixels`)
@@ -1,5 +1,9 @@
1
- import {uid} from '@luma.gl/core';
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
- import {uid} from '@luma.gl/core';
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
- import {uid} from '@luma.gl/core';
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
- import {uid} from '@luma.gl/core';
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
- import {uid} from '@luma.gl/core';
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
- import {uid} from '@luma.gl/core';
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;
@@ -1,5 +1,9 @@
1
- import {uid} from '@luma.gl/core';
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
  const INDEX_OFFSETS = {
5
9
  x: [2, 0, 1],
@@ -2,7 +2,8 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import type {TypedArray, VertexFormat} from '@luma.gl/core';
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 = {
@@ -1,4 +1,6 @@
1
- // import type {Geometry} from './geometry';
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
2
4
 
3
5
  export function unpackIndexedGeometry(geometry: any) {
4
6
  const {indices, attributes} = geometry;
@@ -2,23 +2,17 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import type {PrimitiveTopology, TypedArray} from '@luma.gl/core';
6
- import {uid, assert} from '@luma.gl/core';
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?: Record<string, GeometryAttribute | TypedArray>;
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
- assert(
75
- ArrayBuffer.isView(attribute.value),
76
- `${this._print(attributeName)}: must be typed array or object with value as typed array`
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
- assert(!this.indices);
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: GeometryAttribute): number {
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, uid, assert, getVertexFormatFromAttribute} from '@luma.gl/core';
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
- assert(this.indices.usage === Buffer.INDEX);
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
- attributes[name] = device.createBuffer({data: attribute.value, id: `${attributeName}-buffer`});
125
- const {value, size, normalized} = attribute;
126
- bufferLayout.push({name, format: getVertexFormatFromAttribute(value, size, normalized)});
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);
@@ -1,3 +1,7 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
1
5
  /*
2
6
  export function getAttributeLayoutsFromGeometry(geometry: Geometry) {
3
7
  const layouts: Record<string, {}> = {};
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';
@@ -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, glsl} from '@luma.gl/core';
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
- cache[hash].pipeline.destroy();
84
- delete cache[hash];
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