@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/dist/index.cjs
ADDED
|
@@ -0,0 +1,2574 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
+
var __spreadValues = (a, b) => {
|
|
12
|
+
for (var prop in b || (b = {}))
|
|
13
|
+
if (__hasOwnProp.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
if (__getOwnPropSymbols)
|
|
16
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
+
if (__propIsEnum.call(b, prop))
|
|
18
|
+
__defNormalProp(a, prop, b[prop]);
|
|
19
|
+
}
|
|
20
|
+
return a;
|
|
21
|
+
};
|
|
22
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
23
|
+
var __export = (target, all) => {
|
|
24
|
+
for (var name in all)
|
|
25
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
26
|
+
};
|
|
27
|
+
var __copyProps = (to, from, except, desc) => {
|
|
28
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
29
|
+
for (let key of __getOwnPropNames(from))
|
|
30
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
31
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
32
|
+
}
|
|
33
|
+
return to;
|
|
34
|
+
};
|
|
35
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
36
|
+
var __async = (__this, __arguments, generator) => {
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
var fulfilled = (value) => {
|
|
39
|
+
try {
|
|
40
|
+
step(generator.next(value));
|
|
41
|
+
} catch (e) {
|
|
42
|
+
reject(e);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
var rejected = (value) => {
|
|
46
|
+
try {
|
|
47
|
+
step(generator.throw(value));
|
|
48
|
+
} catch (e) {
|
|
49
|
+
reject(e);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
53
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// src/index.ts
|
|
58
|
+
var src_exports = {};
|
|
59
|
+
__export(src_exports, {
|
|
60
|
+
AnimationLoop: () => AnimationLoop,
|
|
61
|
+
AnimationLoopTemplate: () => AnimationLoopTemplate,
|
|
62
|
+
ClipSpace: () => ClipSpace,
|
|
63
|
+
ConeGeometry: () => ConeGeometry,
|
|
64
|
+
CubeGeometry: () => CubeGeometry,
|
|
65
|
+
CylinderGeometry: () => CylinderGeometry,
|
|
66
|
+
Geometry: () => Geometry,
|
|
67
|
+
GroupNode: () => GroupNode,
|
|
68
|
+
IcoSphereGeometry: () => IcoSphereGeometry,
|
|
69
|
+
KeyFrames: () => KeyFrames,
|
|
70
|
+
Model: () => Model,
|
|
71
|
+
ModelNode: () => ModelNode,
|
|
72
|
+
PipelineFactory: () => PipelineFactory,
|
|
73
|
+
PlaneGeometry: () => PlaneGeometry,
|
|
74
|
+
ScenegraphNode: () => ScenegraphNode,
|
|
75
|
+
SphereGeometry: () => SphereGeometry,
|
|
76
|
+
Timeline: () => Timeline,
|
|
77
|
+
Transform: () => Transform,
|
|
78
|
+
TruncatedConeGeometry: () => TruncatedConeGeometry,
|
|
79
|
+
makeAnimationLoop: () => makeAnimationLoop
|
|
80
|
+
});
|
|
81
|
+
module.exports = __toCommonJS(src_exports);
|
|
82
|
+
|
|
83
|
+
// src/animation/timeline.ts
|
|
84
|
+
var channelHandles = 1;
|
|
85
|
+
var animationHandles = 1;
|
|
86
|
+
var Timeline = class {
|
|
87
|
+
constructor() {
|
|
88
|
+
this.time = 0;
|
|
89
|
+
this.channels = /* @__PURE__ */ new Map();
|
|
90
|
+
this.animations = /* @__PURE__ */ new Map();
|
|
91
|
+
this.playing = false;
|
|
92
|
+
this.lastEngineTime = -1;
|
|
93
|
+
}
|
|
94
|
+
addChannel(props) {
|
|
95
|
+
const { delay = 0, duration = Number.POSITIVE_INFINITY, rate = 1, repeat = 1 } = props;
|
|
96
|
+
const handle = channelHandles++;
|
|
97
|
+
const channel = {
|
|
98
|
+
time: 0,
|
|
99
|
+
delay,
|
|
100
|
+
duration,
|
|
101
|
+
rate,
|
|
102
|
+
repeat
|
|
103
|
+
};
|
|
104
|
+
this._setChannelTime(channel, this.time);
|
|
105
|
+
this.channels.set(handle, channel);
|
|
106
|
+
return handle;
|
|
107
|
+
}
|
|
108
|
+
removeChannel(handle) {
|
|
109
|
+
this.channels.delete(handle);
|
|
110
|
+
for (const [animationHandle, animation] of this.animations) {
|
|
111
|
+
if (animation.channel === handle) {
|
|
112
|
+
this.detachAnimation(animationHandle);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
isFinished(handle) {
|
|
117
|
+
const channel = this.channels.get(handle);
|
|
118
|
+
if (channel === void 0) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
return this.time >= channel.delay + channel.duration * channel.repeat;
|
|
122
|
+
}
|
|
123
|
+
getTime(handle) {
|
|
124
|
+
if (handle === void 0) {
|
|
125
|
+
return this.time;
|
|
126
|
+
}
|
|
127
|
+
const channel = this.channels.get(handle);
|
|
128
|
+
if (channel === void 0) {
|
|
129
|
+
return -1;
|
|
130
|
+
}
|
|
131
|
+
return channel.time;
|
|
132
|
+
}
|
|
133
|
+
setTime(time) {
|
|
134
|
+
this.time = Math.max(0, time);
|
|
135
|
+
const channels = this.channels.values();
|
|
136
|
+
for (const channel of channels) {
|
|
137
|
+
this._setChannelTime(channel, this.time);
|
|
138
|
+
}
|
|
139
|
+
const animations = this.animations.values();
|
|
140
|
+
for (const animationData of animations) {
|
|
141
|
+
const { animation, channel } = animationData;
|
|
142
|
+
animation.setTime(this.getTime(channel));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
play() {
|
|
146
|
+
this.playing = true;
|
|
147
|
+
}
|
|
148
|
+
pause() {
|
|
149
|
+
this.playing = false;
|
|
150
|
+
this.lastEngineTime = -1;
|
|
151
|
+
}
|
|
152
|
+
reset() {
|
|
153
|
+
this.setTime(0);
|
|
154
|
+
}
|
|
155
|
+
attachAnimation(animation, channelHandle) {
|
|
156
|
+
const animationHandle = animationHandles++;
|
|
157
|
+
this.animations.set(animationHandle, {
|
|
158
|
+
animation,
|
|
159
|
+
channel: channelHandle
|
|
160
|
+
});
|
|
161
|
+
animation.setTime(this.getTime(channelHandle));
|
|
162
|
+
return animationHandle;
|
|
163
|
+
}
|
|
164
|
+
detachAnimation(handle) {
|
|
165
|
+
this.animations.delete(handle);
|
|
166
|
+
}
|
|
167
|
+
update(engineTime) {
|
|
168
|
+
if (this.playing) {
|
|
169
|
+
if (this.lastEngineTime === -1) {
|
|
170
|
+
this.lastEngineTime = engineTime;
|
|
171
|
+
}
|
|
172
|
+
this.setTime(this.time + (engineTime - this.lastEngineTime));
|
|
173
|
+
this.lastEngineTime = engineTime;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
_setChannelTime(channel, time) {
|
|
177
|
+
const offsetTime = time - channel.delay;
|
|
178
|
+
const totalDuration = channel.duration * channel.repeat;
|
|
179
|
+
if (offsetTime >= totalDuration) {
|
|
180
|
+
channel.time = channel.duration * channel.rate;
|
|
181
|
+
} else {
|
|
182
|
+
channel.time = Math.max(0, offsetTime) % channel.duration;
|
|
183
|
+
channel.time *= channel.rate;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// src/animation/key-frames.ts
|
|
189
|
+
var KeyFrames = class {
|
|
190
|
+
constructor(keyFrames) {
|
|
191
|
+
this.startIndex = -1;
|
|
192
|
+
this.endIndex = -1;
|
|
193
|
+
this.factor = 0;
|
|
194
|
+
this.times = [];
|
|
195
|
+
this.values = [];
|
|
196
|
+
this._lastTime = -1;
|
|
197
|
+
this.setKeyFrames(keyFrames);
|
|
198
|
+
this.setTime(0);
|
|
199
|
+
}
|
|
200
|
+
setKeyFrames(keyFrames) {
|
|
201
|
+
const numKeys = keyFrames.length;
|
|
202
|
+
this.times.length = numKeys;
|
|
203
|
+
this.values.length = numKeys;
|
|
204
|
+
for (let i = 0; i < numKeys; ++i) {
|
|
205
|
+
this.times[i] = keyFrames[i][0];
|
|
206
|
+
this.values[i] = keyFrames[i][1];
|
|
207
|
+
}
|
|
208
|
+
this._calculateKeys(this._lastTime);
|
|
209
|
+
}
|
|
210
|
+
setTime(time) {
|
|
211
|
+
time = Math.max(0, time);
|
|
212
|
+
if (time !== this._lastTime) {
|
|
213
|
+
this._calculateKeys(time);
|
|
214
|
+
this._lastTime = time;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
getStartTime() {
|
|
218
|
+
return this.times[this.startIndex];
|
|
219
|
+
}
|
|
220
|
+
getEndTime() {
|
|
221
|
+
return this.times[this.endIndex];
|
|
222
|
+
}
|
|
223
|
+
getStartData() {
|
|
224
|
+
return this.values[this.startIndex];
|
|
225
|
+
}
|
|
226
|
+
getEndData() {
|
|
227
|
+
return this.values[this.endIndex];
|
|
228
|
+
}
|
|
229
|
+
_calculateKeys(time) {
|
|
230
|
+
let index = 0;
|
|
231
|
+
const numKeys = this.times.length;
|
|
232
|
+
for (index = 0; index < numKeys - 2; ++index) {
|
|
233
|
+
if (this.times[index + 1] > time) {
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
this.startIndex = index;
|
|
238
|
+
this.endIndex = index + 1;
|
|
239
|
+
const startTime = this.times[this.startIndex];
|
|
240
|
+
const endTime = this.times[this.endIndex];
|
|
241
|
+
this.factor = Math.min(Math.max(0, (time - startTime) / (endTime - startTime)), 1);
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
// src/animation-loop/render-loop.ts
|
|
246
|
+
var AnimationLoopTemplate = class {
|
|
247
|
+
constructor(animationProps) {
|
|
248
|
+
}
|
|
249
|
+
onInitialize(animationProps) {
|
|
250
|
+
return __async(this, null, function* () {
|
|
251
|
+
return null;
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
// src/animation-loop/animation-loop.ts
|
|
257
|
+
var import_core = require("@luma.gl/core");
|
|
258
|
+
var import_core2 = require("@luma.gl/core");
|
|
259
|
+
var import_stats = require("@probe.gl/stats");
|
|
260
|
+
var statIdCounter = 0;
|
|
261
|
+
var DEFAULT_ANIMATION_LOOP_PROPS = {
|
|
262
|
+
device: null,
|
|
263
|
+
onAddHTML: () => "",
|
|
264
|
+
onInitialize: () => __async(void 0, null, function* () {
|
|
265
|
+
return null;
|
|
266
|
+
}),
|
|
267
|
+
onRender: () => {
|
|
268
|
+
},
|
|
269
|
+
onFinalize: () => {
|
|
270
|
+
},
|
|
271
|
+
onError: (error) => console.error(error),
|
|
272
|
+
// eslint-disable-line no-console
|
|
273
|
+
stats: import_core.luma.stats.get(`animation-loop-${statIdCounter++}`),
|
|
274
|
+
// view parameters
|
|
275
|
+
useDevicePixels: true,
|
|
276
|
+
autoResizeViewport: false,
|
|
277
|
+
autoResizeDrawingBuffer: false
|
|
278
|
+
};
|
|
279
|
+
var AnimationLoop = class {
|
|
280
|
+
// _gpuTimeQuery: Query | null = null;
|
|
281
|
+
/*
|
|
282
|
+
* @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
|
|
283
|
+
*/
|
|
284
|
+
constructor(props) {
|
|
285
|
+
this.device = null;
|
|
286
|
+
this.canvas = null;
|
|
287
|
+
this.animationProps = null;
|
|
288
|
+
this.timeline = null;
|
|
289
|
+
this.needsRedraw = "initialized";
|
|
290
|
+
this._initialized = false;
|
|
291
|
+
this._running = false;
|
|
292
|
+
this._animationFrameId = null;
|
|
293
|
+
this._nextFramePromise = null;
|
|
294
|
+
this._resolveNextFrame = null;
|
|
295
|
+
this._cpuStartTime = 0;
|
|
296
|
+
this.props = __spreadValues(__spreadValues({}, DEFAULT_ANIMATION_LOOP_PROPS), props);
|
|
297
|
+
props = this.props;
|
|
298
|
+
if (!props.device) {
|
|
299
|
+
throw new Error("No device provided");
|
|
300
|
+
}
|
|
301
|
+
const { useDevicePixels = true } = this.props;
|
|
302
|
+
this.stats = props.stats || new import_stats.Stats({ id: "animation-loop-stats" });
|
|
303
|
+
this.cpuTime = this.stats.get("CPU Time");
|
|
304
|
+
this.gpuTime = this.stats.get("GPU Time");
|
|
305
|
+
this.frameRate = this.stats.get("Frame Rate");
|
|
306
|
+
this.setProps({
|
|
307
|
+
autoResizeViewport: props.autoResizeViewport,
|
|
308
|
+
autoResizeDrawingBuffer: props.autoResizeDrawingBuffer,
|
|
309
|
+
useDevicePixels
|
|
310
|
+
});
|
|
311
|
+
this.start = this.start.bind(this);
|
|
312
|
+
this.stop = this.stop.bind(this);
|
|
313
|
+
this._onMousemove = this._onMousemove.bind(this);
|
|
314
|
+
this._onMouseleave = this._onMouseleave.bind(this);
|
|
315
|
+
}
|
|
316
|
+
destroy() {
|
|
317
|
+
this.stop();
|
|
318
|
+
this._setDisplay(null);
|
|
319
|
+
}
|
|
320
|
+
/** @deprecated Use .destroy() */
|
|
321
|
+
delete() {
|
|
322
|
+
this.destroy();
|
|
323
|
+
}
|
|
324
|
+
setNeedsRedraw(reason) {
|
|
325
|
+
this.needsRedraw = this.needsRedraw || reason;
|
|
326
|
+
return this;
|
|
327
|
+
}
|
|
328
|
+
// TODO - move to CanvasContext
|
|
329
|
+
setProps(props) {
|
|
330
|
+
if ("autoResizeViewport" in props) {
|
|
331
|
+
this.props.autoResizeViewport = props.autoResizeViewport || false;
|
|
332
|
+
}
|
|
333
|
+
if ("autoResizeDrawingBuffer" in props) {
|
|
334
|
+
this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer || false;
|
|
335
|
+
}
|
|
336
|
+
if ("useDevicePixels" in props) {
|
|
337
|
+
this.props.useDevicePixels = props.useDevicePixels || false;
|
|
338
|
+
}
|
|
339
|
+
return this;
|
|
340
|
+
}
|
|
341
|
+
/** Starts a render loop if not already running */
|
|
342
|
+
start() {
|
|
343
|
+
return __async(this, null, function* () {
|
|
344
|
+
if (this._running) {
|
|
345
|
+
return this;
|
|
346
|
+
}
|
|
347
|
+
this._running = true;
|
|
348
|
+
try {
|
|
349
|
+
if (!this._running) {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
let appContext;
|
|
353
|
+
if (!this._initialized) {
|
|
354
|
+
this._initialized = true;
|
|
355
|
+
yield this._initDevice();
|
|
356
|
+
this._initialize();
|
|
357
|
+
yield this.props.onInitialize(this._getAnimationProps());
|
|
358
|
+
}
|
|
359
|
+
if (!this._running) {
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
if (appContext !== false) {
|
|
363
|
+
this._cancelAnimationFrame();
|
|
364
|
+
this._requestAnimationFrame();
|
|
365
|
+
}
|
|
366
|
+
return this;
|
|
367
|
+
} catch (err) {
|
|
368
|
+
const error = err instanceof Error ? err : new Error("Unknown error");
|
|
369
|
+
this.props.onError(error);
|
|
370
|
+
throw error;
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
/** Explicitly draw a frame */
|
|
375
|
+
redraw() {
|
|
376
|
+
var _a;
|
|
377
|
+
if ((_a = this.device) == null ? void 0 : _a.isLost) {
|
|
378
|
+
return this;
|
|
379
|
+
}
|
|
380
|
+
this._beginTimers();
|
|
381
|
+
this._setupFrame();
|
|
382
|
+
this._updateAnimationProps();
|
|
383
|
+
this._renderFrame(this._getAnimationProps());
|
|
384
|
+
this._clearNeedsRedraw();
|
|
385
|
+
if (this._resolveNextFrame) {
|
|
386
|
+
this._resolveNextFrame(this);
|
|
387
|
+
this._nextFramePromise = null;
|
|
388
|
+
this._resolveNextFrame = null;
|
|
389
|
+
}
|
|
390
|
+
this._endTimers();
|
|
391
|
+
return this;
|
|
392
|
+
}
|
|
393
|
+
// Stops a render loop if already running, finalizing
|
|
394
|
+
stop() {
|
|
395
|
+
if (this._running) {
|
|
396
|
+
if (this.animationProps) {
|
|
397
|
+
this.props.onFinalize(this.animationProps);
|
|
398
|
+
}
|
|
399
|
+
this._cancelAnimationFrame();
|
|
400
|
+
this._nextFramePromise = null;
|
|
401
|
+
this._resolveNextFrame = null;
|
|
402
|
+
this._running = false;
|
|
403
|
+
}
|
|
404
|
+
return this;
|
|
405
|
+
}
|
|
406
|
+
attachTimeline(timeline) {
|
|
407
|
+
this.timeline = timeline;
|
|
408
|
+
return this.timeline;
|
|
409
|
+
}
|
|
410
|
+
detachTimeline() {
|
|
411
|
+
this.timeline = null;
|
|
412
|
+
}
|
|
413
|
+
waitForRender() {
|
|
414
|
+
this.setNeedsRedraw("waitForRender");
|
|
415
|
+
if (!this._nextFramePromise) {
|
|
416
|
+
this._nextFramePromise = new Promise((resolve) => {
|
|
417
|
+
this._resolveNextFrame = resolve;
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
return this._nextFramePromise;
|
|
421
|
+
}
|
|
422
|
+
toDataURL() {
|
|
423
|
+
return __async(this, null, function* () {
|
|
424
|
+
this.setNeedsRedraw("toDataURL");
|
|
425
|
+
yield this.waitForRender();
|
|
426
|
+
if (this.canvas instanceof HTMLCanvasElement) {
|
|
427
|
+
return this.canvas.toDataURL();
|
|
428
|
+
}
|
|
429
|
+
throw new Error("OffscreenCanvas");
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
// PRIVATE METHODS
|
|
433
|
+
_initialize() {
|
|
434
|
+
this._startEventHandling();
|
|
435
|
+
this._initializeAnimationProps();
|
|
436
|
+
this._updateAnimationProps();
|
|
437
|
+
this._resizeCanvasDrawingBuffer();
|
|
438
|
+
this._resizeViewport();
|
|
439
|
+
}
|
|
440
|
+
_setDisplay(display) {
|
|
441
|
+
if (this.display) {
|
|
442
|
+
this.display.destroy();
|
|
443
|
+
this.display.animationLoop = null;
|
|
444
|
+
}
|
|
445
|
+
if (display) {
|
|
446
|
+
display.animationLoop = this;
|
|
447
|
+
}
|
|
448
|
+
this.display = display;
|
|
449
|
+
}
|
|
450
|
+
_requestAnimationFrame() {
|
|
451
|
+
if (!this._running) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
this._animationFrameId = (0, import_core2.requestAnimationFrame)(this._animationFrame.bind(this));
|
|
455
|
+
}
|
|
456
|
+
_cancelAnimationFrame() {
|
|
457
|
+
if (this._animationFrameId !== null) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
(0, import_core2.cancelAnimationFrame)(this._animationFrameId);
|
|
461
|
+
this._animationFrameId = null;
|
|
462
|
+
}
|
|
463
|
+
_animationFrame() {
|
|
464
|
+
if (!this._running) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
this.redraw();
|
|
468
|
+
this._requestAnimationFrame();
|
|
469
|
+
}
|
|
470
|
+
// Called on each frame, can be overridden to call onRender multiple times
|
|
471
|
+
// to support e.g. stereoscopic rendering
|
|
472
|
+
_renderFrame(animationProps) {
|
|
473
|
+
if (this.display) {
|
|
474
|
+
this.display._renderFrame(animationProps);
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
this.props.onRender(this._getAnimationProps());
|
|
478
|
+
}
|
|
479
|
+
_clearNeedsRedraw() {
|
|
480
|
+
this.needsRedraw = false;
|
|
481
|
+
}
|
|
482
|
+
_setupFrame() {
|
|
483
|
+
this._resizeCanvasDrawingBuffer();
|
|
484
|
+
this._resizeViewport();
|
|
485
|
+
}
|
|
486
|
+
// Initialize the object that will be passed to app callbacks
|
|
487
|
+
_initializeAnimationProps() {
|
|
488
|
+
var _a, _b;
|
|
489
|
+
if (!this.device) {
|
|
490
|
+
throw new Error("loop");
|
|
491
|
+
}
|
|
492
|
+
this.animationProps = {
|
|
493
|
+
animationLoop: this,
|
|
494
|
+
device: this.device,
|
|
495
|
+
canvas: (_b = (_a = this.device) == null ? void 0 : _a.canvasContext) == null ? void 0 : _b.canvas,
|
|
496
|
+
renderPass: this.device.getDefaultRenderPass(),
|
|
497
|
+
timeline: this.timeline,
|
|
498
|
+
// Initial values
|
|
499
|
+
useDevicePixels: this.props.useDevicePixels,
|
|
500
|
+
needsRedraw: false,
|
|
501
|
+
// Placeholders
|
|
502
|
+
width: 1,
|
|
503
|
+
height: 1,
|
|
504
|
+
aspect: 1,
|
|
505
|
+
// Animation props
|
|
506
|
+
time: 0,
|
|
507
|
+
startTime: Date.now(),
|
|
508
|
+
engineTime: 0,
|
|
509
|
+
tick: 0,
|
|
510
|
+
tock: 0,
|
|
511
|
+
// Experimental
|
|
512
|
+
_mousePosition: null
|
|
513
|
+
// Event props
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
_getAnimationProps() {
|
|
517
|
+
if (!this.animationProps) {
|
|
518
|
+
throw new Error("animationProps");
|
|
519
|
+
}
|
|
520
|
+
return this.animationProps;
|
|
521
|
+
}
|
|
522
|
+
// Update the context object that will be passed to app callbacks
|
|
523
|
+
_updateAnimationProps() {
|
|
524
|
+
if (!this.animationProps) {
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
this.animationProps.renderPass = this.device.getDefaultRenderPass();
|
|
528
|
+
const { width, height, aspect } = this._getSizeAndAspect();
|
|
529
|
+
if (width !== this.animationProps.width || height !== this.animationProps.height) {
|
|
530
|
+
this.setNeedsRedraw("drawing buffer resized");
|
|
531
|
+
}
|
|
532
|
+
if (aspect !== this.animationProps.aspect) {
|
|
533
|
+
this.setNeedsRedraw("drawing buffer aspect changed");
|
|
534
|
+
}
|
|
535
|
+
this.animationProps.width = width;
|
|
536
|
+
this.animationProps.height = height;
|
|
537
|
+
this.animationProps.aspect = aspect;
|
|
538
|
+
this.animationProps.needsRedraw = this.needsRedraw;
|
|
539
|
+
this.animationProps.engineTime = Date.now() - this.animationProps.startTime;
|
|
540
|
+
if (this.timeline) {
|
|
541
|
+
this.timeline.update(this.animationProps.engineTime);
|
|
542
|
+
}
|
|
543
|
+
this.animationProps.tick = Math.floor(this.animationProps.time / 1e3 * 60);
|
|
544
|
+
this.animationProps.tock++;
|
|
545
|
+
this.animationProps.time = this.timeline ? this.timeline.getTime() : this.animationProps.engineTime;
|
|
546
|
+
}
|
|
547
|
+
/** Wait for supplied device */
|
|
548
|
+
_initDevice() {
|
|
549
|
+
return __async(this, null, function* () {
|
|
550
|
+
var _a;
|
|
551
|
+
this.device = yield this.props.device;
|
|
552
|
+
if (!this.device) {
|
|
553
|
+
throw new Error("No device provided");
|
|
554
|
+
}
|
|
555
|
+
this.canvas = ((_a = this.device.canvasContext) == null ? void 0 : _a.canvas) || null;
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
_createInfoDiv() {
|
|
559
|
+
if (this.canvas && this.props.onAddHTML) {
|
|
560
|
+
const wrapperDiv = document.createElement("div");
|
|
561
|
+
document.body.appendChild(wrapperDiv);
|
|
562
|
+
wrapperDiv.style.position = "relative";
|
|
563
|
+
const div = document.createElement("div");
|
|
564
|
+
div.style.position = "absolute";
|
|
565
|
+
div.style.left = "10px";
|
|
566
|
+
div.style.bottom = "10px";
|
|
567
|
+
div.style.width = "300px";
|
|
568
|
+
div.style.background = "white";
|
|
569
|
+
if (this.canvas instanceof HTMLCanvasElement) {
|
|
570
|
+
wrapperDiv.appendChild(this.canvas);
|
|
571
|
+
}
|
|
572
|
+
wrapperDiv.appendChild(div);
|
|
573
|
+
const html = this.props.onAddHTML(div);
|
|
574
|
+
if (html) {
|
|
575
|
+
div.innerHTML = html;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
_getSizeAndAspect() {
|
|
580
|
+
var _a, _b, _c, _d;
|
|
581
|
+
if (!this.device) {
|
|
582
|
+
return { width: 1, height: 1, aspect: 1 };
|
|
583
|
+
}
|
|
584
|
+
const [width, height] = ((_b = (_a = this.device) == null ? void 0 : _a.canvasContext) == null ? void 0 : _b.getPixelSize()) || [1, 1];
|
|
585
|
+
let aspect = 1;
|
|
586
|
+
const canvas = (_d = (_c = this.device) == null ? void 0 : _c.canvasContext) == null ? void 0 : _d.canvas;
|
|
587
|
+
if (canvas && canvas.clientHeight) {
|
|
588
|
+
aspect = canvas.clientWidth / canvas.clientHeight;
|
|
589
|
+
} else if (width > 0 && height > 0) {
|
|
590
|
+
aspect = width / height;
|
|
591
|
+
}
|
|
592
|
+
return { width, height, aspect };
|
|
593
|
+
}
|
|
594
|
+
/** Default viewport setup */
|
|
595
|
+
_resizeViewport() {
|
|
596
|
+
if (this.props.autoResizeViewport && this.device.gl) {
|
|
597
|
+
this.device.gl.viewport(0, 0, this.device.gl.drawingBufferWidth, this.device.gl.drawingBufferHeight);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Resize the render buffer of the canvas to match canvas client size
|
|
602
|
+
* Optionally multiplying with devicePixel ratio
|
|
603
|
+
*/
|
|
604
|
+
_resizeCanvasDrawingBuffer() {
|
|
605
|
+
var _a, _b;
|
|
606
|
+
if (this.props.autoResizeDrawingBuffer) {
|
|
607
|
+
(_b = (_a = this.device) == null ? void 0 : _a.canvasContext) == null ? void 0 : _b.resize({ useDevicePixels: this.props.useDevicePixels });
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
_beginTimers() {
|
|
611
|
+
this.frameRate.timeEnd();
|
|
612
|
+
this.frameRate.timeStart();
|
|
613
|
+
}
|
|
614
|
+
_endTimers() {
|
|
615
|
+
this.cpuTime.timeEnd();
|
|
616
|
+
}
|
|
617
|
+
// Event handling
|
|
618
|
+
_startEventHandling() {
|
|
619
|
+
if (this.canvas) {
|
|
620
|
+
this.canvas.addEventListener("mousemove", this._onMousemove.bind(this));
|
|
621
|
+
this.canvas.addEventListener("mouseleave", this._onMouseleave.bind(this));
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
_onMousemove(event) {
|
|
625
|
+
if (event instanceof MouseEvent) {
|
|
626
|
+
this._getAnimationProps()._mousePosition = [event.offsetX, event.offsetY];
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
_onMouseleave(event) {
|
|
630
|
+
this._getAnimationProps()._mousePosition = null;
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
// src/animation-loop/make-animation-loop.ts
|
|
635
|
+
var import_core3 = require("@luma.gl/core");
|
|
636
|
+
function makeAnimationLoop(AnimationLoopTemplateCtor, props) {
|
|
637
|
+
let renderLoop = null;
|
|
638
|
+
const device = (props == null ? void 0 : props.device) || import_core3.luma.createDevice();
|
|
639
|
+
const animationLoop = new AnimationLoop(__spreadProps(__spreadValues({}, props), {
|
|
640
|
+
device,
|
|
641
|
+
onInitialize(animationProps) {
|
|
642
|
+
return __async(this, null, function* () {
|
|
643
|
+
renderLoop = new AnimationLoopTemplateCtor(animationProps);
|
|
644
|
+
return yield renderLoop == null ? void 0 : renderLoop.onInitialize(animationProps);
|
|
645
|
+
});
|
|
646
|
+
},
|
|
647
|
+
onRender: (animationProps) => renderLoop == null ? void 0 : renderLoop.onRender(animationProps),
|
|
648
|
+
onFinalize: (animationProps) => renderLoop == null ? void 0 : renderLoop.onFinalize(animationProps)
|
|
649
|
+
}));
|
|
650
|
+
animationLoop.getInfo = () => {
|
|
651
|
+
return this.AnimationLoopTemplateCtor.info;
|
|
652
|
+
};
|
|
653
|
+
return animationLoop;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// src/model/model.ts
|
|
657
|
+
var import_core5 = require("@luma.gl/core");
|
|
658
|
+
var import_core6 = require("@luma.gl/core");
|
|
659
|
+
|
|
660
|
+
// src/model/model-utils.ts
|
|
661
|
+
var import_core4 = require("@luma.gl/core");
|
|
662
|
+
var GLTF_TO_LUMA_ATTRIBUTE_MAP = {
|
|
663
|
+
POSITION: "positions",
|
|
664
|
+
NORMAL: "normals",
|
|
665
|
+
COLOR_0: "colors",
|
|
666
|
+
TEXCOORD_0: "texCoords",
|
|
667
|
+
TEXCOORD_1: "texCoords1",
|
|
668
|
+
TEXCOORD_2: "texCoords2"
|
|
669
|
+
};
|
|
670
|
+
function getIndexBufferFromGeometry(device, geometry) {
|
|
671
|
+
if (!geometry.indices) {
|
|
672
|
+
return void 0;
|
|
673
|
+
}
|
|
674
|
+
const data = geometry.indices.value || geometry.indices;
|
|
675
|
+
(0, import_core4.assert)(
|
|
676
|
+
data instanceof Uint16Array || data instanceof Uint32Array,
|
|
677
|
+
'attribute array for "indices" must be of integer type'
|
|
678
|
+
);
|
|
679
|
+
return device.createBuffer({ usage: import_core4.Buffer.INDEX, data });
|
|
680
|
+
}
|
|
681
|
+
function getAttributeBuffersFromGeometry(device, geometry) {
|
|
682
|
+
const buffers = {};
|
|
683
|
+
for (const [name, attribute] of Object.entries(geometry.attributes)) {
|
|
684
|
+
const remappedName = mapAttributeName(name);
|
|
685
|
+
if (attribute == null ? void 0 : attribute.constant) {
|
|
686
|
+
throw new Error("constant attributes not supported");
|
|
687
|
+
} else {
|
|
688
|
+
const typedArray = attribute == null ? void 0 : attribute.value;
|
|
689
|
+
buffers[remappedName] = device.createBuffer({ data: typedArray, id: `${remappedName}-buffer` });
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
return buffers;
|
|
693
|
+
}
|
|
694
|
+
function mapAttributeName(name) {
|
|
695
|
+
return GLTF_TO_LUMA_ATTRIBUTE_MAP[name] || name;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// src/lib/pipeline-factory.ts
|
|
699
|
+
var import_shadertools = require("@luma.gl/shadertools");
|
|
700
|
+
var DEFAULT_RENDER_PIPELINE_OPTIONS = {
|
|
701
|
+
vs: "",
|
|
702
|
+
fs: "",
|
|
703
|
+
modules: [],
|
|
704
|
+
defines: {},
|
|
705
|
+
inject: {},
|
|
706
|
+
transpileToGLSL100: false,
|
|
707
|
+
layout: null,
|
|
708
|
+
varyings: [],
|
|
709
|
+
bufferMode: 35981,
|
|
710
|
+
// // varyings/bufferMode for xform feedback, 0x8c8d: SEPARATE_ATTRIBS
|
|
711
|
+
topology: "triangle-list",
|
|
712
|
+
parameters: {}
|
|
713
|
+
};
|
|
714
|
+
var PipelineFactory = class {
|
|
715
|
+
constructor(device) {
|
|
716
|
+
this.stateHash = 0;
|
|
717
|
+
// Used to change hashing if hooks are modified
|
|
718
|
+
this._hashCounter = 0;
|
|
719
|
+
this._hashes = {};
|
|
720
|
+
this._useCounts = {};
|
|
721
|
+
this._pipelineCache = {};
|
|
722
|
+
this._getUniforms = {};
|
|
723
|
+
this._hookFunctions = [];
|
|
724
|
+
this._defaultModules = [];
|
|
725
|
+
this.device = device;
|
|
726
|
+
}
|
|
727
|
+
// private readonly _registeredModules = {}; // TODO: Remove? This isn't used anywhere in luma.gl
|
|
728
|
+
static getDefaultPipelineFactory(device) {
|
|
729
|
+
device.defaultPipelineFactory = device.defaultPipelineFactory || new PipelineFactory(device);
|
|
730
|
+
return device.defaultPipelineFactory;
|
|
731
|
+
}
|
|
732
|
+
addDefaultModule(module2) {
|
|
733
|
+
if (!this._defaultModules.find((m) => m.name === (typeof module2 === "string" ? module2 : module2.name))) {
|
|
734
|
+
this._defaultModules.push(module2);
|
|
735
|
+
}
|
|
736
|
+
this.stateHash++;
|
|
737
|
+
}
|
|
738
|
+
removeDefaultModule(module2) {
|
|
739
|
+
const moduleName = typeof module2 === "string" ? module2 : module2.name;
|
|
740
|
+
this._defaultModules = this._defaultModules.filter((m) => m.name !== moduleName);
|
|
741
|
+
this.stateHash++;
|
|
742
|
+
}
|
|
743
|
+
addShaderHook(hook, opts) {
|
|
744
|
+
if (opts) {
|
|
745
|
+
hook = Object.assign(opts, { hook });
|
|
746
|
+
}
|
|
747
|
+
this._hookFunctions.push(hook);
|
|
748
|
+
this.stateHash++;
|
|
749
|
+
}
|
|
750
|
+
createRenderPipeline(options) {
|
|
751
|
+
const props = __spreadValues(__spreadValues({}, DEFAULT_RENDER_PIPELINE_OPTIONS), options);
|
|
752
|
+
const modules = this._getModuleList(props.modules);
|
|
753
|
+
const hash = this._hashRenderPipeline(__spreadProps(__spreadValues({}, props), { modules }));
|
|
754
|
+
if (!this._pipelineCache[hash]) {
|
|
755
|
+
const { pipeline, getUniforms } = this._createRenderPipeline(__spreadProps(__spreadValues({}, props), { modules }));
|
|
756
|
+
pipeline.hash = hash;
|
|
757
|
+
this._pipelineCache[hash] = pipeline;
|
|
758
|
+
this._getUniforms[hash] = getUniforms || ((x) => ({}));
|
|
759
|
+
this._useCounts[hash] = 0;
|
|
760
|
+
}
|
|
761
|
+
this._useCounts[hash]++;
|
|
762
|
+
return {
|
|
763
|
+
pipeline: this._pipelineCache[hash],
|
|
764
|
+
getUniforms: this._getUniforms[hash]
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
release(pipeline) {
|
|
768
|
+
const hash = pipeline.hash;
|
|
769
|
+
this._useCounts[hash]--;
|
|
770
|
+
if (this._useCounts[hash] === 0) {
|
|
771
|
+
this._pipelineCache[hash].destroy();
|
|
772
|
+
delete this._pipelineCache[hash];
|
|
773
|
+
delete this._getUniforms[hash];
|
|
774
|
+
delete this._useCounts[hash];
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
getUniforms(pipeline) {
|
|
778
|
+
return this._getUniforms[pipeline.hash] || null;
|
|
779
|
+
}
|
|
780
|
+
// PRIVATE
|
|
781
|
+
_createRenderPipeline(props) {
|
|
782
|
+
const platformInfo = {
|
|
783
|
+
gpu: this.device.info.gpu,
|
|
784
|
+
features: this.device.features
|
|
785
|
+
};
|
|
786
|
+
if (!props.fs) {
|
|
787
|
+
throw new Error("fs");
|
|
788
|
+
}
|
|
789
|
+
const assembled = (0, import_shadertools.assembleShaders)(platformInfo, __spreadProps(__spreadValues({}, props), { fs: props.fs, hookFunctions: this._hookFunctions }));
|
|
790
|
+
const pipeline = this.device.createRenderPipeline(__spreadProps(__spreadValues({}, props), {
|
|
791
|
+
vs: this.device.createShader({ stage: "vertex", source: assembled.vs }),
|
|
792
|
+
fs: assembled.fs ? this.device.createShader({ stage: "fragment", source: assembled.fs }) : null
|
|
793
|
+
}));
|
|
794
|
+
return { pipeline, getUniforms: assembled.getUniforms };
|
|
795
|
+
}
|
|
796
|
+
/** Calculate a hash based on all the inputs for a render pipeline */
|
|
797
|
+
_hashRenderPipeline(props) {
|
|
798
|
+
const { modules = [], varyings = [], defines = {}, inject = {}, parameters = {} } = props;
|
|
799
|
+
const vsHash = this._getHash(props.vs);
|
|
800
|
+
const fsHash = props.fs ? this._getHash(props.fs) : 0;
|
|
801
|
+
const moduleHashes = modules.map((m) => this._getHash(typeof m === "string" ? m : m.name)).sort();
|
|
802
|
+
const varyingHashes = varyings.map((v) => this._getHash(v));
|
|
803
|
+
const defineKeys = Object.keys(defines).sort();
|
|
804
|
+
const injectKeys = Object.keys(inject).sort();
|
|
805
|
+
const defineHashes = [];
|
|
806
|
+
const injectHashes = [];
|
|
807
|
+
for (const key of defineKeys) {
|
|
808
|
+
defineHashes.push(this._getHash(key));
|
|
809
|
+
defineHashes.push(this._getHash(String(defines[key])));
|
|
810
|
+
}
|
|
811
|
+
for (const key of injectKeys) {
|
|
812
|
+
injectHashes.push(this._getHash(key));
|
|
813
|
+
injectHashes.push(this._getHash(inject[key]));
|
|
814
|
+
}
|
|
815
|
+
const parameterHash = JSON.stringify(parameters);
|
|
816
|
+
return `${vsHash}/${fsHash}D${defineHashes.join("/")}M${moduleHashes.join(
|
|
817
|
+
"/"
|
|
818
|
+
)}I${injectHashes.join("/")}V${varyingHashes.join("/")}H${this.stateHash}B${props.bufferMode}${props.transpileToGLSL100 ? "T" : ""}P${parameterHash}`;
|
|
819
|
+
}
|
|
820
|
+
_getHash(key) {
|
|
821
|
+
if (this._hashes[key] === void 0) {
|
|
822
|
+
this._hashes[key] = this._hashCounter++;
|
|
823
|
+
}
|
|
824
|
+
return this._hashes[key];
|
|
825
|
+
}
|
|
826
|
+
// Dedupe and combine with default modules
|
|
827
|
+
_getModuleList(appModules = []) {
|
|
828
|
+
const modules = new Array(this._defaultModules.length + appModules.length);
|
|
829
|
+
const seen = {};
|
|
830
|
+
let count = 0;
|
|
831
|
+
for (let i = 0, len = this._defaultModules.length; i < len; ++i) {
|
|
832
|
+
const module2 = this._defaultModules[i];
|
|
833
|
+
const name = module2.name;
|
|
834
|
+
modules[count++] = module2;
|
|
835
|
+
seen[name] = true;
|
|
836
|
+
}
|
|
837
|
+
for (let i = 0, len = appModules.length; i < len; ++i) {
|
|
838
|
+
const module2 = appModules[i];
|
|
839
|
+
const name = module2.name;
|
|
840
|
+
if (!seen[name]) {
|
|
841
|
+
modules[count++] = module2;
|
|
842
|
+
seen[name] = true;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
modules.length = count;
|
|
846
|
+
return modules;
|
|
847
|
+
}
|
|
848
|
+
};
|
|
849
|
+
|
|
850
|
+
// src/model/model.ts
|
|
851
|
+
var DEFAULT_MODEL_PROPS = __spreadProps(__spreadValues({}, import_core6.RenderPipeline._DEFAULT_PROPS), {
|
|
852
|
+
vs: null,
|
|
853
|
+
fs: null,
|
|
854
|
+
id: "unnamed",
|
|
855
|
+
handle: void 0,
|
|
856
|
+
userData: {},
|
|
857
|
+
defines: {},
|
|
858
|
+
modules: [],
|
|
859
|
+
moduleSettings: {},
|
|
860
|
+
geometry: null,
|
|
861
|
+
pipelineFactory: void 0
|
|
862
|
+
});
|
|
863
|
+
var Model = class {
|
|
864
|
+
constructor(device, props) {
|
|
865
|
+
this.fs = null;
|
|
866
|
+
this.userData = {};
|
|
867
|
+
/** instance count */
|
|
868
|
+
this.instanceCount = 0;
|
|
869
|
+
/** Buffer-valued attributes */
|
|
870
|
+
this.bufferAttributes = {};
|
|
871
|
+
/** Constant-valued attributes */
|
|
872
|
+
this.constantAttributes = {};
|
|
873
|
+
/** Bindings (textures, samplers, uniform buffers) */
|
|
874
|
+
this.bindings = {};
|
|
875
|
+
/** Uniforms */
|
|
876
|
+
this.uniforms = {};
|
|
877
|
+
props = __spreadValues(__spreadValues({}, DEFAULT_MODEL_PROPS), props);
|
|
878
|
+
this.id = props.id;
|
|
879
|
+
this.device = device;
|
|
880
|
+
Object.assign(this.userData, props.userData);
|
|
881
|
+
if (!props.vs) {
|
|
882
|
+
throw new Error("no vertex shader");
|
|
883
|
+
}
|
|
884
|
+
this.vs = getShaderSource(this.device, props.vs);
|
|
885
|
+
if (props.fs) {
|
|
886
|
+
this.fs = getShaderSource(this.device, props.fs);
|
|
887
|
+
}
|
|
888
|
+
this.vertexCount = props.vertexCount;
|
|
889
|
+
this.instanceCount = props.instanceCount;
|
|
890
|
+
this.topology = props.topology;
|
|
891
|
+
if (props.geometry) {
|
|
892
|
+
this.vertexCount = props.geometry.vertexCount;
|
|
893
|
+
this.topology = props.geometry.topology || "triangle-list";
|
|
894
|
+
}
|
|
895
|
+
this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
896
|
+
const { pipeline, getUniforms } = this.pipelineFactory.createRenderPipeline(__spreadProps(__spreadValues({}, props), {
|
|
897
|
+
vs: this.vs,
|
|
898
|
+
fs: this.fs,
|
|
899
|
+
topology: this.topology,
|
|
900
|
+
defines: props.defines,
|
|
901
|
+
parameters: props.parameters,
|
|
902
|
+
layout: props.layout
|
|
903
|
+
}));
|
|
904
|
+
this.pipeline = pipeline;
|
|
905
|
+
this._getModuleUniforms = getUniforms;
|
|
906
|
+
if (props.geometry) {
|
|
907
|
+
this._setGeometry(props.geometry);
|
|
908
|
+
}
|
|
909
|
+
this.setUniforms(this._getModuleUniforms());
|
|
910
|
+
this.setProps(props);
|
|
911
|
+
}
|
|
912
|
+
destroy() {
|
|
913
|
+
this.pipelineFactory.release(this.pipeline);
|
|
914
|
+
}
|
|
915
|
+
draw(renderPass) {
|
|
916
|
+
this.pipeline.draw({
|
|
917
|
+
renderPass,
|
|
918
|
+
vertexCount: this.vertexCount,
|
|
919
|
+
instanceCount: this.instanceCount
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
setProps(props) {
|
|
923
|
+
if (props.indices) {
|
|
924
|
+
this.setIndexBuffer(props.indices);
|
|
925
|
+
}
|
|
926
|
+
if (props.attributes) {
|
|
927
|
+
this.setAttributes(props.attributes);
|
|
928
|
+
}
|
|
929
|
+
if (props.bindings) {
|
|
930
|
+
this.setBindings(props.bindings);
|
|
931
|
+
}
|
|
932
|
+
if (props.uniforms) {
|
|
933
|
+
this.setUniforms(props.uniforms);
|
|
934
|
+
}
|
|
935
|
+
if (props.moduleSettings) {
|
|
936
|
+
this.updateModuleSettings(props.moduleSettings);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
updateModuleSettings(props) {
|
|
940
|
+
const uniforms = this._getModuleUniforms(props);
|
|
941
|
+
this.setUniforms(uniforms);
|
|
942
|
+
}
|
|
943
|
+
setIndexBuffer(indices) {
|
|
944
|
+
this.pipeline.setIndexBuffer(indices);
|
|
945
|
+
}
|
|
946
|
+
setAttributes(bufferAttributes) {
|
|
947
|
+
if (bufferAttributes.indices) {
|
|
948
|
+
import_core5.log.warn(`Model:${this.id} setAttributes() - indices should be set using setIndexBuffer()`);
|
|
949
|
+
}
|
|
950
|
+
this.pipeline.setAttributes(bufferAttributes);
|
|
951
|
+
Object.assign(this.bufferAttributes, bufferAttributes);
|
|
952
|
+
}
|
|
953
|
+
setConstantAttributes(constantAttributes) {
|
|
954
|
+
this.pipeline.setConstantAttributes(constantAttributes);
|
|
955
|
+
Object.assign(this.constantAttributes, constantAttributes);
|
|
956
|
+
}
|
|
957
|
+
/** Set the bindings */
|
|
958
|
+
setBindings(bindings) {
|
|
959
|
+
this.pipeline.setBindings(bindings);
|
|
960
|
+
Object.assign(this.bindings, bindings);
|
|
961
|
+
}
|
|
962
|
+
setUniforms(uniforms) {
|
|
963
|
+
this.pipeline.setUniforms(uniforms);
|
|
964
|
+
Object.assign(this.uniforms, uniforms);
|
|
965
|
+
}
|
|
966
|
+
_setGeometry(geometry) {
|
|
967
|
+
const geometryBuffers = getAttributeBuffersFromGeometry(this.device, geometry);
|
|
968
|
+
this.setAttributes(geometryBuffers);
|
|
969
|
+
const indexBuffer = getIndexBufferFromGeometry(this.device, geometry);
|
|
970
|
+
if (indexBuffer) {
|
|
971
|
+
this.setIndexBuffer(indexBuffer);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
function getShaderSource(device, shader) {
|
|
976
|
+
if (typeof shader === "string") {
|
|
977
|
+
return shader;
|
|
978
|
+
}
|
|
979
|
+
switch (device.info.type) {
|
|
980
|
+
case "webgpu":
|
|
981
|
+
if (shader == null ? void 0 : shader.wgsl) {
|
|
982
|
+
return shader.wgsl;
|
|
983
|
+
}
|
|
984
|
+
throw new Error("WebGPU does not support GLSL shaders");
|
|
985
|
+
default:
|
|
986
|
+
if (shader == null ? void 0 : shader.glsl) {
|
|
987
|
+
return shader.glsl;
|
|
988
|
+
}
|
|
989
|
+
throw new Error("WebGL does not support WGSL shaders");
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
// src/transform/transform.ts
|
|
994
|
+
var import_shadertools2 = require("@luma.gl/shadertools");
|
|
995
|
+
var import_constants = require("@luma.gl/constants");
|
|
996
|
+
var import_webgl = require("@luma.gl/webgl");
|
|
997
|
+
var Transform = class {
|
|
998
|
+
constructor(device, props = {}) {
|
|
999
|
+
// model: Model;
|
|
1000
|
+
this.elementCount = 0;
|
|
1001
|
+
// bufferTransform: BufferTransform | null = null;
|
|
1002
|
+
// textureTransform: TextureTransform | null = null;
|
|
1003
|
+
this.elementIDBuffer = null;
|
|
1004
|
+
this.device = import_webgl.WebGLDevice.attach(device);
|
|
1005
|
+
this.gl = this.device.gl2;
|
|
1006
|
+
this._buildResourceTransforms(props);
|
|
1007
|
+
props = this._updateModelProps(props);
|
|
1008
|
+
this.model = new Model(this.device, __spreadProps(__spreadValues({}, props), {
|
|
1009
|
+
fs: props.fs || (0, import_shadertools2.getPassthroughFS)({ version: (0, import_shadertools2.getShaderInfo)(props.vs).version }),
|
|
1010
|
+
id: props.id || "transform-model",
|
|
1011
|
+
// @ts-expect-error
|
|
1012
|
+
drawMode: props.drawMode || import_constants.GL.POINTS,
|
|
1013
|
+
vertexCount: props.elementCount
|
|
1014
|
+
}));
|
|
1015
|
+
Object.seal(this);
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* Check if Transforms are supported (they are not under WebGL1)
|
|
1019
|
+
* @todo differentiate writing to buffer vs not
|
|
1020
|
+
*/
|
|
1021
|
+
static isSupported(device) {
|
|
1022
|
+
return false;
|
|
1023
|
+
}
|
|
1024
|
+
/** Delete owned resources. */
|
|
1025
|
+
destroy() {
|
|
1026
|
+
}
|
|
1027
|
+
/** @deprecated Use destroy*() */
|
|
1028
|
+
delete() {
|
|
1029
|
+
this.destroy();
|
|
1030
|
+
}
|
|
1031
|
+
/** Run one transform loop. */
|
|
1032
|
+
run(options) {
|
|
1033
|
+
const { clearRenderTarget = true } = options || {};
|
|
1034
|
+
const updatedOpts = this._updateDrawOptions(options);
|
|
1035
|
+
if (clearRenderTarget && updatedOpts.framebuffer) {
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
/** swap resources if a map is provided */
|
|
1039
|
+
swap() {
|
|
1040
|
+
}
|
|
1041
|
+
/** Return Buffer object for given varying name. */
|
|
1042
|
+
getBuffer(varyingName) {
|
|
1043
|
+
return null;
|
|
1044
|
+
}
|
|
1045
|
+
/** Return data either from Buffer or from Texture */
|
|
1046
|
+
getData(options = {}) {
|
|
1047
|
+
}
|
|
1048
|
+
/** Return framebuffer object if rendering to textures */
|
|
1049
|
+
getFramebuffer() {
|
|
1050
|
+
return null;
|
|
1051
|
+
}
|
|
1052
|
+
/** Update some or all buffer/texture bindings. */
|
|
1053
|
+
update(props) {
|
|
1054
|
+
}
|
|
1055
|
+
// Private
|
|
1056
|
+
_updateModelProps(props) {
|
|
1057
|
+
const updatedProps = __spreadValues({}, props);
|
|
1058
|
+
return updatedProps;
|
|
1059
|
+
}
|
|
1060
|
+
_buildResourceTransforms(props) {
|
|
1061
|
+
}
|
|
1062
|
+
_updateDrawOptions(options) {
|
|
1063
|
+
const updatedOpts = __spreadValues({}, options);
|
|
1064
|
+
return updatedOpts;
|
|
1065
|
+
}
|
|
1066
|
+
};
|
|
1067
|
+
|
|
1068
|
+
// src/lib/clip-space.ts
|
|
1069
|
+
var import_core8 = require("@luma.gl/core");
|
|
1070
|
+
var import_webgl2 = require("@luma.gl/webgl");
|
|
1071
|
+
|
|
1072
|
+
// src/geometry/geometry.ts
|
|
1073
|
+
var import_core7 = require("@luma.gl/core");
|
|
1074
|
+
var Geometry = class {
|
|
1075
|
+
constructor(props) {
|
|
1076
|
+
this.userData = {};
|
|
1077
|
+
const { attributes = {}, indices = null, vertexCount = null } = props;
|
|
1078
|
+
this.id = props.id || (0, import_core7.uid)("geometry");
|
|
1079
|
+
this.topology = props.topology;
|
|
1080
|
+
if (indices) {
|
|
1081
|
+
this.indices = ArrayBuffer.isView(indices) ? { value: indices, size: 1 } : indices;
|
|
1082
|
+
}
|
|
1083
|
+
this.attributes = {};
|
|
1084
|
+
for (const [attributeName, attributeValue] of Object.entries(attributes)) {
|
|
1085
|
+
const attribute = ArrayBuffer.isView(attributeValue) ? { value: attributeValue } : attributeValue;
|
|
1086
|
+
(0, import_core7.assert)(
|
|
1087
|
+
ArrayBuffer.isView(attribute.value),
|
|
1088
|
+
`${this._print(attributeName)}: must be typed array or object with value as typed array`
|
|
1089
|
+
);
|
|
1090
|
+
if ((attributeName === "POSITION" || attributeName === "positions") && !attribute.size) {
|
|
1091
|
+
attribute.size = 3;
|
|
1092
|
+
}
|
|
1093
|
+
if (attributeName === "indices") {
|
|
1094
|
+
(0, import_core7.assert)(!this.indices);
|
|
1095
|
+
this.indices = attribute;
|
|
1096
|
+
} else {
|
|
1097
|
+
this.attributes[attributeName] = attribute;
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
if (this.indices && this.indices.isIndexed !== void 0) {
|
|
1101
|
+
this.indices = Object.assign({}, this.indices);
|
|
1102
|
+
delete this.indices.isIndexed;
|
|
1103
|
+
}
|
|
1104
|
+
this.vertexCount = vertexCount || this._calculateVertexCount(this.attributes, this.indices);
|
|
1105
|
+
}
|
|
1106
|
+
getVertexCount() {
|
|
1107
|
+
return this.vertexCount;
|
|
1108
|
+
}
|
|
1109
|
+
// Return an object with all attributes plus indices added as a field.
|
|
1110
|
+
getAttributes() {
|
|
1111
|
+
return this.indices ? __spreadValues({ indices: this.indices }, this.attributes) : this.attributes;
|
|
1112
|
+
}
|
|
1113
|
+
// PRIVATE
|
|
1114
|
+
_print(attributeName) {
|
|
1115
|
+
return `Geometry ${this.id} attribute ${attributeName}`;
|
|
1116
|
+
}
|
|
1117
|
+
// GeometryAttribute
|
|
1118
|
+
// value: typed array
|
|
1119
|
+
// type: indices, vertices, uvs
|
|
1120
|
+
// size: elements per vertex
|
|
1121
|
+
// target: WebGL buffer type (string or constant)
|
|
1122
|
+
_setAttributes(attributes, indices) {
|
|
1123
|
+
return this;
|
|
1124
|
+
}
|
|
1125
|
+
_calculateVertexCount(attributes, indices) {
|
|
1126
|
+
if (indices) {
|
|
1127
|
+
return indices.value.length;
|
|
1128
|
+
}
|
|
1129
|
+
let vertexCount = Infinity;
|
|
1130
|
+
for (const attributeName in attributes) {
|
|
1131
|
+
const attribute = attributes[attributeName];
|
|
1132
|
+
const { value, size, constant } = attribute;
|
|
1133
|
+
if (!constant && value && size >= 1) {
|
|
1134
|
+
vertexCount = Math.min(vertexCount, value.length / size);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
(0, import_core7.assert)(Number.isFinite(vertexCount));
|
|
1138
|
+
return vertexCount;
|
|
1139
|
+
}
|
|
1140
|
+
};
|
|
1141
|
+
|
|
1142
|
+
// src/lib/clip-space.ts
|
|
1143
|
+
var CLIPSPACE_VERTEX_SHADER = import_core8.glsl`\
|
|
1144
|
+
attribute vec2 aClipSpacePosition;
|
|
1145
|
+
attribute vec2 aTexCoord;
|
|
1146
|
+
attribute vec2 aCoordinate;
|
|
1147
|
+
|
|
1148
|
+
varying vec2 position;
|
|
1149
|
+
varying vec2 coordinate;
|
|
1150
|
+
varying vec2 uv;
|
|
1151
|
+
|
|
1152
|
+
void main(void) {
|
|
1153
|
+
gl_Position = vec4(aClipSpacePosition, 0., 1.);
|
|
1154
|
+
position = aClipSpacePosition;
|
|
1155
|
+
coordinate = aCoordinate;
|
|
1156
|
+
uv = aTexCoord;
|
|
1157
|
+
}
|
|
1158
|
+
`;
|
|
1159
|
+
var POSITIONS = [-1, -1, 1, -1, -1, 1, 1, 1];
|
|
1160
|
+
var ClipSpace = class extends Model {
|
|
1161
|
+
constructor(device, opts) {
|
|
1162
|
+
const TEX_COORDS = POSITIONS.map((coord) => coord === -1 ? 0 : coord);
|
|
1163
|
+
super(
|
|
1164
|
+
import_webgl2.WebGLDevice.attach(device),
|
|
1165
|
+
__spreadProps(__spreadValues({}, opts), {
|
|
1166
|
+
vs: CLIPSPACE_VERTEX_SHADER,
|
|
1167
|
+
vertexCount: 4,
|
|
1168
|
+
geometry: new Geometry({
|
|
1169
|
+
topology: "triangle-strip",
|
|
1170
|
+
vertexCount: 4,
|
|
1171
|
+
attributes: {
|
|
1172
|
+
aClipSpacePosition: { size: 2, value: new Float32Array(POSITIONS) },
|
|
1173
|
+
aTexCoord: { size: 2, value: new Float32Array(TEX_COORDS) },
|
|
1174
|
+
aCoordinate: { size: 2, value: new Float32Array(TEX_COORDS) }
|
|
1175
|
+
}
|
|
1176
|
+
})
|
|
1177
|
+
})
|
|
1178
|
+
);
|
|
1179
|
+
}
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1182
|
+
// src/scenegraph/scenegraph-node.ts
|
|
1183
|
+
var import_core9 = require("@luma.gl/core");
|
|
1184
|
+
var import_core10 = require("@math.gl/core");
|
|
1185
|
+
var ScenegraphNode = class {
|
|
1186
|
+
constructor(props = {}) {
|
|
1187
|
+
this.matrix = new import_core10.Matrix4();
|
|
1188
|
+
this.display = true;
|
|
1189
|
+
this.position = new import_core10.Vector3();
|
|
1190
|
+
this.rotation = new import_core10.Vector3();
|
|
1191
|
+
this.scale = new import_core10.Vector3(1, 1, 1);
|
|
1192
|
+
this.userData = {};
|
|
1193
|
+
this.props = {};
|
|
1194
|
+
const { id } = props;
|
|
1195
|
+
this.id = id || (0, import_core9.uid)(this.constructor.name);
|
|
1196
|
+
this._setScenegraphNodeProps(props);
|
|
1197
|
+
}
|
|
1198
|
+
getBounds() {
|
|
1199
|
+
return null;
|
|
1200
|
+
}
|
|
1201
|
+
destroy() {
|
|
1202
|
+
}
|
|
1203
|
+
/** @deprecated use .destroy() */
|
|
1204
|
+
delete() {
|
|
1205
|
+
this.destroy();
|
|
1206
|
+
}
|
|
1207
|
+
setProps(props) {
|
|
1208
|
+
this._setScenegraphNodeProps(props);
|
|
1209
|
+
return this;
|
|
1210
|
+
}
|
|
1211
|
+
toString() {
|
|
1212
|
+
return `{type: ScenegraphNode, id: ${this.id})}`;
|
|
1213
|
+
}
|
|
1214
|
+
setPosition(position) {
|
|
1215
|
+
(0, import_core9.assert)(position.length === 3, "setPosition requires vector argument");
|
|
1216
|
+
this.position = position;
|
|
1217
|
+
return this;
|
|
1218
|
+
}
|
|
1219
|
+
setRotation(rotation) {
|
|
1220
|
+
(0, import_core9.assert)(rotation.length === 3, "setRotation requires vector argument");
|
|
1221
|
+
this.rotation = rotation;
|
|
1222
|
+
return this;
|
|
1223
|
+
}
|
|
1224
|
+
setScale(scale) {
|
|
1225
|
+
(0, import_core9.assert)(scale.length === 3, "setScale requires vector argument");
|
|
1226
|
+
this.scale = scale;
|
|
1227
|
+
return this;
|
|
1228
|
+
}
|
|
1229
|
+
setMatrix(matrix, copyMatrix = true) {
|
|
1230
|
+
if (copyMatrix) {
|
|
1231
|
+
this.matrix.copy(matrix);
|
|
1232
|
+
} else {
|
|
1233
|
+
this.matrix = matrix;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
setMatrixComponents(components) {
|
|
1237
|
+
const { position, rotation, scale, update = true } = components;
|
|
1238
|
+
if (position) {
|
|
1239
|
+
this.setPosition(position);
|
|
1240
|
+
}
|
|
1241
|
+
if (rotation) {
|
|
1242
|
+
this.setRotation(rotation);
|
|
1243
|
+
}
|
|
1244
|
+
if (scale) {
|
|
1245
|
+
this.setScale(scale);
|
|
1246
|
+
}
|
|
1247
|
+
if (update) {
|
|
1248
|
+
this.updateMatrix();
|
|
1249
|
+
}
|
|
1250
|
+
return this;
|
|
1251
|
+
}
|
|
1252
|
+
updateMatrix() {
|
|
1253
|
+
const pos = this.position;
|
|
1254
|
+
const rot = this.rotation;
|
|
1255
|
+
const scale = this.scale;
|
|
1256
|
+
this.matrix.identity();
|
|
1257
|
+
this.matrix.translate(pos);
|
|
1258
|
+
this.matrix.rotateXYZ(rot);
|
|
1259
|
+
this.matrix.scale(scale);
|
|
1260
|
+
return this;
|
|
1261
|
+
}
|
|
1262
|
+
update(options = {}) {
|
|
1263
|
+
const { position, rotation, scale } = options;
|
|
1264
|
+
if (position) {
|
|
1265
|
+
this.setPosition(position);
|
|
1266
|
+
}
|
|
1267
|
+
if (rotation) {
|
|
1268
|
+
this.setRotation(rotation);
|
|
1269
|
+
}
|
|
1270
|
+
if (scale) {
|
|
1271
|
+
this.setScale(scale);
|
|
1272
|
+
}
|
|
1273
|
+
this.updateMatrix();
|
|
1274
|
+
return this;
|
|
1275
|
+
}
|
|
1276
|
+
getCoordinateUniforms(viewMatrix, modelMatrix) {
|
|
1277
|
+
(0, import_core9.assert)(viewMatrix);
|
|
1278
|
+
modelMatrix = modelMatrix || this.matrix;
|
|
1279
|
+
const worldMatrix = new import_core10.Matrix4(viewMatrix).multiplyRight(modelMatrix);
|
|
1280
|
+
const worldInverse = worldMatrix.invert();
|
|
1281
|
+
const worldInverseTranspose = worldInverse.transpose();
|
|
1282
|
+
return {
|
|
1283
|
+
viewMatrix,
|
|
1284
|
+
modelMatrix,
|
|
1285
|
+
objectMatrix: modelMatrix,
|
|
1286
|
+
worldMatrix,
|
|
1287
|
+
worldInverseMatrix: worldInverse,
|
|
1288
|
+
worldInverseTransposeMatrix: worldInverseTranspose
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1291
|
+
// TODO - copied code, not yet vetted
|
|
1292
|
+
/*
|
|
1293
|
+
transform() {
|
|
1294
|
+
if (!this.parent) {
|
|
1295
|
+
this.endPosition.set(this.position);
|
|
1296
|
+
this.endRotation.set(this.rotation);
|
|
1297
|
+
this.endScale.set(this.scale);
|
|
1298
|
+
} else {
|
|
1299
|
+
const parent = this.parent;
|
|
1300
|
+
this.endPosition.set(this.position.add(parent.endPosition));
|
|
1301
|
+
this.endRotation.set(this.rotation.add(parent.endRotation));
|
|
1302
|
+
this.endScale.set(this.scale.add(parent.endScale));
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
const ch = this.children;
|
|
1306
|
+
for (let i = 0; i < ch.length; ++i) {
|
|
1307
|
+
ch[i].transform();
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
return this;
|
|
1311
|
+
}
|
|
1312
|
+
*/
|
|
1313
|
+
_setScenegraphNodeProps(props) {
|
|
1314
|
+
if ("display" in props) {
|
|
1315
|
+
this.display = props.display;
|
|
1316
|
+
}
|
|
1317
|
+
if ("position" in props) {
|
|
1318
|
+
this.setPosition(props.position);
|
|
1319
|
+
}
|
|
1320
|
+
if ("rotation" in props) {
|
|
1321
|
+
this.setRotation(props.rotation);
|
|
1322
|
+
}
|
|
1323
|
+
if ("scale" in props) {
|
|
1324
|
+
this.setScale(props.scale);
|
|
1325
|
+
}
|
|
1326
|
+
if ("matrix" in props) {
|
|
1327
|
+
this.setMatrix(props.matrix);
|
|
1328
|
+
}
|
|
1329
|
+
Object.assign(this.props, props);
|
|
1330
|
+
}
|
|
1331
|
+
};
|
|
1332
|
+
|
|
1333
|
+
// src/scenegraph/group-node.ts
|
|
1334
|
+
var import_core11 = require("@math.gl/core");
|
|
1335
|
+
var import_core12 = require("@luma.gl/core");
|
|
1336
|
+
var GroupNode = class extends ScenegraphNode {
|
|
1337
|
+
constructor(props = {}) {
|
|
1338
|
+
props = Array.isArray(props) ? { children: props } : props;
|
|
1339
|
+
const { children = [] } = props;
|
|
1340
|
+
import_core12.log.assert(
|
|
1341
|
+
children.every((child) => child instanceof ScenegraphNode),
|
|
1342
|
+
"every child must an instance of ScenegraphNode"
|
|
1343
|
+
);
|
|
1344
|
+
super(props);
|
|
1345
|
+
this.children = children;
|
|
1346
|
+
}
|
|
1347
|
+
getBounds() {
|
|
1348
|
+
const result = [[Infinity, Infinity, Infinity], [-Infinity, -Infinity, -Infinity]];
|
|
1349
|
+
this.traverse((node, { worldMatrix }) => {
|
|
1350
|
+
const bounds = node.getBounds();
|
|
1351
|
+
if (!bounds) {
|
|
1352
|
+
return;
|
|
1353
|
+
}
|
|
1354
|
+
const [min, max] = bounds;
|
|
1355
|
+
const center = new import_core11.Vector3(min).add(max).divide([2, 2, 2]);
|
|
1356
|
+
worldMatrix.transformAsPoint(center, center);
|
|
1357
|
+
const halfSize = new import_core11.Vector3(max).subtract(min).divide([2, 2, 2]);
|
|
1358
|
+
worldMatrix.transformAsVector(halfSize, halfSize);
|
|
1359
|
+
for (let v = 0; v < 8; v++) {
|
|
1360
|
+
const position = new import_core11.Vector3(
|
|
1361
|
+
v & 1 ? -1 : 1,
|
|
1362
|
+
v & 2 ? -1 : 1,
|
|
1363
|
+
v & 4 ? -1 : 1
|
|
1364
|
+
).multiply(halfSize).add(center);
|
|
1365
|
+
for (let i = 0; i < 3; i++) {
|
|
1366
|
+
result[0][i] = Math.min(result[0][i], position[i]);
|
|
1367
|
+
result[1][i] = Math.max(result[1][i], position[i]);
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
});
|
|
1371
|
+
if (!Number.isFinite(result[0][0])) {
|
|
1372
|
+
return null;
|
|
1373
|
+
}
|
|
1374
|
+
return result;
|
|
1375
|
+
}
|
|
1376
|
+
destroy() {
|
|
1377
|
+
this.children.forEach((child) => child.destroy());
|
|
1378
|
+
this.removeAll();
|
|
1379
|
+
super.destroy();
|
|
1380
|
+
}
|
|
1381
|
+
// Unpacks arrays and nested arrays of children
|
|
1382
|
+
add(...children) {
|
|
1383
|
+
for (const child of children) {
|
|
1384
|
+
if (Array.isArray(child)) {
|
|
1385
|
+
this.add(...child);
|
|
1386
|
+
} else {
|
|
1387
|
+
this.children.push(child);
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
return this;
|
|
1391
|
+
}
|
|
1392
|
+
remove(child) {
|
|
1393
|
+
const children = this.children;
|
|
1394
|
+
const indexOf = children.indexOf(child);
|
|
1395
|
+
if (indexOf > -1) {
|
|
1396
|
+
children.splice(indexOf, 1);
|
|
1397
|
+
}
|
|
1398
|
+
return this;
|
|
1399
|
+
}
|
|
1400
|
+
removeAll() {
|
|
1401
|
+
this.children = [];
|
|
1402
|
+
return this;
|
|
1403
|
+
}
|
|
1404
|
+
traverse(visitor, { worldMatrix = new import_core11.Matrix4() } = {}) {
|
|
1405
|
+
const modelMatrix = new import_core11.Matrix4(worldMatrix).multiplyRight(this.matrix);
|
|
1406
|
+
for (const child of this.children) {
|
|
1407
|
+
if (child instanceof GroupNode) {
|
|
1408
|
+
child.traverse(visitor, { worldMatrix: modelMatrix });
|
|
1409
|
+
} else {
|
|
1410
|
+
visitor(child, { worldMatrix: modelMatrix });
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
};
|
|
1415
|
+
|
|
1416
|
+
// src/scenegraph/model-node.ts
|
|
1417
|
+
var ModelNode = class extends ScenegraphNode {
|
|
1418
|
+
// TODO - is this used? override callbacks to make sure we call them with this
|
|
1419
|
+
// onBeforeRender = null;
|
|
1420
|
+
// onAfterRender = null;
|
|
1421
|
+
// AfterRender = null;
|
|
1422
|
+
constructor(props) {
|
|
1423
|
+
super(props);
|
|
1424
|
+
this.bounds = null;
|
|
1425
|
+
this.model = props.model;
|
|
1426
|
+
this.managedResources = props.managedResources || [];
|
|
1427
|
+
this.bounds = props.bounds || null;
|
|
1428
|
+
this.setProps(props);
|
|
1429
|
+
}
|
|
1430
|
+
getBounds() {
|
|
1431
|
+
return this.bounds;
|
|
1432
|
+
}
|
|
1433
|
+
destroy() {
|
|
1434
|
+
if (this.model) {
|
|
1435
|
+
this.model.destroy();
|
|
1436
|
+
this.model = null;
|
|
1437
|
+
}
|
|
1438
|
+
this.managedResources.forEach((resource) => resource.destroy());
|
|
1439
|
+
this.managedResources = [];
|
|
1440
|
+
}
|
|
1441
|
+
// Expose model methods
|
|
1442
|
+
draw(renderPass) {
|
|
1443
|
+
return this.model.draw(renderPass);
|
|
1444
|
+
}
|
|
1445
|
+
};
|
|
1446
|
+
|
|
1447
|
+
// src/geometries/cone-geometry.ts
|
|
1448
|
+
var import_core14 = require("@luma.gl/core");
|
|
1449
|
+
|
|
1450
|
+
// src/geometries/truncated-cone-geometry.ts
|
|
1451
|
+
var import_core13 = require("@luma.gl/core");
|
|
1452
|
+
var INDEX_OFFSETS = {
|
|
1453
|
+
x: [2, 0, 1],
|
|
1454
|
+
y: [0, 1, 2],
|
|
1455
|
+
z: [1, 2, 0]
|
|
1456
|
+
};
|
|
1457
|
+
var TruncatedConeGeometry = class extends Geometry {
|
|
1458
|
+
constructor(props = {}) {
|
|
1459
|
+
const { id = (0, import_core13.uid)("truncated-code-geometry") } = props;
|
|
1460
|
+
const { indices, attributes } = tesselateTruncatedCone(props);
|
|
1461
|
+
super(__spreadProps(__spreadValues({}, props), {
|
|
1462
|
+
id,
|
|
1463
|
+
topology: "triangle-list",
|
|
1464
|
+
indices,
|
|
1465
|
+
attributes: __spreadValues({
|
|
1466
|
+
POSITION: { size: 3, value: attributes.POSITION },
|
|
1467
|
+
NORMAL: { size: 3, value: attributes.NORMAL },
|
|
1468
|
+
TEXCOORD_0: { size: 2, value: attributes.TEXCOORD_0 }
|
|
1469
|
+
}, props.attributes)
|
|
1470
|
+
}));
|
|
1471
|
+
}
|
|
1472
|
+
};
|
|
1473
|
+
function tesselateTruncatedCone(props = {}) {
|
|
1474
|
+
const {
|
|
1475
|
+
bottomRadius = 0,
|
|
1476
|
+
topRadius = 0,
|
|
1477
|
+
height = 1,
|
|
1478
|
+
nradial = 10,
|
|
1479
|
+
nvertical = 10,
|
|
1480
|
+
verticalAxis = "y",
|
|
1481
|
+
topCap = false,
|
|
1482
|
+
bottomCap = false
|
|
1483
|
+
} = props;
|
|
1484
|
+
const extra = (topCap ? 2 : 0) + (bottomCap ? 2 : 0);
|
|
1485
|
+
const numVertices = (nradial + 1) * (nvertical + 1 + extra);
|
|
1486
|
+
const slant = Math.atan2(bottomRadius - topRadius, height);
|
|
1487
|
+
const msin = Math.sin;
|
|
1488
|
+
const mcos = Math.cos;
|
|
1489
|
+
const mpi = Math.PI;
|
|
1490
|
+
const cosSlant = mcos(slant);
|
|
1491
|
+
const sinSlant = msin(slant);
|
|
1492
|
+
const start = topCap ? -2 : 0;
|
|
1493
|
+
const end = nvertical + (bottomCap ? 2 : 0);
|
|
1494
|
+
const vertsAroundEdge = nradial + 1;
|
|
1495
|
+
const indices = new Uint16Array(nradial * (nvertical + extra) * 6);
|
|
1496
|
+
const indexOffset = INDEX_OFFSETS[verticalAxis];
|
|
1497
|
+
const positions = new Float32Array(numVertices * 3);
|
|
1498
|
+
const normals = new Float32Array(numVertices * 3);
|
|
1499
|
+
const texCoords = new Float32Array(numVertices * 2);
|
|
1500
|
+
let i3 = 0;
|
|
1501
|
+
let i2 = 0;
|
|
1502
|
+
for (let i = start; i <= end; i++) {
|
|
1503
|
+
let v = i / nvertical;
|
|
1504
|
+
let y = height * v;
|
|
1505
|
+
let ringRadius;
|
|
1506
|
+
if (i < 0) {
|
|
1507
|
+
y = 0;
|
|
1508
|
+
v = 1;
|
|
1509
|
+
ringRadius = bottomRadius;
|
|
1510
|
+
} else if (i > nvertical) {
|
|
1511
|
+
y = height;
|
|
1512
|
+
v = 1;
|
|
1513
|
+
ringRadius = topRadius;
|
|
1514
|
+
} else {
|
|
1515
|
+
ringRadius = bottomRadius + (topRadius - bottomRadius) * (i / nvertical);
|
|
1516
|
+
}
|
|
1517
|
+
if (i === -2 || i === nvertical + 2) {
|
|
1518
|
+
ringRadius = 0;
|
|
1519
|
+
v = 0;
|
|
1520
|
+
}
|
|
1521
|
+
y -= height / 2;
|
|
1522
|
+
for (let j = 0; j < vertsAroundEdge; j++) {
|
|
1523
|
+
const sin = msin(j * mpi * 2 / nradial);
|
|
1524
|
+
const cos = mcos(j * mpi * 2 / nradial);
|
|
1525
|
+
positions[i3 + indexOffset[0]] = sin * ringRadius;
|
|
1526
|
+
positions[i3 + indexOffset[1]] = y;
|
|
1527
|
+
positions[i3 + indexOffset[2]] = cos * ringRadius;
|
|
1528
|
+
normals[i3 + indexOffset[0]] = i < 0 || i > nvertical ? 0 : sin * cosSlant;
|
|
1529
|
+
normals[i3 + indexOffset[1]] = i < 0 ? -1 : i > nvertical ? 1 : sinSlant;
|
|
1530
|
+
normals[i3 + indexOffset[2]] = i < 0 || i > nvertical ? 0 : cos * cosSlant;
|
|
1531
|
+
texCoords[i2 + 0] = j / nradial;
|
|
1532
|
+
texCoords[i2 + 1] = v;
|
|
1533
|
+
i2 += 2;
|
|
1534
|
+
i3 += 3;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
for (let i = 0; i < nvertical + extra; i++) {
|
|
1538
|
+
for (let j = 0; j < nradial; j++) {
|
|
1539
|
+
const index = (i * nradial + j) * 6;
|
|
1540
|
+
indices[index + 0] = vertsAroundEdge * (i + 0) + 0 + j;
|
|
1541
|
+
indices[index + 1] = vertsAroundEdge * (i + 0) + 1 + j;
|
|
1542
|
+
indices[index + 2] = vertsAroundEdge * (i + 1) + 1 + j;
|
|
1543
|
+
indices[index + 3] = vertsAroundEdge * (i + 0) + 0 + j;
|
|
1544
|
+
indices[index + 4] = vertsAroundEdge * (i + 1) + 1 + j;
|
|
1545
|
+
indices[index + 5] = vertsAroundEdge * (i + 1) + 0 + j;
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
return {
|
|
1549
|
+
indices,
|
|
1550
|
+
attributes: {
|
|
1551
|
+
POSITION: positions,
|
|
1552
|
+
NORMAL: normals,
|
|
1553
|
+
TEXCOORD_0: texCoords
|
|
1554
|
+
}
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
// src/geometries/cone-geometry.ts
|
|
1559
|
+
var ConeGeometry = class extends TruncatedConeGeometry {
|
|
1560
|
+
constructor(props = {}) {
|
|
1561
|
+
const { id = (0, import_core14.uid)("cone-geometry"), radius = 1, cap = true } = props;
|
|
1562
|
+
super(__spreadProps(__spreadValues({}, props), {
|
|
1563
|
+
id,
|
|
1564
|
+
topRadius: 0,
|
|
1565
|
+
topCap: Boolean(cap),
|
|
1566
|
+
bottomCap: Boolean(cap),
|
|
1567
|
+
bottomRadius: radius
|
|
1568
|
+
}));
|
|
1569
|
+
}
|
|
1570
|
+
};
|
|
1571
|
+
|
|
1572
|
+
// src/geometries/cube-geometry.ts
|
|
1573
|
+
var import_core15 = require("@luma.gl/core");
|
|
1574
|
+
var CubeGeometry = class extends Geometry {
|
|
1575
|
+
constructor(props = {}) {
|
|
1576
|
+
const { id = (0, import_core15.uid)("cube-geometry"), indices = true } = props;
|
|
1577
|
+
super(indices ? __spreadProps(__spreadValues({}, props), {
|
|
1578
|
+
id,
|
|
1579
|
+
topology: "triangle-list",
|
|
1580
|
+
indices: { size: 1, value: CUBE_INDICES },
|
|
1581
|
+
attributes: __spreadValues(__spreadValues({}, ATTRIBUTES), props.attributes)
|
|
1582
|
+
}) : __spreadProps(__spreadValues({}, props), {
|
|
1583
|
+
id,
|
|
1584
|
+
topology: "triangle-list",
|
|
1585
|
+
indices: void 0,
|
|
1586
|
+
attributes: __spreadValues(__spreadValues({}, NON_INDEXED_ATTRIBUTES), props.attributes)
|
|
1587
|
+
}));
|
|
1588
|
+
}
|
|
1589
|
+
};
|
|
1590
|
+
var CUBE_INDICES = new Uint16Array([
|
|
1591
|
+
0,
|
|
1592
|
+
1,
|
|
1593
|
+
2,
|
|
1594
|
+
0,
|
|
1595
|
+
2,
|
|
1596
|
+
3,
|
|
1597
|
+
4,
|
|
1598
|
+
5,
|
|
1599
|
+
6,
|
|
1600
|
+
4,
|
|
1601
|
+
6,
|
|
1602
|
+
7,
|
|
1603
|
+
8,
|
|
1604
|
+
9,
|
|
1605
|
+
10,
|
|
1606
|
+
8,
|
|
1607
|
+
10,
|
|
1608
|
+
11,
|
|
1609
|
+
12,
|
|
1610
|
+
13,
|
|
1611
|
+
14,
|
|
1612
|
+
12,
|
|
1613
|
+
14,
|
|
1614
|
+
15,
|
|
1615
|
+
16,
|
|
1616
|
+
17,
|
|
1617
|
+
18,
|
|
1618
|
+
16,
|
|
1619
|
+
18,
|
|
1620
|
+
19,
|
|
1621
|
+
20,
|
|
1622
|
+
21,
|
|
1623
|
+
22,
|
|
1624
|
+
20,
|
|
1625
|
+
22,
|
|
1626
|
+
23
|
|
1627
|
+
]);
|
|
1628
|
+
var CUBE_POSITIONS = new Float32Array([
|
|
1629
|
+
-1,
|
|
1630
|
+
-1,
|
|
1631
|
+
1,
|
|
1632
|
+
1,
|
|
1633
|
+
-1,
|
|
1634
|
+
1,
|
|
1635
|
+
1,
|
|
1636
|
+
1,
|
|
1637
|
+
1,
|
|
1638
|
+
-1,
|
|
1639
|
+
1,
|
|
1640
|
+
1,
|
|
1641
|
+
-1,
|
|
1642
|
+
-1,
|
|
1643
|
+
-1,
|
|
1644
|
+
-1,
|
|
1645
|
+
1,
|
|
1646
|
+
-1,
|
|
1647
|
+
1,
|
|
1648
|
+
1,
|
|
1649
|
+
-1,
|
|
1650
|
+
1,
|
|
1651
|
+
-1,
|
|
1652
|
+
-1,
|
|
1653
|
+
-1,
|
|
1654
|
+
1,
|
|
1655
|
+
-1,
|
|
1656
|
+
-1,
|
|
1657
|
+
1,
|
|
1658
|
+
1,
|
|
1659
|
+
1,
|
|
1660
|
+
1,
|
|
1661
|
+
1,
|
|
1662
|
+
1,
|
|
1663
|
+
1,
|
|
1664
|
+
-1,
|
|
1665
|
+
-1,
|
|
1666
|
+
-1,
|
|
1667
|
+
-1,
|
|
1668
|
+
1,
|
|
1669
|
+
-1,
|
|
1670
|
+
-1,
|
|
1671
|
+
1,
|
|
1672
|
+
-1,
|
|
1673
|
+
1,
|
|
1674
|
+
-1,
|
|
1675
|
+
-1,
|
|
1676
|
+
1,
|
|
1677
|
+
1,
|
|
1678
|
+
-1,
|
|
1679
|
+
-1,
|
|
1680
|
+
1,
|
|
1681
|
+
1,
|
|
1682
|
+
-1,
|
|
1683
|
+
1,
|
|
1684
|
+
1,
|
|
1685
|
+
1,
|
|
1686
|
+
1,
|
|
1687
|
+
-1,
|
|
1688
|
+
1,
|
|
1689
|
+
-1,
|
|
1690
|
+
-1,
|
|
1691
|
+
-1,
|
|
1692
|
+
-1,
|
|
1693
|
+
-1,
|
|
1694
|
+
1,
|
|
1695
|
+
-1,
|
|
1696
|
+
1,
|
|
1697
|
+
1,
|
|
1698
|
+
-1,
|
|
1699
|
+
1,
|
|
1700
|
+
-1
|
|
1701
|
+
]);
|
|
1702
|
+
var CUBE_NORMALS = new Float32Array([
|
|
1703
|
+
// Front face
|
|
1704
|
+
0,
|
|
1705
|
+
0,
|
|
1706
|
+
1,
|
|
1707
|
+
0,
|
|
1708
|
+
0,
|
|
1709
|
+
1,
|
|
1710
|
+
0,
|
|
1711
|
+
0,
|
|
1712
|
+
1,
|
|
1713
|
+
0,
|
|
1714
|
+
0,
|
|
1715
|
+
1,
|
|
1716
|
+
// Back face
|
|
1717
|
+
0,
|
|
1718
|
+
0,
|
|
1719
|
+
-1,
|
|
1720
|
+
0,
|
|
1721
|
+
0,
|
|
1722
|
+
-1,
|
|
1723
|
+
0,
|
|
1724
|
+
0,
|
|
1725
|
+
-1,
|
|
1726
|
+
0,
|
|
1727
|
+
0,
|
|
1728
|
+
-1,
|
|
1729
|
+
// Top face
|
|
1730
|
+
0,
|
|
1731
|
+
1,
|
|
1732
|
+
0,
|
|
1733
|
+
0,
|
|
1734
|
+
1,
|
|
1735
|
+
0,
|
|
1736
|
+
0,
|
|
1737
|
+
1,
|
|
1738
|
+
0,
|
|
1739
|
+
0,
|
|
1740
|
+
1,
|
|
1741
|
+
0,
|
|
1742
|
+
// Bottom face
|
|
1743
|
+
0,
|
|
1744
|
+
-1,
|
|
1745
|
+
0,
|
|
1746
|
+
0,
|
|
1747
|
+
-1,
|
|
1748
|
+
0,
|
|
1749
|
+
0,
|
|
1750
|
+
-1,
|
|
1751
|
+
0,
|
|
1752
|
+
0,
|
|
1753
|
+
-1,
|
|
1754
|
+
0,
|
|
1755
|
+
// Right face
|
|
1756
|
+
1,
|
|
1757
|
+
0,
|
|
1758
|
+
0,
|
|
1759
|
+
1,
|
|
1760
|
+
0,
|
|
1761
|
+
0,
|
|
1762
|
+
1,
|
|
1763
|
+
0,
|
|
1764
|
+
0,
|
|
1765
|
+
1,
|
|
1766
|
+
0,
|
|
1767
|
+
0,
|
|
1768
|
+
// Left face
|
|
1769
|
+
-1,
|
|
1770
|
+
0,
|
|
1771
|
+
0,
|
|
1772
|
+
-1,
|
|
1773
|
+
0,
|
|
1774
|
+
0,
|
|
1775
|
+
-1,
|
|
1776
|
+
0,
|
|
1777
|
+
0,
|
|
1778
|
+
-1,
|
|
1779
|
+
0,
|
|
1780
|
+
0
|
|
1781
|
+
]);
|
|
1782
|
+
var CUBE_TEX_COORDS = new Float32Array([
|
|
1783
|
+
// Front face
|
|
1784
|
+
0,
|
|
1785
|
+
0,
|
|
1786
|
+
1,
|
|
1787
|
+
0,
|
|
1788
|
+
1,
|
|
1789
|
+
1,
|
|
1790
|
+
0,
|
|
1791
|
+
1,
|
|
1792
|
+
// Back face
|
|
1793
|
+
1,
|
|
1794
|
+
0,
|
|
1795
|
+
1,
|
|
1796
|
+
1,
|
|
1797
|
+
0,
|
|
1798
|
+
1,
|
|
1799
|
+
0,
|
|
1800
|
+
0,
|
|
1801
|
+
// Top face
|
|
1802
|
+
0,
|
|
1803
|
+
1,
|
|
1804
|
+
0,
|
|
1805
|
+
0,
|
|
1806
|
+
1,
|
|
1807
|
+
0,
|
|
1808
|
+
1,
|
|
1809
|
+
1,
|
|
1810
|
+
// Bottom face
|
|
1811
|
+
1,
|
|
1812
|
+
1,
|
|
1813
|
+
0,
|
|
1814
|
+
1,
|
|
1815
|
+
0,
|
|
1816
|
+
0,
|
|
1817
|
+
1,
|
|
1818
|
+
0,
|
|
1819
|
+
// Right face
|
|
1820
|
+
1,
|
|
1821
|
+
0,
|
|
1822
|
+
1,
|
|
1823
|
+
1,
|
|
1824
|
+
0,
|
|
1825
|
+
1,
|
|
1826
|
+
0,
|
|
1827
|
+
0,
|
|
1828
|
+
// Left face
|
|
1829
|
+
0,
|
|
1830
|
+
0,
|
|
1831
|
+
1,
|
|
1832
|
+
0,
|
|
1833
|
+
1,
|
|
1834
|
+
1,
|
|
1835
|
+
0,
|
|
1836
|
+
1
|
|
1837
|
+
]);
|
|
1838
|
+
var CUBE_NON_INDEXED_POSITIONS = new Float32Array([
|
|
1839
|
+
1,
|
|
1840
|
+
-1,
|
|
1841
|
+
1,
|
|
1842
|
+
1,
|
|
1843
|
+
-1,
|
|
1844
|
+
-1,
|
|
1845
|
+
1,
|
|
1846
|
+
1,
|
|
1847
|
+
-1,
|
|
1848
|
+
-1,
|
|
1849
|
+
-1,
|
|
1850
|
+
1,
|
|
1851
|
+
1,
|
|
1852
|
+
-1,
|
|
1853
|
+
-1,
|
|
1854
|
+
1,
|
|
1855
|
+
1,
|
|
1856
|
+
-1,
|
|
1857
|
+
1,
|
|
1858
|
+
1,
|
|
1859
|
+
-1,
|
|
1860
|
+
-1,
|
|
1861
|
+
-1,
|
|
1862
|
+
1,
|
|
1863
|
+
1,
|
|
1864
|
+
1,
|
|
1865
|
+
1,
|
|
1866
|
+
1,
|
|
1867
|
+
1,
|
|
1868
|
+
-1,
|
|
1869
|
+
1,
|
|
1870
|
+
1,
|
|
1871
|
+
1,
|
|
1872
|
+
-1,
|
|
1873
|
+
-1,
|
|
1874
|
+
1,
|
|
1875
|
+
1,
|
|
1876
|
+
1,
|
|
1877
|
+
-1,
|
|
1878
|
+
1,
|
|
1879
|
+
1,
|
|
1880
|
+
1,
|
|
1881
|
+
1,
|
|
1882
|
+
1,
|
|
1883
|
+
1,
|
|
1884
|
+
-1,
|
|
1885
|
+
-1,
|
|
1886
|
+
1,
|
|
1887
|
+
-1,
|
|
1888
|
+
1,
|
|
1889
|
+
1,
|
|
1890
|
+
1,
|
|
1891
|
+
1,
|
|
1892
|
+
1,
|
|
1893
|
+
1,
|
|
1894
|
+
1,
|
|
1895
|
+
1,
|
|
1896
|
+
1,
|
|
1897
|
+
-1,
|
|
1898
|
+
1,
|
|
1899
|
+
-1,
|
|
1900
|
+
1,
|
|
1901
|
+
-1,
|
|
1902
|
+
1,
|
|
1903
|
+
-1,
|
|
1904
|
+
1,
|
|
1905
|
+
1,
|
|
1906
|
+
1,
|
|
1907
|
+
1,
|
|
1908
|
+
1,
|
|
1909
|
+
-1,
|
|
1910
|
+
1,
|
|
1911
|
+
-1,
|
|
1912
|
+
-1,
|
|
1913
|
+
1,
|
|
1914
|
+
1,
|
|
1915
|
+
-1,
|
|
1916
|
+
1,
|
|
1917
|
+
1,
|
|
1918
|
+
1,
|
|
1919
|
+
-1,
|
|
1920
|
+
1,
|
|
1921
|
+
-1,
|
|
1922
|
+
1,
|
|
1923
|
+
-1,
|
|
1924
|
+
-1,
|
|
1925
|
+
-1,
|
|
1926
|
+
1,
|
|
1927
|
+
-1,
|
|
1928
|
+
-1,
|
|
1929
|
+
1,
|
|
1930
|
+
1,
|
|
1931
|
+
-1,
|
|
1932
|
+
1,
|
|
1933
|
+
-1,
|
|
1934
|
+
1,
|
|
1935
|
+
1,
|
|
1936
|
+
1,
|
|
1937
|
+
1,
|
|
1938
|
+
1,
|
|
1939
|
+
-1,
|
|
1940
|
+
1,
|
|
1941
|
+
1,
|
|
1942
|
+
1,
|
|
1943
|
+
-1,
|
|
1944
|
+
-1,
|
|
1945
|
+
1,
|
|
1946
|
+
1,
|
|
1947
|
+
-1,
|
|
1948
|
+
-1,
|
|
1949
|
+
1,
|
|
1950
|
+
1,
|
|
1951
|
+
1,
|
|
1952
|
+
-1,
|
|
1953
|
+
1,
|
|
1954
|
+
1,
|
|
1955
|
+
1,
|
|
1956
|
+
1,
|
|
1957
|
+
1,
|
|
1958
|
+
1,
|
|
1959
|
+
1,
|
|
1960
|
+
-1,
|
|
1961
|
+
-1,
|
|
1962
|
+
1,
|
|
1963
|
+
-1,
|
|
1964
|
+
-1,
|
|
1965
|
+
-1,
|
|
1966
|
+
1,
|
|
1967
|
+
-1,
|
|
1968
|
+
1,
|
|
1969
|
+
-1,
|
|
1970
|
+
1,
|
|
1971
|
+
1,
|
|
1972
|
+
1,
|
|
1973
|
+
-1,
|
|
1974
|
+
1,
|
|
1975
|
+
1,
|
|
1976
|
+
-1,
|
|
1977
|
+
-1,
|
|
1978
|
+
1,
|
|
1979
|
+
-1,
|
|
1980
|
+
1,
|
|
1981
|
+
-1,
|
|
1982
|
+
1
|
|
1983
|
+
]);
|
|
1984
|
+
var CUBE_NON_INDEXED_TEX_COORDS = new Float32Array([
|
|
1985
|
+
1,
|
|
1986
|
+
1,
|
|
1987
|
+
0,
|
|
1988
|
+
1,
|
|
1989
|
+
0,
|
|
1990
|
+
0,
|
|
1991
|
+
1,
|
|
1992
|
+
0,
|
|
1993
|
+
1,
|
|
1994
|
+
1,
|
|
1995
|
+
0,
|
|
1996
|
+
0,
|
|
1997
|
+
1,
|
|
1998
|
+
1,
|
|
1999
|
+
0,
|
|
2000
|
+
1,
|
|
2001
|
+
0,
|
|
2002
|
+
0,
|
|
2003
|
+
1,
|
|
2004
|
+
0,
|
|
2005
|
+
1,
|
|
2006
|
+
1,
|
|
2007
|
+
0,
|
|
2008
|
+
0,
|
|
2009
|
+
1,
|
|
2010
|
+
1,
|
|
2011
|
+
0,
|
|
2012
|
+
1,
|
|
2013
|
+
0,
|
|
2014
|
+
0,
|
|
2015
|
+
1,
|
|
2016
|
+
0,
|
|
2017
|
+
1,
|
|
2018
|
+
1,
|
|
2019
|
+
0,
|
|
2020
|
+
0,
|
|
2021
|
+
1,
|
|
2022
|
+
1,
|
|
2023
|
+
0,
|
|
2024
|
+
1,
|
|
2025
|
+
0,
|
|
2026
|
+
0,
|
|
2027
|
+
1,
|
|
2028
|
+
0,
|
|
2029
|
+
1,
|
|
2030
|
+
1,
|
|
2031
|
+
0,
|
|
2032
|
+
0,
|
|
2033
|
+
1,
|
|
2034
|
+
1,
|
|
2035
|
+
0,
|
|
2036
|
+
1,
|
|
2037
|
+
0,
|
|
2038
|
+
0,
|
|
2039
|
+
0,
|
|
2040
|
+
0,
|
|
2041
|
+
1,
|
|
2042
|
+
0,
|
|
2043
|
+
1,
|
|
2044
|
+
1,
|
|
2045
|
+
1,
|
|
2046
|
+
1,
|
|
2047
|
+
0,
|
|
2048
|
+
1,
|
|
2049
|
+
0,
|
|
2050
|
+
0,
|
|
2051
|
+
1,
|
|
2052
|
+
0,
|
|
2053
|
+
1,
|
|
2054
|
+
1,
|
|
2055
|
+
0,
|
|
2056
|
+
0
|
|
2057
|
+
]);
|
|
2058
|
+
var CUBE_NON_INDEXED_COLORS = new Float32Array([
|
|
2059
|
+
1,
|
|
2060
|
+
0,
|
|
2061
|
+
1,
|
|
2062
|
+
1,
|
|
2063
|
+
0,
|
|
2064
|
+
0,
|
|
2065
|
+
1,
|
|
2066
|
+
1,
|
|
2067
|
+
0,
|
|
2068
|
+
0,
|
|
2069
|
+
0,
|
|
2070
|
+
1,
|
|
2071
|
+
1,
|
|
2072
|
+
0,
|
|
2073
|
+
0,
|
|
2074
|
+
1,
|
|
2075
|
+
1,
|
|
2076
|
+
0,
|
|
2077
|
+
1,
|
|
2078
|
+
1,
|
|
2079
|
+
0,
|
|
2080
|
+
0,
|
|
2081
|
+
0,
|
|
2082
|
+
1,
|
|
2083
|
+
1,
|
|
2084
|
+
1,
|
|
2085
|
+
1,
|
|
2086
|
+
1,
|
|
2087
|
+
1,
|
|
2088
|
+
0,
|
|
2089
|
+
1,
|
|
2090
|
+
1,
|
|
2091
|
+
1,
|
|
2092
|
+
0,
|
|
2093
|
+
0,
|
|
2094
|
+
1,
|
|
2095
|
+
1,
|
|
2096
|
+
1,
|
|
2097
|
+
0,
|
|
2098
|
+
1,
|
|
2099
|
+
1,
|
|
2100
|
+
1,
|
|
2101
|
+
1,
|
|
2102
|
+
1,
|
|
2103
|
+
1,
|
|
2104
|
+
0,
|
|
2105
|
+
0,
|
|
2106
|
+
1,
|
|
2107
|
+
0,
|
|
2108
|
+
1,
|
|
2109
|
+
1,
|
|
2110
|
+
1,
|
|
2111
|
+
1,
|
|
2112
|
+
1,
|
|
2113
|
+
1,
|
|
2114
|
+
1,
|
|
2115
|
+
1,
|
|
2116
|
+
1,
|
|
2117
|
+
0,
|
|
2118
|
+
1,
|
|
2119
|
+
0,
|
|
2120
|
+
1,
|
|
2121
|
+
0,
|
|
2122
|
+
1,
|
|
2123
|
+
0,
|
|
2124
|
+
1,
|
|
2125
|
+
1,
|
|
2126
|
+
1,
|
|
2127
|
+
1,
|
|
2128
|
+
1,
|
|
2129
|
+
0,
|
|
2130
|
+
1,
|
|
2131
|
+
0,
|
|
2132
|
+
0,
|
|
2133
|
+
1,
|
|
2134
|
+
1,
|
|
2135
|
+
0,
|
|
2136
|
+
1,
|
|
2137
|
+
1,
|
|
2138
|
+
1,
|
|
2139
|
+
0,
|
|
2140
|
+
1,
|
|
2141
|
+
0,
|
|
2142
|
+
1,
|
|
2143
|
+
0,
|
|
2144
|
+
0,
|
|
2145
|
+
0,
|
|
2146
|
+
1,
|
|
2147
|
+
0,
|
|
2148
|
+
0,
|
|
2149
|
+
1,
|
|
2150
|
+
1,
|
|
2151
|
+
0,
|
|
2152
|
+
1,
|
|
2153
|
+
0,
|
|
2154
|
+
1,
|
|
2155
|
+
1,
|
|
2156
|
+
1,
|
|
2157
|
+
1,
|
|
2158
|
+
1,
|
|
2159
|
+
0,
|
|
2160
|
+
1,
|
|
2161
|
+
1,
|
|
2162
|
+
1,
|
|
2163
|
+
0,
|
|
2164
|
+
0,
|
|
2165
|
+
1,
|
|
2166
|
+
1,
|
|
2167
|
+
0,
|
|
2168
|
+
0,
|
|
2169
|
+
1,
|
|
2170
|
+
1,
|
|
2171
|
+
1,
|
|
2172
|
+
0,
|
|
2173
|
+
1,
|
|
2174
|
+
1,
|
|
2175
|
+
1,
|
|
2176
|
+
1,
|
|
2177
|
+
1,
|
|
2178
|
+
1,
|
|
2179
|
+
1,
|
|
2180
|
+
0,
|
|
2181
|
+
0,
|
|
2182
|
+
1,
|
|
2183
|
+
0,
|
|
2184
|
+
0,
|
|
2185
|
+
0,
|
|
2186
|
+
1,
|
|
2187
|
+
0,
|
|
2188
|
+
1,
|
|
2189
|
+
0,
|
|
2190
|
+
1,
|
|
2191
|
+
1,
|
|
2192
|
+
1,
|
|
2193
|
+
0,
|
|
2194
|
+
1,
|
|
2195
|
+
1,
|
|
2196
|
+
0,
|
|
2197
|
+
0,
|
|
2198
|
+
1,
|
|
2199
|
+
0,
|
|
2200
|
+
1,
|
|
2201
|
+
0,
|
|
2202
|
+
1
|
|
2203
|
+
]);
|
|
2204
|
+
var ATTRIBUTES = {
|
|
2205
|
+
POSITION: { size: 3, value: CUBE_POSITIONS },
|
|
2206
|
+
NORMAL: { size: 3, value: CUBE_NORMALS },
|
|
2207
|
+
TEXCOORD_0: { size: 2, value: CUBE_TEX_COORDS }
|
|
2208
|
+
};
|
|
2209
|
+
var NON_INDEXED_ATTRIBUTES = {
|
|
2210
|
+
POSITION: { size: 4, value: CUBE_NON_INDEXED_POSITIONS },
|
|
2211
|
+
// NORMAL: {size: 3, value: CUBE_NON_INDEXED_NORMALS},
|
|
2212
|
+
TEXCOORD_0: { size: 2, value: CUBE_NON_INDEXED_TEX_COORDS },
|
|
2213
|
+
COLOR_0: { size: 3, value: CUBE_NON_INDEXED_COLORS }
|
|
2214
|
+
};
|
|
2215
|
+
|
|
2216
|
+
// src/geometries/cylinder-geometry.ts
|
|
2217
|
+
var import_core16 = require("@luma.gl/core");
|
|
2218
|
+
var CylinderGeometry = class extends TruncatedConeGeometry {
|
|
2219
|
+
constructor(props = {}) {
|
|
2220
|
+
const { id = (0, import_core16.uid)("cylinder-geometry"), radius = 1 } = props;
|
|
2221
|
+
super(__spreadProps(__spreadValues({}, props), {
|
|
2222
|
+
id,
|
|
2223
|
+
bottomRadius: radius,
|
|
2224
|
+
topRadius: radius
|
|
2225
|
+
}));
|
|
2226
|
+
}
|
|
2227
|
+
};
|
|
2228
|
+
|
|
2229
|
+
// src/geometries/ico-sphere-geometry.ts
|
|
2230
|
+
var import_core17 = require("@luma.gl/core");
|
|
2231
|
+
var import_core18 = require("@math.gl/core");
|
|
2232
|
+
var ICO_POSITIONS = [-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 1, 0, -1, 0, 1, 0, 0];
|
|
2233
|
+
var ICO_INDICES = [3, 4, 5, 3, 5, 1, 3, 1, 0, 3, 0, 4, 4, 0, 2, 4, 2, 5, 2, 0, 1, 5, 2, 1];
|
|
2234
|
+
var IcoSphereGeometry = class extends Geometry {
|
|
2235
|
+
constructor(props = {}) {
|
|
2236
|
+
const { id = (0, import_core17.uid)("ico-sphere-geometry") } = props;
|
|
2237
|
+
const { indices, attributes } = tesselateIcosaHedron(props);
|
|
2238
|
+
super(__spreadProps(__spreadValues({}, props), {
|
|
2239
|
+
id,
|
|
2240
|
+
topology: "triangle-list",
|
|
2241
|
+
indices,
|
|
2242
|
+
attributes: __spreadValues(__spreadValues({}, attributes), props.attributes)
|
|
2243
|
+
}));
|
|
2244
|
+
}
|
|
2245
|
+
};
|
|
2246
|
+
function tesselateIcosaHedron(props) {
|
|
2247
|
+
const { iterations = 0 } = props;
|
|
2248
|
+
const PI = Math.PI;
|
|
2249
|
+
const PI2 = PI * 2;
|
|
2250
|
+
const positions = [...ICO_POSITIONS];
|
|
2251
|
+
let indices = [...ICO_INDICES];
|
|
2252
|
+
positions.push();
|
|
2253
|
+
indices.push();
|
|
2254
|
+
const getMiddlePoint = (() => {
|
|
2255
|
+
const pointMemo = {};
|
|
2256
|
+
return (i1, i2) => {
|
|
2257
|
+
i1 *= 3;
|
|
2258
|
+
i2 *= 3;
|
|
2259
|
+
const mini = i1 < i2 ? i1 : i2;
|
|
2260
|
+
const maxi = i1 > i2 ? i1 : i2;
|
|
2261
|
+
const key = `${mini}|${maxi}`;
|
|
2262
|
+
if (key in pointMemo) {
|
|
2263
|
+
return pointMemo[key];
|
|
2264
|
+
}
|
|
2265
|
+
const x1 = positions[i1];
|
|
2266
|
+
const y1 = positions[i1 + 1];
|
|
2267
|
+
const z1 = positions[i1 + 2];
|
|
2268
|
+
const x2 = positions[i2];
|
|
2269
|
+
const y2 = positions[i2 + 1];
|
|
2270
|
+
const z2 = positions[i2 + 2];
|
|
2271
|
+
let xm = (x1 + x2) / 2;
|
|
2272
|
+
let ym = (y1 + y2) / 2;
|
|
2273
|
+
let zm = (z1 + z2) / 2;
|
|
2274
|
+
const len = Math.sqrt(xm * xm + ym * ym + zm * zm);
|
|
2275
|
+
xm /= len;
|
|
2276
|
+
ym /= len;
|
|
2277
|
+
zm /= len;
|
|
2278
|
+
positions.push(xm, ym, zm);
|
|
2279
|
+
return pointMemo[key] = positions.length / 3 - 1;
|
|
2280
|
+
};
|
|
2281
|
+
})();
|
|
2282
|
+
for (let i = 0; i < iterations; i++) {
|
|
2283
|
+
const indices2 = [];
|
|
2284
|
+
for (let j = 0; j < indices.length; j += 3) {
|
|
2285
|
+
const a = getMiddlePoint(indices[j + 0], indices[j + 1]);
|
|
2286
|
+
const b = getMiddlePoint(indices[j + 1], indices[j + 2]);
|
|
2287
|
+
const c = getMiddlePoint(indices[j + 2], indices[j + 0]);
|
|
2288
|
+
indices2.push(c, indices[j + 0], a, a, indices[j + 1], b, b, indices[j + 2], c, a, b, c);
|
|
2289
|
+
}
|
|
2290
|
+
indices = indices2;
|
|
2291
|
+
}
|
|
2292
|
+
const normals = new Array(positions.length);
|
|
2293
|
+
const texCoords = new Array(positions.length / 3 * 2);
|
|
2294
|
+
const l = indices.length;
|
|
2295
|
+
for (let i = l - 3; i >= 0; i -= 3) {
|
|
2296
|
+
const i1 = indices[i + 0];
|
|
2297
|
+
const i2 = indices[i + 1];
|
|
2298
|
+
const i3 = indices[i + 2];
|
|
2299
|
+
const in1 = i1 * 3;
|
|
2300
|
+
const in2 = i2 * 3;
|
|
2301
|
+
const in3 = i3 * 3;
|
|
2302
|
+
const iu1 = i1 * 2;
|
|
2303
|
+
const iu2 = i2 * 2;
|
|
2304
|
+
const iu3 = i3 * 2;
|
|
2305
|
+
const x1 = positions[in1 + 0];
|
|
2306
|
+
const y1 = positions[in1 + 1];
|
|
2307
|
+
const z1 = positions[in1 + 2];
|
|
2308
|
+
const theta1 = Math.acos(z1 / Math.sqrt(x1 * x1 + y1 * y1 + z1 * z1));
|
|
2309
|
+
const phi1 = Math.atan2(y1, x1) + PI;
|
|
2310
|
+
const v1 = theta1 / PI;
|
|
2311
|
+
const u1 = 1 - phi1 / PI2;
|
|
2312
|
+
const x2 = positions[in2 + 0];
|
|
2313
|
+
const y2 = positions[in2 + 1];
|
|
2314
|
+
const z2 = positions[in2 + 2];
|
|
2315
|
+
const theta2 = Math.acos(z2 / Math.sqrt(x2 * x2 + y2 * y2 + z2 * z2));
|
|
2316
|
+
const phi2 = Math.atan2(y2, x2) + PI;
|
|
2317
|
+
const v2 = theta2 / PI;
|
|
2318
|
+
const u2 = 1 - phi2 / PI2;
|
|
2319
|
+
const x3 = positions[in3 + 0];
|
|
2320
|
+
const y3 = positions[in3 + 1];
|
|
2321
|
+
const z3 = positions[in3 + 2];
|
|
2322
|
+
const theta3 = Math.acos(z3 / Math.sqrt(x3 * x3 + y3 * y3 + z3 * z3));
|
|
2323
|
+
const phi3 = Math.atan2(y3, x3) + PI;
|
|
2324
|
+
const v3 = theta3 / PI;
|
|
2325
|
+
const u3 = 1 - phi3 / PI2;
|
|
2326
|
+
const vec1 = [x3 - x2, y3 - y2, z3 - z2];
|
|
2327
|
+
const vec2 = [x1 - x2, y1 - y2, z1 - z2];
|
|
2328
|
+
const normal = new import_core18.Vector3(vec1).cross(vec2).normalize();
|
|
2329
|
+
let newIndex;
|
|
2330
|
+
if ((u1 === 0 || u2 === 0 || u3 === 0) && (u1 === 0 || u1 > 0.5) && (u2 === 0 || u2 > 0.5) && (u3 === 0 || u3 > 0.5)) {
|
|
2331
|
+
positions.push(positions[in1 + 0], positions[in1 + 1], positions[in1 + 2]);
|
|
2332
|
+
newIndex = positions.length / 3 - 1;
|
|
2333
|
+
indices.push(newIndex);
|
|
2334
|
+
texCoords[newIndex * 2 + 0] = 1;
|
|
2335
|
+
texCoords[newIndex * 2 + 1] = v1;
|
|
2336
|
+
normals[newIndex * 3 + 0] = normal.x;
|
|
2337
|
+
normals[newIndex * 3 + 1] = normal.y;
|
|
2338
|
+
normals[newIndex * 3 + 2] = normal.z;
|
|
2339
|
+
positions.push(positions[in2 + 0], positions[in2 + 1], positions[in2 + 2]);
|
|
2340
|
+
newIndex = positions.length / 3 - 1;
|
|
2341
|
+
indices.push(newIndex);
|
|
2342
|
+
texCoords[newIndex * 2 + 0] = 1;
|
|
2343
|
+
texCoords[newIndex * 2 + 1] = v2;
|
|
2344
|
+
normals[newIndex * 3 + 0] = normal.x;
|
|
2345
|
+
normals[newIndex * 3 + 1] = normal.y;
|
|
2346
|
+
normals[newIndex * 3 + 2] = normal.z;
|
|
2347
|
+
positions.push(positions[in3 + 0], positions[in3 + 1], positions[in3 + 2]);
|
|
2348
|
+
newIndex = positions.length / 3 - 1;
|
|
2349
|
+
indices.push(newIndex);
|
|
2350
|
+
texCoords[newIndex * 2 + 0] = 1;
|
|
2351
|
+
texCoords[newIndex * 2 + 1] = v3;
|
|
2352
|
+
normals[newIndex * 3 + 0] = normal.x;
|
|
2353
|
+
normals[newIndex * 3 + 1] = normal.y;
|
|
2354
|
+
normals[newIndex * 3 + 2] = normal.z;
|
|
2355
|
+
}
|
|
2356
|
+
normals[in1 + 0] = normals[in2 + 0] = normals[in3 + 0] = normal.x;
|
|
2357
|
+
normals[in1 + 1] = normals[in2 + 1] = normals[in3 + 1] = normal.y;
|
|
2358
|
+
normals[in1 + 2] = normals[in2 + 2] = normals[in3 + 2] = normal.z;
|
|
2359
|
+
texCoords[iu1 + 0] = u1;
|
|
2360
|
+
texCoords[iu1 + 1] = v1;
|
|
2361
|
+
texCoords[iu2 + 0] = u2;
|
|
2362
|
+
texCoords[iu2 + 1] = v2;
|
|
2363
|
+
texCoords[iu3 + 0] = u3;
|
|
2364
|
+
texCoords[iu3 + 1] = v3;
|
|
2365
|
+
}
|
|
2366
|
+
return {
|
|
2367
|
+
indices: { size: 1, value: new Uint16Array(indices) },
|
|
2368
|
+
attributes: {
|
|
2369
|
+
POSITION: { size: 3, value: new Float32Array(positions) },
|
|
2370
|
+
NORMAL: { size: 3, value: new Float32Array(normals) },
|
|
2371
|
+
TEXCOORD_0: { size: 2, value: new Float32Array(texCoords) }
|
|
2372
|
+
}
|
|
2373
|
+
};
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
// src/geometries/plane-geometry.ts
|
|
2377
|
+
var import_core19 = require("@luma.gl/core");
|
|
2378
|
+
|
|
2379
|
+
// src/geometry/geometry-utils.ts
|
|
2380
|
+
function unpackIndexedGeometry(geometry) {
|
|
2381
|
+
const { indices, attributes } = geometry;
|
|
2382
|
+
if (!indices) {
|
|
2383
|
+
return geometry;
|
|
2384
|
+
}
|
|
2385
|
+
const vertexCount = indices.value.length;
|
|
2386
|
+
const unpackedAttributes = {};
|
|
2387
|
+
for (const attributeName in attributes) {
|
|
2388
|
+
const attribute = attributes[attributeName];
|
|
2389
|
+
const { constant, value, size } = attribute;
|
|
2390
|
+
if (constant || !size) {
|
|
2391
|
+
continue;
|
|
2392
|
+
}
|
|
2393
|
+
const unpackedValue = new value.constructor(vertexCount * size);
|
|
2394
|
+
for (let x = 0; x < vertexCount; ++x) {
|
|
2395
|
+
const index = indices.value[x];
|
|
2396
|
+
for (let i = 0; i < size; i++) {
|
|
2397
|
+
unpackedValue[x * size + i] = value[index * size + i];
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
unpackedAttributes[attributeName] = { size, value: unpackedValue };
|
|
2401
|
+
}
|
|
2402
|
+
return {
|
|
2403
|
+
attributes: Object.assign({}, attributes, unpackedAttributes)
|
|
2404
|
+
};
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
// src/geometries/plane-geometry.ts
|
|
2408
|
+
var PlaneGeometry = class extends Geometry {
|
|
2409
|
+
constructor(props = {}) {
|
|
2410
|
+
const { id = (0, import_core19.uid)("plane-geometry") } = props;
|
|
2411
|
+
const { indices, attributes } = tesselatePlane(props);
|
|
2412
|
+
super(__spreadProps(__spreadValues({}, props), {
|
|
2413
|
+
id,
|
|
2414
|
+
topology: "triangle-list",
|
|
2415
|
+
indices,
|
|
2416
|
+
attributes: __spreadValues(__spreadValues({}, attributes), props.attributes)
|
|
2417
|
+
}));
|
|
2418
|
+
}
|
|
2419
|
+
};
|
|
2420
|
+
function tesselatePlane(props) {
|
|
2421
|
+
const { type = "x,y", offset = 0, flipCull = false, unpack = false } = props;
|
|
2422
|
+
const coords = type.split(",");
|
|
2423
|
+
let c1len = props[`${coords[0]}len`] || 1;
|
|
2424
|
+
const c2len = props[`${coords[1]}len`] || 1;
|
|
2425
|
+
const subdivisions1 = props[`n${coords[0]}`] || 1;
|
|
2426
|
+
const subdivisions2 = props[`n${coords[1]}`] || 1;
|
|
2427
|
+
const numVertices = (subdivisions1 + 1) * (subdivisions2 + 1);
|
|
2428
|
+
const positions = new Float32Array(numVertices * 3);
|
|
2429
|
+
const normals = new Float32Array(numVertices * 3);
|
|
2430
|
+
const texCoords = new Float32Array(numVertices * 2);
|
|
2431
|
+
if (flipCull) {
|
|
2432
|
+
c1len = -c1len;
|
|
2433
|
+
}
|
|
2434
|
+
let i2 = 0;
|
|
2435
|
+
let i3 = 0;
|
|
2436
|
+
for (let z = 0; z <= subdivisions2; z++) {
|
|
2437
|
+
for (let x = 0; x <= subdivisions1; x++) {
|
|
2438
|
+
const u = x / subdivisions1;
|
|
2439
|
+
const v = z / subdivisions2;
|
|
2440
|
+
texCoords[i2 + 0] = flipCull ? 1 - u : u;
|
|
2441
|
+
texCoords[i2 + 1] = v;
|
|
2442
|
+
switch (type) {
|
|
2443
|
+
case "x,y":
|
|
2444
|
+
positions[i3 + 0] = c1len * u - c1len * 0.5;
|
|
2445
|
+
positions[i3 + 1] = c2len * v - c2len * 0.5;
|
|
2446
|
+
positions[i3 + 2] = offset;
|
|
2447
|
+
normals[i3 + 0] = 0;
|
|
2448
|
+
normals[i3 + 1] = 0;
|
|
2449
|
+
normals[i3 + 2] = flipCull ? 1 : -1;
|
|
2450
|
+
break;
|
|
2451
|
+
case "x,z":
|
|
2452
|
+
positions[i3 + 0] = c1len * u - c1len * 0.5;
|
|
2453
|
+
positions[i3 + 1] = offset;
|
|
2454
|
+
positions[i3 + 2] = c2len * v - c2len * 0.5;
|
|
2455
|
+
normals[i3 + 0] = 0;
|
|
2456
|
+
normals[i3 + 1] = flipCull ? 1 : -1;
|
|
2457
|
+
normals[i3 + 2] = 0;
|
|
2458
|
+
break;
|
|
2459
|
+
case "y,z":
|
|
2460
|
+
positions[i3 + 0] = offset;
|
|
2461
|
+
positions[i3 + 1] = c1len * u - c1len * 0.5;
|
|
2462
|
+
positions[i3 + 2] = c2len * v - c2len * 0.5;
|
|
2463
|
+
normals[i3 + 0] = flipCull ? 1 : -1;
|
|
2464
|
+
normals[i3 + 1] = 0;
|
|
2465
|
+
normals[i3 + 2] = 0;
|
|
2466
|
+
break;
|
|
2467
|
+
default:
|
|
2468
|
+
throw new Error("PlaneGeometry: unknown type");
|
|
2469
|
+
}
|
|
2470
|
+
i2 += 2;
|
|
2471
|
+
i3 += 3;
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
const numVertsAcross = subdivisions1 + 1;
|
|
2475
|
+
const indices = new Uint16Array(subdivisions1 * subdivisions2 * 6);
|
|
2476
|
+
for (let z = 0; z < subdivisions2; z++) {
|
|
2477
|
+
for (let x = 0; x < subdivisions1; x++) {
|
|
2478
|
+
const index = (z * subdivisions1 + x) * 6;
|
|
2479
|
+
indices[index + 0] = (z + 0) * numVertsAcross + x;
|
|
2480
|
+
indices[index + 1] = (z + 1) * numVertsAcross + x;
|
|
2481
|
+
indices[index + 2] = (z + 0) * numVertsAcross + x + 1;
|
|
2482
|
+
indices[index + 3] = (z + 1) * numVertsAcross + x;
|
|
2483
|
+
indices[index + 4] = (z + 1) * numVertsAcross + x + 1;
|
|
2484
|
+
indices[index + 5] = (z + 0) * numVertsAcross + x + 1;
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
const geometry = {
|
|
2488
|
+
indices: { size: 1, value: indices },
|
|
2489
|
+
attributes: {
|
|
2490
|
+
POSITION: { size: 3, value: positions },
|
|
2491
|
+
NORMAL: { size: 3, value: normals },
|
|
2492
|
+
TEXCOORD_0: { size: 2, value: texCoords }
|
|
2493
|
+
}
|
|
2494
|
+
};
|
|
2495
|
+
return unpack ? unpackIndexedGeometry(geometry) : geometry;
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2498
|
+
// src/geometries/sphere-geometry.ts
|
|
2499
|
+
var import_core20 = require("@luma.gl/core");
|
|
2500
|
+
var SphereGeometry = class extends Geometry {
|
|
2501
|
+
constructor(props = {}) {
|
|
2502
|
+
const { id = (0, import_core20.uid)("sphere-geometry") } = props;
|
|
2503
|
+
const { indices, attributes } = tesselateSphere(props);
|
|
2504
|
+
super(__spreadProps(__spreadValues({}, props), {
|
|
2505
|
+
id,
|
|
2506
|
+
topology: "triangle-list",
|
|
2507
|
+
indices,
|
|
2508
|
+
attributes: __spreadValues(__spreadValues({}, attributes), props.attributes)
|
|
2509
|
+
}));
|
|
2510
|
+
}
|
|
2511
|
+
};
|
|
2512
|
+
function tesselateSphere(props) {
|
|
2513
|
+
const { nlat = 10, nlong = 10 } = props;
|
|
2514
|
+
const startLat = 0;
|
|
2515
|
+
const endLat = Math.PI;
|
|
2516
|
+
const latRange = endLat - startLat;
|
|
2517
|
+
const startLong = 0;
|
|
2518
|
+
const endLong = 2 * Math.PI;
|
|
2519
|
+
const longRange = endLong - startLong;
|
|
2520
|
+
const numVertices = (nlat + 1) * (nlong + 1);
|
|
2521
|
+
const radius = (n1, n2, n3, u, v) => props.radius || 1;
|
|
2522
|
+
const positions = new Float32Array(numVertices * 3);
|
|
2523
|
+
const normals = new Float32Array(numVertices * 3);
|
|
2524
|
+
const texCoords = new Float32Array(numVertices * 2);
|
|
2525
|
+
const IndexType = numVertices > 65535 ? Uint32Array : Uint16Array;
|
|
2526
|
+
const indices = new IndexType(nlat * nlong * 6);
|
|
2527
|
+
for (let y = 0; y <= nlat; y++) {
|
|
2528
|
+
for (let x = 0; x <= nlong; x++) {
|
|
2529
|
+
const u = x / nlong;
|
|
2530
|
+
const v = y / nlat;
|
|
2531
|
+
const index = x + y * (nlong + 1);
|
|
2532
|
+
const i2 = index * 2;
|
|
2533
|
+
const i3 = index * 3;
|
|
2534
|
+
const theta = longRange * u;
|
|
2535
|
+
const phi = latRange * v;
|
|
2536
|
+
const sinTheta = Math.sin(theta);
|
|
2537
|
+
const cosTheta = Math.cos(theta);
|
|
2538
|
+
const sinPhi = Math.sin(phi);
|
|
2539
|
+
const cosPhi = Math.cos(phi);
|
|
2540
|
+
const ux = cosTheta * sinPhi;
|
|
2541
|
+
const uy = cosPhi;
|
|
2542
|
+
const uz = sinTheta * sinPhi;
|
|
2543
|
+
const r = radius(ux, uy, uz, u, v);
|
|
2544
|
+
positions[i3 + 0] = r * ux;
|
|
2545
|
+
positions[i3 + 1] = r * uy;
|
|
2546
|
+
positions[i3 + 2] = r * uz;
|
|
2547
|
+
normals[i3 + 0] = ux;
|
|
2548
|
+
normals[i3 + 1] = uy;
|
|
2549
|
+
normals[i3 + 2] = uz;
|
|
2550
|
+
texCoords[i2 + 0] = u;
|
|
2551
|
+
texCoords[i2 + 1] = 1 - v;
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
const numVertsAround = nlong + 1;
|
|
2555
|
+
for (let x = 0; x < nlong; x++) {
|
|
2556
|
+
for (let y = 0; y < nlat; y++) {
|
|
2557
|
+
const index = (x * nlat + y) * 6;
|
|
2558
|
+
indices[index + 0] = y * numVertsAround + x;
|
|
2559
|
+
indices[index + 1] = y * numVertsAround + x + 1;
|
|
2560
|
+
indices[index + 2] = (y + 1) * numVertsAround + x;
|
|
2561
|
+
indices[index + 3] = (y + 1) * numVertsAround + x;
|
|
2562
|
+
indices[index + 4] = y * numVertsAround + x + 1;
|
|
2563
|
+
indices[index + 5] = (y + 1) * numVertsAround + x + 1;
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
return {
|
|
2567
|
+
indices: { size: 1, value: indices },
|
|
2568
|
+
attributes: {
|
|
2569
|
+
POSITION: { size: 3, value: positions },
|
|
2570
|
+
NORMAL: { size: 3, value: normals },
|
|
2571
|
+
TEXCOORD_0: { size: 2, value: texCoords }
|
|
2572
|
+
}
|
|
2573
|
+
};
|
|
2574
|
+
}
|