computeVertexNormals method

void computeVertexNormals()

Implementation

void computeVertexNormals() {
  var index = this.index;
  var positionAttribute = getAttribute('position');

  if (positionAttribute != null) {
    var normalAttribute = getAttribute('normal');

    if (normalAttribute == null) {
      final array = List<double>.filled(positionAttribute.count * 3, 0);
      normalAttribute = Float32BufferAttribute(Float32Array.from(array), 3, false);
      setAttribute('normal', normalAttribute);
    } else {
      // reset existing normals to zero

      for (var i = 0, il = normalAttribute.count; i < il; i++) {
        normalAttribute.setXYZ(i, 0, 0, 0);
      }
    }

    var pA = Vector3.init(), pB = Vector3.init(), pC = Vector3.init();
    var nA = Vector3.init(), nB = Vector3.init(), nC = Vector3.init();
    var cb = Vector3.init(), ab = Vector3.init();

    // indexed elements

    if (index != null) {
      for (var i = 0, il = index.count; i < il; i += 3) {
        var vA = index.getX(i + 0)!.toInt();
        var vB = index.getX(i + 1)!.toInt();
        var vC = index.getX(i + 2)!.toInt();

        pA.fromBufferAttribute(positionAttribute, vA);
        pB.fromBufferAttribute(positionAttribute, vB);
        pC.fromBufferAttribute(positionAttribute, vC);

        cb.subVectors(pC, pB);
        ab.subVectors(pA, pB);
        cb.cross(ab);

        nA.fromBufferAttribute(normalAttribute, vA);
        nB.fromBufferAttribute(normalAttribute, vB);
        nC.fromBufferAttribute(normalAttribute, vC);

        nA.add(cb);
        nB.add(cb);
        nC.add(cb);

        normalAttribute.setXYZ(vA, nA.x, nA.y, nA.z);
        normalAttribute.setXYZ(vB, nB.x, nB.y, nB.z);
        normalAttribute.setXYZ(vC, nC.x, nC.y, nC.z);
      }
    } else {
      // non-indexed elements (unconnected triangle soup)

      for (var i = 0, il = positionAttribute.count; i < il; i += 3) {
        pA.fromBufferAttribute(positionAttribute, i + 0);
        pB.fromBufferAttribute(positionAttribute, i + 1);
        pC.fromBufferAttribute(positionAttribute, i + 2);

        cb.subVectors(pC, pB);
        ab.subVectors(pA, pB);
        cb.cross(ab);

        normalAttribute.setXYZ(i + 0, cb.x, cb.y, cb.z);
        normalAttribute.setXYZ(i + 1, cb.x, cb.y, cb.z);
        normalAttribute.setXYZ(i + 2, cb.x, cb.y, cb.z);
      }
    }

    normalizeNormals();

    normalAttribute.needsUpdate = true;
  }
}