@forgeax/engine-geometry 0.1.33 → 0.1.35
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vertex-attribute-layout.d.ts","sourceRoot":"","sources":["../src/vertex-attribute-layout.ts"],"names":[],"mappings":"AA+BA,OAAO,EAEL,UAAU,EAGV,KAAK,MAAM,EACX,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAE/B,MAAM,uBAAuB,CAAC;AAE/B,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;CAehB,CAAC;AAEX,KAAK,YAAY,GAAG,MAAM,OAAO,oBAAoB,CAAC;AAmBtD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;QACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC,CAAC;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;CACvD;AAgBD,gFAAgF;AAChF,eAAO,MAAM,4BAA4B,EAAE,kBAKzC,CAAC;AAEH,kEAAkE;AAClE,eAAO,MAAM,yBAAyB,EAAE,kBAItC,CAAC;AA4BH;;;;;;;;;;;;GAYG;AACH,wBAAgB,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,CAOrF;AAED,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,kBAAkB,EACvB,IAAI,CAAC,EAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,GACnC,0BAA0B,EAAE,CAwC9B;AAED,4FAA4F;AAC5F,wBAAgB,sCAAsC,CACpD,UAAU,EAAE,sBAAsB,EAClC,IAAI,CAAC,EAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,GACnC,0BAA0B,EAAE,CAyB9B;AAED,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,oBAAoB,CAAC,CAAC,YAAY,CAAC,CAAC;IAC7D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,iFAAiF;AACjF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,SAAS,+BAA+B,EAAE,CAAC;IAChE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE;IAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EACzC,UAAU,EAAE,sBAAsB,GACjC,MAAM,GAAG,SAAS,CAcpB;
|
|
1
|
+
{"version":3,"file":"vertex-attribute-layout.d.ts","sourceRoot":"","sources":["../src/vertex-attribute-layout.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgeax/engine-geometry",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.35",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"LICENSE"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@forgeax/engine-ecs": "0.1.
|
|
26
|
-
"@forgeax/engine-math": "0.1.
|
|
27
|
-
"@forgeax/engine-pack": "0.1.
|
|
28
|
-
"@forgeax/engine-types": "0.1.
|
|
25
|
+
"@forgeax/engine-ecs": "0.1.35",
|
|
26
|
+
"@forgeax/engine-math": "0.1.35",
|
|
27
|
+
"@forgeax/engine-pack": "0.1.35",
|
|
28
|
+
"@forgeax/engine-types": "0.1.35"
|
|
29
29
|
},
|
|
30
30
|
"forgeax": {
|
|
31
31
|
"metrics": {
|
|
@@ -33,6 +33,22 @@ function makeCompleteAttributeMap(): VertexAttributeMap {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
describe('vertex attribute layout owner', () => {
|
|
36
|
+
it('shares immutable layouts by attribute presence while observing mutable map edits', () => {
|
|
37
|
+
const map = { position: makeBuffer(), normal: makeBuffer() };
|
|
38
|
+
const first = deriveVertexLayoutProjection(map);
|
|
39
|
+
const sibling = deriveVertexLayoutProjection({ normal: makeBuffer(), position: makeBuffer() });
|
|
40
|
+
expect(sibling).toBe(first);
|
|
41
|
+
expect(deriveVertexLayoutProjectionFromMask(first.mask).unwrap()).toBe(first);
|
|
42
|
+
expect(Object.isFrozen(first.attributes[0])).toBe(true);
|
|
43
|
+
const edited: Record<string, Float32Array> = map;
|
|
44
|
+
edited.color = makeBuffer();
|
|
45
|
+
const colored = deriveVertexLayoutProjection(edited);
|
|
46
|
+
expect(colored).not.toBe(first);
|
|
47
|
+
expect(colored.arrayStride).toBe(first.arrayStride + 16);
|
|
48
|
+
delete edited.color;
|
|
49
|
+
expect(deriveVertexLayoutProjection(edited)).toBe(first);
|
|
50
|
+
});
|
|
51
|
+
|
|
36
52
|
it('publishes the ordinary and skinned maps from the same geometry owner', () => {
|
|
37
53
|
expect(Object.keys(DEFAULT_VERTEX_ATTRIBUTE_MAP)).toEqual([
|
|
38
54
|
'position',
|
|
@@ -315,24 +315,31 @@ function fnv1a(input: string): string {
|
|
|
315
315
|
return `vlp-v1-${(hash >>> 0).toString(16).padStart(8, '0')}`;
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
+
// The finite canonical mask is the complete layout identity. Do not key this
|
|
319
|
+
// cache by a mesh/map object: authoring maps may change in place.
|
|
320
|
+
const layoutsByMask = new Map<number, VertexLayoutProjection>();
|
|
321
|
+
|
|
318
322
|
/** Derive the one canonical immutable layout projection for a vertex map. */
|
|
319
323
|
export function deriveVertexLayoutProjection(map: VertexAttributeMap): VertexLayoutProjection {
|
|
324
|
+
let mask = 0;
|
|
325
|
+
for (let index = 0; index < CANONICAL_KEYS.length; index += 1) {
|
|
326
|
+
const key = CANONICAL_KEYS[index];
|
|
327
|
+
if (key !== undefined && map[key] !== undefined) mask |= 1 << index;
|
|
328
|
+
}
|
|
329
|
+
return layoutFromMask(mask);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function layoutFromMask(mask: number): VertexLayoutProjection {
|
|
333
|
+
const cached = layoutsByMask.get(mask);
|
|
334
|
+
if (cached !== undefined) return cached;
|
|
320
335
|
const attributes: VertexLayoutProjectionAttribute[] = [];
|
|
321
336
|
let offset = 0;
|
|
322
|
-
let
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
if (value === undefined) continue;
|
|
337
|
+
for (let index = 0; index < CANONICAL_KEYS.length; index += 1) {
|
|
338
|
+
const key = CANONICAL_KEYS[index];
|
|
339
|
+
if (key === undefined || (mask & (1 << index)) === 0) continue;
|
|
326
340
|
const format = ATTRIBUTE_FORMAT_MAP[key];
|
|
327
341
|
const byteLength = bytesForFormat(format);
|
|
328
|
-
attributes.push({
|
|
329
|
-
key,
|
|
330
|
-
shaderLocation: CANONICAL_KEYS.indexOf(key),
|
|
331
|
-
offset,
|
|
332
|
-
format,
|
|
333
|
-
byteLength,
|
|
334
|
-
});
|
|
335
|
-
mask |= 1 << CANONICAL_KEYS.indexOf(key);
|
|
342
|
+
attributes.push(Object.freeze({ key, shaderLocation: index, offset, format, byteLength }));
|
|
336
343
|
offset += byteLength;
|
|
337
344
|
}
|
|
338
345
|
const digestInput = [
|
|
@@ -343,13 +350,15 @@ export function deriveVertexLayoutProjection(map: VertexAttributeMap): VertexLay
|
|
|
343
350
|
(entry) => `${entry.key},${entry.shaderLocation},${entry.offset},${entry.format}`,
|
|
344
351
|
),
|
|
345
352
|
].join('|');
|
|
346
|
-
|
|
353
|
+
const projection: VertexLayoutProjection = Object.freeze({
|
|
347
354
|
schemaVersion: 1,
|
|
348
355
|
attributes: Object.freeze(attributes),
|
|
349
356
|
mask,
|
|
350
357
|
arrayStride: offset,
|
|
351
358
|
digest: fnv1a(digestInput),
|
|
352
359
|
});
|
|
360
|
+
layoutsByMask.set(mask, projection);
|
|
361
|
+
return projection;
|
|
353
362
|
}
|
|
354
363
|
|
|
355
364
|
export interface PackedVertexAttributes {
|
|
@@ -405,14 +414,7 @@ export function deriveVertexLayoutProjectionFromMask(
|
|
|
405
414
|
detail: { mask, knownMask, unknownMask, reason: 'unknown-bits' },
|
|
406
415
|
});
|
|
407
416
|
}
|
|
408
|
-
|
|
409
|
-
for (let index = 0; index < CANONICAL_KEYS.length; index += 1) {
|
|
410
|
-
if ((mask & (1 << index)) === 0) continue;
|
|
411
|
-
const key = CANONICAL_KEYS[index];
|
|
412
|
-
if (key !== undefined)
|
|
413
|
-
map[key] = key === 'skinIndex' ? new Uint16Array(0) : new Float32Array(0);
|
|
414
|
-
}
|
|
415
|
-
return ok(deriveVertexLayoutProjection(map as VertexAttributeMap));
|
|
417
|
+
return ok(layoutFromMask(unsignedMask));
|
|
416
418
|
}
|
|
417
419
|
|
|
418
420
|
/** Pack tightly-owned attributes into the projection's canonical interleaved bytes. */
|