@needle-tools/gltf-build-pipeline 1.1.1 → 1.1.3
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 +6 -0
- package/dist/transforms/needle_progressive.js +8 -8
- package/dist/utils/fileutils.d.ts +1 -1
- package/dist/utils/fileutils.js +11 -8
- package/pack-gltf.mjs +20 -7
- package/package.json +1 -1
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.1.3] - 2023-05-24
|
|
8
|
+
- minor change adding info about reduced size after processing gltf files
|
|
9
|
+
|
|
10
|
+
## [1.1.2] - 2023-05-24
|
|
11
|
+
- fix: wasm out of memory error caused by starting to many compression processes at once
|
|
12
|
+
|
|
7
13
|
## [1.1.1] - 2023-05-18
|
|
8
14
|
- fix: fix progressive texture processing for empty slots array, assume texture slot "baseColorTexture" (for custom shader support)
|
|
9
15
|
|
|
@@ -23,12 +23,9 @@ function registerExtensions(io) {
|
|
|
23
23
|
export async function make_progressive(opts) {
|
|
24
24
|
console.log("INFO: Run progressive transform: " + opts.path);
|
|
25
25
|
const file = opts.path;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const prog = process(f, opts);
|
|
29
|
-
tasks.push(prog);
|
|
26
|
+
return foreachGLTF(file, async (f) => {
|
|
27
|
+
await process(f, opts);
|
|
30
28
|
});
|
|
31
|
-
await Promise.all(tasks);
|
|
32
29
|
}
|
|
33
30
|
async function process(file, opts) {
|
|
34
31
|
if (!file.endsWith(".glb") && !file.endsWith(".gltf")) {
|
|
@@ -50,7 +47,7 @@ async function process(file, opts) {
|
|
|
50
47
|
console.log("WARN: \"" + err.message + "\" at \"" + file + "\"");
|
|
51
48
|
}
|
|
52
49
|
else
|
|
53
|
-
console.log("ERR: \"" + err.message + "\" at \"" + file + "\"");
|
|
50
|
+
console.log("ERR: \"" + err.message + "\" at \"" + file + "\"\nStacktrace:\n" + err.stack);
|
|
54
51
|
return;
|
|
55
52
|
});
|
|
56
53
|
if (document) {
|
|
@@ -76,7 +73,7 @@ async function process(file, opts) {
|
|
|
76
73
|
}
|
|
77
74
|
}
|
|
78
75
|
catch (err) {
|
|
79
|
-
console.log("ERR: failed to process file \"" + file + "\", Reason: " + err.message);
|
|
76
|
+
console.log("ERR: failed to process file \"" + file + "\", Reason: " + err.message, "\nStack:\n" + err.stack);
|
|
80
77
|
}
|
|
81
78
|
}
|
|
82
79
|
// basic idea:
|
|
@@ -159,7 +156,10 @@ export function make_progressive_textures(filePath, _options = TEXTURE_RESIZE_DE
|
|
|
159
156
|
}
|
|
160
157
|
}
|
|
161
158
|
await resizeTexture(options, texture, logger, uri || name, slots);
|
|
162
|
-
|
|
159
|
+
if (opts?.useCache === false) {
|
|
160
|
+
}
|
|
161
|
+
else
|
|
162
|
+
addToCache(key, texture.getImage());
|
|
163
163
|
}
|
|
164
164
|
logger.debug(`Progressive transform finished in ${((Date.now() - startTime) / 1000).toFixed(1)} sec.`);
|
|
165
165
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare type GLTFFileCallback = (file: string) => void | Promise<void>;
|
|
2
|
-
export declare function foreachGLTF(args: string | string[], callback: GLTFFileCallback): void
|
|
2
|
+
export declare function foreachGLTF(args: string | string[], callback: GLTFFileCallback): Promise<void>;
|
package/dist/utils/fileutils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, statSync, readdirSync, readFileSync } from 'fs';
|
|
2
2
|
import { isAbsolute } from 'path';
|
|
3
|
-
export function foreachGLTF(args, callback) {
|
|
3
|
+
export async function foreachGLTF(args, callback) {
|
|
4
4
|
// get original directory this run was invoked from
|
|
5
5
|
const initDir = process.env.INIT_CWD;
|
|
6
6
|
const context = {
|
|
@@ -10,11 +10,11 @@ export function foreachGLTF(args, callback) {
|
|
|
10
10
|
// traverse recursively through all files and directories
|
|
11
11
|
if (Array.isArray(args)) {
|
|
12
12
|
for (const arg of args) {
|
|
13
|
-
testEntry(arg, callback, context);
|
|
13
|
+
await testEntry(arg, callback, context);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
else if (typeof args === "string") {
|
|
17
|
-
testEntry(args, callback, context);
|
|
17
|
+
await testEntry(args, callback, context);
|
|
18
18
|
}
|
|
19
19
|
// try to run with needle config
|
|
20
20
|
if (context.filesFound <= 0 && context.baseDirectory) {
|
|
@@ -26,13 +26,13 @@ export function foreachGLTF(args, callback) {
|
|
|
26
26
|
// If it's an absolute path
|
|
27
27
|
if (existsSync(buildDirectory)) {
|
|
28
28
|
console.log("INFO: Using build directory from needle.config.json: " + buildDirectory);
|
|
29
|
-
testEntry(buildDirectory, callback, context);
|
|
29
|
+
await testEntry(buildDirectory, callback, context);
|
|
30
30
|
}
|
|
31
31
|
else { // if its a relative path
|
|
32
32
|
const newPath = context.baseDirectory + "/" + buildDirectory;
|
|
33
33
|
if (existsSync(newPath)) {
|
|
34
34
|
console.log("INFO: Using build directory from needle.config.json: " + newPath);
|
|
35
|
-
testEntry(newPath, callback, context);
|
|
35
|
+
await testEntry(newPath, callback, context);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -42,7 +42,7 @@ export function foreachGLTF(args, callback) {
|
|
|
42
42
|
console.log("WARN: No glTF files found. Make sure to invoke with a valid path to a glTF file or directory. This path may be relative to " + initDir);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
function testEntry(entry, callback, context) {
|
|
45
|
+
async function testEntry(entry, callback, context) {
|
|
46
46
|
if (entry === "." || entry === "./") {
|
|
47
47
|
if (context.baseDirectory) {
|
|
48
48
|
entry = context.baseDirectory;
|
|
@@ -82,7 +82,10 @@ function testEntry(entry, callback, context) {
|
|
|
82
82
|
}
|
|
83
83
|
if (entry.endsWith(".glb") || entry.endsWith(".gltf")) {
|
|
84
84
|
context.filesFound += 1;
|
|
85
|
-
callback(entry);
|
|
85
|
+
const res = callback(entry);
|
|
86
|
+
if (res instanceof Promise) {
|
|
87
|
+
await res;
|
|
88
|
+
}
|
|
86
89
|
}
|
|
87
90
|
else {
|
|
88
91
|
const stat = statSync(entry);
|
|
@@ -93,7 +96,7 @@ function testEntry(entry, callback, context) {
|
|
|
93
96
|
}
|
|
94
97
|
const files = readdirSync(entry);
|
|
95
98
|
for (const file of files) {
|
|
96
|
-
testEntry(entry + "/" + file, callback, context);
|
|
99
|
+
await testEntry(entry + "/" + file, callback, context);
|
|
97
100
|
}
|
|
98
101
|
}
|
|
99
102
|
else {
|
package/pack-gltf.mjs
CHANGED
|
@@ -69,6 +69,10 @@ if (noToktx)
|
|
|
69
69
|
console.log("Using toktx is disabled");
|
|
70
70
|
|
|
71
71
|
const packedFiles = new Set();
|
|
72
|
+
let totalGPUMemoryInMB = 0;
|
|
73
|
+
let totalFilesProcessed = 0;
|
|
74
|
+
let totalFileSizeInMB = 0;
|
|
75
|
+
let totalFileSizeInMBBefore = 0;
|
|
72
76
|
|
|
73
77
|
async function packFile(file) {
|
|
74
78
|
if (!existsSync(file)) {
|
|
@@ -84,7 +88,7 @@ async function packFile(file) {
|
|
|
84
88
|
console.log("→ Begin packing: " + file);
|
|
85
89
|
|
|
86
90
|
try {
|
|
87
|
-
const
|
|
91
|
+
const prevSizeInMB = statSync(file).size / 1024 / 1024;
|
|
88
92
|
const startTime = Date.now();
|
|
89
93
|
const io = new NodeIO()
|
|
90
94
|
.registerExtensions(ALL_EXTENSIONS)
|
|
@@ -105,8 +109,8 @@ async function packFile(file) {
|
|
|
105
109
|
await document.transform(
|
|
106
110
|
needle_asset(),
|
|
107
111
|
needle_texture_transform({
|
|
108
|
-
useCache: allowCaching,
|
|
109
|
-
noToktx: noToktx,
|
|
112
|
+
useCache: allowCaching,
|
|
113
|
+
noToktx: noToktx,
|
|
110
114
|
debug: debug,
|
|
111
115
|
reportGPUMemory: val => totalGPUTextureMemmory += val
|
|
112
116
|
}),
|
|
@@ -117,10 +121,15 @@ async function packFile(file) {
|
|
|
117
121
|
if (debug) file += ".debug.glb";
|
|
118
122
|
await io.write(file, document);
|
|
119
123
|
const duration = Date.now() - startTime;
|
|
120
|
-
const
|
|
124
|
+
const sizeInMB = statSync(file).size / 1024 / 1024;
|
|
121
125
|
const filename = path.basename(file);
|
|
122
126
|
const gpuMemoryInMB = totalGPUTextureMemmory / 1024 / 1024;
|
|
123
|
-
console.log(`← Compressing done in ${(duration / 1000).toFixed(1)} sec, ${
|
|
127
|
+
console.log(`← Compressing done in ${(duration / 1000).toFixed(1)} sec, ${prevSizeInMB.toFixed(1)} MB → ${sizeInMB.toFixed(1)} MB (GPU: ${gpuMemoryInMB.toFixed(1)} MB textures): ${filename} at ${file}`);
|
|
128
|
+
|
|
129
|
+
totalFilesProcessed++;
|
|
130
|
+
totalFileSizeInMB += sizeInMB;
|
|
131
|
+
totalFileSizeInMBBefore += prevSizeInMB;
|
|
132
|
+
totalGPUMemoryInMB += gpuMemoryInMB;
|
|
124
133
|
return true;
|
|
125
134
|
}
|
|
126
135
|
catch (err) {
|
|
@@ -130,7 +139,11 @@ async function packFile(file) {
|
|
|
130
139
|
}
|
|
131
140
|
}
|
|
132
141
|
|
|
133
|
-
|
|
142
|
+
let startTime = Date.now();
|
|
134
143
|
foreachGLTF(process.argv, async (file) => {
|
|
135
144
|
await packFile(file);
|
|
136
|
-
})
|
|
145
|
+
}).then(() => {
|
|
146
|
+
const duration = Date.now() - startTime;
|
|
147
|
+
const durationInMinutes = duration / 1000 / 60;
|
|
148
|
+
console.log(`Finished packing ${totalFilesProcessed} files in ${durationInMinutes.toFixed(1)} minutes; total size ${totalFileSizeInMBBefore.toFixed(1)} MB → ${totalFileSizeInMB.toFixed(1)} MB, total GPU memory: ${totalGPUMemoryInMB.toFixed(1)} MB`);
|
|
149
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/gltf-build-pipeline",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
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",
|