@needle-tools/gltf-build-pipeline 1.4.5 → 1.4.7
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
CHANGED
|
@@ -4,6 +4,12 @@ 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.7] - 2023-04-16
|
|
8
|
+
- add: `asset.extras.needle` now contains information about used build pipeline
|
|
9
|
+
|
|
10
|
+
## [1.4.6] - 2023-04-10
|
|
11
|
+
- fix: NEEDLE_progressive meshes do not revert primitive data for skinned meshes anymore. See NE-4596
|
|
12
|
+
|
|
7
13
|
## [1.4.5] - 2023-04-05
|
|
8
14
|
- fix: generating mesh and texture LOD for glbs without `NEEDLE_` extension
|
|
9
15
|
- fix: guid generation for progressive meshes when no `NEEDLE_` extension is present
|
|
@@ -1,17 +1,35 @@
|
|
|
1
1
|
import { createTransform } from '@gltf-transform/functions';
|
|
2
2
|
import { getVersion } from '../index.js';
|
|
3
|
+
const generatorName = "Needle Build Pipeline";
|
|
4
|
+
export function writeNeedleAsset(document) {
|
|
5
|
+
const root = document.getRoot();
|
|
6
|
+
const asset = root.getAsset();
|
|
7
|
+
if (asset) {
|
|
8
|
+
asset.extras = writeNeedleExtras(asset.extras);
|
|
9
|
+
const version = getVersion();
|
|
10
|
+
asset.generator = generatorName;
|
|
11
|
+
if (version?.length > 0) {
|
|
12
|
+
asset.generator += " " + version;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
3
16
|
export function needle_asset() {
|
|
4
17
|
return createTransform("needle_asset_transform", (document) => {
|
|
5
|
-
|
|
6
|
-
const asset = root.getAsset();
|
|
7
|
-
if (asset) {
|
|
8
|
-
const version = getVersion();
|
|
9
|
-
if (!asset.generator.startsWith("Needle glTF Build Pipeline")) {
|
|
10
|
-
asset.generator = "Needle glTF Build Pipeline";
|
|
11
|
-
if (version?.length > 0) {
|
|
12
|
-
asset.generator += " " + version;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
18
|
+
writeNeedleAsset(document);
|
|
16
19
|
});
|
|
17
20
|
}
|
|
21
|
+
/** @internal */
|
|
22
|
+
function writeNeedleExtras(extras) {
|
|
23
|
+
if (!extras)
|
|
24
|
+
extras = {};
|
|
25
|
+
if (typeof extras === "object" && !extras["needle"]) {
|
|
26
|
+
let generator = generatorName;
|
|
27
|
+
const version = getVersion();
|
|
28
|
+
if (version?.length > 0)
|
|
29
|
+
generator += " " + version;
|
|
30
|
+
extras["needle"] = {
|
|
31
|
+
generator: generator
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return extras;
|
|
35
|
+
}
|
|
@@ -7,7 +7,7 @@ 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";
|
|
9
9
|
import { foreachGLTF, generateGuid } from '../utils/index.js';
|
|
10
|
-
import { needle_asset } from './needle_asset.js';
|
|
10
|
+
import { needle_asset, writeNeedleAsset } from './needle_asset.js';
|
|
11
11
|
import { MeshoptDecoder, MeshoptSimplifier } from 'meshoptimizer';
|
|
12
12
|
import { compressPrimitive } from './needle_mesh_transform.js';
|
|
13
13
|
import { calculateMeshDensity, getMeshInformation } from "../utils/mesh.js";
|
|
@@ -155,7 +155,7 @@ export function make_progressive_textures(filePath, _options = TEXTURE_RESIZE_DE
|
|
|
155
155
|
continue;
|
|
156
156
|
}
|
|
157
157
|
const textureGuid = settings.guid?.length ? settings.guid : generateGuid(path + "_texture_" + index.toString());
|
|
158
|
-
const outPath = createTextureLod(textureLodBasePath, 0, texture, slots, textureGuid, textureIndex);
|
|
158
|
+
const outPath = createTextureLod(doc, textureLodBasePath, 0, texture, slots, textureGuid, textureIndex);
|
|
159
159
|
if (!outPath) {
|
|
160
160
|
continue;
|
|
161
161
|
}
|
|
@@ -190,7 +190,7 @@ export function make_progressive_textures(filePath, _options = TEXTURE_RESIZE_DE
|
|
|
190
190
|
logger.debug(`Progressive transform finished in ${((Date.now() - startTime) / 1000).toFixed(1)} sec.`);
|
|
191
191
|
});
|
|
192
192
|
}
|
|
193
|
-
function createTextureLod(basePath, level, texture, slots, guid, textureIndex) {
|
|
193
|
+
function createTextureLod(doc, basePath, level, texture, slots, guid, textureIndex) {
|
|
194
194
|
// const imageBytes = texture.getImage();
|
|
195
195
|
// if (imageBytes) {
|
|
196
196
|
// // write bytes
|
|
@@ -199,6 +199,7 @@ function createTextureLod(basePath, level, texture, slots, guid, textureIndex) {
|
|
|
199
199
|
// return outPath;
|
|
200
200
|
// }
|
|
201
201
|
const newDoc = new Document();
|
|
202
|
+
writeNeedleAsset(newDoc);
|
|
202
203
|
newDoc.createScene();
|
|
203
204
|
newDoc.createBuffer();
|
|
204
205
|
// add texture
|
|
@@ -474,11 +475,13 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
474
475
|
let maxDensity = 0;
|
|
475
476
|
let primitiveIndex = 0;
|
|
476
477
|
const lodLevelInFile = generatedLODInfos.length;
|
|
477
|
-
const clonedData =
|
|
478
|
+
const clonedData = { primitives: [], weights: [...mesh.getWeights()] };
|
|
478
479
|
for (const prim of mesh.listPrimitives()) {
|
|
479
480
|
const data = clonePrimitiveData(prim);
|
|
480
|
-
|
|
481
|
-
|
|
481
|
+
if (data != null) {
|
|
482
|
+
clonedData.primitives.push(data);
|
|
483
|
+
}
|
|
484
|
+
console.log(`[${NAME}] Simplify mesh[${index}] primitive[${primitiveIndex}] (embedded)`);
|
|
482
485
|
const lastLod = LODS[lodLevelInFile];
|
|
483
486
|
// TODO: this should be run after simplification but then we need to change the runtime to use the LOD 0 density
|
|
484
487
|
const density = calculateMeshDensity(prim);
|
|
@@ -496,7 +499,7 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
496
499
|
}
|
|
497
500
|
else if (difference < 32 || diff01 <= 0.05) {
|
|
498
501
|
// 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
|
|
499
|
-
console.log(`[${NAME}]: Flag mesh LOD ${generatedLODInfos.length}: vertex count difference below threshold (removed ${difference} vertices, ${(-diff01 * 100).toFixed(2)} %) → will remove
|
|
502
|
+
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()}\"`);
|
|
500
503
|
try {
|
|
501
504
|
for (const lodInfo of generatedLODInfos) {
|
|
502
505
|
rmSync(outputDirectory + "/" + lodInfo.path);
|
|
@@ -507,9 +510,12 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
507
510
|
}
|
|
508
511
|
// reset data (simplify might have changed the mesh data that we cloned before)
|
|
509
512
|
const primitives = mesh.listPrimitives();
|
|
510
|
-
if (clonedData.length == primitives.length) {
|
|
513
|
+
if (clonedData.primitives.length == primitives.length) {
|
|
514
|
+
if (clonedData.weights?.length > 0) {
|
|
515
|
+
mesh.setWeights(clonedData.weights);
|
|
516
|
+
}
|
|
511
517
|
for (let i = 0; i < primitives.length; i++) {
|
|
512
|
-
setPrimitiveData(primitives[i], clonedData[i]);
|
|
518
|
+
setPrimitiveData(primitives[i], clonedData.primitives[i]);
|
|
513
519
|
}
|
|
514
520
|
}
|
|
515
521
|
return;
|
|
@@ -540,9 +546,14 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
540
546
|
});
|
|
541
547
|
}
|
|
542
548
|
function clonePrimitiveData(prim) {
|
|
549
|
+
const semantics = prim.listSemantics();
|
|
550
|
+
if (semantics.some(s => s.includes("JOINTS"))) {
|
|
551
|
+
return null;
|
|
552
|
+
}
|
|
543
553
|
const indices = new Uint32Array(prim.getIndices().getArray());
|
|
544
554
|
const attributes = {};
|
|
545
|
-
for (const attr of
|
|
555
|
+
for (const attr of semantics) {
|
|
556
|
+
console.log(`[${NAME}] Clone attribute ${attr}`);
|
|
546
557
|
const accessor = prim.getAttribute(attr);
|
|
547
558
|
if (accessor) {
|
|
548
559
|
attributes[attr] = new Float32Array(accessor.getArray());
|
|
@@ -594,6 +605,7 @@ async function createMeshLod(doc, basePath, level, mesh, meshInfo, guid, lodLeve
|
|
|
594
605
|
}
|
|
595
606
|
}
|
|
596
607
|
const newDoc = new Document();
|
|
608
|
+
writeNeedleAsset(newDoc);
|
|
597
609
|
const newScene = newDoc.createScene();
|
|
598
610
|
newDoc.createBuffer();
|
|
599
611
|
const newNode = newDoc.createNode();
|
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.7",
|
|
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",
|