MATHLIB.CPP (6214B)
1 /* 2 =========================================================================== 3 Copyright (C) 1999-2005 Id Software, Inc. 4 5 This file is part of Quake III Arena source code. 6 7 Quake III Arena source code is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the License, 10 or (at your option) any later version. 11 12 Quake III Arena source code is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Foobar; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 =========================================================================== 21 */ 22 // mathlib.c -- math primitives 23 24 #include "stdafx.h" 25 #include "cmdlib.h" 26 #include "mathlib.h" 27 28 vec3_t vec3_origin = {0.0f,0.0f,0.0f}; 29 30 31 float VectorLength(vec3_t v) 32 { 33 int i; 34 float length; 35 36 length = 0.0f; 37 for (i=0 ; i< 3 ; i++) 38 length += v[i]*v[i]; 39 length = (float)sqrt (length); 40 41 return length; 42 } 43 44 qboolean VectorCompare (vec3_t v1, vec3_t v2) 45 { 46 int i; 47 48 for (i=0 ; i<3 ; i++) 49 if (fabs(v1[i]-v2[i]) > EQUAL_EPSILON) 50 return false; 51 52 return true; 53 } 54 55 vec_t Q_rint (vec_t in) 56 { 57 if (g_PrefsDlg.m_bNoClamp) 58 return in; 59 else 60 return (float)floor (in + 0.5); 61 } 62 63 void VectorMA (vec3_t va, float scale, vec3_t vb, vec3_t vc) 64 { 65 vc[0] = va[0] + scale*vb[0]; 66 vc[1] = va[1] + scale*vb[1]; 67 vc[2] = va[2] + scale*vb[2]; 68 } 69 70 void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross) 71 { 72 cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; 73 cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; 74 cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; 75 } 76 77 vec_t _DotProduct (vec3_t v1, vec3_t v2) 78 { 79 return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; 80 } 81 82 void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out) 83 { 84 out[0] = va[0]-vb[0]; 85 out[1] = va[1]-vb[1]; 86 out[2] = va[2]-vb[2]; 87 } 88 89 void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out) 90 { 91 out[0] = va[0]+vb[0]; 92 out[1] = va[1]+vb[1]; 93 out[2] = va[2]+vb[2]; 94 } 95 96 void _VectorCopy (vec3_t in, vec3_t out) 97 { 98 out[0] = in[0]; 99 out[1] = in[1]; 100 out[2] = in[2]; 101 } 102 103 vec_t VectorNormalize (vec3_t v) 104 { 105 int i; 106 float length; 107 108 length = 0.0f; 109 for (i=0 ; i< 3 ; i++) 110 length += v[i]*v[i]; 111 length = (float)sqrt (length); 112 if (length == 0) 113 return (vec_t)0; 114 115 for (i=0 ; i< 3 ; i++) 116 v[i] /= length; 117 118 return length; 119 } 120 121 void VectorInverse (vec3_t v) 122 { 123 v[0] = -v[0]; 124 v[1] = -v[1]; 125 v[2] = -v[2]; 126 } 127 128 void VectorScale (vec3_t v, vec_t scale, vec3_t out) 129 { 130 out[0] = v[0] * scale; 131 out[1] = v[1] * scale; 132 out[2] = v[2] * scale; 133 } 134 135 136 void VectorRotate (vec3_t vIn, vec3_t vRotation, vec3_t out) 137 { 138 vec3_t vWork, va; 139 VectorCopy(vIn, va); 140 VectorCopy(va, vWork); 141 int nIndex[3][2]; 142 nIndex[0][0] = 1; nIndex[0][1] = 2; 143 nIndex[1][0] = 2; nIndex[1][1] = 0; 144 nIndex[2][0] = 0; nIndex[2][1] = 1; 145 146 for (int i = 0; i < 3; i++) 147 { 148 if (vRotation[i] != 0) 149 { 150 double dAngle = vRotation[i] * Q_PI / 180.0; 151 double c = cos(dAngle); 152 double s = sin(dAngle); 153 vWork[nIndex[i][0]] = va[nIndex[i][0]] * c - va[nIndex[i][1]] * s; 154 vWork[nIndex[i][1]] = va[nIndex[i][0]] * s + va[nIndex[i][1]] * c; 155 } 156 VectorCopy(vWork, va); 157 } 158 VectorCopy(vWork, out); 159 } 160 161 void VectorRotate (vec3_t vIn, vec3_t vRotation, vec3_t vOrigin, vec3_t out) 162 { 163 vec3_t vTemp, vTemp2; 164 VectorSubtract(vIn, vOrigin, vTemp); 165 VectorRotate(vTemp, vRotation, vTemp2); 166 VectorAdd(vTemp2, vOrigin, out); 167 } 168 169 void VectorPolar(vec3_t v, float radius, float theta, float phi) 170 { 171 v[0]=float(radius * cos(theta) * cos(phi)); 172 v[1]=float(radius * sin(theta) * cos(phi)); 173 v[2]=float(radius * sin(phi)); 174 } 175 176 void VectorSnap(vec3_t v) 177 { 178 for (int i = 0; i < 3; i++) 179 { 180 v[i] = floor (v[i] + 0.5); 181 } 182 } 183 184 185 void _Vector5Add (vec5_t va, vec5_t vb, vec5_t out) 186 { 187 out[0] = va[0]+vb[0]; 188 out[1] = va[1]+vb[1]; 189 out[2] = va[2]+vb[2]; 190 out[3] = va[3]+vb[3]; 191 out[4] = va[4]+vb[4]; 192 } 193 194 void _Vector5Scale (vec5_t v, vec_t scale, vec5_t out) 195 { 196 out[0] = v[0] * scale; 197 out[1] = v[1] * scale; 198 out[2] = v[2] * scale; 199 out[3] = v[3] * scale; 200 out[4] = v[4] * scale; 201 } 202 203 void _Vector53Copy (vec5_t in, vec3_t out) 204 { 205 out[0] = in[0]; 206 out[1] = in[1]; 207 out[2] = in[2]; 208 } 209 210 // NOTE: added these from Ritual's Q3Radiant 211 void ClearBounds (vec3_t mins, vec3_t maxs) 212 { 213 mins[0] = mins[1] = mins[2] = 99999; 214 maxs[0] = maxs[1] = maxs[2] = -99999; 215 } 216 217 void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs) 218 { 219 int i; 220 vec_t val; 221 222 for (i=0 ; i<3 ; i++) 223 { 224 val = v[i]; 225 if (val < mins[i]) 226 mins[i] = val; 227 if (val > maxs[i]) 228 maxs[i] = val; 229 } 230 } 231 232 #define PITCH 0 // up / down 233 #define YAW 1 // left / right 234 #define ROLL 2 // fall over 235 #ifndef M_PI 236 #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h 237 #endif 238 239 void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) 240 { 241 float angle; 242 static float sr, sp, sy, cr, cp, cy; 243 // static to help MS compiler fp bugs 244 245 angle = angles[YAW] * (M_PI*2 / 360); 246 sy = sin(angle); 247 cy = cos(angle); 248 angle = angles[PITCH] * (M_PI*2 / 360); 249 sp = sin(angle); 250 cp = cos(angle); 251 angle = angles[ROLL] * (M_PI*2 / 360); 252 sr = sin(angle); 253 cr = cos(angle); 254 255 if (forward) 256 { 257 forward[0] = cp*cy; 258 forward[1] = cp*sy; 259 forward[2] = -sp; 260 } 261 if (right) 262 { 263 right[0] = -sr*sp*cy+cr*sy; 264 right[1] = -sr*sp*sy-cr*cy; 265 right[2] = -sr*cp; 266 } 267 if (up) 268 { 269 up[0] = cr*sp*cy+sr*sy; 270 up[1] = cr*sp*sy-sr*cy; 271 up[2] = cr*cp; 272 } 273 } 274 275 void VectorToAngles( vec3_t vec, vec3_t angles ) 276 { 277 float forward; 278 float yaw, pitch; 279 280 if ( ( vec[ 0 ] == 0 ) && ( vec[ 1 ] == 0 ) ) 281 { 282 yaw = 0; 283 if ( vec[ 2 ] > 0 ) 284 { 285 pitch = 90; 286 } 287 else 288 { 289 pitch = 270; 290 } 291 } 292 else 293 { 294 yaw = atan2( vec[ 1 ], vec[ 0 ] ) * 180 / M_PI; 295 if ( yaw < 0 ) 296 { 297 yaw += 360; 298 } 299 300 forward = ( float )sqrt( vec[ 0 ] * vec[ 0 ] + vec[ 1 ] * vec[ 1 ] ); 301 pitch = atan2( vec[ 2 ], forward ) * 180 / M_PI; 302 if ( pitch < 0 ) 303 { 304 pitch += 360; 305 } 306 } 307 308 angles[ 0 ] = pitch; 309 angles[ 1 ] = yaw; 310 angles[ 2 ] = 0; 311 }