@forgeax/engine-geometry 0.1.23 → 0.1.25
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/index.mjs +42 -25
- 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/tangent.ts +46 -32
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physical-tangent.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/physical-tangent.unit.test.ts"],"names":[],"mappings":""}
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { decodeMeshBinHeader, MESH_BIN_HEADER_V4_BYTES, MESH_BIN_VERSION } from '@forgeax/engine-pack';
|
|
2
2
|
import { box3, circle2, box2 } from '@forgeax/engine-math';
|
|
3
|
-
import { ok, countUvSets, AssetError, ASSET_ERROR_HINTS
|
|
3
|
+
import { err, ok, countUvSets, AssetError, ASSET_ERROR_HINTS } from '@forgeax/engine-types';
|
|
4
4
|
|
|
5
5
|
// src/assets/mesh-binary.ts
|
|
6
6
|
var EPSILON = 1e-8;
|
|
@@ -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;
|