@kitware/vtk.js 32.7.0 → 32.7.2
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.
|
@@ -133,7 +133,7 @@ function createAnimationSampler(glTFSampler) {
|
|
|
133
133
|
result = cubicSplineInterpolate(path, t0, t1, i0, i1, time);
|
|
134
134
|
break;
|
|
135
135
|
default:
|
|
136
|
-
|
|
136
|
+
vtkWarningMacro(`Unknown interpolation method: ${glTFSampler.interpolation}`);
|
|
137
137
|
}
|
|
138
138
|
return result;
|
|
139
139
|
}
|
|
@@ -101,7 +101,7 @@ class GLTFParser {
|
|
|
101
101
|
if (mesh.primitives) {
|
|
102
102
|
mesh.primitives = mesh.primitives.map((primitive, idx) => {
|
|
103
103
|
const attributes = primitive.attributes;
|
|
104
|
-
primitive.name = `
|
|
104
|
+
primitive.name = `primitive-${idx}`;
|
|
105
105
|
primitive.attributes = {};
|
|
106
106
|
for (const attribute in attributes) {
|
|
107
107
|
const attr = SEMANTIC_ATTRIBUTE_MAP[attribute];
|
|
@@ -30,18 +30,15 @@ async function parseGLTF(gltf, options) {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
* Creates VTK polydata from a GLTF mesh
|
|
34
|
-
* @param {
|
|
33
|
+
* Creates VTK polydata from a GLTF mesh primitive
|
|
34
|
+
* @param {GLTFPrimitive} primitive - The GLTF mesh primitive
|
|
35
35
|
* @returns {vtkPolyData} The created VTK polydata
|
|
36
36
|
*/
|
|
37
|
-
async function createPolyDataFromGLTFMesh(
|
|
38
|
-
const primitive = mesh.primitives[0]; // For simplicity, we'll just use the first primitive
|
|
39
|
-
|
|
37
|
+
async function createPolyDataFromGLTFMesh(primitive) {
|
|
40
38
|
if (!primitive || !primitive.attributes) {
|
|
41
|
-
vtkWarningMacro('
|
|
39
|
+
vtkWarningMacro('Primitive has no position data, skipping');
|
|
42
40
|
return null;
|
|
43
41
|
}
|
|
44
|
-
const mode = primitive.mode;
|
|
45
42
|
if (primitive.extensions?.KHR_draco_mesh_compression) {
|
|
46
43
|
return handleKHRDracoMeshCompression(primitive.extensions.KHR_draco_mesh_compression);
|
|
47
44
|
}
|
|
@@ -118,10 +115,10 @@ async function createPolyDataFromGLTFMesh(mesh) {
|
|
|
118
115
|
});
|
|
119
116
|
|
|
120
117
|
// Handle indices if available
|
|
121
|
-
if (primitive.indices
|
|
118
|
+
if (primitive.indices != null) {
|
|
122
119
|
const indices = primitive.indices.value;
|
|
123
120
|
const nCells = indices.length - 2;
|
|
124
|
-
switch (mode) {
|
|
121
|
+
switch (primitive.mode) {
|
|
125
122
|
case MODES.GL_LINE_STRIP:
|
|
126
123
|
case MODES.GL_TRIANGLE_STRIP:
|
|
127
124
|
case MODES.GL_LINE_LOOP:
|
|
@@ -135,7 +132,7 @@ async function createPolyDataFromGLTFMesh(mesh) {
|
|
|
135
132
|
}
|
|
136
133
|
}
|
|
137
134
|
}
|
|
138
|
-
switch (mode) {
|
|
135
|
+
switch (primitive.mode) {
|
|
139
136
|
case MODES.GL_TRIANGLES:
|
|
140
137
|
case MODES.GL_TRIANGLE_FAN:
|
|
141
138
|
polyData.setPolys(cells);
|
|
@@ -159,7 +156,7 @@ async function createPolyDataFromGLTFMesh(mesh) {
|
|
|
159
156
|
|
|
160
157
|
/**
|
|
161
158
|
* Creates a VTK property from a GLTF material
|
|
162
|
-
* @param {
|
|
159
|
+
* @param {object} model - The vtk model object
|
|
163
160
|
* @param {GLTFMaterial} material - The GLTF material
|
|
164
161
|
* @param {vtkActor} actor - The VTK actor
|
|
165
162
|
*/
|
|
@@ -169,15 +166,15 @@ async function createPropertyFromGLTFMaterial(model, material, actor) {
|
|
|
169
166
|
const emissiveFactor = material.emissiveFactor;
|
|
170
167
|
const property = actor.getProperty();
|
|
171
168
|
const pbr = material.pbrMetallicRoughness;
|
|
172
|
-
if (pbr
|
|
169
|
+
if (pbr != null) {
|
|
173
170
|
if (!pbr?.metallicFactor || pbr?.metallicFactor <= 0 || pbr?.metallicFactor >= 1) {
|
|
174
|
-
|
|
171
|
+
vtkDebugMacro('Invalid material.pbrMetallicRoughness.metallicFactor value. Using default value instead.');
|
|
175
172
|
} else metallicFactor = pbr.metallicFactor;
|
|
176
173
|
if (!pbr?.roughnessFactor || pbr?.roughnessFactor <= 0 || pbr?.roughnessFactor >= 1) {
|
|
177
|
-
|
|
174
|
+
vtkDebugMacro('Invalid material.pbrMetallicRoughness.roughnessFactor value. Using default value instead.');
|
|
178
175
|
} else roughnessFactor = pbr.roughnessFactor;
|
|
179
176
|
const color = pbr.baseColorFactor;
|
|
180
|
-
if (color
|
|
177
|
+
if (color != null) {
|
|
181
178
|
property.setDiffuseColor(color[0], color[1], color[2]);
|
|
182
179
|
property.setOpacity(color[3]);
|
|
183
180
|
}
|
|
@@ -187,7 +184,7 @@ async function createPropertyFromGLTFMaterial(model, material, actor) {
|
|
|
187
184
|
if (pbr.baseColorTexture) {
|
|
188
185
|
pbr.baseColorTexture.extensions;
|
|
189
186
|
const tex = pbr.baseColorTexture.texture;
|
|
190
|
-
if (tex.extensions
|
|
187
|
+
if (tex.extensions != null) {
|
|
191
188
|
const extensionsNames = Object.keys(tex.extensions);
|
|
192
189
|
extensionsNames.forEach(extensionName => {
|
|
193
190
|
// TODO: Handle KHR_texture_basisu extension
|
|
@@ -243,7 +240,7 @@ async function createPropertyFromGLTFMaterial(model, material, actor) {
|
|
|
243
240
|
property.setEmissionTexture(emissiveTex);
|
|
244
241
|
|
|
245
242
|
// Handle mutiple Uvs
|
|
246
|
-
if (material.emissiveTexture.texCoord
|
|
243
|
+
if (material.emissiveTexture.texCoord != null) {
|
|
247
244
|
const pd = actor.getMapper().getInputData().getPointData();
|
|
248
245
|
pd.setActiveTCoords(`TEXCOORD_${material.emissiveTexture.texCoord}`);
|
|
249
246
|
}
|
|
@@ -257,14 +254,14 @@ async function createPropertyFromGLTFMaterial(model, material, actor) {
|
|
|
257
254
|
const normalImage = await loadImage(tex.source);
|
|
258
255
|
const normalTex = createVTKTextureFromGLTFTexture(normalImage, sampler);
|
|
259
256
|
property.setNormalTexture(normalTex);
|
|
260
|
-
if (material.normalTexture.scale
|
|
257
|
+
if (material.normalTexture.scale != null) {
|
|
261
258
|
property.setNormalStrength(material.normalTexture.scale);
|
|
262
259
|
}
|
|
263
260
|
}
|
|
264
261
|
}
|
|
265
262
|
|
|
266
263
|
// Material extensions
|
|
267
|
-
if (material.extensions
|
|
264
|
+
if (material.extensions != null) {
|
|
268
265
|
const extensionsNames = Object.keys(material.extensions);
|
|
269
266
|
extensionsNames.forEach(extensionName => {
|
|
270
267
|
const extension = material.extensions[extensionName];
|
|
@@ -291,17 +288,17 @@ async function createPropertyFromGLTFMaterial(model, material, actor) {
|
|
|
291
288
|
|
|
292
289
|
/**
|
|
293
290
|
* Handles primitive extensions
|
|
291
|
+
* @param {string} nodeId The GLTF node id
|
|
294
292
|
* @param {*} extensions The extensions object
|
|
295
293
|
* @param {*} model The vtk model object
|
|
296
|
-
* @param {GLTFNode} node The GLTF node
|
|
297
294
|
*/
|
|
298
|
-
function handlePrimitiveExtensions(extensions, model
|
|
295
|
+
function handlePrimitiveExtensions(nodeId, extensions, model) {
|
|
299
296
|
const extensionsNames = Object.keys(extensions);
|
|
300
297
|
extensionsNames.forEach(extensionName => {
|
|
301
298
|
const extension = extensions[extensionName];
|
|
302
299
|
switch (extensionName) {
|
|
303
300
|
case 'KHR_materials_variants':
|
|
304
|
-
model.variantMappings.set(
|
|
301
|
+
model.variantMappings.set(nodeId, extension.mappings);
|
|
305
302
|
break;
|
|
306
303
|
default:
|
|
307
304
|
vtkWarningMacro(`Unhandled extension: ${extensionName}`);
|
|
@@ -314,33 +311,43 @@ function handlePrimitiveExtensions(extensions, model, node) {
|
|
|
314
311
|
* @param {GLTFMesh} mesh - The GLTF mesh
|
|
315
312
|
* @returns {vtkActor} The created VTK actor
|
|
316
313
|
*/
|
|
317
|
-
async function createActorFromGTLFNode(
|
|
314
|
+
async function createActorFromGTLFNode(worldMatrix) {
|
|
318
315
|
const actor = vtkActor.newInstance();
|
|
319
316
|
const mapper = vtkMapper.newInstance();
|
|
320
317
|
mapper.setColorModeToDirectScalars();
|
|
321
318
|
actor.setMapper(mapper);
|
|
322
319
|
actor.setUserMatrix(worldMatrix);
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
320
|
+
const polydata = vtkPolyData.newInstance();
|
|
321
|
+
mapper.setInputData(polydata);
|
|
322
|
+
return actor;
|
|
323
|
+
}
|
|
327
324
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
325
|
+
/**
|
|
326
|
+
* Creates a VTK actor from a GLTF mesh
|
|
327
|
+
* @param {GLTFMesh} mesh - The GLTF mesh
|
|
328
|
+
* @returns {vtkActor} The created VTK actor
|
|
329
|
+
*/
|
|
330
|
+
async function createActorFromGTLFPrimitive(model, primitive, worldMatrix) {
|
|
331
|
+
const actor = vtkActor.newInstance();
|
|
332
|
+
const mapper = vtkMapper.newInstance();
|
|
333
|
+
mapper.setColorModeToDirectScalars();
|
|
334
|
+
actor.setMapper(mapper);
|
|
335
|
+
actor.setUserMatrix(worldMatrix);
|
|
336
|
+
const polydata = await createPolyDataFromGLTFMesh(primitive);
|
|
337
|
+
mapper.setInputData(polydata);
|
|
338
|
+
|
|
339
|
+
// Support for materials
|
|
340
|
+
if (primitive.material != null) {
|
|
341
|
+
await createPropertyFromGLTFMaterial(model, primitive.material, actor);
|
|
342
|
+
}
|
|
343
|
+
if (primitive.extensions != null) {
|
|
344
|
+
handlePrimitiveExtensions(`${primitive.name}`, primitive.extensions, model);
|
|
338
345
|
}
|
|
339
346
|
return actor;
|
|
340
347
|
}
|
|
341
348
|
|
|
342
349
|
/**
|
|
343
|
-
*
|
|
350
|
+
* Creates a GLTF animation object
|
|
344
351
|
* @param {GLTFAnimation} animation
|
|
345
352
|
* @returns
|
|
346
353
|
*/
|
|
@@ -366,7 +373,7 @@ function getTransformationMatrix(node) {
|
|
|
366
373
|
const translation = node.translation ?? vec3.create();
|
|
367
374
|
const rotation = node.rotation ?? quat.create();
|
|
368
375
|
const scale = node.scale ?? vec3.fromValues(1.0, 1.0, 1.0);
|
|
369
|
-
const matrix = node.matrix
|
|
376
|
+
const matrix = node.matrix != null ? mat4.clone(node.matrix) : mat4.fromRotationTranslationScale(mat4.create(), rotation, translation, scale);
|
|
370
377
|
return matrix;
|
|
371
378
|
}
|
|
372
379
|
|
|
@@ -384,13 +391,17 @@ async function processNode(node, model) {
|
|
|
384
391
|
const worldMatrix = mat4.multiply(mat4.create(), parentMatrix, node.transform);
|
|
385
392
|
|
|
386
393
|
// Create actor for the current node
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
actor.setUserMatrix(worldMatrix);
|
|
394
|
+
if (node.mesh != null) {
|
|
395
|
+
const nodeActor = await createActorFromGTLFNode(worldMatrix);
|
|
390
396
|
if (parentActor) {
|
|
391
|
-
|
|
397
|
+
nodeActor.setParentProp(parentActor);
|
|
392
398
|
}
|
|
393
|
-
model.actors.set(node.id
|
|
399
|
+
model.actors.set(`${node.id}`, nodeActor);
|
|
400
|
+
await Promise.all(node.mesh.primitives.map(async (primitive, i) => {
|
|
401
|
+
const actor = await createActorFromGTLFPrimitive(model, primitive, worldMatrix);
|
|
402
|
+
actor.setParentProp(nodeActor);
|
|
403
|
+
model.actors.set(`${node.id}_${primitive.name}`, actor);
|
|
404
|
+
}));
|
|
394
405
|
}
|
|
395
406
|
|
|
396
407
|
// Handle KHRLightsPunctual extension
|