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;
}