/*
export function computeTangents({indices, positions, normals, uvs}) {
  var index = geometry.index;
  var attributes = geometry.attributes;

  // based on http://www.terathon.com/code/tangent.html
  // (per vertex tangents)

  if (
    index === null ||
    attributes.position === undefined ||
    attributes.normal === undefined ||
    attributes.uv === undefined
  ) {
    console.warn(
      'THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()'
    );
    return;
  }

  var nVertices = positions.length / 3;

  var tangents = new Float32Array(4 * nVertices); // size: 4

  var tan1 = [],
    tan2 = [];

  for (var k = 0; k < nVertices; k++) {
    tan1[k] = new THREE.Vector3();
    tan2[k] = new THREE.Vector3();
  }

  var vA = new THREE.Vector3(),
    vB = new THREE.Vector3(),
    vC = new THREE.Vector3(),
    uvA = new THREE.Vector2(),
    uvB = new THREE.Vector2(),
    uvC = new THREE.Vector2(),
    sdir = new THREE.Vector3(),
    tdir = new THREE.Vector3();

  function handleTriangle(a, b, c) {
    vA.fromArray(positions, a * 3);
    vB.fromArray(positions, b * 3);
    vC.fromArray(positions, c * 3);

    uvA.fromArray(uvs, a * 2);
    uvB.fromArray(uvs, b * 2);
    uvC.fromArray(uvs, c * 2);

    var x1 = vB.x - vA.x;
    var x2 = vC.x - vA.x;

    var y1 = vB.y - vA.y;
    var y2 = vC.y - vA.y;

    var z1 = vB.z - vA.z;
    var z2 = vC.z - vA.z;

    var s1 = uvB.x - uvA.x;
    var s2 = uvC.x - uvA.x;

    var t1 = uvB.y - uvA.y;
    var t2 = uvC.y - uvA.y;

    var r = 1.0 / (s1 * t2 - s2 * t1);

    sdir.set((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);

    tdir.set((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);

    tan1[a].add(sdir);
    tan1[b].add(sdir);
    tan1[c].add(sdir);

    tan2[a].add(tdir);
    tan2[b].add(tdir);
    tan2[c].add(tdir);
  }

  var groups = geometry.groups;

  if (groups.length === 0) {
    groups = [
      {
        start: 0,
        count: indices.length
      }
    ];
  }

  for (var j = 0, jl = groups.length; j < jl; ++j) {
    var group = groups[j];

    var start = group.start;
    var count = group.count;

    for (var i = start, il = start + count; i < il; i += 3) {
      handleTriangle(indices[i + 0], indices[i + 1], indices[i + 2]);
    }
  }

  var tmp = new THREE.Vector3(),
    tmp2 = new THREE.Vector3();
  var n = new THREE.Vector3(),
    n2 = new THREE.Vector3();
  var w, t, test;

  function handleVertex(v) {
    n.fromArray(normals, v * 3);
    n2.copy(n);

    t = tan1[v];

    // Gram-Schmidt orthogonalize

    tmp.copy(t);
    tmp.sub(n.multiplyScalar(n.dot(t))).normalize();

    // Calculate handedness

    tmp2.crossVectors(n2, t);
    test = tmp2.dot(tan2[v]);
    w = test < 0.0 ? -1.0 : 1.0;

    tangents[v * 4] = tmp.x;
    tangents[v * 4 + 1] = tmp.y;
    tangents[v * 4 + 2] = tmp.z;
    tangents[v * 4 + 3] = w;
  }

  for (var j = 0, jl = groups.length; j < jl; ++j) {
    var group = groups[j];

    var start = group.start;
    var count = group.count;

    for (var i = start, il = start + count; i < il; i += 3) {
      handleVertex(indices[i + 0]);
      handleVertex(indices[i + 1]);
      handleVertex(indices[i + 2]);
    }
  }
}
*/
