@forgeax/engine-geometry 0.1.32 → 0.1.34
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/README.md
CHANGED
|
@@ -33,6 +33,12 @@ forgeax-engine. A **leaf** package: depends on `@forgeax/engine-ecs` (`Result`),
|
|
|
33
33
|
structured `.detail.field/.value/.reason`. No silent fallback, no `console.warn`,
|
|
34
34
|
no `null` return (charter P3).
|
|
35
35
|
|
|
36
|
+
The canonical vertex layout is interned by its finite attribute-presence mask.
|
|
37
|
+
Mesh maps and packed masks resolve to the same deeply frozen projection; changing
|
|
38
|
+
an authoring map's attributes derives a different mask without retaining the map
|
|
39
|
+
or its buffers. Layout offsets, formats, and digests still derive from the one
|
|
40
|
+
canonical attribute schema.
|
|
41
|
+
|
|
36
42
|
## MeshBuilder
|
|
37
43
|
|
|
38
44
|
`MeshBuilder` is the incremental authoring owner for custom geometry. Append
|
package/dist/index.mjs
CHANGED
|
@@ -400,23 +400,26 @@ function fnv1a(input) {
|
|
|
400
400
|
}
|
|
401
401
|
return `vlp-v1-${(hash >>> 0).toString(16).padStart(8, "0")}`;
|
|
402
402
|
}
|
|
403
|
+
var layoutsByMask = /* @__PURE__ */ new Map();
|
|
403
404
|
function deriveVertexLayoutProjection(map) {
|
|
405
|
+
let mask = 0;
|
|
406
|
+
for (let index = 0; index < CANONICAL_KEYS.length; index += 1) {
|
|
407
|
+
const key = CANONICAL_KEYS[index];
|
|
408
|
+
if (key !== void 0 && map[key] !== void 0) mask |= 1 << index;
|
|
409
|
+
}
|
|
410
|
+
return layoutFromMask(mask);
|
|
411
|
+
}
|
|
412
|
+
function layoutFromMask(mask) {
|
|
413
|
+
const cached = layoutsByMask.get(mask);
|
|
414
|
+
if (cached !== void 0) return cached;
|
|
404
415
|
const attributes = [];
|
|
405
416
|
let offset = 0;
|
|
406
|
-
let
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
if (value === void 0) continue;
|
|
417
|
+
for (let index = 0; index < CANONICAL_KEYS.length; index += 1) {
|
|
418
|
+
const key = CANONICAL_KEYS[index];
|
|
419
|
+
if (key === void 0 || (mask & 1 << index) === 0) continue;
|
|
410
420
|
const format = ATTRIBUTE_FORMAT_MAP[key];
|
|
411
421
|
const byteLength = bytesForFormat(format);
|
|
412
|
-
attributes.push({
|
|
413
|
-
key,
|
|
414
|
-
shaderLocation: CANONICAL_KEYS.indexOf(key),
|
|
415
|
-
offset,
|
|
416
|
-
format,
|
|
417
|
-
byteLength
|
|
418
|
-
});
|
|
419
|
-
mask |= 1 << CANONICAL_KEYS.indexOf(key);
|
|
422
|
+
attributes.push(Object.freeze({ key, shaderLocation: index, offset, format, byteLength }));
|
|
420
423
|
offset += byteLength;
|
|
421
424
|
}
|
|
422
425
|
const digestInput = [
|
|
@@ -427,13 +430,15 @@ function deriveVertexLayoutProjection(map) {
|
|
|
427
430
|
(entry) => `${entry.key},${entry.shaderLocation},${entry.offset},${entry.format}`
|
|
428
431
|
)
|
|
429
432
|
].join("|");
|
|
430
|
-
|
|
433
|
+
const projection = Object.freeze({
|
|
431
434
|
schemaVersion: 1,
|
|
432
435
|
attributes: Object.freeze(attributes),
|
|
433
436
|
mask,
|
|
434
437
|
arrayStride: offset,
|
|
435
438
|
digest: fnv1a(digestInput)
|
|
436
439
|
});
|
|
440
|
+
layoutsByMask.set(mask, projection);
|
|
441
|
+
return projection;
|
|
437
442
|
}
|
|
438
443
|
var VertexAttributePackError = class extends AssetError {
|
|
439
444
|
constructor(detail) {
|
|
@@ -465,14 +470,7 @@ function deriveVertexLayoutProjectionFromMask(mask) {
|
|
|
465
470
|
detail: { mask, knownMask, unknownMask, reason: "unknown-bits" }
|
|
466
471
|
});
|
|
467
472
|
}
|
|
468
|
-
|
|
469
|
-
for (let index = 0; index < CANONICAL_KEYS.length; index += 1) {
|
|
470
|
-
if ((mask & 1 << index) === 0) continue;
|
|
471
|
-
const key = CANONICAL_KEYS[index];
|
|
472
|
-
if (key !== void 0)
|
|
473
|
-
map[key] = key === "skinIndex" ? new Uint16Array(0) : new Float32Array(0);
|
|
474
|
-
}
|
|
475
|
-
return ok(deriveVertexLayoutProjection(map));
|
|
473
|
+
return ok(layoutFromMask(unsignedMask));
|
|
476
474
|
}
|
|
477
475
|
function packInterleavedVertexAttributes(map, vertexCount) {
|
|
478
476
|
const invalid3 = (detail) => err(new VertexAttributePackError(detail));
|