Vec3f RawModel::getFaceNormal()

in src/raw/RawModel.cpp [661:681]


Vec3f RawModel::getFaceNormal(int verts[3]) const {
  const float l0 = (vertices[verts[1]].position - vertices[verts[0]].position).LengthSquared();
  const float l1 = (vertices[verts[2]].position - vertices[verts[1]].position).LengthSquared();
  const float l2 = (vertices[verts[0]].position - vertices[verts[2]].position).LengthSquared();
  const int index = (l0 > l1) ? (l0 > l2 ? 2 : 1) : (l1 > l2 ? 0 : 1);

  const Vec3f e0 = vertices[verts[(index + 1) % 3]].position - vertices[verts[index]].position;
  const Vec3f e1 = vertices[verts[(index + 2) % 3]].position - vertices[verts[index]].position;
  if (e0.LengthSquared() < FLT_MIN || e1.LengthSquared() < FLT_MIN) {
    return Vec3f{0.0f};
  }
  auto result = Vec3f::CrossProduct(e0, e1);
  auto resultLengthSquared = result.LengthSquared();
  if (resultLengthSquared < FLT_MIN) {
    return Vec3f{0.0f};
  }
  float edgeDot = std::max(-1.0f, std::min(1.0f, Vec3f::DotProduct(e0, e1)));
  float angle = acos(edgeDot);
  float area = resultLengthSquared / 2.0f;
  return result.Normalized() * angle * area;
}