@forgeax/engine-geometry 0.1.21 → 0.1.24
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/dist/__tests__/physical-tangent.unit.test.d.ts +2 -0
- package/dist/__tests__/physical-tangent.unit.test.d.ts.map +1 -0
- package/dist/assets/mesh-binary.d.ts.map +1 -1
- package/dist/assets/mesh-decoder.d.ts.map +1 -1
- package/dist/assets/primitive-mesh.d.ts +2 -0
- package/dist/assets/primitive-mesh.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +64 -43
- package/dist/index.mjs.map +1 -1
- package/dist/tangent.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/physical-tangent.unit.test.ts +34 -0
- package/src/assets/mesh-binary.ts +3 -1
- package/src/assets/mesh-decoder.ts +4 -17
- package/src/assets/primitive-mesh.ts +19 -0
- package/src/index.ts +6 -2
- package/src/tangent.ts +46 -32
- package/dist/.tsbuildinfo +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physical-tangent.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/physical-tangent.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mesh-binary.d.ts","sourceRoot":"","sources":["../../src/assets/mesh-binary.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,SAAS,EAKV,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"mesh-binary.d.ts","sourceRoot":"","sources":["../../src/assets/mesh-binary.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,SAAS,EAKV,MAAM,uBAAuB,CAAC;AAkW/B,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,SAAS,GAAG,SAAS,CA0BvB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,SAAS,GAAG,SAAS,CAgCvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mesh-decoder.d.ts","sourceRoot":"","sources":["../../src/assets/mesh-decoder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAC7B,KAAK,SAAS,EAGd,KAAK,SAAS,EAGf,MAAM,uBAAuB,CAAC;AAI/B,eAAO,MAAM,aAAa,EAAE,SAAS,CAAC,SAAS,EAAE,MAAM,CAEtB,CAAC;
|
|
1
|
+
{"version":3,"file":"mesh-decoder.d.ts","sourceRoot":"","sources":["../../src/assets/mesh-decoder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAC7B,KAAK,SAAS,EAGd,KAAK,SAAS,EAGf,MAAM,uBAAuB,CAAC;AAI/B,eAAO,MAAM,aAAa,EAAE,SAAS,CAAC,SAAS,EAAE,MAAM,CAEtB,CAAC;AAclC,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,EAAE,YAAY,CAAC,SAAS,CA+CpD,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,wBAAwB,CAAC,SAAS,EAAE,MAAM,CAI7E,CAAC"}
|
|
@@ -2,4 +2,6 @@ import type { AssetError, MeshAsset, Result } from '@forgeax/engine-types';
|
|
|
2
2
|
export type PrimitiveMeshKind = 'cube' | 'triangle' | 'quad' | 'sphere' | 'cylinder' | 'nine-slice-quad';
|
|
3
3
|
/** Create one ordinary mesh payload for allocation or interning by an owning World. */
|
|
4
4
|
export declare function createPrimitiveMesh(kind: PrimitiveMeshKind): Result<MeshAsset, AssetError>;
|
|
5
|
+
/** Resolve the canonical Pack v2 procedural mesh descriptor without duplicating its alias table. */
|
|
6
|
+
export declare function createProceduralMesh(payload: unknown): Result<MeshAsset, AssetError> | undefined;
|
|
5
7
|
//# sourceMappingURL=primitive-mesh.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitive-mesh.d.ts","sourceRoot":"","sources":["../../src/assets/primitive-mesh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAM3E,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,UAAU,GACV,MAAM,GACN,QAAQ,GACR,UAAU,GACV,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"primitive-mesh.d.ts","sourceRoot":"","sources":["../../src/assets/primitive-mesh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAM3E,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,UAAU,GACV,MAAM,GACN,QAAQ,GACR,UAAU,GACV,iBAAiB,CAAC;AAWtB,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,CAoB1F;AAED,oGAAoG;AACpG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG,SAAS,CAOhG"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type { VertexAttributePackDetail } from '@forgeax/engine-types';
|
|
2
|
+
export { decodeMeshBinary, normalizeMeshPayload } from './assets/mesh-binary';
|
|
2
3
|
export { meshAssetContribution, meshAssetDecoder, meshAssetKind } from './assets/mesh-decoder';
|
|
3
|
-
export { createPrimitiveMesh, type PrimitiveMeshKind } from './assets/primitive-mesh';
|
|
4
|
+
export { createPrimitiveMesh, createProceduralMesh, type PrimitiveMeshKind, } from './assets/primitive-mesh';
|
|
4
5
|
export { createBoxGeometry, meshFromInterleaved, PROCEDURAL_FLOATS_PER_VERTEX, } from './box';
|
|
5
6
|
export { createCapsuleGeometry } from './capsule';
|
|
6
7
|
export { createConeGeometry } from './cone';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,YAAY,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,YAAY,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC/F,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,iBAAiB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,4BAA4B,GAC7B,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,KAAK,OAAO,EACZ,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,IAAI,GACV,MAAM,QAAQ,CAAC;AAEhB,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EACL,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EACL,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EACL,8BAA8B,EAC9B,wBAAwB,EACxB,sCAAsC,EACtC,4BAA4B,EAC5B,oCAAoC,EACpC,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC3B,+BAA+B,EAC/B,wBAAwB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,EACpC,KAAK,+BAA+B,GACrC,MAAM,2BAA2B,CAAC"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ok, countUvSets, AssetError, ASSET_ERROR_HINTS, err } from '@forgeax/engine-types';
|
|
2
1
|
import { decodeMeshBinHeader, MESH_BIN_HEADER_V4_BYTES, MESH_BIN_VERSION } from '@forgeax/engine-pack';
|
|
3
2
|
import { box3, circle2, box2 } from '@forgeax/engine-math';
|
|
3
|
+
import { err, ok, countUvSets, AssetError, ASSET_ERROR_HINTS } from '@forgeax/engine-types';
|
|
4
4
|
|
|
5
|
-
// src/assets/mesh-
|
|
5
|
+
// src/assets/mesh-binary.ts
|
|
6
6
|
var EPSILON = 1e-8;
|
|
7
7
|
function tangentInputError(field, value, reason) {
|
|
8
8
|
return new AssetError({
|
|
@@ -82,6 +82,7 @@ function computeTangentVec4(positions, normals, uvs, indices) {
|
|
|
82
82
|
const vertexCount = preflight.value;
|
|
83
83
|
const accumT = new Float32Array(vertexCount * 3);
|
|
84
84
|
const accumSign = new Float32Array(vertexCount);
|
|
85
|
+
let validTriangleCount = 0;
|
|
85
86
|
const triangleCount = indices !== void 0 ? indices.length / 3 : vertexCount / 3;
|
|
86
87
|
for (let tri = 0; tri < triangleCount; tri++) {
|
|
87
88
|
const i0 = indices !== void 0 ? indices[tri * 3] ?? 0 : tri * 3;
|
|
@@ -125,6 +126,7 @@ function computeTangentVec4(positions, normals, uvs, indices) {
|
|
|
125
126
|
const cz = dP1x * dP2y - dP1y * dP2x;
|
|
126
127
|
const faceArea = 0.5 * Math.sqrt(cx * cx + cy * cy + cz * cz);
|
|
127
128
|
if (faceArea < EPSILON) continue;
|
|
129
|
+
validTriangleCount += 1;
|
|
128
130
|
const signDet = det >= 0 ? 1 : -1;
|
|
129
131
|
const signedWeight = faceArea * signDet;
|
|
130
132
|
for (const vi of [i0, i1, i2]) {
|
|
@@ -134,6 +136,15 @@ function computeTangentVec4(positions, normals, uvs, indices) {
|
|
|
134
136
|
accumSign[vi] = (accumSign[vi] ?? 0) + signedWeight;
|
|
135
137
|
}
|
|
136
138
|
}
|
|
139
|
+
if (validTriangleCount === 0) {
|
|
140
|
+
return err(
|
|
141
|
+
tangentInputError(
|
|
142
|
+
"tangent",
|
|
143
|
+
0,
|
|
144
|
+
"material-tangent-required: no triangle has a valid UV-derived tangent"
|
|
145
|
+
)
|
|
146
|
+
);
|
|
147
|
+
}
|
|
137
148
|
const out = new Float32Array(vertexCount * 4);
|
|
138
149
|
for (let v = 0; v < vertexCount; v++) {
|
|
139
150
|
let tx = accumT[v * 3] ?? 0;
|
|
@@ -150,26 +161,29 @@ function computeTangentVec4(positions, normals, uvs, indices) {
|
|
|
150
161
|
let rx = 1;
|
|
151
162
|
let ry = 0;
|
|
152
163
|
let rz = 0;
|
|
153
|
-
if (ax
|
|
154
|
-
rx = 1;
|
|
155
|
-
ry = 0;
|
|
156
|
-
rz = 0;
|
|
157
|
-
} else if (ay <= ax && ay <= az) {
|
|
164
|
+
if (ax > ay && ax > az) {
|
|
158
165
|
rx = 0;
|
|
159
166
|
ry = 1;
|
|
160
|
-
|
|
161
|
-
} else {
|
|
167
|
+
} else if (ay > ax && ay > az) {
|
|
162
168
|
rx = 0;
|
|
163
|
-
ry = 0;
|
|
164
169
|
rz = 1;
|
|
165
170
|
}
|
|
166
171
|
tx = ny * rz - nz * ry;
|
|
167
172
|
ty = nz * rx - nx * rz;
|
|
168
173
|
tz = nx * ry - ny * rx;
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
174
|
+
const fallbackLength = Math.sqrt(tx * tx + ty * ty + tz * tz);
|
|
175
|
+
if (fallbackLength < EPSILON) {
|
|
176
|
+
return err(
|
|
177
|
+
tangentInputError(
|
|
178
|
+
"tangent",
|
|
179
|
+
v,
|
|
180
|
+
"material-tangent-required: supplied normal cannot define a tangent frame"
|
|
181
|
+
)
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
tx /= fallbackLength;
|
|
185
|
+
ty /= fallbackLength;
|
|
186
|
+
tz /= fallbackLength;
|
|
173
187
|
} else {
|
|
174
188
|
tx /= tLen;
|
|
175
189
|
ty /= tLen;
|
|
@@ -187,26 +201,29 @@ function computeTangentVec4(positions, normals, uvs, indices) {
|
|
|
187
201
|
let rx = 1;
|
|
188
202
|
let ry = 0;
|
|
189
203
|
let rz = 0;
|
|
190
|
-
if (ax
|
|
191
|
-
rx = 1;
|
|
192
|
-
ry = 0;
|
|
193
|
-
rz = 0;
|
|
194
|
-
} else if (ay <= ax && ay <= az) {
|
|
204
|
+
if (ax > ay && ax > az) {
|
|
195
205
|
rx = 0;
|
|
196
206
|
ry = 1;
|
|
197
|
-
|
|
198
|
-
} else {
|
|
207
|
+
} else if (ay > ax && ay > az) {
|
|
199
208
|
rx = 0;
|
|
200
|
-
ry = 0;
|
|
201
209
|
rz = 1;
|
|
202
210
|
}
|
|
203
211
|
gx = ny * rz - nz * ry;
|
|
204
212
|
gy = nz * rx - nx * rz;
|
|
205
213
|
gz = nx * ry - ny * rx;
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
214
|
+
const fallbackLength = Math.sqrt(gx * gx + gy * gy + gz * gz);
|
|
215
|
+
if (fallbackLength < EPSILON) {
|
|
216
|
+
return err(
|
|
217
|
+
tangentInputError(
|
|
218
|
+
"tangent",
|
|
219
|
+
v,
|
|
220
|
+
"material-tangent-required: supplied normal cannot define a tangent frame"
|
|
221
|
+
)
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
gx /= fallbackLength;
|
|
225
|
+
gy /= fallbackLength;
|
|
226
|
+
gz /= fallbackLength;
|
|
210
227
|
} else {
|
|
211
228
|
gx /= gLen;
|
|
212
229
|
gy /= gLen;
|
|
@@ -977,7 +994,7 @@ function materialSlotsFor(raw, submeshes, refs) {
|
|
|
977
994
|
if (raw === void 0)
|
|
978
995
|
return submeshes.map((_submesh, index) => ({ slotName: `LegacySlot_${index}` }));
|
|
979
996
|
return raw.map((slot, index) => {
|
|
980
|
-
const reference = slot.defaultMaterialRef === void 0 ?
|
|
997
|
+
const reference = slot.defaultMaterialRef === void 0 ? slot.defaultMaterial : refs[slot.defaultMaterialRef];
|
|
981
998
|
const defaultMaterial = reference === void 0 ? void 0 : parseGuid(reference);
|
|
982
999
|
return {
|
|
983
1000
|
slotName: typeof slot.slotName === "string" && slot.slotName.trim().length > 0 ? slot.slotName : `LegacySlot_${index}`,
|
|
@@ -1387,6 +1404,14 @@ function createSphereGeometry(radius, widthSegments = 16, heightSegments = 12) {
|
|
|
1387
1404
|
}
|
|
1388
1405
|
|
|
1389
1406
|
// src/assets/primitive-mesh.ts
|
|
1407
|
+
var PROCEDURAL_MESH_KINDS = {
|
|
1408
|
+
"procedural-cube": "cube",
|
|
1409
|
+
"procedural-triangle": "triangle",
|
|
1410
|
+
"procedural-quad": "quad",
|
|
1411
|
+
"procedural-sphere": "sphere",
|
|
1412
|
+
"procedural-cylinder": "cylinder",
|
|
1413
|
+
"procedural-nine-slice-quad": "nine-slice-quad"
|
|
1414
|
+
};
|
|
1390
1415
|
function createPrimitiveMesh(kind) {
|
|
1391
1416
|
switch (kind) {
|
|
1392
1417
|
case "cube":
|
|
@@ -1431,30 +1456,26 @@ function createPrimitiveMesh(kind) {
|
|
|
1431
1456
|
return createPlaneGeometry(1, 1, 3, 3);
|
|
1432
1457
|
}
|
|
1433
1458
|
}
|
|
1459
|
+
function createProceduralMesh(payload) {
|
|
1460
|
+
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) return void 0;
|
|
1461
|
+
const geometry = payload.geometry;
|
|
1462
|
+
if (typeof geometry !== "string") return void 0;
|
|
1463
|
+
const kind = PROCEDURAL_MESH_KINDS[geometry];
|
|
1464
|
+
if (kind === void 0) return void 0;
|
|
1465
|
+
return createPrimitiveMesh(kind);
|
|
1466
|
+
}
|
|
1434
1467
|
|
|
1435
1468
|
// src/assets/mesh-decoder.ts
|
|
1436
1469
|
var meshAssetKind = {
|
|
1437
1470
|
kind: "mesh"
|
|
1438
1471
|
};
|
|
1439
|
-
var PROCEDURAL_MESH_KINDS = {
|
|
1440
|
-
"procedural-cube": "cube",
|
|
1441
|
-
"procedural-triangle": "triangle",
|
|
1442
|
-
"procedural-quad": "quad",
|
|
1443
|
-
"procedural-sphere": "sphere",
|
|
1444
|
-
"procedural-cylinder": "cylinder",
|
|
1445
|
-
"procedural-nine-slice-quad": "nine-slice-quad"
|
|
1446
|
-
};
|
|
1447
1472
|
function proceduralMesh(payload) {
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
if (typeof geometry !== "string") return void 0;
|
|
1451
|
-
const kind = PROCEDURAL_MESH_KINDS[geometry];
|
|
1452
|
-
if (kind === void 0) return void 0;
|
|
1453
|
-
const result = createPrimitiveMesh(kind);
|
|
1473
|
+
const result = createProceduralMesh(payload);
|
|
1474
|
+
if (result === void 0) return void 0;
|
|
1454
1475
|
if (result.ok) return result;
|
|
1455
1476
|
return err({
|
|
1456
1477
|
code: "asset-package-invalid",
|
|
1457
|
-
expected:
|
|
1478
|
+
expected: result.error.expected,
|
|
1458
1479
|
hint: "recook the authored procedural mesh descriptor",
|
|
1459
1480
|
detail: { guid: "", reason: "procedural mesh creation failed" }
|
|
1460
1481
|
});
|
|
@@ -4265,6 +4286,6 @@ function createTorusGeometry(radius, tube, radialSegments = 8, tubularSegments =
|
|
|
4265
4286
|
return meshFromInterleaved(vertices, indices);
|
|
4266
4287
|
}
|
|
4267
4288
|
|
|
4268
|
-
export { PROCEDURAL_FLOATS_PER_VERTEX, VertexAttributePackError, buildMeshAttributeMapForUvSets, compute2dBounds, computeTangentVec4, create2dGeometry, create2dRingGeometry, createBoxGeometry, createCapsuleGeometry, createConeGeometry, createCylinderGeometry, createEdgesGeometry, createMeshBuilder, createPlaneGeometry, createPrimitiveMesh, createSphereGeometry, createTeapotGeometry, createTorusGeometry, createWireframeGeometry, deriveVertexBufferLayout, deriveVertexBufferLayoutFromProjection, deriveVertexLayoutProjection, deriveVertexLayoutProjectionFromMask, meshAssetContribution, meshAssetDecoder, meshAssetKind, meshFromInterleaved, packInterleavedVertexAttributes };
|
|
4289
|
+
export { PROCEDURAL_FLOATS_PER_VERTEX, VertexAttributePackError, buildMeshAttributeMapForUvSets, compute2dBounds, computeTangentVec4, create2dGeometry, create2dRingGeometry, createBoxGeometry, createCapsuleGeometry, createConeGeometry, createCylinderGeometry, createEdgesGeometry, createMeshBuilder, createPlaneGeometry, createPrimitiveMesh, createProceduralMesh, createSphereGeometry, createTeapotGeometry, createTorusGeometry, createWireframeGeometry, decodeMeshBinary, deriveVertexBufferLayout, deriveVertexBufferLayoutFromProjection, deriveVertexLayoutProjection, deriveVertexLayoutProjectionFromMask, meshAssetContribution, meshAssetDecoder, meshAssetKind, meshFromInterleaved, normalizeMeshPayload, packInterleavedVertexAttributes };
|
|
4269
4290
|
//# sourceMappingURL=index.mjs.map
|
|
4270
4291
|
//# sourceMappingURL=index.mjs.map
|