diff --git a/src/engine/math_util.c b/src/engine/math_util.c index d4fbb2159..65a62c044 100644 --- a/src/engine/math_util.c +++ b/src/engine/math_util.c @@ -293,77 +293,67 @@ void mtxf_translate(Mat4 dest, Vec3f b) { * angle allows a bank rotation of the camera. */ void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) { - register f32 invLength; - f32 dx; - f32 dz; - f32 xColY; - f32 yColY; - f32 zColY; - f32 xColZ; - f32 yColZ; - f32 zColZ; - f32 xColX; - f32 yColX; - f32 zColX; + Vec3f forward, right, up; + f32 sinRoll, cosRoll; + f32 dx, dz, xzDist; + f32 invLength; + + forward[0] = from[0] - to[0]; + forward[1] = from[1] - to[1]; + forward[2] = from[2] - to[2]; + invLength = 1.0f / sqrtf(forward[0] * forward[0] + forward[1] * forward[1] + forward[2] * forward[2]); + forward[0] *= invLength; + forward[1] *= invLength; + forward[2] *= invLength; dx = to[0] - from[0]; dz = to[2] - from[2]; + xzDist = dx * dx + dz * dz; + if (xzDist != 0.0f) { + invLength = -1.0f / sqrtf(xzDist); + dx *= invLength; + dz *= invLength; + } else { + dx = dz = 0.0f; + } + + sinRoll = sins(roll); + cosRoll = coss(roll); - invLength = -1.0 / sqrtf(dx * dx + dz * dz); - dx *= invLength; - dz *= invLength; + up[0] = sinRoll * dz; + up[1] = cosRoll; + up[2] = -sinRoll * dx; - yColY = coss(roll); - xColY = sins(roll) * dz; - zColY = -sins(roll) * dx; + right[0] = up[1] * forward[2] - up[2] * forward[1]; + right[1] = up[2] * forward[0] - up[0] * forward[2]; + right[2] = up[0] * forward[1] - up[1] * forward[0]; - xColZ = to[0] - from[0]; - yColZ = to[1] - from[1]; - zColZ = to[2] - from[2]; + invLength = 1.0f / sqrtf(right[0] * right[0] + right[1] * right[1] + right[2] * right[2]); + right[0] *= invLength; + right[1] *= invLength; + right[2] *= invLength; - invLength = -1.0 / sqrtf(xColZ * xColZ + yColZ * yColZ + zColZ * zColZ); - xColZ *= invLength; - yColZ *= invLength; - zColZ *= invLength; + up[0] = forward[1] * right[2] - forward[2] * right[1]; + up[1] = forward[2] * right[0] - forward[0] * right[2]; + up[2] = forward[0] * right[1] - forward[1] * right[0]; + + mtx[0][0] = right[0]; + mtx[1][0] = right[1]; + mtx[2][0] = right[2]; + mtx[3][0] = -(from[0] * right[0] + from[1] * right[1] + from[2] * right[2]); - xColX = yColY * zColZ - zColY * yColZ; - yColX = zColY * xColZ - xColY * zColZ; - zColX = xColY * yColZ - yColY * xColZ; + mtx[0][1] = up[0]; + mtx[1][1] = up[1]; + mtx[2][1] = up[2]; + mtx[3][1] = -(from[0] * up[0] + from[1] * up[1] + from[2] * up[2]); - invLength = 1.0 / sqrtf(xColX * xColX + yColX * yColX + zColX * zColX); + mtx[0][2] = forward[0]; + mtx[1][2] = forward[1]; + mtx[2][2] = forward[2]; + mtx[3][2] = -(from[0] * forward[0] + from[1] * forward[1] + from[2] * forward[2]); - xColX *= invLength; - yColX *= invLength; - zColX *= invLength; - - xColY = yColZ * zColX - zColZ * yColX; - yColY = zColZ * xColX - xColZ * zColX; - zColY = xColZ * yColX - yColZ * xColX; - - invLength = 1.0 / sqrtf(xColY * xColY + yColY * yColY + zColY * zColY); - xColY *= invLength; - yColY *= invLength; - zColY *= invLength; - - mtx[0][0] = xColX; - mtx[1][0] = yColX; - mtx[2][0] = zColX; - mtx[3][0] = -(from[0] * xColX + from[1] * yColX + from[2] * zColX); - - mtx[0][1] = xColY; - mtx[1][1] = yColY; - mtx[2][1] = zColY; - mtx[3][1] = -(from[0] * xColY + from[1] * yColY + from[2] * zColY); - - mtx[0][2] = xColZ; - mtx[1][2] = yColZ; - mtx[2][2] = zColZ; - mtx[3][2] = -(from[0] * xColZ + from[1] * yColZ + from[2] * zColZ); - - mtx[0][3] = 0; - mtx[1][3] = 0; - mtx[2][3] = 0; - mtx[3][3] = 1; + mtx[0][3] = mtx[1][3] = mtx[2][3] = 0.0f; + mtx[3][3] = 1.0f; } /**