UNPKG

@tolokoban/tgd

Version:

ToloGameDev library for WebGL2

78 lines 10.3 kB
import { TgdDataset } from "./../dataset/index.js"; import { webglElementTypeArrayFromNumberArray } from "./../utils/index.js"; import { TgdGeometry } from "./geometry.js"; export class TgdGeometrySphereIco extends TgdGeometry { constructor({ center = [0, 0, 0], radius = 1, subdivisions = 2 } = {}) { const dataset = new TgdDataset({ POSITION: "vec3", NORMAL: "vec3", }); const positions = []; const normals = []; const elements = []; createIcosahedron(positions, normals, elements, center, radius); for (let loop = 0; loop < subdivisions; loop++) { subdivide(positions, normals, elements, center, radius); } dataset.set("POSITION", new Float32Array(positions)); dataset.set("NORMAL", new Float32Array(normals)); super({ dataset, elements: webglElementTypeArrayFromNumberArray(elements), drawMode: "TRIANGLES", }); } } function createIcosahedron(positions, normals, elements, center, radius) { const [cx, cy, cz] = center; normals.push(-0, -1, -0, 0.7236, -0.4472, 0.5257, -0.2764, -0.4472, 0.8507, -0.8944, -0.4472, -0, -0.2764, -0.4472, -0.8507, 0.7236, -0.4472, -0.5257, 0.2764, 0.4472, 0.8507, -0.7236, 0.4472, 0.5257, -0.7236, 0.4472, -0.5257, 0.2764, 0.4472, -0.8507, 0.8944, 0.4472, -0, -0, 1, -0); for (let i = 0; i < normals.length; i += 3) { positions.push(normals[i + 0] * radius + cx, normals[i + 1] * radius + cy, normals[i + 2] * radius + cz); } // prettier-ignore elements.push(0, 1, 2, 1, 0, 5, 0, 2, 3, 0, 3, 4, 0, 4, 5, 1, 5, 10, 2, 1, 6, 3, 2, 7, 4, 3, 8, 5, 4, 9, 1, 10, 6, 2, 6, 7, 3, 7, 8, 4, 8, 9, 5, 9, 10, 6, 10, 11, 7, 6, 11, 8, 7, 11, 9, 8, 11, 10, 9, 11); } /** * Each triangle will be divided in 4 sub triangles. */ function subdivide(positions, normals, elements, center, radius) { const [cx, cy, cz] = center; const newElements = []; let pointsCount = Math.floor(positions.length / 3); const indexesOfMidPoints = new Map(); const indexOfMidPoint = (indexA, indexB) => { const idxA = Math.min(indexA, indexB); const idxB = Math.max(indexA, indexB); const key = `${idxA}/${idxB}`; const indexFromCache = indexesOfMidPoints.get(key); if (typeof indexFromCache === "number") return indexFromCache; const [nx, ny, nz] = averageNormal(normals, idxA, idxB); normals.push(nx, ny, nz); positions.push(nx * radius + cx, ny * radius + cy, nz * radius + cz); const newIndex = pointsCount++; indexesOfMidPoints.set(key, newIndex); return newIndex; }; for (let e = 0; e < elements.length; e += 3) { const i0 = elements[e + 0]; const i1 = elements[e + 1]; const i2 = elements[e + 2]; const i01 = indexOfMidPoint(i0, i1); const i12 = indexOfMidPoint(i1, i2); const i02 = indexOfMidPoint(i0, i2); // prettier-ignore newElements.push(i0, i01, i02, i01, i1, i12, i01, i12, i02, i02, i12, i2); } elements.splice(0); elements.push(...newElements); } function averageNormal(normals, i0, i1) { const x = normals[i0 * 3 + 0] + normals[i1 * 3 + 0]; const y = normals[i0 * 3 + 1] + normals[i1 * 3 + 1]; const z = normals[i0 * 3 + 2] + normals[i1 * 3 + 2]; // eslint-disable-next-line unicorn/prefer-modern-math-apis const inv3 = 1 / Math.sqrt(x * x + y * y + z * z); return [x * inv3, y * inv3, z * inv3]; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BoZXJlLWljby5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9nZW9tZXRyeS9zcGhlcmUtaWNvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUE7QUFHekMsT0FBTyxFQUFFLG9DQUFvQyxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQ2pFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFleEMsTUFBTSxPQUFPLG9CQUFxQixTQUFRLFdBQVc7SUFDakQsWUFBWSxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxZQUFZLEdBQUcsQ0FBQyxLQUFrQyxFQUFFO1FBQzlGLE1BQU0sT0FBTyxHQUFHLElBQUksVUFBVSxDQUFDO1lBQzNCLFFBQVEsRUFBRSxNQUFNO1lBQ2hCLE1BQU0sRUFBRSxNQUFNO1NBQ2pCLENBQUMsQ0FBQTtRQUNGLE1BQU0sU0FBUyxHQUFhLEVBQUUsQ0FBQTtRQUM5QixNQUFNLE9BQU8sR0FBYSxFQUFFLENBQUE7UUFDNUIsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFBO1FBQzdCLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUMvRCxLQUFLLElBQUksSUFBSSxHQUFHLENBQUMsRUFBRSxJQUFJLEdBQUcsWUFBWSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUM7WUFDN0MsU0FBUyxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUMzRCxDQUFDO1FBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsSUFBSSxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQTtRQUNwRCxPQUFPLENBQUMsR0FBRyxD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TyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDbkQsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDbkQsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDbkQsMkRBQTJEO0lBQzNELE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDakQsT0FBTyxDQUFDLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUE7QUFDekMsQ0FBQyJ9