@needle-tools/gltf-build-pipeline 1.4.1-beta.13 → 1.4.1-beta.15
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,10 @@ 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.1-beta.15] - 2023-04-02
|
|
8
|
+
- fix: issue where discarding all LODs might result in broken mesh due to simplify having modified the original mesh
|
|
9
|
+
- fix: don't produce LODs if GLB/glTF was produced with old generator
|
|
10
|
+
|
|
7
11
|
## [1.4.1-beta.13] - 2023-03-26
|
|
8
12
|
- change: passthrough `NEEDLE_editor` & `NEEDLE_gltf_dependencies` extensions
|
|
9
13
|
|
|
@@ -20,5 +20,6 @@ export interface IExtensionWriter {
|
|
|
20
20
|
assignTo?(obj: object): any;
|
|
21
21
|
write(context: WriterContext, prop: IExtensibleProperty): void;
|
|
22
22
|
}
|
|
23
|
+
export declare let currentGenerator: string;
|
|
23
24
|
export declare function createOpaqueExtension(name: string, types: PropertyType | PropertyType[], opts?: Options): IOpaqueExtension;
|
|
24
25
|
export {};
|
|
@@ -4,6 +4,7 @@ const ALL_PROPERTY_TYPES = [];
|
|
|
4
4
|
for (const key in PropertyType) {
|
|
5
5
|
ALL_PROPERTY_TYPES.push(PropertyType[key]);
|
|
6
6
|
}
|
|
7
|
+
export let currentGenerator = "";
|
|
7
8
|
// an opaque extension can be used to pass data through the gltf transform process
|
|
8
9
|
// it should also be able to re-write/fix json pointers after the transformation which might have shuffled them around
|
|
9
10
|
export function createOpaqueExtension(name, types, opts) {
|
|
@@ -18,6 +19,7 @@ export function createOpaqueExtension(name, types, opts) {
|
|
|
18
19
|
// private roots: Array<OpaqueProperty> = [];
|
|
19
20
|
jsonPointerHandler;
|
|
20
21
|
read(context) {
|
|
22
|
+
currentGenerator = context.jsonDoc.json.asset?.generator;
|
|
21
23
|
if (debugLog)
|
|
22
24
|
console.log("READ " + EXTENSION_NAME);
|
|
23
25
|
this.jsonPointerHandler = new JsonPointerHandler(this.document, EXTENSION_NAME);
|
|
@@ -1,7 +1,7 @@
|
|
|
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
3
|
import { NEEDLE_PROGRESSIVE_EXTENSION_NAME, NEEDLE_progressive } from "../extensions/NEEDLE_progressive/index.js";
|
|
4
|
-
import { createOpaqueExtension, NEEDLE_compression_texture, NEEDLE_mesh_compression, NEEDLE_progressive_mesh_settings, NEEDLE_progressive_texture_settings, registerExtensions as registerDefaultExtensions } from '../extensions/index.js';
|
|
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
5
|
import path 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';
|
|
@@ -299,6 +299,12 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
299
299
|
// const fileNameWithoutExtension = path.basename(filePath, path.extname(filePath));
|
|
300
300
|
const outputDirectory = directory + "/";
|
|
301
301
|
return createTransform("PROGRESSIVE_MESHES", async (doc, _context) => {
|
|
302
|
+
// this is to ensure we're not creating progressive meshes for engine versions that don't support loading them yet
|
|
303
|
+
// the generator should include the version or the app that produced the GLB too (needle engine repo: 2c00d0e304e205cf9d4ac0499faabb92a706a5c4)
|
|
304
|
+
if (currentGenerator == "Needle Engine") {
|
|
305
|
+
console.log("WARN: Skip creating mesh LODs - Unsupported generator found... Please update your editor integration");
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
302
308
|
if (isMeshLOD(filePath)) {
|
|
303
309
|
console.log("Progressive Mesh Transform: skip lod at " + filePath);
|
|
304
310
|
return Promise.resolve();
|
|
@@ -331,8 +337,13 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
331
337
|
}
|
|
332
338
|
/** Map of visited GUID -> extension */
|
|
333
339
|
const visited = new Map();
|
|
334
|
-
const
|
|
340
|
+
const root = doc.getRoot();
|
|
341
|
+
const meshes = root.listMeshes();
|
|
335
342
|
for (const mesh of meshes) {
|
|
343
|
+
await processMesh(mesh);
|
|
344
|
+
}
|
|
345
|
+
console.log(`[${NAME}]: Finished generating progressive meshes for \"${filename}\"`);
|
|
346
|
+
async function processMesh(mesh) {
|
|
336
347
|
/** The size and vertex count of the original mesh */
|
|
337
348
|
const originalMeshInformation = getMeshInformation(mesh);
|
|
338
349
|
const { totalVertexCount: originalTotalVertexCount, maxVertexCount: originalMaxVertexCount } = originalMeshInformation;
|
|
@@ -340,7 +351,7 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
340
351
|
if (!settings) {
|
|
341
352
|
if (originalMaxVertexCount < 32) {
|
|
342
353
|
logger.debug(`[${NAME}] Skipping, no settings found and no primitive with more than 32 vertices. mesh[${index}] has ${originalTotalVertexCount} vertices (max: ${originalMaxVertexCount})`);
|
|
343
|
-
|
|
354
|
+
return;
|
|
344
355
|
}
|
|
345
356
|
else {
|
|
346
357
|
settings = {
|
|
@@ -352,12 +363,12 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
352
363
|
}
|
|
353
364
|
else if (settings.generateLods === false) {
|
|
354
365
|
logger.debug(`[${NAME}] progressive mesh disabled for mesh at index ${index++}`);
|
|
355
|
-
|
|
366
|
+
return;
|
|
356
367
|
}
|
|
357
368
|
const progressiveExt = doc.createExtension(NEEDLE_progressive);
|
|
358
369
|
if (!progressiveExt || !progressiveExt.createMesh) {
|
|
359
370
|
logger.debug(`[${NAME}] Skipping because progressive extension is not available. ${index++}`);
|
|
360
|
-
|
|
371
|
+
return;
|
|
361
372
|
}
|
|
362
373
|
// check if we have already produced LODs for this mesh
|
|
363
374
|
let needsToGenerateLODs = true;
|
|
@@ -449,7 +460,11 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
449
460
|
let maxDensity = 0;
|
|
450
461
|
let primitiveIndex = 0;
|
|
451
462
|
const lodLevelInFile = generatedLODInfos.length;
|
|
463
|
+
const clonedData = new Array();
|
|
452
464
|
for (const prim of mesh.listPrimitives()) {
|
|
465
|
+
const data = clonePrimitiveData(prim);
|
|
466
|
+
clonedData.push(data);
|
|
467
|
+
console.log(`[${NAME}] Simplify mesh[${index}] primitive[${primitiveIndex}] with ${data.indices.length / 3} triangles`);
|
|
453
468
|
const lastLod = LODS[lodLevelInFile];
|
|
454
469
|
// TODO: this should be run after simplification but then we need to change the runtime to use the LOD 0 density
|
|
455
470
|
const density = calculateMeshDensity(prim);
|
|
@@ -476,7 +491,14 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
476
491
|
catch (err) {
|
|
477
492
|
logger.error(`ERR: [${NAME}] Failed to remove LOD files for \"${mesh.getName()}\"`);
|
|
478
493
|
}
|
|
479
|
-
|
|
494
|
+
// reset data (simplify might have changed the mesh data that we cloned before)
|
|
495
|
+
const primitives = mesh.listPrimitives();
|
|
496
|
+
if (clonedData.length == primitives.length) {
|
|
497
|
+
for (let i = 0; i < primitives.length; i++) {
|
|
498
|
+
setPrimitiveData(primitives[i], clonedData[i]);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return;
|
|
480
502
|
}
|
|
481
503
|
if (generatedLODInfos.length > 0) {
|
|
482
504
|
const model = progressiveExt.createMesh({
|
|
@@ -501,9 +523,31 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
501
523
|
}
|
|
502
524
|
}
|
|
503
525
|
}
|
|
504
|
-
console.log(`[${NAME}]: Finished generating progressive meshes for \"${filename}\"`);
|
|
505
526
|
});
|
|
506
527
|
}
|
|
528
|
+
function clonePrimitiveData(prim) {
|
|
529
|
+
const indices = new Uint32Array(prim.getIndices().getArray());
|
|
530
|
+
const attributes = {};
|
|
531
|
+
for (const attr of prim.listSemantics()) {
|
|
532
|
+
const accessor = prim.getAttribute(attr);
|
|
533
|
+
if (accessor) {
|
|
534
|
+
attributes[attr] = new Float32Array(accessor.getArray());
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return { indices, attributes };
|
|
538
|
+
}
|
|
539
|
+
function setPrimitiveData(prim, data) {
|
|
540
|
+
const indices = prim.getIndices();
|
|
541
|
+
if (indices) {
|
|
542
|
+
indices.setArray(data.indices);
|
|
543
|
+
}
|
|
544
|
+
for (const attr of prim.listSemantics()) {
|
|
545
|
+
const accessor = prim.getAttribute(attr);
|
|
546
|
+
if (accessor) {
|
|
547
|
+
accessor.setArray(data.attributes[attr]);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
507
551
|
/**
|
|
508
552
|
* @param basePath the base path to save the lod files
|
|
509
553
|
* @param level: 0 = original, 1 = first lod, 2 = second lod, ...
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/gltf-build-pipeline",
|
|
3
|
-
"version": "1.4.1-beta.
|
|
3
|
+
"version": "1.4.1-beta.15",
|
|
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",
|