math_angles.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "q_shared.h"
  19. #include <float.h>
  20. angles_t ang_zero( 0.0f, 0.0f, 0.0f );
  21. void toAngles( mat3_t &src, angles_t &dst ) {
  22. double theta;
  23. double cp;
  24. double sp;
  25. sp = src[ 0 ][ 2 ];
  26. // cap off our sin value so that we don't get any NANs
  27. if ( sp > 1.0 ) {
  28. sp = 1.0;
  29. } else if ( sp < -1.0 ) {
  30. sp = -1.0;
  31. }
  32. theta = -asin( sp );
  33. cp = cos( theta );
  34. if ( cp > 8192 * FLT_EPSILON ) {
  35. dst.pitch = theta * 180 / M_PI;
  36. dst.yaw = atan2( src[ 0 ][ 1 ], src[ 0 ][ 0 ] ) * 180 / M_PI;
  37. dst.roll = atan2( src[ 1 ][ 2 ], src[ 2 ][ 2 ] ) * 180 / M_PI;
  38. } else {
  39. dst.pitch = theta * 180 / M_PI;
  40. dst.yaw = -atan2( src[ 1 ][ 0 ], src[ 1 ][ 1 ] ) * 180 / M_PI;
  41. dst.roll = 0;
  42. }
  43. }
  44. void toAngles( quat_t &src, angles_t &dst ) {
  45. mat3_t temp;
  46. toMatrix( src, temp );
  47. toAngles( temp, dst );
  48. }
  49. void toAngles( idVec3_t &src, angles_t &dst ) {
  50. dst.pitch = src[ 0 ];
  51. dst.yaw = src[ 1 ];
  52. dst.roll = src[ 2 ];
  53. }
  54. void angles_t::toVectors( idVec3_t *forward, idVec3_t *right, idVec3_t *up ) {
  55. float angle;
  56. static float sr, sp, sy, cr, cp, cy; // static to help MS compiler fp bugs
  57. angle = yaw * ( M_PI * 2 / 360 );
  58. sy = sin( angle );
  59. cy = cos( angle );
  60. angle = pitch * ( M_PI * 2 / 360 );
  61. sp = sin( angle );
  62. cp = cos( angle );
  63. angle = roll * ( M_PI * 2 / 360 );
  64. sr = sin( angle );
  65. cr = cos( angle );
  66. if ( forward ) {
  67. forward->set( cp * cy, cp * sy, -sp );
  68. }
  69. if ( right ) {
  70. right->set( -sr * sp * cy + cr * sy, -sr * sp * sy + -cr * cy, -sr * cp );
  71. }
  72. if ( up ) {
  73. up->set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp );
  74. }
  75. }
  76. idVec3_t angles_t::toForward( void ) {
  77. float angle;
  78. static float sp, sy, cp, cy; // static to help MS compiler fp bugs
  79. angle = yaw * ( M_PI * 2 / 360 );
  80. sy = sin( angle );
  81. cy = cos( angle );
  82. angle = pitch * ( M_PI * 2 / 360 );
  83. sp = sin( angle );
  84. cp = cos( angle );
  85. return idVec3_t( cp * cy, cp * sy, -sp );
  86. }
  87. /*
  88. =================
  89. Normalize360
  90. returns angles normalized to the range [0 <= angle < 360]
  91. =================
  92. */
  93. angles_t& angles_t::Normalize360( void ) {
  94. pitch = (360.0 / 65536) * ( ( int )( pitch * ( 65536 / 360.0 ) ) & 65535 );
  95. yaw = (360.0 / 65536) * ( ( int )( yaw * ( 65536 / 360.0 ) ) & 65535 );
  96. roll = (360.0 / 65536) * ( ( int )( roll * ( 65536 / 360.0 ) ) & 65535 );
  97. return *this;
  98. }
  99. /*
  100. =================
  101. Normalize180
  102. returns angles normalized to the range [-180 < angle <= 180]
  103. =================
  104. */
  105. angles_t& angles_t::Normalize180( void ) {
  106. Normalize360();
  107. if ( pitch > 180.0 ) {
  108. pitch -= 360.0;
  109. }
  110. if ( yaw > 180.0 ) {
  111. yaw -= 360.0;
  112. }
  113. if ( roll > 180.0 ) {
  114. roll -= 360.0;
  115. }
  116. return *this;
  117. }