UNPKG

primitive-geometry

Version:

Geometries for 3D rendering, including normals, UVs and cell indices (faces). Perfect if you want to supercharge your dependency folder... with 30KB of geometries.

112 lines (89 loc) 2.62 kB
/** @module torus */ import { checkArguments, getCellsTypedArray, normalize, TAU, TMP, } from "./utils.js"; /** * @typedef {object} TorusOptions * @property {number} [radius=0.4] * @property {number} [segments=64] * @property {number} [minorRadius=0.1] * @property {number} [minorSegments=32] * @property {number} [theta=TAU] * @property {number} [thetaOffset=0] * @property {number} [phi=TAU] * @property {number} [phiOffset=0] */ /** * @alias module:torus * @param {TorusOptions} [options={}] * @returns {import("../types.js").SimplicialComplex} */ function torus({ radius = 0.4, segments = 64, minorRadius = 0.1, minorSegments = 32, theta = TAU, thetaOffset = 0, phi = TAU, phiOffset = 0, } = {}) { checkArguments(arguments); const size = (minorSegments + 1) * (segments + 1); const positions = new Float32Array(size * 3); const normals = new Float32Array(size * 3); const uvs = new Float32Array(size * 2); const cells = new (getCellsTypedArray(size))(minorSegments * segments * 6); let vertexIndex = 0; let cellIndex = 0; for (let j = 0; j <= minorSegments; j++) { const v = j / minorSegments; for (let i = 0; i <= segments; i++, vertexIndex++) { const u = i / segments; const p = u * phi + phiOffset; const cosPhi = -Math.cos(p); const sinPhi = Math.sin(p); const t = v * theta + thetaOffset; const cosTheta = -Math.cos(t); const sinTheta = Math.sin(t); TMP[0] = (radius + minorRadius * cosTheta) * cosPhi; TMP[1] = (radius + minorRadius * cosTheta) * sinPhi; TMP[2] = minorRadius * sinTheta; positions[vertexIndex * 3] = TMP[0]; positions[vertexIndex * 3 + 1] = TMP[1]; positions[vertexIndex * 3 + 2] = TMP[2]; TMP[0] -= radius * cosPhi; TMP[1] -= radius * sinPhi; normalize(TMP); normals[vertexIndex * 3] = TMP[0]; normals[vertexIndex * 3 + 1] = TMP[1]; normals[vertexIndex * 3 + 2] = TMP[2]; uvs[vertexIndex * 2] = u; uvs[vertexIndex * 2 + 1] = v; if (j > 0 && i > 0) { const a = (segments + 1) * j + i - 1; const b = (segments + 1) * (j - 1) + i - 1; const c = (segments + 1) * (j - 1) + i; const d = (segments + 1) * j + i; cells[cellIndex] = a; cells[cellIndex + 1] = b; cells[cellIndex + 2] = d; cells[cellIndex + 3] = b; cells[cellIndex + 4] = c; cells[cellIndex + 5] = d; cellIndex += 6; } } } return { positions, normals, uvs, cells, }; } export default torus;