@@ -63,6 +63,20 @@ bool vm_matrix_equal(const matrix4 &self, const matrix4 &other)
6363 vm_vec_equal (self.vec .pos , other.vec .pos );
6464}
6565
66+ // -----------------------------------------------------------
67+ // atan2_safe()
68+ //
69+ // Wrapper around atan2() that handles the special case of x == 0 and y == 0.
70+ //
71+ float atan2_safe (float y, float x)
72+ {
73+ // special case
74+ if ( x == 0 .0f && y == 0 .0f )
75+ return 0 .0f ;
76+
77+ return atan2 (y, x);
78+ }
79+
6680// ---------------------------------------------------------------------
6781// vm_vec_component()
6882//
@@ -1109,7 +1123,7 @@ angles *vm_extract_angles_matrix(angles *a, const matrix *m)
11091123{
11101124 float sinh,cosh,cosp;
11111125
1112- a->h = atan2 (m->vec .fvec .xyz .x ,m->vec .fvec .xyz .z );
1126+ a->h = atan2_safe (m->vec .fvec .xyz .x ,m->vec .fvec .xyz .z );
11131127
11141128 sinh = sinf (a->h ); cosh = cosf (a->h );
11151129
@@ -1124,7 +1138,7 @@ angles *vm_extract_angles_matrix(angles *a, const matrix *m)
11241138
11251139 fvec_xz_distance = fl_sqrt ( ( (m->vec .fvec .xyz .x )*(m->vec .fvec .xyz .x ) ) + ( (m->vec .fvec .xyz .z )*(m->vec .fvec .xyz .z ) ) );
11261140
1127- a->p = atan2 (-m->vec .fvec .xyz .y , fvec_xz_distance);
1141+ a->p = atan2_safe (-m->vec .fvec .xyz .y , fvec_xz_distance);
11281142
11291143 if (cosp == 0 .0f ) // the cosine of pitch is zero. we're pitched straight up. say no bank
11301144
@@ -1136,7 +1150,7 @@ angles *vm_extract_angles_matrix(angles *a, const matrix *m)
11361150 sinb = m->vec .rvec .xyz .y /cosp;
11371151 cosb = m->vec .uvec .xyz .y /cosp;
11381152
1139- a->b = atan2 (sinb,cosb);
1153+ a->b = atan2_safe (sinb,cosb);
11401154 }
11411155
11421156
@@ -1182,7 +1196,7 @@ static angles *vm_extract_angles_vector_normalized(angles *a, const vec3d *v)
11821196
11831197 a->p = asinf_safe (-v->xyz .y );
11841198
1185- a->h = atan2 (v->xyz .z ,v->xyz .x );
1199+ a->h = atan2_safe (v->xyz .z ,v->xyz .x );
11861200
11871201 return a;
11881202}
@@ -1853,10 +1867,10 @@ float vm_closest_angle_to_matrix(const matrix* mat, const vec3d* rot_axis, float
18531867 // If we support IEEE float handling, we don't need this, the div by 0 will be handled correctly with the INF. If not, do this:
18541868 const float yz_recip = (!std::numeric_limits<float >::is_iec559 && y * z < 0 .001f ) ? FLT_MAX : 1 .0f / (y * z);
18551869
1856- solutions = { 2 .0f * atan2f (-sr_neg * (y * y + sr) * yz_recip, -2 .0f * sr_neg),
1857- 2 .0f * atan2f (sr_neg * (y * y + sr) * yz_recip, 2 .0f * sr_neg),
1858- 2 .0f * atan2f (-sr_pos * (y * y - sr) * yz_recip, -2 .0f * sr_pos),
1859- 2 .0f * atan2f (sr_pos * (y * y - sr) * yz_recip, 2 .0f * sr_pos) };
1870+ solutions = { 2 .0f * atan2_safe (-sr_neg * (y * y + sr) * yz_recip, -2 .0f * sr_neg),
1871+ 2 .0f * atan2_safe (sr_neg * (y * y + sr) * yz_recip, 2 .0f * sr_neg),
1872+ 2 .0f * atan2_safe (-sr_pos * (y * y - sr) * yz_recip, -2 .0f * sr_pos),
1873+ 2 .0f * atan2_safe (sr_pos * (y * y - sr) * yz_recip, 2 .0f * sr_pos) };
18601874 }
18611875 float value = -2 .0f ;
18621876 float correct = 0 ;
0 commit comments