From 05f3f66be77f2e16862e3043d7c4ef56b91af16a Mon Sep 17 00:00:00 2001 From: Garux Date: Sat, 3 May 2025 16:30:26 +0500 Subject: [PATCH] snap angle, angles keys on transform to zero to avoid scientific notation in saved string --- libs/math/vector.h | 18 ++++++++++++++++++ plugins/entity/angle.h | 13 +++++++++---- plugins/entity/angles.h | 18 ++++++------------ plugins/entity/miscmodel.cpp | 2 +- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/libs/math/vector.h b/libs/math/vector.h index bb71cb3f..d10293fa 100644 --- a/libs/math/vector.h +++ b/libs/math/vector.h @@ -60,6 +60,12 @@ inline Element float_snapped( const Element& f, const OtherElement& snap ){ return Element( std::llrint( f / snap ) * snap ); // llrint has more significant bits } +/// \brief Returns \p f rounded to zero if less than \p snap. +template +inline Element float_snapped_to_zero( const Element& f, const OtherElement& snap ){ + return std::fabs( f ) < snap? 0 : f; +} + /// \brief Returns true if \p f has no decimal fraction part. template inline bool float_is_integer( const Element& f ){ @@ -524,6 +530,18 @@ template inline void vector3_snap( BasicVector3& self, const OtherElement& snap ){ self = vector3_snapped( self, snap ); } +template +inline BasicVector3 vector3_snapped_to_zero( const BasicVector3& self, const OtherElement& snap ){ + return BasicVector3( + Element( float_snapped_to_zero( self.x(), snap ) ), + Element( float_snapped_to_zero( self.y(), snap ) ), + Element( float_snapped_to_zero( self.z(), snap ) ) + ); +} +template +inline void vector3_snap_to_zero( BasicVector3& self, const OtherElement& snap ){ + self = vector3_snapped_to_zero( self, snap ); +} inline Vector3 vector3_for_spherical( double theta, double phi ){ return Vector3( diff --git a/plugins/entity/angle.h b/plugins/entity/angle.h index c90a8b00..6bc0e6d6 100644 --- a/plugins/entity/angle.h +++ b/plugins/entity/angle.h @@ -78,9 +78,13 @@ public: } }; -inline float float_snapped_to_zero( float value ){ - return fabs( value ) < 1e-6 ? 0.f : value; -} +/* +zero snap angle value to avoid scientific notation after sprinf %g +it's not supported in e.g. Q3: +https://github.com/id-Software/Quake-III-Arena/blob/master/code/game/bg_lib.c#L910 +0.0001f is least value, which produces no scientific notation, must be good nuff precision too 🤞🏿 +*/ +const float ANGLEKEY_SMALLEST = 0.0001f; inline float angle_rotated( float angle, const Quaternion& rotation ){ return float_snapped_to_zero( @@ -89,6 +93,7 @@ inline float angle_rotated( float angle, const Quaternion& rotation ){ matrix4_rotation_for_quaternion_quantised( rotation ), matrix4_rotation_for_z_degrees( angle ) ) - ).z() + ).z(), + ANGLEKEY_SMALLEST ); } diff --git a/plugins/entity/angles.h b/plugins/entity/angles.h index 91238db0..e051bb43 100644 --- a/plugins/entity/angles.h +++ b/plugins/entity/angles.h @@ -105,33 +105,27 @@ inline Matrix4 matrix4_rotation_for_euler_xyz_degrees_quantised( const Vector3& return matrix4_rotation_for_euler_xyz_degrees( angles ); } -inline Vector3 angles_snapped_to_zero( const Vector3& angles ){ - const float epsilon = ( fabs( angles[0] ) > 0.001f || fabs( angles[1] ) > 0.001f || fabs( angles[2] ) > 0.001f ) ? 5e-5 : 1e-6; - return Vector3( fabs( angles[0] ) < epsilon ? 0.f : angles[0], - fabs( angles[1] ) < epsilon ? 0.f : angles[1], - fabs( angles[2] ) < epsilon ? 0.f : angles[2] - ); -} - inline Vector3 angles_rotated( const Vector3& angles, const Quaternion& rotation ){ - return angles_snapped_to_zero( + return vector3_snapped_to_zero( matrix4_get_rotation_euler_xyz_degrees( matrix4_multiplied_by_matrix4( matrix4_rotation_for_quaternion_quantised( rotation ), matrix4_rotation_for_euler_xyz_degrees_quantised( angles ) ) - ) + ), + ANGLEKEY_SMALLEST ); } #if 0 inline Vector3 angles_rotated_for_rotated_pivot( const Vector3& angles, const Quaternion& rotation ){ - return angles_snapped_to_zero( + return vector3_snapped_to_zero( matrix4_get_rotation_euler_xyz_degrees( matrix4_multiplied_by_matrix4( matrix4_rotation_for_euler_xyz_degrees_quantised( angles ), matrix4_rotation_for_quaternion_quantised( rotation ) ) - ) + ), + ANGLEKEY_SMALLEST ); } #endif diff --git a/plugins/entity/miscmodel.cpp b/plugins/entity/miscmodel.cpp index 941cde1b..a17f95c3 100644 --- a/plugins/entity/miscmodel.cpp +++ b/plugins/entity/miscmodel.cpp @@ -339,7 +339,7 @@ public: m_scale = matrix4_get_scale_vec3( mat ); #endif - //m_angles = angles_snapped_to_zero( matrix4_get_rotation_euler_xyz_degrees( mat ) ); + //m_angles = vector3_snapped_to_zero( matrix4_get_rotation_euler_xyz_degrees( mat ), ANGLEKEY_SMALLEST ); } void snapto( float snap ){ m_originKey.m_origin = origin_snapped( m_originKey.m_origin, snap );