src/primitives.js
function concatVertices(arrayOfArrays) {
  const names = {};
  let baseName;
  // get names of all arrays.
  // and numElements for each set of vertices
  for (let ii = 0; ii < arrayOfArrays.length; ++ii) {
    const arrays = arrayOfArrays[ii];
    Object.keys(arrays).forEach(function(name) {  // eslint-disable-line
      if (!names[name]) {
        names[name] = [];
      }
      if (!baseName && name !== 'indices') {
        baseName = name;
      }
      const arrayInfo = arrays[name];
      const numComponents = getNumComponents(arrayInfo, name);
      const array = getArray(arrayInfo);
      const numElements = array.length / numComponents;
      names[name].push(numElements);
    });
  }

  // compute length of combined array
  // and return one for reference
  function getLengthOfCombinedArrays(name) {
    let length = 0;
    let arraySpec;
    for (let ii = 0; ii < arrayOfArrays.length; ++ii) {
      const arrays = arrayOfArrays[ii];
      const arrayInfo = arrays[name];
      const array = getArray(arrayInfo);
      length += array.length;
      if (!arraySpec || arrayInfo.data) {
        arraySpec = arrayInfo;
      }
    }
    return {
      length: length,
      spec: arraySpec,
    };
  }

  function copyArraysToNewArray(name, base, newArray) {
    let baseIndex = 0;
    let offset = 0;
    for (let ii = 0; ii < arrayOfArrays.length; ++ii) {
      const arrays = arrayOfArrays[ii];
      const arrayInfo = arrays[name];
      const array = getArray(arrayInfo);
      if (name === 'indices') {
        copyElements(array, newArray, offset, baseIndex);
        baseIndex += base[ii];
      } else {
        copyElements(array, newArray, offset);
      }
      offset += array.length;
    }
  }

  const base = names[baseName];

  const newArrays = {};
  Object.keys(names).forEach(function(name) {
    const info = getLengthOfCombinedArrays(name);
    const newArraySpec = createArrayOfSameType(info.spec, info.length);
    copyArraysToNewArray(name, base, getArray(newArraySpec));
    newArrays[name] = newArraySpec;
  });
  return newArrays;
}
function concatVertices(arrayOfArrays) {
  const names = {};
  let baseName;
  // get names of all arrays.
  // and numElements for each set of vertices
  for (let ii = 0; ii < arrayOfArrays.length; ++ii) {
    const arrays = arrayOfArrays[ii];
    Object.keys(arrays).forEach(function(name) {  // eslint-disable-line
      if (!names[name]) {
        names[name] = [];
      }
      if (!baseName && name !== 'indices') {
        baseName = name;
      }
      const arrayInfo = arrays[name];
      const numComponents = getNumComponents(arrayInfo, name);
      const array = getArray(arrayInfo);
      const numElements = array.length / numComponents;
      names[name].push(numElements);
    });
  }

  // compute length of combined array
  // and return one for reference
  function getLengthOfCombinedArrays(name) {
    let length = 0;
    let arraySpec;
    for (let ii = 0; ii < arrayOfArrays.length; ++ii) {
      const arrays = arrayOfArrays[ii];
      const arrayInfo = arrays[name];
      const array = getArray(arrayInfo);
      length += array.length;
      if (!arraySpec || arrayInfo.data) {
        arraySpec = arrayInfo;
      }
    }
    return {
      length: length,
      spec: arraySpec,
    };
  }

  function copyArraysToNewArray(name, base, newArray) {
    let baseIndex = 0;
    let offset = 0;
    for (let ii = 0; ii < arrayOfArrays.length; ++ii) {
      const arrays = arrayOfArrays[ii];
      const arrayInfo = arrays[name];
      const array = getArray(arrayInfo);
      if (name === 'indices') {
        copyElements(array, newArray, offset, baseIndex);
        baseIndex += base[ii];
      } else {
        copyElements(array, newArray, offset);
      }
      offset += array.length;
    }
  }

  const base = names[baseName];

  const newArrays = {};
  Object.keys(names).forEach(function(name) {
    const info = getLengthOfCombinedArrays(name);
    const newArraySpec = createArrayOfSameType(info.spec, info.length);
    copyArraysToNewArray(name, base, getArray(newArraySpec));
    newArrays[name] = newArraySpec;
  });
  return newArrays;
}
function concatVertices ( arrayOfArrays ) { const names = { } ; let baseName ; // get names of all arrays. // and numElements for each set of vertices for ( let ii = 0 ; ii < arrayOfArrays . length ; ++ ii ) { const arrays = arrayOfArrays [ ii ] ; Object . keys ( arrays ) . forEach ( function ( name ) { // eslint-disable-line if ( ! names [ name ] ) { names [ name ] = [ ] ; } if ( ! baseName && name !== 'indices' ) { baseName = name ; } const arrayInfo = arrays [ name ] ; const numComponents = getNumComponents ( arrayInfo , name ) ; const array = getArray ( arrayInfo ) ; const numElements = array . length / numComponents ; names [ name ] . push ( numElements ) ; } ) ; } // compute length of combined array // and return one for reference function getLengthOfCombinedArrays ( name ) { let length = 0 ; let arraySpec ; for ( let ii = 0 ; ii < arrayOfArrays . length ; ++ ii ) { const arrays = arrayOfArrays [ ii ] ; const arrayInfo = arrays [ name ] ; const array = getArray ( arrayInfo ) ; length += array . length ; if ( ! arraySpec || arrayInfo . data ) { arraySpec = arrayInfo ; } } return { length : length , spec : arraySpec , } ; } function copyArraysToNewArray ( name , base , newArray ) { let baseIndex = 0 ; let offset = 0 ; for ( let ii = 0 ; ii < arrayOfArrays . length ; ++ ii ) { const arrays = arrayOfArrays [ ii ] ; const arrayInfo = arrays [ name ] ; const array = getArray ( arrayInfo ) ; if ( name === 'indices' ) { copyElements ( array , newArray , offset , baseIndex ) ; baseIndex += base [ ii ] ; } else { copyElements ( array , newArray , offset ) ; } offset += array . length ; } } const base = names [ baseName ] ; const newArrays = { } ; Object . keys ( names ) . forEach ( function ( name ) { const info = getLengthOfCombinedArrays ( name ) ; const newArraySpec = createArrayOfSameType ( info . spec , info . length ) ; copyArraysToNewArray ( name , base , getArray ( newArraySpec ) ) ; newArrays [ name ] = newArraySpec ; } ) ; return newArrays ; }
Concatinates sets of vertices

Assumes the vertices match in composition. For example
if one set of vertices has positions, normals, and indices
all sets of vertices must have positions, normals, and indices
and of the same type.

Example:

const cubeVertices = twgl.primtiives.createCubeVertices(2);
const sphereVertices = twgl.primitives.createSphereVertices(1, 10, 10);
// move the sphere 2 units up
twgl.primitives.reorientVertices(
sphereVertices, twgl.m4.translation([0, 2, 0]));
// merge the sphere with the cube
const cubeSphereVertices = twgl.primitives.concatVertices(
[cubeVertices, sphereVertices]);
// turn them into WebGL buffers and attrib data
const bufferInfo = twgl.createBufferInfoFromArrays(gl, cubeSphereVertices);

@param {module:twgl.Arrays[]} arrays Array of arrays of vertices
@return {module:twgl.Arrays} The concatinated vertices.
@memberOf module:twgl/primitives
Concatinates sets of vertices