@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,2 +1,3 @@
1
- import { Transform } from '@gltf-transform/core';
1
+ import { Document, Transform } from '@gltf-transform/core';
2
+ export declare function writeNeedleAsset(document: Document): void;
2
3
  export declare function needle_asset(): Transform;
@@ -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
- const root = document.getRoot();
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 = new Array();
478
+ const clonedData = { primitives: [], weights: [...mesh.getWeights()] };
478
479
  for (const prim of mesh.listPrimitives()) {
479
480
  const data = clonePrimitiveData(prim);
480
- clonedData.push(data);
481
- console.log(`[${NAME}] Simplify mesh[${index}] primitive[${primitiveIndex}] with ${data.indices.length / 3} triangles`);
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 LODs. \"${mesh.getName()}\"`);
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 prim.listSemantics()) {
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.5",
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",