@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
|
@@ -1,53 +1,57 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {luma, Device} from '@luma.gl/core';
|
|
6
|
+
import {requestAnimationFrame, cancelAnimationFrame} from '@luma.gl/core';
|
|
3
7
|
import {Timeline} from '../animation/timeline';
|
|
4
|
-
import {AnimationProps} from '
|
|
8
|
+
import {AnimationProps} from './animation-props';
|
|
5
9
|
import {Stats, Stat} from '@probe.gl/stats';
|
|
6
|
-
import {isBrowser} from '@probe.gl/env';
|
|
7
|
-
|
|
8
|
-
const isPage = isBrowser() && typeof document !== 'undefined';
|
|
9
10
|
|
|
10
11
|
let statIdCounter = 0;
|
|
11
12
|
|
|
12
|
-
type ContextProps = DeviceProps;
|
|
13
|
-
|
|
14
13
|
/** AnimationLoop properties */
|
|
15
14
|
export type AnimationLoopProps = {
|
|
16
|
-
|
|
15
|
+
device: Device | Promise<Device>;
|
|
16
|
+
|
|
17
17
|
onAddHTML?: (div: HTMLDivElement) => string; // innerHTML
|
|
18
|
-
onInitialize?: (animationProps: AnimationProps) =>
|
|
19
|
-
onRender?: (animationProps: AnimationProps) =>
|
|
18
|
+
onInitialize?: (animationProps: AnimationProps) => Promise<unknown>;
|
|
19
|
+
onRender?: (animationProps: AnimationProps) => unknown;
|
|
20
20
|
onFinalize?: (animationProps: AnimationProps) => void;
|
|
21
21
|
onError?: (reason: Error) => void;
|
|
22
22
|
|
|
23
|
-
device?: Device | null;
|
|
24
|
-
deviceProps?: DeviceProps;
|
|
25
23
|
stats?: Stats;
|
|
26
24
|
|
|
25
|
+
// view parameters - TODO move to CanvasContext?
|
|
26
|
+
autoResizeViewport?: boolean;
|
|
27
|
+
autoResizeDrawingBuffer?: boolean;
|
|
28
|
+
useDevicePixels?: number | boolean;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type MutableAnimationLoopProps = {
|
|
27
32
|
// view parameters
|
|
28
|
-
debug?: boolean;
|
|
29
33
|
autoResizeViewport?: boolean;
|
|
30
34
|
autoResizeDrawingBuffer?: boolean;
|
|
31
35
|
useDevicePixels?: number | boolean;
|
|
32
36
|
};
|
|
33
37
|
|
|
34
38
|
const DEFAULT_ANIMATION_LOOP_PROPS: Required<AnimationLoopProps> = {
|
|
35
|
-
|
|
39
|
+
device: null!,
|
|
40
|
+
|
|
36
41
|
onAddHTML: () => '',
|
|
37
|
-
onInitialize: () =>
|
|
42
|
+
onInitialize: async () => {
|
|
43
|
+
return null;
|
|
44
|
+
},
|
|
38
45
|
onRender: () => {},
|
|
39
46
|
onFinalize: () => {},
|
|
40
|
-
onError:
|
|
47
|
+
onError: error => console.error(error), // eslint-disable-line no-console
|
|
41
48
|
|
|
42
|
-
device: null,
|
|
43
|
-
deviceProps: {},
|
|
44
|
-
debug: false,
|
|
45
49
|
stats: luma.stats.get(`animation-loop-${statIdCounter++}`),
|
|
46
50
|
|
|
47
51
|
// view parameters
|
|
48
52
|
useDevicePixels: true,
|
|
49
|
-
autoResizeViewport:
|
|
50
|
-
autoResizeDrawingBuffer:
|
|
53
|
+
autoResizeViewport: false,
|
|
54
|
+
autoResizeDrawingBuffer: false
|
|
51
55
|
};
|
|
52
56
|
|
|
53
57
|
/** Convenient animation loop */
|
|
@@ -71,7 +75,7 @@ export class AnimationLoop {
|
|
|
71
75
|
_running: boolean = false;
|
|
72
76
|
_animationFrameId: any = null;
|
|
73
77
|
_nextFramePromise: Promise<AnimationLoop> | null = null;
|
|
74
|
-
_resolveNextFrame: ((AnimationLoop) => void) | null = null;
|
|
78
|
+
_resolveNextFrame: ((animationLoop: AnimationLoop) => void) | null = null;
|
|
75
79
|
_cpuStartTime: number = 0;
|
|
76
80
|
|
|
77
81
|
// _gpuTimeQuery: Query | null = null;
|
|
@@ -79,17 +83,17 @@ export class AnimationLoop {
|
|
|
79
83
|
/*
|
|
80
84
|
* @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
|
|
81
85
|
*/
|
|
82
|
-
constructor(props: AnimationLoopProps
|
|
86
|
+
constructor(props: AnimationLoopProps) {
|
|
83
87
|
this.props = {...DEFAULT_ANIMATION_LOOP_PROPS, ...props};
|
|
84
88
|
props = this.props;
|
|
85
89
|
|
|
86
|
-
|
|
90
|
+
if (!props.device) {
|
|
91
|
+
throw new Error('No device provided');
|
|
92
|
+
}
|
|
87
93
|
|
|
88
|
-
|
|
89
|
-
this.device = props.device || null;
|
|
90
|
-
// @ts-expect-error
|
|
91
|
-
this.gl = (this.device && this.device.gl) || props.gl;
|
|
94
|
+
const {useDevicePixels = true} = this.props;
|
|
92
95
|
|
|
96
|
+
// state
|
|
93
97
|
this.stats = props.stats || new Stats({id: 'animation-loop-stats'});
|
|
94
98
|
this.cpuTime = this.stats.get('CPU Time');
|
|
95
99
|
this.gpuTime = this.stats.get('GPU Time');
|
|
@@ -119,13 +123,14 @@ export class AnimationLoop {
|
|
|
119
123
|
this.destroy();
|
|
120
124
|
}
|
|
121
125
|
|
|
126
|
+
/** Flags this animation loop as needing redraw */
|
|
122
127
|
setNeedsRedraw(reason: string): this {
|
|
123
128
|
this.needsRedraw = this.needsRedraw || reason;
|
|
124
129
|
return this;
|
|
125
130
|
}
|
|
126
131
|
|
|
127
|
-
|
|
128
|
-
setProps(props:
|
|
132
|
+
/** TODO - move these props to CanvasContext? */
|
|
133
|
+
setProps(props: MutableAnimationLoopProps): this {
|
|
129
134
|
if ('autoResizeViewport' in props) {
|
|
130
135
|
this.props.autoResizeViewport = props.autoResizeViewport || false;
|
|
131
136
|
}
|
|
@@ -146,16 +151,11 @@ export class AnimationLoop {
|
|
|
146
151
|
this._running = true;
|
|
147
152
|
|
|
148
153
|
try {
|
|
149
|
-
// check that we haven't been stopped
|
|
150
|
-
if (!this._running) {
|
|
151
|
-
return null;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
154
|
let appContext;
|
|
155
155
|
if (!this._initialized) {
|
|
156
156
|
this._initialized = true;
|
|
157
157
|
// Create the WebGL context
|
|
158
|
-
await this.
|
|
158
|
+
await this._initDevice();
|
|
159
159
|
this._initialize();
|
|
160
160
|
|
|
161
161
|
// Note: onIntialize can return a promise (e.g. in case app needs to load resources)
|
|
@@ -176,20 +176,38 @@ export class AnimationLoop {
|
|
|
176
176
|
|
|
177
177
|
return this;
|
|
178
178
|
} catch (err: unknown) {
|
|
179
|
-
const error = err instanceof Error ? err : new Error('Unknown error')
|
|
179
|
+
const error = err instanceof Error ? err : new Error('Unknown error');
|
|
180
180
|
this.props.onError(error);
|
|
181
181
|
// this._running = false; // TODO
|
|
182
182
|
throw error;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
/** Stops a render loop if already running, finalizing */
|
|
187
|
+
stop() {
|
|
188
|
+
// console.debug(`Stopping ${this.constructor.name}`);
|
|
189
|
+
if (this._running) {
|
|
190
|
+
// call callback
|
|
191
|
+
// If stop is called immediately, we can end up in a state where props haven't been initialized...
|
|
192
|
+
if (this.animationProps) {
|
|
193
|
+
this.props.onFinalize(this.animationProps);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
this._cancelAnimationFrame();
|
|
197
|
+
this._nextFramePromise = null;
|
|
198
|
+
this._resolveNextFrame = null;
|
|
199
|
+
this._running = false;
|
|
200
|
+
}
|
|
201
|
+
return this;
|
|
202
|
+
}
|
|
203
|
+
|
|
186
204
|
/** Explicitly draw a frame */
|
|
187
205
|
redraw(): this {
|
|
188
206
|
if (this.device?.isLost) {
|
|
189
207
|
return this;
|
|
190
208
|
}
|
|
191
209
|
|
|
192
|
-
this.
|
|
210
|
+
this._beginFrameTimers();
|
|
193
211
|
|
|
194
212
|
this._setupFrame();
|
|
195
213
|
this._updateAnimationProps();
|
|
@@ -205,49 +223,35 @@ export class AnimationLoop {
|
|
|
205
223
|
this._resolveNextFrame = null;
|
|
206
224
|
}
|
|
207
225
|
|
|
208
|
-
this.
|
|
226
|
+
this._endFrameTimers();
|
|
209
227
|
|
|
210
228
|
return this;
|
|
211
229
|
}
|
|
212
230
|
|
|
213
|
-
|
|
214
|
-
stop() {
|
|
215
|
-
// console.debug(`Stopping ${this.constructor.name}`);
|
|
216
|
-
if (this._running) {
|
|
217
|
-
// call callback
|
|
218
|
-
// If stop is called immediately, we can end up in a state where props haven't been initialized...
|
|
219
|
-
if (this.animationProps) {
|
|
220
|
-
this.props.onFinalize(this.animationProps);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
this._cancelAnimationFrame();
|
|
224
|
-
this._nextFramePromise = null;
|
|
225
|
-
this._resolveNextFrame = null;
|
|
226
|
-
this._running = false;
|
|
227
|
-
}
|
|
228
|
-
return this;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
+
/** Add a timeline, it will be automatically updated by the animation loop. */
|
|
231
232
|
attachTimeline(timeline: Timeline): Timeline {
|
|
232
233
|
this.timeline = timeline;
|
|
233
234
|
return this.timeline;
|
|
234
235
|
}
|
|
235
236
|
|
|
237
|
+
/** Remove a timeline */
|
|
236
238
|
detachTimeline(): void {
|
|
237
239
|
this.timeline = null;
|
|
238
240
|
}
|
|
239
241
|
|
|
242
|
+
/** Wait until a render completes */
|
|
240
243
|
waitForRender(): Promise<AnimationLoop> {
|
|
241
244
|
this.setNeedsRedraw('waitForRender');
|
|
242
245
|
|
|
243
246
|
if (!this._nextFramePromise) {
|
|
244
|
-
this._nextFramePromise = new Promise(
|
|
247
|
+
this._nextFramePromise = new Promise(resolve => {
|
|
245
248
|
this._resolveNextFrame = resolve;
|
|
246
249
|
});
|
|
247
250
|
}
|
|
248
251
|
return this._nextFramePromise;
|
|
249
252
|
}
|
|
250
253
|
|
|
254
|
+
/** TODO - should use device.deviceContext */
|
|
251
255
|
async toDataURL(): Promise<string> {
|
|
252
256
|
this.setNeedsRedraw('toDataURL');
|
|
253
257
|
await this.waitForRender();
|
|
@@ -259,7 +263,7 @@ export class AnimationLoop {
|
|
|
259
263
|
|
|
260
264
|
// PRIVATE METHODS
|
|
261
265
|
|
|
262
|
-
_initialize() {
|
|
266
|
+
_initialize(): void {
|
|
263
267
|
this._startEventHandling();
|
|
264
268
|
|
|
265
269
|
// Initialize the callback data
|
|
@@ -273,9 +277,9 @@ export class AnimationLoop {
|
|
|
273
277
|
// this._gpuTimeQuery = Query.isSupported(this.gl, ['timers']) ? new Query(this.gl) : null;
|
|
274
278
|
}
|
|
275
279
|
|
|
276
|
-
_setDisplay(display) {
|
|
280
|
+
_setDisplay(display: any): void {
|
|
277
281
|
if (this.display) {
|
|
278
|
-
this.display.
|
|
282
|
+
this.display.destroy();
|
|
279
283
|
this.display.animationLoop = null;
|
|
280
284
|
}
|
|
281
285
|
|
|
@@ -287,7 +291,7 @@ export class AnimationLoop {
|
|
|
287
291
|
this.display = display;
|
|
288
292
|
}
|
|
289
293
|
|
|
290
|
-
_requestAnimationFrame() {
|
|
294
|
+
_requestAnimationFrame(): void {
|
|
291
295
|
if (!this._running) {
|
|
292
296
|
return;
|
|
293
297
|
}
|
|
@@ -301,8 +305,8 @@ export class AnimationLoop {
|
|
|
301
305
|
this._animationFrameId = requestAnimationFrame(this._animationFrame.bind(this));
|
|
302
306
|
}
|
|
303
307
|
|
|
304
|
-
_cancelAnimationFrame() {
|
|
305
|
-
if (this._animationFrameId
|
|
308
|
+
_cancelAnimationFrame(): void {
|
|
309
|
+
if (this._animationFrameId === null) {
|
|
306
310
|
return;
|
|
307
311
|
}
|
|
308
312
|
|
|
@@ -312,11 +316,11 @@ export class AnimationLoop {
|
|
|
312
316
|
// if (this.display && this.display.cancelAnimationFrame) {
|
|
313
317
|
// this.display.cancelAnimationFrame(this._animationFrameId);
|
|
314
318
|
// }
|
|
315
|
-
|
|
319
|
+
cancelAnimationFrame(this._animationFrameId);
|
|
316
320
|
this._animationFrameId = null;
|
|
317
321
|
}
|
|
318
322
|
|
|
319
|
-
_animationFrame() {
|
|
323
|
+
_animationFrame(): void {
|
|
320
324
|
if (!this._running) {
|
|
321
325
|
return;
|
|
322
326
|
}
|
|
@@ -326,36 +330,40 @@ export class AnimationLoop {
|
|
|
326
330
|
|
|
327
331
|
// Called on each frame, can be overridden to call onRender multiple times
|
|
328
332
|
// to support e.g. stereoscopic rendering
|
|
329
|
-
_renderFrame(
|
|
333
|
+
_renderFrame(animationProps: AnimationProps): void {
|
|
330
334
|
// Allow e.g. VR display to render multiple frames.
|
|
331
335
|
if (this.display) {
|
|
332
|
-
this.display._renderFrame(
|
|
336
|
+
this.display._renderFrame(animationProps);
|
|
333
337
|
return;
|
|
334
338
|
}
|
|
335
339
|
|
|
336
340
|
// call callback
|
|
337
|
-
this.props.onRender(
|
|
341
|
+
this.props.onRender(this._getAnimationProps());
|
|
338
342
|
// end callback
|
|
343
|
+
|
|
344
|
+
// Submit commands (necessary on WebGPU)
|
|
345
|
+
this.device.submit();
|
|
339
346
|
}
|
|
340
347
|
|
|
341
|
-
_clearNeedsRedraw() {
|
|
348
|
+
_clearNeedsRedraw(): void {
|
|
342
349
|
this.needsRedraw = false;
|
|
343
350
|
}
|
|
344
351
|
|
|
345
|
-
_setupFrame() {
|
|
352
|
+
_setupFrame(): void {
|
|
346
353
|
this._resizeCanvasDrawingBuffer();
|
|
347
354
|
this._resizeViewport();
|
|
348
355
|
}
|
|
349
356
|
|
|
350
357
|
// Initialize the object that will be passed to app callbacks
|
|
351
|
-
_initializeAnimationProps() {
|
|
358
|
+
_initializeAnimationProps(): void {
|
|
352
359
|
if (!this.device) {
|
|
353
360
|
throw new Error('loop');
|
|
354
361
|
}
|
|
355
362
|
this.animationProps = {
|
|
356
363
|
animationLoop: this,
|
|
364
|
+
|
|
357
365
|
device: this.device,
|
|
358
|
-
canvas: this.device?.canvasContext?.canvas
|
|
366
|
+
canvas: this.device?.canvasContext?.canvas,
|
|
359
367
|
timeline: this.timeline,
|
|
360
368
|
|
|
361
369
|
// Initial values
|
|
@@ -392,6 +400,7 @@ export class AnimationLoop {
|
|
|
392
400
|
return;
|
|
393
401
|
}
|
|
394
402
|
|
|
403
|
+
// Can this be replaced with canvas context?
|
|
395
404
|
const {width, height, aspect} = this._getSizeAndAspect();
|
|
396
405
|
if (width !== this.animationProps.width || height !== this.animationProps.height) {
|
|
397
406
|
this.setNeedsRedraw('drawing buffer resized');
|
|
@@ -422,15 +431,17 @@ export class AnimationLoop {
|
|
|
422
431
|
: this.animationProps.engineTime;
|
|
423
432
|
}
|
|
424
433
|
|
|
425
|
-
/**
|
|
426
|
-
async
|
|
427
|
-
|
|
428
|
-
this.device
|
|
429
|
-
|
|
430
|
-
|
|
434
|
+
/** Wait for supplied device */
|
|
435
|
+
async _initDevice() {
|
|
436
|
+
this.device = await this.props.device;
|
|
437
|
+
if (!this.device) {
|
|
438
|
+
throw new Error('No device provided');
|
|
439
|
+
}
|
|
440
|
+
this.canvas = this.device.canvasContext?.canvas || null;
|
|
441
|
+
// this._createInfoDiv();
|
|
431
442
|
}
|
|
432
443
|
|
|
433
|
-
_createInfoDiv() {
|
|
444
|
+
_createInfoDiv(): void {
|
|
434
445
|
if (this.canvas && this.props.onAddHTML) {
|
|
435
446
|
const wrapperDiv = document.createElement('div');
|
|
436
447
|
document.body.appendChild(wrapperDiv);
|
|
@@ -452,7 +463,7 @@ export class AnimationLoop {
|
|
|
452
463
|
}
|
|
453
464
|
}
|
|
454
465
|
|
|
455
|
-
_getSizeAndAspect(): {width: number; height: number; aspect: number}
|
|
466
|
+
_getSizeAndAspect(): {width: number; height: number; aspect: number} {
|
|
456
467
|
if (!this.device) {
|
|
457
468
|
return {width: 1, height: 1, aspect: 1};
|
|
458
469
|
}
|
|
@@ -475,11 +486,19 @@ export class AnimationLoop {
|
|
|
475
486
|
}
|
|
476
487
|
|
|
477
488
|
/** Default viewport setup */
|
|
478
|
-
_resizeViewport() {
|
|
489
|
+
_resizeViewport(): void {
|
|
490
|
+
// TODO can we use canvas context to code this in a portable way?
|
|
479
491
|
// @ts-expect-error Expose on canvasContext
|
|
480
492
|
if (this.props.autoResizeViewport && this.device.gl) {
|
|
481
493
|
// @ts-expect-error Expose canvasContext
|
|
482
|
-
this.device.gl.viewport(
|
|
494
|
+
this.device.gl.viewport(
|
|
495
|
+
0,
|
|
496
|
+
0,
|
|
497
|
+
// @ts-expect-error Expose canvasContext
|
|
498
|
+
this.device.gl.drawingBufferWidth,
|
|
499
|
+
// @ts-expect-error Expose canvasContext
|
|
500
|
+
this.device.gl.drawingBufferHeight
|
|
501
|
+
);
|
|
483
502
|
}
|
|
484
503
|
}
|
|
485
504
|
|
|
@@ -487,13 +506,13 @@ export class AnimationLoop {
|
|
|
487
506
|
* Resize the render buffer of the canvas to match canvas client size
|
|
488
507
|
* Optionally multiplying with devicePixel ratio
|
|
489
508
|
*/
|
|
490
|
-
_resizeCanvasDrawingBuffer() {
|
|
509
|
+
_resizeCanvasDrawingBuffer(): void {
|
|
491
510
|
if (this.props.autoResizeDrawingBuffer) {
|
|
492
511
|
this.device?.canvasContext?.resize({useDevicePixels: this.props.useDevicePixels});
|
|
493
512
|
}
|
|
494
513
|
}
|
|
495
514
|
|
|
496
|
-
|
|
515
|
+
_beginFrameTimers() {
|
|
497
516
|
this.frameRate.timeEnd();
|
|
498
517
|
this.frameRate.timeStart();
|
|
499
518
|
|
|
@@ -513,10 +532,10 @@ export class AnimationLoop {
|
|
|
513
532
|
// this._gpuTimeQuery.beginTimeElapsedQuery();
|
|
514
533
|
// }
|
|
515
534
|
|
|
516
|
-
|
|
535
|
+
this.cpuTime.timeStart();
|
|
517
536
|
}
|
|
518
537
|
|
|
519
|
-
|
|
538
|
+
_endFrameTimers() {
|
|
520
539
|
this.cpuTime.timeEnd();
|
|
521
540
|
|
|
522
541
|
// if (this._gpuTimeQuery) {
|
|
@@ -529,16 +548,18 @@ export class AnimationLoop {
|
|
|
529
548
|
|
|
530
549
|
_startEventHandling() {
|
|
531
550
|
if (this.canvas) {
|
|
532
|
-
this.canvas.addEventListener('mousemove', this._onMousemove);
|
|
533
|
-
this.canvas.addEventListener('mouseleave', this._onMouseleave);
|
|
551
|
+
this.canvas.addEventListener('mousemove', this._onMousemove.bind(this));
|
|
552
|
+
this.canvas.addEventListener('mouseleave', this._onMouseleave.bind(this));
|
|
534
553
|
}
|
|
535
554
|
}
|
|
536
555
|
|
|
537
|
-
_onMousemove(
|
|
538
|
-
|
|
556
|
+
_onMousemove(event: Event) {
|
|
557
|
+
if (event instanceof MouseEvent) {
|
|
558
|
+
this._getAnimationProps()._mousePosition = [event.offsetX, event.offsetY];
|
|
559
|
+
}
|
|
539
560
|
}
|
|
540
561
|
|
|
541
|
-
_onMouseleave(
|
|
562
|
+
_onMouseleave(event: Event) {
|
|
542
563
|
this._getAnimationProps()._mousePosition = null;
|
|
543
564
|
}
|
|
544
565
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {Device} from '@luma.gl/
|
|
2
|
-
import {Timeline} from '../animation/timeline'
|
|
1
|
+
import {Device} from '@luma.gl/core';
|
|
2
|
+
import {Timeline} from '../animation/timeline';
|
|
3
3
|
import type {AnimationLoop} from './animation-loop';
|
|
4
4
|
|
|
5
5
|
/** Properties passed to every render frame */
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {luma} from '@luma.gl/core';
|
|
6
|
+
import {AnimationLoopTemplate} from './animation-loop-template';
|
|
7
|
+
import {AnimationLoop, AnimationLoopProps} from './animation-loop';
|
|
8
|
+
import type {AnimationProps} from './animation-props';
|
|
9
|
+
|
|
10
|
+
export type MakeAnimationLoopProps = Omit<
|
|
11
|
+
AnimationLoopProps,
|
|
12
|
+
'onCreateDevice' | 'onInitialize' | 'onRedraw' | 'onFinalize'
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
/** Instantiates and runs the render loop */
|
|
16
|
+
export function makeAnimationLoop(
|
|
17
|
+
AnimationLoopTemplateCtor: typeof AnimationLoopTemplate,
|
|
18
|
+
props?: MakeAnimationLoopProps
|
|
19
|
+
): AnimationLoop {
|
|
20
|
+
let renderLoop: AnimationLoopTemplate | null = null;
|
|
21
|
+
|
|
22
|
+
const device = props?.device || luma.createDevice();
|
|
23
|
+
|
|
24
|
+
// Create an animation loop;
|
|
25
|
+
const animationLoop = new AnimationLoop({
|
|
26
|
+
...props,
|
|
27
|
+
|
|
28
|
+
device,
|
|
29
|
+
|
|
30
|
+
async onInitialize(animationProps: AnimationProps): Promise<unknown> {
|
|
31
|
+
// @ts-expect-error abstract to prevent instantiation
|
|
32
|
+
renderLoop = new AnimationLoopTemplateCtor(animationProps);
|
|
33
|
+
// Any async loading can be handled here
|
|
34
|
+
return await renderLoop?.onInitialize(animationProps);
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
onRender: (animationProps: AnimationProps) => renderLoop?.onRender(animationProps),
|
|
38
|
+
|
|
39
|
+
onFinalize: (animationProps: AnimationProps) => renderLoop?.onFinalize(animationProps)
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// @ts-expect-error Hack: adds info for the website to find
|
|
43
|
+
animationLoop.getInfo = () => {
|
|
44
|
+
// @ts-ignore
|
|
45
|
+
// eslint-disable-next-line no-invalid-this
|
|
46
|
+
return this.AnimationLoopTemplateCtor.info;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Start the loop automatically
|
|
50
|
+
// animationLoop.start();
|
|
51
|
+
|
|
52
|
+
return animationLoop;
|
|
53
|
+
}
|