@needle-tools/gltf-build-pipeline 1.4.4 → 1.4.6
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/CHANGELOG.md +7 -0
- package/dist/transforms/needle_progressive.js +37 -16
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ All notable changes to this package will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [1.4.6] - 2023-04-10
|
|
8
|
+
- fix: NEEDLE_progressive meshes do not revert primitive data for skinned meshes anymore. See NE-4596
|
|
9
|
+
|
|
10
|
+
## [1.4.5] - 2023-04-05
|
|
11
|
+
- fix: generating mesh and texture LOD for glbs without `NEEDLE_` extension
|
|
12
|
+
- fix: guid generation for progressive meshes when no `NEEDLE_` extension is present
|
|
13
|
+
|
|
7
14
|
## [1.4.4] - 2023-04-03
|
|
8
15
|
- change: clamp simplification error for LOD meshes to 5%
|
|
9
16
|
|
|
@@ -2,7 +2,7 @@ import { BufferUtils, Document, NodeIO, PropertyType } from '@gltf-transform/cor
|
|
|
2
2
|
import { SIMPLIFY_DEFAULTS, WELD_DEFAULTS, listTextureSlots, sparse } from '@gltf-transform/functions';
|
|
3
3
|
import { NEEDLE_PROGRESSIVE_EXTENSION_NAME, NEEDLE_progressive } from "../extensions/NEEDLE_progressive/index.js";
|
|
4
4
|
import { createOpaqueExtension, currentGenerator, NEEDLE_compression_texture, NEEDLE_mesh_compression, NEEDLE_progressive_mesh_settings, NEEDLE_progressive_texture_settings, registerExtensions as registerDefaultExtensions } from '../extensions/index.js';
|
|
5
|
-
import path from 'path';
|
|
5
|
+
import path, { basename } from 'path';
|
|
6
6
|
import { existsSync, readFileSync, rmSync, statSync, writeFileSync } from 'fs';
|
|
7
7
|
import { addMetaToCache, addToCache, getHash, getKey, tryGetFromCache, tryGetMetaFromCache } from '../cache/index.js';
|
|
8
8
|
import sharp from "sharp";
|
|
@@ -97,6 +97,7 @@ const NAME = 'NEEDLE_progressive';
|
|
|
97
97
|
export function make_progressive_textures(filePath, _options = TEXTURE_RESIZE_DEFAULTS, opts) {
|
|
98
98
|
console.log("Make progressive: " + filePath);
|
|
99
99
|
const startTime = Date.now();
|
|
100
|
+
const filename = basename(filePath);
|
|
100
101
|
const options = { ...TEXTURE_RESIZE_DEFAULTS, ..._options };
|
|
101
102
|
const directory = path.dirname(filePath);
|
|
102
103
|
// const fileNameWithoutExtension = path.basename(filePath, path.extname(filePath));
|
|
@@ -122,13 +123,23 @@ export function make_progressive_textures(filePath, _options = TEXTURE_RESIZE_DE
|
|
|
122
123
|
logger.debug(`[${NAME}] Skipping, [${slots.join(', ')}] excluded by "slots" parameter. ${textureIndex}`);
|
|
123
124
|
continue;
|
|
124
125
|
}
|
|
125
|
-
|
|
126
|
+
let settings = texture.getExtension(NEEDLE_progressive_texture_settings.EXTENSION_NAME);
|
|
126
127
|
if (!settings) {
|
|
127
|
-
|
|
128
|
-
|
|
128
|
+
const size = texture.getSize();
|
|
129
|
+
if (size?.length >= 2 && size[0] <= 128 && size[1] <= 128) {
|
|
130
|
+
logger.warn(`[${NAME}] Skipping texture[${textureIndex}], no settings found`);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
settings = {
|
|
135
|
+
guid: generateGuid(filename + "_texture_" + index.toString()),
|
|
136
|
+
maxSize: 128,
|
|
137
|
+
};
|
|
138
|
+
logger.debug(`[${NAME}] No settings found for texture[${index}] - will use default settings (maxSize: ${settings.maxSize}, guid: ${settings.guid})`);
|
|
139
|
+
}
|
|
129
140
|
}
|
|
130
|
-
if (
|
|
131
|
-
logger.warn(`[${NAME}] Skipping, settings are invalid ${
|
|
141
|
+
if (settings.maxSize == undefined || settings.maxSize <= 0) {
|
|
142
|
+
logger.warn(`[${NAME}] Skipping texture[${textureIndex}], settings are invalid (maxSize: ${settings.maxSize})`);
|
|
132
143
|
continue;
|
|
133
144
|
}
|
|
134
145
|
options.size[0] = settings.maxSize;
|
|
@@ -343,10 +354,10 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
343
354
|
const root = doc.getRoot();
|
|
344
355
|
const meshes = root.listMeshes();
|
|
345
356
|
for (const mesh of meshes) {
|
|
346
|
-
await processMesh(mesh);
|
|
357
|
+
await processMesh(mesh, { filename });
|
|
347
358
|
}
|
|
348
359
|
console.log(`[${NAME}]: Finished generating progressive meshes for \"${filename}\"`);
|
|
349
|
-
async function processMesh(mesh) {
|
|
360
|
+
async function processMesh(mesh, args) {
|
|
350
361
|
/** The size and vertex count of the original mesh */
|
|
351
362
|
const originalMeshInformation = getMeshInformation(mesh);
|
|
352
363
|
const { totalVertexCount: originalTotalVertexCount, maxVertexCount: originalMaxVertexCount } = originalMeshInformation;
|
|
@@ -358,7 +369,7 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
358
369
|
}
|
|
359
370
|
else {
|
|
360
371
|
settings = {
|
|
361
|
-
guid: generateGuid(
|
|
372
|
+
guid: generateGuid(args.filename + "_mesh_" + index.toString()),
|
|
362
373
|
generateLods: true,
|
|
363
374
|
};
|
|
364
375
|
logger.debug(`[${NAME}] No settings found for mesh[${index}] with ${originalTotalVertexCount} vertices (max: ${originalMaxVertexCount}) - will use default settings (guid: ${settings.guid})`);
|
|
@@ -463,11 +474,13 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
463
474
|
let maxDensity = 0;
|
|
464
475
|
let primitiveIndex = 0;
|
|
465
476
|
const lodLevelInFile = generatedLODInfos.length;
|
|
466
|
-
const clonedData =
|
|
477
|
+
const clonedData = { primitives: [], weights: [...mesh.getWeights()] };
|
|
467
478
|
for (const prim of mesh.listPrimitives()) {
|
|
468
479
|
const data = clonePrimitiveData(prim);
|
|
469
|
-
|
|
470
|
-
|
|
480
|
+
if (data != null) {
|
|
481
|
+
clonedData.primitives.push(data);
|
|
482
|
+
}
|
|
483
|
+
console.log(`[${NAME}] Simplify mesh[${index}] primitive[${primitiveIndex}] (embedded)`);
|
|
471
484
|
const lastLod = LODS[lodLevelInFile];
|
|
472
485
|
// TODO: this should be run after simplification but then we need to change the runtime to use the LOD 0 density
|
|
473
486
|
const density = calculateMeshDensity(prim);
|
|
@@ -485,7 +498,7 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
485
498
|
}
|
|
486
499
|
else if (difference < 32 || diff01 <= 0.05) {
|
|
487
500
|
// the lowest LOD has the same vertex count as the original mesh → we don't need to write the extension and can also delete previously generated LODs
|
|
488
|
-
console.log(`[${NAME}]: Flag mesh LOD ${generatedLODInfos.length}: vertex count difference below threshold (removed ${difference} vertices, ${(-diff01 * 100).toFixed(2)} %) → will remove
|
|
501
|
+
console.log(`[${NAME}]: Flag mesh LOD ${generatedLODInfos.length} (embedded): vertex count difference below threshold (removed ${difference} vertices, ${(-diff01 * 100).toFixed(2)} %) → will remove LOD. \"${mesh.getName()}\"`);
|
|
489
502
|
try {
|
|
490
503
|
for (const lodInfo of generatedLODInfos) {
|
|
491
504
|
rmSync(outputDirectory + "/" + lodInfo.path);
|
|
@@ -496,9 +509,12 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
496
509
|
}
|
|
497
510
|
// reset data (simplify might have changed the mesh data that we cloned before)
|
|
498
511
|
const primitives = mesh.listPrimitives();
|
|
499
|
-
if (clonedData.length == primitives.length) {
|
|
512
|
+
if (clonedData.primitives.length == primitives.length) {
|
|
513
|
+
if (clonedData.weights?.length > 0) {
|
|
514
|
+
mesh.setWeights(clonedData.weights);
|
|
515
|
+
}
|
|
500
516
|
for (let i = 0; i < primitives.length; i++) {
|
|
501
|
-
setPrimitiveData(primitives[i], clonedData[i]);
|
|
517
|
+
setPrimitiveData(primitives[i], clonedData.primitives[i]);
|
|
502
518
|
}
|
|
503
519
|
}
|
|
504
520
|
return;
|
|
@@ -529,9 +545,14 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
529
545
|
});
|
|
530
546
|
}
|
|
531
547
|
function clonePrimitiveData(prim) {
|
|
548
|
+
const semantics = prim.listSemantics();
|
|
549
|
+
if (semantics.some(s => s.includes("JOINTS"))) {
|
|
550
|
+
return null;
|
|
551
|
+
}
|
|
532
552
|
const indices = new Uint32Array(prim.getIndices().getArray());
|
|
533
553
|
const attributes = {};
|
|
534
|
-
for (const attr of
|
|
554
|
+
for (const attr of semantics) {
|
|
555
|
+
console.log(`[${NAME}] Clone attribute ${attr}`);
|
|
535
556
|
const accessor = prim.getAttribute(attr);
|
|
536
557
|
if (accessor) {
|
|
537
558
|
attributes[attr] = new Float32Array(accessor.getArray());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/gltf-build-pipeline",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.6",
|
|
4
4
|
"description": "Pipeline and tools for optimizing gltf files using gltf-transform and compression settings within glTF extensions",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"type": "module",
|