From e61100a8589c97b297ed2ff578556e9954d1e8ad Mon Sep 17 00:00:00 2001 From: Kp Date: Sat, 13 Apr 2019 18:00:07 +0000 Subject: [PATCH] Fix integer truncation in quaternion setup Commit 47a6f744d split out redundant code, but accidentally stored temporaries in a `signed short` instead of a `fix` as they should have been. This truncated some values, causing odd results whenever quaternions were used. Fix the problem by storing the intermediate results in a `fix`. Fixes: 47a6f744d81ac77c327aca6cf0a9f7a42bc845d1 ("Factor out vms_quaternion_from_matrix division") Reported-by: Ninjared --- common/maths/vecmat.cpp | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/common/maths/vecmat.cpp b/common/maths/vecmat.cpp index c78a7023c..b44c33ff3 100644 --- a/common/maths/vecmat.cpp +++ b/common/maths/vecmat.cpp @@ -624,36 +624,36 @@ void vms_quaternion_from_matrix(vms_quaternion &rq, const vms_matrix &m) const auto fy = m.fvec.y; const auto fz = m.fvec.z; const fix tr = rx + uy + fz; - vms_quaternion q; + fix qw, qx, qy, qz; if (tr > 0) { fix s = fixmul(fix_sqrt(tr + fl2f(1.0)), fl2f(2.0)); - q.w = fixmul(fl2f(0.25), s); - q.x = fixdiv(fy - uz, s); - q.y = fixdiv(rz - fx, s); - q.z = fixdiv(ux - ry, s); + qw = fixmul(fl2f(0.25), s); + qx = fixdiv(fy - uz, s); + qy = fixdiv(rz - fx, s); + qz = fixdiv(ux - ry, s); } else if ((rx > uy) & (rx > fz)) { fix s = fixmul(fix_sqrt(fl2f(1.0) + rx - uy - fz), fl2f(2.0)); - q.w = fixdiv(fy - uz, s); - q.x = fixmul(fl2f(0.25), s); - q.y = fixdiv(ry + ux, s); - q.z = fixdiv(rz + fx, s); + qw = fixdiv(fy - uz, s); + qx = fixmul(fl2f(0.25), s); + qy = fixdiv(ry + ux, s); + qz = fixdiv(rz + fx, s); } else if (uy > fz) { fix s = fixmul(fix_sqrt(fl2f(1.0) + uy - rx - fz), fl2f(2.0)); - q.w = fixdiv(rz - fx, s); - q.x = fixdiv(ry + ux, s); - q.y = fixmul(fl2f(0.25), s); - q.z = fixdiv(uz + fy, s); + qw = fixdiv(rz - fx, s); + qx = fixdiv(ry + ux, s); + qy = fixmul(fl2f(0.25), s); + qz = fixdiv(uz + fy, s); } else { fix s = fixmul(fix_sqrt(fl2f(1.0) + fz - rx - uy), fl2f(2.0)); - q.w = fixdiv(ux - ry, s); - q.x = fixdiv(rz + fx, s); - q.y = fixdiv(uz + fy, s); - q.z = fixmul(fl2f(0.25), s); + qw = fixdiv(ux - ry, s); + qx = fixdiv(rz + fx, s); + qy = fixdiv(uz + fy, s); + qz = fixmul(fl2f(0.25), s); } - rq.w = q.w / 2; - rq.x = q.x / 2; - rq.y = q.y / 2; - rq.z = q.z / 2; + rq.w = qw / 2; + rq.x = qx / 2; + rq.y = qy / 2; + rq.z = qz / 2; } // convert vms_quaternion to vms_matrix