src/primitives.js
function createTorusVertices(
    radius,
    thickness,
    radialSubdivisions,
    bodySubdivisions,
    startAngle,
    endAngle) {
  if (radialSubdivisions < 3) {
    throw Error('radialSubdivisions must be 3 or greater');
  }

  if (bodySubdivisions < 3) {
    throw Error('verticalSubdivisions must be 3 or greater');
  }

  startAngle = startAngle || 0;
  endAngle = endAngle || Math.PI * 2;
  const range = endAngle - startAngle;

  const radialParts = radialSubdivisions + 1;
  const bodyParts   = bodySubdivisions + 1;
  const numVertices = radialParts * bodyParts;
  const positions   = createAugmentedTypedArray(3, numVertices);
  const normals     = createAugmentedTypedArray(3, numVertices);
  const texcoords   = createAugmentedTypedArray(2, numVertices);
  const indices     = createAugmentedTypedArray(3, (radialSubdivisions) * (bodySubdivisions) * 2, Uint16Array);

  for (let slice = 0; slice < bodyParts; ++slice) {
    const v = slice / bodySubdivisions;
    const sliceAngle = v * Math.PI * 2;
    const sliceSin = Math.sin(sliceAngle);
    const ringRadius = radius + sliceSin * thickness;
    const ny = Math.cos(sliceAngle);
    const y = ny * thickness;
    for (let ring = 0; ring < radialParts; ++ring) {
      const u = ring / radialSubdivisions;
      const ringAngle = startAngle + u * range;
      const xSin = Math.sin(ringAngle);
      const zCos = Math.cos(ringAngle);
      const x = xSin * ringRadius;
      const z = zCos * ringRadius;
      const nx = xSin * sliceSin;
      const nz = zCos * sliceSin;
      positions.push(x, y, z);
      normals.push(nx, ny, nz);
      texcoords.push(u, 1 - v);
    }
  }

  for (let slice = 0; slice < bodySubdivisions; ++slice) {  // eslint-disable-line
    for (let ring = 0; ring < radialSubdivisions; ++ring) {  // eslint-disable-line
      const nextRingIndex  = 1 + ring;
      const nextSliceIndex = 1 + slice;
      indices.push(radialParts * slice          + ring,
                   radialParts * nextSliceIndex + ring,
                   radialParts * slice          + nextRingIndex);
      indices.push(radialParts * nextSliceIndex + ring,
                   radialParts * nextSliceIndex + nextRingIndex,
                   radialParts * slice          + nextRingIndex);
    }
  }

  return {
    position: positions,
    normal:   normals,
    texcoord: texcoords,
    indices:  indices,
  };
}
function createTorusVertices(
    radius,
    thickness,
    radialSubdivisions,
    bodySubdivisions,
    startAngle,
    endAngle) {
  if (radialSubdivisions < 3) {
    throw Error('radialSubdivisions must be 3 or greater');
  }

  if (bodySubdivisions < 3) {
    throw Error('verticalSubdivisions must be 3 or greater');
  }

  startAngle = startAngle || 0;
  endAngle = endAngle || Math.PI * 2;
  const range = endAngle - startAngle;

  const radialParts = radialSubdivisions + 1;
  const bodyParts   = bodySubdivisions + 1;
  const numVertices = radialParts * bodyParts;
  const positions   = createAugmentedTypedArray(3, numVertices);
  const normals     = createAugmentedTypedArray(3, numVertices);
  const texcoords   = createAugmentedTypedArray(2, numVertices);
  const indices     = createAugmentedTypedArray(3, (radialSubdivisions) * (bodySubdivisions) * 2, Uint16Array);

  for (let slice = 0; slice < bodyParts; ++slice) {
    const v = slice / bodySubdivisions;
    const sliceAngle = v * Math.PI * 2;
    const sliceSin = Math.sin(sliceAngle);
    const ringRadius = radius + sliceSin * thickness;
    const ny = Math.cos(sliceAngle);
    const y = ny * thickness;
    for (let ring = 0; ring < radialParts; ++ring) {
      const u = ring / radialSubdivisions;
      const ringAngle = startAngle + u * range;
      const xSin = Math.sin(ringAngle);
      const zCos = Math.cos(ringAngle);
      const x = xSin * ringRadius;
      const z = zCos * ringRadius;
      const nx = xSin * sliceSin;
      const nz = zCos * sliceSin;
      positions.push(x, y, z);
      normals.push(nx, ny, nz);
      texcoords.push(u, 1 - v);
    }
  }

  for (let slice = 0; slice < bodySubdivisions; ++slice) {  // eslint-disable-line
    for (let ring = 0; ring < radialSubdivisions; ++ring) {  // eslint-disable-line
      const nextRingIndex  = 1 + ring;
      const nextSliceIndex = 1 + slice;
      indices.push(radialParts * slice          + ring,
                   radialParts * nextSliceIndex + ring,
                   radialParts * slice          + nextRingIndex);
      indices.push(radialParts * nextSliceIndex + ring,
                   radialParts * nextSliceIndex + nextRingIndex,
                   radialParts * slice          + nextRingIndex);
    }
  }

  return {
    position: positions,
    normal:   normals,
    texcoord: texcoords,
    indices:  indices,
  };
}
function createTorusVertices ( radius , thickness , radialSubdivisions , bodySubdivisions , startAngle , endAngle ) { if ( radialSubdivisions < 3 ) { throw Error ( 'radialSubdivisions must be 3 or greater' ) ; } if ( bodySubdivisions < 3 ) { throw Error ( 'verticalSubdivisions must be 3 or greater' ) ; } startAngle = startAngle || 0 ; endAngle = endAngle || Math . PI * 2 ; const range = endAngle - startAngle ; const radialParts = radialSubdivisions + 1 ; const bodyParts = bodySubdivisions + 1 ; const numVertices = radialParts * bodyParts ; const positions = createAugmentedTypedArray ( 3 , numVertices ) ; const normals = createAugmentedTypedArray ( 3 , numVertices ) ; const texcoords = createAugmentedTypedArray ( 2 , numVertices ) ; const indices = createAugmentedTypedArray ( 3 , ( radialSubdivisions ) * ( bodySubdivisions ) * 2 , Uint16Array ) ; for ( let slice = 0 ; slice < bodyParts ; ++ slice ) { const v = slice / bodySubdivisions ; const sliceAngle = v * Math . PI * 2 ; const sliceSin = Math . sin ( sliceAngle ) ; const ringRadius = radius + sliceSin * thickness ; const ny = Math . cos ( sliceAngle ) ; const y = ny * thickness ; for ( let ring = 0 ; ring < radialParts ; ++ ring ) { const u = ring / radialSubdivisions ; const ringAngle = startAngle + u * range ; const xSin = Math . sin ( ringAngle ) ; const zCos = Math . cos ( ringAngle ) ; const x = xSin * ringRadius ; const z = zCos * ringRadius ; const nx = xSin * sliceSin ; const nz = zCos * sliceSin ; positions . push ( x , y , z ) ; normals . push ( nx , ny , nz ) ; texcoords . push ( u , 1 - v ) ; } } for ( let slice = 0 ; slice < bodySubdivisions ; ++ slice ) { // eslint-disable-line for ( let ring = 0 ; ring < radialSubdivisions ; ++ ring ) { // eslint-disable-line const nextRingIndex = 1 + ring ; const nextSliceIndex = 1 + slice ; indices . push ( radialParts * slice + ring , radialParts * nextSliceIndex + ring , radialParts * slice + nextRingIndex ) ; indices . push ( radialParts * nextSliceIndex + ring , radialParts * nextSliceIndex + nextRingIndex , radialParts * slice + nextRingIndex ) ; } } return { position : positions , normal : normals , texcoord : texcoords , indices : indices , } ; }
Creates buffers for a torus

@param {WebGLRenderingContext} gl The WebGLRenderingContext.
@param {number} radius radius of center of torus circle.
@param {number} thickness radius of torus ring.
@param {number} radialSubdivisions The number of subdivisions around the torus.
@param {number} bodySubdivisions The number of subdivisions around the body torus.
@param {boolean} [startAngle] start angle in radians. Default = 0.
@param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2.
@return {Object.<string, WebGLBuffer>} The created buffers.
@memberOf module:twgl/primitives
@function createTorusBuffers
 
Creates vertices for a torus

@param {number} radius radius of center of torus circle.
@param {number} thickness radius of torus ring.
@param {number} radialSubdivisions The number of subdivisions around the torus.
@param {number} bodySubdivisions The number of subdivisions around the body torus.
@param {boolean} [startAngle] start angle in radians. Default = 0.
@param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2.
@return {Object.<string, TypedArray>} The created vertices.
@memberOf module:twgl/primitives
Creates buffers for a torus