MD5mesh smooth normal calculation

Hi everyone!

I’m trying to calculate smooth normals for a .md5mesh. I’m getting incorrect lighting, it seems some normals get flipped and show up on the wrong side.

Here is a screenshot showing both sides of the model.
The brighter side is where the light hits the model, but some parts get lighted on the wrong side.

My normal calculation:

  let a = new Float32Array(3);
  let b = new Float32Array(3);
  let n = new Float32Array(3);
  for (let ii = 0; ii < mesh.tris.length; ii += 3) {
    let i1 = mesh.tris[ii + 0];
    let i2 = mesh.tris[ii + 1];
    let i3 = mesh.tris[ii + 2];
    let v1 = mesh.verts[i1];
    let v2 = mesh.verts[i2];
    let v3 = mesh.verts[i3];

    // normal
    vec3.subtract(a, v2.pos, v1.pos);
    vec3.subtract(b, v3.pos, v1.pos);
    vec3.cross(n, b, a);

    // angles
    let a1 = vec3.angle(
      vec3.subtract(a, v2.pos, v1.pos),
      vec3.subtract(b, v3.pos, v1.pos)
    let a2 = vec3.angle(
      vec3.subtract(a, v3.pos, v2.pos),
      vec3.subtract(b, v1.pos, v2.pos)
    let a3 = vec3.angle(
      vec3.subtract(a, v1.pos, v3.pos),
      vec3.subtract(b, v2.pos, v3.pos)

    vec3.add(v1.normal, v1.normal, vec3.scale(vec3.create(), n, a1));
    vec3.add(v2.normal, v2.normal, vec3.scale(vec3.create(), n, a2));
    vec3.add(v3.normal, v3.normal, vec3.scale(vec3.create(), n, a3));


What is going wrong here?

Edit: If that helps, all models have multiple meshes. I first concat all meshes together, then calculate the smooth normals for it and then use these for each mesh.

This strange bug occured in the mesh parse function when parsing the joint orientations.

In the past quat.calculateW returned a fixed negated w component, today it’s not negated. Simple negating it again fixed my bug!