@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
129 lines (97 loc) • 3.77 kB
JavaScript
import { STSpace } from "./STSpace.js";
import { vec3 } from "gl-matrix";
import { GROUP_WITH_ANY } from "./constants/GROUP_WITH_ANY.js";
import { assert } from "../../../../core/assert.js";
import { GetNormal } from "./GetNormal.js";
import { NormalizeSafe } from "./NormalizeSafe.js";
import { GetPosition } from "./GetPosition.js";
import { clamp01 } from "../../../../core/math/clamp01.js";
import { v3_scale_dot_sub_normalize } from "./v3_scale_dot_sub_normalize.js";
let offset = 0;
const _buffer = new ArrayBuffer(3 * 4 * 6);
const vOs = new Float32Array(_buffer, offset, 3);
offset += 12;
const vOt = new Float32Array(_buffer, offset, 3);
offset += 12;
const n = new Float32Array(_buffer, offset, 3);
offset += 12;
const p0 = new Float32Array(_buffer, offset, 3);
offset += 12;
const p1 = new Float32Array(_buffer, offset, 3);
offset += 12;
const p2 = new Float32Array(_buffer, offset, 3);
offset += 12;
/**
*
* @param {STSpace} res
* @param {number[]|Uint32Array|Int32Array} face_indices
* @param {number} iFaces
* @param {number[]} piTriListIn
* @param {STriInfo[]} pTriInfos
* @param {SMikkTSpaceContext} pContext
* @param {number} iVertexRepresentitive
*/
export function EvalTspace(res, face_indices, iFaces, piTriListIn, pTriInfos, pContext, iVertexRepresentitive) {
let fAngleSum = 0;
res.vOs[0] = 0.0;
res.vOs[1] = 0.0;
res.vOs[2] = 0.0;
res.vOt[0] = 0.0;
res.vOt[1] = 0.0;
res.vOt[2] = 0.0;
res.fMagS = 0;
res.fMagT = 0;
for (let face = 0; face < iFaces; face++) {
const f = face_indices[face];
const tri_info = pTriInfos[f];
// only valid triangles get to add their contribution
if ((tri_info.iFlag & GROUP_WITH_ANY) === 0) {
let i = -1;
const f3 = 3 * f;
if (piTriListIn[f3] === iVertexRepresentitive) {
i = 0;
} else if (piTriListIn[f3 + 1] === iVertexRepresentitive) {
i = 1;
} else if (piTriListIn[f3 + 2] === iVertexRepresentitive) {
i = 2;
}
assert(i >= 0 && i < 3);
// project
const index = piTriListIn[f3 + i];
GetNormal(n, pContext, index);
v3_scale_dot_sub_normalize(vOs, n, tri_info.vOs);
v3_scale_dot_sub_normalize(vOt, n, tri_info.vOt);
const i0 = piTriListIn[f3 + (i > 0 ? (i - 1) : 2)];
const i1 = piTriListIn[f3 + i];
const i2 = piTriListIn[f3 + (i < 2 ? (i + 1) : 0)];
GetPosition(p0, 0, pContext, i0);
GetPosition(p1, 0, pContext, i1);
GetPosition(p2, 0, pContext, i2);
vec3.sub(p0, p0, p1);
vec3.sub(p1, p2, p1);
// project
v3_scale_dot_sub_normalize(p0, n, p0);
v3_scale_dot_sub_normalize(p1, n, p1);
// weight contribution by the angle
// between the two edge vectors
const fCos = clamp01(vec3.dot(p0, p1));
const fAngle = Math.acos(fCos);
const fMagS = tri_info.fMagS;
const fMagT = tri_info.fMagT;
vec3.scale(p2, vOs, fAngle);
vec3.add(res.vOs, res.vOs, p2);
vec3.scale(p2, vOt, fAngle);
vec3.add(res.vOt, res.vOt, p2);
res.fMagS += (fAngle * fMagS);
res.fMagT += (fAngle * fMagT);
fAngleSum += fAngle;
}
}
// normalize
NormalizeSafe(res.vOs, res.vOs);
NormalizeSafe(res.vOt, res.vOt);
if (fAngleSum > 0) {
res.fMagS /= fAngleSum;
res.fMagT /= fAngleSum;
}
}