@luma.gl/engine 9.0.0-alpha.3 → 9.0.0-alpha.30
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 +2 -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 +0 -20
- package/dist/animation/key-frames.js.map +1 -1
- package/dist/animation/timeline.d.ts +5 -5
- package/dist/animation/timeline.d.ts.map +1 -1
- package/dist/animation/timeline.js +0 -30
- package/dist/animation/timeline.js.map +1 -1
- package/dist/{lib → animation-loop}/animation-loop.d.ts +28 -29
- package/dist/animation-loop/animation-loop.d.ts.map +1 -0
- package/dist/{lib → animation-loop}/animation-loop.js +96 -175
- package/dist/animation-loop/animation-loop.js.map +1 -0
- package/dist/{lib → animation-loop}/animation-props.d.ts +7 -7
- package/dist/animation-loop/animation-props.d.ts.map +1 -0
- package/dist/animation-loop/animation-props.js.map +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 +28 -0
- package/dist/animation-loop/make-animation-loop.js.map +1 -0
- package/dist/animation-loop/render-loop.d.ts +23 -0
- package/dist/animation-loop/render-loop.d.ts.map +1 -0
- package/dist/animation-loop/render-loop.js +7 -0
- package/dist/animation-loop/render-loop.js.map +1 -0
- package/dist/dist.dev.js +14887 -0
- package/dist/geometries/cone-geometry.d.ts +1 -1
- package/dist/geometries/cone-geometry.d.ts.map +1 -1
- package/dist/geometries/cone-geometry.js +6 -5
- package/dist/geometries/cone-geometry.js.map +1 -1
- 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 +15 -8
- package/dist/geometries/cube-geometry.js.map +1 -1
- package/dist/geometries/cylinder-geometry.d.ts +1 -1
- package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
- package/dist/geometries/cylinder-geometry.js +6 -5
- package/dist/geometries/cylinder-geometry.js.map +1 -1
- 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 +9 -18
- package/dist/geometries/ico-sphere-geometry.js.map +1 -1
- 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 +10 -19
- package/dist/geometries/plane-geometry.js.map +1 -1
- 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 +9 -13
- package/dist/geometries/sphere-geometry.js.map +1 -1
- package/dist/geometries/truncated-cone-geometry.d.ts +2 -2
- package/dist/geometries/truncated-cone-geometry.d.ts.map +1 -1
- package/dist/geometries/truncated-cone-geometry.js +9 -14
- package/dist/geometries/truncated-cone-geometry.js.map +1 -1
- 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.map +1 -1
- package/dist/geometry/geometry-utils.d.ts.map +1 -1
- package/dist/geometry/geometry-utils.js +0 -9
- package/dist/geometry/geometry-utils.js.map +1 -1
- package/dist/geometry/geometry.d.ts +35 -58
- package/dist/geometry/geometry.d.ts.map +1 -1
- package/dist/geometry/geometry.js +26 -89
- package/dist/geometry/geometry.js.map +1 -1
- package/dist/geometry/primitive-utils.js.map +1 -1
- package/dist/index.cjs +2574 -0
- package/dist/index.d.ts +18 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -13
- package/dist/index.js.map +1 -1
- 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 +36 -1
- package/dist/lib/clip-space.js.map +1 -1
- package/dist/lib/pipeline-factory.d.ts +19 -14
- package/dist/lib/pipeline-factory.d.ts.map +1 -1
- package/dist/lib/pipeline-factory.js +52 -63
- package/dist/lib/pipeline-factory.js.map +1 -1
- package/dist/{lib → model}/model-utils.d.ts +2 -2
- package/dist/model/model-utils.d.ts.map +1 -0
- package/dist/{lib → model}/model-utils.js +3 -8
- package/dist/model/model-utils.js.map +1 -0
- package/dist/model/model.d.ts +65 -0
- package/dist/model/model.d.ts.map +1 -0
- package/dist/{lib → model}/model.js +56 -75
- package/dist/model/model.js.map +1 -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 +95 -0
- package/dist/scenegraph/group-node.js.map +1 -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 +29 -0
- package/dist/scenegraph/model-node.js.map +1 -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 +142 -0
- package/dist/scenegraph/scenegraph-node.js.map +1 -0
- package/dist/transform/transform.d.ts +98 -0
- package/dist/transform/transform.d.ts.map +1 -0
- package/dist/transform/transform.js +67 -0
- package/dist/transform/transform.js.map +1 -0
- package/dist.min.js +314 -0
- package/package.json +22 -12
- package/src/animation/timeline.ts +2 -2
- package/src/{lib → animation-loop}/animation-loop.ts +115 -97
- package/src/{lib → animation-loop}/animation-props.ts +6 -5
- package/src/animation-loop/make-animation-loop.ts +44 -0
- package/src/animation-loop/render-loop.ts +23 -0
- package/src/geometries/cone-geometry.ts +1 -1
- package/src/geometries/cube-geometry.ts +6 -3
- package/src/geometries/cylinder-geometry.ts +2 -2
- package/src/geometries/ico-sphere-geometry.ts +7 -6
- package/src/geometries/plane-geometry.ts +5 -4
- package/src/geometries/sphere-geometry.ts +4 -3
- package/src/geometries/truncated-cone-geometry.ts +4 -3
- package/src/geometry/geometry-table.ts +1 -1
- package/src/geometry/geometry-utils.ts +3 -3
- package/src/geometry/geometry.ts +72 -115
- package/src/index.ts +28 -12
- package/src/lib/clip-space.ts +17 -15
- package/src/lib/pipeline-factory.ts +60 -51
- package/src/{lib → model}/model-utils.ts +5 -4
- package/src/model/model.ts +226 -0
- package/src/scenegraph/group-node.ts +103 -0
- package/src/scenegraph/model-node.ts +50 -0
- package/src/scenegraph/scenegraph-node.ts +204 -0
- package/src/transform/transform.ts +246 -0
- 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/lib/animation-loop.d.ts.map +0 -1
- 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.map +0 -1
- package/dist/lib/model-utils.d.ts.map +0 -1
- 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.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/lib/model.ts +0 -179
- package/src/lib/render-loop.ts +0 -58
- /package/dist/{lib → animation-loop}/animation-props.js +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luma.gl/engine",
|
|
3
|
-
"version": "9.0.0-alpha.
|
|
3
|
+
"version": "9.0.0-alpha.30",
|
|
4
4
|
"description": "WebGL2 Components for High Performance Rendering and Computation",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"publishConfig": {
|
|
7
8
|
"access": "public"
|
|
@@ -16,27 +17,36 @@
|
|
|
16
17
|
"animation",
|
|
17
18
|
"3d"
|
|
18
19
|
],
|
|
19
|
-
"types": "
|
|
20
|
-
"main": "dist/index.
|
|
20
|
+
"types": "dist/index.d.ts",
|
|
21
|
+
"main": "dist/index.cjs",
|
|
21
22
|
"module": "dist/index.js",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"import": "./dist/index.js",
|
|
26
|
+
"require": "./dist/index.cjs",
|
|
27
|
+
"types": "./dist/index.d.ts"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
22
30
|
"files": [
|
|
23
31
|
"src",
|
|
24
32
|
"dist",
|
|
33
|
+
"dist.min.js",
|
|
25
34
|
"README.md"
|
|
26
35
|
],
|
|
27
36
|
"sideEffects": false,
|
|
28
37
|
"scripts": {
|
|
29
|
-
"
|
|
30
|
-
"build
|
|
38
|
+
"build-bundle": "ocular-bundle ./src/index.ts",
|
|
39
|
+
"pre-build": "npm run build-bundle && npm run build-bundle -- --env=dev"
|
|
31
40
|
},
|
|
32
41
|
"dependencies": {
|
|
33
42
|
"@babel/runtime": "^7.0.0",
|
|
34
|
-
"@luma.gl/constants": "9.0.0-alpha.
|
|
35
|
-
"@luma.gl/
|
|
36
|
-
"@luma.gl/
|
|
37
|
-
"@
|
|
38
|
-
"@
|
|
39
|
-
"@probe.gl/
|
|
43
|
+
"@luma.gl/constants": "9.0.0-alpha.30",
|
|
44
|
+
"@luma.gl/core": "9.0.0-alpha.30",
|
|
45
|
+
"@luma.gl/shadertools": "9.0.0-alpha.30",
|
|
46
|
+
"@luma.gl/webgl": "9.0.0-alpha.30",
|
|
47
|
+
"@math.gl/core": "4.0.0-alpha.4",
|
|
48
|
+
"@probe.gl/log": "^4.0.2",
|
|
49
|
+
"@probe.gl/stats": "^4.0.2"
|
|
40
50
|
},
|
|
41
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "7fb163f20d3400d59b59a17d36b4f3c466c559ba"
|
|
42
52
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @param rate = 1
|
|
8
8
|
* @param repeat = 1
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
export type ChannelOptions = {
|
|
11
11
|
delay?: number
|
|
12
12
|
duration?: number
|
|
13
13
|
rate?: number
|
|
@@ -27,7 +27,7 @@ export type AnimationOptions = {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
type Animation = {
|
|
30
|
-
channel
|
|
30
|
+
channel?: number;
|
|
31
31
|
animation: {
|
|
32
32
|
setTime: (time: number) => void
|
|
33
33
|
}
|
|
@@ -1,63 +1,64 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// luma.gl, MIT license
|
|
2
|
+
|
|
3
|
+
import {luma, Device} from '@luma.gl/core';
|
|
4
|
+
import {requestAnimationFrame, cancelAnimationFrame} from '@luma.gl/core';
|
|
3
5
|
import {Timeline} from '../animation/timeline';
|
|
4
|
-
import {AnimationProps} from '
|
|
6
|
+
import {AnimationProps} from './animation-props';
|
|
5
7
|
import {Stats, Stat} from '@probe.gl/stats';
|
|
6
|
-
import {isBrowser} from '@probe.gl/env';
|
|
7
|
-
|
|
8
|
-
const isPage = isBrowser() && typeof document !== 'undefined';
|
|
9
8
|
|
|
10
9
|
let statIdCounter = 0;
|
|
11
10
|
|
|
12
|
-
type ContextProps = DeviceProps;
|
|
13
|
-
|
|
14
11
|
/** AnimationLoop properties */
|
|
15
12
|
export type AnimationLoopProps = {
|
|
16
|
-
|
|
13
|
+
device: Device | Promise<Device>;
|
|
14
|
+
|
|
17
15
|
onAddHTML?: (div: HTMLDivElement) => string; // innerHTML
|
|
18
|
-
onInitialize?: (animationProps: AnimationProps) =>
|
|
19
|
-
onRender?: (animationProps: AnimationProps) =>
|
|
16
|
+
onInitialize?: (animationProps: AnimationProps) => Promise<unknown>;
|
|
17
|
+
onRender?: (animationProps: AnimationProps) => unknown;
|
|
20
18
|
onFinalize?: (animationProps: AnimationProps) => void;
|
|
21
19
|
onError?: (reason: Error) => void;
|
|
22
20
|
|
|
23
|
-
device?: Device;
|
|
24
|
-
deviceProps?: DeviceProps;
|
|
25
21
|
stats?: Stats;
|
|
26
22
|
|
|
27
|
-
// view parameters
|
|
28
|
-
debug?: boolean;
|
|
23
|
+
// view parameters - TODO move to CanvasContext?
|
|
29
24
|
autoResizeViewport?: boolean;
|
|
30
25
|
autoResizeDrawingBuffer?: boolean;
|
|
31
26
|
useDevicePixels?: number | boolean;
|
|
32
27
|
};
|
|
33
28
|
|
|
29
|
+
export type MutableAnimationLoopProps = {
|
|
30
|
+
// view parameters
|
|
31
|
+
autoResizeViewport?: boolean;
|
|
32
|
+
autoResizeDrawingBuffer?: boolean;
|
|
33
|
+
useDevicePixels?: number | boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
34
37
|
const DEFAULT_ANIMATION_LOOP_PROPS: Required<AnimationLoopProps> = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
device: null!,
|
|
39
|
+
|
|
40
|
+
onAddHTML: () => '',
|
|
41
|
+
onInitialize: async () => { return null; },
|
|
38
42
|
onRender: () => {},
|
|
39
43
|
onFinalize: () => {},
|
|
40
44
|
onError: (error) => console.error(error), // eslint-disable-line no-console
|
|
41
45
|
|
|
42
|
-
device: undefined,
|
|
43
|
-
deviceProps: {},
|
|
44
|
-
debug: false,
|
|
45
46
|
stats: luma.stats.get(`animation-loop-${statIdCounter++}`),
|
|
46
47
|
|
|
47
48
|
// view parameters
|
|
48
49
|
useDevicePixels: true,
|
|
49
|
-
autoResizeViewport:
|
|
50
|
-
autoResizeDrawingBuffer:
|
|
50
|
+
autoResizeViewport: false,
|
|
51
|
+
autoResizeDrawingBuffer: false,
|
|
51
52
|
};
|
|
52
53
|
|
|
53
54
|
/** Convenient animation loop */
|
|
54
|
-
export
|
|
55
|
-
device: Device;
|
|
56
|
-
canvas: HTMLCanvasElement
|
|
55
|
+
export class AnimationLoop {
|
|
56
|
+
device: Device | null = null;
|
|
57
|
+
canvas: HTMLCanvasElement | OffscreenCanvas | null = null;
|
|
57
58
|
|
|
58
59
|
props: Required<AnimationLoopProps>;
|
|
59
|
-
animationProps: AnimationProps;
|
|
60
|
-
timeline: Timeline = null;
|
|
60
|
+
animationProps: AnimationProps | null = null;
|
|
61
|
+
timeline: Timeline | null = null;
|
|
61
62
|
stats: Stats;
|
|
62
63
|
cpuTime: Stat;
|
|
63
64
|
gpuTime: Stat;
|
|
@@ -65,13 +66,13 @@ export default class AnimationLoop {
|
|
|
65
66
|
|
|
66
67
|
display: any;
|
|
67
68
|
|
|
68
|
-
needsRedraw: string |
|
|
69
|
+
needsRedraw: string | false = 'initialized';
|
|
69
70
|
|
|
70
71
|
_initialized: boolean = false;
|
|
71
72
|
_running: boolean = false;
|
|
72
|
-
_animationFrameId = null;
|
|
73
|
+
_animationFrameId: any = null;
|
|
73
74
|
_nextFramePromise: Promise<AnimationLoop> | null = null;
|
|
74
|
-
_resolveNextFrame: ((AnimationLoop) => void) | null = null;
|
|
75
|
+
_resolveNextFrame: ((animationLoop: AnimationLoop) => void) | null = null;
|
|
75
76
|
_cpuStartTime: number = 0;
|
|
76
77
|
|
|
77
78
|
// _gpuTimeQuery: Query | null = null;
|
|
@@ -79,18 +80,18 @@ export default class AnimationLoop {
|
|
|
79
80
|
/*
|
|
80
81
|
* @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
|
|
81
82
|
*/
|
|
82
|
-
constructor(props: AnimationLoopProps
|
|
83
|
+
constructor(props: AnimationLoopProps) {
|
|
83
84
|
this.props = {...DEFAULT_ANIMATION_LOOP_PROPS, ...props};
|
|
84
85
|
props = this.props;
|
|
85
86
|
|
|
86
|
-
|
|
87
|
+
if (!props.device) {
|
|
88
|
+
throw new Error('No device provided');
|
|
89
|
+
}
|
|
87
90
|
|
|
88
|
-
|
|
89
|
-
this.device = props.device;
|
|
90
|
-
// @ts-expect-error
|
|
91
|
-
this.gl = (this.device && this.device.gl) || props.gl;
|
|
91
|
+
const {useDevicePixels = true} = this.props;
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
// state
|
|
94
|
+
this.stats = props.stats || new Stats({id: 'animation-loop-stats'});
|
|
94
95
|
this.cpuTime = this.stats.get('CPU Time');
|
|
95
96
|
this.gpuTime = this.stats.get('GPU Time');
|
|
96
97
|
this.frameRate = this.stats.get('Frame Rate');
|
|
@@ -125,15 +126,15 @@ export default class AnimationLoop {
|
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
// TODO - move to CanvasContext
|
|
128
|
-
setProps(props:
|
|
129
|
+
setProps(props: MutableAnimationLoopProps): this {
|
|
129
130
|
if ('autoResizeViewport' in props) {
|
|
130
|
-
this.props.autoResizeViewport = props.autoResizeViewport;
|
|
131
|
+
this.props.autoResizeViewport = props.autoResizeViewport || false;
|
|
131
132
|
}
|
|
132
133
|
if ('autoResizeDrawingBuffer' in props) {
|
|
133
|
-
this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer;
|
|
134
|
+
this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer || false;
|
|
134
135
|
}
|
|
135
136
|
if ('useDevicePixels' in props) {
|
|
136
|
-
this.props.useDevicePixels = props.useDevicePixels;
|
|
137
|
+
this.props.useDevicePixels = props.useDevicePixels || false;
|
|
137
138
|
}
|
|
138
139
|
return this;
|
|
139
140
|
}
|
|
@@ -155,11 +156,11 @@ export default class AnimationLoop {
|
|
|
155
156
|
if (!this._initialized) {
|
|
156
157
|
this._initialized = true;
|
|
157
158
|
// Create the WebGL context
|
|
158
|
-
await this.
|
|
159
|
+
await this._initDevice();
|
|
159
160
|
this._initialize();
|
|
160
161
|
|
|
161
162
|
// Note: onIntialize can return a promise (e.g. in case app needs to load resources)
|
|
162
|
-
await this.onInitialize(this.
|
|
163
|
+
await this.props.onInitialize(this._getAnimationProps());
|
|
163
164
|
}
|
|
164
165
|
|
|
165
166
|
// check that we haven't been stopped
|
|
@@ -185,16 +186,16 @@ export default class AnimationLoop {
|
|
|
185
186
|
|
|
186
187
|
/** Explicitly draw a frame */
|
|
187
188
|
redraw(): this {
|
|
188
|
-
if (this.device
|
|
189
|
+
if (this.device?.isLost) {
|
|
189
190
|
return this;
|
|
190
191
|
}
|
|
191
192
|
|
|
192
193
|
this._beginTimers();
|
|
193
194
|
|
|
194
195
|
this._setupFrame();
|
|
195
|
-
this.
|
|
196
|
+
this._updateAnimationProps();
|
|
196
197
|
|
|
197
|
-
this._renderFrame(this.
|
|
198
|
+
this._renderFrame(this._getAnimationProps());
|
|
198
199
|
|
|
199
200
|
// clear needsRedraw flag
|
|
200
201
|
this._clearNeedsRedraw();
|
|
@@ -215,7 +216,10 @@ export default class AnimationLoop {
|
|
|
215
216
|
// console.debug(`Stopping ${this.constructor.name}`);
|
|
216
217
|
if (this._running) {
|
|
217
218
|
// call callback
|
|
218
|
-
|
|
219
|
+
// If stop is called immediately, we can end up in a state where props haven't been initialized...
|
|
220
|
+
if (this.animationProps) {
|
|
221
|
+
this.props.onFinalize(this.animationProps);
|
|
222
|
+
}
|
|
219
223
|
|
|
220
224
|
this._cancelAnimationFrame();
|
|
221
225
|
this._nextFramePromise = null;
|
|
@@ -245,26 +249,13 @@ export default class AnimationLoop {
|
|
|
245
249
|
return this._nextFramePromise;
|
|
246
250
|
}
|
|
247
251
|
|
|
248
|
-
async toDataURL() {
|
|
252
|
+
async toDataURL(): Promise<string> {
|
|
249
253
|
this.setNeedsRedraw('toDataURL');
|
|
250
254
|
await this.waitForRender();
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
return this.props.onCreateDevice(deviceProps);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
onInitialize(animationProps: AnimationProps): {} | void {
|
|
259
|
-
return this.props.onInitialize(animationProps);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
onRender(animationProps: AnimationProps) {
|
|
263
|
-
return this.props.onRender(animationProps);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
onFinalize(animationProps: AnimationProps) {
|
|
267
|
-
return this.props.onFinalize(animationProps);
|
|
255
|
+
if (this.canvas instanceof HTMLCanvasElement) {
|
|
256
|
+
return this.canvas.toDataURL();
|
|
257
|
+
}
|
|
258
|
+
throw new Error('OffscreenCanvas');
|
|
268
259
|
}
|
|
269
260
|
|
|
270
261
|
// PRIVATE METHODS
|
|
@@ -273,8 +264,8 @@ export default class AnimationLoop {
|
|
|
273
264
|
this._startEventHandling();
|
|
274
265
|
|
|
275
266
|
// Initialize the callback data
|
|
276
|
-
this.
|
|
277
|
-
this.
|
|
267
|
+
this._initializeAnimationProps();
|
|
268
|
+
this._updateAnimationProps();
|
|
278
269
|
|
|
279
270
|
// Default viewport setup, in case onInitialize wants to render
|
|
280
271
|
this._resizeCanvasDrawingBuffer();
|
|
@@ -283,9 +274,9 @@ export default class AnimationLoop {
|
|
|
283
274
|
// this._gpuTimeQuery = Query.isSupported(this.gl, ['timers']) ? new Query(this.gl) : null;
|
|
284
275
|
}
|
|
285
276
|
|
|
286
|
-
_setDisplay(display) {
|
|
277
|
+
_setDisplay(display: any) {
|
|
287
278
|
if (this.display) {
|
|
288
|
-
this.display.
|
|
279
|
+
this.display.destroy();
|
|
289
280
|
this.display.animationLoop = null;
|
|
290
281
|
}
|
|
291
282
|
|
|
@@ -322,7 +313,7 @@ export default class AnimationLoop {
|
|
|
322
313
|
// if (this.display && this.display.cancelAnimationFrame) {
|
|
323
314
|
// this.display.cancelAnimationFrame(this._animationFrameId);
|
|
324
315
|
// }
|
|
325
|
-
|
|
316
|
+
cancelAnimationFrame(this._animationFrameId);
|
|
326
317
|
this._animationFrameId = null;
|
|
327
318
|
}
|
|
328
319
|
|
|
@@ -336,20 +327,20 @@ export default class AnimationLoop {
|
|
|
336
327
|
|
|
337
328
|
// Called on each frame, can be overridden to call onRender multiple times
|
|
338
329
|
// to support e.g. stereoscopic rendering
|
|
339
|
-
_renderFrame(
|
|
330
|
+
_renderFrame(animationProps: AnimationProps) {
|
|
340
331
|
// Allow e.g. VR display to render multiple frames.
|
|
341
332
|
if (this.display) {
|
|
342
|
-
this.display._renderFrame(
|
|
333
|
+
this.display._renderFrame(animationProps);
|
|
343
334
|
return;
|
|
344
335
|
}
|
|
345
336
|
|
|
346
337
|
// call callback
|
|
347
|
-
this.onRender(
|
|
338
|
+
this.props.onRender(this._getAnimationProps());
|
|
348
339
|
// end callback
|
|
349
340
|
}
|
|
350
341
|
|
|
351
342
|
_clearNeedsRedraw() {
|
|
352
|
-
this.needsRedraw =
|
|
343
|
+
this.needsRedraw = false;
|
|
353
344
|
}
|
|
354
345
|
|
|
355
346
|
_setupFrame() {
|
|
@@ -358,16 +349,21 @@ export default class AnimationLoop {
|
|
|
358
349
|
}
|
|
359
350
|
|
|
360
351
|
// Initialize the object that will be passed to app callbacks
|
|
361
|
-
|
|
352
|
+
_initializeAnimationProps() {
|
|
353
|
+
if (!this.device) {
|
|
354
|
+
throw new Error('loop');
|
|
355
|
+
}
|
|
362
356
|
this.animationProps = {
|
|
363
357
|
animationLoop: this,
|
|
358
|
+
|
|
364
359
|
device: this.device,
|
|
365
|
-
canvas: this.device
|
|
360
|
+
canvas: this.device?.canvasContext?.canvas,
|
|
361
|
+
renderPass: this.device.getDefaultRenderPass(),
|
|
366
362
|
timeline: this.timeline,
|
|
367
363
|
|
|
368
364
|
// Initial values
|
|
369
365
|
useDevicePixels: this.props.useDevicePixels,
|
|
370
|
-
needsRedraw:
|
|
366
|
+
needsRedraw: false,
|
|
371
367
|
|
|
372
368
|
// Placeholders
|
|
373
369
|
width: 1,
|
|
@@ -386,8 +382,21 @@ export default class AnimationLoop {
|
|
|
386
382
|
};
|
|
387
383
|
}
|
|
388
384
|
|
|
385
|
+
_getAnimationProps(): AnimationProps {
|
|
386
|
+
if (!this.animationProps) {
|
|
387
|
+
throw new Error('animationProps');
|
|
388
|
+
}
|
|
389
|
+
return this.animationProps;
|
|
390
|
+
}
|
|
391
|
+
|
|
389
392
|
// Update the context object that will be passed to app callbacks
|
|
390
|
-
|
|
393
|
+
_updateAnimationProps(): void {
|
|
394
|
+
if (!this.animationProps) {
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
this.animationProps.renderPass = this.device.getDefaultRenderPass();
|
|
399
|
+
|
|
391
400
|
const {width, height, aspect} = this._getSizeAndAspect();
|
|
392
401
|
if (width !== this.animationProps.width || height !== this.animationProps.height) {
|
|
393
402
|
this.setNeedsRedraw('drawing buffer resized');
|
|
@@ -418,13 +427,14 @@ export default class AnimationLoop {
|
|
|
418
427
|
: this.animationProps.engineTime;
|
|
419
428
|
}
|
|
420
429
|
|
|
421
|
-
/**
|
|
422
|
-
async
|
|
423
|
-
|
|
424
|
-
this.device
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
this.
|
|
430
|
+
/** Wait for supplied device */
|
|
431
|
+
async _initDevice() {
|
|
432
|
+
this.device = await this.props.device;
|
|
433
|
+
if (!this.device) {
|
|
434
|
+
throw new Error('No device provided');
|
|
435
|
+
}
|
|
436
|
+
this.canvas = this.device.canvasContext?.canvas || null;
|
|
437
|
+
// this._createInfoDiv();
|
|
428
438
|
}
|
|
429
439
|
|
|
430
440
|
_createInfoDiv() {
|
|
@@ -438,7 +448,9 @@ export default class AnimationLoop {
|
|
|
438
448
|
div.style.bottom = '10px';
|
|
439
449
|
div.style.width = '300px';
|
|
440
450
|
div.style.background = 'white';
|
|
441
|
-
|
|
451
|
+
if (this.canvas instanceof HTMLCanvasElement) {
|
|
452
|
+
wrapperDiv.appendChild(this.canvas);
|
|
453
|
+
}
|
|
442
454
|
wrapperDiv.appendChild(div);
|
|
443
455
|
const html = this.props.onAddHTML(div);
|
|
444
456
|
if (html) {
|
|
@@ -447,13 +459,16 @@ export default class AnimationLoop {
|
|
|
447
459
|
}
|
|
448
460
|
}
|
|
449
461
|
|
|
450
|
-
_getSizeAndAspect() {
|
|
462
|
+
_getSizeAndAspect(): {width: number; height: number; aspect: number} {
|
|
463
|
+
if (!this.device) {
|
|
464
|
+
return {width: 1, height: 1, aspect: 1};
|
|
465
|
+
}
|
|
451
466
|
// https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
|
|
452
|
-
const [width, height] = this.device
|
|
467
|
+
const [width, height] = this.device?.canvasContext?.getPixelSize() || [1, 1];
|
|
453
468
|
|
|
454
469
|
// https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
|
|
455
470
|
let aspect = 1;
|
|
456
|
-
const canvas = this.device
|
|
471
|
+
const canvas = this.device?.canvasContext?.canvas;
|
|
457
472
|
|
|
458
473
|
// @ts-expect-error
|
|
459
474
|
if (canvas && canvas.clientHeight) {
|
|
@@ -481,7 +496,7 @@ export default class AnimationLoop {
|
|
|
481
496
|
*/
|
|
482
497
|
_resizeCanvasDrawingBuffer() {
|
|
483
498
|
if (this.props.autoResizeDrawingBuffer) {
|
|
484
|
-
this.device
|
|
499
|
+
this.device?.canvasContext?.resize({useDevicePixels: this.props.useDevicePixels});
|
|
485
500
|
}
|
|
486
501
|
}
|
|
487
502
|
|
|
@@ -521,15 +536,18 @@ export default class AnimationLoop {
|
|
|
521
536
|
|
|
522
537
|
_startEventHandling() {
|
|
523
538
|
if (this.canvas) {
|
|
524
|
-
this.canvas.addEventListener('mousemove', this._onMousemove);
|
|
525
|
-
this.canvas.addEventListener('mouseleave', this._onMouseleave);
|
|
539
|
+
this.canvas.addEventListener('mousemove', this._onMousemove.bind(this));
|
|
540
|
+
this.canvas.addEventListener('mouseleave', this._onMouseleave.bind(this));
|
|
526
541
|
}
|
|
527
542
|
}
|
|
528
543
|
|
|
529
|
-
_onMousemove(
|
|
530
|
-
|
|
544
|
+
_onMousemove(event: Event) {
|
|
545
|
+
if (event instanceof MouseEvent) {
|
|
546
|
+
this._getAnimationProps()._mousePosition = [event.offsetX, event.offsetY];
|
|
547
|
+
}
|
|
531
548
|
}
|
|
532
|
-
|
|
533
|
-
|
|
549
|
+
|
|
550
|
+
_onMouseleave(event: Event) {
|
|
551
|
+
this._getAnimationProps()._mousePosition = null;
|
|
534
552
|
}
|
|
535
553
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {Device} from '@luma.gl/
|
|
1
|
+
import {Device, RenderPass} from '@luma.gl/core';
|
|
2
2
|
import {Timeline} from '../animation/timeline'
|
|
3
|
-
import type AnimationLoop from './animation-loop';
|
|
3
|
+
import type {AnimationLoop} from './animation-loop';
|
|
4
4
|
|
|
5
5
|
/** Properties passed to every render frame */
|
|
6
6
|
export type AnimationProps = {
|
|
7
7
|
device: Device;
|
|
8
|
+
renderPass: RenderPass;
|
|
8
9
|
animationLoop: AnimationLoop;
|
|
9
10
|
|
|
10
11
|
/** @todo Should be canvasContext */
|
|
@@ -22,10 +23,10 @@ export type AnimationProps = {
|
|
|
22
23
|
tock: number;
|
|
23
24
|
|
|
24
25
|
// Initial values
|
|
25
|
-
needsRedraw?: string;
|
|
26
|
+
needsRedraw?: string | false;
|
|
26
27
|
|
|
27
|
-
timeline: Timeline;
|
|
28
|
+
timeline: Timeline | null;
|
|
28
29
|
|
|
29
30
|
// Experimental
|
|
30
|
-
_mousePosition?: [number, number]; // [offsetX, offsetY],
|
|
31
|
+
_mousePosition?: [number, number] | null; // [offsetX, offsetY],
|
|
31
32
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// luma.gl, MIT license
|
|
2
|
+
import {luma} from '@luma.gl/core';
|
|
3
|
+
import {AnimationLoopTemplate} from './render-loop'
|
|
4
|
+
import {AnimationLoop, AnimationLoopProps} from './animation-loop'
|
|
5
|
+
import type {AnimationProps} from './animation-props';
|
|
6
|
+
|
|
7
|
+
export type MakeAnimationLoopProps = Omit<AnimationLoopProps, 'onCreateDevice' | 'onInitialize' | 'onRedraw' | 'onFinalize'>;
|
|
8
|
+
|
|
9
|
+
/** Instantiates and runs the render loop */
|
|
10
|
+
export function makeAnimationLoop(AnimationLoopTemplateCtor: typeof AnimationLoopTemplate, props?: MakeAnimationLoopProps): AnimationLoop {
|
|
11
|
+
let renderLoop: AnimationLoopTemplate | null = null;
|
|
12
|
+
|
|
13
|
+
const device = props?.device || luma.createDevice();
|
|
14
|
+
|
|
15
|
+
// Create an animation loop;
|
|
16
|
+
const animationLoop = new AnimationLoop({
|
|
17
|
+
... props,
|
|
18
|
+
|
|
19
|
+
device,
|
|
20
|
+
|
|
21
|
+
async onInitialize(animationProps: AnimationProps): Promise<unknown> {
|
|
22
|
+
// @ts-expect-error abstract to prevent instantiation
|
|
23
|
+
renderLoop = new AnimationLoopTemplateCtor(animationProps);
|
|
24
|
+
// Any async loading can be handled here
|
|
25
|
+
return await renderLoop?.onInitialize(animationProps);
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
onRender: (animationProps: AnimationProps) => renderLoop?.onRender(animationProps),
|
|
29
|
+
|
|
30
|
+
onFinalize: (animationProps: AnimationProps) => renderLoop?.onFinalize(animationProps)
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// @ts-expect-error Hack: adds info for the website to find
|
|
34
|
+
animationLoop.getInfo = () => {
|
|
35
|
+
// @ts-ignore
|
|
36
|
+
// eslint-disable-next-line no-invalid-this
|
|
37
|
+
return this.AnimationLoopTemplateCtor.info;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Start the loop automatically
|
|
41
|
+
// animationLoop.start();
|
|
42
|
+
|
|
43
|
+
return animationLoop;
|
|
44
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type {AnimationProps} from './animation-props';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Minimal class that represents a "componentized" rendering life cycle
|
|
5
|
+
* (resource construction, repeated rendering, resource destruction)
|
|
6
|
+
*
|
|
7
|
+
* @note A motivation for this class compared to the raw animation loop is
|
|
8
|
+
* that it simplifies TypeScript code by allowing resources to be typed unconditionally
|
|
9
|
+
* since they are allocated in the constructor rather than in onInitialized
|
|
10
|
+
*
|
|
11
|
+
* @note Introduced in luma.gl v9
|
|
12
|
+
*
|
|
13
|
+
* @example AnimationLoopTemplate is intended to be subclassed,
|
|
14
|
+
* but the subclass should not be instantiated directly. Instead the subclass
|
|
15
|
+
* (i.e. the constructor of the subclass) should be used
|
|
16
|
+
* as an argument to create an AnimationLoop.
|
|
17
|
+
*/
|
|
18
|
+
export abstract class AnimationLoopTemplate {
|
|
19
|
+
constructor(animationProps?: AnimationProps) {}
|
|
20
|
+
async onInitialize(animationProps: AnimationProps): Promise<unknown> { return null; }
|
|
21
|
+
abstract onRender(animationProps: AnimationProps): unknown;
|
|
22
|
+
abstract onFinalize(animationProps: AnimationProps): void;
|
|
23
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {uid} from '@luma.gl/
|
|
2
|
-
import Geometry from '../geometry/geometry';
|
|
1
|
+
import {uid} from '@luma.gl/core';
|
|
2
|
+
import {Geometry} from '../geometry/geometry';
|
|
3
3
|
// import type {GeometryType} from '../geometry/geometry-type';
|
|
4
4
|
|
|
5
5
|
export type CubeGeometryProps = {
|
|
6
6
|
id?: string;
|
|
7
7
|
indices?: boolean;
|
|
8
|
-
attributes
|
|
8
|
+
attributes?: any;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export class CubeGeometry extends Geometry {
|
|
@@ -14,11 +14,14 @@ export class CubeGeometry extends Geometry {
|
|
|
14
14
|
super(indices ? {
|
|
15
15
|
...props,
|
|
16
16
|
id,
|
|
17
|
+
topology: 'triangle-list',
|
|
17
18
|
indices: {size: 1, value: CUBE_INDICES},
|
|
18
19
|
attributes: {...ATTRIBUTES, ...props.attributes}
|
|
19
20
|
} : {
|
|
20
21
|
...props,
|
|
21
22
|
id,
|
|
23
|
+
topology: 'triangle-list',
|
|
24
|
+
indices: undefined,
|
|
22
25
|
attributes: {...NON_INDEXED_ATTRIBUTES, ...props.attributes}
|
|
23
26
|
});
|
|
24
27
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {uid} from '@luma.gl/
|
|
1
|
+
import {uid} from '@luma.gl/core';
|
|
2
2
|
import {TruncatedConeGeometry} from './truncated-cone-geometry';
|
|
3
3
|
|
|
4
4
|
export type CylinderGeometryProps = {
|
|
5
5
|
id?: string;
|
|
6
6
|
radius?: number;
|
|
7
|
-
attributes
|
|
7
|
+
attributes?: any;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
export class CylinderGeometry extends TruncatedConeGeometry {
|