@@ -1476,34 +1476,52 @@ static inline float quaternion_dot(const float* a, const float* b) {
14761476constexpr float ONE_PART_IN_A_MILLION = 0 .000001f ;
14771477constexpr float FP_MAG_THRESHOLD = 0 .0000001f ;
14781478
1479- static int lua_quaternion_normalize (lua_State *L)
1479+ // This logic largely copied from indra
1480+ static inline void normalize_quaternion (const float * in, float * out)
14801481{
1481- const float * quat = luaSL_checkquaternion (L, 1 );
1482- // This logic largely copied from indra
1483- float mag = sqrtf (quaternion_dot (quat, quat));
1482+ float mag = sqrtf (quaternion_dot (in, in));
14841483 if (mag > FP_MAG_THRESHOLD)
14851484 {
14861485 // Floating point error can prevent some quaternions from achieving
14871486 // exact unity length. When trying to renormalize such quaternions we
14881487 // can oscillate between multiple quantized states. To prevent such
14891488 // drifts we only renormalize if the length is far enough from unity.
1490- if (fabs (1 .f - mag) > ONE_PART_IN_A_MILLION)
1489+ if (fabsf (1 .f - mag) > ONE_PART_IN_A_MILLION)
14911490 {
14921491 float oomag = 1 .0f / mag;
1493- luaSL_pushquaternion (L, quat[0 ] * oomag, quat[1 ] * oomag, quat[2 ] * oomag, quat[3 ] * oomag);
1492+ out[0 ] = in[0 ] * oomag;
1493+ out[1 ] = in[1 ] * oomag;
1494+ out[2 ] = in[2 ] * oomag;
1495+ out[3 ] = in[3 ] * oomag;
14941496 }
14951497 else
14961498 {
1497- // We don't normalize in this case in indra, so push the original input
1498- lua_pushvalue (L, 1 );
1499+ out[0 ] = in[0 ];
1500+ out[1 ] = in[1 ];
1501+ out[2 ] = in[2 ];
1502+ out[3 ] = in[3 ];
14991503 }
15001504 }
15011505 else
15021506 {
15031507 // We were given a very bad quaternion so we set it to identity
1504- luaSL_pushquaternion (L, 0 , 0 , 0 , 1 );
1508+ out[0 ] = 0 .0f ;
1509+ out[1 ] = 0 .0f ;
1510+ out[2 ] = 0 .0f ;
1511+ out[3 ] = 1 .0f ;
15051512 }
1513+ }
15061514
1515+ static int lua_quaternion_normalize (lua_State *L)
1516+ {
1517+ const float * quat = luaSL_checkquaternion (L, 1 );
1518+ float res[4 ];
1519+ normalize_quaternion (quat, res);
1520+ // We don't normalize in this case in indra, so push the original input
1521+ if (res[0 ] == quat[0 ] && res[1 ] == quat[1 ] && res[2 ] == quat[2 ] && res[3 ] == quat[3 ])
1522+ lua_pushvalue (L, 1 );
1523+ else
1524+ luaSL_pushquaternion (L, res[0 ], res[1 ], res[2 ], res[3 ]);
15071525 return 1 ;
15081526}
15091527
@@ -1576,10 +1594,11 @@ static int lua_quaternion_conjugate(lua_State *L)
15761594
15771595static inline void push_rotated_vector (lua_State *L, const float * vec) {
15781596 const float * quat = luaSL_checkquaternion (L, 1 );
1597+ float nquat[4 ];
1598+ normalize_quaternion (quat, nquat);
15791599 float res[3 ] = {0 .0f };
1580- rot_vec (vec, quat, res);
1581- float invSqrt = 1 .0f / sqrtf (res[0 ] * res[0 ] + res[1 ] * res[1 ] + res[2 ] * res[2 ]);
1582- lua_pushvector (L, res[0 ] * invSqrt, res[1 ] * invSqrt, res[2 ] * invSqrt);
1600+ rot_vec (vec, nquat, res);
1601+ lua_pushvector (L, res[0 ], res[1 ], res[2 ]);
15831602}
15841603
15851604static int lua_quaternion_tofwd (lua_State *L)
0 commit comments