UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

129 lines (97 loc) 3.77 kB
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; } }