UNPKG

ogl

Version:
71 lines (56 loc) 2.61 kB
// https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusGeometry.js import { Geometry } from '../core/Geometry.js'; import { Vec3 } from '../math/Vec3.js'; export class Torus extends Geometry { constructor(gl, { radius = 0.5, tube = 0.2, radialSegments = 8, tubularSegments = 6, arc = Math.PI * 2, attributes = {} } = {}) { const num = (radialSegments + 1) * (tubularSegments + 1); const numIndices = radialSegments * tubularSegments * 6; const vertices = new Float32Array(num * 3); const normals = new Float32Array(num * 3); const uvs = new Float32Array(num * 2); const indices = num > 65536 ? new Uint32Array(numIndices) : new Uint16Array(numIndices); const center = new Vec3(); const vertex = new Vec3(); const normal = new Vec3(); // generate vertices, normals and uvs let idx = 0; for (let j = 0; j <= radialSegments; j++) { for (let i = 0; i <= tubularSegments; i++, idx++) { const u = (i / tubularSegments) * arc; const v = (j / radialSegments) * Math.PI * 2; // vertex vertex.x = (radius + tube * Math.cos(v)) * Math.cos(u); vertex.y = (radius + tube * Math.cos(v)) * Math.sin(u); vertex.z = tube * Math.sin(v); vertices.set([vertex.x, vertex.y, vertex.z], idx * 3); // normal center.x = radius * Math.cos(u); center.y = radius * Math.sin(u); normal.sub(vertex, center).normalize(); normals.set([normal.x, normal.y, normal.z], idx * 3); // uv uvs.set([i / tubularSegments, j / radialSegments], idx * 2); } } // generate indices idx = 0; for (let j = 1; j <= radialSegments; j++) { for (let i = 1; i <= tubularSegments; i++, idx++) { // indices const a = (tubularSegments + 1) * j + i - 1; const b = (tubularSegments + 1) * (j - 1) + i - 1; const c = (tubularSegments + 1) * (j - 1) + i; const d = (tubularSegments + 1) * j + i; // faces indices.set([a, b, d, b, c, d], idx * 6); } } Object.assign(attributes, { position: { size: 3, data: vertices }, normal: { size: 3, data: normals }, uv: { size: 2, data: uvs }, index: { data: indices }, }); super(gl, attributes); } }