@luma.gl/gltf 9.2.6 → 9.3.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +1362 -313
- package/dist/dist.min.js +98 -46
- package/dist/gltf/animations/animations.d.ts +16 -4
- package/dist/gltf/animations/animations.d.ts.map +1 -1
- package/dist/gltf/animations/interpolate.d.ts +4 -3
- package/dist/gltf/animations/interpolate.d.ts.map +1 -1
- package/dist/gltf/animations/interpolate.js +27 -36
- package/dist/gltf/animations/interpolate.js.map +1 -1
- package/dist/gltf/create-gltf-model.d.ts +15 -1
- package/dist/gltf/create-gltf-model.d.ts.map +1 -1
- package/dist/gltf/create-gltf-model.js +154 -48
- package/dist/gltf/create-gltf-model.js.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.d.ts +39 -2
- package/dist/gltf/create-scenegraph-from-gltf.d.ts.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.js +76 -6
- package/dist/gltf/create-scenegraph-from-gltf.js.map +1 -1
- package/dist/gltf/gltf-animator.d.ts +26 -0
- package/dist/gltf/gltf-animator.d.ts.map +1 -1
- package/dist/gltf/gltf-animator.js +22 -19
- package/dist/gltf/gltf-animator.js.map +1 -1
- package/dist/gltf/gltf-extension-support.d.ts +10 -0
- package/dist/gltf/gltf-extension-support.d.ts.map +1 -0
- package/dist/gltf/gltf-extension-support.js +173 -0
- package/dist/gltf/gltf-extension-support.js.map +1 -0
- package/dist/index.cjs +1302 -276
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/parsers/parse-gltf-animations.d.ts +1 -0
- package/dist/parsers/parse-gltf-animations.d.ts.map +1 -1
- package/dist/parsers/parse-gltf-animations.js +73 -28
- package/dist/parsers/parse-gltf-animations.js.map +1 -1
- package/dist/parsers/parse-gltf-lights.d.ts +5 -0
- package/dist/parsers/parse-gltf-lights.d.ts.map +1 -0
- package/dist/parsers/parse-gltf-lights.js +163 -0
- package/dist/parsers/parse-gltf-lights.js.map +1 -0
- package/dist/parsers/parse-gltf.d.ts +19 -2
- package/dist/parsers/parse-gltf.d.ts.map +1 -1
- package/dist/parsers/parse-gltf.js +101 -61
- package/dist/parsers/parse-gltf.js.map +1 -1
- package/dist/parsers/parse-pbr-material.d.ts +115 -2
- package/dist/parsers/parse-pbr-material.d.ts.map +1 -1
- package/dist/parsers/parse-pbr-material.js +570 -54
- package/dist/parsers/parse-pbr-material.js.map +1 -1
- package/dist/pbr/pbr-environment.d.ts +10 -4
- package/dist/pbr/pbr-environment.d.ts.map +1 -1
- package/dist/pbr/pbr-environment.js +18 -15
- package/dist/pbr/pbr-environment.js.map +1 -1
- package/dist/pbr/pbr-material.d.ts +13 -3
- package/dist/pbr/pbr-material.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.d.ts +12 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.js +3 -0
- package/dist/webgl-to-webgpu/convert-webgl-attribute.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts +11 -5
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js +16 -12
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts +2 -9
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.js +2 -14
- package/dist/webgl-to-webgpu/convert-webgl-topology.js.map +1 -1
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts +27 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts.map +1 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js +34 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js.map +1 -0
- package/package.json +8 -9
- package/src/gltf/animations/animations.ts +17 -5
- package/src/gltf/animations/interpolate.ts +49 -68
- package/src/gltf/create-gltf-model.ts +214 -48
- package/src/gltf/create-scenegraph-from-gltf.ts +134 -11
- package/src/gltf/gltf-animator.ts +34 -25
- package/src/gltf/gltf-extension-support.ts +214 -0
- package/src/index.ts +11 -2
- package/src/parsers/parse-gltf-animations.ts +94 -33
- package/src/parsers/parse-gltf-lights.ts +218 -0
- package/src/parsers/parse-gltf.ts +170 -90
- package/src/parsers/parse-pbr-material.ts +870 -80
- package/src/pbr/pbr-environment.ts +44 -21
- package/src/pbr/pbr-material.ts +18 -3
- package/src/webgl-to-webgpu/convert-webgl-attribute.ts +12 -1
- package/src/webgl-to-webgpu/convert-webgl-sampler.ts +38 -29
- package/src/webgl-to-webgpu/convert-webgl-topology.ts +2 -14
- package/src/webgl-to-webgpu/gltf-webgl-constants.ts +35 -0
- package/dist/utils/deep-copy.d.ts +0 -3
- package/dist/utils/deep-copy.d.ts.map +0 -1
- package/dist/utils/deep-copy.js +0 -21
- package/dist/utils/deep-copy.js.map +0 -1
- package/src/utils/deep-copy.ts +0 -22
package/dist/index.cjs
CHANGED
|
@@ -22,7 +22,9 @@ var dist_exports = {};
|
|
|
22
22
|
__export(dist_exports, {
|
|
23
23
|
GLTFAnimator: () => GLTFAnimator,
|
|
24
24
|
createScenegraphsFromGLTF: () => createScenegraphsFromGLTF,
|
|
25
|
+
getGLTFExtensionSupport: () => getGLTFExtensionSupport,
|
|
25
26
|
loadPBREnvironment: () => loadPBREnvironment,
|
|
27
|
+
parseGLTFLights: () => parseGLTFLights,
|
|
26
28
|
parsePBRMaterial: () => parsePBRMaterial
|
|
27
29
|
});
|
|
28
30
|
module.exports = __toCommonJS(dist_exports);
|
|
@@ -31,7 +33,8 @@ module.exports = __toCommonJS(dist_exports);
|
|
|
31
33
|
var import_engine = require("@luma.gl/engine");
|
|
32
34
|
var import_textures = require("@loaders.gl/textures");
|
|
33
35
|
function loadPBREnvironment(device, props) {
|
|
34
|
-
const
|
|
36
|
+
const specularMipLevels = props.specularMipLevels ?? 1;
|
|
37
|
+
const brdfLutTexture = new import_engine.DynamicTexture(device, {
|
|
35
38
|
id: "brdfLUT",
|
|
36
39
|
sampler: {
|
|
37
40
|
addressModeU: "clamp-to-edge",
|
|
@@ -44,7 +47,7 @@ function loadPBREnvironment(device, props) {
|
|
|
44
47
|
});
|
|
45
48
|
const diffuseEnvSampler = makeCube(device, {
|
|
46
49
|
id: "DiffuseEnvSampler",
|
|
47
|
-
getTextureForFace: (
|
|
50
|
+
getTextureForFace: (face) => (0, import_textures.loadImageTexture)(props.getTexUrl("diffuse", FACES.indexOf(face), 0)),
|
|
48
51
|
sampler: {
|
|
49
52
|
addressModeU: "clamp-to-edge",
|
|
50
53
|
addressModeV: "clamp-to-edge",
|
|
@@ -54,12 +57,13 @@ function loadPBREnvironment(device, props) {
|
|
|
54
57
|
});
|
|
55
58
|
const specularEnvSampler = makeCube(device, {
|
|
56
59
|
id: "SpecularEnvSampler",
|
|
57
|
-
getTextureForFace: (
|
|
60
|
+
getTextureForFace: (face) => {
|
|
58
61
|
const imageArray = [];
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
const direction = FACES.indexOf(face);
|
|
63
|
+
for (let lod = 0; lod < specularMipLevels; lod++) {
|
|
64
|
+
imageArray.push((0, import_textures.loadImageTexture)(props.getTexUrl("specular", direction, lod)));
|
|
61
65
|
}
|
|
62
|
-
return imageArray;
|
|
66
|
+
return Promise.all(imageArray);
|
|
63
67
|
},
|
|
64
68
|
sampler: {
|
|
65
69
|
addressModeU: "clamp-to-edge",
|
|
@@ -75,28 +79,57 @@ function loadPBREnvironment(device, props) {
|
|
|
75
79
|
specularEnvSampler
|
|
76
80
|
};
|
|
77
81
|
}
|
|
78
|
-
var FACES = [
|
|
82
|
+
var FACES = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"];
|
|
79
83
|
function makeCube(device, { id, getTextureForFace, sampler }) {
|
|
80
|
-
const data = {
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
const data = Promise.all(FACES.map((face) => getTextureForFace(face))).then((faceDataArray) => {
|
|
85
|
+
const cubeData = {};
|
|
86
|
+
FACES.forEach((face, index) => {
|
|
87
|
+
cubeData[face] = faceDataArray[index];
|
|
88
|
+
});
|
|
89
|
+
return cubeData;
|
|
83
90
|
});
|
|
84
|
-
return new import_engine.
|
|
91
|
+
return new import_engine.DynamicTexture(device, {
|
|
85
92
|
id,
|
|
86
93
|
dimension: "cube",
|
|
87
94
|
mipmaps: false,
|
|
88
95
|
sampler,
|
|
89
|
-
// @ts-expect-error
|
|
90
96
|
data
|
|
91
97
|
});
|
|
92
98
|
}
|
|
93
99
|
|
|
94
100
|
// dist/parsers/parse-pbr-material.js
|
|
95
|
-
var import_constants2 = require("@luma.gl/constants");
|
|
96
101
|
var import_core = require("@luma.gl/core");
|
|
97
102
|
|
|
103
|
+
// dist/webgl-to-webgpu/gltf-webgl-constants.js
|
|
104
|
+
var GLEnum;
|
|
105
|
+
(function(GLEnum2) {
|
|
106
|
+
GLEnum2[GLEnum2["POINTS"] = 0] = "POINTS";
|
|
107
|
+
GLEnum2[GLEnum2["LINES"] = 1] = "LINES";
|
|
108
|
+
GLEnum2[GLEnum2["LINE_LOOP"] = 2] = "LINE_LOOP";
|
|
109
|
+
GLEnum2[GLEnum2["LINE_STRIP"] = 3] = "LINE_STRIP";
|
|
110
|
+
GLEnum2[GLEnum2["TRIANGLES"] = 4] = "TRIANGLES";
|
|
111
|
+
GLEnum2[GLEnum2["TRIANGLE_STRIP"] = 5] = "TRIANGLE_STRIP";
|
|
112
|
+
GLEnum2[GLEnum2["TRIANGLE_FAN"] = 6] = "TRIANGLE_FAN";
|
|
113
|
+
GLEnum2[GLEnum2["ONE"] = 1] = "ONE";
|
|
114
|
+
GLEnum2[GLEnum2["SRC_ALPHA"] = 770] = "SRC_ALPHA";
|
|
115
|
+
GLEnum2[GLEnum2["ONE_MINUS_SRC_ALPHA"] = 771] = "ONE_MINUS_SRC_ALPHA";
|
|
116
|
+
GLEnum2[GLEnum2["FUNC_ADD"] = 32774] = "FUNC_ADD";
|
|
117
|
+
GLEnum2[GLEnum2["LINEAR"] = 9729] = "LINEAR";
|
|
118
|
+
GLEnum2[GLEnum2["NEAREST"] = 9728] = "NEAREST";
|
|
119
|
+
GLEnum2[GLEnum2["NEAREST_MIPMAP_NEAREST"] = 9984] = "NEAREST_MIPMAP_NEAREST";
|
|
120
|
+
GLEnum2[GLEnum2["LINEAR_MIPMAP_NEAREST"] = 9985] = "LINEAR_MIPMAP_NEAREST";
|
|
121
|
+
GLEnum2[GLEnum2["NEAREST_MIPMAP_LINEAR"] = 9986] = "NEAREST_MIPMAP_LINEAR";
|
|
122
|
+
GLEnum2[GLEnum2["LINEAR_MIPMAP_LINEAR"] = 9987] = "LINEAR_MIPMAP_LINEAR";
|
|
123
|
+
GLEnum2[GLEnum2["TEXTURE_MIN_FILTER"] = 10241] = "TEXTURE_MIN_FILTER";
|
|
124
|
+
GLEnum2[GLEnum2["TEXTURE_WRAP_S"] = 10242] = "TEXTURE_WRAP_S";
|
|
125
|
+
GLEnum2[GLEnum2["TEXTURE_WRAP_T"] = 10243] = "TEXTURE_WRAP_T";
|
|
126
|
+
GLEnum2[GLEnum2["REPEAT"] = 10497] = "REPEAT";
|
|
127
|
+
GLEnum2[GLEnum2["CLAMP_TO_EDGE"] = 33071] = "CLAMP_TO_EDGE";
|
|
128
|
+
GLEnum2[GLEnum2["MIRRORED_REPEAT"] = 33648] = "MIRRORED_REPEAT";
|
|
129
|
+
GLEnum2[GLEnum2["UNPACK_FLIP_Y_WEBGL"] = 37440] = "UNPACK_FLIP_Y_WEBGL";
|
|
130
|
+
})(GLEnum || (GLEnum = {}));
|
|
131
|
+
|
|
98
132
|
// dist/webgl-to-webgpu/convert-webgl-sampler.js
|
|
99
|
-
var import_constants = require("@luma.gl/constants");
|
|
100
133
|
function convertSampler(gltfSampler) {
|
|
101
134
|
return {
|
|
102
135
|
addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),
|
|
@@ -107,11 +140,11 @@ function convertSampler(gltfSampler) {
|
|
|
107
140
|
}
|
|
108
141
|
function convertSamplerWrapMode(mode) {
|
|
109
142
|
switch (mode) {
|
|
110
|
-
case
|
|
143
|
+
case GLEnum.CLAMP_TO_EDGE:
|
|
111
144
|
return "clamp-to-edge";
|
|
112
|
-
case
|
|
145
|
+
case GLEnum.REPEAT:
|
|
113
146
|
return "repeat";
|
|
114
|
-
case
|
|
147
|
+
case GLEnum.MIRRORED_REPEAT:
|
|
115
148
|
return "mirror-repeat";
|
|
116
149
|
default:
|
|
117
150
|
return void 0;
|
|
@@ -119,9 +152,9 @@ function convertSamplerWrapMode(mode) {
|
|
|
119
152
|
}
|
|
120
153
|
function convertSamplerMagFilter(mode) {
|
|
121
154
|
switch (mode) {
|
|
122
|
-
case
|
|
155
|
+
case GLEnum.NEAREST:
|
|
123
156
|
return "nearest";
|
|
124
|
-
case
|
|
157
|
+
case GLEnum.LINEAR:
|
|
125
158
|
return "linear";
|
|
126
159
|
default:
|
|
127
160
|
return void 0;
|
|
@@ -129,17 +162,17 @@ function convertSamplerMagFilter(mode) {
|
|
|
129
162
|
}
|
|
130
163
|
function convertSamplerMinFilter(mode) {
|
|
131
164
|
switch (mode) {
|
|
132
|
-
case
|
|
165
|
+
case GLEnum.NEAREST:
|
|
133
166
|
return { minFilter: "nearest" };
|
|
134
|
-
case
|
|
167
|
+
case GLEnum.LINEAR:
|
|
135
168
|
return { minFilter: "linear" };
|
|
136
|
-
case
|
|
169
|
+
case GLEnum.NEAREST_MIPMAP_NEAREST:
|
|
137
170
|
return { minFilter: "nearest", mipmapFilter: "nearest" };
|
|
138
|
-
case
|
|
171
|
+
case GLEnum.LINEAR_MIPMAP_NEAREST:
|
|
139
172
|
return { minFilter: "linear", mipmapFilter: "nearest" };
|
|
140
|
-
case
|
|
173
|
+
case GLEnum.NEAREST_MIPMAP_LINEAR:
|
|
141
174
|
return { minFilter: "nearest", mipmapFilter: "linear" };
|
|
142
|
-
case
|
|
175
|
+
case GLEnum.LINEAR_MIPMAP_LINEAR:
|
|
143
176
|
return { minFilter: "linear", mipmapFilter: "linear" };
|
|
144
177
|
default:
|
|
145
178
|
return {};
|
|
@@ -171,7 +204,8 @@ function parsePBRMaterial(device, material, attributes, options) {
|
|
|
171
204
|
if (imageBasedLightingEnvironment) {
|
|
172
205
|
parsedMaterial.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.diffuseEnvSampler.texture;
|
|
173
206
|
parsedMaterial.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.specularEnvSampler.texture;
|
|
174
|
-
parsedMaterial.bindings.
|
|
207
|
+
parsedMaterial.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;
|
|
208
|
+
parsedMaterial.uniforms.IBLenabled = true;
|
|
175
209
|
parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];
|
|
176
210
|
}
|
|
177
211
|
if (options == null ? void 0 : options.pbrDebug) {
|
|
@@ -185,113 +219,713 @@ function parsePBRMaterial(device, material, attributes, options) {
|
|
|
185
219
|
parsedMaterial.defines["HAS_TANGENTS"] = true;
|
|
186
220
|
if (attributes["TEXCOORD_0"])
|
|
187
221
|
parsedMaterial.defines["HAS_UV"] = true;
|
|
222
|
+
if (attributes["JOINTS_0"] && attributes["WEIGHTS_0"])
|
|
223
|
+
parsedMaterial.defines["HAS_SKIN"] = true;
|
|
224
|
+
if (attributes["COLOR_0"])
|
|
225
|
+
parsedMaterial.defines["HAS_COLORS"] = true;
|
|
188
226
|
if (options == null ? void 0 : options.imageBasedLightingEnvironment)
|
|
189
227
|
parsedMaterial.defines["USE_IBL"] = true;
|
|
190
228
|
if (options == null ? void 0 : options.lights)
|
|
191
229
|
parsedMaterial.defines["USE_LIGHTS"] = true;
|
|
192
230
|
if (material) {
|
|
193
|
-
|
|
231
|
+
if (options.validateAttributes !== false) {
|
|
232
|
+
warnOnMissingExpectedAttributes(material, attributes);
|
|
233
|
+
}
|
|
234
|
+
parseMaterial(device, material, parsedMaterial, options.gltf);
|
|
194
235
|
}
|
|
195
236
|
return parsedMaterial;
|
|
196
237
|
}
|
|
197
|
-
function
|
|
198
|
-
|
|
238
|
+
function warnOnMissingExpectedAttributes(material, attributes) {
|
|
239
|
+
var _a;
|
|
240
|
+
const uvDependentTextureSlots = getUvDependentTextureSlots(material);
|
|
241
|
+
if (uvDependentTextureSlots.length > 0 && !attributes["TEXCOORD_0"]) {
|
|
242
|
+
import_core.log.warn(`glTF material uses ${uvDependentTextureSlots.join(", ")} but primitive is missing TEXCOORD_0; textured shading will sample the default UV coordinates`)();
|
|
243
|
+
}
|
|
244
|
+
const isUnlitMaterial = Boolean(material.unlit || ((_a = material.extensions) == null ? void 0 : _a.KHR_materials_unlit));
|
|
245
|
+
if (isUnlitMaterial || attributes["NORMAL"]) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const missingNormalReason = material.normalTexture ? "lit PBR shading with normalTexture" : "lit PBR shading";
|
|
249
|
+
import_core.log.warn(`glTF primitive is missing NORMAL while using ${missingNormalReason}; shading will fall back to geometric normals`)();
|
|
250
|
+
}
|
|
251
|
+
function getUvDependentTextureSlots(material) {
|
|
252
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
|
|
253
|
+
const uvDependentTextureSlots = [];
|
|
254
|
+
if ((_a = material.pbrMetallicRoughness) == null ? void 0 : _a.baseColorTexture) {
|
|
255
|
+
uvDependentTextureSlots.push("baseColorTexture");
|
|
256
|
+
}
|
|
257
|
+
if ((_b = material.pbrMetallicRoughness) == null ? void 0 : _b.metallicRoughnessTexture) {
|
|
258
|
+
uvDependentTextureSlots.push("metallicRoughnessTexture");
|
|
259
|
+
}
|
|
260
|
+
if (material.normalTexture) {
|
|
261
|
+
uvDependentTextureSlots.push("normalTexture");
|
|
262
|
+
}
|
|
263
|
+
if (material.occlusionTexture) {
|
|
264
|
+
uvDependentTextureSlots.push("occlusionTexture");
|
|
265
|
+
}
|
|
266
|
+
if (material.emissiveTexture) {
|
|
267
|
+
uvDependentTextureSlots.push("emissiveTexture");
|
|
268
|
+
}
|
|
269
|
+
if ((_d = (_c = material.extensions) == null ? void 0 : _c.KHR_materials_specular) == null ? void 0 : _d.specularTexture) {
|
|
270
|
+
uvDependentTextureSlots.push("KHR_materials_specular.specularTexture");
|
|
271
|
+
}
|
|
272
|
+
if ((_f = (_e = material.extensions) == null ? void 0 : _e.KHR_materials_specular) == null ? void 0 : _f.specularColorTexture) {
|
|
273
|
+
uvDependentTextureSlots.push("KHR_materials_specular.specularColorTexture");
|
|
274
|
+
}
|
|
275
|
+
if ((_h = (_g = material.extensions) == null ? void 0 : _g.KHR_materials_transmission) == null ? void 0 : _h.transmissionTexture) {
|
|
276
|
+
uvDependentTextureSlots.push("KHR_materials_transmission.transmissionTexture");
|
|
277
|
+
}
|
|
278
|
+
if ((_j = (_i = material.extensions) == null ? void 0 : _i.KHR_materials_clearcoat) == null ? void 0 : _j.clearcoatTexture) {
|
|
279
|
+
uvDependentTextureSlots.push("KHR_materials_clearcoat.clearcoatTexture");
|
|
280
|
+
}
|
|
281
|
+
if ((_l = (_k = material.extensions) == null ? void 0 : _k.KHR_materials_clearcoat) == null ? void 0 : _l.clearcoatRoughnessTexture) {
|
|
282
|
+
uvDependentTextureSlots.push("KHR_materials_clearcoat.clearcoatRoughnessTexture");
|
|
283
|
+
}
|
|
284
|
+
if ((_n = (_m = material.extensions) == null ? void 0 : _m.KHR_materials_sheen) == null ? void 0 : _n.sheenColorTexture) {
|
|
285
|
+
uvDependentTextureSlots.push("KHR_materials_sheen.sheenColorTexture");
|
|
286
|
+
}
|
|
287
|
+
if ((_p = (_o = material.extensions) == null ? void 0 : _o.KHR_materials_sheen) == null ? void 0 : _p.sheenRoughnessTexture) {
|
|
288
|
+
uvDependentTextureSlots.push("KHR_materials_sheen.sheenRoughnessTexture");
|
|
289
|
+
}
|
|
290
|
+
if ((_r = (_q = material.extensions) == null ? void 0 : _q.KHR_materials_iridescence) == null ? void 0 : _r.iridescenceTexture) {
|
|
291
|
+
uvDependentTextureSlots.push("KHR_materials_iridescence.iridescenceTexture");
|
|
292
|
+
}
|
|
293
|
+
if ((_t = (_s = material.extensions) == null ? void 0 : _s.KHR_materials_anisotropy) == null ? void 0 : _t.anisotropyTexture) {
|
|
294
|
+
uvDependentTextureSlots.push("KHR_materials_anisotropy.anisotropyTexture");
|
|
295
|
+
}
|
|
296
|
+
return uvDependentTextureSlots;
|
|
297
|
+
}
|
|
298
|
+
function parseMaterial(device, material, parsedMaterial, gltf) {
|
|
299
|
+
var _a;
|
|
300
|
+
parsedMaterial.uniforms.unlit = Boolean(material.unlit || ((_a = material.extensions) == null ? void 0 : _a.KHR_materials_unlit));
|
|
199
301
|
if (material.pbrMetallicRoughness) {
|
|
200
|
-
parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);
|
|
302
|
+
parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial, gltf);
|
|
201
303
|
}
|
|
202
304
|
if (material.normalTexture) {
|
|
203
|
-
addTexture(device, material.normalTexture, "pbr_normalSampler",
|
|
305
|
+
addTexture(device, material.normalTexture, "pbr_normalSampler", parsedMaterial, {
|
|
306
|
+
featureOptions: {
|
|
307
|
+
define: "HAS_NORMALMAP",
|
|
308
|
+
enabledUniformName: "normalMapEnabled"
|
|
309
|
+
},
|
|
310
|
+
gltf
|
|
311
|
+
});
|
|
204
312
|
const { scale = 1 } = material.normalTexture;
|
|
205
313
|
parsedMaterial.uniforms.normalScale = scale;
|
|
206
314
|
}
|
|
207
315
|
if (material.occlusionTexture) {
|
|
208
|
-
addTexture(device, material.occlusionTexture, "pbr_occlusionSampler",
|
|
316
|
+
addTexture(device, material.occlusionTexture, "pbr_occlusionSampler", parsedMaterial, {
|
|
317
|
+
featureOptions: {
|
|
318
|
+
define: "HAS_OCCLUSIONMAP",
|
|
319
|
+
enabledUniformName: "occlusionMapEnabled"
|
|
320
|
+
},
|
|
321
|
+
gltf
|
|
322
|
+
});
|
|
209
323
|
const { strength = 1 } = material.occlusionTexture;
|
|
210
324
|
parsedMaterial.uniforms.occlusionStrength = strength;
|
|
211
325
|
}
|
|
326
|
+
parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
|
|
212
327
|
if (material.emissiveTexture) {
|
|
213
|
-
addTexture(device, material.emissiveTexture, "pbr_emissiveSampler",
|
|
214
|
-
|
|
328
|
+
addTexture(device, material.emissiveTexture, "pbr_emissiveSampler", parsedMaterial, {
|
|
329
|
+
featureOptions: {
|
|
330
|
+
define: "HAS_EMISSIVEMAP",
|
|
331
|
+
enabledUniformName: "emissiveMapEnabled"
|
|
332
|
+
},
|
|
333
|
+
gltf
|
|
334
|
+
});
|
|
215
335
|
}
|
|
216
|
-
|
|
217
|
-
|
|
336
|
+
parseMaterialExtensions(device, material.extensions, parsedMaterial, gltf);
|
|
337
|
+
switch (material.alphaMode || "OPAQUE") {
|
|
338
|
+
case "OPAQUE":
|
|
339
|
+
break;
|
|
340
|
+
case "MASK": {
|
|
218
341
|
const { alphaCutoff = 0.5 } = material;
|
|
219
342
|
parsedMaterial.defines["ALPHA_CUTOFF"] = true;
|
|
343
|
+
parsedMaterial.uniforms.alphaCutoffEnabled = true;
|
|
220
344
|
parsedMaterial.uniforms.alphaCutoff = alphaCutoff;
|
|
221
345
|
break;
|
|
346
|
+
}
|
|
222
347
|
case "BLEND":
|
|
223
348
|
import_core.log.warn("glTF BLEND alphaMode might not work well because it requires mesh sorting")();
|
|
224
|
-
parsedMaterial
|
|
225
|
-
parsedMaterial.parameters.blendColorOperation = "add";
|
|
226
|
-
parsedMaterial.parameters.blendColorSrcFactor = "src-alpha";
|
|
227
|
-
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
228
|
-
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
229
|
-
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
230
|
-
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
231
|
-
parsedMaterial.glParameters["blend"] = true;
|
|
232
|
-
parsedMaterial.glParameters["blendEquation"] = 32774;
|
|
233
|
-
parsedMaterial.glParameters["blendFunc"] = [
|
|
234
|
-
770,
|
|
235
|
-
771,
|
|
236
|
-
1,
|
|
237
|
-
771
|
|
238
|
-
];
|
|
349
|
+
applyAlphaBlendParameters(parsedMaterial);
|
|
239
350
|
break;
|
|
240
351
|
}
|
|
241
352
|
}
|
|
242
|
-
function
|
|
353
|
+
function applyAlphaBlendParameters(parsedMaterial) {
|
|
354
|
+
parsedMaterial.parameters.blend = true;
|
|
355
|
+
parsedMaterial.parameters.blendColorOperation = "add";
|
|
356
|
+
parsedMaterial.parameters.blendColorSrcFactor = "src-alpha";
|
|
357
|
+
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
358
|
+
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
359
|
+
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
360
|
+
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
361
|
+
parsedMaterial.glParameters["blend"] = true;
|
|
362
|
+
parsedMaterial.glParameters["blendEquation"] = GLEnum.FUNC_ADD;
|
|
363
|
+
parsedMaterial.glParameters["blendFunc"] = [
|
|
364
|
+
GLEnum.SRC_ALPHA,
|
|
365
|
+
GLEnum.ONE_MINUS_SRC_ALPHA,
|
|
366
|
+
GLEnum.ONE,
|
|
367
|
+
GLEnum.ONE_MINUS_SRC_ALPHA
|
|
368
|
+
];
|
|
369
|
+
}
|
|
370
|
+
function applyTransmissionBlendApproximation(parsedMaterial) {
|
|
371
|
+
parsedMaterial.parameters.blend = true;
|
|
372
|
+
parsedMaterial.parameters.depthWriteEnabled = false;
|
|
373
|
+
parsedMaterial.parameters.blendColorOperation = "add";
|
|
374
|
+
parsedMaterial.parameters.blendColorSrcFactor = "one";
|
|
375
|
+
parsedMaterial.parameters.blendColorDstFactor = "one-minus-src-alpha";
|
|
376
|
+
parsedMaterial.parameters.blendAlphaOperation = "add";
|
|
377
|
+
parsedMaterial.parameters.blendAlphaSrcFactor = "one";
|
|
378
|
+
parsedMaterial.parameters.blendAlphaDstFactor = "one-minus-src-alpha";
|
|
379
|
+
parsedMaterial.glParameters["blend"] = true;
|
|
380
|
+
parsedMaterial.glParameters["depthMask"] = false;
|
|
381
|
+
parsedMaterial.glParameters["blendEquation"] = GLEnum.FUNC_ADD;
|
|
382
|
+
parsedMaterial.glParameters["blendFunc"] = [
|
|
383
|
+
GLEnum.ONE,
|
|
384
|
+
GLEnum.ONE_MINUS_SRC_ALPHA,
|
|
385
|
+
GLEnum.ONE,
|
|
386
|
+
GLEnum.ONE_MINUS_SRC_ALPHA
|
|
387
|
+
];
|
|
388
|
+
}
|
|
389
|
+
function parsePbrMetallicRoughness(device, pbrMetallicRoughness, parsedMaterial, gltf) {
|
|
243
390
|
if (pbrMetallicRoughness.baseColorTexture) {
|
|
244
|
-
addTexture(device, pbrMetallicRoughness.baseColorTexture, "pbr_baseColorSampler",
|
|
391
|
+
addTexture(device, pbrMetallicRoughness.baseColorTexture, "pbr_baseColorSampler", parsedMaterial, {
|
|
392
|
+
featureOptions: {
|
|
393
|
+
define: "HAS_BASECOLORMAP",
|
|
394
|
+
enabledUniformName: "baseColorMapEnabled"
|
|
395
|
+
},
|
|
396
|
+
gltf
|
|
397
|
+
});
|
|
245
398
|
}
|
|
246
399
|
parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
|
|
247
400
|
if (pbrMetallicRoughness.metallicRoughnessTexture) {
|
|
248
|
-
addTexture(device, pbrMetallicRoughness.metallicRoughnessTexture, "pbr_metallicRoughnessSampler",
|
|
401
|
+
addTexture(device, pbrMetallicRoughness.metallicRoughnessTexture, "pbr_metallicRoughnessSampler", parsedMaterial, {
|
|
402
|
+
featureOptions: {
|
|
403
|
+
define: "HAS_METALROUGHNESSMAP",
|
|
404
|
+
enabledUniformName: "metallicRoughnessMapEnabled"
|
|
405
|
+
},
|
|
406
|
+
gltf
|
|
407
|
+
});
|
|
249
408
|
}
|
|
250
409
|
const { metallicFactor = 1, roughnessFactor = 1 } = pbrMetallicRoughness;
|
|
251
410
|
parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];
|
|
252
411
|
}
|
|
253
|
-
function
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if (
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
|
|
412
|
+
function parseMaterialExtensions(device, extensions, parsedMaterial, gltf) {
|
|
413
|
+
if (!extensions) {
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
if (hasMaterialExtensionShading(extensions)) {
|
|
417
|
+
parsedMaterial.defines["USE_MATERIAL_EXTENSIONS"] = true;
|
|
418
|
+
}
|
|
419
|
+
parseSpecularExtension(device, extensions.KHR_materials_specular, parsedMaterial, gltf);
|
|
420
|
+
parseIorExtension(extensions.KHR_materials_ior, parsedMaterial);
|
|
421
|
+
parseTransmissionExtension(device, extensions.KHR_materials_transmission, parsedMaterial, gltf);
|
|
422
|
+
parseVolumeExtension(device, extensions.KHR_materials_volume, parsedMaterial, gltf);
|
|
423
|
+
parseClearcoatExtension(device, extensions.KHR_materials_clearcoat, parsedMaterial, gltf);
|
|
424
|
+
parseSheenExtension(device, extensions.KHR_materials_sheen, parsedMaterial, gltf);
|
|
425
|
+
parseIridescenceExtension(device, extensions.KHR_materials_iridescence, parsedMaterial, gltf);
|
|
426
|
+
parseAnisotropyExtension(device, extensions.KHR_materials_anisotropy, parsedMaterial, gltf);
|
|
427
|
+
parseEmissiveStrengthExtension(extensions.KHR_materials_emissive_strength, parsedMaterial);
|
|
428
|
+
}
|
|
429
|
+
function hasMaterialExtensionShading(extensions) {
|
|
430
|
+
return Boolean(extensions.KHR_materials_specular || extensions.KHR_materials_ior || extensions.KHR_materials_transmission || extensions.KHR_materials_volume || extensions.KHR_materials_clearcoat || extensions.KHR_materials_sheen || extensions.KHR_materials_iridescence || extensions.KHR_materials_anisotropy);
|
|
431
|
+
}
|
|
432
|
+
function parseSpecularExtension(device, extension, parsedMaterial, gltf) {
|
|
433
|
+
if (!extension) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
if (extension.specularColorFactor) {
|
|
437
|
+
parsedMaterial.uniforms.specularColorFactor = extension.specularColorFactor;
|
|
438
|
+
}
|
|
439
|
+
if (extension.specularFactor !== void 0) {
|
|
440
|
+
parsedMaterial.uniforms.specularIntensityFactor = extension.specularFactor;
|
|
441
|
+
}
|
|
442
|
+
if (extension.specularColorTexture) {
|
|
443
|
+
addTexture(device, extension.specularColorTexture, "pbr_specularColorSampler", parsedMaterial, {
|
|
444
|
+
featureOptions: {
|
|
445
|
+
define: "HAS_SPECULARCOLORMAP",
|
|
446
|
+
enabledUniformName: "specularColorMapEnabled"
|
|
447
|
+
},
|
|
448
|
+
gltf
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
if (extension.specularTexture) {
|
|
452
|
+
addTexture(device, extension.specularTexture, "pbr_specularIntensitySampler", parsedMaterial, {
|
|
453
|
+
featureOptions: {
|
|
454
|
+
define: "HAS_SPECULARINTENSITYMAP",
|
|
455
|
+
enabledUniformName: "specularIntensityMapEnabled"
|
|
456
|
+
},
|
|
457
|
+
gltf
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
function parseIorExtension(extension, parsedMaterial) {
|
|
462
|
+
if ((extension == null ? void 0 : extension.ior) !== void 0) {
|
|
463
|
+
parsedMaterial.uniforms.ior = extension.ior;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
function parseTransmissionExtension(device, extension, parsedMaterial, gltf) {
|
|
467
|
+
if (!extension) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
if (extension.transmissionFactor !== void 0) {
|
|
471
|
+
parsedMaterial.uniforms.transmissionFactor = extension.transmissionFactor;
|
|
472
|
+
}
|
|
473
|
+
if (extension.transmissionTexture) {
|
|
474
|
+
addTexture(device, extension.transmissionTexture, "pbr_transmissionSampler", parsedMaterial, {
|
|
475
|
+
featureOptions: {
|
|
476
|
+
define: "HAS_TRANSMISSIONMAP",
|
|
477
|
+
enabledUniformName: "transmissionMapEnabled"
|
|
478
|
+
},
|
|
479
|
+
gltf
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
if ((extension.transmissionFactor ?? 0) > 0 || extension.transmissionTexture) {
|
|
483
|
+
import_core.log.warn("KHR_materials_transmission uses a premultiplied-alpha blending approximation and may require mesh sorting")();
|
|
484
|
+
applyTransmissionBlendApproximation(parsedMaterial);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
function parseVolumeExtension(device, extension, parsedMaterial, gltf) {
|
|
488
|
+
if (!extension) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
if (extension.thicknessFactor !== void 0) {
|
|
492
|
+
parsedMaterial.uniforms.thicknessFactor = extension.thicknessFactor;
|
|
493
|
+
}
|
|
494
|
+
if (extension.thicknessTexture) {
|
|
495
|
+
addTexture(device, extension.thicknessTexture, "pbr_thicknessSampler", parsedMaterial, {
|
|
496
|
+
featureOptions: {
|
|
497
|
+
define: "HAS_THICKNESSMAP"
|
|
498
|
+
},
|
|
499
|
+
gltf
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
if (extension.attenuationDistance !== void 0) {
|
|
503
|
+
parsedMaterial.uniforms.attenuationDistance = extension.attenuationDistance;
|
|
504
|
+
}
|
|
505
|
+
if (extension.attenuationColor) {
|
|
506
|
+
parsedMaterial.uniforms.attenuationColor = extension.attenuationColor;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
function parseClearcoatExtension(device, extension, parsedMaterial, gltf) {
|
|
510
|
+
if (!extension) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
if (extension.clearcoatFactor !== void 0) {
|
|
514
|
+
parsedMaterial.uniforms.clearcoatFactor = extension.clearcoatFactor;
|
|
515
|
+
}
|
|
516
|
+
if (extension.clearcoatRoughnessFactor !== void 0) {
|
|
517
|
+
parsedMaterial.uniforms.clearcoatRoughnessFactor = extension.clearcoatRoughnessFactor;
|
|
518
|
+
}
|
|
519
|
+
if (extension.clearcoatTexture) {
|
|
520
|
+
addTexture(device, extension.clearcoatTexture, "pbr_clearcoatSampler", parsedMaterial, {
|
|
521
|
+
featureOptions: {
|
|
522
|
+
define: "HAS_CLEARCOATMAP",
|
|
523
|
+
enabledUniformName: "clearcoatMapEnabled"
|
|
524
|
+
},
|
|
525
|
+
gltf
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
if (extension.clearcoatRoughnessTexture) {
|
|
529
|
+
addTexture(device, extension.clearcoatRoughnessTexture, "pbr_clearcoatRoughnessSampler", parsedMaterial, {
|
|
530
|
+
featureOptions: {
|
|
531
|
+
define: "HAS_CLEARCOATROUGHNESSMAP",
|
|
532
|
+
enabledUniformName: "clearcoatRoughnessMapEnabled"
|
|
533
|
+
},
|
|
534
|
+
gltf
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
if (extension.clearcoatNormalTexture) {
|
|
538
|
+
addTexture(device, extension.clearcoatNormalTexture, "pbr_clearcoatNormalSampler", parsedMaterial, {
|
|
539
|
+
featureOptions: {
|
|
540
|
+
define: "HAS_CLEARCOATNORMALMAP"
|
|
541
|
+
},
|
|
542
|
+
gltf
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
function parseSheenExtension(device, extension, parsedMaterial, gltf) {
|
|
547
|
+
if (!extension) {
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
if (extension.sheenColorFactor) {
|
|
551
|
+
parsedMaterial.uniforms.sheenColorFactor = extension.sheenColorFactor;
|
|
552
|
+
}
|
|
553
|
+
if (extension.sheenRoughnessFactor !== void 0) {
|
|
554
|
+
parsedMaterial.uniforms.sheenRoughnessFactor = extension.sheenRoughnessFactor;
|
|
555
|
+
}
|
|
556
|
+
if (extension.sheenColorTexture) {
|
|
557
|
+
addTexture(device, extension.sheenColorTexture, "pbr_sheenColorSampler", parsedMaterial, {
|
|
558
|
+
featureOptions: {
|
|
559
|
+
define: "HAS_SHEENCOLORMAP",
|
|
560
|
+
enabledUniformName: "sheenColorMapEnabled"
|
|
561
|
+
},
|
|
562
|
+
gltf
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
if (extension.sheenRoughnessTexture) {
|
|
566
|
+
addTexture(device, extension.sheenRoughnessTexture, "pbr_sheenRoughnessSampler", parsedMaterial, {
|
|
567
|
+
featureOptions: {
|
|
568
|
+
define: "HAS_SHEENROUGHNESSMAP",
|
|
569
|
+
enabledUniformName: "sheenRoughnessMapEnabled"
|
|
570
|
+
},
|
|
571
|
+
gltf
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
function parseIridescenceExtension(device, extension, parsedMaterial, gltf) {
|
|
576
|
+
if (!extension) {
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
if (extension.iridescenceFactor !== void 0) {
|
|
580
|
+
parsedMaterial.uniforms.iridescenceFactor = extension.iridescenceFactor;
|
|
581
|
+
}
|
|
582
|
+
if (extension.iridescenceIor !== void 0) {
|
|
583
|
+
parsedMaterial.uniforms.iridescenceIor = extension.iridescenceIor;
|
|
584
|
+
}
|
|
585
|
+
if (extension.iridescenceThicknessMinimum !== void 0 || extension.iridescenceThicknessMaximum !== void 0) {
|
|
586
|
+
parsedMaterial.uniforms.iridescenceThicknessRange = [
|
|
587
|
+
extension.iridescenceThicknessMinimum ?? 100,
|
|
588
|
+
extension.iridescenceThicknessMaximum ?? 400
|
|
589
|
+
];
|
|
590
|
+
}
|
|
591
|
+
if (extension.iridescenceTexture) {
|
|
592
|
+
addTexture(device, extension.iridescenceTexture, "pbr_iridescenceSampler", parsedMaterial, {
|
|
593
|
+
featureOptions: {
|
|
594
|
+
define: "HAS_IRIDESCENCEMAP",
|
|
595
|
+
enabledUniformName: "iridescenceMapEnabled"
|
|
596
|
+
},
|
|
597
|
+
gltf
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
if (extension.iridescenceThicknessTexture) {
|
|
601
|
+
addTexture(device, extension.iridescenceThicknessTexture, "pbr_iridescenceThicknessSampler", parsedMaterial, {
|
|
602
|
+
featureOptions: {
|
|
603
|
+
define: "HAS_IRIDESCENCETHICKNESSMAP"
|
|
604
|
+
},
|
|
605
|
+
gltf
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
function parseAnisotropyExtension(device, extension, parsedMaterial, gltf) {
|
|
610
|
+
if (!extension) {
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
if (extension.anisotropyStrength !== void 0) {
|
|
614
|
+
parsedMaterial.uniforms.anisotropyStrength = extension.anisotropyStrength;
|
|
615
|
+
}
|
|
616
|
+
if (extension.anisotropyRotation !== void 0) {
|
|
617
|
+
parsedMaterial.uniforms.anisotropyRotation = extension.anisotropyRotation;
|
|
618
|
+
}
|
|
619
|
+
if (extension.anisotropyTexture) {
|
|
620
|
+
addTexture(device, extension.anisotropyTexture, "pbr_anisotropySampler", parsedMaterial, {
|
|
621
|
+
featureOptions: {
|
|
622
|
+
define: "HAS_ANISOTROPYMAP",
|
|
623
|
+
enabledUniformName: "anisotropyMapEnabled"
|
|
624
|
+
},
|
|
625
|
+
gltf
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
function parseEmissiveStrengthExtension(extension, parsedMaterial) {
|
|
630
|
+
if ((extension == null ? void 0 : extension.emissiveStrength) !== void 0) {
|
|
631
|
+
parsedMaterial.uniforms.emissiveStrength = extension.emissiveStrength;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
function addTexture(device, gltfTexture, uniformName, parsedMaterial, textureParseOptions = {}) {
|
|
635
|
+
var _a, _b, _c;
|
|
636
|
+
const { featureOptions = {}, gltf } = textureParseOptions;
|
|
637
|
+
const { define, enabledUniformName } = featureOptions;
|
|
638
|
+
const resolvedTextureInfo = resolveTextureInfo(gltfTexture, gltf);
|
|
639
|
+
const image = (_b = (_a = resolvedTextureInfo.texture) == null ? void 0 : _a.source) == null ? void 0 : _b.image;
|
|
640
|
+
if (!image) {
|
|
641
|
+
import_core.log.warn(`Skipping unresolved glTF texture for ${String(uniformName)}`)();
|
|
642
|
+
return;
|
|
261
643
|
}
|
|
262
644
|
const gltfSampler = {
|
|
263
645
|
wrapS: 10497,
|
|
264
646
|
// default REPEAT S (U) wrapping mode.
|
|
265
647
|
wrapT: 10497,
|
|
266
648
|
// default REPEAT T (V) wrapping mode.
|
|
267
|
-
|
|
649
|
+
minFilter: 9729,
|
|
650
|
+
// default LINEAR filtering
|
|
651
|
+
magFilter: 9729,
|
|
652
|
+
// default LINEAR filtering
|
|
653
|
+
...(_c = resolvedTextureInfo == null ? void 0 : resolvedTextureInfo.texture) == null ? void 0 : _c.sampler
|
|
268
654
|
};
|
|
269
|
-
const
|
|
270
|
-
id:
|
|
271
|
-
sampler: convertSampler(gltfSampler)
|
|
272
|
-
|
|
273
|
-
|
|
655
|
+
const baseOptions = {
|
|
656
|
+
id: resolvedTextureInfo.uniformName || resolvedTextureInfo.id,
|
|
657
|
+
sampler: convertSampler(gltfSampler)
|
|
658
|
+
};
|
|
659
|
+
let texture;
|
|
660
|
+
if (image.compressed) {
|
|
661
|
+
texture = createCompressedTexture(device, image, baseOptions);
|
|
662
|
+
} else {
|
|
663
|
+
const { width, height } = device.getExternalImageSize(image);
|
|
664
|
+
texture = device.createTexture({
|
|
665
|
+
...baseOptions,
|
|
666
|
+
width,
|
|
667
|
+
height,
|
|
668
|
+
data: image
|
|
669
|
+
});
|
|
670
|
+
}
|
|
274
671
|
parsedMaterial.bindings[uniformName] = texture;
|
|
275
672
|
if (define)
|
|
276
673
|
parsedMaterial.defines[define] = true;
|
|
674
|
+
if (enabledUniformName) {
|
|
675
|
+
parsedMaterial.uniforms[enabledUniformName] = true;
|
|
676
|
+
}
|
|
277
677
|
parsedMaterial.generatedTextures.push(texture);
|
|
278
678
|
}
|
|
679
|
+
function resolveTextureInfo(gltfTexture, gltf) {
|
|
680
|
+
if (gltfTexture.texture || gltfTexture.index === void 0 || !(gltf == null ? void 0 : gltf.textures)) {
|
|
681
|
+
return gltfTexture;
|
|
682
|
+
}
|
|
683
|
+
const resolvedTextureEntry = gltf.textures[gltfTexture.index];
|
|
684
|
+
if (!resolvedTextureEntry) {
|
|
685
|
+
return gltfTexture;
|
|
686
|
+
}
|
|
687
|
+
if ("texture" in resolvedTextureEntry && resolvedTextureEntry.texture) {
|
|
688
|
+
return {
|
|
689
|
+
...resolvedTextureEntry,
|
|
690
|
+
...gltfTexture,
|
|
691
|
+
texture: resolvedTextureEntry.texture
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
if (!("source" in resolvedTextureEntry)) {
|
|
695
|
+
return gltfTexture;
|
|
696
|
+
}
|
|
697
|
+
return {
|
|
698
|
+
...gltfTexture,
|
|
699
|
+
texture: resolvedTextureEntry
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
function createCompressedTextureFallback(device, baseOptions) {
|
|
703
|
+
return device.createTexture({
|
|
704
|
+
...baseOptions,
|
|
705
|
+
format: "rgba8unorm",
|
|
706
|
+
width: 1,
|
|
707
|
+
height: 1,
|
|
708
|
+
mipLevels: 1
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
function resolveCompressedTextureFormat(level) {
|
|
712
|
+
return level.textureFormat;
|
|
713
|
+
}
|
|
714
|
+
function getMaxCompressedMipLevels(baseWidth, baseHeight, format) {
|
|
715
|
+
const { blockWidth = 1, blockHeight = 1 } = import_core.textureFormatDecoder.getInfo(format);
|
|
716
|
+
let count = 1;
|
|
717
|
+
for (let i = 1; ; i++) {
|
|
718
|
+
const w = Math.max(1, baseWidth >> i);
|
|
719
|
+
const h = Math.max(1, baseHeight >> i);
|
|
720
|
+
if (w < blockWidth || h < blockHeight)
|
|
721
|
+
break;
|
|
722
|
+
count++;
|
|
723
|
+
}
|
|
724
|
+
return count;
|
|
725
|
+
}
|
|
726
|
+
function createCompressedTexture(device, image, baseOptions) {
|
|
727
|
+
var _a, _b;
|
|
728
|
+
let levels;
|
|
729
|
+
if (Array.isArray(image.data) && ((_a = image.data[0]) == null ? void 0 : _a.data)) {
|
|
730
|
+
levels = image.data;
|
|
731
|
+
} else if ("mipmaps" in image && Array.isArray(image.mipmaps)) {
|
|
732
|
+
levels = image.mipmaps;
|
|
733
|
+
} else {
|
|
734
|
+
levels = [];
|
|
735
|
+
}
|
|
736
|
+
if (levels.length === 0 || !((_b = levels[0]) == null ? void 0 : _b.data)) {
|
|
737
|
+
import_core.log.warn("createCompressedTexture: compressed image has no valid mip levels, creating fallback")();
|
|
738
|
+
return createCompressedTextureFallback(device, baseOptions);
|
|
739
|
+
}
|
|
740
|
+
const baseLevel = levels[0];
|
|
741
|
+
const baseWidth = baseLevel.width ?? image.width ?? 0;
|
|
742
|
+
const baseHeight = baseLevel.height ?? image.height ?? 0;
|
|
743
|
+
if (baseWidth <= 0 || baseHeight <= 0) {
|
|
744
|
+
import_core.log.warn("createCompressedTexture: base level has invalid dimensions, creating fallback")();
|
|
745
|
+
return createCompressedTextureFallback(device, baseOptions);
|
|
746
|
+
}
|
|
747
|
+
const format = resolveCompressedTextureFormat(baseLevel);
|
|
748
|
+
if (!format) {
|
|
749
|
+
import_core.log.warn("createCompressedTexture: compressed image has no textureFormat, creating fallback")();
|
|
750
|
+
return createCompressedTextureFallback(device, baseOptions);
|
|
751
|
+
}
|
|
752
|
+
const maxMipLevels = getMaxCompressedMipLevels(baseWidth, baseHeight, format);
|
|
753
|
+
const levelLimit = Math.min(levels.length, maxMipLevels);
|
|
754
|
+
let validLevelCount = 1;
|
|
755
|
+
for (let i = 1; i < levelLimit; i++) {
|
|
756
|
+
const level = levels[i];
|
|
757
|
+
if (!level.data || level.width <= 0 || level.height <= 0) {
|
|
758
|
+
import_core.log.warn(`createCompressedTexture: mip level ${i} has invalid data/dimensions, truncating`)();
|
|
759
|
+
break;
|
|
760
|
+
}
|
|
761
|
+
const levelFormat = resolveCompressedTextureFormat(level);
|
|
762
|
+
if (levelFormat && levelFormat !== format) {
|
|
763
|
+
import_core.log.warn(`createCompressedTexture: mip level ${i} format '${levelFormat}' differs from base '${format}', truncating`)();
|
|
764
|
+
break;
|
|
765
|
+
}
|
|
766
|
+
const expectedW = Math.max(1, baseWidth >> i);
|
|
767
|
+
const expectedH = Math.max(1, baseHeight >> i);
|
|
768
|
+
if (level.width !== expectedW || level.height !== expectedH) {
|
|
769
|
+
import_core.log.warn(`createCompressedTexture: mip level ${i} dimensions ${level.width}x${level.height} don't match expected ${expectedW}x${expectedH}, truncating`)();
|
|
770
|
+
break;
|
|
771
|
+
}
|
|
772
|
+
validLevelCount++;
|
|
773
|
+
}
|
|
774
|
+
const texture = device.createTexture({
|
|
775
|
+
...baseOptions,
|
|
776
|
+
format,
|
|
777
|
+
usage: import_core.Texture.TEXTURE | import_core.Texture.COPY_DST,
|
|
778
|
+
width: baseWidth,
|
|
779
|
+
height: baseHeight,
|
|
780
|
+
mipLevels: validLevelCount,
|
|
781
|
+
data: baseLevel.data
|
|
782
|
+
});
|
|
783
|
+
for (let i = 1; i < validLevelCount; i++) {
|
|
784
|
+
texture.writeData(levels[i].data, {
|
|
785
|
+
width: levels[i].width,
|
|
786
|
+
height: levels[i].height,
|
|
787
|
+
mipLevel: i
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
return texture;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// dist/parsers/parse-gltf-lights.js
|
|
794
|
+
var import_core2 = require("@math.gl/core");
|
|
795
|
+
var GLTF_COLOR_FACTOR = 255;
|
|
796
|
+
function parseGLTFLights(gltf) {
|
|
797
|
+
var _a, _b, _c, _d;
|
|
798
|
+
const lightDefs = (
|
|
799
|
+
// `postProcessGLTF()` moves KHR_lights_punctual into `gltf.lights`.
|
|
800
|
+
gltf.lights || ((_b = (_a = gltf.extensions) == null ? void 0 : _a["KHR_lights_punctual"]) == null ? void 0 : _b["lights"])
|
|
801
|
+
);
|
|
802
|
+
if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {
|
|
803
|
+
return [];
|
|
804
|
+
}
|
|
805
|
+
const lights = [];
|
|
806
|
+
const parentNodeById = createParentNodeMap(gltf.nodes || []);
|
|
807
|
+
const worldMatrixByNodeId = /* @__PURE__ */ new Map();
|
|
808
|
+
for (const node of gltf.nodes || []) {
|
|
809
|
+
const lightIndex = node.light ?? ((_d = (_c = node.extensions) == null ? void 0 : _c.KHR_lights_punctual) == null ? void 0 : _d.light);
|
|
810
|
+
if (typeof lightIndex !== "number") {
|
|
811
|
+
continue;
|
|
812
|
+
}
|
|
813
|
+
const gltfLight = lightDefs[lightIndex];
|
|
814
|
+
if (!gltfLight) {
|
|
815
|
+
continue;
|
|
816
|
+
}
|
|
817
|
+
const color = normalizeGLTFLightColor(gltfLight.color || [1, 1, 1]);
|
|
818
|
+
const intensity = gltfLight.intensity ?? 1;
|
|
819
|
+
const range = gltfLight.range;
|
|
820
|
+
const worldMatrix = getNodeWorldMatrix(node, parentNodeById, worldMatrixByNodeId);
|
|
821
|
+
switch (gltfLight.type) {
|
|
822
|
+
case "directional":
|
|
823
|
+
lights.push(parseDirectionalLight(worldMatrix, color, intensity));
|
|
824
|
+
break;
|
|
825
|
+
case "point":
|
|
826
|
+
lights.push(parsePointLight(worldMatrix, color, intensity, range));
|
|
827
|
+
break;
|
|
828
|
+
case "spot":
|
|
829
|
+
lights.push(parseSpotLight(worldMatrix, color, intensity, range, gltfLight.spot));
|
|
830
|
+
break;
|
|
831
|
+
default:
|
|
832
|
+
break;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
return lights;
|
|
836
|
+
}
|
|
837
|
+
function normalizeGLTFLightColor(color) {
|
|
838
|
+
return color.map((component) => component * GLTF_COLOR_FACTOR);
|
|
839
|
+
}
|
|
840
|
+
function parsePointLight(worldMatrix, color, intensity, range) {
|
|
841
|
+
const position = getLightPosition(worldMatrix);
|
|
842
|
+
let attenuation = [1, 0, 0];
|
|
843
|
+
if (range !== void 0 && range > 0) {
|
|
844
|
+
attenuation = [1, 0, 1 / (range * range)];
|
|
845
|
+
}
|
|
846
|
+
return {
|
|
847
|
+
type: "point",
|
|
848
|
+
position,
|
|
849
|
+
color,
|
|
850
|
+
intensity,
|
|
851
|
+
attenuation
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
function parseDirectionalLight(worldMatrix, color, intensity) {
|
|
855
|
+
const direction = getLightDirection(worldMatrix);
|
|
856
|
+
return {
|
|
857
|
+
type: "directional",
|
|
858
|
+
direction,
|
|
859
|
+
color,
|
|
860
|
+
intensity
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
function parseSpotLight(worldMatrix, color, intensity, range, spot = {}) {
|
|
864
|
+
const position = getLightPosition(worldMatrix);
|
|
865
|
+
const direction = getLightDirection(worldMatrix);
|
|
866
|
+
let attenuation = [1, 0, 0];
|
|
867
|
+
if (range !== void 0 && range > 0) {
|
|
868
|
+
attenuation = [1, 0, 1 / (range * range)];
|
|
869
|
+
}
|
|
870
|
+
return {
|
|
871
|
+
type: "spot",
|
|
872
|
+
position,
|
|
873
|
+
direction,
|
|
874
|
+
color,
|
|
875
|
+
intensity,
|
|
876
|
+
attenuation,
|
|
877
|
+
innerConeAngle: spot.innerConeAngle ?? 0,
|
|
878
|
+
outerConeAngle: spot.outerConeAngle ?? Math.PI / 4
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
function createParentNodeMap(nodes) {
|
|
882
|
+
const parentNodeById = /* @__PURE__ */ new Map();
|
|
883
|
+
for (const node of nodes) {
|
|
884
|
+
for (const childNode of node.children || []) {
|
|
885
|
+
parentNodeById.set(childNode.id, node);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
return parentNodeById;
|
|
889
|
+
}
|
|
890
|
+
function getNodeWorldMatrix(node, parentNodeById, worldMatrixByNodeId) {
|
|
891
|
+
const cachedWorldMatrix = worldMatrixByNodeId.get(node.id);
|
|
892
|
+
if (cachedWorldMatrix) {
|
|
893
|
+
return cachedWorldMatrix;
|
|
894
|
+
}
|
|
895
|
+
const localMatrix = getNodeLocalMatrix(node);
|
|
896
|
+
const parentNode = parentNodeById.get(node.id);
|
|
897
|
+
const worldMatrix = parentNode ? new import_core2.Matrix4(getNodeWorldMatrix(parentNode, parentNodeById, worldMatrixByNodeId)).multiplyRight(localMatrix) : localMatrix;
|
|
898
|
+
worldMatrixByNodeId.set(node.id, worldMatrix);
|
|
899
|
+
return worldMatrix;
|
|
900
|
+
}
|
|
901
|
+
function getNodeLocalMatrix(node) {
|
|
902
|
+
if (node.matrix) {
|
|
903
|
+
return new import_core2.Matrix4(node.matrix);
|
|
904
|
+
}
|
|
905
|
+
const matrix = new import_core2.Matrix4();
|
|
906
|
+
if (node.translation) {
|
|
907
|
+
matrix.translate(node.translation);
|
|
908
|
+
}
|
|
909
|
+
if (node.rotation) {
|
|
910
|
+
matrix.multiplyRight(new import_core2.Matrix4().fromQuaternion(node.rotation));
|
|
911
|
+
}
|
|
912
|
+
if (node.scale) {
|
|
913
|
+
matrix.scale(node.scale);
|
|
914
|
+
}
|
|
915
|
+
return matrix;
|
|
916
|
+
}
|
|
917
|
+
function getLightPosition(worldMatrix) {
|
|
918
|
+
return worldMatrix.transformAsPoint([0, 0, 0]);
|
|
919
|
+
}
|
|
920
|
+
function getLightDirection(worldMatrix) {
|
|
921
|
+
return worldMatrix.transformDirection([0, 0, -1]);
|
|
922
|
+
}
|
|
279
923
|
|
|
280
924
|
// dist/parsers/parse-gltf.js
|
|
281
|
-
var
|
|
282
|
-
var
|
|
925
|
+
var import_engine4 = require("@luma.gl/engine");
|
|
926
|
+
var import_shadertools2 = require("@luma.gl/shadertools");
|
|
283
927
|
|
|
284
928
|
// dist/webgl-to-webgpu/convert-webgl-topology.js
|
|
285
|
-
var GLEnum;
|
|
286
|
-
(function(GLEnum2) {
|
|
287
|
-
GLEnum2[GLEnum2["POINTS"] = 0] = "POINTS";
|
|
288
|
-
GLEnum2[GLEnum2["LINES"] = 1] = "LINES";
|
|
289
|
-
GLEnum2[GLEnum2["LINE_LOOP"] = 2] = "LINE_LOOP";
|
|
290
|
-
GLEnum2[GLEnum2["LINE_STRIP"] = 3] = "LINE_STRIP";
|
|
291
|
-
GLEnum2[GLEnum2["TRIANGLES"] = 4] = "TRIANGLES";
|
|
292
|
-
GLEnum2[GLEnum2["TRIANGLE_STRIP"] = 5] = "TRIANGLE_STRIP";
|
|
293
|
-
GLEnum2[GLEnum2["TRIANGLE_FAN"] = 6] = "TRIANGLE_FAN";
|
|
294
|
-
})(GLEnum || (GLEnum = {}));
|
|
295
929
|
function convertGLDrawModeToTopology(drawMode) {
|
|
296
930
|
switch (drawMode) {
|
|
297
931
|
case GLEnum.POINTS:
|
|
@@ -310,56 +944,95 @@ function convertGLDrawModeToTopology(drawMode) {
|
|
|
310
944
|
}
|
|
311
945
|
|
|
312
946
|
// dist/gltf/create-gltf-model.js
|
|
313
|
-
var
|
|
314
|
-
var import_shadertools = require("@luma.gl/shadertools");
|
|
947
|
+
var import_core3 = require("@luma.gl/core");
|
|
315
948
|
var import_engine2 = require("@luma.gl/engine");
|
|
949
|
+
var import_shadertools = require("@luma.gl/shadertools");
|
|
950
|
+
var import_engine3 = require("@luma.gl/engine");
|
|
316
951
|
var SHADER = (
|
|
317
952
|
/* WGSL */
|
|
318
953
|
`
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
954
|
+
struct VertexInputs {
|
|
955
|
+
@location(0) positions: vec3f,
|
|
956
|
+
#ifdef HAS_NORMALS
|
|
957
|
+
@location(1) normals: vec3f,
|
|
958
|
+
#endif
|
|
959
|
+
#ifdef HAS_TANGENTS
|
|
960
|
+
@location(2) TANGENT: vec4f,
|
|
961
|
+
#endif
|
|
962
|
+
#ifdef HAS_UV
|
|
963
|
+
@location(3) texCoords: vec2f,
|
|
964
|
+
#endif
|
|
965
|
+
#ifdef HAS_SKIN
|
|
966
|
+
@location(4) JOINTS_0: vec4u,
|
|
967
|
+
@location(5) WEIGHTS_0: vec4f,
|
|
968
|
+
#endif
|
|
969
|
+
};
|
|
328
970
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
971
|
+
struct FragmentInputs {
|
|
972
|
+
@builtin(position) position: vec4f,
|
|
973
|
+
@location(0) pbrPosition: vec3f,
|
|
974
|
+
@location(1) pbrUV: vec2f,
|
|
975
|
+
@location(2) pbrNormal: vec3f,
|
|
976
|
+
#ifdef HAS_TANGENTS
|
|
977
|
+
@location(3) pbrTangent: vec4f,
|
|
978
|
+
#endif
|
|
979
|
+
};
|
|
333
980
|
|
|
334
981
|
@vertex
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
982
|
+
fn vertexMain(inputs: VertexInputs) -> FragmentInputs {
|
|
983
|
+
var outputs: FragmentInputs;
|
|
984
|
+
var position = vec4f(inputs.positions, 1.0);
|
|
985
|
+
var normal = vec3f(0.0, 0.0, 1.0);
|
|
986
|
+
var tangent = vec4f(1.0, 0.0, 0.0, 1.0);
|
|
987
|
+
var uv = vec2f(0.0, 0.0);
|
|
339
988
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
989
|
+
#ifdef HAS_NORMALS
|
|
990
|
+
normal = inputs.normals;
|
|
991
|
+
#endif
|
|
992
|
+
#ifdef HAS_UV
|
|
993
|
+
uv = inputs.texCoords;
|
|
994
|
+
#endif
|
|
995
|
+
#ifdef HAS_TANGENTS
|
|
996
|
+
tangent = inputs.TANGENT;
|
|
997
|
+
#endif
|
|
998
|
+
#ifdef HAS_SKIN
|
|
999
|
+
let skinMatrix = getSkinMatrix(inputs.WEIGHTS_0, inputs.JOINTS_0);
|
|
1000
|
+
position = skinMatrix * position;
|
|
1001
|
+
normal = normalize((skinMatrix * vec4f(normal, 0.0)).xyz);
|
|
1002
|
+
#ifdef HAS_TANGENTS
|
|
1003
|
+
tangent = vec4f(normalize((skinMatrix * vec4f(tangent.xyz, 0.0)).xyz), tangent.w);
|
|
1004
|
+
#endif
|
|
1005
|
+
#endif
|
|
343
1006
|
|
|
344
|
-
|
|
345
|
-
_TANGENT = TANGENT;
|
|
346
|
-
#endif
|
|
1007
|
+
let worldPosition = pbrProjection.modelMatrix * position;
|
|
347
1008
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
1009
|
+
#ifdef HAS_NORMALS
|
|
1010
|
+
normal = normalize((pbrProjection.normalMatrix * vec4f(normal, 0.0)).xyz);
|
|
1011
|
+
#endif
|
|
1012
|
+
#ifdef HAS_TANGENTS
|
|
1013
|
+
let worldTangent = normalize((pbrProjection.modelMatrix * vec4f(tangent.xyz, 0.0)).xyz);
|
|
1014
|
+
outputs.pbrTangent = vec4f(worldTangent, tangent.w);
|
|
1015
|
+
#endif
|
|
351
1016
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
1017
|
+
outputs.position = pbrProjection.modelViewProjectionMatrix * position;
|
|
1018
|
+
outputs.pbrPosition = worldPosition.xyz / worldPosition.w;
|
|
1019
|
+
outputs.pbrUV = uv;
|
|
1020
|
+
outputs.pbrNormal = normal;
|
|
1021
|
+
return outputs;
|
|
1022
|
+
}
|
|
355
1023
|
|
|
356
1024
|
@fragment
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
1025
|
+
fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {
|
|
1026
|
+
fragmentInputs.pbr_vPosition = inputs.pbrPosition;
|
|
1027
|
+
fragmentInputs.pbr_vUV = inputs.pbrUV;
|
|
1028
|
+
fragmentInputs.pbr_vNormal = inputs.pbrNormal;
|
|
1029
|
+
#ifdef HAS_TANGENTS
|
|
1030
|
+
let tangent = normalize(inputs.pbrTangent.xyz);
|
|
1031
|
+
let bitangent = normalize(cross(inputs.pbrNormal, tangent)) * inputs.pbrTangent.w;
|
|
1032
|
+
fragmentInputs.pbr_vTBN = mat3x3f(tangent, bitangent, inputs.pbrNormal);
|
|
1033
|
+
#endif
|
|
1034
|
+
return pbr_filterColor(vec4f(1.0));
|
|
1035
|
+
}
|
|
363
1036
|
`
|
|
364
1037
|
);
|
|
365
1038
|
var vs = (
|
|
@@ -383,6 +1056,11 @@ var vs = (
|
|
|
383
1056
|
in vec2 texCoords;
|
|
384
1057
|
#endif
|
|
385
1058
|
|
|
1059
|
+
#ifdef HAS_SKIN
|
|
1060
|
+
in uvec4 JOINTS_0;
|
|
1061
|
+
in vec4 WEIGHTS_0;
|
|
1062
|
+
#endif
|
|
1063
|
+
|
|
386
1064
|
void main(void) {
|
|
387
1065
|
vec4 _NORMAL = vec4(0.);
|
|
388
1066
|
vec4 _TANGENT = vec4(0.);
|
|
@@ -400,8 +1078,17 @@ var vs = (
|
|
|
400
1078
|
_TEXCOORD_0 = texCoords;
|
|
401
1079
|
#endif
|
|
402
1080
|
|
|
403
|
-
|
|
404
|
-
|
|
1081
|
+
vec4 pos = positions;
|
|
1082
|
+
|
|
1083
|
+
#ifdef HAS_SKIN
|
|
1084
|
+
mat4 skinMat = getSkinMatrix(WEIGHTS_0, JOINTS_0);
|
|
1085
|
+
pos = skinMat * pos;
|
|
1086
|
+
_NORMAL = skinMat * _NORMAL;
|
|
1087
|
+
_TANGENT = vec4((skinMat * vec4(_TANGENT.xyz, 0.)).xyz, _TANGENT.w);
|
|
1088
|
+
#endif
|
|
1089
|
+
|
|
1090
|
+
pbr_setPositionNormalTangentUV(pos, _NORMAL, _TANGENT, _TEXCOORD_0);
|
|
1091
|
+
gl_Position = pbrProjection.modelViewProjectionMatrix * pos;
|
|
405
1092
|
}
|
|
406
1093
|
`
|
|
407
1094
|
);
|
|
@@ -416,9 +1103,24 @@ var fs = (
|
|
|
416
1103
|
}
|
|
417
1104
|
`
|
|
418
1105
|
);
|
|
1106
|
+
function createGLTFMaterial(device, options) {
|
|
1107
|
+
const materialFactory = options.materialFactory || new import_engine3.MaterialFactory(device, { modules: [import_shadertools.pbrMaterial] });
|
|
1108
|
+
const pbrMaterialProps = { ...options.parsedPPBRMaterial.uniforms };
|
|
1109
|
+
delete pbrMaterialProps.camera;
|
|
1110
|
+
const materialBindings = Object.fromEntries(Object.entries({
|
|
1111
|
+
...pbrMaterialProps,
|
|
1112
|
+
...options.parsedPPBRMaterial.bindings
|
|
1113
|
+
}).filter(([name, value]) => materialFactory.ownsBinding(name) && isMaterialBindingResource(value)));
|
|
1114
|
+
const material = materialFactory.createMaterial({
|
|
1115
|
+
id: options.id,
|
|
1116
|
+
bindings: materialBindings
|
|
1117
|
+
});
|
|
1118
|
+
material.setProps({ pbrMaterial: pbrMaterialProps });
|
|
1119
|
+
return material;
|
|
1120
|
+
}
|
|
419
1121
|
function createGLTFModel(device, options) {
|
|
420
1122
|
const { id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {} } = options;
|
|
421
|
-
|
|
1123
|
+
import_core3.log.info(4, "createGLTFModel defines: ", parsedPPBRMaterial.defines)();
|
|
422
1124
|
const managedResources = [];
|
|
423
1125
|
const parameters = {
|
|
424
1126
|
depthWriteEnabled: true,
|
|
@@ -434,20 +1136,53 @@ function createGLTFModel(device, options) {
|
|
|
434
1136
|
geometry,
|
|
435
1137
|
topology: geometry.topology,
|
|
436
1138
|
vertexCount,
|
|
437
|
-
modules: [import_shadertools.pbrMaterial],
|
|
1139
|
+
modules: [import_shadertools.pbrMaterial, import_shadertools.skin],
|
|
438
1140
|
...modelOptions,
|
|
439
1141
|
defines: { ...parsedPPBRMaterial.defines, ...modelOptions.defines },
|
|
440
1142
|
parameters: { ...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters }
|
|
441
1143
|
};
|
|
442
|
-
const
|
|
443
|
-
|
|
1144
|
+
const material = options.material || createGLTFMaterial(device, {
|
|
1145
|
+
id: id ? `${id}-material` : void 0,
|
|
1146
|
+
parsedPPBRMaterial
|
|
1147
|
+
});
|
|
1148
|
+
modelProps.material = material;
|
|
1149
|
+
const model = new import_engine3.Model(device, modelProps);
|
|
1150
|
+
const sceneShaderInputValues = {
|
|
444
1151
|
...parsedPPBRMaterial.uniforms,
|
|
445
1152
|
...modelOptions.uniforms,
|
|
446
1153
|
...parsedPPBRMaterial.bindings,
|
|
447
1154
|
...modelOptions.bindings
|
|
448
1155
|
};
|
|
449
|
-
model.shaderInputs.
|
|
450
|
-
|
|
1156
|
+
const sceneShaderInputProps = getSceneShaderInputProps(model.shaderInputs.getModules(), material, sceneShaderInputValues);
|
|
1157
|
+
model.shaderInputs.setProps(sceneShaderInputProps);
|
|
1158
|
+
return new import_engine3.ModelNode({ managedResources, model });
|
|
1159
|
+
}
|
|
1160
|
+
function isMaterialBindingResource(value) {
|
|
1161
|
+
return value instanceof import_core3.Buffer || value instanceof import_engine2.DynamicTexture || value instanceof import_core3.Sampler || value instanceof import_core3.Texture || value instanceof import_core3.TextureView;
|
|
1162
|
+
}
|
|
1163
|
+
function getSceneShaderInputProps(modules, material, shaderInputValues) {
|
|
1164
|
+
const propertyToModuleNameMap = /* @__PURE__ */ new Map();
|
|
1165
|
+
for (const module2 of modules) {
|
|
1166
|
+
for (const uniformName of Object.keys(module2.uniformTypes || {})) {
|
|
1167
|
+
propertyToModuleNameMap.set(uniformName, module2.name);
|
|
1168
|
+
}
|
|
1169
|
+
for (const binding of module2.bindingLayout || []) {
|
|
1170
|
+
propertyToModuleNameMap.set(binding.name, module2.name);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
const sceneShaderInputProps = {};
|
|
1174
|
+
for (const [propertyName, value] of Object.entries(shaderInputValues)) {
|
|
1175
|
+
if (value === void 0) {
|
|
1176
|
+
continue;
|
|
1177
|
+
}
|
|
1178
|
+
const moduleName = propertyToModuleNameMap.get(propertyName);
|
|
1179
|
+
if (!moduleName || material.ownsModule(moduleName)) {
|
|
1180
|
+
continue;
|
|
1181
|
+
}
|
|
1182
|
+
sceneShaderInputProps[moduleName] ||= {};
|
|
1183
|
+
sceneShaderInputProps[moduleName][propertyName] = value;
|
|
1184
|
+
}
|
|
1185
|
+
return sceneShaderInputProps;
|
|
451
1186
|
}
|
|
452
1187
|
|
|
453
1188
|
// dist/parsers/parse-gltf.js
|
|
@@ -458,73 +1193,103 @@ var defaultOptions = {
|
|
|
458
1193
|
lights: true,
|
|
459
1194
|
useTangents: false
|
|
460
1195
|
};
|
|
461
|
-
function parseGLTF(device, gltf,
|
|
462
|
-
const
|
|
463
|
-
const
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
1196
|
+
function parseGLTF(device, gltf, options = {}) {
|
|
1197
|
+
const combinedOptions = { ...defaultOptions, ...options };
|
|
1198
|
+
const materialFactory = new import_engine4.MaterialFactory(device, { modules: [import_shadertools2.pbrMaterial] });
|
|
1199
|
+
const materials = (gltf.materials || []).map((gltfMaterial, materialIndex) => createGLTFMaterial(device, {
|
|
1200
|
+
id: getGLTFMaterialId(gltfMaterial, materialIndex),
|
|
1201
|
+
parsedPPBRMaterial: parsePBRMaterial(device, gltfMaterial, {}, {
|
|
1202
|
+
...combinedOptions,
|
|
1203
|
+
gltf,
|
|
1204
|
+
validateAttributes: false
|
|
1205
|
+
}),
|
|
1206
|
+
materialFactory
|
|
1207
|
+
}));
|
|
1208
|
+
const gltfMaterialIdToMaterialMap = /* @__PURE__ */ new Map();
|
|
1209
|
+
(gltf.materials || []).forEach((gltfMaterial, materialIndex) => {
|
|
1210
|
+
gltfMaterialIdToMaterialMap.set(gltfMaterial.id, materials[materialIndex]);
|
|
472
1211
|
});
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
1212
|
+
const gltfMeshIdToNodeMap = /* @__PURE__ */ new Map();
|
|
1213
|
+
gltf.meshes.forEach((gltfMesh, idx) => {
|
|
1214
|
+
const newMesh = createNodeForGLTFMesh(device, gltfMesh, gltf, gltfMaterialIdToMaterialMap, combinedOptions);
|
|
1215
|
+
gltfMeshIdToNodeMap.set(gltfMesh.id, newMesh);
|
|
1216
|
+
});
|
|
1217
|
+
const gltfNodeIndexToNodeMap = /* @__PURE__ */ new Map();
|
|
1218
|
+
const gltfNodeIdToNodeMap = /* @__PURE__ */ new Map();
|
|
1219
|
+
gltf.nodes.forEach((gltfNode, idx) => {
|
|
1220
|
+
const newNode = createNodeForGLTFNode(device, gltfNode, combinedOptions);
|
|
1221
|
+
gltfNodeIndexToNodeMap.set(idx, newNode);
|
|
1222
|
+
gltfNodeIdToNodeMap.set(gltfNode.id, newNode);
|
|
1223
|
+
});
|
|
1224
|
+
gltf.nodes.forEach((gltfNode, idx) => {
|
|
1225
|
+
gltfNodeIndexToNodeMap.get(idx).add((gltfNode.children ?? []).map(({ id }) => {
|
|
1226
|
+
const child = gltfNodeIdToNodeMap.get(id);
|
|
1227
|
+
if (!child)
|
|
1228
|
+
throw new Error(`Cannot find child ${id} of node ${idx}`);
|
|
1229
|
+
return child;
|
|
1230
|
+
}));
|
|
479
1231
|
if (gltfNode.mesh) {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
id: gltfNode.name || gltfNode.id,
|
|
484
|
-
children
|
|
485
|
-
});
|
|
486
|
-
if (gltfNode.matrix) {
|
|
487
|
-
node.setMatrix(gltfNode.matrix);
|
|
488
|
-
} else {
|
|
489
|
-
node.matrix.identity();
|
|
490
|
-
if (gltfNode.translation) {
|
|
491
|
-
node.matrix.translate(gltfNode.translation);
|
|
492
|
-
}
|
|
493
|
-
if (gltfNode.rotation) {
|
|
494
|
-
const rotationMatrix = new import_core3.Matrix4().fromQuaternion(gltfNode.rotation);
|
|
495
|
-
node.matrix.multiplyRight(rotationMatrix);
|
|
496
|
-
}
|
|
497
|
-
if (gltfNode.scale) {
|
|
498
|
-
node.matrix.scale(gltfNode.scale);
|
|
1232
|
+
const mesh = gltfMeshIdToNodeMap.get(gltfNode.mesh.id);
|
|
1233
|
+
if (!mesh) {
|
|
1234
|
+
throw new Error(`Cannot find mesh child ${gltfNode.mesh.id} of node ${idx}`);
|
|
499
1235
|
}
|
|
1236
|
+
gltfNodeIndexToNodeMap.get(idx).add(mesh);
|
|
500
1237
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
if (!gltfMesh._mesh) {
|
|
509
|
-
const gltfPrimitives = gltfMesh.primitives || [];
|
|
510
|
-
const primitives = gltfPrimitives.map((gltfPrimitive, i) => createPrimitive(device, gltfPrimitive, i, gltfMesh, options));
|
|
511
|
-
const mesh = new import_engine3.GroupNode({
|
|
512
|
-
id: gltfMesh.name || gltfMesh.id,
|
|
513
|
-
children: primitives
|
|
1238
|
+
});
|
|
1239
|
+
const scenes = gltf.scenes.map((gltfScene) => {
|
|
1240
|
+
const children = (gltfScene.nodes || []).map(({ id }) => {
|
|
1241
|
+
const child = gltfNodeIdToNodeMap.get(id);
|
|
1242
|
+
if (!child)
|
|
1243
|
+
throw new Error(`Cannot find child ${id} of scene ${gltfScene.name || gltfScene.id}`);
|
|
1244
|
+
return child;
|
|
514
1245
|
});
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
1246
|
+
return new import_engine4.GroupNode({
|
|
1247
|
+
id: gltfScene.name || gltfScene.id,
|
|
1248
|
+
children
|
|
1249
|
+
});
|
|
1250
|
+
});
|
|
1251
|
+
return { scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap };
|
|
518
1252
|
}
|
|
519
|
-
function
|
|
520
|
-
|
|
1253
|
+
function createNodeForGLTFNode(device, gltfNode, options) {
|
|
1254
|
+
return new import_engine4.GroupNode({
|
|
1255
|
+
id: gltfNode.name || gltfNode.id,
|
|
1256
|
+
children: [],
|
|
1257
|
+
matrix: gltfNode.matrix,
|
|
1258
|
+
position: gltfNode.translation,
|
|
1259
|
+
rotation: gltfNode.rotation,
|
|
1260
|
+
scale: gltfNode.scale
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1263
|
+
function createNodeForGLTFMesh(device, gltfMesh, gltf, gltfMaterialIdToMaterialMap, options) {
|
|
1264
|
+
const gltfPrimitives = gltfMesh.primitives || [];
|
|
1265
|
+
const primitives = gltfPrimitives.map((gltfPrimitive, i) => createNodeForGLTFPrimitive({
|
|
1266
|
+
device,
|
|
1267
|
+
gltfPrimitive,
|
|
1268
|
+
primitiveIndex: i,
|
|
1269
|
+
gltfMesh,
|
|
1270
|
+
gltf,
|
|
1271
|
+
gltfMaterialIdToMaterialMap,
|
|
1272
|
+
options
|
|
1273
|
+
}));
|
|
1274
|
+
const mesh = new import_engine4.GroupNode({
|
|
1275
|
+
id: gltfMesh.name || gltfMesh.id,
|
|
1276
|
+
children: primitives
|
|
1277
|
+
});
|
|
1278
|
+
return mesh;
|
|
1279
|
+
}
|
|
1280
|
+
function createNodeForGLTFPrimitive({ device, gltfPrimitive, primitiveIndex, gltfMesh, gltf, gltfMaterialIdToMaterialMap, options }) {
|
|
1281
|
+
const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${primitiveIndex}`;
|
|
521
1282
|
const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);
|
|
522
1283
|
const vertexCount = gltfPrimitive.indices ? gltfPrimitive.indices.count : getVertexCount(gltfPrimitive.attributes);
|
|
523
1284
|
const geometry = createGeometry(id, gltfPrimitive, topology);
|
|
524
|
-
const parsedPPBRMaterial = parsePBRMaterial(device, gltfPrimitive.material, geometry.attributes,
|
|
1285
|
+
const parsedPPBRMaterial = parsePBRMaterial(device, gltfPrimitive.material, geometry.attributes, {
|
|
1286
|
+
...options,
|
|
1287
|
+
gltf
|
|
1288
|
+
});
|
|
525
1289
|
const modelNode = createGLTFModel(device, {
|
|
526
1290
|
id,
|
|
527
1291
|
geometry: createGeometry(id, gltfPrimitive, topology),
|
|
1292
|
+
material: gltfPrimitive.material ? gltfMaterialIdToMaterialMap.get(gltfPrimitive.material.id) || null : null,
|
|
528
1293
|
parsedPPBRMaterial,
|
|
529
1294
|
modelOptions: options.modelOptions,
|
|
530
1295
|
vertexCount
|
|
@@ -541,42 +1306,41 @@ function createGeometry(id, gltfPrimitive, topology) {
|
|
|
541
1306
|
const { components, size, value } = attribute;
|
|
542
1307
|
attributes[attributeName] = { size: size ?? components, value };
|
|
543
1308
|
}
|
|
544
|
-
return new
|
|
1309
|
+
return new import_engine4.Geometry({
|
|
545
1310
|
id,
|
|
546
1311
|
topology,
|
|
547
1312
|
indices: gltfPrimitive.indices.value,
|
|
548
1313
|
attributes
|
|
549
1314
|
});
|
|
550
1315
|
}
|
|
1316
|
+
function getGLTFMaterialId(gltfMaterial, materialIndex) {
|
|
1317
|
+
return gltfMaterial.name || gltfMaterial.id || `material-${materialIndex}`;
|
|
1318
|
+
}
|
|
551
1319
|
|
|
552
1320
|
// dist/gltf/gltf-animator.js
|
|
553
1321
|
var import_core6 = require("@luma.gl/core");
|
|
554
|
-
var import_core7 = require("@math.gl/core");
|
|
555
1322
|
|
|
556
1323
|
// dist/gltf/animations/interpolate.js
|
|
557
1324
|
var import_core4 = require("@luma.gl/core");
|
|
558
1325
|
var import_core5 = require("@math.gl/core");
|
|
559
|
-
|
|
1326
|
+
function updateTargetPath(target, path, newValue) {
|
|
1327
|
+
switch (path) {
|
|
1328
|
+
case "translation":
|
|
1329
|
+
return target.setPosition(newValue).updateMatrix();
|
|
1330
|
+
case "rotation":
|
|
1331
|
+
return target.setRotation(newValue).updateMatrix();
|
|
1332
|
+
case "scale":
|
|
1333
|
+
return target.setScale(newValue).updateMatrix();
|
|
1334
|
+
default:
|
|
1335
|
+
import_core4.log.warn(`Bad animation path ${path}`)();
|
|
1336
|
+
return null;
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
560
1339
|
function interpolate(time, { input, interpolation, output }, target, path) {
|
|
561
1340
|
const maxTime = input[input.length - 1];
|
|
562
1341
|
const animationTime = time % maxTime;
|
|
563
1342
|
const nextIndex = input.findIndex((t) => t >= animationTime);
|
|
564
1343
|
const previousIndex = Math.max(0, nextIndex - 1);
|
|
565
|
-
if (!Array.isArray(target[path])) {
|
|
566
|
-
switch (path) {
|
|
567
|
-
case "translation":
|
|
568
|
-
target[path] = [0, 0, 0];
|
|
569
|
-
break;
|
|
570
|
-
case "rotation":
|
|
571
|
-
target[path] = [0, 0, 0, 1];
|
|
572
|
-
break;
|
|
573
|
-
case "scale":
|
|
574
|
-
target[path] = [1, 1, 1];
|
|
575
|
-
break;
|
|
576
|
-
default:
|
|
577
|
-
import_core4.log.warn(`Bad animation path ${path}`)();
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
1344
|
const previousTime = input[previousIndex];
|
|
581
1345
|
const nextTime = input[nextIndex];
|
|
582
1346
|
switch (interpolation) {
|
|
@@ -606,68 +1370,73 @@ function interpolate(time, { input, interpolation, output }, target, path) {
|
|
|
606
1370
|
}
|
|
607
1371
|
}
|
|
608
1372
|
function linearInterpolate(target, path, start, stop, ratio) {
|
|
609
|
-
if (!target[path]) {
|
|
610
|
-
throw new Error();
|
|
611
|
-
}
|
|
612
1373
|
if (path === "rotation") {
|
|
613
|
-
|
|
614
|
-
for (let i = 0; i < scratchQuaternion.length; i++) {
|
|
615
|
-
target[path][i] = scratchQuaternion[i];
|
|
616
|
-
}
|
|
1374
|
+
updateTargetPath(target, path, new import_core5.Quaternion().slerp({ start, target: stop, ratio }));
|
|
617
1375
|
} else {
|
|
1376
|
+
const newVal = [];
|
|
618
1377
|
for (let i = 0; i < start.length; i++) {
|
|
619
|
-
|
|
1378
|
+
newVal[i] = ratio * stop[i] + (1 - ratio) * start[i];
|
|
620
1379
|
}
|
|
1380
|
+
updateTargetPath(target, path, newVal);
|
|
621
1381
|
}
|
|
622
1382
|
}
|
|
623
1383
|
function cubicsplineInterpolate(target, path, { p0, outTangent0, inTangent1, p1, tDiff, ratio: t }) {
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
}
|
|
627
|
-
for (let i = 0; i < target[path].length; i++) {
|
|
1384
|
+
const newVal = [];
|
|
1385
|
+
for (let i = 0; i < p0.length; i++) {
|
|
628
1386
|
const m0 = outTangent0[i] * tDiff;
|
|
629
1387
|
const m1 = inTangent1[i] * tDiff;
|
|
630
|
-
|
|
1388
|
+
newVal[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;
|
|
631
1389
|
}
|
|
1390
|
+
updateTargetPath(target, path, newVal);
|
|
632
1391
|
}
|
|
633
1392
|
function stepInterpolate(target, path, value) {
|
|
634
|
-
|
|
635
|
-
throw new Error();
|
|
636
|
-
}
|
|
637
|
-
for (let i = 0; i < value.length; i++) {
|
|
638
|
-
target[path][i] = value[i];
|
|
639
|
-
}
|
|
1393
|
+
updateTargetPath(target, path, value);
|
|
640
1394
|
}
|
|
641
1395
|
|
|
642
1396
|
// dist/gltf/gltf-animator.js
|
|
643
1397
|
var GLTFSingleAnimator = class {
|
|
1398
|
+
/** Animation definition being played. */
|
|
644
1399
|
animation;
|
|
1400
|
+
/** Target scenegraph lookup table. */
|
|
1401
|
+
gltfNodeIdToNodeMap;
|
|
1402
|
+
/** Playback start time in seconds. */
|
|
645
1403
|
startTime = 0;
|
|
1404
|
+
/** Whether playback is currently enabled. */
|
|
646
1405
|
playing = true;
|
|
1406
|
+
/** Playback speed multiplier. */
|
|
647
1407
|
speed = 1;
|
|
1408
|
+
/** Creates a single-animation controller. */
|
|
648
1409
|
constructor(props) {
|
|
649
1410
|
this.animation = props.animation;
|
|
1411
|
+
this.gltfNodeIdToNodeMap = props.gltfNodeIdToNodeMap;
|
|
650
1412
|
this.animation.name ||= "unnamed";
|
|
651
1413
|
Object.assign(this, props);
|
|
652
1414
|
}
|
|
1415
|
+
/** Advances the animation to the supplied wall-clock time in milliseconds. */
|
|
653
1416
|
setTime(timeMs) {
|
|
654
1417
|
if (!this.playing) {
|
|
655
1418
|
return;
|
|
656
1419
|
}
|
|
657
1420
|
const absTime = timeMs / 1e3;
|
|
658
1421
|
const time = (absTime - this.startTime) * this.speed;
|
|
659
|
-
this.animation.channels.forEach(({ sampler,
|
|
660
|
-
|
|
661
|
-
|
|
1422
|
+
this.animation.channels.forEach(({ sampler, targetNodeId, path }) => {
|
|
1423
|
+
const targetNode = this.gltfNodeIdToNodeMap.get(targetNodeId);
|
|
1424
|
+
if (!targetNode) {
|
|
1425
|
+
throw new Error(`Cannot find animation target node ${targetNodeId}`);
|
|
1426
|
+
}
|
|
1427
|
+
interpolate(time, sampler, targetNode, path);
|
|
662
1428
|
});
|
|
663
1429
|
}
|
|
664
1430
|
};
|
|
665
1431
|
var GLTFAnimator = class {
|
|
1432
|
+
/** Individual animation controllers. */
|
|
666
1433
|
animations;
|
|
1434
|
+
/** Creates an animator for the supplied glTF scenegraph. */
|
|
667
1435
|
constructor(props) {
|
|
668
1436
|
this.animations = props.animations.map((animation, index) => {
|
|
669
1437
|
const name = animation.name || `Animation-${index}`;
|
|
670
1438
|
return new GLTFSingleAnimator({
|
|
1439
|
+
gltfNodeIdToNodeMap: props.gltfNodeIdToNodeMap,
|
|
671
1440
|
animation: { name, channels: animation.channels }
|
|
672
1441
|
});
|
|
673
1442
|
});
|
|
@@ -677,27 +1446,18 @@ var GLTFAnimator = class {
|
|
|
677
1446
|
import_core6.log.warn("GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead")();
|
|
678
1447
|
this.setTime(time);
|
|
679
1448
|
}
|
|
1449
|
+
/** Advances every animation to the supplied wall-clock time in milliseconds. */
|
|
680
1450
|
setTime(time) {
|
|
681
1451
|
this.animations.forEach((animation) => animation.setTime(time));
|
|
682
1452
|
}
|
|
1453
|
+
/** Returns the per-animation controllers managed by this animator. */
|
|
683
1454
|
getAnimations() {
|
|
684
1455
|
return this.animations;
|
|
685
1456
|
}
|
|
686
1457
|
};
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
if (gltfNode.translation) {
|
|
691
|
-
node.matrix.translate(gltfNode.translation);
|
|
692
|
-
}
|
|
693
|
-
if (gltfNode.rotation) {
|
|
694
|
-
const rotationMatrix = scratchMatrix.fromQuaternion(gltfNode.rotation);
|
|
695
|
-
node.matrix.multiplyRight(rotationMatrix);
|
|
696
|
-
}
|
|
697
|
-
if (gltfNode.scale) {
|
|
698
|
-
node.matrix.scale(gltfNode.scale);
|
|
699
|
-
}
|
|
700
|
-
}
|
|
1458
|
+
|
|
1459
|
+
// dist/parsers/parse-gltf-animations.js
|
|
1460
|
+
var import_core7 = require("@luma.gl/core");
|
|
701
1461
|
|
|
702
1462
|
// dist/webgl-to-webgpu/convert-webgl-attribute.js
|
|
703
1463
|
var ATTRIBUTE_TYPE_TO_COMPONENTS = {
|
|
@@ -730,61 +1490,327 @@ function accessorToTypedArray(accessor) {
|
|
|
730
1490
|
// dist/parsers/parse-gltf-animations.js
|
|
731
1491
|
function parseGLTFAnimations(gltf) {
|
|
732
1492
|
const gltfAnimations = gltf.animations || [];
|
|
733
|
-
|
|
1493
|
+
const accessorCache1D = /* @__PURE__ */ new Map();
|
|
1494
|
+
const accessorCache2D = /* @__PURE__ */ new Map();
|
|
1495
|
+
return gltfAnimations.flatMap((animation, index) => {
|
|
734
1496
|
const name = animation.name || `Animation-${index}`;
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
1497
|
+
const samplerCache = /* @__PURE__ */ new Map();
|
|
1498
|
+
const channels = animation.channels.flatMap(({ sampler, target }) => {
|
|
1499
|
+
const path = getSupportedAnimationPath(target.path);
|
|
1500
|
+
if (!path) {
|
|
1501
|
+
return [];
|
|
1502
|
+
}
|
|
1503
|
+
const targetNode = gltf.nodes[target.node ?? 0];
|
|
1504
|
+
if (!targetNode) {
|
|
1505
|
+
throw new Error(`Cannot find animation target ${target.node}`);
|
|
1506
|
+
}
|
|
1507
|
+
let parsedSampler = samplerCache.get(sampler);
|
|
1508
|
+
if (!parsedSampler) {
|
|
1509
|
+
const gltfSampler = animation.samplers[sampler];
|
|
1510
|
+
if (!gltfSampler) {
|
|
1511
|
+
throw new Error(`Cannot find animation sampler ${sampler}`);
|
|
1512
|
+
}
|
|
1513
|
+
const { input, interpolation = "LINEAR", output } = gltfSampler;
|
|
1514
|
+
parsedSampler = {
|
|
1515
|
+
input: accessorToJsArray1D(gltf.accessors[input], accessorCache1D),
|
|
1516
|
+
interpolation,
|
|
1517
|
+
output: accessorToJsArray2D(gltf.accessors[output], accessorCache2D)
|
|
1518
|
+
};
|
|
1519
|
+
samplerCache.set(sampler, parsedSampler);
|
|
1520
|
+
}
|
|
1521
|
+
return {
|
|
1522
|
+
sampler: parsedSampler,
|
|
1523
|
+
targetNodeId: targetNode.id,
|
|
1524
|
+
path
|
|
1525
|
+
};
|
|
1526
|
+
});
|
|
1527
|
+
return channels.length ? [{ name, channels }] : [];
|
|
746
1528
|
});
|
|
747
1529
|
}
|
|
748
|
-
function
|
|
749
|
-
if (
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
1530
|
+
function getSupportedAnimationPath(path) {
|
|
1531
|
+
if (path === "pointer") {
|
|
1532
|
+
import_core7.log.warn("KHR_animation_pointer channels are not supported and will be skipped")();
|
|
1533
|
+
return null;
|
|
1534
|
+
}
|
|
1535
|
+
return path;
|
|
1536
|
+
}
|
|
1537
|
+
function accessorToJsArray1D(accessor, accessorCache) {
|
|
1538
|
+
if (accessorCache.has(accessor)) {
|
|
1539
|
+
return accessorCache.get(accessor);
|
|
1540
|
+
}
|
|
1541
|
+
const { typedArray: array, components } = accessorToTypedArray(accessor);
|
|
1542
|
+
assert(components === 1, "accessorToJsArray1D must have exactly 1 component");
|
|
1543
|
+
const result = Array.from(array);
|
|
1544
|
+
accessorCache.set(accessor, result);
|
|
1545
|
+
return result;
|
|
1546
|
+
}
|
|
1547
|
+
function accessorToJsArray2D(accessor, accessorCache) {
|
|
1548
|
+
if (accessorCache.has(accessor)) {
|
|
1549
|
+
return accessorCache.get(accessor);
|
|
1550
|
+
}
|
|
1551
|
+
const { typedArray: array, components } = accessorToTypedArray(accessor);
|
|
1552
|
+
assert(components >= 1, "accessorToJsArray2D must have at least 1 component");
|
|
1553
|
+
const result = [];
|
|
1554
|
+
for (let i = 0; i < array.length; i += components) {
|
|
1555
|
+
result.push(Array.from(array.slice(i, i + components)));
|
|
1556
|
+
}
|
|
1557
|
+
accessorCache.set(accessor, result);
|
|
1558
|
+
return result;
|
|
1559
|
+
}
|
|
1560
|
+
function assert(condition, message) {
|
|
1561
|
+
if (!condition) {
|
|
1562
|
+
throw new Error(message);
|
|
760
1563
|
}
|
|
761
|
-
return accessor._animation;
|
|
762
1564
|
}
|
|
763
1565
|
|
|
764
|
-
// dist/
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
1566
|
+
// dist/gltf/gltf-extension-support.js
|
|
1567
|
+
var UNKNOWN_EXTENSION_SUPPORT = {
|
|
1568
|
+
supportLevel: "none",
|
|
1569
|
+
comment: "Not currently listed in the luma.gl glTF extension support registry."
|
|
1570
|
+
};
|
|
1571
|
+
var GLTF_EXTENSION_SUPPORT_REGISTRY = {
|
|
1572
|
+
KHR_draco_mesh_compression: {
|
|
1573
|
+
supportLevel: "built-in",
|
|
1574
|
+
comment: "Decoded by loaders.gl before luma.gl builds the scenegraph."
|
|
1575
|
+
},
|
|
1576
|
+
EXT_meshopt_compression: {
|
|
1577
|
+
supportLevel: "built-in",
|
|
1578
|
+
comment: "Meshopt-compressed primitives are decoded during load."
|
|
1579
|
+
},
|
|
1580
|
+
KHR_mesh_quantization: {
|
|
1581
|
+
supportLevel: "built-in",
|
|
1582
|
+
comment: "Quantized accessors are unpacked before geometry creation."
|
|
1583
|
+
},
|
|
1584
|
+
KHR_lights_punctual: {
|
|
1585
|
+
supportLevel: "built-in",
|
|
1586
|
+
comment: "Parsed into luma.gl Light objects."
|
|
1587
|
+
},
|
|
1588
|
+
KHR_materials_unlit: {
|
|
1589
|
+
supportLevel: "built-in",
|
|
1590
|
+
comment: "Unlit materials bypass the default lighting path."
|
|
1591
|
+
},
|
|
1592
|
+
KHR_materials_emissive_strength: {
|
|
1593
|
+
supportLevel: "built-in",
|
|
1594
|
+
comment: "Applied by the stock PBR shader."
|
|
1595
|
+
},
|
|
1596
|
+
KHR_texture_basisu: {
|
|
1597
|
+
supportLevel: "built-in",
|
|
1598
|
+
comment: "BasisU / KTX2 textures pass through when the device supports them."
|
|
1599
|
+
},
|
|
1600
|
+
KHR_texture_transform: {
|
|
1601
|
+
supportLevel: "built-in",
|
|
1602
|
+
comment: "UV transforms are applied during load."
|
|
1603
|
+
},
|
|
1604
|
+
EXT_texture_webp: {
|
|
1605
|
+
supportLevel: "loader-only",
|
|
1606
|
+
comment: "Texture source is resolved during load; final support depends on browser and device decode support."
|
|
1607
|
+
},
|
|
1608
|
+
EXT_texture_avif: {
|
|
1609
|
+
supportLevel: "loader-only",
|
|
1610
|
+
comment: "Texture source is resolved during load; final support depends on browser and device decode support."
|
|
1611
|
+
},
|
|
1612
|
+
KHR_materials_specular: {
|
|
1613
|
+
supportLevel: "built-in",
|
|
1614
|
+
comment: "The stock shader now applies specular factors and textures to the dielectric F0 term."
|
|
1615
|
+
},
|
|
1616
|
+
KHR_materials_ior: {
|
|
1617
|
+
supportLevel: "built-in",
|
|
1618
|
+
comment: "The stock shader now drives dielectric reflectance from the glTF IOR value."
|
|
1619
|
+
},
|
|
1620
|
+
KHR_materials_transmission: {
|
|
1621
|
+
supportLevel: "built-in",
|
|
1622
|
+
comment: "The stock shader now applies transmission to the base layer and exposes transparency through alpha, without a scene-color refraction buffer."
|
|
1623
|
+
},
|
|
1624
|
+
KHR_materials_volume: {
|
|
1625
|
+
supportLevel: "built-in",
|
|
1626
|
+
comment: "Thickness and attenuation now tint transmitted light in the stock shader."
|
|
1627
|
+
},
|
|
1628
|
+
KHR_materials_clearcoat: {
|
|
1629
|
+
supportLevel: "built-in",
|
|
1630
|
+
comment: "The stock shader now adds a secondary clearcoat specular lobe."
|
|
1631
|
+
},
|
|
1632
|
+
KHR_materials_sheen: {
|
|
1633
|
+
supportLevel: "built-in",
|
|
1634
|
+
comment: "The stock shader now adds a sheen lobe for cloth-like materials."
|
|
1635
|
+
},
|
|
1636
|
+
KHR_materials_iridescence: {
|
|
1637
|
+
supportLevel: "built-in",
|
|
1638
|
+
comment: "The stock shader now tints specular response with a view-dependent thin-film iridescence approximation."
|
|
1639
|
+
},
|
|
1640
|
+
KHR_materials_anisotropy: {
|
|
1641
|
+
supportLevel: "built-in",
|
|
1642
|
+
comment: "The stock shader now shapes highlights and IBL response with an anisotropy-direction approximation."
|
|
1643
|
+
},
|
|
1644
|
+
KHR_materials_pbrSpecularGlossiness: {
|
|
1645
|
+
supportLevel: "loader-only",
|
|
1646
|
+
comment: "Extension data can be loaded, but it is not translated into the default metallic-roughness material path."
|
|
1647
|
+
},
|
|
1648
|
+
KHR_materials_variants: {
|
|
1649
|
+
supportLevel: "loader-only",
|
|
1650
|
+
comment: "Variant metadata can be loaded, but applications must choose and apply variants."
|
|
1651
|
+
},
|
|
1652
|
+
EXT_mesh_gpu_instancing: {
|
|
1653
|
+
supportLevel: "none",
|
|
1654
|
+
comment: "GPU instancing data is not yet converted into luma.gl instanced draw setup."
|
|
1655
|
+
},
|
|
1656
|
+
KHR_node_visibility: {
|
|
1657
|
+
supportLevel: "none",
|
|
1658
|
+
comment: "Node-visibility animations and toggles are not mapped onto runtime scenegraph state."
|
|
1659
|
+
},
|
|
1660
|
+
KHR_animation_pointer: {
|
|
1661
|
+
supportLevel: "none",
|
|
1662
|
+
comment: "Animation pointers are not mapped onto runtime scenegraph updates."
|
|
1663
|
+
},
|
|
1664
|
+
KHR_materials_diffuse_transmission: {
|
|
1665
|
+
supportLevel: "none",
|
|
1666
|
+
comment: "Diffuse-transmission shading is not implemented in the stock PBR shader."
|
|
1667
|
+
},
|
|
1668
|
+
KHR_materials_dispersion: {
|
|
1669
|
+
supportLevel: "none",
|
|
1670
|
+
comment: "Chromatic dispersion is not implemented in the stock PBR shader."
|
|
1671
|
+
},
|
|
1672
|
+
KHR_materials_volume_scatter: {
|
|
1673
|
+
supportLevel: "none",
|
|
1674
|
+
comment: "Volume scattering is not implemented in the stock PBR shader."
|
|
1675
|
+
},
|
|
1676
|
+
KHR_xmp: {
|
|
1677
|
+
supportLevel: "none",
|
|
1678
|
+
comment: "Metadata payloads remain in the loaded glTF, but luma.gl does not interpret them."
|
|
1679
|
+
},
|
|
1680
|
+
KHR_xmp_json_ld: {
|
|
1681
|
+
supportLevel: "none",
|
|
1682
|
+
comment: "Metadata is preserved in the glTF, but luma.gl does not interpret it."
|
|
1683
|
+
},
|
|
1684
|
+
EXT_lights_image_based: {
|
|
1685
|
+
supportLevel: "none",
|
|
1686
|
+
comment: "Use loadPBREnvironment() or custom environment setup instead."
|
|
1687
|
+
},
|
|
1688
|
+
EXT_texture_video: {
|
|
1689
|
+
supportLevel: "none",
|
|
1690
|
+
comment: "Video textures are not created automatically by the stock pipeline."
|
|
1691
|
+
},
|
|
1692
|
+
MSFT_lod: {
|
|
1693
|
+
supportLevel: "none",
|
|
1694
|
+
comment: "Level-of-detail switching is not implemented in the stock scenegraph loader."
|
|
768
1695
|
}
|
|
769
|
-
|
|
770
|
-
|
|
1696
|
+
};
|
|
1697
|
+
function getGLTFExtensionSupport(gltf) {
|
|
1698
|
+
const extensionNames = Array.from(collectGLTFExtensionNames(gltf)).sort();
|
|
1699
|
+
const extensionSupportEntries = extensionNames.map((extensionName) => {
|
|
1700
|
+
const extensionSupportDefinition = GLTF_EXTENSION_SUPPORT_REGISTRY[extensionName] || UNKNOWN_EXTENSION_SUPPORT;
|
|
1701
|
+
return [
|
|
1702
|
+
extensionName,
|
|
1703
|
+
{
|
|
1704
|
+
extensionName,
|
|
1705
|
+
supported: extensionSupportDefinition.supportLevel === "built-in",
|
|
1706
|
+
supportLevel: extensionSupportDefinition.supportLevel,
|
|
1707
|
+
comment: extensionSupportDefinition.comment
|
|
1708
|
+
}
|
|
1709
|
+
];
|
|
1710
|
+
});
|
|
1711
|
+
return new Map(extensionSupportEntries);
|
|
1712
|
+
}
|
|
1713
|
+
function collectGLTFExtensionNames(gltf) {
|
|
1714
|
+
var _a;
|
|
1715
|
+
const gltfWithRemovedExtensions = gltf;
|
|
1716
|
+
const extensionNames = /* @__PURE__ */ new Set();
|
|
1717
|
+
addExtensionNames(extensionNames, gltf.extensionsUsed);
|
|
1718
|
+
addExtensionNames(extensionNames, gltf.extensionsRequired);
|
|
1719
|
+
addExtensionNames(extensionNames, gltfWithRemovedExtensions.extensionsRemoved);
|
|
1720
|
+
addExtensionNames(extensionNames, Object.keys(gltf.extensions || {}));
|
|
1721
|
+
if (((_a = gltfWithRemovedExtensions.lights) == null ? void 0 : _a.length) || gltf.nodes.some((node) => "light" in node)) {
|
|
1722
|
+
extensionNames.add("KHR_lights_punctual");
|
|
771
1723
|
}
|
|
772
|
-
if (
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
1724
|
+
if (gltf.materials.some((material) => {
|
|
1725
|
+
var _a2;
|
|
1726
|
+
const gltfMaterial = material;
|
|
1727
|
+
return gltfMaterial.unlit || ((_a2 = gltfMaterial.extensions) == null ? void 0 : _a2.KHR_materials_unlit);
|
|
1728
|
+
})) {
|
|
1729
|
+
extensionNames.add("KHR_materials_unlit");
|
|
1730
|
+
}
|
|
1731
|
+
return extensionNames;
|
|
1732
|
+
}
|
|
1733
|
+
function addExtensionNames(extensionNames, newExtensionNames = []) {
|
|
1734
|
+
for (const extensionName of newExtensionNames) {
|
|
1735
|
+
extensionNames.add(extensionName);
|
|
778
1736
|
}
|
|
779
|
-
return object;
|
|
780
1737
|
}
|
|
781
1738
|
|
|
782
1739
|
// dist/gltf/create-scenegraph-from-gltf.js
|
|
783
1740
|
function createScenegraphsFromGLTF(device, gltf, options) {
|
|
784
|
-
|
|
785
|
-
const scenes = parseGLTF(device, gltf, options);
|
|
1741
|
+
const { scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap } = parseGLTF(device, gltf, options);
|
|
786
1742
|
const animations = parseGLTFAnimations(gltf);
|
|
787
|
-
const animator = new GLTFAnimator({ animations });
|
|
788
|
-
|
|
1743
|
+
const animator = new GLTFAnimator({ animations, gltfNodeIdToNodeMap });
|
|
1744
|
+
const lights = parseGLTFLights(gltf);
|
|
1745
|
+
const extensionSupport = getGLTFExtensionSupport(gltf);
|
|
1746
|
+
const sceneBounds = scenes.map((scene) => getScenegraphBounds(scene.getBounds()));
|
|
1747
|
+
const modelBounds = getCombinedScenegraphBounds(sceneBounds);
|
|
1748
|
+
return {
|
|
1749
|
+
scenes,
|
|
1750
|
+
materials,
|
|
1751
|
+
animator,
|
|
1752
|
+
lights,
|
|
1753
|
+
extensionSupport,
|
|
1754
|
+
sceneBounds,
|
|
1755
|
+
modelBounds,
|
|
1756
|
+
gltfMeshIdToNodeMap,
|
|
1757
|
+
gltfNodeIdToNodeMap,
|
|
1758
|
+
gltfNodeIndexToNodeMap,
|
|
1759
|
+
gltf
|
|
1760
|
+
};
|
|
1761
|
+
}
|
|
1762
|
+
function getScenegraphBounds(bounds) {
|
|
1763
|
+
if (!bounds) {
|
|
1764
|
+
return {
|
|
1765
|
+
bounds: null,
|
|
1766
|
+
center: [0, 0, 0],
|
|
1767
|
+
size: [0, 0, 0],
|
|
1768
|
+
radius: 0.5,
|
|
1769
|
+
recommendedOrbitDistance: 1
|
|
1770
|
+
};
|
|
1771
|
+
}
|
|
1772
|
+
const normalizedBounds = [
|
|
1773
|
+
[bounds[0][0], bounds[0][1], bounds[0][2]],
|
|
1774
|
+
[bounds[1][0], bounds[1][1], bounds[1][2]]
|
|
1775
|
+
];
|
|
1776
|
+
const size = [
|
|
1777
|
+
normalizedBounds[1][0] - normalizedBounds[0][0],
|
|
1778
|
+
normalizedBounds[1][1] - normalizedBounds[0][1],
|
|
1779
|
+
normalizedBounds[1][2] - normalizedBounds[0][2]
|
|
1780
|
+
];
|
|
1781
|
+
const center = [
|
|
1782
|
+
normalizedBounds[0][0] + size[0] * 0.5,
|
|
1783
|
+
normalizedBounds[0][1] + size[1] * 0.5,
|
|
1784
|
+
normalizedBounds[0][2] + size[2] * 0.5
|
|
1785
|
+
];
|
|
1786
|
+
const maxHalfExtent = Math.max(size[0], size[1], size[2]) * 0.5;
|
|
1787
|
+
const radius = Math.max(0.5 * Math.hypot(size[0], size[1], size[2]), 1e-3);
|
|
1788
|
+
return {
|
|
1789
|
+
bounds: normalizedBounds,
|
|
1790
|
+
center,
|
|
1791
|
+
size,
|
|
1792
|
+
radius,
|
|
1793
|
+
recommendedOrbitDistance: Math.max(Math.max(maxHalfExtent, 1e-3) / Math.tan(Math.PI / 6) * 1.15, radius * 1.1)
|
|
1794
|
+
};
|
|
1795
|
+
}
|
|
1796
|
+
function getCombinedScenegraphBounds(sceneBounds) {
|
|
1797
|
+
let combinedBounds = null;
|
|
1798
|
+
for (const sceneBoundInfo of sceneBounds) {
|
|
1799
|
+
if (!sceneBoundInfo.bounds) {
|
|
1800
|
+
continue;
|
|
1801
|
+
}
|
|
1802
|
+
if (!combinedBounds) {
|
|
1803
|
+
combinedBounds = [
|
|
1804
|
+
[...sceneBoundInfo.bounds[0]],
|
|
1805
|
+
[...sceneBoundInfo.bounds[1]]
|
|
1806
|
+
];
|
|
1807
|
+
continue;
|
|
1808
|
+
}
|
|
1809
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
1810
|
+
combinedBounds[0][axis] = Math.min(combinedBounds[0][axis], sceneBoundInfo.bounds[0][axis]);
|
|
1811
|
+
combinedBounds[1][axis] = Math.max(combinedBounds[1][axis], sceneBoundInfo.bounds[1][axis]);
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
return getScenegraphBounds(combinedBounds);
|
|
789
1815
|
}
|
|
790
1816
|
//# sourceMappingURL=index.cjs.map
|