@luma.gl/engine 9.0.0-alpha.9 → 9.0.0-beta.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 (187) hide show
  1. package/LICENSE +3 -1
  2. package/dist/animation/key-frames.d.ts +1 -1
  3. package/dist/animation/key-frames.d.ts.map +1 -1
  4. package/dist/animation/key-frames.js +51 -72
  5. package/dist/animation/timeline.d.ts +8 -8
  6. package/dist/animation/timeline.d.ts.map +1 -1
  7. package/dist/animation/timeline.js +95 -131
  8. package/dist/animation-loop/animation-loop-template.d.ts +23 -0
  9. package/dist/animation-loop/animation-loop-template.d.ts.map +1 -0
  10. package/dist/animation-loop/animation-loop-template.js +21 -0
  11. package/dist/{lib → animation-loop}/animation-loop.d.ts +31 -23
  12. package/dist/animation-loop/animation-loop.d.ts.map +1 -0
  13. package/dist/animation-loop/animation-loop.js +442 -0
  14. package/dist/{lib → animation-loop}/animation-props.d.ts +4 -5
  15. package/dist/animation-loop/animation-props.d.ts.map +1 -0
  16. package/dist/animation-loop/animation-props.js +1 -0
  17. package/dist/animation-loop/make-animation-loop.d.ts +6 -0
  18. package/dist/animation-loop/make-animation-loop.d.ts.map +1 -0
  19. package/dist/animation-loop/make-animation-loop.js +32 -0
  20. package/dist/computation.d.ts +95 -0
  21. package/dist/computation.d.ts.map +1 -0
  22. package/dist/computation.js +248 -0
  23. package/dist/debug/copy-texture-to-image.d.ts +26 -0
  24. package/dist/debug/copy-texture-to-image.d.ts.map +1 -0
  25. package/dist/debug/copy-texture-to-image.js +43 -0
  26. package/dist/debug/debug-framebuffer.d.ts +11 -0
  27. package/dist/debug/debug-framebuffer.d.ts.map +1 -0
  28. package/dist/debug/debug-framebuffer.js +46 -0
  29. package/dist/debug/debug-shader-layout.d.ts +9 -0
  30. package/dist/debug/debug-shader-layout.d.ts.map +1 -0
  31. package/dist/debug/debug-shader-layout.js +27 -0
  32. package/dist/debug/pixel-data-utils.d.ts +24 -0
  33. package/dist/debug/pixel-data-utils.d.ts.map +1 -0
  34. package/dist/debug/pixel-data-utils.js +39 -0
  35. package/dist/dist.dev.js +9592 -0
  36. package/dist/dist.min.js +102 -0
  37. package/dist/geometries/cone-geometry.d.ts +2 -2
  38. package/dist/geometries/cone-geometry.d.ts.map +1 -1
  39. package/dist/geometries/cone-geometry.js +13 -18
  40. package/dist/geometries/cube-geometry.d.ts +2 -2
  41. package/dist/geometries/cube-geometry.d.ts.map +1 -1
  42. package/dist/geometries/cube-geometry.js +192 -57
  43. package/dist/geometries/cylinder-geometry.d.ts +2 -2
  44. package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
  45. package/dist/geometries/cylinder-geometry.js +11 -15
  46. package/dist/geometries/ico-sphere-geometry.d.ts +2 -2
  47. package/dist/geometries/ico-sphere-geometry.d.ts.map +1 -1
  48. package/dist/geometries/ico-sphere-geometry.js +143 -171
  49. package/dist/geometries/plane-geometry.d.ts +2 -2
  50. package/dist/geometries/plane-geometry.d.ts.map +1 -1
  51. package/dist/geometries/plane-geometry.js +95 -122
  52. package/dist/geometries/sphere-geometry.d.ts +2 -2
  53. package/dist/geometries/sphere-geometry.d.ts.map +1 -1
  54. package/dist/geometries/sphere-geometry.js +78 -101
  55. package/dist/geometries/truncated-cone-geometry.d.ts +2 -4
  56. package/dist/geometries/truncated-cone-geometry.d.ts.map +1 -1
  57. package/dist/geometries/truncated-cone-geometry.js +100 -134
  58. package/dist/geometry/geometry-table.d.ts +2 -2
  59. package/dist/geometry/geometry-table.d.ts.map +1 -1
  60. package/dist/geometry/geometry-table.js +3 -1
  61. package/dist/geometry/geometry-utils.d.ts.map +1 -1
  62. package/dist/geometry/geometry-utils.js +35 -41
  63. package/dist/geometry/geometry.d.ts +43 -43
  64. package/dist/geometry/geometry.d.ts.map +1 -1
  65. package/dist/geometry/geometry.js +82 -139
  66. package/dist/geometry/gpu-geometry.d.ts +37 -0
  67. package/dist/geometry/gpu-geometry.d.ts.map +1 -0
  68. package/dist/geometry/gpu-geometry.js +90 -0
  69. package/dist/geometry/gpu-table.d.ts +1 -0
  70. package/dist/geometry/gpu-table.d.ts.map +1 -0
  71. package/dist/geometry/gpu-table.js +42 -0
  72. package/dist/index.cjs +3444 -0
  73. package/dist/index.cjs.map +7 -0
  74. package/dist/index.d.ts +43 -24
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +29 -15
  77. package/dist/lib/clip-space.d.ts +8 -0
  78. package/dist/lib/clip-space.d.ts.map +1 -1
  79. package/dist/lib/clip-space.js +43 -2
  80. package/dist/lib/pipeline-factory.d.ts +17 -51
  81. package/dist/lib/pipeline-factory.d.ts.map +1 -1
  82. package/dist/lib/pipeline-factory.js +84 -209
  83. package/dist/lib/shader-factory.d.ts +17 -0
  84. package/dist/lib/shader-factory.d.ts.map +1 -0
  85. package/dist/lib/shader-factory.js +46 -0
  86. package/dist/model/model.d.ts +219 -0
  87. package/dist/model/model.d.ts.map +1 -0
  88. package/dist/model/model.js +659 -0
  89. package/dist/scenegraph/group-node.d.ts +21 -0
  90. package/dist/scenegraph/group-node.d.ts.map +1 -0
  91. package/dist/scenegraph/group-node.js +84 -0
  92. package/dist/scenegraph/model-node.d.ts +18 -0
  93. package/dist/scenegraph/model-node.d.ts.map +1 -0
  94. package/dist/scenegraph/model-node.js +35 -0
  95. package/dist/scenegraph/scenegraph-node.d.ts +56 -0
  96. package/dist/scenegraph/scenegraph-node.d.ts.map +1 -0
  97. package/dist/scenegraph/scenegraph-node.js +153 -0
  98. package/dist/shader-inputs.d.ts +63 -0
  99. package/dist/shader-inputs.d.ts.map +1 -0
  100. package/dist/shader-inputs.js +107 -0
  101. package/dist/transform/buffer-transform.d.ts +35 -0
  102. package/dist/transform/buffer-transform.d.ts.map +1 -0
  103. package/dist/transform/buffer-transform.js +70 -0
  104. package/dist/transform/texture-transform.d.ts +57 -0
  105. package/dist/transform/texture-transform.d.ts.map +1 -0
  106. package/dist/transform/texture-transform.js +117 -0
  107. package/dist.min.js +25 -0
  108. package/package.json +24 -14
  109. package/src/animation/timeline.ts +35 -34
  110. package/src/animation-loop/animation-loop-template.ts +25 -0
  111. package/src/{lib → animation-loop}/animation-loop.ts +114 -93
  112. package/src/{lib → animation-loop}/animation-props.ts +2 -2
  113. package/src/animation-loop/make-animation-loop.ts +53 -0
  114. package/src/computation.ts +346 -0
  115. package/src/debug/copy-texture-to-image.ts +70 -0
  116. package/src/debug/debug-framebuffer.ts +70 -0
  117. package/src/debug/debug-shader-layout.ts +38 -0
  118. package/src/debug/pixel-data-utils.ts +54 -0
  119. package/src/geometries/cone-geometry.ts +1 -1
  120. package/src/geometries/cube-geometry.ts +62 -56
  121. package/src/geometries/cylinder-geometry.ts +2 -2
  122. package/src/geometries/ico-sphere-geometry.ts +6 -5
  123. package/src/geometries/plane-geometry.ts +5 -4
  124. package/src/geometries/sphere-geometry.ts +4 -3
  125. package/src/geometries/truncated-cone-geometry.ts +6 -14
  126. package/src/geometry/geometry-table.ts +10 -7
  127. package/src/geometry/geometry-utils.ts +19 -3
  128. package/src/geometry/geometry.ts +68 -110
  129. package/src/geometry/gpu-geometry.ts +132 -0
  130. package/src/geometry/gpu-table.ts +41 -0
  131. package/src/index.ts +37 -10
  132. package/src/lib/clip-space.ts +32 -34
  133. package/src/lib/pipeline-factory.ts +83 -193
  134. package/src/lib/shader-factory.ts +57 -0
  135. package/src/model/model.ts +835 -0
  136. package/src/scenegraph/group-node.ts +107 -0
  137. package/src/scenegraph/model-node.ts +50 -0
  138. package/src/scenegraph/scenegraph-node.ts +204 -0
  139. package/src/shader-inputs.ts +157 -0
  140. package/src/transform/buffer-transform.ts +102 -0
  141. package/src/transform/texture-transform.ts +168 -0
  142. package/dist/animation/key-frames.js.map +0 -1
  143. package/dist/animation/timeline.js.map +0 -1
  144. package/dist/bundle.d.ts +0 -2
  145. package/dist/bundle.d.ts.map +0 -1
  146. package/dist/bundle.js +0 -5
  147. package/dist/bundle.js.map +0 -1
  148. package/dist/geometries/cone-geometry.js.map +0 -1
  149. package/dist/geometries/cube-geometry.js.map +0 -1
  150. package/dist/geometries/cylinder-geometry.js.map +0 -1
  151. package/dist/geometries/ico-sphere-geometry.js.map +0 -1
  152. package/dist/geometries/plane-geometry.js.map +0 -1
  153. package/dist/geometries/sphere-geometry.js.map +0 -1
  154. package/dist/geometries/truncated-cone-geometry.js.map +0 -1
  155. package/dist/geometry/geometry-table.js.map +0 -1
  156. package/dist/geometry/geometry-utils.js.map +0 -1
  157. package/dist/geometry/geometry.js.map +0 -1
  158. package/dist/geometry/primitive-utils.d.ts +0 -1
  159. package/dist/geometry/primitive-utils.d.ts.map +0 -1
  160. package/dist/geometry/primitive-utils.js +0 -2
  161. package/dist/geometry/primitive-utils.js.map +0 -1
  162. package/dist/index.js.map +0 -1
  163. package/dist/lib/animation-loop.d.ts.map +0 -1
  164. package/dist/lib/animation-loop.js +0 -480
  165. package/dist/lib/animation-loop.js.map +0 -1
  166. package/dist/lib/animation-props.d.ts.map +0 -1
  167. package/dist/lib/animation-props.js +0 -2
  168. package/dist/lib/animation-props.js.map +0 -1
  169. package/dist/lib/clip-space.js.map +0 -1
  170. package/dist/lib/model-utils.d.ts +0 -5
  171. package/dist/lib/model-utils.d.ts.map +0 -1
  172. package/dist/lib/model-utils.js +0 -45
  173. package/dist/lib/model-utils.js.map +0 -1
  174. package/dist/lib/model.d.ts +0 -41
  175. package/dist/lib/model.d.ts.map +0 -1
  176. package/dist/lib/model.js +0 -182
  177. package/dist/lib/model.js.map +0 -1
  178. package/dist/lib/pipeline-factory.js.map +0 -1
  179. package/dist/lib/render-loop.d.ts +0 -14
  180. package/dist/lib/render-loop.d.ts.map +0 -1
  181. package/dist/lib/render-loop.js +0 -49
  182. package/dist/lib/render-loop.js.map +0 -1
  183. package/src/bundle.ts +0 -4
  184. package/src/geometry/primitive-utils.ts +0 -30
  185. package/src/lib/model-utils.ts +0 -124
  186. package/src/lib/model.ts +0 -183
  187. package/src/lib/render-loop.ts +0 -58
package/dist/index.cjs ADDED
@@ -0,0 +1,3444 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var __publicField = (obj, key, value) => {
21
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
22
+ return value;
23
+ };
24
+
25
+ // dist/index.js
26
+ var dist_exports = {};
27
+ __export(dist_exports, {
28
+ AnimationLoop: () => AnimationLoop,
29
+ AnimationLoopTemplate: () => AnimationLoopTemplate,
30
+ BufferTransform: () => BufferTransform,
31
+ ClipSpace: () => ClipSpace,
32
+ Computation: () => Computation,
33
+ ConeGeometry: () => ConeGeometry,
34
+ CubeGeometry: () => CubeGeometry,
35
+ CylinderGeometry: () => CylinderGeometry,
36
+ GPUGeometry: () => GPUGeometry,
37
+ Geometry: () => Geometry,
38
+ GroupNode: () => GroupNode,
39
+ IcoSphereGeometry: () => IcoSphereGeometry,
40
+ KeyFrames: () => KeyFrames,
41
+ Model: () => Model,
42
+ ModelNode: () => ModelNode,
43
+ PipelineFactory: () => PipelineFactory,
44
+ PlaneGeometry: () => PlaneGeometry,
45
+ ScenegraphNode: () => ScenegraphNode,
46
+ ShaderFactory: () => ShaderFactory,
47
+ SphereGeometry: () => SphereGeometry,
48
+ TextureTransform: () => TextureTransform,
49
+ Timeline: () => Timeline,
50
+ TruncatedConeGeometry: () => TruncatedConeGeometry,
51
+ _ShaderInputs: () => ShaderInputs,
52
+ makeAnimationLoop: () => makeAnimationLoop
53
+ });
54
+ module.exports = __toCommonJS(dist_exports);
55
+
56
+ // dist/animation/timeline.js
57
+ var channelHandles = 1;
58
+ var animationHandles = 1;
59
+ var Timeline = class {
60
+ time = 0;
61
+ channels = /* @__PURE__ */ new Map();
62
+ animations = /* @__PURE__ */ new Map();
63
+ playing = false;
64
+ lastEngineTime = -1;
65
+ constructor() {
66
+ }
67
+ addChannel(props) {
68
+ const { delay = 0, duration = Number.POSITIVE_INFINITY, rate = 1, repeat = 1 } = props;
69
+ const channelId = channelHandles++;
70
+ const channel = {
71
+ time: 0,
72
+ delay,
73
+ duration,
74
+ rate,
75
+ repeat
76
+ };
77
+ this._setChannelTime(channel, this.time);
78
+ this.channels.set(channelId, channel);
79
+ return channelId;
80
+ }
81
+ removeChannel(channelId) {
82
+ this.channels.delete(channelId);
83
+ for (const [animationHandle, animation] of this.animations) {
84
+ if (animation.channel === channelId) {
85
+ this.detachAnimation(animationHandle);
86
+ }
87
+ }
88
+ }
89
+ isFinished(channelId) {
90
+ const channel = this.channels.get(channelId);
91
+ if (channel === void 0) {
92
+ return false;
93
+ }
94
+ return this.time >= channel.delay + channel.duration * channel.repeat;
95
+ }
96
+ getTime(channelId) {
97
+ if (channelId === void 0) {
98
+ return this.time;
99
+ }
100
+ const channel = this.channels.get(channelId);
101
+ if (channel === void 0) {
102
+ return -1;
103
+ }
104
+ return channel.time;
105
+ }
106
+ setTime(time) {
107
+ this.time = Math.max(0, time);
108
+ const channels = this.channels.values();
109
+ for (const channel of channels) {
110
+ this._setChannelTime(channel, this.time);
111
+ }
112
+ const animations = this.animations.values();
113
+ for (const animationData of animations) {
114
+ const { animation, channel } = animationData;
115
+ animation.setTime(this.getTime(channel));
116
+ }
117
+ }
118
+ play() {
119
+ this.playing = true;
120
+ }
121
+ pause() {
122
+ this.playing = false;
123
+ this.lastEngineTime = -1;
124
+ }
125
+ reset() {
126
+ this.setTime(0);
127
+ }
128
+ attachAnimation(animation, channelHandle) {
129
+ const animationHandle = animationHandles++;
130
+ this.animations.set(animationHandle, {
131
+ animation,
132
+ channel: channelHandle
133
+ });
134
+ animation.setTime(this.getTime(channelHandle));
135
+ return animationHandle;
136
+ }
137
+ detachAnimation(channelId) {
138
+ this.animations.delete(channelId);
139
+ }
140
+ update(engineTime) {
141
+ if (this.playing) {
142
+ if (this.lastEngineTime === -1) {
143
+ this.lastEngineTime = engineTime;
144
+ }
145
+ this.setTime(this.time + (engineTime - this.lastEngineTime));
146
+ this.lastEngineTime = engineTime;
147
+ }
148
+ }
149
+ _setChannelTime(channel, time) {
150
+ const offsetTime = time - channel.delay;
151
+ const totalDuration = channel.duration * channel.repeat;
152
+ if (offsetTime >= totalDuration) {
153
+ channel.time = channel.duration * channel.rate;
154
+ } else {
155
+ channel.time = Math.max(0, offsetTime) % channel.duration;
156
+ channel.time *= channel.rate;
157
+ }
158
+ }
159
+ };
160
+
161
+ // dist/animation/key-frames.js
162
+ var KeyFrames = class {
163
+ startIndex = -1;
164
+ endIndex = -1;
165
+ factor = 0;
166
+ times = [];
167
+ values = [];
168
+ _lastTime = -1;
169
+ constructor(keyFrames) {
170
+ this.setKeyFrames(keyFrames);
171
+ this.setTime(0);
172
+ }
173
+ setKeyFrames(keyFrames) {
174
+ const numKeys = keyFrames.length;
175
+ this.times.length = numKeys;
176
+ this.values.length = numKeys;
177
+ for (let i = 0; i < numKeys; ++i) {
178
+ this.times[i] = keyFrames[i][0];
179
+ this.values[i] = keyFrames[i][1];
180
+ }
181
+ this._calculateKeys(this._lastTime);
182
+ }
183
+ setTime(time) {
184
+ time = Math.max(0, time);
185
+ if (time !== this._lastTime) {
186
+ this._calculateKeys(time);
187
+ this._lastTime = time;
188
+ }
189
+ }
190
+ getStartTime() {
191
+ return this.times[this.startIndex];
192
+ }
193
+ getEndTime() {
194
+ return this.times[this.endIndex];
195
+ }
196
+ getStartData() {
197
+ return this.values[this.startIndex];
198
+ }
199
+ getEndData() {
200
+ return this.values[this.endIndex];
201
+ }
202
+ _calculateKeys(time) {
203
+ let index = 0;
204
+ const numKeys = this.times.length;
205
+ for (index = 0; index < numKeys - 2; ++index) {
206
+ if (this.times[index + 1] > time) {
207
+ break;
208
+ }
209
+ }
210
+ this.startIndex = index;
211
+ this.endIndex = index + 1;
212
+ const startTime = this.times[this.startIndex];
213
+ const endTime = this.times[this.endIndex];
214
+ this.factor = Math.min(Math.max(0, (time - startTime) / (endTime - startTime)), 1);
215
+ }
216
+ };
217
+
218
+ // dist/animation-loop/animation-loop-template.js
219
+ var AnimationLoopTemplate = class {
220
+ constructor(animationProps) {
221
+ }
222
+ async onInitialize(animationProps) {
223
+ return null;
224
+ }
225
+ };
226
+
227
+ // dist/animation-loop/animation-loop.js
228
+ var import_core = require("@luma.gl/core");
229
+ var import_core2 = require("@luma.gl/core");
230
+ var import_stats = require("@probe.gl/stats");
231
+ var statIdCounter = 0;
232
+ var DEFAULT_ANIMATION_LOOP_PROPS = {
233
+ device: null,
234
+ onAddHTML: () => "",
235
+ onInitialize: async () => {
236
+ return null;
237
+ },
238
+ onRender: () => {
239
+ },
240
+ onFinalize: () => {
241
+ },
242
+ onError: (error) => console.error(error),
243
+ // eslint-disable-line no-console
244
+ stats: import_core.luma.stats.get(`animation-loop-${statIdCounter++}`),
245
+ // view parameters
246
+ useDevicePixels: true,
247
+ autoResizeViewport: false,
248
+ autoResizeDrawingBuffer: false
249
+ };
250
+ var AnimationLoop = class {
251
+ device = null;
252
+ canvas = null;
253
+ props;
254
+ animationProps = null;
255
+ timeline = null;
256
+ stats;
257
+ cpuTime;
258
+ gpuTime;
259
+ frameRate;
260
+ display;
261
+ needsRedraw = "initialized";
262
+ _initialized = false;
263
+ _running = false;
264
+ _animationFrameId = null;
265
+ _nextFramePromise = null;
266
+ _resolveNextFrame = null;
267
+ _cpuStartTime = 0;
268
+ // _gpuTimeQuery: Query | null = null;
269
+ /*
270
+ * @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
271
+ */
272
+ constructor(props) {
273
+ this.props = { ...DEFAULT_ANIMATION_LOOP_PROPS, ...props };
274
+ props = this.props;
275
+ if (!props.device) {
276
+ throw new Error("No device provided");
277
+ }
278
+ const { useDevicePixels = true } = this.props;
279
+ this.stats = props.stats || new import_stats.Stats({ id: "animation-loop-stats" });
280
+ this.cpuTime = this.stats.get("CPU Time");
281
+ this.gpuTime = this.stats.get("GPU Time");
282
+ this.frameRate = this.stats.get("Frame Rate");
283
+ this.setProps({
284
+ autoResizeViewport: props.autoResizeViewport,
285
+ autoResizeDrawingBuffer: props.autoResizeDrawingBuffer,
286
+ useDevicePixels
287
+ });
288
+ this.start = this.start.bind(this);
289
+ this.stop = this.stop.bind(this);
290
+ this._onMousemove = this._onMousemove.bind(this);
291
+ this._onMouseleave = this._onMouseleave.bind(this);
292
+ }
293
+ destroy() {
294
+ this.stop();
295
+ this._setDisplay(null);
296
+ }
297
+ /** @deprecated Use .destroy() */
298
+ delete() {
299
+ this.destroy();
300
+ }
301
+ /** Flags this animation loop as needing redraw */
302
+ setNeedsRedraw(reason) {
303
+ this.needsRedraw = this.needsRedraw || reason;
304
+ return this;
305
+ }
306
+ /** TODO - move these props to CanvasContext? */
307
+ setProps(props) {
308
+ if ("autoResizeViewport" in props) {
309
+ this.props.autoResizeViewport = props.autoResizeViewport || false;
310
+ }
311
+ if ("autoResizeDrawingBuffer" in props) {
312
+ this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer || false;
313
+ }
314
+ if ("useDevicePixels" in props) {
315
+ this.props.useDevicePixels = props.useDevicePixels || false;
316
+ }
317
+ return this;
318
+ }
319
+ /** Starts a render loop if not already running */
320
+ async start() {
321
+ if (this._running) {
322
+ return this;
323
+ }
324
+ this._running = true;
325
+ try {
326
+ let appContext;
327
+ if (!this._initialized) {
328
+ this._initialized = true;
329
+ await this._initDevice();
330
+ this._initialize();
331
+ await this.props.onInitialize(this._getAnimationProps());
332
+ }
333
+ if (!this._running) {
334
+ return null;
335
+ }
336
+ if (appContext !== false) {
337
+ this._cancelAnimationFrame();
338
+ this._requestAnimationFrame();
339
+ }
340
+ return this;
341
+ } catch (err) {
342
+ const error = err instanceof Error ? err : new Error("Unknown error");
343
+ this.props.onError(error);
344
+ throw error;
345
+ }
346
+ }
347
+ /** Stops a render loop if already running, finalizing */
348
+ stop() {
349
+ if (this._running) {
350
+ if (this.animationProps) {
351
+ this.props.onFinalize(this.animationProps);
352
+ }
353
+ this._cancelAnimationFrame();
354
+ this._nextFramePromise = null;
355
+ this._resolveNextFrame = null;
356
+ this._running = false;
357
+ }
358
+ return this;
359
+ }
360
+ /** Explicitly draw a frame */
361
+ redraw() {
362
+ var _a;
363
+ if ((_a = this.device) == null ? void 0 : _a.isLost) {
364
+ return this;
365
+ }
366
+ this._beginFrameTimers();
367
+ this._setupFrame();
368
+ this._updateAnimationProps();
369
+ this._renderFrame(this._getAnimationProps());
370
+ this._clearNeedsRedraw();
371
+ if (this._resolveNextFrame) {
372
+ this._resolveNextFrame(this);
373
+ this._nextFramePromise = null;
374
+ this._resolveNextFrame = null;
375
+ }
376
+ this._endFrameTimers();
377
+ return this;
378
+ }
379
+ /** Add a timeline, it will be automatically updated by the animation loop. */
380
+ attachTimeline(timeline) {
381
+ this.timeline = timeline;
382
+ return this.timeline;
383
+ }
384
+ /** Remove a timeline */
385
+ detachTimeline() {
386
+ this.timeline = null;
387
+ }
388
+ /** Wait until a render completes */
389
+ waitForRender() {
390
+ this.setNeedsRedraw("waitForRender");
391
+ if (!this._nextFramePromise) {
392
+ this._nextFramePromise = new Promise((resolve) => {
393
+ this._resolveNextFrame = resolve;
394
+ });
395
+ }
396
+ return this._nextFramePromise;
397
+ }
398
+ /** TODO - should use device.deviceContext */
399
+ async toDataURL() {
400
+ this.setNeedsRedraw("toDataURL");
401
+ await this.waitForRender();
402
+ if (this.canvas instanceof HTMLCanvasElement) {
403
+ return this.canvas.toDataURL();
404
+ }
405
+ throw new Error("OffscreenCanvas");
406
+ }
407
+ // PRIVATE METHODS
408
+ _initialize() {
409
+ this._startEventHandling();
410
+ this._initializeAnimationProps();
411
+ this._updateAnimationProps();
412
+ this._resizeCanvasDrawingBuffer();
413
+ this._resizeViewport();
414
+ }
415
+ _setDisplay(display) {
416
+ if (this.display) {
417
+ this.display.destroy();
418
+ this.display.animationLoop = null;
419
+ }
420
+ if (display) {
421
+ display.animationLoop = this;
422
+ }
423
+ this.display = display;
424
+ }
425
+ _requestAnimationFrame() {
426
+ if (!this._running) {
427
+ return;
428
+ }
429
+ this._animationFrameId = (0, import_core2.requestAnimationFrame)(this._animationFrame.bind(this));
430
+ }
431
+ _cancelAnimationFrame() {
432
+ if (this._animationFrameId === null) {
433
+ return;
434
+ }
435
+ (0, import_core2.cancelAnimationFrame)(this._animationFrameId);
436
+ this._animationFrameId = null;
437
+ }
438
+ _animationFrame() {
439
+ if (!this._running) {
440
+ return;
441
+ }
442
+ this.redraw();
443
+ this._requestAnimationFrame();
444
+ }
445
+ // Called on each frame, can be overridden to call onRender multiple times
446
+ // to support e.g. stereoscopic rendering
447
+ _renderFrame(animationProps) {
448
+ if (this.display) {
449
+ this.display._renderFrame(animationProps);
450
+ return;
451
+ }
452
+ this.props.onRender(this._getAnimationProps());
453
+ this.device.submit();
454
+ }
455
+ _clearNeedsRedraw() {
456
+ this.needsRedraw = false;
457
+ }
458
+ _setupFrame() {
459
+ this._resizeCanvasDrawingBuffer();
460
+ this._resizeViewport();
461
+ }
462
+ // Initialize the object that will be passed to app callbacks
463
+ _initializeAnimationProps() {
464
+ var _a, _b;
465
+ if (!this.device) {
466
+ throw new Error("loop");
467
+ }
468
+ this.animationProps = {
469
+ animationLoop: this,
470
+ device: this.device,
471
+ canvas: (_b = (_a = this.device) == null ? void 0 : _a.canvasContext) == null ? void 0 : _b.canvas,
472
+ timeline: this.timeline,
473
+ // Initial values
474
+ useDevicePixels: this.props.useDevicePixels,
475
+ needsRedraw: false,
476
+ // Placeholders
477
+ width: 1,
478
+ height: 1,
479
+ aspect: 1,
480
+ // Animation props
481
+ time: 0,
482
+ startTime: Date.now(),
483
+ engineTime: 0,
484
+ tick: 0,
485
+ tock: 0,
486
+ // Experimental
487
+ _mousePosition: null
488
+ // Event props
489
+ };
490
+ }
491
+ _getAnimationProps() {
492
+ if (!this.animationProps) {
493
+ throw new Error("animationProps");
494
+ }
495
+ return this.animationProps;
496
+ }
497
+ // Update the context object that will be passed to app callbacks
498
+ _updateAnimationProps() {
499
+ if (!this.animationProps) {
500
+ return;
501
+ }
502
+ const { width, height, aspect } = this._getSizeAndAspect();
503
+ if (width !== this.animationProps.width || height !== this.animationProps.height) {
504
+ this.setNeedsRedraw("drawing buffer resized");
505
+ }
506
+ if (aspect !== this.animationProps.aspect) {
507
+ this.setNeedsRedraw("drawing buffer aspect changed");
508
+ }
509
+ this.animationProps.width = width;
510
+ this.animationProps.height = height;
511
+ this.animationProps.aspect = aspect;
512
+ this.animationProps.needsRedraw = this.needsRedraw;
513
+ this.animationProps.engineTime = Date.now() - this.animationProps.startTime;
514
+ if (this.timeline) {
515
+ this.timeline.update(this.animationProps.engineTime);
516
+ }
517
+ this.animationProps.tick = Math.floor(this.animationProps.time / 1e3 * 60);
518
+ this.animationProps.tock++;
519
+ this.animationProps.time = this.timeline ? this.timeline.getTime() : this.animationProps.engineTime;
520
+ }
521
+ /** Wait for supplied device */
522
+ async _initDevice() {
523
+ var _a;
524
+ this.device = await this.props.device;
525
+ if (!this.device) {
526
+ throw new Error("No device provided");
527
+ }
528
+ this.canvas = ((_a = this.device.canvasContext) == null ? void 0 : _a.canvas) || null;
529
+ }
530
+ _createInfoDiv() {
531
+ if (this.canvas && this.props.onAddHTML) {
532
+ const wrapperDiv = document.createElement("div");
533
+ document.body.appendChild(wrapperDiv);
534
+ wrapperDiv.style.position = "relative";
535
+ const div = document.createElement("div");
536
+ div.style.position = "absolute";
537
+ div.style.left = "10px";
538
+ div.style.bottom = "10px";
539
+ div.style.width = "300px";
540
+ div.style.background = "white";
541
+ if (this.canvas instanceof HTMLCanvasElement) {
542
+ wrapperDiv.appendChild(this.canvas);
543
+ }
544
+ wrapperDiv.appendChild(div);
545
+ const html = this.props.onAddHTML(div);
546
+ if (html) {
547
+ div.innerHTML = html;
548
+ }
549
+ }
550
+ }
551
+ _getSizeAndAspect() {
552
+ var _a, _b, _c, _d;
553
+ if (!this.device) {
554
+ return { width: 1, height: 1, aspect: 1 };
555
+ }
556
+ const [width, height] = ((_b = (_a = this.device) == null ? void 0 : _a.canvasContext) == null ? void 0 : _b.getPixelSize()) || [1, 1];
557
+ let aspect = 1;
558
+ const canvas2 = (_d = (_c = this.device) == null ? void 0 : _c.canvasContext) == null ? void 0 : _d.canvas;
559
+ if (canvas2 && canvas2.clientHeight) {
560
+ aspect = canvas2.clientWidth / canvas2.clientHeight;
561
+ } else if (width > 0 && height > 0) {
562
+ aspect = width / height;
563
+ }
564
+ return { width, height, aspect };
565
+ }
566
+ /** Default viewport setup */
567
+ _resizeViewport() {
568
+ if (this.props.autoResizeViewport && this.device.gl) {
569
+ this.device.gl.viewport(
570
+ 0,
571
+ 0,
572
+ // @ts-expect-error Expose canvasContext
573
+ this.device.gl.drawingBufferWidth,
574
+ // @ts-expect-error Expose canvasContext
575
+ this.device.gl.drawingBufferHeight
576
+ );
577
+ }
578
+ }
579
+ /**
580
+ * Resize the render buffer of the canvas to match canvas client size
581
+ * Optionally multiplying with devicePixel ratio
582
+ */
583
+ _resizeCanvasDrawingBuffer() {
584
+ var _a, _b;
585
+ if (this.props.autoResizeDrawingBuffer) {
586
+ (_b = (_a = this.device) == null ? void 0 : _a.canvasContext) == null ? void 0 : _b.resize({ useDevicePixels: this.props.useDevicePixels });
587
+ }
588
+ }
589
+ _beginFrameTimers() {
590
+ this.frameRate.timeEnd();
591
+ this.frameRate.timeStart();
592
+ this.cpuTime.timeStart();
593
+ }
594
+ _endFrameTimers() {
595
+ this.cpuTime.timeEnd();
596
+ }
597
+ // Event handling
598
+ _startEventHandling() {
599
+ if (this.canvas) {
600
+ this.canvas.addEventListener("mousemove", this._onMousemove.bind(this));
601
+ this.canvas.addEventListener("mouseleave", this._onMouseleave.bind(this));
602
+ }
603
+ }
604
+ _onMousemove(event) {
605
+ if (event instanceof MouseEvent) {
606
+ this._getAnimationProps()._mousePosition = [event.offsetX, event.offsetY];
607
+ }
608
+ }
609
+ _onMouseleave(event) {
610
+ this._getAnimationProps()._mousePosition = null;
611
+ }
612
+ };
613
+
614
+ // dist/animation-loop/make-animation-loop.js
615
+ var import_core3 = require("@luma.gl/core");
616
+ function makeAnimationLoop(AnimationLoopTemplateCtor, props) {
617
+ let renderLoop = null;
618
+ const device = (props == null ? void 0 : props.device) || import_core3.luma.createDevice();
619
+ const animationLoop = new AnimationLoop({
620
+ ...props,
621
+ device,
622
+ async onInitialize(animationProps) {
623
+ renderLoop = new AnimationLoopTemplateCtor(animationProps);
624
+ return await (renderLoop == null ? void 0 : renderLoop.onInitialize(animationProps));
625
+ },
626
+ onRender: (animationProps) => renderLoop == null ? void 0 : renderLoop.onRender(animationProps),
627
+ onFinalize: (animationProps) => renderLoop == null ? void 0 : renderLoop.onFinalize(animationProps)
628
+ });
629
+ animationLoop.getInfo = () => {
630
+ return this.AnimationLoopTemplateCtor.info;
631
+ };
632
+ return animationLoop;
633
+ }
634
+
635
+ // dist/model/model.js
636
+ var import_core8 = require("@luma.gl/core");
637
+ var import_core9 = require("@luma.gl/core");
638
+ var import_core10 = require("@luma.gl/core");
639
+ var import_core11 = require("@luma.gl/core");
640
+ var import_shadertools2 = require("@luma.gl/shadertools");
641
+
642
+ // dist/geometry/gpu-geometry.js
643
+ var import_core4 = require("@luma.gl/core");
644
+ var GPUGeometry = class {
645
+ id;
646
+ userData = {};
647
+ /** Determines how vertices are read from the 'vertex' attributes */
648
+ topology;
649
+ bufferLayout = [];
650
+ vertexCount;
651
+ indices;
652
+ attributes;
653
+ constructor(props) {
654
+ this.id = props.id || (0, import_core4.uid)("geometry");
655
+ this.topology = props.topology;
656
+ this.indices = props.indices || null;
657
+ this.attributes = props.attributes;
658
+ this.vertexCount = props.vertexCount;
659
+ this.bufferLayout = props.bufferLayout || [];
660
+ if (this.indices) {
661
+ (0, import_core4.assert)(this.indices.usage === import_core4.Buffer.INDEX);
662
+ }
663
+ }
664
+ destroy() {
665
+ var _a;
666
+ (_a = this.indices) == null ? void 0 : _a.destroy();
667
+ for (const attribute of Object.values(this.attributes)) {
668
+ attribute.destroy();
669
+ }
670
+ }
671
+ getVertexCount() {
672
+ return this.vertexCount;
673
+ }
674
+ getAttributes() {
675
+ return this.attributes;
676
+ }
677
+ getIndexes() {
678
+ return this.indices;
679
+ }
680
+ _calculateVertexCount(positions) {
681
+ const vertexCount = positions.byteLength / 12;
682
+ return vertexCount;
683
+ }
684
+ };
685
+ function makeGPUGeometry(device, geometry) {
686
+ if (geometry instanceof GPUGeometry) {
687
+ return geometry;
688
+ }
689
+ const indices = getIndexBufferFromGeometry(device, geometry);
690
+ const { attributes, bufferLayout } = getAttributeBuffersFromGeometry(device, geometry);
691
+ return new GPUGeometry({
692
+ topology: geometry.topology || "triangle-list",
693
+ bufferLayout,
694
+ vertexCount: geometry.vertexCount,
695
+ indices,
696
+ attributes
697
+ });
698
+ }
699
+ function getIndexBufferFromGeometry(device, geometry) {
700
+ if (!geometry.indices) {
701
+ return void 0;
702
+ }
703
+ const data = geometry.indices.value;
704
+ return device.createBuffer({ usage: import_core4.Buffer.INDEX, data });
705
+ }
706
+ function getAttributeBuffersFromGeometry(device, geometry) {
707
+ const bufferLayout = [];
708
+ const attributes = {};
709
+ for (const [attributeName, attribute] of Object.entries(geometry.attributes)) {
710
+ let name = attributeName;
711
+ switch (attributeName) {
712
+ case "POSITION":
713
+ name = "positions";
714
+ break;
715
+ case "NORMAL":
716
+ name = "normals";
717
+ break;
718
+ case "TEXCOORD_0":
719
+ name = "texCoords";
720
+ break;
721
+ case "COLOR_0":
722
+ name = "colors";
723
+ break;
724
+ }
725
+ attributes[name] = device.createBuffer({ data: attribute.value, id: `${attributeName}-buffer` });
726
+ const { value, size, normalized } = attribute;
727
+ bufferLayout.push({ name, format: (0, import_core4.getVertexFormatFromAttribute)(value, size, normalized) });
728
+ }
729
+ const vertexCount = geometry._calculateVertexCount(geometry.attributes, geometry.indices);
730
+ return { attributes, bufferLayout, vertexCount };
731
+ }
732
+
733
+ // dist/shader-inputs.js
734
+ var import_core5 = require("@luma.gl/core");
735
+ var import_shadertools = require("@luma.gl/shadertools");
736
+ var ShaderInputs = class {
737
+ /**
738
+ * The map of modules
739
+ * @todo should should this include the resolved dependencies?
740
+ */
741
+ modules;
742
+ /** Stores the uniform values for each module */
743
+ moduleUniforms;
744
+ /** Stores the uniform bindings for each module */
745
+ moduleBindings;
746
+ /** Tracks if uniforms have changed */
747
+ moduleUniformsChanged;
748
+ /**
749
+ * Create a new UniformStore instance
750
+ * @param modules
751
+ */
752
+ constructor(modules) {
753
+ const allModules = (0, import_shadertools._resolveModules)(Object.values(modules));
754
+ import_core5.log.log(1, "Creating ShaderInputs with modules", allModules.map((m) => m.name))();
755
+ this.modules = modules;
756
+ this.moduleUniforms = {};
757
+ this.moduleBindings = {};
758
+ for (const [name, module2] of Object.entries(modules)) {
759
+ const moduleName = name;
760
+ this.moduleUniforms[moduleName] = module2.defaultUniforms || {};
761
+ this.moduleBindings[moduleName] = {};
762
+ }
763
+ }
764
+ /** Destroy */
765
+ destroy() {
766
+ }
767
+ /**
768
+ * Set module props
769
+ */
770
+ setProps(props) {
771
+ var _a;
772
+ for (const name of Object.keys(props)) {
773
+ const moduleName = name;
774
+ const moduleProps = props[moduleName];
775
+ const module2 = this.modules[moduleName];
776
+ if (!module2) {
777
+ import_core5.log.warn(`Module ${name} not found`)();
778
+ continue;
779
+ }
780
+ const oldUniforms = this.moduleUniforms[moduleName];
781
+ const uniforms = ((_a = module2.getUniforms) == null ? void 0 : _a.call(module2, moduleProps, this.moduleUniforms[moduleName])) || moduleProps;
782
+ this.moduleUniforms[moduleName] = { ...oldUniforms, ...uniforms };
783
+ }
784
+ }
785
+ /** Merges all bindings for the shader (from the various modules) */
786
+ // getUniformBlocks(): Record<string, Texture | Sampler> {
787
+ // return this.moduleUniforms;
788
+ // }
789
+ /**
790
+ * Return the map of modules
791
+ * @todo should should this include the resolved dependencies?
792
+ */
793
+ getModules() {
794
+ return Object.values(this.modules);
795
+ }
796
+ /** Get all uniform values for all modules */
797
+ getUniformValues() {
798
+ return this.moduleUniforms;
799
+ }
800
+ /** Merges all bindings for the shader (from the various modules) */
801
+ getBindings() {
802
+ const bindings = {};
803
+ for (const moduleBindings of Object.values(this.moduleBindings)) {
804
+ Object.assign(bindings, moduleBindings);
805
+ }
806
+ return bindings;
807
+ }
808
+ getDebugTable() {
809
+ var _a;
810
+ const table = {};
811
+ for (const [moduleName, module2] of Object.entries(this.moduleUniforms)) {
812
+ for (const [key, value] of Object.entries(module2)) {
813
+ table[`${moduleName}.${key}`] = {
814
+ type: (_a = this.modules[moduleName].uniformTypes) == null ? void 0 : _a[key],
815
+ value: String(value)
816
+ };
817
+ }
818
+ }
819
+ return table;
820
+ }
821
+ };
822
+
823
+ // dist/lib/pipeline-factory.js
824
+ var import_core6 = require("@luma.gl/core");
825
+ var _PipelineFactory = class {
826
+ device;
827
+ _hashCounter = 0;
828
+ _hashes = {};
829
+ _renderPipelineCache = {};
830
+ _computePipelineCache = {};
831
+ /** Get the singleton default pipeline factory for the specified device */
832
+ static getDefaultPipelineFactory(device) {
833
+ device._lumaData.defaultPipelineFactory = device._lumaData.defaultPipelineFactory || new _PipelineFactory(device);
834
+ return device._lumaData.defaultPipelineFactory;
835
+ }
836
+ constructor(device) {
837
+ this.device = device;
838
+ }
839
+ /** Return a RenderPipeline matching props. Reuses a similar pipeline if already created. */
840
+ createRenderPipeline(props) {
841
+ const allProps = { ...import_core6.RenderPipeline.defaultProps, ...props };
842
+ const hash = this._hashRenderPipeline(allProps);
843
+ if (!this._renderPipelineCache[hash]) {
844
+ const pipeline = this.device.createRenderPipeline({
845
+ ...allProps,
846
+ id: allProps.id ? `${allProps.id}-cached` : void 0
847
+ });
848
+ pipeline.hash = hash;
849
+ this._renderPipelineCache[hash] = { pipeline, useCount: 0 };
850
+ }
851
+ this._renderPipelineCache[hash].useCount++;
852
+ return this._renderPipelineCache[hash].pipeline;
853
+ }
854
+ createComputePipeline(props) {
855
+ const allProps = { ...import_core6.ComputePipeline.defaultProps, ...props };
856
+ const hash = this._hashComputePipeline(allProps);
857
+ if (!this._computePipelineCache[hash]) {
858
+ const pipeline = this.device.createComputePipeline({
859
+ ...allProps,
860
+ id: allProps.id ? `${allProps.id}-cached` : void 0
861
+ });
862
+ pipeline.hash = hash;
863
+ this._computePipelineCache[hash] = { pipeline, useCount: 0 };
864
+ }
865
+ this._computePipelineCache[hash].useCount++;
866
+ return this._computePipelineCache[hash].pipeline;
867
+ }
868
+ release(pipeline) {
869
+ const hash = pipeline.hash;
870
+ const cache = pipeline instanceof import_core6.ComputePipeline ? this._computePipelineCache : this._renderPipelineCache;
871
+ cache[hash].useCount--;
872
+ if (cache[hash].useCount === 0) {
873
+ cache[hash].pipeline.destroy();
874
+ delete cache[hash];
875
+ }
876
+ }
877
+ // PRIVATE
878
+ _hashComputePipeline(props) {
879
+ const shaderHash = this._getHash(props.shader.source);
880
+ return `${shaderHash}`;
881
+ }
882
+ /** Calculate a hash based on all the inputs for a render pipeline */
883
+ _hashRenderPipeline(props) {
884
+ const vsHash = this._getHash(props.vs.source);
885
+ const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
886
+ const varyingHash = "-";
887
+ const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
888
+ switch (this.device.type) {
889
+ default:
890
+ const parameterHash = this._getHash(JSON.stringify(props.parameters));
891
+ return `${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`;
892
+ }
893
+ }
894
+ _getHash(key) {
895
+ if (this._hashes[key] === void 0) {
896
+ this._hashes[key] = this._hashCounter++;
897
+ }
898
+ return this._hashes[key];
899
+ }
900
+ };
901
+ var PipelineFactory = _PipelineFactory;
902
+ __publicField(PipelineFactory, "defaultProps", { ...import_core6.RenderPipeline.defaultProps });
903
+
904
+ // dist/lib/shader-factory.js
905
+ var import_core7 = require("@luma.gl/core");
906
+ var _ShaderFactory = class {
907
+ device;
908
+ _cache = {};
909
+ /** Returns the default ShaderFactory for the given {@link Device}, creating one if necessary. */
910
+ static getDefaultShaderFactory(device) {
911
+ device._lumaData.defaultShaderFactory ||= new _ShaderFactory(device);
912
+ return device._lumaData.defaultShaderFactory;
913
+ }
914
+ /** @internal */
915
+ constructor(device) {
916
+ this.device = device;
917
+ }
918
+ /** Requests a {@link Shader} from the cache, creating a new Shader only if necessary. */
919
+ createShader(props) {
920
+ const key = this._hashShader(props);
921
+ let cacheEntry = this._cache[key];
922
+ if (!cacheEntry) {
923
+ const shader = this.device.createShader({
924
+ ...props,
925
+ id: props.id ? `${props.id}-cached` : void 0
926
+ });
927
+ this._cache[key] = cacheEntry = { shader, useCount: 0 };
928
+ }
929
+ cacheEntry.useCount++;
930
+ return cacheEntry.shader;
931
+ }
932
+ /** Releases a previously-requested {@link Shader}, destroying it if no users remain. */
933
+ release(shader) {
934
+ const key = this._hashShader(shader);
935
+ const cacheEntry = this._cache[key];
936
+ if (cacheEntry) {
937
+ cacheEntry.useCount--;
938
+ if (cacheEntry.useCount === 0) {
939
+ delete this._cache[key];
940
+ cacheEntry.shader.destroy();
941
+ }
942
+ }
943
+ }
944
+ // PRIVATE
945
+ _hashShader(value) {
946
+ return `${value.stage}:${value.source}`;
947
+ }
948
+ };
949
+ var ShaderFactory = _ShaderFactory;
950
+ __publicField(ShaderFactory, "defaultProps", { ...import_core7.Shader.defaultProps });
951
+
952
+ // dist/debug/debug-shader-layout.js
953
+ function getDebugTableForShaderLayout(layout, name) {
954
+ var _a;
955
+ const table = {};
956
+ const header = "Values";
957
+ if (layout.attributes.length === 0 && !((_a = layout.varyings) == null ? void 0 : _a.length)) {
958
+ return { "No attributes or varyings": { [header]: "N/A" } };
959
+ }
960
+ for (const attributeDeclaration of layout.attributes) {
961
+ if (attributeDeclaration) {
962
+ const glslDeclaration = `${attributeDeclaration.location} ${attributeDeclaration.name}: ${attributeDeclaration.type}`;
963
+ table[`in ${glslDeclaration}`] = { [header]: attributeDeclaration.stepMode || "vertex" };
964
+ }
965
+ }
966
+ for (const varyingDeclaration of layout.varyings || []) {
967
+ const glslDeclaration = `${varyingDeclaration.location} ${varyingDeclaration.name}`;
968
+ table[`out ${glslDeclaration}`] = { [header]: JSON.stringify(varyingDeclaration.accessor) };
969
+ }
970
+ return table;
971
+ }
972
+
973
+ // dist/debug/debug-framebuffer.js
974
+ var canvas = null;
975
+ var ctx = null;
976
+ function debugFramebuffer(fbo, { id, minimap, opaque, top = "0", left = "0", rgbaScale = 1 }) {
977
+ if (!canvas) {
978
+ canvas = document.createElement("canvas");
979
+ canvas.id = id;
980
+ canvas.title = id;
981
+ canvas.style.zIndex = "100";
982
+ canvas.style.position = "absolute";
983
+ canvas.style.top = top;
984
+ canvas.style.left = left;
985
+ canvas.style.border = "blue 1px solid";
986
+ canvas.style.transform = "scaleY(-1)";
987
+ document.body.appendChild(canvas);
988
+ ctx = canvas.getContext("2d");
989
+ }
990
+ if (canvas.width !== fbo.width || canvas.height !== fbo.height) {
991
+ canvas.width = fbo.width / 2;
992
+ canvas.height = fbo.height / 2;
993
+ canvas.style.width = "400px";
994
+ canvas.style.height = "400px";
995
+ }
996
+ const color = fbo.device.readPixelsToArrayWebGL(fbo);
997
+ const imageData = ctx.createImageData(fbo.width, fbo.height);
998
+ const offset = 0;
999
+ for (let i = 0; i < color.length; i += 4) {
1000
+ imageData.data[offset + i + 0] = color[i + 0] * rgbaScale;
1001
+ imageData.data[offset + i + 1] = color[i + 1] * rgbaScale;
1002
+ imageData.data[offset + i + 2] = color[i + 2] * rgbaScale;
1003
+ imageData.data[offset + i + 3] = opaque ? 255 : color[i + 3] * rgbaScale;
1004
+ }
1005
+ ctx.putImageData(imageData, 0, 0);
1006
+ }
1007
+
1008
+ // dist/model/model.js
1009
+ var LOG_DRAW_PRIORITY = 2;
1010
+ var LOG_DRAW_TIMEOUT = 1e4;
1011
+ var _Model = class {
1012
+ device;
1013
+ id;
1014
+ source;
1015
+ vs;
1016
+ fs;
1017
+ pipelineFactory;
1018
+ shaderFactory;
1019
+ userData = {};
1020
+ // Fixed properties (change can trigger pipeline rebuild)
1021
+ /** The render pipeline GPU parameters, depth testing etc */
1022
+ parameters;
1023
+ /** The primitive topology */
1024
+ topology;
1025
+ /** Buffer layout */
1026
+ bufferLayout;
1027
+ // Dynamic properties
1028
+ /** Vertex count */
1029
+ vertexCount;
1030
+ /** instance count */
1031
+ instanceCount = 0;
1032
+ /** Index buffer */
1033
+ indexBuffer = null;
1034
+ /** Buffer-valued attributes */
1035
+ bufferAttributes = {};
1036
+ /** Constant-valued attributes */
1037
+ constantAttributes = {};
1038
+ /** Bindings (textures, samplers, uniform buffers) */
1039
+ bindings = {};
1040
+ /** Sets uniforms @deprecated Use uniform buffers and setBindings() for portability*/
1041
+ uniforms = {};
1042
+ /**
1043
+ * VertexArray
1044
+ * @note not implemented: if bufferLayout is updated, vertex array has to be rebuilt!
1045
+ * @todo - allow application to define multiple vertex arrays?
1046
+ * */
1047
+ vertexArray;
1048
+ /** TransformFeedback, WebGL 2 only. */
1049
+ transformFeedback = null;
1050
+ /** The underlying GPU "program". @note May be recreated if parameters change */
1051
+ pipeline;
1052
+ /** ShaderInputs instance */
1053
+ shaderInputs;
1054
+ _uniformStore;
1055
+ _attributeInfos = {};
1056
+ _gpuGeometry = null;
1057
+ _getModuleUniforms;
1058
+ props;
1059
+ _pipelineNeedsUpdate = "newly created";
1060
+ _needsRedraw = "initializing";
1061
+ _destroyed = false;
1062
+ /** "Time" of last draw. Monotonically increasing timestamp */
1063
+ _lastDrawTimestamp = -1;
1064
+ constructor(device, props) {
1065
+ var _a, _b, _c;
1066
+ this.props = { ..._Model.defaultProps, ...props };
1067
+ props = this.props;
1068
+ this.id = props.id || (0, import_core10.uid)("model");
1069
+ this.device = device;
1070
+ Object.assign(this.userData, props.userData);
1071
+ const moduleMap = Object.fromEntries(((_a = this.props.modules) == null ? void 0 : _a.map((module2) => [module2.name, module2])) || []);
1072
+ this.setShaderInputs(props.shaderInputs || new ShaderInputs(moduleMap));
1073
+ const platformInfo = getPlatformInfo(device);
1074
+ const modules = (((_b = this.props.modules) == null ? void 0 : _b.length) > 0 ? this.props.modules : (_c = this.shaderInputs) == null ? void 0 : _c.getModules()) || [];
1075
+ const isWebGPU = this.device.type === "webgpu";
1076
+ if (isWebGPU && this.props.source) {
1077
+ this.props.shaderLayout ||= (0, import_shadertools2.getShaderLayoutFromWGSL)(this.props.source);
1078
+ const { source, getUniforms } = this.props.shaderAssembler.assembleShader({
1079
+ platformInfo,
1080
+ ...this.props,
1081
+ modules
1082
+ });
1083
+ this.source = source;
1084
+ this._getModuleUniforms = getUniforms;
1085
+ } else {
1086
+ const { vs, fs, getUniforms } = this.props.shaderAssembler.assembleShaderPair({
1087
+ platformInfo,
1088
+ ...this.props,
1089
+ modules
1090
+ });
1091
+ this.vs = vs;
1092
+ this.fs = fs;
1093
+ this._getModuleUniforms = getUniforms;
1094
+ }
1095
+ this.vertexCount = this.props.vertexCount;
1096
+ this.instanceCount = this.props.instanceCount;
1097
+ this.topology = this.props.topology;
1098
+ this.bufferLayout = this.props.bufferLayout;
1099
+ this.parameters = this.props.parameters;
1100
+ if (props.geometry) {
1101
+ this.setGeometry(props.geometry);
1102
+ }
1103
+ this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
1104
+ this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
1105
+ this.pipeline = this._updatePipeline();
1106
+ this.vertexArray = device.createVertexArray({
1107
+ renderPipeline: this.pipeline
1108
+ });
1109
+ if (this._gpuGeometry) {
1110
+ this._setGeometryAttributes(this._gpuGeometry);
1111
+ }
1112
+ if (props.vertexCount) {
1113
+ this.setVertexCount(props.vertexCount);
1114
+ }
1115
+ if (props.instanceCount) {
1116
+ this.setInstanceCount(props.instanceCount);
1117
+ }
1118
+ if (props.indices) {
1119
+ throw new Error("Model.props.indices removed. Use props.indexBuffer");
1120
+ }
1121
+ if (props.indexBuffer) {
1122
+ this.setIndexBuffer(props.indexBuffer);
1123
+ }
1124
+ if (props.attributes) {
1125
+ this.setAttributes(props.attributes, {
1126
+ ignoreUnknownAttributes: props.ignoreUnknownAttributes
1127
+ });
1128
+ }
1129
+ if (props.constantAttributes) {
1130
+ this.setConstantAttributes(props.constantAttributes);
1131
+ }
1132
+ if (props.bindings) {
1133
+ this.setBindings(props.bindings);
1134
+ }
1135
+ if (props.uniforms) {
1136
+ this.setUniforms(props.uniforms);
1137
+ }
1138
+ if (props.moduleSettings) {
1139
+ import_core10.log.warn("Model.props.moduleSettings is deprecated. Use Model.shaderInputs.setProps()")();
1140
+ this.updateModuleSettings(props.moduleSettings);
1141
+ }
1142
+ if (props.transformFeedback) {
1143
+ this.transformFeedback = props.transformFeedback;
1144
+ }
1145
+ Object.seal(this);
1146
+ }
1147
+ destroy() {
1148
+ var _a;
1149
+ if (this._destroyed)
1150
+ return;
1151
+ this.pipelineFactory.release(this.pipeline);
1152
+ this.shaderFactory.release(this.pipeline.vs);
1153
+ if (this.pipeline.fs) {
1154
+ this.shaderFactory.release(this.pipeline.fs);
1155
+ }
1156
+ this._uniformStore.destroy();
1157
+ (_a = this._gpuGeometry) == null ? void 0 : _a.destroy();
1158
+ this._destroyed = true;
1159
+ }
1160
+ // Draw call
1161
+ /** Query redraw status. Clears the status. */
1162
+ needsRedraw() {
1163
+ if (this._getBindingsUpdateTimestamp() > this._lastDrawTimestamp) {
1164
+ this.setNeedsRedraw("contents of bound textures or buffers updated");
1165
+ }
1166
+ const needsRedraw = this._needsRedraw;
1167
+ this._needsRedraw = false;
1168
+ return needsRedraw;
1169
+ }
1170
+ /** Mark the model as needing a redraw */
1171
+ setNeedsRedraw(reason) {
1172
+ this._needsRedraw ||= reason;
1173
+ }
1174
+ predraw() {
1175
+ this.updateShaderInputs();
1176
+ this.pipeline = this._updatePipeline();
1177
+ }
1178
+ draw(renderPass) {
1179
+ this.predraw();
1180
+ let drawSuccess;
1181
+ try {
1182
+ this._logDrawCallStart();
1183
+ this.pipeline = this._updatePipeline();
1184
+ this.pipeline.setBindings(this.bindings);
1185
+ if (!(0, import_core10.isObjectEmpty)(this.uniforms)) {
1186
+ this.pipeline.setUniformsWebGL(this.uniforms);
1187
+ }
1188
+ const { indexBuffer } = this.vertexArray;
1189
+ const indexCount = indexBuffer ? indexBuffer.byteLength / (indexBuffer.indexType === "uint32" ? 4 : 2) : void 0;
1190
+ drawSuccess = this.pipeline.draw({
1191
+ renderPass,
1192
+ vertexArray: this.vertexArray,
1193
+ vertexCount: this.vertexCount,
1194
+ instanceCount: this.instanceCount,
1195
+ indexCount,
1196
+ transformFeedback: this.transformFeedback
1197
+ });
1198
+ } finally {
1199
+ this._logDrawCallEnd();
1200
+ }
1201
+ this._logFramebuffer(renderPass);
1202
+ if (drawSuccess) {
1203
+ this._lastDrawTimestamp = this.device.timestamp;
1204
+ this._needsRedraw = false;
1205
+ } else {
1206
+ this._needsRedraw = "waiting for resource initialization";
1207
+ }
1208
+ return drawSuccess;
1209
+ }
1210
+ // Update fixed fields (can trigger pipeline rebuild)
1211
+ /**
1212
+ * Updates the optional geometry
1213
+ * Geometry, set topology and bufferLayout
1214
+ * @note Can trigger a pipeline rebuild / pipeline cache fetch on WebGPU
1215
+ */
1216
+ setGeometry(geometry) {
1217
+ var _a;
1218
+ (_a = this._gpuGeometry) == null ? void 0 : _a.destroy();
1219
+ const gpuGeometry = geometry && makeGPUGeometry(this.device, geometry);
1220
+ if (gpuGeometry) {
1221
+ this.setTopology(gpuGeometry.topology || "triangle-list");
1222
+ this.bufferLayout = mergeBufferLayouts(gpuGeometry.bufferLayout, this.bufferLayout);
1223
+ if (this.vertexArray) {
1224
+ this._setGeometryAttributes(gpuGeometry);
1225
+ }
1226
+ }
1227
+ this._gpuGeometry = gpuGeometry;
1228
+ }
1229
+ /**
1230
+ * Updates the primitive topology ('triangle-list', 'triangle-strip' etc).
1231
+ * @note Triggers a pipeline rebuild / pipeline cache fetch on WebGPU
1232
+ */
1233
+ setTopology(topology) {
1234
+ if (topology !== this.topology) {
1235
+ this.topology = topology;
1236
+ this._setPipelineNeedsUpdate("topology");
1237
+ }
1238
+ }
1239
+ /**
1240
+ * Updates the buffer layout.
1241
+ * @note Triggers a pipeline rebuild / pipeline cache fetch
1242
+ */
1243
+ setBufferLayout(bufferLayout) {
1244
+ this.bufferLayout = this._gpuGeometry ? mergeBufferLayouts(bufferLayout, this._gpuGeometry.bufferLayout) : bufferLayout;
1245
+ this._setPipelineNeedsUpdate("bufferLayout");
1246
+ this.pipeline = this._updatePipeline();
1247
+ this.vertexArray = this.device.createVertexArray({
1248
+ renderPipeline: this.pipeline
1249
+ });
1250
+ if (this._gpuGeometry) {
1251
+ this._setGeometryAttributes(this._gpuGeometry);
1252
+ }
1253
+ }
1254
+ /**
1255
+ * Set GPU parameters.
1256
+ * @note Can trigger a pipeline rebuild / pipeline cache fetch.
1257
+ * @param parameters
1258
+ */
1259
+ setParameters(parameters) {
1260
+ if (!(0, import_core10.deepEqual)(parameters, this.parameters, 2)) {
1261
+ this.parameters = parameters;
1262
+ this._setPipelineNeedsUpdate("parameters");
1263
+ }
1264
+ }
1265
+ // Update dynamic fields
1266
+ /**
1267
+ * Updates the vertex count (used in draw calls)
1268
+ * @note Any attributes with stepMode=vertex need to be at least this big
1269
+ */
1270
+ setVertexCount(vertexCount) {
1271
+ this.vertexCount = vertexCount;
1272
+ this.setNeedsRedraw("vertexCount");
1273
+ }
1274
+ /**
1275
+ * Updates the instance count (used in draw calls)
1276
+ * @note Any attributes with stepMode=instance need to be at least this big
1277
+ */
1278
+ setInstanceCount(instanceCount) {
1279
+ this.instanceCount = instanceCount;
1280
+ this.setNeedsRedraw("instanceCount");
1281
+ }
1282
+ setShaderInputs(shaderInputs) {
1283
+ this.shaderInputs = shaderInputs;
1284
+ this._uniformStore = new import_core9.UniformStore(this.shaderInputs.modules);
1285
+ for (const moduleName of Object.keys(this.shaderInputs.modules)) {
1286
+ const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
1287
+ this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
1288
+ }
1289
+ this.setNeedsRedraw("shaderInputs");
1290
+ }
1291
+ updateShaderInputs() {
1292
+ this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
1293
+ this.setNeedsRedraw("shaderInputs");
1294
+ }
1295
+ /**
1296
+ * Sets bindings (textures, samplers, uniform buffers)
1297
+ */
1298
+ setBindings(bindings) {
1299
+ Object.assign(this.bindings, bindings);
1300
+ this.setNeedsRedraw("bindings");
1301
+ }
1302
+ /**
1303
+ * Updates optional transform feedback. WebGL only.
1304
+ */
1305
+ setTransformFeedback(transformFeedback) {
1306
+ this.transformFeedback = transformFeedback;
1307
+ this.setNeedsRedraw("transformFeedback");
1308
+ }
1309
+ /**
1310
+ * Sets the index buffer
1311
+ * @todo - how to unset it if we change geometry?
1312
+ */
1313
+ setIndexBuffer(indexBuffer) {
1314
+ this.vertexArray.setIndexBuffer(indexBuffer);
1315
+ this.setNeedsRedraw("indexBuffer");
1316
+ }
1317
+ /**
1318
+ * Sets attributes (buffers)
1319
+ * @note Overrides any attributes previously set with the same name
1320
+ */
1321
+ setAttributes(buffers, options) {
1322
+ if (buffers.indices) {
1323
+ import_core10.log.warn(`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`)();
1324
+ }
1325
+ for (const [bufferName, buffer] of Object.entries(buffers)) {
1326
+ const bufferLayout = this.bufferLayout.find((layout) => getAttributeNames(layout).includes(bufferName));
1327
+ if (!bufferLayout) {
1328
+ import_core10.log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)();
1329
+ continue;
1330
+ }
1331
+ const attributeNames = getAttributeNames(bufferLayout);
1332
+ let set = false;
1333
+ for (const attributeName of attributeNames) {
1334
+ const attributeInfo = this._attributeInfos[attributeName];
1335
+ if (attributeInfo) {
1336
+ this.vertexArray.setBuffer(attributeInfo.location, buffer);
1337
+ set = true;
1338
+ }
1339
+ }
1340
+ if (!set && ((options == null ? void 0 : options.ignoreUnknownAttributes) || this.props.ignoreUnknownAttributes)) {
1341
+ import_core10.log.warn(`Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`)();
1342
+ }
1343
+ }
1344
+ this.setNeedsRedraw("attributes");
1345
+ }
1346
+ /**
1347
+ * Sets constant attributes
1348
+ * @note Overrides any attributes previously set with the same name
1349
+ * Constant attributes are only supported in WebGL, not in WebGPU
1350
+ * Any attribute that is disabled in the current vertex array object
1351
+ * is read from the context's global constant value for that attribute location.
1352
+ * @param constantAttributes
1353
+ */
1354
+ setConstantAttributes(attributes) {
1355
+ for (const [attributeName, value] of Object.entries(attributes)) {
1356
+ const attributeInfo = this._attributeInfos[attributeName];
1357
+ if (attributeInfo) {
1358
+ this.vertexArray.setConstantWebGL(attributeInfo.location, value);
1359
+ } else {
1360
+ import_core10.log.warn(`Model "${this.id}: Ignoring constant supplied for unknown attribute "${attributeName}"`)();
1361
+ }
1362
+ }
1363
+ this.setNeedsRedraw("constants");
1364
+ }
1365
+ // DEPRECATED METHODS
1366
+ /**
1367
+ * Sets individual uniforms
1368
+ * @deprecated WebGL only, use uniform buffers for portability
1369
+ * @param uniforms
1370
+ */
1371
+ setUniforms(uniforms) {
1372
+ if (!(0, import_core10.isObjectEmpty)(uniforms)) {
1373
+ this.pipeline.setUniformsWebGL(uniforms);
1374
+ Object.assign(this.uniforms, uniforms);
1375
+ }
1376
+ this.setNeedsRedraw("uniforms");
1377
+ }
1378
+ /**
1379
+ * @deprecated Updates shader module settings (which results in uniforms being set)
1380
+ */
1381
+ updateModuleSettings(props) {
1382
+ import_core10.log.warn("Model.updateModuleSettings is deprecated. Use Model.shaderInputs.setProps()")();
1383
+ const { bindings, uniforms } = (0, import_core10.splitUniformsAndBindings)(this._getModuleUniforms(props));
1384
+ Object.assign(this.bindings, bindings);
1385
+ Object.assign(this.uniforms, uniforms);
1386
+ this.setNeedsRedraw("moduleSettings");
1387
+ }
1388
+ // Internal methods
1389
+ /** Get the timestamp of the latest updated bound GPU memory resource (buffer/texture). */
1390
+ _getBindingsUpdateTimestamp() {
1391
+ let timestamp = 0;
1392
+ for (const binding of Object.values(this.bindings)) {
1393
+ if (binding instanceof import_core8.TextureView) {
1394
+ timestamp = Math.max(timestamp, binding.texture.updateTimestamp);
1395
+ } else if (binding instanceof import_core8.Buffer || binding instanceof import_core8.Texture) {
1396
+ timestamp = Math.max(timestamp, binding.updateTimestamp);
1397
+ } else if (!(binding instanceof import_core8.Sampler)) {
1398
+ timestamp = Math.max(timestamp, binding.buffer.updateTimestamp);
1399
+ }
1400
+ }
1401
+ return timestamp;
1402
+ }
1403
+ /**
1404
+ * Updates the optional geometry attributes
1405
+ * Geometry, sets several attributes, indexBuffer, and also vertex count
1406
+ * @note Can trigger a pipeline rebuild / pipeline cache fetch on WebGPU
1407
+ */
1408
+ _setGeometryAttributes(gpuGeometry) {
1409
+ const attributes = { ...gpuGeometry.attributes };
1410
+ for (const [attributeName] of Object.entries(attributes)) {
1411
+ if (!this.pipeline.shaderLayout.attributes.find((layout) => layout.name === attributeName) && attributeName !== "positions") {
1412
+ delete attributes[attributeName];
1413
+ }
1414
+ }
1415
+ this.vertexCount = gpuGeometry.vertexCount;
1416
+ this.setIndexBuffer(gpuGeometry.indices);
1417
+ this.setAttributes(gpuGeometry.attributes, { ignoreUnknownAttributes: true });
1418
+ this.setAttributes(attributes, { ignoreUnknownAttributes: this.props.ignoreUnknownAttributes });
1419
+ this.setNeedsRedraw("geometry attributes");
1420
+ }
1421
+ /** Mark pipeline as needing update */
1422
+ _setPipelineNeedsUpdate(reason) {
1423
+ this._pipelineNeedsUpdate ||= reason;
1424
+ this.setNeedsRedraw(reason);
1425
+ }
1426
+ /** Update pipeline if needed */
1427
+ _updatePipeline() {
1428
+ if (this._pipelineNeedsUpdate) {
1429
+ let prevShaderVs = null;
1430
+ let prevShaderFs = null;
1431
+ if (this.pipeline) {
1432
+ import_core10.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
1433
+ prevShaderVs = this.pipeline.vs;
1434
+ prevShaderFs = this.pipeline.fs;
1435
+ }
1436
+ this._pipelineNeedsUpdate = false;
1437
+ const vs = this.shaderFactory.createShader({
1438
+ id: `${this.id}-vertex`,
1439
+ stage: "vertex",
1440
+ source: this.source || this.vs,
1441
+ debug: this.props.debugShaders
1442
+ });
1443
+ let fs = null;
1444
+ if (this.source) {
1445
+ fs = vs;
1446
+ } else if (this.fs) {
1447
+ fs = this.shaderFactory.createShader({
1448
+ id: `${this.id}-fragment`,
1449
+ stage: "fragment",
1450
+ source: this.source || this.fs,
1451
+ debug: this.props.debugShaders
1452
+ });
1453
+ }
1454
+ this.pipeline = this.pipelineFactory.createRenderPipeline({
1455
+ ...this.props,
1456
+ bufferLayout: this.bufferLayout,
1457
+ topology: this.topology,
1458
+ parameters: this.parameters,
1459
+ vs,
1460
+ fs
1461
+ });
1462
+ this._attributeInfos = (0, import_core11.getAttributeInfosFromLayouts)(this.pipeline.shaderLayout, this.bufferLayout);
1463
+ if (prevShaderVs)
1464
+ this.shaderFactory.release(prevShaderVs);
1465
+ if (prevShaderFs)
1466
+ this.shaderFactory.release(prevShaderFs);
1467
+ }
1468
+ return this.pipeline;
1469
+ }
1470
+ /** Throttle draw call logging */
1471
+ _lastLogTime = 0;
1472
+ _logOpen = false;
1473
+ _logDrawCallStart() {
1474
+ const logDrawTimeout = import_core10.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
1475
+ if (import_core10.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
1476
+ return;
1477
+ }
1478
+ this._lastLogTime = Date.now();
1479
+ this._logOpen = true;
1480
+ import_core10.log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core10.log.level <= 2 })();
1481
+ }
1482
+ _logDrawCallEnd() {
1483
+ if (this._logOpen) {
1484
+ const shaderLayoutTable = getDebugTableForShaderLayout(this.pipeline.shaderLayout, this.id);
1485
+ import_core10.log.table(LOG_DRAW_PRIORITY, shaderLayoutTable)();
1486
+ const uniformTable = this.shaderInputs.getDebugTable();
1487
+ for (const [name, value] of Object.entries(this.uniforms)) {
1488
+ uniformTable[name] = { value };
1489
+ }
1490
+ import_core10.log.table(LOG_DRAW_PRIORITY, uniformTable)();
1491
+ const attributeTable = this._getAttributeDebugTable();
1492
+ import_core10.log.table(LOG_DRAW_PRIORITY, this._attributeInfos)();
1493
+ import_core10.log.table(LOG_DRAW_PRIORITY, attributeTable)();
1494
+ import_core10.log.groupEnd(LOG_DRAW_PRIORITY)();
1495
+ this._logOpen = false;
1496
+ }
1497
+ }
1498
+ _drawCount = 0;
1499
+ _logFramebuffer(renderPass) {
1500
+ const debugFramebuffers = import_core10.log.get("framebuffer");
1501
+ this._drawCount++;
1502
+ if (!debugFramebuffers || this._drawCount++ > 3 && this._drawCount % 60) {
1503
+ return;
1504
+ }
1505
+ const framebuffer = renderPass.props.framebuffer;
1506
+ if (framebuffer) {
1507
+ debugFramebuffer(framebuffer, { id: framebuffer.id, minimap: true });
1508
+ }
1509
+ }
1510
+ _getAttributeDebugTable() {
1511
+ const table = {};
1512
+ for (const [name, attributeInfo] of Object.entries(this._attributeInfos)) {
1513
+ table[attributeInfo.location] = {
1514
+ name,
1515
+ type: attributeInfo.shaderType,
1516
+ values: this._getBufferOrConstantValues(this.vertexArray.attributes[attributeInfo.location], attributeInfo.bufferDataType)
1517
+ };
1518
+ }
1519
+ if (this.vertexArray.indexBuffer) {
1520
+ const { indexBuffer } = this.vertexArray;
1521
+ const values = indexBuffer.indexType === "uint32" ? new Uint32Array(indexBuffer.debugData) : new Uint16Array(indexBuffer.debugData);
1522
+ table.indices = {
1523
+ name: "indices",
1524
+ type: indexBuffer.indexType,
1525
+ values: values.toString()
1526
+ };
1527
+ }
1528
+ return table;
1529
+ }
1530
+ // TODO - fix typing of luma data types
1531
+ _getBufferOrConstantValues(attribute, dataType) {
1532
+ const TypedArrayConstructor = (0, import_core11.getTypedArrayFromDataType)(dataType);
1533
+ const typedArray = attribute instanceof import_core8.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
1534
+ return typedArray.toString();
1535
+ }
1536
+ };
1537
+ var Model = _Model;
1538
+ __publicField(Model, "defaultProps", {
1539
+ ...import_core9.RenderPipeline.defaultProps,
1540
+ source: null,
1541
+ vs: null,
1542
+ fs: null,
1543
+ id: "unnamed",
1544
+ handle: void 0,
1545
+ userData: {},
1546
+ defines: {},
1547
+ modules: [],
1548
+ moduleSettings: void 0,
1549
+ geometry: null,
1550
+ indexBuffer: null,
1551
+ attributes: {},
1552
+ constantAttributes: {},
1553
+ varyings: [],
1554
+ shaderInputs: void 0,
1555
+ pipelineFactory: void 0,
1556
+ shaderFactory: void 0,
1557
+ transformFeedback: void 0,
1558
+ shaderAssembler: import_shadertools2.ShaderAssembler.getDefaultShaderAssembler(),
1559
+ debugShaders: void 0,
1560
+ ignoreUnknownAttributes: void 0
1561
+ });
1562
+ function mergeBufferLayouts(layouts1, layouts2) {
1563
+ const layouts = [...layouts1];
1564
+ for (const attribute of layouts2) {
1565
+ const index = layouts.findIndex((attribute2) => attribute2.name === attribute.name);
1566
+ if (index < 0) {
1567
+ layouts.push(attribute);
1568
+ } else {
1569
+ layouts[index] = attribute;
1570
+ }
1571
+ }
1572
+ return layouts;
1573
+ }
1574
+ function getPlatformInfo(device) {
1575
+ return {
1576
+ type: device.type,
1577
+ shaderLanguage: device.info.shadingLanguage,
1578
+ shaderLanguageVersion: device.info.shadingLanguageVersion,
1579
+ gpu: device.info.gpu,
1580
+ // HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
1581
+ features: device.features
1582
+ };
1583
+ }
1584
+ function getAttributeNames(bufferLayout) {
1585
+ var _a;
1586
+ return bufferLayout.attributes ? (_a = bufferLayout.attributes) == null ? void 0 : _a.map((layout) => layout.attribute) : [bufferLayout.name];
1587
+ }
1588
+
1589
+ // dist/transform/buffer-transform.js
1590
+ var import_core12 = require("@luma.gl/core");
1591
+ var import_shadertools3 = require("@luma.gl/shadertools");
1592
+ var BufferTransform = class {
1593
+ device;
1594
+ model;
1595
+ transformFeedback;
1596
+ /** @deprecated Use device feature test. */
1597
+ static isSupported(device) {
1598
+ var _a;
1599
+ return ((_a = device == null ? void 0 : device.info) == null ? void 0 : _a.type) === "webgl";
1600
+ }
1601
+ constructor(device, props = Model.defaultProps) {
1602
+ (0, import_core12.assert)(BufferTransform.isSupported(device), "BufferTransform not yet implemented on WebGPU");
1603
+ this.device = device;
1604
+ this.model = new Model(this.device, {
1605
+ id: props.id || "buffer-transform-model",
1606
+ fs: props.fs || (0, import_shadertools3.getPassthroughFS)(),
1607
+ topology: props.topology || "point-list",
1608
+ ...props
1609
+ });
1610
+ this.transformFeedback = this.device.createTransformFeedback({
1611
+ layout: this.model.pipeline.shaderLayout,
1612
+ buffers: props.feedbackBuffers
1613
+ });
1614
+ this.model.setTransformFeedback(this.transformFeedback);
1615
+ Object.seal(this);
1616
+ }
1617
+ /** Destroy owned resources. */
1618
+ destroy() {
1619
+ if (this.model) {
1620
+ this.model.destroy();
1621
+ }
1622
+ }
1623
+ /** @deprecated Use {@link destroy}. */
1624
+ delete() {
1625
+ this.destroy();
1626
+ }
1627
+ /** Run one transform loop. */
1628
+ run(options) {
1629
+ const renderPass = this.device.beginRenderPass(options);
1630
+ this.model.draw(renderPass);
1631
+ renderPass.end();
1632
+ }
1633
+ /** @deprecated */
1634
+ update(...args) {
1635
+ console.warn("TextureTransform#update() not implemented");
1636
+ }
1637
+ /** Returns the {@link Buffer} or {@link BufferRange} for given varying name. */
1638
+ getBuffer(varyingName) {
1639
+ return this.transformFeedback.getBuffer(varyingName);
1640
+ }
1641
+ readAsync(varyingName) {
1642
+ const result = this.getBuffer(varyingName);
1643
+ if (result instanceof import_core12.Buffer) {
1644
+ return result.readAsync();
1645
+ }
1646
+ const { buffer, byteOffset = 0, byteLength = buffer.byteLength } = result;
1647
+ return buffer.readAsync(byteOffset, byteLength);
1648
+ }
1649
+ };
1650
+
1651
+ // dist/transform/texture-transform.js
1652
+ var import_shadertools4 = require("@luma.gl/shadertools");
1653
+ var FS_OUTPUT_VARIABLE = "transform_output";
1654
+ var TextureTransform = class {
1655
+ device;
1656
+ model;
1657
+ sampler;
1658
+ currentIndex = 0;
1659
+ samplerTextureMap = null;
1660
+ bindings = [];
1661
+ // each element is an object : {sourceTextures, targetTexture, framebuffer}
1662
+ resources = {};
1663
+ // resources to be deleted
1664
+ constructor(device, props) {
1665
+ this.device = device;
1666
+ this.sampler = device.createSampler({
1667
+ addressModeU: "clamp-to-edge",
1668
+ addressModeV: "clamp-to-edge",
1669
+ minFilter: "nearest",
1670
+ magFilter: "nearest",
1671
+ mipmapFilter: "nearest"
1672
+ });
1673
+ this.model = new Model(this.device, {
1674
+ id: props.id || "texture-transform-model",
1675
+ fs: props.fs || (0, import_shadertools4.getPassthroughFS)({
1676
+ input: props.targetTextureVarying,
1677
+ inputChannels: props.targetTextureChannels,
1678
+ output: FS_OUTPUT_VARIABLE
1679
+ }),
1680
+ vertexCount: props.vertexCount,
1681
+ // TODO(donmccurdy): Naming?
1682
+ ...props
1683
+ });
1684
+ this._initialize(props);
1685
+ Object.seal(this);
1686
+ }
1687
+ // Delete owned resources.
1688
+ destroy() {
1689
+ }
1690
+ /** @deprecated Use {@link destroy}. */
1691
+ delete() {
1692
+ this.destroy();
1693
+ }
1694
+ run(options) {
1695
+ const { framebuffer } = this.bindings[this.currentIndex];
1696
+ const renderPass = this.device.beginRenderPass({ framebuffer, ...options });
1697
+ this.model.draw(renderPass);
1698
+ renderPass.end();
1699
+ }
1700
+ /** @deprecated */
1701
+ update(...args) {
1702
+ console.warn("TextureTransform#update() not implemented");
1703
+ }
1704
+ getData({ packed = false } = {}) {
1705
+ throw new Error("getData() not implemented");
1706
+ }
1707
+ getTargetTexture() {
1708
+ const { targetTexture } = this.bindings[this.currentIndex];
1709
+ return targetTexture;
1710
+ }
1711
+ getFramebuffer() {
1712
+ const currentResources = this.bindings[this.currentIndex];
1713
+ return currentResources.framebuffer;
1714
+ }
1715
+ // Private
1716
+ _initialize(props) {
1717
+ this._updateBindings(props);
1718
+ }
1719
+ _updateBindings(props) {
1720
+ this.bindings[this.currentIndex] = this._updateBinding(this.bindings[this.currentIndex], props);
1721
+ }
1722
+ _updateBinding(binding, { sourceBuffers, sourceTextures, targetTexture }) {
1723
+ if (!binding) {
1724
+ binding = {
1725
+ sourceBuffers: {},
1726
+ sourceTextures: {},
1727
+ targetTexture: null
1728
+ };
1729
+ }
1730
+ Object.assign(binding.sourceTextures, sourceTextures);
1731
+ Object.assign(binding.sourceBuffers, sourceBuffers);
1732
+ if (targetTexture) {
1733
+ binding.targetTexture = targetTexture;
1734
+ const { width, height } = targetTexture;
1735
+ if (binding.framebuffer) {
1736
+ binding.framebuffer.destroy();
1737
+ }
1738
+ binding.framebuffer = this.device.createFramebuffer({
1739
+ id: "transform-framebuffer",
1740
+ width,
1741
+ height,
1742
+ colorAttachments: [targetTexture]
1743
+ });
1744
+ binding.framebuffer.resize({ width, height });
1745
+ }
1746
+ return binding;
1747
+ }
1748
+ // set texture filtering parameters on source textures.
1749
+ _setSourceTextureParameters() {
1750
+ const index = this.currentIndex;
1751
+ const { sourceTextures } = this.bindings[index];
1752
+ for (const name in sourceTextures) {
1753
+ sourceTextures[name].sampler = this.sampler;
1754
+ }
1755
+ }
1756
+ };
1757
+
1758
+ // dist/lib/clip-space.js
1759
+ var import_core14 = require("@luma.gl/core");
1760
+
1761
+ // dist/geometry/geometry.js
1762
+ var import_core13 = require("@luma.gl/core");
1763
+ var Geometry = class {
1764
+ id;
1765
+ /** Determines how vertices are read from the 'vertex' attributes */
1766
+ topology;
1767
+ vertexCount;
1768
+ indices;
1769
+ attributes;
1770
+ userData = {};
1771
+ constructor(props) {
1772
+ const { attributes = {}, indices = null, vertexCount = null } = props;
1773
+ this.id = props.id || (0, import_core13.uid)("geometry");
1774
+ this.topology = props.topology;
1775
+ if (indices) {
1776
+ this.indices = ArrayBuffer.isView(indices) ? { value: indices, size: 1 } : indices;
1777
+ }
1778
+ this.attributes = {};
1779
+ for (const [attributeName, attributeValue] of Object.entries(attributes)) {
1780
+ const attribute = ArrayBuffer.isView(attributeValue) ? { value: attributeValue } : attributeValue;
1781
+ (0, import_core13.assert)(ArrayBuffer.isView(attribute.value), `${this._print(attributeName)}: must be typed array or object with value as typed array`);
1782
+ if ((attributeName === "POSITION" || attributeName === "positions") && !attribute.size) {
1783
+ attribute.size = 3;
1784
+ }
1785
+ if (attributeName === "indices") {
1786
+ (0, import_core13.assert)(!this.indices);
1787
+ this.indices = attribute;
1788
+ } else {
1789
+ this.attributes[attributeName] = attribute;
1790
+ }
1791
+ }
1792
+ if (this.indices && this.indices.isIndexed !== void 0) {
1793
+ this.indices = Object.assign({}, this.indices);
1794
+ delete this.indices.isIndexed;
1795
+ }
1796
+ this.vertexCount = vertexCount || this._calculateVertexCount(this.attributes, this.indices);
1797
+ }
1798
+ getVertexCount() {
1799
+ return this.vertexCount;
1800
+ }
1801
+ /**
1802
+ * Return an object with all attributes plus indices added as a field.
1803
+ * TODO Geometry types are a mess
1804
+ */
1805
+ getAttributes() {
1806
+ return this.indices ? { indices: this.indices, ...this.attributes } : this.attributes;
1807
+ }
1808
+ // PRIVATE
1809
+ _print(attributeName) {
1810
+ return `Geometry ${this.id} attribute ${attributeName}`;
1811
+ }
1812
+ /**
1813
+ * GeometryAttribute
1814
+ * value: typed array
1815
+ * type: indices, vertices, uvs
1816
+ * size: elements per vertex
1817
+ * target: WebGL buffer type (string or constant)
1818
+ *
1819
+ * @param attributes
1820
+ * @param indices
1821
+ * @returns
1822
+ */
1823
+ _setAttributes(attributes, indices) {
1824
+ return this;
1825
+ }
1826
+ _calculateVertexCount(attributes, indices) {
1827
+ if (indices) {
1828
+ return indices.value.length;
1829
+ }
1830
+ let vertexCount = Infinity;
1831
+ for (const attribute of Object.values(attributes)) {
1832
+ const { value, size, constant } = attribute;
1833
+ if (!constant && value && size >= 1) {
1834
+ vertexCount = Math.min(vertexCount, value.length / size);
1835
+ }
1836
+ }
1837
+ (0, import_core13.assert)(Number.isFinite(vertexCount));
1838
+ return vertexCount;
1839
+ }
1840
+ };
1841
+
1842
+ // dist/lib/clip-space.js
1843
+ var CLIPSPACE_VERTEX_SHADER = `#version 300 es
1844
+ in vec2 aClipSpacePosition;
1845
+ in vec2 aTexCoord;
1846
+ in vec2 aCoordinate;
1847
+ out vec2 position;
1848
+ out vec2 coordinate;
1849
+ out vec2 uv;
1850
+ void main(void) {
1851
+ gl_Position = vec4(aClipSpacePosition, 0., 1.);
1852
+ position = aClipSpacePosition;
1853
+ coordinate = aCoordinate;
1854
+ uv = aTexCoord;
1855
+ }
1856
+ `;
1857
+ var POSITIONS = [-1, -1, 1, -1, -1, 1, 1, 1];
1858
+ var ClipSpace = class extends Model {
1859
+ constructor(device, opts) {
1860
+ const TEX_COORDS = POSITIONS.map((coord) => coord === -1 ? 0 : coord);
1861
+ super(device, {
1862
+ ...opts,
1863
+ vs: CLIPSPACE_VERTEX_SHADER,
1864
+ vertexCount: 4,
1865
+ geometry: new Geometry({
1866
+ topology: "triangle-strip",
1867
+ vertexCount: 4,
1868
+ attributes: {
1869
+ aClipSpacePosition: { size: 2, value: new Float32Array(POSITIONS) },
1870
+ aTexCoord: { size: 2, value: new Float32Array(TEX_COORDS) },
1871
+ aCoordinate: { size: 2, value: new Float32Array(TEX_COORDS) }
1872
+ }
1873
+ })
1874
+ });
1875
+ }
1876
+ };
1877
+
1878
+ // dist/scenegraph/scenegraph-node.js
1879
+ var import_core15 = require("@luma.gl/core");
1880
+ var import_core16 = require("@math.gl/core");
1881
+ var ScenegraphNode = class {
1882
+ id;
1883
+ matrix = new import_core16.Matrix4();
1884
+ display = true;
1885
+ position = new import_core16.Vector3();
1886
+ rotation = new import_core16.Vector3();
1887
+ scale = new import_core16.Vector3(1, 1, 1);
1888
+ userData = {};
1889
+ props = {};
1890
+ constructor(props = {}) {
1891
+ const { id } = props;
1892
+ this.id = id || (0, import_core15.uid)(this.constructor.name);
1893
+ this._setScenegraphNodeProps(props);
1894
+ }
1895
+ getBounds() {
1896
+ return null;
1897
+ }
1898
+ destroy() {
1899
+ }
1900
+ /** @deprecated use .destroy() */
1901
+ delete() {
1902
+ this.destroy();
1903
+ }
1904
+ setProps(props) {
1905
+ this._setScenegraphNodeProps(props);
1906
+ return this;
1907
+ }
1908
+ toString() {
1909
+ return `{type: ScenegraphNode, id: ${this.id})}`;
1910
+ }
1911
+ setPosition(position) {
1912
+ (0, import_core15.assert)(position.length === 3, "setPosition requires vector argument");
1913
+ this.position = position;
1914
+ return this;
1915
+ }
1916
+ setRotation(rotation) {
1917
+ (0, import_core15.assert)(rotation.length === 3, "setRotation requires vector argument");
1918
+ this.rotation = rotation;
1919
+ return this;
1920
+ }
1921
+ setScale(scale) {
1922
+ (0, import_core15.assert)(scale.length === 3, "setScale requires vector argument");
1923
+ this.scale = scale;
1924
+ return this;
1925
+ }
1926
+ setMatrix(matrix, copyMatrix = true) {
1927
+ if (copyMatrix) {
1928
+ this.matrix.copy(matrix);
1929
+ } else {
1930
+ this.matrix = matrix;
1931
+ }
1932
+ }
1933
+ setMatrixComponents(components) {
1934
+ const { position, rotation, scale, update = true } = components;
1935
+ if (position) {
1936
+ this.setPosition(position);
1937
+ }
1938
+ if (rotation) {
1939
+ this.setRotation(rotation);
1940
+ }
1941
+ if (scale) {
1942
+ this.setScale(scale);
1943
+ }
1944
+ if (update) {
1945
+ this.updateMatrix();
1946
+ }
1947
+ return this;
1948
+ }
1949
+ updateMatrix() {
1950
+ const pos = this.position;
1951
+ const rot = this.rotation;
1952
+ const scale = this.scale;
1953
+ this.matrix.identity();
1954
+ this.matrix.translate(pos);
1955
+ this.matrix.rotateXYZ(rot);
1956
+ this.matrix.scale(scale);
1957
+ return this;
1958
+ }
1959
+ update(options = {}) {
1960
+ const { position, rotation, scale } = options;
1961
+ if (position) {
1962
+ this.setPosition(position);
1963
+ }
1964
+ if (rotation) {
1965
+ this.setRotation(rotation);
1966
+ }
1967
+ if (scale) {
1968
+ this.setScale(scale);
1969
+ }
1970
+ this.updateMatrix();
1971
+ return this;
1972
+ }
1973
+ getCoordinateUniforms(viewMatrix, modelMatrix) {
1974
+ (0, import_core15.assert)(viewMatrix);
1975
+ modelMatrix = modelMatrix || this.matrix;
1976
+ const worldMatrix = new import_core16.Matrix4(viewMatrix).multiplyRight(modelMatrix);
1977
+ const worldInverse = worldMatrix.invert();
1978
+ const worldInverseTranspose = worldInverse.transpose();
1979
+ return {
1980
+ viewMatrix,
1981
+ modelMatrix,
1982
+ objectMatrix: modelMatrix,
1983
+ worldMatrix,
1984
+ worldInverseMatrix: worldInverse,
1985
+ worldInverseTransposeMatrix: worldInverseTranspose
1986
+ };
1987
+ }
1988
+ // TODO - copied code, not yet vetted
1989
+ /*
1990
+ transform() {
1991
+ if (!this.parent) {
1992
+ this.endPosition.set(this.position);
1993
+ this.endRotation.set(this.rotation);
1994
+ this.endScale.set(this.scale);
1995
+ } else {
1996
+ const parent = this.parent;
1997
+ this.endPosition.set(this.position.add(parent.endPosition));
1998
+ this.endRotation.set(this.rotation.add(parent.endRotation));
1999
+ this.endScale.set(this.scale.add(parent.endScale));
2000
+ }
2001
+
2002
+ const ch = this.children;
2003
+ for (let i = 0; i < ch.length; ++i) {
2004
+ ch[i].transform();
2005
+ }
2006
+
2007
+ return this;
2008
+ }
2009
+ */
2010
+ _setScenegraphNodeProps(props) {
2011
+ if ("display" in props) {
2012
+ this.display = props.display;
2013
+ }
2014
+ if ("position" in props) {
2015
+ this.setPosition(props.position);
2016
+ }
2017
+ if ("rotation" in props) {
2018
+ this.setRotation(props.rotation);
2019
+ }
2020
+ if ("scale" in props) {
2021
+ this.setScale(props.scale);
2022
+ }
2023
+ if ("matrix" in props) {
2024
+ this.setMatrix(props.matrix);
2025
+ }
2026
+ Object.assign(this.props, props);
2027
+ }
2028
+ };
2029
+
2030
+ // dist/scenegraph/group-node.js
2031
+ var import_core17 = require("@math.gl/core");
2032
+ var import_core18 = require("@luma.gl/core");
2033
+ var GroupNode = class extends ScenegraphNode {
2034
+ children;
2035
+ constructor(props = {}) {
2036
+ props = Array.isArray(props) ? { children: props } : props;
2037
+ const { children = [] } = props;
2038
+ import_core18.log.assert(children.every((child) => child instanceof ScenegraphNode), "every child must an instance of ScenegraphNode");
2039
+ super(props);
2040
+ this.children = children;
2041
+ }
2042
+ getBounds() {
2043
+ const result = [
2044
+ [Infinity, Infinity, Infinity],
2045
+ [-Infinity, -Infinity, -Infinity]
2046
+ ];
2047
+ this.traverse((node, { worldMatrix }) => {
2048
+ const bounds = node.getBounds();
2049
+ if (!bounds) {
2050
+ return;
2051
+ }
2052
+ const [min, max] = bounds;
2053
+ const center = new import_core17.Vector3(min).add(max).divide([2, 2, 2]);
2054
+ worldMatrix.transformAsPoint(center, center);
2055
+ const halfSize = new import_core17.Vector3(max).subtract(min).divide([2, 2, 2]);
2056
+ worldMatrix.transformAsVector(halfSize, halfSize);
2057
+ for (let v = 0; v < 8; v++) {
2058
+ const position = new import_core17.Vector3(v & 1 ? -1 : 1, v & 2 ? -1 : 1, v & 4 ? -1 : 1).multiply(halfSize).add(center);
2059
+ for (let i = 0; i < 3; i++) {
2060
+ result[0][i] = Math.min(result[0][i], position[i]);
2061
+ result[1][i] = Math.max(result[1][i], position[i]);
2062
+ }
2063
+ }
2064
+ });
2065
+ if (!Number.isFinite(result[0][0])) {
2066
+ return null;
2067
+ }
2068
+ return result;
2069
+ }
2070
+ destroy() {
2071
+ this.children.forEach((child) => child.destroy());
2072
+ this.removeAll();
2073
+ super.destroy();
2074
+ }
2075
+ // Unpacks arrays and nested arrays of children
2076
+ add(...children) {
2077
+ for (const child of children) {
2078
+ if (Array.isArray(child)) {
2079
+ this.add(...child);
2080
+ } else {
2081
+ this.children.push(child);
2082
+ }
2083
+ }
2084
+ return this;
2085
+ }
2086
+ remove(child) {
2087
+ const children = this.children;
2088
+ const indexOf = children.indexOf(child);
2089
+ if (indexOf > -1) {
2090
+ children.splice(indexOf, 1);
2091
+ }
2092
+ return this;
2093
+ }
2094
+ removeAll() {
2095
+ this.children = [];
2096
+ return this;
2097
+ }
2098
+ traverse(visitor, { worldMatrix = new import_core17.Matrix4() } = {}) {
2099
+ const modelMatrix = new import_core17.Matrix4(worldMatrix).multiplyRight(this.matrix);
2100
+ for (const child of this.children) {
2101
+ if (child instanceof GroupNode) {
2102
+ child.traverse(visitor, { worldMatrix: modelMatrix });
2103
+ } else {
2104
+ visitor(child, { worldMatrix: modelMatrix });
2105
+ }
2106
+ }
2107
+ }
2108
+ };
2109
+
2110
+ // dist/scenegraph/model-node.js
2111
+ var ModelNode = class extends ScenegraphNode {
2112
+ model;
2113
+ bounds = null;
2114
+ managedResources;
2115
+ // TODO - is this used? override callbacks to make sure we call them with this
2116
+ // onBeforeRender = null;
2117
+ // onAfterRender = null;
2118
+ // AfterRender = null;
2119
+ constructor(props) {
2120
+ super(props);
2121
+ this.model = props.model;
2122
+ this.managedResources = props.managedResources || [];
2123
+ this.bounds = props.bounds || null;
2124
+ this.setProps(props);
2125
+ }
2126
+ getBounds() {
2127
+ return this.bounds;
2128
+ }
2129
+ destroy() {
2130
+ if (this.model) {
2131
+ this.model.destroy();
2132
+ this.model = null;
2133
+ }
2134
+ this.managedResources.forEach((resource) => resource.destroy());
2135
+ this.managedResources = [];
2136
+ }
2137
+ // Expose model methods
2138
+ draw(renderPass) {
2139
+ return this.model.draw(renderPass);
2140
+ }
2141
+ };
2142
+
2143
+ // dist/geometries/cone-geometry.js
2144
+ var import_core20 = require("@luma.gl/core");
2145
+
2146
+ // dist/geometries/truncated-cone-geometry.js
2147
+ var import_core19 = require("@luma.gl/core");
2148
+ var INDEX_OFFSETS = {
2149
+ x: [2, 0, 1],
2150
+ y: [0, 1, 2],
2151
+ z: [1, 2, 0]
2152
+ };
2153
+ var TruncatedConeGeometry = class extends Geometry {
2154
+ constructor(props = {}) {
2155
+ const { id = (0, import_core19.uid)("truncated-code-geometry") } = props;
2156
+ const { indices, attributes } = tesselateTruncatedCone(props);
2157
+ super({
2158
+ ...props,
2159
+ id,
2160
+ topology: "triangle-list",
2161
+ indices,
2162
+ attributes: {
2163
+ POSITION: { size: 3, value: attributes.POSITION },
2164
+ NORMAL: { size: 3, value: attributes.NORMAL },
2165
+ TEXCOORD_0: { size: 2, value: attributes.TEXCOORD_0 },
2166
+ ...props.attributes
2167
+ }
2168
+ });
2169
+ }
2170
+ };
2171
+ function tesselateTruncatedCone(props = {}) {
2172
+ const { bottomRadius = 0, topRadius = 0, height = 1, nradial = 10, nvertical = 10, verticalAxis = "y", topCap = false, bottomCap = false } = props;
2173
+ const extra = (topCap ? 2 : 0) + (bottomCap ? 2 : 0);
2174
+ const numVertices = (nradial + 1) * (nvertical + 1 + extra);
2175
+ const slant = Math.atan2(bottomRadius - topRadius, height);
2176
+ const msin = Math.sin;
2177
+ const mcos = Math.cos;
2178
+ const mpi = Math.PI;
2179
+ const cosSlant = mcos(slant);
2180
+ const sinSlant = msin(slant);
2181
+ const start = topCap ? -2 : 0;
2182
+ const end = nvertical + (bottomCap ? 2 : 0);
2183
+ const vertsAroundEdge = nradial + 1;
2184
+ const indices = new Uint16Array(nradial * (nvertical + extra) * 6);
2185
+ const indexOffset = INDEX_OFFSETS[verticalAxis];
2186
+ const positions = new Float32Array(numVertices * 3);
2187
+ const normals = new Float32Array(numVertices * 3);
2188
+ const texCoords = new Float32Array(numVertices * 2);
2189
+ let i3 = 0;
2190
+ let i2 = 0;
2191
+ for (let i = start; i <= end; i++) {
2192
+ let v = i / nvertical;
2193
+ let y = height * v;
2194
+ let ringRadius;
2195
+ if (i < 0) {
2196
+ y = 0;
2197
+ v = 1;
2198
+ ringRadius = bottomRadius;
2199
+ } else if (i > nvertical) {
2200
+ y = height;
2201
+ v = 1;
2202
+ ringRadius = topRadius;
2203
+ } else {
2204
+ ringRadius = bottomRadius + (topRadius - bottomRadius) * (i / nvertical);
2205
+ }
2206
+ if (i === -2 || i === nvertical + 2) {
2207
+ ringRadius = 0;
2208
+ v = 0;
2209
+ }
2210
+ y -= height / 2;
2211
+ for (let j = 0; j < vertsAroundEdge; j++) {
2212
+ const sin = msin(j * mpi * 2 / nradial);
2213
+ const cos = mcos(j * mpi * 2 / nradial);
2214
+ positions[i3 + indexOffset[0]] = sin * ringRadius;
2215
+ positions[i3 + indexOffset[1]] = y;
2216
+ positions[i3 + indexOffset[2]] = cos * ringRadius;
2217
+ normals[i3 + indexOffset[0]] = i < 0 || i > nvertical ? 0 : sin * cosSlant;
2218
+ normals[i3 + indexOffset[1]] = i < 0 ? -1 : i > nvertical ? 1 : sinSlant;
2219
+ normals[i3 + indexOffset[2]] = i < 0 || i > nvertical ? 0 : cos * cosSlant;
2220
+ texCoords[i2 + 0] = j / nradial;
2221
+ texCoords[i2 + 1] = v;
2222
+ i2 += 2;
2223
+ i3 += 3;
2224
+ }
2225
+ }
2226
+ for (let i = 0; i < nvertical + extra; i++) {
2227
+ for (let j = 0; j < nradial; j++) {
2228
+ const index = (i * nradial + j) * 6;
2229
+ indices[index + 0] = vertsAroundEdge * (i + 0) + 0 + j;
2230
+ indices[index + 1] = vertsAroundEdge * (i + 0) + 1 + j;
2231
+ indices[index + 2] = vertsAroundEdge * (i + 1) + 1 + j;
2232
+ indices[index + 3] = vertsAroundEdge * (i + 0) + 0 + j;
2233
+ indices[index + 4] = vertsAroundEdge * (i + 1) + 1 + j;
2234
+ indices[index + 5] = vertsAroundEdge * (i + 1) + 0 + j;
2235
+ }
2236
+ }
2237
+ return {
2238
+ indices,
2239
+ attributes: {
2240
+ POSITION: positions,
2241
+ NORMAL: normals,
2242
+ TEXCOORD_0: texCoords
2243
+ }
2244
+ };
2245
+ }
2246
+
2247
+ // dist/geometries/cone-geometry.js
2248
+ var ConeGeometry = class extends TruncatedConeGeometry {
2249
+ constructor(props = {}) {
2250
+ const { id = (0, import_core20.uid)("cone-geometry"), radius = 1, cap = true } = props;
2251
+ super({
2252
+ ...props,
2253
+ id,
2254
+ topRadius: 0,
2255
+ topCap: Boolean(cap),
2256
+ bottomCap: Boolean(cap),
2257
+ bottomRadius: radius
2258
+ });
2259
+ }
2260
+ };
2261
+
2262
+ // dist/geometries/cube-geometry.js
2263
+ var import_core21 = require("@luma.gl/core");
2264
+ var CubeGeometry = class extends Geometry {
2265
+ constructor(props = {}) {
2266
+ const { id = (0, import_core21.uid)("cube-geometry"), indices = true } = props;
2267
+ super(indices ? {
2268
+ ...props,
2269
+ id,
2270
+ topology: "triangle-list",
2271
+ indices: { size: 1, value: CUBE_INDICES },
2272
+ attributes: { ...ATTRIBUTES, ...props.attributes }
2273
+ } : {
2274
+ ...props,
2275
+ id,
2276
+ topology: "triangle-list",
2277
+ indices: void 0,
2278
+ attributes: { ...NON_INDEXED_ATTRIBUTES, ...props.attributes }
2279
+ });
2280
+ }
2281
+ };
2282
+ var CUBE_INDICES = new Uint16Array([
2283
+ 0,
2284
+ 1,
2285
+ 2,
2286
+ 0,
2287
+ 2,
2288
+ 3,
2289
+ 4,
2290
+ 5,
2291
+ 6,
2292
+ 4,
2293
+ 6,
2294
+ 7,
2295
+ 8,
2296
+ 9,
2297
+ 10,
2298
+ 8,
2299
+ 10,
2300
+ 11,
2301
+ 12,
2302
+ 13,
2303
+ 14,
2304
+ 12,
2305
+ 14,
2306
+ 15,
2307
+ 16,
2308
+ 17,
2309
+ 18,
2310
+ 16,
2311
+ 18,
2312
+ 19,
2313
+ 20,
2314
+ 21,
2315
+ 22,
2316
+ 20,
2317
+ 22,
2318
+ 23
2319
+ ]);
2320
+ var CUBE_POSITIONS = new Float32Array([
2321
+ -1,
2322
+ -1,
2323
+ 1,
2324
+ 1,
2325
+ -1,
2326
+ 1,
2327
+ 1,
2328
+ 1,
2329
+ 1,
2330
+ -1,
2331
+ 1,
2332
+ 1,
2333
+ -1,
2334
+ -1,
2335
+ -1,
2336
+ -1,
2337
+ 1,
2338
+ -1,
2339
+ 1,
2340
+ 1,
2341
+ -1,
2342
+ 1,
2343
+ -1,
2344
+ -1,
2345
+ -1,
2346
+ 1,
2347
+ -1,
2348
+ -1,
2349
+ 1,
2350
+ 1,
2351
+ 1,
2352
+ 1,
2353
+ 1,
2354
+ 1,
2355
+ 1,
2356
+ -1,
2357
+ -1,
2358
+ -1,
2359
+ -1,
2360
+ 1,
2361
+ -1,
2362
+ -1,
2363
+ 1,
2364
+ -1,
2365
+ 1,
2366
+ -1,
2367
+ -1,
2368
+ 1,
2369
+ 1,
2370
+ -1,
2371
+ -1,
2372
+ 1,
2373
+ 1,
2374
+ -1,
2375
+ 1,
2376
+ 1,
2377
+ 1,
2378
+ 1,
2379
+ -1,
2380
+ 1,
2381
+ -1,
2382
+ -1,
2383
+ -1,
2384
+ -1,
2385
+ -1,
2386
+ 1,
2387
+ -1,
2388
+ 1,
2389
+ 1,
2390
+ -1,
2391
+ 1,
2392
+ -1
2393
+ ]);
2394
+ var CUBE_NORMALS = new Float32Array([
2395
+ // Front face
2396
+ 0,
2397
+ 0,
2398
+ 1,
2399
+ 0,
2400
+ 0,
2401
+ 1,
2402
+ 0,
2403
+ 0,
2404
+ 1,
2405
+ 0,
2406
+ 0,
2407
+ 1,
2408
+ // Back face
2409
+ 0,
2410
+ 0,
2411
+ -1,
2412
+ 0,
2413
+ 0,
2414
+ -1,
2415
+ 0,
2416
+ 0,
2417
+ -1,
2418
+ 0,
2419
+ 0,
2420
+ -1,
2421
+ // Top face
2422
+ 0,
2423
+ 1,
2424
+ 0,
2425
+ 0,
2426
+ 1,
2427
+ 0,
2428
+ 0,
2429
+ 1,
2430
+ 0,
2431
+ 0,
2432
+ 1,
2433
+ 0,
2434
+ // Bottom face
2435
+ 0,
2436
+ -1,
2437
+ 0,
2438
+ 0,
2439
+ -1,
2440
+ 0,
2441
+ 0,
2442
+ -1,
2443
+ 0,
2444
+ 0,
2445
+ -1,
2446
+ 0,
2447
+ // Right face
2448
+ 1,
2449
+ 0,
2450
+ 0,
2451
+ 1,
2452
+ 0,
2453
+ 0,
2454
+ 1,
2455
+ 0,
2456
+ 0,
2457
+ 1,
2458
+ 0,
2459
+ 0,
2460
+ // Left face
2461
+ -1,
2462
+ 0,
2463
+ 0,
2464
+ -1,
2465
+ 0,
2466
+ 0,
2467
+ -1,
2468
+ 0,
2469
+ 0,
2470
+ -1,
2471
+ 0,
2472
+ 0
2473
+ ]);
2474
+ var CUBE_TEX_COORDS = new Float32Array([
2475
+ // Front face
2476
+ 0,
2477
+ 0,
2478
+ 1,
2479
+ 0,
2480
+ 1,
2481
+ 1,
2482
+ 0,
2483
+ 1,
2484
+ // Back face
2485
+ 1,
2486
+ 0,
2487
+ 1,
2488
+ 1,
2489
+ 0,
2490
+ 1,
2491
+ 0,
2492
+ 0,
2493
+ // Top face
2494
+ 0,
2495
+ 1,
2496
+ 0,
2497
+ 0,
2498
+ 1,
2499
+ 0,
2500
+ 1,
2501
+ 1,
2502
+ // Bottom face
2503
+ 1,
2504
+ 1,
2505
+ 0,
2506
+ 1,
2507
+ 0,
2508
+ 0,
2509
+ 1,
2510
+ 0,
2511
+ // Right face
2512
+ 1,
2513
+ 0,
2514
+ 1,
2515
+ 1,
2516
+ 0,
2517
+ 1,
2518
+ 0,
2519
+ 0,
2520
+ // Left face
2521
+ 0,
2522
+ 0,
2523
+ 1,
2524
+ 0,
2525
+ 1,
2526
+ 1,
2527
+ 0,
2528
+ 1
2529
+ ]);
2530
+ var CUBE_NON_INDEXED_POSITIONS = new Float32Array([
2531
+ 1,
2532
+ -1,
2533
+ 1,
2534
+ -1,
2535
+ -1,
2536
+ 1,
2537
+ -1,
2538
+ -1,
2539
+ -1,
2540
+ 1,
2541
+ -1,
2542
+ -1,
2543
+ 1,
2544
+ -1,
2545
+ 1,
2546
+ -1,
2547
+ -1,
2548
+ -1,
2549
+ 1,
2550
+ 1,
2551
+ 1,
2552
+ 1,
2553
+ -1,
2554
+ 1,
2555
+ 1,
2556
+ -1,
2557
+ -1,
2558
+ 1,
2559
+ 1,
2560
+ -1,
2561
+ 1,
2562
+ 1,
2563
+ 1,
2564
+ 1,
2565
+ -1,
2566
+ -1,
2567
+ -1,
2568
+ 1,
2569
+ 1,
2570
+ 1,
2571
+ 1,
2572
+ 1,
2573
+ 1,
2574
+ 1,
2575
+ -1,
2576
+ -1,
2577
+ 1,
2578
+ -1,
2579
+ -1,
2580
+ 1,
2581
+ 1,
2582
+ 1,
2583
+ 1,
2584
+ -1,
2585
+ -1,
2586
+ -1,
2587
+ 1,
2588
+ -1,
2589
+ 1,
2590
+ 1,
2591
+ -1,
2592
+ 1,
2593
+ -1,
2594
+ -1,
2595
+ -1,
2596
+ -1,
2597
+ -1,
2598
+ -1,
2599
+ 1,
2600
+ -1,
2601
+ 1,
2602
+ -1,
2603
+ 1,
2604
+ 1,
2605
+ 1,
2606
+ -1,
2607
+ 1,
2608
+ 1,
2609
+ -1,
2610
+ -1,
2611
+ 1,
2612
+ -1,
2613
+ -1,
2614
+ 1,
2615
+ 1,
2616
+ -1,
2617
+ 1,
2618
+ 1,
2619
+ 1,
2620
+ 1,
2621
+ 1,
2622
+ -1,
2623
+ -1,
2624
+ -1,
2625
+ -1,
2626
+ -1,
2627
+ -1,
2628
+ 1,
2629
+ -1,
2630
+ 1,
2631
+ 1,
2632
+ -1,
2633
+ 1,
2634
+ -1,
2635
+ -1,
2636
+ -1,
2637
+ 1,
2638
+ -1
2639
+ ]);
2640
+ var CUBE_NON_INDEXED_TEX_COORDS = new Float32Array([
2641
+ 1,
2642
+ 1,
2643
+ 0,
2644
+ 1,
2645
+ 0,
2646
+ 0,
2647
+ 1,
2648
+ 0,
2649
+ 1,
2650
+ 1,
2651
+ 0,
2652
+ 0,
2653
+ 1,
2654
+ 1,
2655
+ 0,
2656
+ 1,
2657
+ 0,
2658
+ 0,
2659
+ 1,
2660
+ 0,
2661
+ 1,
2662
+ 1,
2663
+ 0,
2664
+ 0,
2665
+ 1,
2666
+ 1,
2667
+ 0,
2668
+ 1,
2669
+ 0,
2670
+ 0,
2671
+ 1,
2672
+ 0,
2673
+ 1,
2674
+ 1,
2675
+ 0,
2676
+ 0,
2677
+ 1,
2678
+ 1,
2679
+ 0,
2680
+ 1,
2681
+ 0,
2682
+ 0,
2683
+ 1,
2684
+ 0,
2685
+ 1,
2686
+ 1,
2687
+ 0,
2688
+ 0,
2689
+ 1,
2690
+ 1,
2691
+ 0,
2692
+ 1,
2693
+ 0,
2694
+ 0,
2695
+ 0,
2696
+ 0,
2697
+ 1,
2698
+ 0,
2699
+ 1,
2700
+ 1,
2701
+ 1,
2702
+ 1,
2703
+ 0,
2704
+ 1,
2705
+ 0,
2706
+ 0,
2707
+ 1,
2708
+ 0,
2709
+ 1,
2710
+ 1,
2711
+ 0,
2712
+ 0
2713
+ ]);
2714
+ var CUBE_NON_INDEXED_COLORS = new Float32Array([
2715
+ 1,
2716
+ 0,
2717
+ 1,
2718
+ 1,
2719
+ 0,
2720
+ 0,
2721
+ 1,
2722
+ 1,
2723
+ 0,
2724
+ 0,
2725
+ 0,
2726
+ 1,
2727
+ 1,
2728
+ 0,
2729
+ 0,
2730
+ 1,
2731
+ 1,
2732
+ 0,
2733
+ 1,
2734
+ 1,
2735
+ 0,
2736
+ 0,
2737
+ 0,
2738
+ 1,
2739
+ 1,
2740
+ 1,
2741
+ 1,
2742
+ 1,
2743
+ 1,
2744
+ 0,
2745
+ 1,
2746
+ 1,
2747
+ 1,
2748
+ 0,
2749
+ 0,
2750
+ 1,
2751
+ 1,
2752
+ 1,
2753
+ 0,
2754
+ 1,
2755
+ 1,
2756
+ 1,
2757
+ 1,
2758
+ 1,
2759
+ 1,
2760
+ 0,
2761
+ 0,
2762
+ 1,
2763
+ 0,
2764
+ 1,
2765
+ 1,
2766
+ 1,
2767
+ 1,
2768
+ 1,
2769
+ 1,
2770
+ 1,
2771
+ 1,
2772
+ 1,
2773
+ 0,
2774
+ 1,
2775
+ 0,
2776
+ 1,
2777
+ 0,
2778
+ 1,
2779
+ 0,
2780
+ 1,
2781
+ 1,
2782
+ 1,
2783
+ 1,
2784
+ 1,
2785
+ 0,
2786
+ 1,
2787
+ 0,
2788
+ 0,
2789
+ 1,
2790
+ 1,
2791
+ 0,
2792
+ 1,
2793
+ 1,
2794
+ 1,
2795
+ 0,
2796
+ 1,
2797
+ 0,
2798
+ 1,
2799
+ 0,
2800
+ 0,
2801
+ 0,
2802
+ 1,
2803
+ 0,
2804
+ 0,
2805
+ 1,
2806
+ 1,
2807
+ 0,
2808
+ 1,
2809
+ 0,
2810
+ 1,
2811
+ 1,
2812
+ 1,
2813
+ 1,
2814
+ 1,
2815
+ 0,
2816
+ 1,
2817
+ 1,
2818
+ 1,
2819
+ 0,
2820
+ 0,
2821
+ 1,
2822
+ 1,
2823
+ 0,
2824
+ 0,
2825
+ 1,
2826
+ 1,
2827
+ 1,
2828
+ 0,
2829
+ 1,
2830
+ 1,
2831
+ 1,
2832
+ 1,
2833
+ 1,
2834
+ 1,
2835
+ 1,
2836
+ 0,
2837
+ 0,
2838
+ 1,
2839
+ 0,
2840
+ 0,
2841
+ 0,
2842
+ 1,
2843
+ 0,
2844
+ 1,
2845
+ 0,
2846
+ 1,
2847
+ 1,
2848
+ 1,
2849
+ 0,
2850
+ 1,
2851
+ 1,
2852
+ 0,
2853
+ 0,
2854
+ 1,
2855
+ 0,
2856
+ 1,
2857
+ 0,
2858
+ 1
2859
+ ]);
2860
+ var ATTRIBUTES = {
2861
+ POSITION: { size: 3, value: CUBE_POSITIONS },
2862
+ NORMAL: { size: 3, value: CUBE_NORMALS },
2863
+ TEXCOORD_0: { size: 2, value: CUBE_TEX_COORDS }
2864
+ };
2865
+ var NON_INDEXED_ATTRIBUTES = {
2866
+ POSITION: { size: 3, value: CUBE_NON_INDEXED_POSITIONS },
2867
+ // NORMAL: {size: 3, value: CUBE_NON_INDEXED_NORMALS},
2868
+ TEXCOORD_0: { size: 2, value: CUBE_NON_INDEXED_TEX_COORDS },
2869
+ COLOR_0: { size: 3, value: CUBE_NON_INDEXED_COLORS }
2870
+ };
2871
+
2872
+ // dist/geometries/cylinder-geometry.js
2873
+ var import_core22 = require("@luma.gl/core");
2874
+ var CylinderGeometry = class extends TruncatedConeGeometry {
2875
+ constructor(props = {}) {
2876
+ const { id = (0, import_core22.uid)("cylinder-geometry"), radius = 1 } = props;
2877
+ super({
2878
+ ...props,
2879
+ id,
2880
+ bottomRadius: radius,
2881
+ topRadius: radius
2882
+ });
2883
+ }
2884
+ };
2885
+
2886
+ // dist/geometries/ico-sphere-geometry.js
2887
+ var import_core23 = require("@luma.gl/core");
2888
+ var import_core24 = require("@math.gl/core");
2889
+ var ICO_POSITIONS = [-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 1, 0, -1, 0, 1, 0, 0];
2890
+ var ICO_INDICES = [3, 4, 5, 3, 5, 1, 3, 1, 0, 3, 0, 4, 4, 0, 2, 4, 2, 5, 2, 0, 1, 5, 2, 1];
2891
+ var IcoSphereGeometry = class extends Geometry {
2892
+ constructor(props = {}) {
2893
+ const { id = (0, import_core23.uid)("ico-sphere-geometry") } = props;
2894
+ const { indices, attributes } = tesselateIcosaHedron(props);
2895
+ super({
2896
+ ...props,
2897
+ id,
2898
+ topology: "triangle-list",
2899
+ indices,
2900
+ attributes: { ...attributes, ...props.attributes }
2901
+ });
2902
+ }
2903
+ };
2904
+ function tesselateIcosaHedron(props) {
2905
+ const { iterations = 0 } = props;
2906
+ const PI = Math.PI;
2907
+ const PI2 = PI * 2;
2908
+ const positions = [...ICO_POSITIONS];
2909
+ let indices = [...ICO_INDICES];
2910
+ positions.push();
2911
+ indices.push();
2912
+ const getMiddlePoint = (() => {
2913
+ const pointMemo = {};
2914
+ return (i1, i2) => {
2915
+ i1 *= 3;
2916
+ i2 *= 3;
2917
+ const mini = i1 < i2 ? i1 : i2;
2918
+ const maxi = i1 > i2 ? i1 : i2;
2919
+ const key = `${mini}|${maxi}`;
2920
+ if (key in pointMemo) {
2921
+ return pointMemo[key];
2922
+ }
2923
+ const x1 = positions[i1];
2924
+ const y1 = positions[i1 + 1];
2925
+ const z1 = positions[i1 + 2];
2926
+ const x2 = positions[i2];
2927
+ const y2 = positions[i2 + 1];
2928
+ const z2 = positions[i2 + 2];
2929
+ let xm = (x1 + x2) / 2;
2930
+ let ym = (y1 + y2) / 2;
2931
+ let zm = (z1 + z2) / 2;
2932
+ const len = Math.sqrt(xm * xm + ym * ym + zm * zm);
2933
+ xm /= len;
2934
+ ym /= len;
2935
+ zm /= len;
2936
+ positions.push(xm, ym, zm);
2937
+ return pointMemo[key] = positions.length / 3 - 1;
2938
+ };
2939
+ })();
2940
+ for (let i = 0; i < iterations; i++) {
2941
+ const indices2 = [];
2942
+ for (let j = 0; j < indices.length; j += 3) {
2943
+ const a = getMiddlePoint(indices[j + 0], indices[j + 1]);
2944
+ const b = getMiddlePoint(indices[j + 1], indices[j + 2]);
2945
+ const c = getMiddlePoint(indices[j + 2], indices[j + 0]);
2946
+ indices2.push(c, indices[j + 0], a, a, indices[j + 1], b, b, indices[j + 2], c, a, b, c);
2947
+ }
2948
+ indices = indices2;
2949
+ }
2950
+ const normals = new Array(positions.length);
2951
+ const texCoords = new Array(positions.length / 3 * 2);
2952
+ const l = indices.length;
2953
+ for (let i = l - 3; i >= 0; i -= 3) {
2954
+ const i1 = indices[i + 0];
2955
+ const i2 = indices[i + 1];
2956
+ const i3 = indices[i + 2];
2957
+ const in1 = i1 * 3;
2958
+ const in2 = i2 * 3;
2959
+ const in3 = i3 * 3;
2960
+ const iu1 = i1 * 2;
2961
+ const iu2 = i2 * 2;
2962
+ const iu3 = i3 * 2;
2963
+ const x1 = positions[in1 + 0];
2964
+ const y1 = positions[in1 + 1];
2965
+ const z1 = positions[in1 + 2];
2966
+ const theta1 = Math.acos(z1 / Math.sqrt(x1 * x1 + y1 * y1 + z1 * z1));
2967
+ const phi1 = Math.atan2(y1, x1) + PI;
2968
+ const v1 = theta1 / PI;
2969
+ const u1 = 1 - phi1 / PI2;
2970
+ const x2 = positions[in2 + 0];
2971
+ const y2 = positions[in2 + 1];
2972
+ const z2 = positions[in2 + 2];
2973
+ const theta2 = Math.acos(z2 / Math.sqrt(x2 * x2 + y2 * y2 + z2 * z2));
2974
+ const phi2 = Math.atan2(y2, x2) + PI;
2975
+ const v2 = theta2 / PI;
2976
+ const u2 = 1 - phi2 / PI2;
2977
+ const x3 = positions[in3 + 0];
2978
+ const y3 = positions[in3 + 1];
2979
+ const z3 = positions[in3 + 2];
2980
+ const theta3 = Math.acos(z3 / Math.sqrt(x3 * x3 + y3 * y3 + z3 * z3));
2981
+ const phi3 = Math.atan2(y3, x3) + PI;
2982
+ const v3 = theta3 / PI;
2983
+ const u3 = 1 - phi3 / PI2;
2984
+ const vec1 = [x3 - x2, y3 - y2, z3 - z2];
2985
+ const vec2 = [x1 - x2, y1 - y2, z1 - z2];
2986
+ const normal = new import_core24.Vector3(vec1).cross(vec2).normalize();
2987
+ let newIndex;
2988
+ if ((u1 === 0 || u2 === 0 || u3 === 0) && (u1 === 0 || u1 > 0.5) && (u2 === 0 || u2 > 0.5) && (u3 === 0 || u3 > 0.5)) {
2989
+ positions.push(positions[in1 + 0], positions[in1 + 1], positions[in1 + 2]);
2990
+ newIndex = positions.length / 3 - 1;
2991
+ indices.push(newIndex);
2992
+ texCoords[newIndex * 2 + 0] = 1;
2993
+ texCoords[newIndex * 2 + 1] = v1;
2994
+ normals[newIndex * 3 + 0] = normal.x;
2995
+ normals[newIndex * 3 + 1] = normal.y;
2996
+ normals[newIndex * 3 + 2] = normal.z;
2997
+ positions.push(positions[in2 + 0], positions[in2 + 1], positions[in2 + 2]);
2998
+ newIndex = positions.length / 3 - 1;
2999
+ indices.push(newIndex);
3000
+ texCoords[newIndex * 2 + 0] = 1;
3001
+ texCoords[newIndex * 2 + 1] = v2;
3002
+ normals[newIndex * 3 + 0] = normal.x;
3003
+ normals[newIndex * 3 + 1] = normal.y;
3004
+ normals[newIndex * 3 + 2] = normal.z;
3005
+ positions.push(positions[in3 + 0], positions[in3 + 1], positions[in3 + 2]);
3006
+ newIndex = positions.length / 3 - 1;
3007
+ indices.push(newIndex);
3008
+ texCoords[newIndex * 2 + 0] = 1;
3009
+ texCoords[newIndex * 2 + 1] = v3;
3010
+ normals[newIndex * 3 + 0] = normal.x;
3011
+ normals[newIndex * 3 + 1] = normal.y;
3012
+ normals[newIndex * 3 + 2] = normal.z;
3013
+ }
3014
+ normals[in1 + 0] = normals[in2 + 0] = normals[in3 + 0] = normal.x;
3015
+ normals[in1 + 1] = normals[in2 + 1] = normals[in3 + 1] = normal.y;
3016
+ normals[in1 + 2] = normals[in2 + 2] = normals[in3 + 2] = normal.z;
3017
+ texCoords[iu1 + 0] = u1;
3018
+ texCoords[iu1 + 1] = v1;
3019
+ texCoords[iu2 + 0] = u2;
3020
+ texCoords[iu2 + 1] = v2;
3021
+ texCoords[iu3 + 0] = u3;
3022
+ texCoords[iu3 + 1] = v3;
3023
+ }
3024
+ return {
3025
+ indices: { size: 1, value: new Uint16Array(indices) },
3026
+ attributes: {
3027
+ POSITION: { size: 3, value: new Float32Array(positions) },
3028
+ NORMAL: { size: 3, value: new Float32Array(normals) },
3029
+ TEXCOORD_0: { size: 2, value: new Float32Array(texCoords) }
3030
+ }
3031
+ };
3032
+ }
3033
+
3034
+ // dist/geometries/plane-geometry.js
3035
+ var import_core25 = require("@luma.gl/core");
3036
+
3037
+ // dist/geometry/geometry-utils.js
3038
+ function unpackIndexedGeometry(geometry) {
3039
+ const { indices, attributes } = geometry;
3040
+ if (!indices) {
3041
+ return geometry;
3042
+ }
3043
+ const vertexCount = indices.value.length;
3044
+ const unpackedAttributes = {};
3045
+ for (const attributeName in attributes) {
3046
+ const attribute = attributes[attributeName];
3047
+ const { constant, value, size } = attribute;
3048
+ if (constant || !size) {
3049
+ continue;
3050
+ }
3051
+ const unpackedValue = new value.constructor(vertexCount * size);
3052
+ for (let x = 0; x < vertexCount; ++x) {
3053
+ const index = indices.value[x];
3054
+ for (let i = 0; i < size; i++) {
3055
+ unpackedValue[x * size + i] = value[index * size + i];
3056
+ }
3057
+ }
3058
+ unpackedAttributes[attributeName] = { size, value: unpackedValue };
3059
+ }
3060
+ return {
3061
+ attributes: Object.assign({}, attributes, unpackedAttributes)
3062
+ };
3063
+ }
3064
+
3065
+ // dist/geometries/plane-geometry.js
3066
+ var PlaneGeometry = class extends Geometry {
3067
+ constructor(props = {}) {
3068
+ const { id = (0, import_core25.uid)("plane-geometry") } = props;
3069
+ const { indices, attributes } = tesselatePlane(props);
3070
+ super({
3071
+ ...props,
3072
+ id,
3073
+ topology: "triangle-list",
3074
+ indices,
3075
+ attributes: { ...attributes, ...props.attributes }
3076
+ });
3077
+ }
3078
+ };
3079
+ function tesselatePlane(props) {
3080
+ const { type = "x,y", offset = 0, flipCull = false, unpack = false } = props;
3081
+ const coords = type.split(",");
3082
+ let c1len = props[`${coords[0]}len`] || 1;
3083
+ const c2len = props[`${coords[1]}len`] || 1;
3084
+ const subdivisions1 = props[`n${coords[0]}`] || 1;
3085
+ const subdivisions2 = props[`n${coords[1]}`] || 1;
3086
+ const numVertices = (subdivisions1 + 1) * (subdivisions2 + 1);
3087
+ const positions = new Float32Array(numVertices * 3);
3088
+ const normals = new Float32Array(numVertices * 3);
3089
+ const texCoords = new Float32Array(numVertices * 2);
3090
+ if (flipCull) {
3091
+ c1len = -c1len;
3092
+ }
3093
+ let i2 = 0;
3094
+ let i3 = 0;
3095
+ for (let z = 0; z <= subdivisions2; z++) {
3096
+ for (let x = 0; x <= subdivisions1; x++) {
3097
+ const u = x / subdivisions1;
3098
+ const v = z / subdivisions2;
3099
+ texCoords[i2 + 0] = flipCull ? 1 - u : u;
3100
+ texCoords[i2 + 1] = v;
3101
+ switch (type) {
3102
+ case "x,y":
3103
+ positions[i3 + 0] = c1len * u - c1len * 0.5;
3104
+ positions[i3 + 1] = c2len * v - c2len * 0.5;
3105
+ positions[i3 + 2] = offset;
3106
+ normals[i3 + 0] = 0;
3107
+ normals[i3 + 1] = 0;
3108
+ normals[i3 + 2] = flipCull ? 1 : -1;
3109
+ break;
3110
+ case "x,z":
3111
+ positions[i3 + 0] = c1len * u - c1len * 0.5;
3112
+ positions[i3 + 1] = offset;
3113
+ positions[i3 + 2] = c2len * v - c2len * 0.5;
3114
+ normals[i3 + 0] = 0;
3115
+ normals[i3 + 1] = flipCull ? 1 : -1;
3116
+ normals[i3 + 2] = 0;
3117
+ break;
3118
+ case "y,z":
3119
+ positions[i3 + 0] = offset;
3120
+ positions[i3 + 1] = c1len * u - c1len * 0.5;
3121
+ positions[i3 + 2] = c2len * v - c2len * 0.5;
3122
+ normals[i3 + 0] = flipCull ? 1 : -1;
3123
+ normals[i3 + 1] = 0;
3124
+ normals[i3 + 2] = 0;
3125
+ break;
3126
+ default:
3127
+ throw new Error("PlaneGeometry: unknown type");
3128
+ }
3129
+ i2 += 2;
3130
+ i3 += 3;
3131
+ }
3132
+ }
3133
+ const numVertsAcross = subdivisions1 + 1;
3134
+ const indices = new Uint16Array(subdivisions1 * subdivisions2 * 6);
3135
+ for (let z = 0; z < subdivisions2; z++) {
3136
+ for (let x = 0; x < subdivisions1; x++) {
3137
+ const index = (z * subdivisions1 + x) * 6;
3138
+ indices[index + 0] = (z + 0) * numVertsAcross + x;
3139
+ indices[index + 1] = (z + 1) * numVertsAcross + x;
3140
+ indices[index + 2] = (z + 0) * numVertsAcross + x + 1;
3141
+ indices[index + 3] = (z + 1) * numVertsAcross + x;
3142
+ indices[index + 4] = (z + 1) * numVertsAcross + x + 1;
3143
+ indices[index + 5] = (z + 0) * numVertsAcross + x + 1;
3144
+ }
3145
+ }
3146
+ const geometry = {
3147
+ indices: { size: 1, value: indices },
3148
+ attributes: {
3149
+ POSITION: { size: 3, value: positions },
3150
+ NORMAL: { size: 3, value: normals },
3151
+ TEXCOORD_0: { size: 2, value: texCoords }
3152
+ }
3153
+ };
3154
+ return unpack ? unpackIndexedGeometry(geometry) : geometry;
3155
+ }
3156
+
3157
+ // dist/geometries/sphere-geometry.js
3158
+ var import_core26 = require("@luma.gl/core");
3159
+ var SphereGeometry = class extends Geometry {
3160
+ constructor(props = {}) {
3161
+ const { id = (0, import_core26.uid)("sphere-geometry") } = props;
3162
+ const { indices, attributes } = tesselateSphere(props);
3163
+ super({
3164
+ ...props,
3165
+ id,
3166
+ topology: "triangle-list",
3167
+ indices,
3168
+ attributes: { ...attributes, ...props.attributes }
3169
+ });
3170
+ }
3171
+ };
3172
+ function tesselateSphere(props) {
3173
+ const { nlat = 10, nlong = 10 } = props;
3174
+ const startLat = 0;
3175
+ const endLat = Math.PI;
3176
+ const latRange = endLat - startLat;
3177
+ const startLong = 0;
3178
+ const endLong = 2 * Math.PI;
3179
+ const longRange = endLong - startLong;
3180
+ const numVertices = (nlat + 1) * (nlong + 1);
3181
+ const radius = (n1, n2, n3, u, v) => props.radius || 1;
3182
+ const positions = new Float32Array(numVertices * 3);
3183
+ const normals = new Float32Array(numVertices * 3);
3184
+ const texCoords = new Float32Array(numVertices * 2);
3185
+ const IndexType = numVertices > 65535 ? Uint32Array : Uint16Array;
3186
+ const indices = new IndexType(nlat * nlong * 6);
3187
+ for (let y = 0; y <= nlat; y++) {
3188
+ for (let x = 0; x <= nlong; x++) {
3189
+ const u = x / nlong;
3190
+ const v = y / nlat;
3191
+ const index = x + y * (nlong + 1);
3192
+ const i2 = index * 2;
3193
+ const i3 = index * 3;
3194
+ const theta = longRange * u;
3195
+ const phi = latRange * v;
3196
+ const sinTheta = Math.sin(theta);
3197
+ const cosTheta = Math.cos(theta);
3198
+ const sinPhi = Math.sin(phi);
3199
+ const cosPhi = Math.cos(phi);
3200
+ const ux = cosTheta * sinPhi;
3201
+ const uy = cosPhi;
3202
+ const uz = sinTheta * sinPhi;
3203
+ const r = radius(ux, uy, uz, u, v);
3204
+ positions[i3 + 0] = r * ux;
3205
+ positions[i3 + 1] = r * uy;
3206
+ positions[i3 + 2] = r * uz;
3207
+ normals[i3 + 0] = ux;
3208
+ normals[i3 + 1] = uy;
3209
+ normals[i3 + 2] = uz;
3210
+ texCoords[i2 + 0] = u;
3211
+ texCoords[i2 + 1] = 1 - v;
3212
+ }
3213
+ }
3214
+ const numVertsAround = nlong + 1;
3215
+ for (let x = 0; x < nlong; x++) {
3216
+ for (let y = 0; y < nlat; y++) {
3217
+ const index = (x * nlat + y) * 6;
3218
+ indices[index + 0] = y * numVertsAround + x;
3219
+ indices[index + 1] = y * numVertsAround + x + 1;
3220
+ indices[index + 2] = (y + 1) * numVertsAround + x;
3221
+ indices[index + 3] = (y + 1) * numVertsAround + x;
3222
+ indices[index + 4] = y * numVertsAround + x + 1;
3223
+ indices[index + 5] = (y + 1) * numVertsAround + x + 1;
3224
+ }
3225
+ }
3226
+ return {
3227
+ indices: { size: 1, value: indices },
3228
+ attributes: {
3229
+ POSITION: { size: 3, value: positions },
3230
+ NORMAL: { size: 3, value: normals },
3231
+ TEXCOORD_0: { size: 2, value: texCoords }
3232
+ }
3233
+ };
3234
+ }
3235
+
3236
+ // dist/computation.js
3237
+ var import_core27 = require("@luma.gl/core");
3238
+ var import_core28 = require("@luma.gl/core");
3239
+ var import_core29 = require("@luma.gl/core");
3240
+ var import_shadertools5 = require("@luma.gl/shadertools");
3241
+ var LOG_DRAW_PRIORITY2 = 2;
3242
+ var LOG_DRAW_TIMEOUT2 = 1e4;
3243
+ var _Computation = class {
3244
+ device;
3245
+ id;
3246
+ pipelineFactory;
3247
+ shaderFactory;
3248
+ userData = {};
3249
+ /** Bindings (textures, samplers, uniform buffers) */
3250
+ bindings = {};
3251
+ /** The underlying GPU "program". @note May be recreated if parameters change */
3252
+ pipeline;
3253
+ /** the underlying compiled compute shader */
3254
+ shader;
3255
+ source;
3256
+ /** ShaderInputs instance */
3257
+ shaderInputs;
3258
+ _uniformStore;
3259
+ _pipelineNeedsUpdate = "newly created";
3260
+ _getModuleUniforms;
3261
+ props;
3262
+ _destroyed = false;
3263
+ constructor(device, props) {
3264
+ var _a, _b, _c;
3265
+ if (device.type !== "webgpu") {
3266
+ throw new Error("Computation is only supported in WebGPU");
3267
+ }
3268
+ this.props = { ..._Computation.defaultProps, ...props };
3269
+ props = this.props;
3270
+ this.id = props.id || (0, import_core28.uid)("model");
3271
+ this.device = device;
3272
+ Object.assign(this.userData, props.userData);
3273
+ const moduleMap = Object.fromEntries(((_a = this.props.modules) == null ? void 0 : _a.map((module2) => [module2.name, module2])) || []);
3274
+ this.setShaderInputs(props.shaderInputs || new ShaderInputs(moduleMap));
3275
+ this.props.shaderLayout ||= (0, import_shadertools5.getShaderLayoutFromWGSL)(this.props.source);
3276
+ const platformInfo = getPlatformInfo2(device);
3277
+ const modules = (((_b = this.props.modules) == null ? void 0 : _b.length) > 0 ? this.props.modules : (_c = this.shaderInputs) == null ? void 0 : _c.getModules()) || [];
3278
+ this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
3279
+ this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
3280
+ const { source, getUniforms } = this.props.shaderAssembler.assembleShader({
3281
+ platformInfo,
3282
+ ...this.props,
3283
+ modules
3284
+ });
3285
+ this.source = source;
3286
+ this._getModuleUniforms = getUniforms;
3287
+ this.pipeline = this._updatePipeline();
3288
+ if (props.bindings) {
3289
+ this.setBindings(props.bindings);
3290
+ }
3291
+ Object.seal(this);
3292
+ }
3293
+ destroy() {
3294
+ if (this._destroyed)
3295
+ return;
3296
+ this.pipelineFactory.release(this.pipeline);
3297
+ this.shaderFactory.release(this.shader);
3298
+ this._uniformStore.destroy();
3299
+ this._destroyed = true;
3300
+ }
3301
+ // Draw call
3302
+ predraw() {
3303
+ this.updateShaderInputs();
3304
+ }
3305
+ dispatch(computePass, x, y, z) {
3306
+ try {
3307
+ this._logDrawCallStart();
3308
+ this.pipeline = this._updatePipeline();
3309
+ this.pipeline.setBindings(this.bindings);
3310
+ computePass.setPipeline(this.pipeline);
3311
+ computePass.setBindings([]);
3312
+ computePass.dispatch(x, y, z);
3313
+ } finally {
3314
+ this._logDrawCallEnd();
3315
+ }
3316
+ }
3317
+ // Update fixed fields (can trigger pipeline rebuild)
3318
+ // Update dynamic fields
3319
+ /**
3320
+ * Updates the vertex count (used in draw calls)
3321
+ * @note Any attributes with stepMode=vertex need to be at least this big
3322
+ */
3323
+ setVertexCount(vertexCount) {
3324
+ }
3325
+ /**
3326
+ * Updates the instance count (used in draw calls)
3327
+ * @note Any attributes with stepMode=instance need to be at least this big
3328
+ */
3329
+ setInstanceCount(instanceCount) {
3330
+ }
3331
+ setShaderInputs(shaderInputs) {
3332
+ this.shaderInputs = shaderInputs;
3333
+ this._uniformStore = new import_core27.UniformStore(this.shaderInputs.modules);
3334
+ for (const moduleName of Object.keys(this.shaderInputs.modules)) {
3335
+ const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
3336
+ this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
3337
+ }
3338
+ }
3339
+ /**
3340
+ * Updates shader module settings (which results in uniforms being set)
3341
+ */
3342
+ setShaderModuleProps(props) {
3343
+ const uniforms = this._getModuleUniforms(props);
3344
+ const keys = Object.keys(uniforms).filter((k) => {
3345
+ const uniform = uniforms[k];
3346
+ return !(0, import_core28.isNumberArray)(uniform) && typeof uniform !== "number" && typeof uniform !== "boolean";
3347
+ });
3348
+ const bindings = {};
3349
+ for (const k of keys) {
3350
+ bindings[k] = uniforms[k];
3351
+ delete uniforms[k];
3352
+ }
3353
+ }
3354
+ updateShaderInputs() {
3355
+ this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
3356
+ }
3357
+ /**
3358
+ * Sets bindings (textures, samplers, uniform buffers)
3359
+ */
3360
+ setBindings(bindings) {
3361
+ Object.assign(this.bindings, bindings);
3362
+ }
3363
+ _setPipelineNeedsUpdate(reason) {
3364
+ this._pipelineNeedsUpdate = this._pipelineNeedsUpdate || reason;
3365
+ }
3366
+ _updatePipeline() {
3367
+ if (this._pipelineNeedsUpdate) {
3368
+ let prevShader = null;
3369
+ if (this.pipeline) {
3370
+ import_core28.log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)();
3371
+ prevShader = this.shader;
3372
+ }
3373
+ this._pipelineNeedsUpdate = false;
3374
+ this.shader = this.shaderFactory.createShader({
3375
+ id: `${this.id}-fragment`,
3376
+ stage: "compute",
3377
+ source: this.source,
3378
+ debug: this.props.debugShaders
3379
+ });
3380
+ this.pipeline = this.pipelineFactory.createComputePipeline({
3381
+ ...this.props,
3382
+ shader: this.shader
3383
+ });
3384
+ if (prevShader) {
3385
+ this.shaderFactory.release(prevShader);
3386
+ }
3387
+ }
3388
+ return this.pipeline;
3389
+ }
3390
+ /** Throttle draw call logging */
3391
+ _lastLogTime = 0;
3392
+ _logOpen = false;
3393
+ _logDrawCallStart() {
3394
+ const logDrawTimeout = import_core28.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT2;
3395
+ if (import_core28.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
3396
+ return;
3397
+ }
3398
+ this._lastLogTime = Date.now();
3399
+ this._logOpen = true;
3400
+ import_core28.log.group(LOG_DRAW_PRIORITY2, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core28.log.level <= 2 })();
3401
+ }
3402
+ _logDrawCallEnd() {
3403
+ if (this._logOpen) {
3404
+ const uniformTable = this.shaderInputs.getDebugTable();
3405
+ import_core28.log.table(LOG_DRAW_PRIORITY2, uniformTable)();
3406
+ import_core28.log.groupEnd(LOG_DRAW_PRIORITY2)();
3407
+ this._logOpen = false;
3408
+ }
3409
+ }
3410
+ _drawCount = 0;
3411
+ // TODO - fix typing of luma data types
3412
+ _getBufferOrConstantValues(attribute, dataType) {
3413
+ const TypedArrayConstructor = (0, import_core29.getTypedArrayFromDataType)(dataType);
3414
+ const typedArray = attribute instanceof import_core27.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
3415
+ return typedArray.toString();
3416
+ }
3417
+ };
3418
+ var Computation = _Computation;
3419
+ __publicField(Computation, "defaultProps", {
3420
+ ...import_core27.ComputePipeline.defaultProps,
3421
+ id: "unnamed",
3422
+ handle: void 0,
3423
+ userData: {},
3424
+ source: "",
3425
+ modules: [],
3426
+ defines: {},
3427
+ bindings: void 0,
3428
+ shaderInputs: void 0,
3429
+ pipelineFactory: void 0,
3430
+ shaderFactory: void 0,
3431
+ shaderAssembler: import_shadertools5.ShaderAssembler.getDefaultShaderAssembler(),
3432
+ debugShaders: void 0
3433
+ });
3434
+ function getPlatformInfo2(device) {
3435
+ return {
3436
+ type: device.type,
3437
+ shaderLanguage: device.info.shadingLanguage,
3438
+ shaderLanguageVersion: device.info.shadingLanguageVersion,
3439
+ gpu: device.info.gpu,
3440
+ // HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
3441
+ features: device.features
3442
+ };
3443
+ }
3444
+ //# sourceMappingURL=index.cjs.map