@needle-tools/gltf-build-pipeline 2.8.0-alpha.2 → 2.8.1-alpha.0

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,11 @@ 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
+ ## [2.8.1-alpha.0] - 2024-03-26
8
+ - Fix: Issue where cache key gets longer depending on the primitive count
9
+ - Fix: Cache key not taking index buffer into account
10
+ - Fix: Caching of mesh LODs did clone shared mesh attributes for every primitive instead of re-using previous clones
11
+
7
12
  ## [2.8.0-alpha.2] - 2024-03-04
8
13
  - change: use webp compression for textures smaller than 32x32
9
14
  - fix: webp compression for small textures (64x64)
@@ -202,8 +202,9 @@ export function getHash(property, level = 0) {
202
202
  const weights = property.getWeights();
203
203
  hash += hashObject(weights);
204
204
  const primitives = property.listPrimitives();
205
- for (const prim of primitives)
206
- hashStr += getHash(prim, level + 1);
205
+ for (const prim of primitives) {
206
+ hash += hashString(getHash(prim, level + 1));
207
+ }
207
208
  }
208
209
  else if (property instanceof Primitive) {
209
210
  const indices = property.getIndices();
@@ -222,11 +223,19 @@ export function getHash(property, level = 0) {
222
223
  targets,
223
224
  semantics: semanticsNames
224
225
  });
226
+ if (indices) {
227
+ const indexBuffer = indices.getArray();
228
+ if (indexBuffer) {
229
+ hash += hashBuffer(indexBuffer.buffer, indexBuffer.byteOffset, indexBuffer.byteLength);
230
+ }
231
+ }
225
232
  // We can not pass the whole buffer into hashObject since very large meshes will cause errors when trying to stringify
226
233
  // See https://linear.app/needle/issue/NE-6414
227
234
  for (const sem of semantics) {
228
- const arr = property.getAttribute(sem).getArray();
229
- hash += hashBuffer(arr.buffer, arr.byteOffset, arr.byteLength);
235
+ const arr = property.getAttribute(sem)?.getArray();
236
+ if (arr) {
237
+ hash += hashBuffer(arr.buffer, arr.byteOffset, arr.byteLength);
238
+ }
230
239
  }
231
240
  }
232
241
  }
@@ -850,27 +850,14 @@ async function createMeshLod(inputFileName, doc, basePath, level, mesh, meshInfo
850
850
  }
851
851
  const tasks = new Array();
852
852
  // let didRunSimplification = false;
853
+ const clonedAttributes = new Map();
854
+ debugger;
853
855
  for (const prim of primitives) {
854
856
  const newPrim = newDoc.createPrimitive();
855
857
  newMesh.addPrimitive(newPrim);
856
858
  newPrim.setName(prim.getName());
857
859
  newPrim.setMode(prim.getMode());
858
860
  newPrim.setMaterial(newMat);
859
- const semantics = prim.listSemantics();
860
- for (let i = 0; i < semantics.length; i++) {
861
- const attr = prim.getAttribute(semantics[i]);
862
- if (attr) {
863
- const newAttr = newDoc.createAccessor();
864
- newAttr.setArray(attr.getArray());
865
- newAttr.setType(attr.getType());
866
- newAttr.setSparse(attr.getSparse());
867
- newAttr.setNormalized(attr.getNormalized());
868
- newPrim.setAttribute(semantics[i], newAttr);
869
- }
870
- else {
871
- logger.warn(`[${NAME}] Missing attribute ${semantics[i]} in mesh LOD ${level}`);
872
- }
873
- }
874
861
  const indices = prim.getIndices();
875
862
  if (indices) {
876
863
  const newIndices = newDoc.createAccessor();
@@ -880,6 +867,28 @@ async function createMeshLod(inputFileName, doc, basePath, level, mesh, meshInfo
880
867
  newIndices.setNormalized(indices.getNormalized());
881
868
  newPrim.setIndices(newIndices);
882
869
  }
870
+ const semantics = prim.listSemantics();
871
+ for (let i = 0; i < semantics.length; i++) {
872
+ const attr = prim.getAttribute(semantics[i]);
873
+ if (attr) {
874
+ if (clonedAttributes.has(attr)) {
875
+ const cloned = clonedAttributes.get(attr);
876
+ newPrim.setAttribute(semantics[i], cloned);
877
+ }
878
+ else {
879
+ const newAttr = newDoc.createAccessor();
880
+ newAttr.setArray(attr.getArray());
881
+ newAttr.setType(attr.getType());
882
+ newAttr.setSparse(attr.getSparse());
883
+ newAttr.setNormalized(attr.getNormalized());
884
+ newPrim.setAttribute(semantics[i], newAttr);
885
+ clonedAttributes.set(attr, newAttr);
886
+ }
887
+ }
888
+ else {
889
+ logger.warn(`[${NAME}] Missing attribute ${semantics[i]} in mesh LOD ${level}`);
890
+ }
891
+ }
883
892
  const targets = prim.listTargets();
884
893
  for (const target of targets) {
885
894
  const newTarget = newDoc.createPrimitiveTarget(target.getName());
@@ -964,7 +973,8 @@ async function createMeshLod(inputFileName, doc, basePath, level, mesh, meshInfo
964
973
  // add to cache
965
974
  if (cacheKey != undefined) {
966
975
  const bytes = readFileSync(outPath);
967
- logger.info(`[${NAME}] Add LOD ${level} to cache for \"${mesh.getName()}\" as ${cacheKey}`);
976
+ const sizeInMB = (bytes.byteLength / 1024 / 1024).toFixed(2);
977
+ logger.info(`[${NAME}] Add LOD ${level} to cache (${sizeInMB} MB) for \"${mesh.getName()}\" as ${cacheKey}`);
968
978
  addToCache(cacheKey, bytes);
969
979
  addMetaToCache(cacheKey, { meshInfo: newMeshInformation, density: density });
970
980
  }
@@ -1 +1 @@
1
- export declare const version = "2.8.0-alpha.2";
1
+ export declare const version = "2.8.1-alpha.0";
@@ -1 +1 @@
1
- export const version = "2.8.0-alpha.2";
1
+ export const version = "2.8.1-alpha.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/gltf-build-pipeline",
3
- "version": "2.8.0-alpha.2",
3
+ "version": "2.8.1-alpha.0",
4
4
  "description": "Pipeline and tools for optimizing gltf files using gltf-transform and compression settings within glTF extensions",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",