kotlin-graphics/glm

Wrong Calculation for Vec3 times Quat

wumo opened this issue · 1 comments

wumo commented

glm calculates vec3 * quat as :
https://github.com/g-truc/glm/blob/23e0701c0483283440d4d1bcd17eb7070fa8eb75/glm/detail/type_quat.inl#L352-L356

	template<typename T, qualifier Q>
	GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, qua<T, Q> const& q)
	{
		return glm::inverse(q) * v;
	}

        template<typename T, qualifier Q>
	GLM_FUNC_QUALIFIER qua<T, Q> inverse(qua<T, Q> const& q)
	{
		return conjugate(q) / dot(q, q);
	}

That is glm::inverse(q) * v; which can be expanded as conjugate(q) / dot(q, q) * v;
However Vec3 * Quat is implemented in:

fun times(res: Vec3, a: Vec3, b: Quat): Vec3 {
val dot = dot(a, a)
val iW = b.w / dot
val iX = -b.x / dot
val iY = -b.y / dot
val iZ = -b.z / dot
val uvX = iY * a.z - a.y * iZ
val uvY = iZ * a.x - a.z * iX
val uvZ = iX * a.y - a.x * iY
val uuvX = iY * uvZ - uvY * iZ
val uuvY = iZ * uvX - uvZ * iX
val uuvZ = iX * uvY - uvX * iY
res.x = a.x + (uvX * iW + uuvX) * 2f
res.y = a.y + (uvY * iW + uuvY) * 2f
res.z = a.z + (uvZ * iW + uuvZ) * 2f
return res
}

Where line 62 val dot = dot(a, a) should be val dot = dot(b, b) which calculates the dot product of a quaternion and then is used to calculate the inverse of the quaternion.

nice catch, thanks