recp / cglm

📽 Highly Optimized 2D / 3D Graphics Math (glm) for C
MIT License
2.34k stars 231 forks source link

glm_quat_lerp is incorrect #318

Closed xubury closed 1 year ago

xubury commented 1 year ago

Currently, glm_quat_lerp is calling glm_vec4_lerp. But according to https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#interpolation-slerp, it should be something like this?

  versor a, b;
  glm_quat_copy(prev, a);
  glm_quat_copy(next, b);
  f32 dot = glm_quat_dot(a, b);
  if (dot < 0.0f) {
      glm_vec4_scale(b, -1, b);
      dot = -dot;
  }
  if (dot > 0.9995f) {
      glm_quat_lerp(a, b, factor, out);
      glm_quat_normalize(out);
  }
  else {
      f32 theta0     = acos(dot);
      f32 theta      = factor * theta0;
      f32 sin_theta  = sin(theta);
      f32 sin_theat0 = sin(theta0);
      f32 scale_a    = cos(theta) - dot * sin_theta / sin_theat0;
      f32 scale_b    = sin_theta / sin_theat0;
      glm_vec4_scale(a, scale_a, a);
      glm_vec4_scale(b, scale_b, b);
      glm_quat_add(a, b, out);
  }
recp commented 1 year ago

Hi @xubury,

You are comparing cglm's LERP with glTF's SLERP, cglm also has glm_quat_slerp() which is SLERP.

Thanks