@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
@@ -0,0 +1,442 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ import { luma } from '@luma.gl/core';
5
+ import { requestAnimationFrame, cancelAnimationFrame } from '@luma.gl/core';
6
+ import { Stats } from '@probe.gl/stats';
7
+ let statIdCounter = 0;
8
+ const DEFAULT_ANIMATION_LOOP_PROPS = {
9
+ device: null,
10
+ onAddHTML: () => '',
11
+ onInitialize: async () => {
12
+ return null;
13
+ },
14
+ onRender: () => { },
15
+ onFinalize: () => { },
16
+ onError: error => console.error(error), // eslint-disable-line no-console
17
+ stats: luma.stats.get(`animation-loop-${statIdCounter++}`),
18
+ // view parameters
19
+ useDevicePixels: true,
20
+ autoResizeViewport: false,
21
+ autoResizeDrawingBuffer: false
22
+ };
23
+ /** Convenient animation loop */
24
+ export class AnimationLoop {
25
+ device = null;
26
+ canvas = null;
27
+ props;
28
+ animationProps = null;
29
+ timeline = null;
30
+ stats;
31
+ cpuTime;
32
+ gpuTime;
33
+ frameRate;
34
+ display;
35
+ needsRedraw = 'initialized';
36
+ _initialized = false;
37
+ _running = false;
38
+ _animationFrameId = null;
39
+ _nextFramePromise = null;
40
+ _resolveNextFrame = null;
41
+ _cpuStartTime = 0;
42
+ // _gpuTimeQuery: Query | null = null;
43
+ /*
44
+ * @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
45
+ */
46
+ constructor(props) {
47
+ this.props = { ...DEFAULT_ANIMATION_LOOP_PROPS, ...props };
48
+ props = this.props;
49
+ if (!props.device) {
50
+ throw new Error('No device provided');
51
+ }
52
+ const { useDevicePixels = true } = this.props;
53
+ // state
54
+ this.stats = props.stats || new Stats({ id: 'animation-loop-stats' });
55
+ this.cpuTime = this.stats.get('CPU Time');
56
+ this.gpuTime = this.stats.get('GPU Time');
57
+ this.frameRate = this.stats.get('Frame Rate');
58
+ this.setProps({
59
+ autoResizeViewport: props.autoResizeViewport,
60
+ autoResizeDrawingBuffer: props.autoResizeDrawingBuffer,
61
+ useDevicePixels
62
+ });
63
+ // Bind methods
64
+ this.start = this.start.bind(this);
65
+ this.stop = this.stop.bind(this);
66
+ this._onMousemove = this._onMousemove.bind(this);
67
+ this._onMouseleave = this._onMouseleave.bind(this);
68
+ }
69
+ destroy() {
70
+ this.stop();
71
+ this._setDisplay(null);
72
+ }
73
+ /** @deprecated Use .destroy() */
74
+ delete() {
75
+ this.destroy();
76
+ }
77
+ /** Flags this animation loop as needing redraw */
78
+ setNeedsRedraw(reason) {
79
+ this.needsRedraw = this.needsRedraw || reason;
80
+ return this;
81
+ }
82
+ /** TODO - move these props to CanvasContext? */
83
+ setProps(props) {
84
+ if ('autoResizeViewport' in props) {
85
+ this.props.autoResizeViewport = props.autoResizeViewport || false;
86
+ }
87
+ if ('autoResizeDrawingBuffer' in props) {
88
+ this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer || false;
89
+ }
90
+ if ('useDevicePixels' in props) {
91
+ this.props.useDevicePixels = props.useDevicePixels || false;
92
+ }
93
+ return this;
94
+ }
95
+ /** Starts a render loop if not already running */
96
+ async start() {
97
+ if (this._running) {
98
+ return this;
99
+ }
100
+ this._running = true;
101
+ try {
102
+ let appContext;
103
+ if (!this._initialized) {
104
+ this._initialized = true;
105
+ // Create the WebGL context
106
+ await this._initDevice();
107
+ this._initialize();
108
+ // Note: onIntialize can return a promise (e.g. in case app needs to load resources)
109
+ await this.props.onInitialize(this._getAnimationProps());
110
+ }
111
+ // check that we haven't been stopped
112
+ if (!this._running) {
113
+ return null;
114
+ }
115
+ // Start the loop
116
+ if (appContext !== false) {
117
+ // cancel any pending renders to ensure only one loop can ever run
118
+ this._cancelAnimationFrame();
119
+ this._requestAnimationFrame();
120
+ }
121
+ return this;
122
+ }
123
+ catch (err) {
124
+ const error = err instanceof Error ? err : new Error('Unknown error');
125
+ this.props.onError(error);
126
+ // this._running = false; // TODO
127
+ throw error;
128
+ }
129
+ }
130
+ /** Stops a render loop if already running, finalizing */
131
+ stop() {
132
+ // console.debug(`Stopping ${this.constructor.name}`);
133
+ if (this._running) {
134
+ // call callback
135
+ // If stop is called immediately, we can end up in a state where props haven't been initialized...
136
+ if (this.animationProps) {
137
+ this.props.onFinalize(this.animationProps);
138
+ }
139
+ this._cancelAnimationFrame();
140
+ this._nextFramePromise = null;
141
+ this._resolveNextFrame = null;
142
+ this._running = false;
143
+ }
144
+ return this;
145
+ }
146
+ /** Explicitly draw a frame */
147
+ redraw() {
148
+ if (this.device?.isLost) {
149
+ return this;
150
+ }
151
+ this._beginFrameTimers();
152
+ this._setupFrame();
153
+ this._updateAnimationProps();
154
+ this._renderFrame(this._getAnimationProps());
155
+ // clear needsRedraw flag
156
+ this._clearNeedsRedraw();
157
+ if (this._resolveNextFrame) {
158
+ this._resolveNextFrame(this);
159
+ this._nextFramePromise = null;
160
+ this._resolveNextFrame = null;
161
+ }
162
+ this._endFrameTimers();
163
+ return this;
164
+ }
165
+ /** Add a timeline, it will be automatically updated by the animation loop. */
166
+ attachTimeline(timeline) {
167
+ this.timeline = timeline;
168
+ return this.timeline;
169
+ }
170
+ /** Remove a timeline */
171
+ detachTimeline() {
172
+ this.timeline = null;
173
+ }
174
+ /** Wait until a render completes */
175
+ waitForRender() {
176
+ this.setNeedsRedraw('waitForRender');
177
+ if (!this._nextFramePromise) {
178
+ this._nextFramePromise = new Promise(resolve => {
179
+ this._resolveNextFrame = resolve;
180
+ });
181
+ }
182
+ return this._nextFramePromise;
183
+ }
184
+ /** TODO - should use device.deviceContext */
185
+ async toDataURL() {
186
+ this.setNeedsRedraw('toDataURL');
187
+ await this.waitForRender();
188
+ if (this.canvas instanceof HTMLCanvasElement) {
189
+ return this.canvas.toDataURL();
190
+ }
191
+ throw new Error('OffscreenCanvas');
192
+ }
193
+ // PRIVATE METHODS
194
+ _initialize() {
195
+ this._startEventHandling();
196
+ // Initialize the callback data
197
+ this._initializeAnimationProps();
198
+ this._updateAnimationProps();
199
+ // Default viewport setup, in case onInitialize wants to render
200
+ this._resizeCanvasDrawingBuffer();
201
+ this._resizeViewport();
202
+ // this._gpuTimeQuery = Query.isSupported(this.gl, ['timers']) ? new Query(this.gl) : null;
203
+ }
204
+ _setDisplay(display) {
205
+ if (this.display) {
206
+ this.display.destroy();
207
+ this.display.animationLoop = null;
208
+ }
209
+ // store animation loop on the display
210
+ if (display) {
211
+ display.animationLoop = this;
212
+ }
213
+ this.display = display;
214
+ }
215
+ _requestAnimationFrame() {
216
+ if (!this._running) {
217
+ return;
218
+ }
219
+ // VR display has a separate animation frame to sync with headset
220
+ // TODO WebVR API discontinued, replaced by WebXR: https://immersive-web.github.io/webxr/
221
+ // See https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay/requestAnimationFrame
222
+ // if (this.display && this.display.requestAnimationFrame) {
223
+ // this._animationFrameId = this.display.requestAnimationFrame(this._animationFrame.bind(this));
224
+ // }
225
+ this._animationFrameId = requestAnimationFrame(this._animationFrame.bind(this));
226
+ }
227
+ _cancelAnimationFrame() {
228
+ if (this._animationFrameId === null) {
229
+ return;
230
+ }
231
+ // VR display has a separate animation frame to sync with headset
232
+ // TODO WebVR API discontinued, replaced by WebXR: https://immersive-web.github.io/webxr/
233
+ // See https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay/requestAnimationFrame
234
+ // if (this.display && this.display.cancelAnimationFrame) {
235
+ // this.display.cancelAnimationFrame(this._animationFrameId);
236
+ // }
237
+ cancelAnimationFrame(this._animationFrameId);
238
+ this._animationFrameId = null;
239
+ }
240
+ _animationFrame() {
241
+ if (!this._running) {
242
+ return;
243
+ }
244
+ this.redraw();
245
+ this._requestAnimationFrame();
246
+ }
247
+ // Called on each frame, can be overridden to call onRender multiple times
248
+ // to support e.g. stereoscopic rendering
249
+ _renderFrame(animationProps) {
250
+ // Allow e.g. VR display to render multiple frames.
251
+ if (this.display) {
252
+ this.display._renderFrame(animationProps);
253
+ return;
254
+ }
255
+ // call callback
256
+ this.props.onRender(this._getAnimationProps());
257
+ // end callback
258
+ // Submit commands (necessary on WebGPU)
259
+ this.device.submit();
260
+ }
261
+ _clearNeedsRedraw() {
262
+ this.needsRedraw = false;
263
+ }
264
+ _setupFrame() {
265
+ this._resizeCanvasDrawingBuffer();
266
+ this._resizeViewport();
267
+ }
268
+ // Initialize the object that will be passed to app callbacks
269
+ _initializeAnimationProps() {
270
+ if (!this.device) {
271
+ throw new Error('loop');
272
+ }
273
+ this.animationProps = {
274
+ animationLoop: this,
275
+ device: this.device,
276
+ canvas: this.device?.canvasContext?.canvas,
277
+ timeline: this.timeline,
278
+ // Initial values
279
+ useDevicePixels: this.props.useDevicePixels,
280
+ needsRedraw: false,
281
+ // Placeholders
282
+ width: 1,
283
+ height: 1,
284
+ aspect: 1,
285
+ // Animation props
286
+ time: 0,
287
+ startTime: Date.now(),
288
+ engineTime: 0,
289
+ tick: 0,
290
+ tock: 0,
291
+ // Experimental
292
+ _mousePosition: null // Event props
293
+ };
294
+ }
295
+ _getAnimationProps() {
296
+ if (!this.animationProps) {
297
+ throw new Error('animationProps');
298
+ }
299
+ return this.animationProps;
300
+ }
301
+ // Update the context object that will be passed to app callbacks
302
+ _updateAnimationProps() {
303
+ if (!this.animationProps) {
304
+ return;
305
+ }
306
+ // Can this be replaced with canvas context?
307
+ const { width, height, aspect } = this._getSizeAndAspect();
308
+ if (width !== this.animationProps.width || height !== this.animationProps.height) {
309
+ this.setNeedsRedraw('drawing buffer resized');
310
+ }
311
+ if (aspect !== this.animationProps.aspect) {
312
+ this.setNeedsRedraw('drawing buffer aspect changed');
313
+ }
314
+ this.animationProps.width = width;
315
+ this.animationProps.height = height;
316
+ this.animationProps.aspect = aspect;
317
+ this.animationProps.needsRedraw = this.needsRedraw;
318
+ // Update time properties
319
+ this.animationProps.engineTime = Date.now() - this.animationProps.startTime;
320
+ if (this.timeline) {
321
+ this.timeline.update(this.animationProps.engineTime);
322
+ }
323
+ this.animationProps.tick = Math.floor((this.animationProps.time / 1000) * 60);
324
+ this.animationProps.tock++;
325
+ // For back compatibility
326
+ this.animationProps.time = this.timeline
327
+ ? this.timeline.getTime()
328
+ : this.animationProps.engineTime;
329
+ }
330
+ /** Wait for supplied device */
331
+ async _initDevice() {
332
+ this.device = await this.props.device;
333
+ if (!this.device) {
334
+ throw new Error('No device provided');
335
+ }
336
+ this.canvas = this.device.canvasContext?.canvas || null;
337
+ // this._createInfoDiv();
338
+ }
339
+ _createInfoDiv() {
340
+ if (this.canvas && this.props.onAddHTML) {
341
+ const wrapperDiv = document.createElement('div');
342
+ document.body.appendChild(wrapperDiv);
343
+ wrapperDiv.style.position = 'relative';
344
+ const div = document.createElement('div');
345
+ div.style.position = 'absolute';
346
+ div.style.left = '10px';
347
+ div.style.bottom = '10px';
348
+ div.style.width = '300px';
349
+ div.style.background = 'white';
350
+ if (this.canvas instanceof HTMLCanvasElement) {
351
+ wrapperDiv.appendChild(this.canvas);
352
+ }
353
+ wrapperDiv.appendChild(div);
354
+ const html = this.props.onAddHTML(div);
355
+ if (html) {
356
+ div.innerHTML = html;
357
+ }
358
+ }
359
+ }
360
+ _getSizeAndAspect() {
361
+ if (!this.device) {
362
+ return { width: 1, height: 1, aspect: 1 };
363
+ }
364
+ // https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
365
+ const [width, height] = this.device?.canvasContext?.getPixelSize() || [1, 1];
366
+ // https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
367
+ let aspect = 1;
368
+ const canvas = this.device?.canvasContext?.canvas;
369
+ // @ts-expect-error
370
+ if (canvas && canvas.clientHeight) {
371
+ // @ts-expect-error
372
+ aspect = canvas.clientWidth / canvas.clientHeight;
373
+ }
374
+ else if (width > 0 && height > 0) {
375
+ aspect = width / height;
376
+ }
377
+ return { width, height, aspect };
378
+ }
379
+ /** Default viewport setup */
380
+ _resizeViewport() {
381
+ // TODO can we use canvas context to code this in a portable way?
382
+ // @ts-expect-error Expose on canvasContext
383
+ if (this.props.autoResizeViewport && this.device.gl) {
384
+ // @ts-expect-error Expose canvasContext
385
+ this.device.gl.viewport(0, 0,
386
+ // @ts-expect-error Expose canvasContext
387
+ this.device.gl.drawingBufferWidth,
388
+ // @ts-expect-error Expose canvasContext
389
+ this.device.gl.drawingBufferHeight);
390
+ }
391
+ }
392
+ /**
393
+ * Resize the render buffer of the canvas to match canvas client size
394
+ * Optionally multiplying with devicePixel ratio
395
+ */
396
+ _resizeCanvasDrawingBuffer() {
397
+ if (this.props.autoResizeDrawingBuffer) {
398
+ this.device?.canvasContext?.resize({ useDevicePixels: this.props.useDevicePixels });
399
+ }
400
+ }
401
+ _beginFrameTimers() {
402
+ this.frameRate.timeEnd();
403
+ this.frameRate.timeStart();
404
+ // Check if timer for last frame has completed.
405
+ // GPU timer results are never available in the same
406
+ // frame they are captured.
407
+ // if (
408
+ // this._gpuTimeQuery &&
409
+ // this._gpuTimeQuery.isResultAvailable() &&
410
+ // !this._gpuTimeQuery.isTimerDisjoint()
411
+ // ) {
412
+ // this.stats.get('GPU Time').addTime(this._gpuTimeQuery.getTimerMilliseconds());
413
+ // }
414
+ // if (this._gpuTimeQuery) {
415
+ // // GPU time query start
416
+ // this._gpuTimeQuery.beginTimeElapsedQuery();
417
+ // }
418
+ this.cpuTime.timeStart();
419
+ }
420
+ _endFrameTimers() {
421
+ this.cpuTime.timeEnd();
422
+ // if (this._gpuTimeQuery) {
423
+ // // GPU time query end. Results will be available on next frame.
424
+ // this._gpuTimeQuery.end();
425
+ // }
426
+ }
427
+ // Event handling
428
+ _startEventHandling() {
429
+ if (this.canvas) {
430
+ this.canvas.addEventListener('mousemove', this._onMousemove.bind(this));
431
+ this.canvas.addEventListener('mouseleave', this._onMouseleave.bind(this));
432
+ }
433
+ }
434
+ _onMousemove(event) {
435
+ if (event instanceof MouseEvent) {
436
+ this._getAnimationProps()._mousePosition = [event.offsetX, event.offsetY];
437
+ }
438
+ }
439
+ _onMouseleave(event) {
440
+ this._getAnimationProps()._mousePosition = null;
441
+ }
442
+ }
@@ -1,9 +1,8 @@
1
- /// <reference types="offscreencanvas" />
2
- import { Device } from '@luma.gl/api';
3
- import { Timeline } from '../animation/timeline';
4
- import type { AnimationLoop } from './animation-loop';
1
+ import { Device } from '@luma.gl/core';
2
+ import { Timeline } from "../animation/timeline.js";
3
+ import type { AnimationLoop } from "./animation-loop.js";
5
4
  /** Properties passed to every render frame */
6
- export declare type AnimationProps = {
5
+ export type AnimationProps = {
7
6
  device: Device;
8
7
  animationLoop: AnimationLoop;
9
8
  /** @todo Should be canvasContext */
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation-props.d.ts","sourceRoot":"","sources":["../../src/animation-loop/animation-props.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,eAAe,CAAC;AACrC,OAAO,EAAC,QAAQ,EAAC,iCAA8B;AAC/C,OAAO,KAAK,EAAC,aAAa,EAAC,4BAAyB;AAEpD,+CAA+C;AAC/C,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,aAAa,CAAC;IAE7B,oCAAoC;IACpC,MAAM,EAAE,iBAAiB,GAAG,eAAe,CAAC;IAC5C,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IAGf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IAGb,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAE7B,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAG1B,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC1C,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import { AnimationLoopTemplate } from "./animation-loop-template.js";
2
+ import { AnimationLoop, AnimationLoopProps } from "./animation-loop.js";
3
+ export type MakeAnimationLoopProps = Omit<AnimationLoopProps, 'onCreateDevice' | 'onInitialize' | 'onRedraw' | 'onFinalize'>;
4
+ /** Instantiates and runs the render loop */
5
+ export declare function makeAnimationLoop(AnimationLoopTemplateCtor: typeof AnimationLoopTemplate, props?: MakeAnimationLoopProps): AnimationLoop;
6
+ //# sourceMappingURL=make-animation-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make-animation-loop.d.ts","sourceRoot":"","sources":["../../src/animation-loop/make-animation-loop.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,qBAAqB,EAAC,qCAAkC;AAChE,OAAO,EAAC,aAAa,EAAE,kBAAkB,EAAC,4BAAyB;AAGnE,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,kBAAkB,EAClB,gBAAgB,GAAG,cAAc,GAAG,UAAU,GAAG,YAAY,CAC9D,CAAC;AAEF,4CAA4C;AAC5C,wBAAgB,iBAAiB,CAC/B,yBAAyB,EAAE,OAAO,qBAAqB,EACvD,KAAK,CAAC,EAAE,sBAAsB,GAC7B,aAAa,CAkCf"}
@@ -0,0 +1,32 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ import { luma } from '@luma.gl/core';
5
+ import { AnimationLoop } from "./animation-loop.js";
6
+ /** Instantiates and runs the render loop */
7
+ export function makeAnimationLoop(AnimationLoopTemplateCtor, props) {
8
+ let renderLoop = null;
9
+ const device = props?.device || luma.createDevice();
10
+ // Create an animation loop;
11
+ const animationLoop = new AnimationLoop({
12
+ ...props,
13
+ device,
14
+ async onInitialize(animationProps) {
15
+ // @ts-expect-error abstract to prevent instantiation
16
+ renderLoop = new AnimationLoopTemplateCtor(animationProps);
17
+ // Any async loading can be handled here
18
+ return await renderLoop?.onInitialize(animationProps);
19
+ },
20
+ onRender: (animationProps) => renderLoop?.onRender(animationProps),
21
+ onFinalize: (animationProps) => renderLoop?.onFinalize(animationProps)
22
+ });
23
+ // @ts-expect-error Hack: adds info for the website to find
24
+ animationLoop.getInfo = () => {
25
+ // @ts-ignore
26
+ // eslint-disable-next-line no-invalid-this
27
+ return this.AnimationLoopTemplateCtor.info;
28
+ };
29
+ // Start the loop automatically
30
+ // animationLoop.start();
31
+ return animationLoop;
32
+ }
@@ -0,0 +1,95 @@
1
+ import type { TypedArray } from '@luma.gl/core';
2
+ import type { ComputePipelineProps, Shader, Binding } from '@luma.gl/core';
3
+ import { Device, Buffer, ComputePipeline, ComputePass, UniformStore } from '@luma.gl/core';
4
+ import type { ShaderModule, PlatformInfo } from '@luma.gl/shadertools';
5
+ import { ShaderAssembler } from '@luma.gl/shadertools';
6
+ import { ShaderInputs } from "./shader-inputs.js";
7
+ import { PipelineFactory } from "./lib/pipeline-factory.js";
8
+ import { ShaderFactory } from "./lib/shader-factory.js";
9
+ export type ComputationProps = Omit<ComputePipelineProps, 'shader'> & {
10
+ source?: string;
11
+ /** shadertool shader modules (added to shader code) */
12
+ modules?: ShaderModule[];
13
+ /** Shadertool module defines (configures shader code)*/
14
+ defines?: Record<string, string | number | boolean>;
15
+ /** Shader inputs, used to generated uniform buffers and bindings */
16
+ shaderInputs?: ShaderInputs;
17
+ /** Bindings */
18
+ bindings?: Record<string, Binding>;
19
+ /** Show shader source in browser? */
20
+ debugShaders?: 'never' | 'errors' | 'warnings' | 'always';
21
+ /** Factory used to create a {@link ComputePipeline}. Defaults to {@link Device} default factory. */
22
+ pipelineFactory?: PipelineFactory;
23
+ /** Factory used to create a {@link Shader}. Defaults to {@link Device} default factory. */
24
+ shaderFactory?: ShaderFactory;
25
+ /** Shader assembler. Defaults to the ShaderAssembler.getShaderAssembler() */
26
+ shaderAssembler?: ShaderAssembler;
27
+ };
28
+ /**
29
+ * v9 Model API
30
+ * A model
31
+ * - automatically reuses pipelines (programs) when possible
32
+ * - automatically rebuilds pipelines if necessary to accommodate changed settings
33
+ * shadertools integration
34
+ * - accepts modules and performs shader transpilation
35
+ */
36
+ export declare class Computation {
37
+ static defaultProps: Required<ComputationProps>;
38
+ readonly device: Device;
39
+ readonly id: string;
40
+ readonly pipelineFactory: PipelineFactory;
41
+ readonly shaderFactory: ShaderFactory;
42
+ userData: {
43
+ [key: string]: any;
44
+ };
45
+ /** Bindings (textures, samplers, uniform buffers) */
46
+ bindings: Record<string, Binding>;
47
+ /** The underlying GPU "program". @note May be recreated if parameters change */
48
+ pipeline: ComputePipeline;
49
+ /** the underlying compiled compute shader */
50
+ shader: Shader;
51
+ source: string;
52
+ /** ShaderInputs instance */
53
+ shaderInputs: ShaderInputs;
54
+ _uniformStore: UniformStore;
55
+ _pipelineNeedsUpdate: string | false;
56
+ private _getModuleUniforms;
57
+ private props;
58
+ private _destroyed;
59
+ constructor(device: Device, props: ComputationProps);
60
+ destroy(): void;
61
+ predraw(): void;
62
+ dispatch(computePass: ComputePass, x: number, y?: number, z?: number): void;
63
+ /**
64
+ * Updates the vertex count (used in draw calls)
65
+ * @note Any attributes with stepMode=vertex need to be at least this big
66
+ */
67
+ setVertexCount(vertexCount: number): void;
68
+ /**
69
+ * Updates the instance count (used in draw calls)
70
+ * @note Any attributes with stepMode=instance need to be at least this big
71
+ */
72
+ setInstanceCount(instanceCount: number): void;
73
+ setShaderInputs(shaderInputs: ShaderInputs): void;
74
+ /**
75
+ * Updates shader module settings (which results in uniforms being set)
76
+ */
77
+ setShaderModuleProps(props: Record<string, any>): void;
78
+ updateShaderInputs(): void;
79
+ /**
80
+ * Sets bindings (textures, samplers, uniform buffers)
81
+ */
82
+ setBindings(bindings: Record<string, Binding>): void;
83
+ _setPipelineNeedsUpdate(reason: string): void;
84
+ _updatePipeline(): ComputePipeline;
85
+ /** Throttle draw call logging */
86
+ _lastLogTime: number;
87
+ _logOpen: boolean;
88
+ _logDrawCallStart(): void;
89
+ _logDrawCallEnd(): void;
90
+ protected _drawCount: number;
91
+ _getBufferOrConstantValues(attribute: Buffer | TypedArray, dataType: any): string;
92
+ }
93
+ /** Create a shadertools platform info from the Device */
94
+ export declare function getPlatformInfo(device: Device): PlatformInfo;
95
+ //# sourceMappingURL=computation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computation.d.ts","sourceRoot":"","sources":["../src/computation.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAgB,oBAAoB,EAAE,MAAM,EAAE,OAAO,EAAC,MAAM,eAAe,CAAC;AACxF,OAAO,EAAC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAC,MAAM,eAAe,CAAC;AAGzF,OAAO,KAAK,EAAC,YAAY,EAAE,YAAY,EAAC,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAC,eAAe,EAA0B,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAC,YAAY,EAAC,2BAAwB;AAC7C,OAAO,EAAC,eAAe,EAAC,kCAA+B;AACvD,OAAO,EAAC,aAAa,EAAC,gCAA6B;AAMnD,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,GAAG;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,uDAAuD;IACvD,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAGpD,oEAAoE;IACpE,YAAY,CAAC,EAAE,YAAY,CAAC;IAE5B,eAAe;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnC,qCAAqC;IACrC,YAAY,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IAE1D,oGAAoG;IACpG,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,2FAA2F;IAC3F,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,WAAW;IACtB,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAkB7C;IAEF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IAEtC,QAAQ,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAC,CAAM;IAEpC,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM;IAEvC,gFAAgF;IAChF,QAAQ,EAAE,eAAe,CAAC;IAC1B,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IAEf,4BAA4B;IAC5B,YAAY,EAAE,YAAY,CAAC;IAE3B,aAAa,EAAE,YAAY,CAAC;IAE5B,oBAAoB,EAAE,MAAM,GAAG,KAAK,CAAmB;IAEvD,OAAO,CAAC,kBAAkB,CAAuE;IACjG,OAAO,CAAC,KAAK,CAA6B;IAE1C,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB;IAwDnD,OAAO,IAAI,IAAI;IAUf,OAAO;IAKP,QAAQ,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAyB3E;;;OAGG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAIzC;;;OAGG;IACH,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAI7C,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI;IAUjD;;OAEG;IACH,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAgBtD,kBAAkB,IAAI,IAAI;IAI1B;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIpD,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI7C,eAAe,IAAI,eAAe;IAgClC,iCAAiC;IACjC,YAAY,SAAK;IACjB,QAAQ,UAAS;IAEjB,iBAAiB,IAAI,IAAI;IAazB,eAAe,IAAI,IAAI;IAgBvB,SAAS,CAAC,UAAU,SAAK;IAGzB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE,QAAQ,EAAE,GAAG,GAAG,MAAM;CAMlF;AAED,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAS5D"}