Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

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 }