@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
78 lines • 10.3 kB
JavaScript
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