@needle-tools/gltf-build-pipeline 1.4.8 → 1.4.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/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.10] - 2023-04-23
|
|
8
|
+
- add: NEEDLE_progressive can now load and process already draco compressed meshes
|
|
9
|
+
|
|
10
|
+
## [1.4.9] - 2023-04-23
|
|
11
|
+
- add: NEEDLE_progressive now have `hash` field for LODs which is generated using the content of the LOD and it's settings that produced it.
|
|
12
|
+
- fix: NEEDLE_progressive catches error when copying mesh with extensions where the copy operation fails
|
|
13
|
+
|
|
7
14
|
## [1.4.8] - 2023-04-22
|
|
8
15
|
- fix: update sharp package to `^0.32.6`
|
|
9
16
|
- change: NEEDLE_progressive meshes max LOD error increased
|
package/dist/cache/cache.d.ts
CHANGED
|
@@ -39,6 +39,10 @@ export declare function tryGetMetaFromCache(key: string, ignoreVersion?: boolean
|
|
|
39
39
|
* @returns The key as a string.
|
|
40
40
|
*/
|
|
41
41
|
export declare function getKey(property: ExtensibleProperty): string;
|
|
42
|
+
export declare function getKeyWithHash(property: ExtensibleProperty): {
|
|
43
|
+
key: string;
|
|
44
|
+
hash: number;
|
|
45
|
+
};
|
|
42
46
|
/**
|
|
43
47
|
* Get the hash for a property or an object.
|
|
44
48
|
* @param property The property to get the hash for.
|
package/dist/cache/cache.js
CHANGED
|
@@ -139,6 +139,15 @@ export function getKey(property) {
|
|
|
139
139
|
const key = `${prefix}-${hash}`;
|
|
140
140
|
return key;
|
|
141
141
|
}
|
|
142
|
+
export function getKeyWithHash(property) {
|
|
143
|
+
let prefix = "prop";
|
|
144
|
+
if (property instanceof Texture) {
|
|
145
|
+
prefix = "image";
|
|
146
|
+
}
|
|
147
|
+
let hash = getHash(property);
|
|
148
|
+
const key = `${prefix}-${hash}`;
|
|
149
|
+
return { key, hash };
|
|
150
|
+
}
|
|
142
151
|
/**
|
|
143
152
|
* Get the hash for a property or an object.
|
|
144
153
|
* @param property The property to get the hash for.
|
|
@@ -7,14 +7,19 @@ export type ProgressiveLoadingInfo = {
|
|
|
7
7
|
lods?: Array<LodInfo>;
|
|
8
8
|
};
|
|
9
9
|
type LodInfo = {
|
|
10
|
+
/** Relative path to the LOD file */
|
|
10
11
|
path: string;
|
|
12
|
+
/** Hash of the LOD file. It has been generated using the file content and settings */
|
|
13
|
+
hash: string;
|
|
11
14
|
};
|
|
12
15
|
export type ProgressiveTextureModel = ProgressiveLoadingInfo & {
|
|
13
16
|
lods?: Array<LodInfo & {}>;
|
|
14
17
|
};
|
|
15
18
|
export type ProgressiveMeshModel = ProgressiveLoadingInfo & {
|
|
19
|
+
/** LOD0 vertex density. TODO: remove this since we now have a LODs array. This is just for supporting older engine versions */
|
|
16
20
|
density: number;
|
|
17
21
|
lods?: Array<LodInfo & {
|
|
22
|
+
/** Mesh vertex density */
|
|
18
23
|
density: number;
|
|
19
24
|
vertexCount: number;
|
|
20
25
|
indexCount: number;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { BufferUtils, Document, NodeIO, PropertyType } from '@gltf-transform/core';
|
|
2
2
|
import { SIMPLIFY_DEFAULTS, WELD_DEFAULTS, listTextureSlots, sparse } from '@gltf-transform/functions';
|
|
3
|
+
import draco3d from 'draco3dgltf';
|
|
3
4
|
import { NEEDLE_PROGRESSIVE_EXTENSION_NAME, NEEDLE_progressive } from "../extensions/NEEDLE_progressive/index.js";
|
|
4
5
|
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
6
|
import path, { basename } from 'path';
|
|
6
7
|
import { existsSync, readFileSync, rmSync, statSync, writeFileSync } from 'fs';
|
|
7
|
-
import { addMetaToCache, addToCache, getHash,
|
|
8
|
+
import { addMetaToCache, addToCache, getHash, getKeyWithHash, tryGetFromCache, tryGetMetaFromCache } from '../cache/index.js';
|
|
8
9
|
import sharp from "sharp";
|
|
9
10
|
import { foreachGLTF, generateGuid } from '../utils/index.js';
|
|
10
11
|
import { needle_asset, writeNeedleAsset } from './needle_asset.js';
|
|
@@ -49,6 +50,8 @@ async function process(file, opts) {
|
|
|
49
50
|
registerExtensions(io);
|
|
50
51
|
io.registerDependencies({
|
|
51
52
|
'meshopt.decoder': MeshoptDecoder,
|
|
53
|
+
'draco3d.decoder': await draco3d.createDecoderModule(),
|
|
54
|
+
'draco3d.encoder': await draco3d.createEncoderModule(),
|
|
52
55
|
});
|
|
53
56
|
const document = await io.read(file).catch((err) => {
|
|
54
57
|
// Log this message as a warning, it happens when trying to run on a already compressed gltf file (e.g. pre-processed. When logging an error we fail the build which is not desired)
|
|
@@ -159,12 +162,14 @@ export function make_progressive_textures(filePath, _options = TEXTURE_RESIZE_DE
|
|
|
159
162
|
if (!outPath) {
|
|
160
163
|
continue;
|
|
161
164
|
}
|
|
165
|
+
const { key, hash } = getKeyWithHash(texture);
|
|
162
166
|
const relName = path.relative(directory, outPath);
|
|
163
167
|
// TODO: this path should be added to the NEEDLE dependencies extension
|
|
164
168
|
const model = {
|
|
165
169
|
guid: textureGuid,
|
|
166
170
|
lods: [
|
|
167
171
|
{
|
|
172
|
+
hash: hash.toString(),
|
|
168
173
|
path: relName,
|
|
169
174
|
}
|
|
170
175
|
],
|
|
@@ -172,7 +177,6 @@ export function make_progressive_textures(filePath, _options = TEXTURE_RESIZE_DE
|
|
|
172
177
|
// for backwards compatibility - this should be removed in the future
|
|
173
178
|
model["uri"] = relName;
|
|
174
179
|
texture.setExtension(NEEDLE_PROGRESSIVE_EXTENSION_NAME, progressiveExt.createTexture(model));
|
|
175
|
-
const key = getKey(texture);
|
|
176
180
|
if (opts.useCache) {
|
|
177
181
|
const cached = tryGetFromCache(key);
|
|
178
182
|
if (cached) {
|
|
@@ -526,6 +530,7 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
526
530
|
lods: generatedLODInfos.map(l => {
|
|
527
531
|
return {
|
|
528
532
|
path: l.path,
|
|
533
|
+
hash: l.content_hash.toString(),
|
|
529
534
|
density: l.density,
|
|
530
535
|
vertexCount: l.lodMeshInfo?.totalVertexCount,
|
|
531
536
|
indexCount: l.lodMeshInfo?.totalIndexCount,
|
|
@@ -587,21 +592,21 @@ async function createMeshLod(doc, basePath, level, mesh, meshInfo, guid, lodLeve
|
|
|
587
592
|
const outPath = basePath + fileName;
|
|
588
593
|
const primitives = mesh.listPrimitives();
|
|
589
594
|
let cacheKey = undefined;
|
|
595
|
+
// generate hash for mesh
|
|
596
|
+
let hash = mesh["needle:mesh-hash"];
|
|
597
|
+
if (hash === undefined) {
|
|
598
|
+
hash = getHash(mesh);
|
|
599
|
+
mesh["needle:mesh-hash"] = hash;
|
|
600
|
+
}
|
|
601
|
+
hash += getHash(lodLevel);
|
|
590
602
|
if (opts.useCache !== false) {
|
|
591
|
-
// generate hash for mesh
|
|
592
|
-
let hash = mesh["needle:mesh-hash"];
|
|
593
|
-
if (hash === undefined) {
|
|
594
|
-
hash = getHash(mesh);
|
|
595
|
-
mesh["needle:mesh-hash"] = hash;
|
|
596
|
-
}
|
|
597
|
-
hash += getHash(lodLevel);
|
|
598
603
|
cacheKey = `mesh_lod_${level}_${hash}`;
|
|
599
604
|
const cachedValue = tryGetFromCache(cacheKey);
|
|
600
605
|
const meta = tryGetMetaFromCache(cacheKey);
|
|
601
606
|
if (cachedValue && meta) {
|
|
602
607
|
console.log(`[${NAME}] LOD ${level} loaded ${(cachedValue.length / 1024).toFixed()} KB from cache for \"${mesh.getName()}\"`);
|
|
603
608
|
writeFileSync(outPath, cachedValue);
|
|
604
|
-
return { level, path: fileName, success: true, cacheKey: cacheKey, lodMeshInfo: meta.meshInfo, density: meta.density };
|
|
609
|
+
return { level, path: fileName, success: true, cacheKey: cacheKey, content_hash: hash, lodMeshInfo: meta.meshInfo, density: meta.density };
|
|
605
610
|
}
|
|
606
611
|
}
|
|
607
612
|
const newDoc = new Document();
|
|
@@ -667,9 +672,14 @@ async function createMeshLod(doc, basePath, level, mesh, meshInfo, guid, lodLeve
|
|
|
667
672
|
for (const ext of extensions) {
|
|
668
673
|
const PropertyClass = ext.constructor;
|
|
669
674
|
const newProp = new PropertyClass(newDoc.getGraph());
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
675
|
+
try {
|
|
676
|
+
const copy = newProp.copy(ext);
|
|
677
|
+
const name = ext.extensionName;
|
|
678
|
+
newPrim.setExtension(name, copy);
|
|
679
|
+
}
|
|
680
|
+
catch (err) {
|
|
681
|
+
console.error(`WARN: [${NAME}] Failed to copy extension ${ext.extensionName} for mesh LOD ${level} → ${err}`);
|
|
682
|
+
}
|
|
673
683
|
}
|
|
674
684
|
}
|
|
675
685
|
let primitiveIndex = 0;
|
|
@@ -687,7 +697,7 @@ async function createMeshLod(doc, basePath, level, mesh, meshInfo, guid, lodLeve
|
|
|
687
697
|
const newMeshInformation = getMeshInformation(newMesh);
|
|
688
698
|
if (newMeshInformation.totalVertexCount < 4) {
|
|
689
699
|
console.error(`[${NAME}] mesh LOD ${level} is has less than 4 vertices → skipping`);
|
|
690
|
-
return { level, path: fileName, success: false, cacheKey: cacheKey, lodMeshInfo: null, density: null, };
|
|
700
|
+
return { level, path: fileName, success: false, cacheKey: cacheKey, content_hash: hash, lodMeshInfo: null, density: null, };
|
|
691
701
|
}
|
|
692
702
|
let density = 0;
|
|
693
703
|
for (const prim of newMesh.listPrimitives()) {
|
|
@@ -723,7 +733,7 @@ async function createMeshLod(doc, basePath, level, mesh, meshInfo, guid, lodLeve
|
|
|
723
733
|
addToCache(cacheKey, bytes);
|
|
724
734
|
addMetaToCache(cacheKey, { meshInfo: newMeshInformation, density: density });
|
|
725
735
|
}
|
|
726
|
-
return { level, path: fileName, success: true, lodMeshInfo: newMeshInformation, cacheKey: cacheKey, density: density };
|
|
736
|
+
return { level, path: fileName, success: true, lodMeshInfo: newMeshInformation, cacheKey: cacheKey, content_hash: hash, density: density };
|
|
727
737
|
}
|
|
728
738
|
async function simplifyMesh(doc, mesh, prim, index, lodinfo) {
|
|
729
739
|
const weldOptions = {
|
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.10",
|
|
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",
|