@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.
- package/LICENSE +3 -1
- package/dist/animation/key-frames.d.ts +1 -1
- package/dist/animation/key-frames.d.ts.map +1 -1
- package/dist/animation/key-frames.js +51 -72
- package/dist/animation/timeline.d.ts +8 -8
- package/dist/animation/timeline.d.ts.map +1 -1
- package/dist/animation/timeline.js +95 -131
- package/dist/animation-loop/animation-loop-template.d.ts +23 -0
- package/dist/animation-loop/animation-loop-template.d.ts.map +1 -0
- package/dist/animation-loop/animation-loop-template.js +21 -0
- package/dist/{lib → animation-loop}/animation-loop.d.ts +31 -23
- package/dist/animation-loop/animation-loop.d.ts.map +1 -0
- package/dist/animation-loop/animation-loop.js +442 -0
- package/dist/{lib → animation-loop}/animation-props.d.ts +4 -5
- package/dist/animation-loop/animation-props.d.ts.map +1 -0
- package/dist/animation-loop/animation-props.js +1 -0
- package/dist/animation-loop/make-animation-loop.d.ts +6 -0
- package/dist/animation-loop/make-animation-loop.d.ts.map +1 -0
- package/dist/animation-loop/make-animation-loop.js +32 -0
- package/dist/computation.d.ts +95 -0
- package/dist/computation.d.ts.map +1 -0
- package/dist/computation.js +248 -0
- package/dist/debug/copy-texture-to-image.d.ts +26 -0
- package/dist/debug/copy-texture-to-image.d.ts.map +1 -0
- package/dist/debug/copy-texture-to-image.js +43 -0
- package/dist/debug/debug-framebuffer.d.ts +11 -0
- package/dist/debug/debug-framebuffer.d.ts.map +1 -0
- package/dist/debug/debug-framebuffer.js +46 -0
- package/dist/debug/debug-shader-layout.d.ts +9 -0
- package/dist/debug/debug-shader-layout.d.ts.map +1 -0
- package/dist/debug/debug-shader-layout.js +27 -0
- package/dist/debug/pixel-data-utils.d.ts +24 -0
- package/dist/debug/pixel-data-utils.d.ts.map +1 -0
- package/dist/debug/pixel-data-utils.js +39 -0
- package/dist/dist.dev.js +9592 -0
- package/dist/dist.min.js +102 -0
- package/dist/geometries/cone-geometry.d.ts +2 -2
- package/dist/geometries/cone-geometry.d.ts.map +1 -1
- package/dist/geometries/cone-geometry.js +13 -18
- package/dist/geometries/cube-geometry.d.ts +2 -2
- package/dist/geometries/cube-geometry.d.ts.map +1 -1
- package/dist/geometries/cube-geometry.js +192 -57
- package/dist/geometries/cylinder-geometry.d.ts +2 -2
- package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
- package/dist/geometries/cylinder-geometry.js +11 -15
- package/dist/geometries/ico-sphere-geometry.d.ts +2 -2
- package/dist/geometries/ico-sphere-geometry.d.ts.map +1 -1
- package/dist/geometries/ico-sphere-geometry.js +143 -171
- package/dist/geometries/plane-geometry.d.ts +2 -2
- package/dist/geometries/plane-geometry.d.ts.map +1 -1
- package/dist/geometries/plane-geometry.js +95 -122
- package/dist/geometries/sphere-geometry.d.ts +2 -2
- package/dist/geometries/sphere-geometry.d.ts.map +1 -1
- package/dist/geometries/sphere-geometry.js +78 -101
- package/dist/geometries/truncated-cone-geometry.d.ts +2 -4
- package/dist/geometries/truncated-cone-geometry.d.ts.map +1 -1
- package/dist/geometries/truncated-cone-geometry.js +100 -134
- package/dist/geometry/geometry-table.d.ts +2 -2
- package/dist/geometry/geometry-table.d.ts.map +1 -1
- package/dist/geometry/geometry-table.js +3 -1
- package/dist/geometry/geometry-utils.d.ts.map +1 -1
- package/dist/geometry/geometry-utils.js +35 -41
- package/dist/geometry/geometry.d.ts +43 -43
- package/dist/geometry/geometry.d.ts.map +1 -1
- package/dist/geometry/geometry.js +82 -139
- package/dist/geometry/gpu-geometry.d.ts +37 -0
- package/dist/geometry/gpu-geometry.d.ts.map +1 -0
- package/dist/geometry/gpu-geometry.js +90 -0
- package/dist/geometry/gpu-table.d.ts +1 -0
- package/dist/geometry/gpu-table.d.ts.map +1 -0
- package/dist/geometry/gpu-table.js +42 -0
- package/dist/index.cjs +3444 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +43 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -15
- package/dist/lib/clip-space.d.ts +8 -0
- package/dist/lib/clip-space.d.ts.map +1 -1
- package/dist/lib/clip-space.js +43 -2
- package/dist/lib/pipeline-factory.d.ts +17 -51
- package/dist/lib/pipeline-factory.d.ts.map +1 -1
- package/dist/lib/pipeline-factory.js +84 -209
- package/dist/lib/shader-factory.d.ts +17 -0
- package/dist/lib/shader-factory.d.ts.map +1 -0
- package/dist/lib/shader-factory.js +46 -0
- package/dist/model/model.d.ts +219 -0
- package/dist/model/model.d.ts.map +1 -0
- package/dist/model/model.js +659 -0
- package/dist/scenegraph/group-node.d.ts +21 -0
- package/dist/scenegraph/group-node.d.ts.map +1 -0
- package/dist/scenegraph/group-node.js +84 -0
- package/dist/scenegraph/model-node.d.ts +18 -0
- package/dist/scenegraph/model-node.d.ts.map +1 -0
- package/dist/scenegraph/model-node.js +35 -0
- package/dist/scenegraph/scenegraph-node.d.ts +56 -0
- package/dist/scenegraph/scenegraph-node.d.ts.map +1 -0
- package/dist/scenegraph/scenegraph-node.js +153 -0
- package/dist/shader-inputs.d.ts +63 -0
- package/dist/shader-inputs.d.ts.map +1 -0
- package/dist/shader-inputs.js +107 -0
- package/dist/transform/buffer-transform.d.ts +35 -0
- package/dist/transform/buffer-transform.d.ts.map +1 -0
- package/dist/transform/buffer-transform.js +70 -0
- package/dist/transform/texture-transform.d.ts +57 -0
- package/dist/transform/texture-transform.d.ts.map +1 -0
- package/dist/transform/texture-transform.js +117 -0
- package/dist.min.js +25 -0
- package/package.json +24 -14
- package/src/animation/timeline.ts +35 -34
- package/src/animation-loop/animation-loop-template.ts +25 -0
- package/src/{lib → animation-loop}/animation-loop.ts +114 -93
- package/src/{lib → animation-loop}/animation-props.ts +2 -2
- package/src/animation-loop/make-animation-loop.ts +53 -0
- package/src/computation.ts +346 -0
- package/src/debug/copy-texture-to-image.ts +70 -0
- package/src/debug/debug-framebuffer.ts +70 -0
- package/src/debug/debug-shader-layout.ts +38 -0
- package/src/debug/pixel-data-utils.ts +54 -0
- package/src/geometries/cone-geometry.ts +1 -1
- package/src/geometries/cube-geometry.ts +62 -56
- package/src/geometries/cylinder-geometry.ts +2 -2
- package/src/geometries/ico-sphere-geometry.ts +6 -5
- package/src/geometries/plane-geometry.ts +5 -4
- package/src/geometries/sphere-geometry.ts +4 -3
- package/src/geometries/truncated-cone-geometry.ts +6 -14
- package/src/geometry/geometry-table.ts +10 -7
- package/src/geometry/geometry-utils.ts +19 -3
- package/src/geometry/geometry.ts +68 -110
- package/src/geometry/gpu-geometry.ts +132 -0
- package/src/geometry/gpu-table.ts +41 -0
- package/src/index.ts +37 -10
- package/src/lib/clip-space.ts +32 -34
- package/src/lib/pipeline-factory.ts +83 -193
- package/src/lib/shader-factory.ts +57 -0
- package/src/model/model.ts +835 -0
- package/src/scenegraph/group-node.ts +107 -0
- package/src/scenegraph/model-node.ts +50 -0
- package/src/scenegraph/scenegraph-node.ts +204 -0
- package/src/shader-inputs.ts +157 -0
- package/src/transform/buffer-transform.ts +102 -0
- package/src/transform/texture-transform.ts +168 -0
- package/dist/animation/key-frames.js.map +0 -1
- package/dist/animation/timeline.js.map +0 -1
- package/dist/bundle.d.ts +0 -2
- package/dist/bundle.d.ts.map +0 -1
- package/dist/bundle.js +0 -5
- package/dist/bundle.js.map +0 -1
- package/dist/geometries/cone-geometry.js.map +0 -1
- package/dist/geometries/cube-geometry.js.map +0 -1
- package/dist/geometries/cylinder-geometry.js.map +0 -1
- package/dist/geometries/ico-sphere-geometry.js.map +0 -1
- package/dist/geometries/plane-geometry.js.map +0 -1
- package/dist/geometries/sphere-geometry.js.map +0 -1
- package/dist/geometries/truncated-cone-geometry.js.map +0 -1
- package/dist/geometry/geometry-table.js.map +0 -1
- package/dist/geometry/geometry-utils.js.map +0 -1
- package/dist/geometry/geometry.js.map +0 -1
- package/dist/geometry/primitive-utils.d.ts +0 -1
- package/dist/geometry/primitive-utils.d.ts.map +0 -1
- package/dist/geometry/primitive-utils.js +0 -2
- package/dist/geometry/primitive-utils.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/animation-loop.d.ts.map +0 -1
- package/dist/lib/animation-loop.js +0 -480
- package/dist/lib/animation-loop.js.map +0 -1
- package/dist/lib/animation-props.d.ts.map +0 -1
- package/dist/lib/animation-props.js +0 -2
- package/dist/lib/animation-props.js.map +0 -1
- package/dist/lib/clip-space.js.map +0 -1
- package/dist/lib/model-utils.d.ts +0 -5
- package/dist/lib/model-utils.d.ts.map +0 -1
- package/dist/lib/model-utils.js +0 -45
- package/dist/lib/model-utils.js.map +0 -1
- package/dist/lib/model.d.ts +0 -41
- package/dist/lib/model.d.ts.map +0 -1
- package/dist/lib/model.js +0 -182
- package/dist/lib/model.js.map +0 -1
- package/dist/lib/pipeline-factory.js.map +0 -1
- package/dist/lib/render-loop.d.ts +0 -14
- package/dist/lib/render-loop.d.ts.map +0 -1
- package/dist/lib/render-loop.js +0 -49
- package/dist/lib/render-loop.js.map +0 -1
- package/src/bundle.ts +0 -4
- package/src/geometry/primitive-utils.ts +0 -30
- package/src/lib/model-utils.ts +0 -124
- package/src/lib/model.ts +0 -183
- 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
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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
|
|
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":"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"}
|