2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
29 #include "../precompiled.h"
34 idAngles ang_zero( 0.0f, 0.0f, 0.0f );
39 idAngles::Normalize360
41 returns angles normalized to the range [0 <= angle < 360]
44 idAngles& idAngles::Normalize360( void ) {
47 for ( i = 0; i < 3; i++ ) {
48 if ( ( (*this)[i] >= 360.0f ) || ( (*this)[i] < 0.0f ) ) {
49 (*this)[i] -= floor( (*this)[i] / 360.0f ) * 360.0f;
51 if ( (*this)[i] >= 360.0f ) {
54 if ( (*this)[i] < 0.0f ) {
65 idAngles::Normalize180
67 returns angles normalized to the range [-180 < angle <= 180]
70 idAngles& idAngles::Normalize180( void ) {
73 if ( pitch > 180.0f ) {
81 if ( roll > 180.0f ) {
92 void idAngles::ToVectors( idVec3 *forward, idVec3 *right, idVec3 *up ) const {
93 float sr, sp, sy, cr, cp, cy;
95 idMath::SinCos( DEG2RAD( yaw ), sy, cy );
96 idMath::SinCos( DEG2RAD( pitch ), sp, cp );
97 idMath::SinCos( DEG2RAD( roll ), sr, cr );
100 forward->Set( cp * cy, cp * sy, -sp );
104 right->Set( -sr * sp * cy + cr * sy, -sr * sp * sy + -cr * cy, -sr * cp );
108 up->Set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp );
117 idVec3 idAngles::ToForward( void ) const {
118 float sp, sy, cp, cy;
120 idMath::SinCos( DEG2RAD( yaw ), sy, cy );
121 idMath::SinCos( DEG2RAD( pitch ), sp, cp );
123 return idVec3( cp * cy, cp * sy, -sp );
131 idQuat idAngles::ToQuat( void ) const {
132 float sx, cx, sy, cy, sz, cz;
133 float sxcy, cxcy, sxsy, cxsy;
135 idMath::SinCos( DEG2RAD( yaw ) * 0.5f, sz, cz );
136 idMath::SinCos( DEG2RAD( pitch ) * 0.5f, sy, cy );
137 idMath::SinCos( DEG2RAD( roll ) * 0.5f, sx, cx );
144 return idQuat( cxsy*sz - sxcy*cz, -cxsy*cz - sxcy*sz, sxsy*cz - cxcy*sz, cxcy*cz + sxsy*sz );
152 idRotation idAngles::ToRotation( void ) const {
155 float sx, cx, sy, cy, sz, cz;
156 float sxcy, cxcy, sxsy, cxsy;
158 if ( pitch == 0.0f ) {
160 return idRotation( vec3_origin, idVec3( -1.0f, 0.0f, 0.0f ), roll );
162 if ( roll == 0.0f ) {
163 return idRotation( vec3_origin, idVec3( 0.0f, 0.0f, -1.0f ), yaw );
165 } else if ( yaw == 0.0f && roll == 0.0f ) {
166 return idRotation( vec3_origin, idVec3( 0.0f, -1.0f, 0.0f ), pitch );
169 idMath::SinCos( DEG2RAD( yaw ) * 0.5f, sz, cz );
170 idMath::SinCos( DEG2RAD( pitch ) * 0.5f, sy, cy );
171 idMath::SinCos( DEG2RAD( roll ) * 0.5f, sx, cx );
178 vec.x = cxsy * sz - sxcy * cz;
179 vec.y = -cxsy * cz - sxcy * sz;
180 vec.z = sxsy * cz - cxcy * sz;
181 w = cxcy * cz + sxsy * sz;
182 angle = idMath::ACos( w );
183 if ( angle == 0.0f ) {
184 vec.Set( 0.0f, 0.0f, 1.0f );
186 //vec *= (1.0f / sin( angle ));
188 vec.FixDegenerateNormal();
189 angle *= 2.0f * idMath::M_RAD2DEG;
191 return idRotation( vec3_origin, vec, angle );
199 idMat3 idAngles::ToMat3( void ) const {
201 float sr, sp, sy, cr, cp, cy;
203 idMath::SinCos( DEG2RAD( yaw ), sy, cy );
204 idMath::SinCos( DEG2RAD( pitch ), sp, cp );
205 idMath::SinCos( DEG2RAD( roll ), sr, cr );
207 mat[ 0 ].Set( cp * cy, cp * sy, -sp );
208 mat[ 1 ].Set( sr * sp * cy + cr * -sy, sr * sp * sy + cr * cy, sr * cp );
209 mat[ 2 ].Set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp );
219 idMat4 idAngles::ToMat4( void ) const {
220 return ToMat3().ToMat4();
225 idAngles::ToAngularVelocity
228 idVec3 idAngles::ToAngularVelocity( void ) const {
229 idRotation rotation = idAngles::ToRotation();
230 return rotation.GetVec() * DEG2RAD( rotation.GetAngle() );
238 const char *idAngles::ToString( int precision ) const {
239 return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision );