@luma.gl/gltf 9.0.0-alpha.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/LICENSE +34 -0
  2. package/README.md +3 -0
  3. package/dist/dist.dev.js +15822 -0
  4. package/dist/gltf/create-gltf-model.d.ts +13 -0
  5. package/dist/gltf/create-gltf-model.d.ts.map +1 -0
  6. package/dist/gltf/create-gltf-model.js +105 -0
  7. package/dist/gltf/create-gltf-model.js.map +1 -0
  8. package/dist/gltf/create-gltf-objects.d.ts +9 -0
  9. package/dist/gltf/create-gltf-objects.d.ts.map +1 -0
  10. package/dist/gltf/create-gltf-objects.js +11 -0
  11. package/dist/gltf/create-gltf-objects.js.map +1 -0
  12. package/dist/gltf/gltf-animator.d.ts +35 -0
  13. package/dist/gltf/gltf-animator.d.ts.map +1 -0
  14. package/dist/gltf/gltf-animator.js +223 -0
  15. package/dist/gltf/gltf-animator.js.map +1 -0
  16. package/dist/gltf/gltf-instantiator.d.ts +45 -0
  17. package/dist/gltf/gltf-instantiator.d.ts.map +1 -0
  18. package/dist/gltf/gltf-instantiator.js +180 -0
  19. package/dist/gltf/gltf-instantiator.js.map +1 -0
  20. package/dist/index.cjs +635 -0
  21. package/dist/index.d.ts +6 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +4 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/pbr/parse-pbr-material.d.ts +26 -0
  26. package/dist/pbr/parse-pbr-material.d.ts.map +1 -0
  27. package/dist/pbr/parse-pbr-material.js +137 -0
  28. package/dist/pbr/parse-pbr-material.js.map +1 -0
  29. package/dist/pbr/pbr-environment.d.ts +18 -0
  30. package/dist/pbr/pbr-environment.d.ts.map +1 -0
  31. package/dist/pbr/pbr-environment.js +64 -0
  32. package/dist/pbr/pbr-environment.js.map +1 -0
  33. package/dist.min.js +1253 -0
  34. package/package.json +53 -0
  35. package/src/gltf/create-gltf-model.ts +120 -0
  36. package/src/gltf/create-gltf-objects.ts +18 -0
  37. package/src/gltf/gltf-animator.ts +223 -0
  38. package/src/gltf/gltf-instantiator.ts +225 -0
  39. package/src/index.ts +10 -0
  40. package/src/pbr/parse-pbr-material.ts +398 -0
  41. package/src/pbr/pbr-environment.ts +88 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,635 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, { get: all[name], enumerable: true });
22
+ };
23
+ var __copyProps = (to, from, except, desc) => {
24
+ if (from && typeof from === "object" || typeof from === "function") {
25
+ for (let key of __getOwnPropNames(from))
26
+ if (!__hasOwnProp.call(to, key) && key !== except)
27
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
28
+ }
29
+ return to;
30
+ };
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
+
33
+ // src/index.ts
34
+ var src_exports = {};
35
+ __export(src_exports, {
36
+ GLTFAnimator: () => GLTFAnimator,
37
+ createScenegraphsFromGLTF: () => createScenegraphsFromGLTF,
38
+ parsePBRMaterial: () => parsePBRMaterial
39
+ });
40
+ module.exports = __toCommonJS(src_exports);
41
+
42
+ // src/pbr/parse-pbr-material.ts
43
+ var import_core = require("@luma.gl/core");
44
+ var import_constants = require("@luma.gl/constants");
45
+ function parsePBRMaterial(device, material, attributes, options) {
46
+ const parsedMaterial = {
47
+ defines: {
48
+ // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)
49
+ MANUAL_SRGB: 1,
50
+ SRGB_FAST_APPROXIMATION: 1
51
+ },
52
+ bindings: {},
53
+ uniforms: {
54
+ // TODO: find better values?
55
+ u_Camera: [0, 0, 0],
56
+ // Model should override
57
+ u_MetallicRoughnessValues: [1, 1]
58
+ // Default is 1 and 1
59
+ },
60
+ parameters: {},
61
+ glParameters: {},
62
+ generatedTextures: []
63
+ };
64
+ if (device.features.has("glsl-texture-lod")) {
65
+ parsedMaterial.defines.USE_TEX_LOD = 1;
66
+ }
67
+ const { imageBasedLightingEnvironment } = options;
68
+ if (imageBasedLightingEnvironment) {
69
+ parsedMaterial.bindings.u_DiffuseEnvSampler = imageBasedLightingEnvironment.diffuseEnvSampler;
70
+ parsedMaterial.bindings.u_SpecularEnvSampler = imageBasedLightingEnvironment.specularEnvSampler;
71
+ parsedMaterial.bindings.u_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture;
72
+ parsedMaterial.uniforms.u_ScaleIBLAmbient = [1, 1];
73
+ }
74
+ if (options == null ? void 0 : options.pbrDebug) {
75
+ parsedMaterial.defines.PBR_DEBUG = 1;
76
+ parsedMaterial.uniforms.u_ScaleDiffBaseMR = [0, 0, 0, 0];
77
+ parsedMaterial.uniforms.u_ScaleFGDSpec = [0, 0, 0, 0];
78
+ }
79
+ if (attributes.NORMAL)
80
+ parsedMaterial.defines.HAS_NORMALS = 1;
81
+ if (attributes.TANGENT && (options == null ? void 0 : options.useTangents))
82
+ parsedMaterial.defines.HAS_TANGENTS = 1;
83
+ if (attributes.TEXCOORD_0)
84
+ parsedMaterial.defines.HAS_UV = 1;
85
+ if (options == null ? void 0 : options.imageBasedLightingEnvironment)
86
+ parsedMaterial.defines.USE_IBL = 1;
87
+ if (options == null ? void 0 : options.lights)
88
+ parsedMaterial.defines.USE_LIGHTS = 1;
89
+ if (material) {
90
+ parseMaterial(device, material, parsedMaterial);
91
+ }
92
+ return parsedMaterial;
93
+ }
94
+ function parseMaterial(device, material, parsedMaterial) {
95
+ parsedMaterial.uniforms.pbr_uUnlit = Boolean(material.unlit);
96
+ if (material.pbrMetallicRoughness) {
97
+ parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);
98
+ }
99
+ if (material.normalTexture) {
100
+ addTexture(device, material.normalTexture, "u_NormalSampler", "HAS_NORMALMAP", parsedMaterial);
101
+ const { scale = 1 } = material.normalTexture;
102
+ parsedMaterial.uniforms.u_NormalScale = scale;
103
+ }
104
+ if (material.occlusionTexture) {
105
+ addTexture(
106
+ device,
107
+ material.occlusionTexture,
108
+ "u_OcclusionSampler",
109
+ "HAS_OCCLUSIONMAP",
110
+ parsedMaterial
111
+ );
112
+ const { strength = 1 } = material.occlusionTexture;
113
+ parsedMaterial.uniforms.u_OcclusionStrength = strength;
114
+ }
115
+ if (material.emissiveTexture) {
116
+ addTexture(
117
+ device,
118
+ material.emissiveTexture,
119
+ "u_EmissiveSampler",
120
+ "HAS_EMISSIVEMAP",
121
+ parsedMaterial
122
+ );
123
+ parsedMaterial.uniforms.u_EmissiveFactor = material.emissiveFactor || [0, 0, 0];
124
+ }
125
+ switch (material.alphaMode) {
126
+ case "MASK":
127
+ const { alphaCutoff = 0.5 } = material;
128
+ parsedMaterial.defines.ALPHA_CUTOFF = 1;
129
+ parsedMaterial.uniforms.u_AlphaCutoff = alphaCutoff;
130
+ break;
131
+ case "BLEND":
132
+ import_core.log.warn("glTF BLEND alphaMode might not work well because it requires mesh sorting")();
133
+ parsedMaterial.parameters.blendColorOperation = "add";
134
+ parsedMaterial.parameters.blendColorSrcFactor = "src-alpha";
135
+ parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
136
+ parsedMaterial.parameters.blendAlphaOperation = "add";
137
+ parsedMaterial.parameters.blendAlphaSrcFactor = "one";
138
+ parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
139
+ parsedMaterial.glParameters.blend = true;
140
+ parsedMaterial.glParameters.blendEquation = import_constants.GL.FUNC_ADD;
141
+ parsedMaterial.glParameters.blendFunc = [import_constants.GL.SRC_ALPHA, import_constants.GL.ONE_MINUS_SRC_ALPHA, import_constants.GL.ONE, import_constants.GL.ONE_MINUS_SRC_ALPHA];
142
+ break;
143
+ }
144
+ }
145
+ function parsePbrMetallicRoughness(device, pbrMetallicRoughness, parsedMaterial) {
146
+ if (pbrMetallicRoughness.baseColorTexture) {
147
+ addTexture(
148
+ device,
149
+ pbrMetallicRoughness.baseColorTexture,
150
+ "u_BaseColorSampler",
151
+ "HAS_BASECOLORMAP",
152
+ parsedMaterial
153
+ );
154
+ }
155
+ parsedMaterial.uniforms.u_BaseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
156
+ if (pbrMetallicRoughness.metallicRoughnessTexture) {
157
+ addTexture(
158
+ device,
159
+ pbrMetallicRoughness.metallicRoughnessTexture,
160
+ "u_MetallicRoughnessSampler",
161
+ "HAS_METALROUGHNESSMAP",
162
+ parsedMaterial
163
+ );
164
+ }
165
+ const { metallicFactor = 1, roughnessFactor = 1 } = pbrMetallicRoughness;
166
+ parsedMaterial.uniforms.u_MetallicRoughnessValues = [metallicFactor, roughnessFactor];
167
+ }
168
+ function addTexture(device, gltfTexture, uniformName, define = null, parsedMaterial) {
169
+ var _a, _b;
170
+ const parameters = ((_b = (_a = gltfTexture == null ? void 0 : gltfTexture.texture) == null ? void 0 : _a.sampler) == null ? void 0 : _b.parameters) || {};
171
+ const image = gltfTexture.texture.source.image;
172
+ let textureOptions;
173
+ let specialTextureParameters = {};
174
+ if (image.compressed) {
175
+ textureOptions = image;
176
+ specialTextureParameters = {
177
+ [import_constants.GL.TEXTURE_MIN_FILTER]: image.data.length > 1 ? import_constants.GL.LINEAR_MIPMAP_NEAREST : import_constants.GL.LINEAR
178
+ };
179
+ } else {
180
+ textureOptions = { data: image };
181
+ }
182
+ const texture = device.createTexture(__spreadValues({
183
+ id: gltfTexture.uniformName || gltfTexture.id,
184
+ parameters: __spreadValues(__spreadValues({}, parameters), specialTextureParameters),
185
+ pixelStore: {
186
+ [import_constants.GL.UNPACK_FLIP_Y_WEBGL]: false
187
+ }
188
+ }, textureOptions));
189
+ parsedMaterial.bindings[uniformName] = texture;
190
+ if (define)
191
+ parsedMaterial.defines[define] = 1;
192
+ parsedMaterial.generatedTextures.push(texture);
193
+ }
194
+
195
+ // src/gltf/gltf-instantiator.ts
196
+ var import_engine2 = require("@luma.gl/engine");
197
+ var import_webgl = require("@luma.gl/webgl");
198
+ var import_core5 = require("@math.gl/core");
199
+
200
+ // src/gltf/gltf-animator.ts
201
+ var import_core2 = require("@luma.gl/core");
202
+ var import_core3 = require("@math.gl/core");
203
+ var ATTRIBUTE_TYPE_TO_COMPONENTS = {
204
+ SCALAR: 1,
205
+ VEC2: 2,
206
+ VEC3: 3,
207
+ VEC4: 4,
208
+ MAT2: 4,
209
+ MAT3: 9,
210
+ MAT4: 16
211
+ };
212
+ var ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY = {
213
+ 5120: Int8Array,
214
+ 5121: Uint8Array,
215
+ 5122: Int16Array,
216
+ 5123: Uint16Array,
217
+ 5125: Uint32Array,
218
+ 5126: Float32Array
219
+ };
220
+ var GLTFAnimation = class {
221
+ constructor(props) {
222
+ this.startTime = 0;
223
+ this.playing = true;
224
+ this.speed = 1;
225
+ this.channels = [];
226
+ Object.assign(this, props);
227
+ }
228
+ animate(timeMs) {
229
+ if (!this.playing) {
230
+ return;
231
+ }
232
+ const absTime = timeMs / 1e3;
233
+ const time = (absTime - this.startTime) * this.speed;
234
+ this.channels.forEach(({ sampler, target, path }) => {
235
+ interpolate(time, sampler, target, path);
236
+ applyTranslationRotationScale(target, target._node);
237
+ });
238
+ }
239
+ };
240
+ var GLTFAnimator = class {
241
+ constructor(gltf) {
242
+ this.animations = gltf.animations.map((animation, index) => {
243
+ const name = animation.name || `Animation-${index}`;
244
+ const samplers = animation.samplers.map(({ input, interpolation = "LINEAR", output }) => ({
245
+ input: accessorToJsArray(gltf.accessors[input]),
246
+ interpolation,
247
+ output: accessorToJsArray(gltf.accessors[output])
248
+ }));
249
+ const channels = animation.channels.map(({ sampler, target }) => ({
250
+ sampler: samplers[sampler],
251
+ target: gltf.nodes[target.node],
252
+ path: target.path
253
+ }));
254
+ return new GLTFAnimation({ name, channels });
255
+ });
256
+ }
257
+ /** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */
258
+ animate(time) {
259
+ this.setTime(time);
260
+ }
261
+ setTime(time) {
262
+ this.animations.forEach((animation) => animation.animate(time));
263
+ }
264
+ getAnimations() {
265
+ return this.animations;
266
+ }
267
+ };
268
+ function accessorToJsArray(accessor) {
269
+ if (!accessor._animation) {
270
+ const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[accessor.componentType];
271
+ const components = ATTRIBUTE_TYPE_TO_COMPONENTS[accessor.type];
272
+ const length = components * accessor.count;
273
+ const { buffer, byteOffset } = accessor.bufferView.data;
274
+ const array = new ArrayType(buffer, byteOffset + (accessor.byteOffset || 0), length);
275
+ if (components === 1) {
276
+ accessor._animation = Array.from(array);
277
+ } else {
278
+ const slicedArray = [];
279
+ for (let i = 0; i < array.length; i += components) {
280
+ slicedArray.push(Array.from(array.slice(i, i + components)));
281
+ }
282
+ accessor._animation = slicedArray;
283
+ }
284
+ }
285
+ return accessor._animation;
286
+ }
287
+ var helperMatrix = new import_core3.Matrix4();
288
+ function applyTranslationRotationScale(gltfNode, node) {
289
+ node.matrix.identity();
290
+ if (gltfNode.translation) {
291
+ node.matrix.translate(gltfNode.translation);
292
+ }
293
+ if (gltfNode.rotation) {
294
+ const rotationMatrix = helperMatrix.fromQuaternion(gltfNode.rotation);
295
+ node.matrix.multiplyRight(rotationMatrix);
296
+ }
297
+ if (gltfNode.scale) {
298
+ node.matrix.scale(gltfNode.scale);
299
+ }
300
+ }
301
+ var quaternion = new import_core3.Quaternion();
302
+ function linearInterpolate(target, path, start, stop, ratio) {
303
+ if (path === "rotation") {
304
+ quaternion.slerp({ start, target: stop, ratio });
305
+ for (let i = 0; i < quaternion.length; i++) {
306
+ target[path][i] = quaternion[i];
307
+ }
308
+ } else {
309
+ for (let i = 0; i < start.length; i++) {
310
+ target[path][i] = ratio * stop[i] + (1 - ratio) * start[i];
311
+ }
312
+ }
313
+ }
314
+ function cubicsplineInterpolate(target, path, { p0, outTangent0, inTangent1, p1, tDiff, ratio: t }) {
315
+ for (let i = 0; i < target[path].length; i++) {
316
+ const m0 = outTangent0[i] * tDiff;
317
+ const m1 = inTangent1[i] * tDiff;
318
+ target[path][i] = (2 * Math.pow(t, 3) - 3 * Math.pow(t, 2) + 1) * p0[i] + (Math.pow(t, 3) - 2 * Math.pow(t, 2) + t) * m0 + (-2 * Math.pow(t, 3) + 3 * Math.pow(t, 2)) * p1[i] + (Math.pow(t, 3) - Math.pow(t, 2)) * m1;
319
+ }
320
+ }
321
+ function stepInterpolate(target, path, value) {
322
+ for (let i = 0; i < value.length; i++) {
323
+ target[path][i] = value[i];
324
+ }
325
+ }
326
+ function interpolate(time, { input, interpolation, output }, target, path) {
327
+ const maxTime = input[input.length - 1];
328
+ const animationTime = time % maxTime;
329
+ const nextIndex = input.findIndex((t) => t >= animationTime);
330
+ const previousIndex = Math.max(0, nextIndex - 1);
331
+ if (!Array.isArray(target[path])) {
332
+ switch (path) {
333
+ case "translation":
334
+ target[path] = [0, 0, 0];
335
+ break;
336
+ case "rotation":
337
+ target[path] = [0, 0, 0, 1];
338
+ break;
339
+ case "scale":
340
+ target[path] = [1, 1, 1];
341
+ break;
342
+ default:
343
+ import_core2.log.warn(`Bad animation path ${path}`)();
344
+ }
345
+ }
346
+ (0, import_core2.assert)(target[path].length === output[previousIndex].length);
347
+ const previousTime = input[previousIndex];
348
+ const nextTime = input[nextIndex];
349
+ switch (interpolation) {
350
+ case "STEP":
351
+ stepInterpolate(target, path, output[previousIndex]);
352
+ break;
353
+ case "LINEAR":
354
+ if (nextTime > previousTime) {
355
+ const ratio = (animationTime - previousTime) / (nextTime - previousTime);
356
+ linearInterpolate(target, path, output[previousIndex], output[nextIndex], ratio);
357
+ }
358
+ break;
359
+ case "CUBICSPLINE":
360
+ if (nextTime > previousTime) {
361
+ const ratio = (animationTime - previousTime) / (nextTime - previousTime);
362
+ const tDiff = nextTime - previousTime;
363
+ const p0 = output[3 * previousIndex + 1];
364
+ const outTangent0 = output[3 * previousIndex + 2];
365
+ const inTangent1 = output[3 * nextIndex + 0];
366
+ const p1 = output[3 * nextIndex + 1];
367
+ cubicsplineInterpolate(target, path, { p0, outTangent0, inTangent1, p1, tDiff, ratio });
368
+ }
369
+ break;
370
+ default:
371
+ import_core2.log.warn(`Interpolation ${interpolation} not supported`)();
372
+ break;
373
+ }
374
+ }
375
+
376
+ // src/gltf/create-gltf-model.ts
377
+ var import_core4 = require("@luma.gl/core");
378
+ var import_shadertools = require("@luma.gl/shadertools");
379
+ var import_engine = require("@luma.gl/engine");
380
+ var vs = `
381
+ #pragma vscode_glsllint_stage: vert
382
+ #if (__VERSION__ < 300)
383
+ #define _attr attribute
384
+ #else
385
+ #define _attr in
386
+ #endif
387
+
388
+ // _attr vec4 POSITION;
389
+ _attr vec4 positions;
390
+
391
+ #ifdef HAS_NORMALS
392
+ // _attr vec4 NORMAL;
393
+ _attr vec4 normals;
394
+ #endif
395
+
396
+ #ifdef HAS_TANGENTS
397
+ _attr vec4 TANGENT;
398
+ #endif
399
+
400
+ #ifdef HAS_UV
401
+ // _attr vec2 TEXCOORD_0;
402
+ _attr vec2 texCoords;
403
+ #endif
404
+
405
+ void main(void) {
406
+ vec4 _NORMAL = vec4(0.);
407
+ vec4 _TANGENT = vec4(0.);
408
+ vec2 _TEXCOORD_0 = vec2(0.);
409
+
410
+ #ifdef HAS_NORMALS
411
+ _NORMAL = normals;
412
+ #endif
413
+
414
+ #ifdef HAS_TANGENTS
415
+ _TANGENT = TANGENT;
416
+ #endif
417
+
418
+ #ifdef HAS_UV
419
+ _TEXCOORD_0 = texCoords;
420
+ #endif
421
+
422
+ pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);
423
+ gl_Position = u_MVPMatrix * positions;
424
+ }
425
+ `;
426
+ var fs = `
427
+ #pragma vscode_glsllint_stage: frag
428
+ #if (__VERSION__ < 300)
429
+ #define fragmentColor gl_FragColor
430
+ #else
431
+ out vec4 fragmentColor;
432
+ #endif
433
+
434
+ void main(void) {
435
+ vec3 pos = pbr_vPosition;
436
+ fragmentColor = pbr_filterColor(vec4(1.0));
437
+ }
438
+ `;
439
+ function createGLTFModel(device, options) {
440
+ const { id, geometry, material, vertexCount, materialOptions, modelOptions } = options;
441
+ const parsedMaterial = parsePBRMaterial(device, material, geometry.attributes, materialOptions);
442
+ import_core4.log.info(4, "createGLTFModel defines: ", parsedMaterial.defines)();
443
+ const managedResources = [];
444
+ const parameters = {
445
+ depthWriteEnabled: true,
446
+ depthCompare: "less",
447
+ depthFormat: "depth24plus",
448
+ cullMode: "back"
449
+ };
450
+ const modelProps = __spreadValues({
451
+ id,
452
+ geometry,
453
+ topology: geometry.topology,
454
+ vertexCount,
455
+ modules: [import_shadertools.pbr],
456
+ defines: parsedMaterial.defines,
457
+ // parameters: parsedMaterial.parameters,
458
+ parameters,
459
+ // TODO use/merge parsedMaterial
460
+ vs: addVersionToShader(device, vs),
461
+ fs: addVersionToShader(device, fs),
462
+ bindings: parsedMaterial.bindings,
463
+ uniforms: parsedMaterial.uniforms
464
+ }, modelOptions);
465
+ const model = new import_engine.Model(device, modelProps);
466
+ return new import_engine.ModelNode({ managedResources, model });
467
+ }
468
+ function addVersionToShader(device, source) {
469
+ return device.info.type === "webgl2" ? `#version 300 es
470
+ ${source}` : source;
471
+ }
472
+
473
+ // src/gltf/gltf-instantiator.ts
474
+ var DEFAULT_OPTIONS = {
475
+ modelOptions: {},
476
+ pbrDebug: false,
477
+ imageBasedLightingEnvironment: null,
478
+ lights: true,
479
+ useTangents: false
480
+ };
481
+ var GLTFInstantiator = class {
482
+ constructor(device, options = {}) {
483
+ this.device = import_webgl.WebGLDevice.attach(device);
484
+ this.options = __spreadValues(__spreadValues({}, DEFAULT_OPTIONS), options);
485
+ }
486
+ instantiate(gltf) {
487
+ this.gltf = gltf;
488
+ const scenes = (gltf.scenes || []).map((scene) => this.createScene(scene));
489
+ return scenes;
490
+ }
491
+ createAnimator() {
492
+ if (Array.isArray(this.gltf.animations)) {
493
+ return new GLTFAnimator(this.gltf);
494
+ }
495
+ return null;
496
+ }
497
+ createScene(gltfScene) {
498
+ const gltfNodes = gltfScene.nodes || [];
499
+ const nodes = gltfNodes.map((node) => this.createNode(node));
500
+ const scene = new import_engine2.GroupNode({
501
+ id: gltfScene.name || gltfScene.id,
502
+ children: nodes
503
+ });
504
+ return scene;
505
+ }
506
+ createNode(gltfNode) {
507
+ if (!gltfNode._node) {
508
+ const gltfChildren = gltfNode.children || [];
509
+ const children = gltfChildren.map((child) => this.createNode(child));
510
+ if (gltfNode.mesh) {
511
+ children.push(this.createMesh(gltfNode.mesh));
512
+ }
513
+ const node = new import_engine2.GroupNode({
514
+ id: gltfNode.name || gltfNode.id,
515
+ children
516
+ });
517
+ if (gltfNode.matrix) {
518
+ node.setMatrix(gltfNode.matrix);
519
+ } else {
520
+ node.matrix.identity();
521
+ if (gltfNode.translation) {
522
+ node.matrix.translate(gltfNode.translation);
523
+ }
524
+ if (gltfNode.rotation) {
525
+ const rotationMatrix = new import_core5.Matrix4().fromQuaternion(gltfNode.rotation);
526
+ node.matrix.multiplyRight(rotationMatrix);
527
+ }
528
+ if (gltfNode.scale) {
529
+ node.matrix.scale(gltfNode.scale);
530
+ }
531
+ }
532
+ gltfNode._node = node;
533
+ }
534
+ return gltfNode._node;
535
+ }
536
+ createMesh(gltfMesh) {
537
+ if (!gltfMesh._mesh) {
538
+ const gltfPrimitives = gltfMesh.primitives || [];
539
+ const primitives = gltfPrimitives.map(
540
+ (gltfPrimitive, i) => this.createPrimitive(gltfPrimitive, i, gltfMesh)
541
+ );
542
+ const mesh = new import_engine2.GroupNode({
543
+ id: gltfMesh.name || gltfMesh.id,
544
+ children: primitives
545
+ });
546
+ gltfMesh._mesh = mesh;
547
+ }
548
+ return gltfMesh._mesh;
549
+ }
550
+ createPrimitive(gltfPrimitive, i, gltfMesh) {
551
+ const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${i}`;
552
+ const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);
553
+ const vertexCount = gltfPrimitive.indices ? gltfPrimitive.indices.count : this.getVertexCount(gltfPrimitive.attributes);
554
+ const modelNode = createGLTFModel(this.device, {
555
+ id,
556
+ geometry: this.createGeometry(id, gltfPrimitive, topology),
557
+ material: gltfPrimitive.material,
558
+ materialOptions: this.options,
559
+ modelOptions: this.options.modelOptions,
560
+ vertexCount
561
+ });
562
+ modelNode.bounds = [gltfPrimitive.attributes.POSITION.min, gltfPrimitive.attributes.POSITION.max];
563
+ return modelNode;
564
+ }
565
+ getVertexCount(attributes) {
566
+ throw new Error("getVertexCount not implemented");
567
+ }
568
+ createGeometry(id, gltfPrimitive, topology) {
569
+ const attributes = {};
570
+ for (const [attributeName, attribute] of Object.entries(gltfPrimitive.attributes)) {
571
+ const { components: size, value } = attribute;
572
+ attributes[attributeName] = { size, value };
573
+ }
574
+ ;
575
+ return new import_engine2.Geometry({
576
+ id,
577
+ topology,
578
+ indices: gltfPrimitive.indices.value,
579
+ attributes
580
+ });
581
+ }
582
+ createBuffer(attribute, usage) {
583
+ if (!attribute.bufferView) {
584
+ attribute.bufferView = {};
585
+ }
586
+ const { bufferView } = attribute;
587
+ if (!bufferView.lumaBuffers) {
588
+ bufferView.lumaBuffers = {};
589
+ }
590
+ if (!bufferView.lumaBuffers[usage]) {
591
+ bufferView.lumaBuffers[usage] = this.device.createBuffer({
592
+ id: `from-${bufferView.id}`,
593
+ // Draco decoded files have attribute.value
594
+ data: bufferView.data || attribute.value
595
+ });
596
+ }
597
+ return bufferView.lumaBuffers[usage];
598
+ }
599
+ // TODO - create sampler in WebGL2
600
+ createSampler(gltfSampler) {
601
+ return gltfSampler;
602
+ }
603
+ // Helper methods (move to GLTFLoader.resolve...?)
604
+ needsPOT() {
605
+ return false;
606
+ }
607
+ };
608
+ function convertGLDrawModeToTopology(drawMode) {
609
+ switch (drawMode) {
610
+ case 0 /* POINTS */:
611
+ return "point-list";
612
+ case 1 /* LINES */:
613
+ return "line-list";
614
+ case 3 /* LINE_STRIP */:
615
+ return "line-strip";
616
+ case 2 /* LINE_LOOP */:
617
+ return "line-loop-webgl";
618
+ case 4 /* TRIANGLES */:
619
+ return "triangle-list";
620
+ case 5 /* TRIANGLE_STRIP */:
621
+ return "triangle-strip";
622
+ case 6 /* TRIANGLE_FAN */:
623
+ return "triangle-fan-webgl";
624
+ default:
625
+ throw new Error(drawMode);
626
+ }
627
+ }
628
+
629
+ // src/gltf/create-gltf-objects.ts
630
+ function createScenegraphsFromGLTF(device, gltf, options) {
631
+ const instantiator = new GLTFInstantiator(device, options);
632
+ const scenes = instantiator.instantiate(gltf);
633
+ const animator = instantiator.createAnimator();
634
+ return { scenes, animator };
635
+ }
@@ -0,0 +1,6 @@
1
+ export type { PBREnvironment } from './pbr/pbr-environment';
2
+ export type { ParsePBRMaterialOptions, ParsedPBRMaterial } from './pbr/parse-pbr-material';
3
+ export { parsePBRMaterial } from './pbr/parse-pbr-material';
4
+ export { createScenegraphsFromGLTF } from './gltf/create-gltf-objects';
5
+ export { GLTFAnimator } from './gltf/gltf-animator';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAC1D,YAAY,EAAC,uBAAuB,EAAE,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AACzF,OAAO,EAAC,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAG1D,OAAO,EAAC,yBAAyB,EAAC,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAC,YAAY,EAAC,MAAM,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { parsePBRMaterial } from "./pbr/parse-pbr-material.js";
2
+ export { createScenegraphsFromGLTF } from "./gltf/create-gltf-objects.js";
3
+ export { GLTFAnimator } from "./gltf/gltf-animator.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["parsePBRMaterial","createScenegraphsFromGLTF","GLTFAnimator"],"sources":["../src/index.ts"],"sourcesContent":["// luma.gl, MIT license\n\nexport type {PBREnvironment} from './pbr/pbr-environment';\nexport type {ParsePBRMaterialOptions, ParsedPBRMaterial} from './pbr/parse-pbr-material';\nexport {parsePBRMaterial} from './pbr/parse-pbr-material';\n\n// glTF Scenegraph Instantiator\nexport {createScenegraphsFromGLTF} from './gltf/create-gltf-objects';\nexport {GLTFAnimator} from './gltf/gltf-animator';\n\n"],"mappings":"SAIQA,gBAAgB;AAAA,SAGhBC,yBAAyB;AAAA,SACzBC,YAAY"}
@@ -0,0 +1,26 @@
1
+ import type { Device, Texture, Binding, Parameters } from '@luma.gl/core';
2
+ import { PBREnvironment } from './pbr-environment';
3
+ export type ParsePBRMaterialOptions = {
4
+ /** Debug PBR shader */
5
+ pbrDebug?: boolean;
6
+ /** Enable lights */
7
+ lights?: any;
8
+ /** Use tangents */
9
+ useTangents?: boolean;
10
+ /** provide an image based (texture cube) lighting environment */
11
+ imageBasedLightingEnvironment?: PBREnvironment;
12
+ };
13
+ export type ParsedPBRMaterial = {
14
+ readonly defines: Record<string, number | boolean>;
15
+ readonly bindings: Record<string, Binding>;
16
+ readonly uniforms: Record<string, any>;
17
+ readonly parameters: Parameters;
18
+ readonly glParameters: Record<string, any>;
19
+ /** List of all generated textures, makes it easy to destroy them later */
20
+ readonly generatedTextures: Texture[];
21
+ };
22
+ /**
23
+ * Parses a GLTF material definition into uniforms and parameters for the PBR shader module
24
+ */
25
+ export declare function parsePBRMaterial(device: Device, material: any, attributes: Record<string, any>, options: ParsePBRMaterialOptions): ParsedPBRMaterial;
26
+ //# sourceMappingURL=parse-pbr-material.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-pbr-material.d.ts","sourceRoot":"","sources":["../../src/pbr/parse-pbr-material.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAC,MAAM,eAAe,CAAC;AAGxE,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAIjD,MAAM,MAAM,uBAAuB,GAAG;IACpC,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB;IACpB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,mBAAmB;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iEAAiE;IACjE,6BAA6B,CAAC,EAAE,cAAc,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3C,0EAA0E;IAC1E,QAAQ,CAAC,iBAAiB,EAAE,OAAO,EAAE,CAAC;CACvC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,QAAQ,KAAA,EACR,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/B,OAAO,EAAE,uBAAuB,GAC/B,iBAAiB,CAoDnB"}