00001
00002
00003
00004 #include "q_shared.h"
00005
00006
00007 vec3_t vec3_origin = {0,0,0};
00008 vec3_t axisDefault[3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
00009
00010
00011 vec4_t colorBlack = {0, 0, 0, 1};
00012 vec4_t colorRed = {1, 0, 0, 1};
00013 vec4_t colorGreen = {0, 1, 0, 1};
00014 vec4_t colorBlue = {0, 0, 1, 1};
00015 vec4_t colorYellow = {1, 1, 0, 1};
00016 vec4_t colorMagenta= {1, 0, 1, 1};
00017 vec4_t colorCyan = {0, 1, 1, 1};
00018 vec4_t colorWhite = {1, 1, 1, 1};
00019 vec4_t colorLtGrey = {0.75, 0.75, 0.75, 1};
00020 vec4_t colorMdGrey = {0.5, 0.5, 0.5, 1};
00021 vec4_t colorDkGrey = {0.25, 0.25, 0.25, 1};
00022
00023 vec4_t colorLtBlue = {0.367f, 0.261f, 0.722f, 1};
00024 vec4_t colorDkBlue = {0.199f, 0.0f, 0.398f, 1};
00025
00026 vec4_t g_color_table[8] =
00027 {
00028 {0.0, 0.0, 0.0, 1.0},
00029 {1.0, 0.0, 0.0, 1.0},
00030 {0.0, 1.0, 0.0, 1.0},
00031 {1.0, 1.0, 0.0, 1.0},
00032 {0.0, 0.0, 1.0, 1.0},
00033 {0.0, 1.0, 1.0, 1.0},
00034 {1.0, 0.0, 1.0, 1.0},
00035 {1.0, 1.0, 1.0, 1.0},
00036 };
00037
00038
00039 vec3_t bytedirs[NUMVERTEXNORMALS] =
00040 {
00041 {-0.525731f, 0.000000f, 0.850651f}, {-0.442863f, 0.238856f, 0.864188f},
00042 {-0.295242f, 0.000000f, 0.955423f}, {-0.309017f, 0.500000f, 0.809017f},
00043 {-0.162460f, 0.262866f, 0.951056f}, {0.000000f, 0.000000f, 1.000000f},
00044 {0.000000f, 0.850651f, 0.525731f}, {-0.147621f, 0.716567f, 0.681718f},
00045 {0.147621f, 0.716567f, 0.681718f}, {0.000000f, 0.525731f, 0.850651f},
00046 {0.309017f, 0.500000f, 0.809017f}, {0.525731f, 0.000000f, 0.850651f},
00047 {0.295242f, 0.000000f, 0.955423f}, {0.442863f, 0.238856f, 0.864188f},
00048 {0.162460f, 0.262866f, 0.951056f}, {-0.681718f, 0.147621f, 0.716567f},
00049 {-0.809017f, 0.309017f, 0.500000f},{-0.587785f, 0.425325f, 0.688191f},
00050 {-0.850651f, 0.525731f, 0.000000f},{-0.864188f, 0.442863f, 0.238856f},
00051 {-0.716567f, 0.681718f, 0.147621f},{-0.688191f, 0.587785f, 0.425325f},
00052 {-0.500000f, 0.809017f, 0.309017f}, {-0.238856f, 0.864188f, 0.442863f},
00053 {-0.425325f, 0.688191f, 0.587785f}, {-0.716567f, 0.681718f, -0.147621f},
00054 {-0.500000f, 0.809017f, -0.309017f}, {-0.525731f, 0.850651f, 0.000000f},
00055 {0.000000f, 0.850651f, -0.525731f}, {-0.238856f, 0.864188f, -0.442863f},
00056 {0.000000f, 0.955423f, -0.295242f}, {-0.262866f, 0.951056f, -0.162460f},
00057 {0.000000f, 1.000000f, 0.000000f}, {0.000000f, 0.955423f, 0.295242f},
00058 {-0.262866f, 0.951056f, 0.162460f}, {0.238856f, 0.864188f, 0.442863f},
00059 {0.262866f, 0.951056f, 0.162460f}, {0.500000f, 0.809017f, 0.309017f},
00060 {0.238856f, 0.864188f, -0.442863f},{0.262866f, 0.951056f, -0.162460f},
00061 {0.500000f, 0.809017f, -0.309017f},{0.850651f, 0.525731f, 0.000000f},
00062 {0.716567f, 0.681718f, 0.147621f}, {0.716567f, 0.681718f, -0.147621f},
00063 {0.525731f, 0.850651f, 0.000000f}, {0.425325f, 0.688191f, 0.587785f},
00064 {0.864188f, 0.442863f, 0.238856f}, {0.688191f, 0.587785f, 0.425325f},
00065 {0.809017f, 0.309017f, 0.500000f}, {0.681718f, 0.147621f, 0.716567f},
00066 {0.587785f, 0.425325f, 0.688191f}, {0.955423f, 0.295242f, 0.000000f},
00067 {1.000000f, 0.000000f, 0.000000f}, {0.951056f, 0.162460f, 0.262866f},
00068 {0.850651f, -0.525731f, 0.000000f},{0.955423f, -0.295242f, 0.000000f},
00069 {0.864188f, -0.442863f, 0.238856f}, {0.951056f, -0.162460f, 0.262866f},
00070 {0.809017f, -0.309017f, 0.500000f}, {0.681718f, -0.147621f, 0.716567f},
00071 {0.850651f, 0.000000f, 0.525731f}, {0.864188f, 0.442863f, -0.238856f},
00072 {0.809017f, 0.309017f, -0.500000f}, {0.951056f, 0.162460f, -0.262866f},
00073 {0.525731f, 0.000000f, -0.850651f}, {0.681718f, 0.147621f, -0.716567f},
00074 {0.681718f, -0.147621f, -0.716567f},{0.850651f, 0.000000f, -0.525731f},
00075 {0.809017f, -0.309017f, -0.500000f}, {0.864188f, -0.442863f, -0.238856f},
00076 {0.951056f, -0.162460f, -0.262866f}, {0.147621f, 0.716567f, -0.681718f},
00077 {0.309017f, 0.500000f, -0.809017f}, {0.425325f, 0.688191f, -0.587785f},
00078 {0.442863f, 0.238856f, -0.864188f}, {0.587785f, 0.425325f, -0.688191f},
00079 {0.688191f, 0.587785f, -0.425325f}, {-0.147621f, 0.716567f, -0.681718f},
00080 {-0.309017f, 0.500000f, -0.809017f}, {0.000000f, 0.525731f, -0.850651f},
00081 {-0.525731f, 0.000000f, -0.850651f}, {-0.442863f, 0.238856f, -0.864188f},
00082 {-0.295242f, 0.000000f, -0.955423f}, {-0.162460f, 0.262866f, -0.951056f},
00083 {0.000000f, 0.000000f, -1.000000f}, {0.295242f, 0.000000f, -0.955423f},
00084 {0.162460f, 0.262866f, -0.951056f}, {-0.442863f, -0.238856f, -0.864188f},
00085 {-0.309017f, -0.500000f, -0.809017f}, {-0.162460f, -0.262866f, -0.951056f},
00086 {0.000000f, -0.850651f, -0.525731f}, {-0.147621f, -0.716567f, -0.681718f},
00087 {0.147621f, -0.716567f, -0.681718f}, {0.000000f, -0.525731f, -0.850651f},
00088 {0.309017f, -0.500000f, -0.809017f}, {0.442863f, -0.238856f, -0.864188f},
00089 {0.162460f, -0.262866f, -0.951056f}, {0.238856f, -0.864188f, -0.442863f},
00090 {0.500000f, -0.809017f, -0.309017f}, {0.425325f, -0.688191f, -0.587785f},
00091 {0.716567f, -0.681718f, -0.147621f}, {0.688191f, -0.587785f, -0.425325f},
00092 {0.587785f, -0.425325f, -0.688191f}, {0.000000f, -0.955423f, -0.295242f},
00093 {0.000000f, -1.000000f, 0.000000f}, {0.262866f, -0.951056f, -0.162460f},
00094 {0.000000f, -0.850651f, 0.525731f}, {0.000000f, -0.955423f, 0.295242f},
00095 {0.238856f, -0.864188f, 0.442863f}, {0.262866f, -0.951056f, 0.162460f},
00096 {0.500000f, -0.809017f, 0.309017f}, {0.716567f, -0.681718f, 0.147621f},
00097 {0.525731f, -0.850651f, 0.000000f}, {-0.238856f, -0.864188f, -0.442863f},
00098 {-0.500000f, -0.809017f, -0.309017f}, {-0.262866f, -0.951056f, -0.162460f},
00099 {-0.850651f, -0.525731f, 0.000000f}, {-0.716567f, -0.681718f, -0.147621f},
00100 {-0.716567f, -0.681718f, 0.147621f}, {-0.525731f, -0.850651f, 0.000000f},
00101 {-0.500000f, -0.809017f, 0.309017f}, {-0.238856f, -0.864188f, 0.442863f},
00102 {-0.262866f, -0.951056f, 0.162460f}, {-0.864188f, -0.442863f, 0.238856f},
00103 {-0.809017f, -0.309017f, 0.500000f}, {-0.688191f, -0.587785f, 0.425325f},
00104 {-0.681718f, -0.147621f, 0.716567f}, {-0.442863f, -0.238856f, 0.864188f},
00105 {-0.587785f, -0.425325f, 0.688191f}, {-0.309017f, -0.500000f, 0.809017f},
00106 {-0.147621f, -0.716567f, 0.681718f}, {-0.425325f, -0.688191f, 0.587785f},
00107 {-0.162460f, -0.262866f, 0.951056f}, {0.442863f, -0.238856f, 0.864188f},
00108 {0.162460f, -0.262866f, 0.951056f}, {0.309017f, -0.500000f, 0.809017f},
00109 {0.147621f, -0.716567f, 0.681718f}, {0.000000f, -0.525731f, 0.850651f},
00110 {0.425325f, -0.688191f, 0.587785f}, {0.587785f, -0.425325f, 0.688191f},
00111 {0.688191f, -0.587785f, 0.425325f}, {-0.955423f, 0.295242f, 0.000000f},
00112 {-0.951056f, 0.162460f, 0.262866f}, {-1.000000f, 0.000000f, 0.000000f},
00113 {-0.850651f, 0.000000f, 0.525731f}, {-0.955423f, -0.295242f, 0.000000f},
00114 {-0.951056f, -0.162460f, 0.262866f}, {-0.864188f, 0.442863f, -0.238856f},
00115 {-0.951056f, 0.162460f, -0.262866f}, {-0.809017f, 0.309017f, -0.500000f},
00116 {-0.864188f, -0.442863f, -0.238856f}, {-0.951056f, -0.162460f, -0.262866f},
00117 {-0.809017f, -0.309017f, -0.500000f}, {-0.681718f, 0.147621f, -0.716567f},
00118 {-0.681718f, -0.147621f, -0.716567f}, {-0.850651f, 0.000000f, -0.525731f},
00119 {-0.688191f, 0.587785f, -0.425325f}, {-0.587785f, 0.425325f, -0.688191f},
00120 {-0.425325f, 0.688191f, -0.587785f}, {-0.425325f, -0.688191f, -0.587785f},
00121 {-0.587785f, -0.425325f, -0.688191f}, {-0.688191f, -0.587785f, -0.425325f}
00122 };
00123
00124
00125
00126 int Q_rand( int *seed ) {
00127 *seed = (69069 * *seed + 1);
00128 return *seed;
00129 }
00130
00131 float Q_random( int *seed ) {
00132 return ( Q_rand( seed ) & 0xffff ) / (float)0x10000;
00133 }
00134
00135 float Q_crandom( int *seed ) {
00136 return 2.0 * ( Q_random( seed ) - 0.5 );
00137 }
00138
00139 #ifdef __LCC__
00140
00141 int VectorCompare( const vec3_t v1, const vec3_t v2 ) {
00142 if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) {
00143 return 0;
00144 }
00145 return 1;
00146 }
00147
00148 vec_t VectorLength( const vec3_t v ) {
00149 return (vec_t)sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
00150 }
00151
00152 vec_t VectorLengthSquared( const vec3_t v ) {
00153 return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
00154 }
00155
00156 vec_t Distance( const vec3_t p1, const vec3_t p2 ) {
00157 vec3_t v;
00158
00159 VectorSubtract (p2, p1, v);
00160 return VectorLength( v );
00161 }
00162
00163 vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 ) {
00164 vec3_t v;
00165
00166 VectorSubtract (p2, p1, v);
00167 return v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
00168 }
00169
00170
00171
00172 void VectorNormalizeFast( vec3_t v )
00173 {
00174 float ilength;
00175
00176 ilength = Q_rsqrt( DotProduct( v, v ) );
00177
00178 v[0] *= ilength;
00179 v[1] *= ilength;
00180 v[2] *= ilength;
00181 }
00182
00183 void VectorInverse( vec3_t v ){
00184 v[0] = -v[0];
00185 v[1] = -v[1];
00186 v[2] = -v[2];
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196 #if 0
00197 void CrossProductA (float *v1, float *v2, float *cross)
00198 {
00199 #if 1
00200 static float scratch1, scratch2, scratch3, scratch4, scratch5, scratch6;
00201
00202 __asm mov eax,v1
00203 __asm mov ecx,v2
00204 __asm mov edx,cross
00205
00206 __asm fld dword ptr[eax+4]
00207 __asm fmul dword ptr[ecx+8]
00208 __asm fstp scratch1
00209
00210 __asm fld dword ptr[eax+8]
00211 __asm fmul dword ptr[ecx+4]
00212 __asm fstp scratch2
00213
00214 __asm fld dword ptr[eax+8]
00215 __asm fmul dword ptr[ecx]
00216 __asm fstp scratch3
00217
00218 __asm fld dword ptr[eax]
00219 __asm fmul dword ptr[ecx+8]
00220 __asm fstp scratch4
00221
00222 __asm fld dword ptr[eax]
00223 __asm fmul dword ptr[ecx+4]
00224 __asm fstp scratch5
00225
00226 __asm fld dword ptr[eax+4]
00227 __asm fmul dword ptr[ecx]
00228 __asm fstp scratch6
00229
00230 __asm fld scratch1
00231 __asm fsub scratch2
00232 __asm fstp dword ptr[edx]
00233
00234 __asm fld scratch3
00235 __asm fsub scratch4
00236 __asm fstp dword ptr[edx+4]
00237
00238 __asm fld scratch5
00239 __asm fsub scratch6
00240 __asm fstp dword ptr[edx+8]
00241 #else //doesn't require use of statics, but not nearly as fast.
00242 __asm mov eax,v1
00243 __asm mov ecx,v2
00244 __asm mov edx,cross
00245
00246 __asm fld dword ptr[eax+4]
00247 __asm fmul dword ptr[ecx+8]
00248 __asm fld dword ptr[eax+8]
00249 __asm fmul dword ptr[ecx+4]
00250 __asm fsubp st(1),st
00251 __asm fstp dword ptr[edx]
00252
00253 __asm fld dword ptr[eax+8]
00254 __asm fmul dword ptr[ecx]
00255 __asm fld dword ptr[eax]
00256 __asm fmul dword ptr[ecx+8]
00257 __asm fsubp st(1),st
00258 __asm fstp dword ptr[edx+4]
00259
00260 __asm fld dword ptr[eax]
00261 __asm fmul dword ptr[ecx+4]
00262 __asm fld dword ptr[eax+4]
00263 __asm fmul dword ptr[ecx]
00264 __asm fsubp st(1),st
00265 __asm fstp dword ptr[edx+8]
00266 #endif
00267 }
00268 #endif
00269
00270 void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ) {
00271 cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
00272 cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
00273 cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
00274 }
00275 #endif
00276
00277
00278
00279 signed char ClampChar( int i ) {
00280 if ( i < -128 ) {
00281 return -128;
00282 }
00283 if ( i > 127 ) {
00284 return 127;
00285 }
00286 return i;
00287 }
00288
00289 signed short ClampShort( int i ) {
00290 if ( i < -32768 ) {
00291 return -32768;
00292 }
00293 if ( i > 0x7fff ) {
00294 return 0x7fff;
00295 }
00296 return i;
00297 }
00298
00299
00300
00301 int DirToByte( vec3_t dir ) {
00302 int i, best;
00303 float d, bestd;
00304
00305 if ( !dir ) {
00306 return 0;
00307 }
00308
00309 bestd = 0;
00310 best = 0;
00311 for (i=0 ; i<NUMVERTEXNORMALS ; i++)
00312 {
00313 d = DotProduct (dir, bytedirs[i]);
00314 if (d > bestd)
00315 {
00316 bestd = d;
00317 best = i;
00318 }
00319 }
00320
00321 return best;
00322 }
00323
00324 void ByteToDir( int b, vec3_t dir ) {
00325 if ( b < 0 || b >= NUMVERTEXNORMALS ) {
00326 VectorCopy( vec3_origin, dir );
00327 return;
00328 }
00329 VectorCopy (bytedirs[b], dir);
00330 }
00331
00332
00333 unsigned ColorBytes3 (float r, float g, float b) {
00334 unsigned i;
00335
00336 ( (byte *)&i )[0] = r * 255;
00337 ( (byte *)&i )[1] = g * 255;
00338 ( (byte *)&i )[2] = b * 255;
00339
00340 return i;
00341 }
00342
00343 unsigned ColorBytes4 (float r, float g, float b, float a) {
00344 unsigned i;
00345
00346 ( (byte *)&i )[0] = r * 255;
00347 ( (byte *)&i )[1] = g * 255;
00348 ( (byte *)&i )[2] = b * 255;
00349 ( (byte *)&i )[3] = a * 255;
00350
00351 return i;
00352 }
00353
00354 float NormalizeColor( const vec3_t in, vec3_t out ) {
00355 float max;
00356
00357 max = in[0];
00358 if ( in[1] > max ) {
00359 max = in[1];
00360 }
00361 if ( in[2] > max ) {
00362 max = in[2];
00363 }
00364
00365 if ( !max ) {
00366 VectorClear( out );
00367 } else {
00368 out[0] = in[0] / max;
00369 out[1] = in[1] / max;
00370 out[2] = in[2] / max;
00371 }
00372 return max;
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 qboolean PlaneFromPoints( vec4_t plane, const vec3_t a, const vec3_t b, const vec3_t c ) {
00385 vec3_t d1, d2;
00386
00387 VectorSubtract( b, a, d1 );
00388 VectorSubtract( c, a, d2 );
00389 CrossProduct( d2, d1, plane );
00390 if ( VectorNormalize( plane ) == 0 ) {
00391 return qfalse;
00392 }
00393
00394 plane[3] = DotProduct( a, plane );
00395 return qtrue;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405 void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point,
00406 float degrees ) {
00407 float m[3][3];
00408 float im[3][3];
00409 float zrot[3][3];
00410 float tmpmat[3][3];
00411 float rot[3][3];
00412 int i;
00413 vec3_t vr, vup, vf;
00414 float rad;
00415
00416 vf[0] = dir[0];
00417 vf[1] = dir[1];
00418 vf[2] = dir[2];
00419
00420 PerpendicularVector( vr, dir );
00421 CrossProduct( vr, vf, vup );
00422
00423 m[0][0] = vr[0];
00424 m[1][0] = vr[1];
00425 m[2][0] = vr[2];
00426
00427 m[0][1] = vup[0];
00428 m[1][1] = vup[1];
00429 m[2][1] = vup[2];
00430
00431 m[0][2] = vf[0];
00432 m[1][2] = vf[1];
00433 m[2][2] = vf[2];
00434
00435 memcpy( im, m, sizeof( im ) );
00436
00437 im[0][1] = m[1][0];
00438 im[0][2] = m[2][0];
00439 im[1][0] = m[0][1];
00440 im[1][2] = m[2][1];
00441 im[2][0] = m[0][2];
00442 im[2][1] = m[1][2];
00443
00444 memset( zrot, 0, sizeof( zrot ) );
00445 zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F;
00446
00447 rad = DEG2RAD( degrees );
00448 zrot[0][0] = cos( rad );
00449 zrot[0][1] = sin( rad );
00450 zrot[1][0] = -sin( rad );
00451 zrot[1][1] = cos( rad );
00452
00453 MatrixMultiply( m, zrot, tmpmat );
00454 MatrixMultiply( tmpmat, im, rot );
00455
00456 for ( i = 0; i < 3; i++ ) {
00457 dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2];
00458 }
00459 }
00460
00461
00462
00463
00464
00465
00466 void RotateAroundDirection( vec3_t axis[3], float yaw ) {
00467
00468
00469 PerpendicularVector( axis[1], axis[0] );
00470
00471
00472 if ( yaw ) {
00473 vec3_t temp;
00474
00475 VectorCopy( axis[1], temp );
00476 RotatePointAroundVector( axis[1], axis[0], temp, yaw );
00477 }
00478
00479
00480 CrossProduct( axis[0], axis[1], axis[2] );
00481 }
00482
00483
00484
00485 void vectoangles( const vec3_t value1, vec3_t angles ) {
00486 float forward;
00487 float yaw, pitch;
00488
00489 if ( value1[1] == 0 && value1[0] == 0 ) {
00490 yaw = 0;
00491 if ( value1[2] > 0 ) {
00492 pitch = 90;
00493 }
00494 else {
00495 pitch = 270;
00496 }
00497 }
00498 else {
00499 if ( value1[0] ) {
00500 yaw = ( atan2 ( value1[1], value1[0] ) * 180 / M_PI );
00501 }
00502 else if ( value1[1] > 0 ) {
00503 yaw = 90;
00504 }
00505 else {
00506 yaw = 270;
00507 }
00508 if ( yaw < 0 ) {
00509 yaw += 360;
00510 }
00511
00512 forward = sqrt ( value1[0]*value1[0] + value1[1]*value1[1] );
00513 pitch = ( atan2(value1[2], forward) * 180 / M_PI );
00514 if ( pitch < 0 ) {
00515 pitch += 360;
00516 }
00517 }
00518
00519 angles[PITCH] = -pitch;
00520 angles[YAW] = yaw;
00521 angles[ROLL] = 0;
00522 }
00523
00524
00525
00526
00527
00528
00529
00530 void AnglesToAxis( const vec3_t angles, vec3_t axis[3] ) {
00531 vec3_t right;
00532
00533
00534 AngleVectors( angles, axis[0], right, axis[2] );
00535 VectorSubtract( vec3_origin, right, axis[1] );
00536 }
00537
00538 void AxisClear( vec3_t axis[3] ) {
00539 axis[0][0] = 1;
00540 axis[0][1] = 0;
00541 axis[0][2] = 0;
00542 axis[1][0] = 0;
00543 axis[1][1] = 1;
00544 axis[1][2] = 0;
00545 axis[2][0] = 0;
00546 axis[2][1] = 0;
00547 axis[2][2] = 1;
00548 }
00549
00550 void AxisCopy( vec3_t in[3], vec3_t out[3] ) {
00551 VectorCopy( in[0], out[0] );
00552 VectorCopy( in[1], out[1] );
00553 VectorCopy( in[2], out[2] );
00554 }
00555
00556 void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
00557 {
00558 float d;
00559 vec3_t n;
00560 float inv_denom;
00561
00562 inv_denom = DotProduct( normal, normal );
00563 #ifndef Q3_VM
00564 assert( Q_fabs(inv_denom) != 0.0f );
00565 #endif
00566 inv_denom = 1.0f / inv_denom;
00567
00568 d = DotProduct( normal, p ) * inv_denom;
00569
00570 n[0] = normal[0] * inv_denom;
00571 n[1] = normal[1] * inv_denom;
00572 n[2] = normal[2] * inv_denom;
00573
00574 dst[0] = p[0] - d * n[0];
00575 dst[1] = p[1] - d * n[1];
00576 dst[2] = p[2] - d * n[2];
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 void MakeNormalVectors( const vec3_t forward, vec3_t right, vec3_t up) {
00588 float d;
00589
00590
00591
00592 right[1] = -forward[0];
00593 right[2] = forward[1];
00594 right[0] = forward[2];
00595
00596 d = DotProduct (right, forward);
00597 VectorMA (right, -d, forward, right);
00598 VectorNormalize (right);
00599 CrossProduct (right, forward, up);
00600 }
00601
00602
00603 void VectorRotate( vec3_t in, vec3_t matrix[3], vec3_t out )
00604 {
00605 out[0] = DotProduct( in, matrix[0] );
00606 out[1] = DotProduct( in, matrix[1] );
00607 out[2] = DotProduct( in, matrix[2] );
00608 }
00609
00610
00611
00612 #if !idppc
00613
00614
00615
00616 float Q_rsqrt( float number )
00617 {
00618 long i;
00619 float x2, y;
00620 const float threehalfs = 1.5F;
00621
00622 x2 = number * 0.5F;
00623 y = number;
00624 i = * ( long * ) &y;
00625 i = 0x5f3759df - ( i >> 1 );
00626 y = * ( float * ) &i;
00627 y = y * ( threehalfs - ( x2 * y * y ) );
00628
00629
00630 #ifndef Q3_VM
00631 #ifdef __linux__
00632 assert( !isnan(y) );
00633 #endif
00634 #endif
00635 return y;
00636 }
00637
00638 float Q_fabs( float f ) {
00639 int tmp = * ( int * ) &f;
00640 tmp &= 0x7FFFFFFF;
00641 return * ( float * ) &tmp;
00642 }
00643 #endif
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 float LerpAngle (float from, float to, float frac) {
00654 float a;
00655
00656 if ( to - from > 180 ) {
00657 to -= 360;
00658 }
00659 if ( to - from < -180 ) {
00660 to += 360;
00661 }
00662 a = from + frac * (to - from);
00663
00664 return a;
00665 }
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 float AngleSubtract( float a1, float a2 ) {
00676 float a;
00677
00678 a = a1 - a2;
00679 a=fmod(a,360);
00680 while ( a > 180 ) {
00681 a -= 360;
00682 }
00683 while ( a < -180 ) {
00684 a += 360;
00685 }
00686 return a;
00687 }
00688
00689
00690 void AnglesSubtract( vec3_t v1, vec3_t v2, vec3_t v3 ) {
00691 v3[0] = AngleSubtract( v1[0], v2[0] );
00692 v3[1] = AngleSubtract( v1[1], v2[1] );
00693 v3[2] = AngleSubtract( v1[2], v2[2] );
00694 }
00695
00696
00697 float AngleMod(float a) {
00698 a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535);
00699 return a;
00700 }
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710 float AngleNormalize360 ( float angle ) {
00711 return (360.0 / 65536) * ((int)(angle * (65536 / 360.0)) & 65535);
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 float AngleNormalize180 ( float angle ) {
00723 angle = AngleNormalize360( angle );
00724 if ( angle > 180.0 ) {
00725 angle -= 360.0;
00726 }
00727 return angle;
00728 }
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 float AngleDelta ( float angle1, float angle2 ) {
00739 return AngleNormalize180( angle1 - angle2 );
00740 }
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 void SetPlaneSignbits (cplane_t *out) {
00752 int bits, j;
00753
00754
00755 bits = 0;
00756 for (j=0 ; j<3 ; j++) {
00757 if (out->normal[j] < 0) {
00758 bits |= 1<<j;
00759 }
00760 }
00761 out->signbits = bits;
00762 }
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805 #if !( (defined __linux__ || __FreeBSD__) && (defined __i386__) && (!defined C_ONLY)) // rb010123
00806
00807 #if defined __LCC__ || defined C_ONLY || !id386
00808
00809 int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p)
00810 {
00811 float dist1, dist2;
00812 int sides;
00813
00814
00815 if (p->type < 3)
00816 {
00817 if (p->dist <= emins[p->type])
00818 return 1;
00819 if (p->dist >= emaxs[p->type])
00820 return 2;
00821 return 3;
00822 }
00823
00824
00825 switch (p->signbits)
00826 {
00827 case 0:
00828 dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
00829 dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
00830 break;
00831 case 1:
00832 dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
00833 dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
00834 break;
00835 case 2:
00836 dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
00837 dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
00838 break;
00839 case 3:
00840 dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
00841 dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
00842 break;
00843 case 4:
00844 dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
00845 dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
00846 break;
00847 case 5:
00848 dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
00849 dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
00850 break;
00851 case 6:
00852 dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
00853 dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
00854 break;
00855 case 7:
00856 dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
00857 dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
00858 break;
00859 default:
00860 dist1 = dist2 = 0;
00861 break;
00862 }
00863
00864 sides = 0;
00865 if (dist1 >= p->dist)
00866 sides = 1;
00867 if (dist2 < p->dist)
00868 sides |= 2;
00869
00870 return sides;
00871 }
00872 #else
00873 #pragma warning( disable: 4035 )
00874
00875 __declspec( naked ) int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p)
00876 {
00877 static int bops_initialized;
00878 static int Ljmptab[8];
00879
00880 __asm {
00881
00882 push ebx
00883
00884 cmp bops_initialized, 1
00885 je initialized
00886 mov bops_initialized, 1
00887
00888 mov Ljmptab[0*4], offset Lcase0
00889 mov Ljmptab[1*4], offset Lcase1
00890 mov Ljmptab[2*4], offset Lcase2
00891 mov Ljmptab[3*4], offset Lcase3
00892 mov Ljmptab[4*4], offset Lcase4
00893 mov Ljmptab[5*4], offset Lcase5
00894 mov Ljmptab[6*4], offset Lcase6
00895 mov Ljmptab[7*4], offset Lcase7
00896
00897 initialized:
00898
00899 mov edx,dword ptr[4+12+esp]
00900 mov ecx,dword ptr[4+4+esp]
00901 xor eax,eax
00902 mov ebx,dword ptr[4+8+esp]
00903 mov al,byte ptr[17+edx]
00904 cmp al,8
00905 jge Lerror
00906 fld dword ptr[0+edx]
00907 fld st(0)
00908 jmp dword ptr[Ljmptab+eax*4]
00909 Lcase0:
00910 fmul dword ptr[ebx]
00911 fld dword ptr[0+4+edx]
00912 fxch st(2)
00913 fmul dword ptr[ecx]
00914 fxch st(2)
00915 fld st(0)
00916 fmul dword ptr[4+ebx]
00917 fld dword ptr[0+8+edx]
00918 fxch st(2)
00919 fmul dword ptr[4+ecx]
00920 fxch st(2)
00921 fld st(0)
00922 fmul dword ptr[8+ebx]
00923 fxch st(5)
00924 faddp st(3),st(0)
00925 fmul dword ptr[8+ecx]
00926 fxch st(1)
00927 faddp st(3),st(0)
00928 fxch st(3)
00929 faddp st(2),st(0)
00930 jmp LSetSides
00931 Lcase1:
00932 fmul dword ptr[ecx]
00933 fld dword ptr[0+4+edx]
00934 fxch st(2)
00935 fmul dword ptr[ebx]
00936 fxch st(2)
00937 fld st(0)
00938 fmul dword ptr[4+ebx]
00939 fld dword ptr[0+8+edx]
00940 fxch st(2)
00941 fmul dword ptr[4+ecx]
00942 fxch st(2)
00943 fld st(0)
00944 fmul dword ptr[8+ebx]
00945 fxch st(5)
00946 faddp st(3),st(0)
00947 fmul dword ptr[8+ecx]
00948 fxch st(1)
00949 faddp st(3),st(0)
00950 fxch st(3)
00951 faddp st(2),st(0)
00952 jmp LSetSides
00953 Lcase2:
00954 fmul dword ptr[ebx]
00955 fld dword ptr[0+4+edx]
00956 fxch st(2)
00957 fmul dword ptr[ecx]
00958 fxch st(2)
00959 fld st(0)
00960 fmul dword ptr[4+ecx]
00961 fld dword ptr[0+8+edx]
00962 fxch st(2)
00963 fmul dword ptr[4+ebx]
00964 fxch st(2)
00965 fld st(0)
00966 fmul dword ptr[8+ebx]
00967 fxch st(5)
00968 faddp st(3),st(0)
00969 fmul dword ptr[8+ecx]
00970 fxch st(1)
00971 faddp st(3),st(0)
00972 fxch st(3)
00973 faddp st(2),st(0)
00974 jmp LSetSides
00975 Lcase3:
00976 fmul dword ptr[ecx]
00977 fld dword ptr[0+4+edx]
00978 fxch st(2)
00979 fmul dword ptr[ebx]
00980 fxch st(2)
00981 fld st(0)
00982 fmul dword ptr[4+ecx]
00983 fld dword ptr[0+8+edx]
00984 fxch st(2)
00985 fmul dword ptr[4+ebx]
00986 fxch st(2)
00987 fld st(0)
00988 fmul dword ptr[8+ebx]
00989 fxch st(5)
00990 faddp st(3),st(0)
00991 fmul dword ptr[8+ecx]
00992 fxch st(1)
00993 faddp st(3),st(0)
00994 fxch st(3)
00995 faddp st(2),st(0)
00996 jmp LSetSides
00997 Lcase4:
00998 fmul dword ptr[ebx]
00999 fld dword ptr[0+4+edx]
01000 fxch st(2)
01001 fmul dword ptr[ecx]
01002 fxch st(2)
01003 fld st(0)
01004 fmul dword ptr[4+ebx]
01005 fld dword ptr[0+8+edx]
01006 fxch st(2)
01007 fmul dword ptr[4+ecx]
01008 fxch st(2)
01009 fld st(0)
01010 fmul dword ptr[8+ecx]
01011 fxch st(5)
01012 faddp st(3),st(0)
01013 fmul dword ptr[8+ebx]
01014 fxch st(1)
01015 faddp st(3),st(0)
01016 fxch st(3)
01017 faddp st(2),st(0)
01018 jmp LSetSides
01019 Lcase5:
01020 fmul dword ptr[ecx]
01021 fld dword ptr[0+4+edx]
01022 fxch st(2)
01023 fmul dword ptr[ebx]
01024 fxch st(2)
01025 fld st(0)
01026 fmul dword ptr[4+ebx]
01027 fld dword ptr[0+8+edx]
01028 fxch st(2)
01029 fmul dword ptr[4+ecx]
01030 fxch st(2)
01031 fld st(0)
01032 fmul dword ptr[8+ecx]
01033 fxch st(5)
01034 faddp st(3),st(0)
01035 fmul dword ptr[8+ebx]
01036 fxch st(1)
01037 faddp st(3),st(0)
01038 fxch st(3)
01039 faddp st(2),st(0)
01040 jmp LSetSides
01041 Lcase6:
01042 fmul dword ptr[ebx]
01043 fld dword ptr[0+4+edx]
01044 fxch st(2)
01045 fmul dword ptr[ecx]
01046 fxch st(2)
01047 fld st(0)
01048 fmul dword ptr[4+ecx]
01049 fld dword ptr[0+8+edx]
01050 fxch st(2)
01051 fmul dword ptr[4+ebx]
01052 fxch st(2)
01053 fld st(0)
01054 fmul dword ptr[8+ecx]
01055 fxch st(5)
01056 faddp st(3),st(0)
01057 fmul dword ptr[8+ebx]
01058 fxch st(1)
01059 faddp st(3),st(0)
01060 fxch st(3)
01061 faddp st(2),st(0)
01062 jmp LSetSides
01063 Lcase7:
01064 fmul dword ptr[ecx]
01065 fld dword ptr[0+4+edx]
01066 fxch st(2)
01067 fmul dword ptr[ebx]
01068 fxch st(2)
01069 fld st(0)
01070 fmul dword ptr[4+ecx]
01071 fld dword ptr[0+8+edx]
01072 fxch st(2)
01073 fmul dword ptr[4+ebx]
01074 fxch st(2)
01075 fld st(0)
01076 fmul dword ptr[8+ecx]
01077 fxch st(5)
01078 faddp st(3),st(0)
01079 fmul dword ptr[8+ebx]
01080 fxch st(1)
01081 faddp st(3),st(0)
01082 fxch st(3)
01083 faddp st(2),st(0)
01084 LSetSides:
01085 faddp st(2),st(0)
01086 fcomp dword ptr[12+edx]
01087 xor ecx,ecx
01088 fnstsw ax
01089 fcomp dword ptr[12+edx]
01090 and ah,1
01091 xor ah,1
01092 add cl,ah
01093 fnstsw ax
01094 and ah,1
01095 add ah,ah
01096 add cl,ah
01097 pop ebx
01098 mov eax,ecx
01099 ret
01100 Lerror:
01101 int 3
01102 }
01103 }
01104 #pragma warning( default: 4035 )
01105
01106 #endif
01107 #endif
01108
01109
01110
01111
01112
01113
01114 float RadiusFromBounds( const vec3_t mins, const vec3_t maxs ) {
01115 int i;
01116 vec3_t corner;
01117 float a, b;
01118
01119 for (i=0 ; i<3 ; i++) {
01120 a = fabs( mins[i] );
01121 b = fabs( maxs[i] );
01122 corner[i] = a > b ? a : b;
01123 }
01124
01125 return VectorLength (corner);
01126 }
01127
01128
01129 void ClearBounds( vec3_t mins, vec3_t maxs ) {
01130 mins[0] = mins[1] = mins[2] = 99999;
01131 maxs[0] = maxs[1] = maxs[2] = -99999;
01132 }
01133
01134 vec_t DistanceHorizontal( const vec3_t p1, const vec3_t p2 ) {
01135 vec3_t v;
01136
01137 VectorSubtract( p2, p1, v );
01138 return sqrt( v[0]*v[0] + v[1]*v[1] );
01139 }
01140
01141 vec_t DistanceHorizontalSquared( const vec3_t p1, const vec3_t p2 ) {
01142 vec3_t v;
01143
01144 VectorSubtract( p2, p1, v );
01145 return v[0]*v[0] + v[1]*v[1];
01146 }
01147
01148 void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs ) {
01149 if ( v[0] < mins[0] ) {
01150 mins[0] = v[0];
01151 }
01152 if ( v[0] > maxs[0]) {
01153 maxs[0] = v[0];
01154 }
01155
01156 if ( v[1] < mins[1] ) {
01157 mins[1] = v[1];
01158 }
01159 if ( v[1] > maxs[1]) {
01160 maxs[1] = v[1];
01161 }
01162
01163 if ( v[2] < mins[2] ) {
01164 mins[2] = v[2];
01165 }
01166 if ( v[2] > maxs[2]) {
01167 maxs[2] = v[2];
01168 }
01169 }
01170
01171
01172 vec_t VectorNormalize( vec3_t v ) {
01173 float length, ilength;
01174
01175 length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
01176 length = sqrt (length);
01177
01178 if ( length ) {
01179 ilength = 1/length;
01180 v[0] *= ilength;
01181 v[1] *= ilength;
01182 v[2] *= ilength;
01183 }
01184
01185 return length;
01186 }
01187
01188 vec_t VectorNormalize2( const vec3_t v, vec3_t out) {
01189 float length, ilength;
01190
01191 length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
01192 length = sqrt (length);
01193
01194 if (length)
01195 {
01196 #ifndef Q3_VM // bk0101022 - FPE related
01197
01198 #endif
01199 ilength = 1/length;
01200 out[0] = v[0]*ilength;
01201 out[1] = v[1]*ilength;
01202 out[2] = v[2]*ilength;
01203 } else {
01204 #ifndef Q3_VM // bk0101022 - FPE related
01205
01206 #endif
01207 VectorClear( out );
01208 }
01209
01210 return length;
01211
01212 }
01213
01214 void _VectorMA( const vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc) {
01215 vecc[0] = veca[0] + scale*vecb[0];
01216 vecc[1] = veca[1] + scale*vecb[1];
01217 vecc[2] = veca[2] + scale*vecb[2];
01218 }
01219
01220
01221 vec_t _DotProduct( const vec3_t v1, const vec3_t v2 ) {
01222 return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
01223 }
01224
01225 void _VectorSubtract( const vec3_t veca, const vec3_t vecb, vec3_t out ) {
01226 out[0] = veca[0]-vecb[0];
01227 out[1] = veca[1]-vecb[1];
01228 out[2] = veca[2]-vecb[2];
01229 }
01230
01231 void _VectorAdd( const vec3_t veca, const vec3_t vecb, vec3_t out ) {
01232 out[0] = veca[0]+vecb[0];
01233 out[1] = veca[1]+vecb[1];
01234 out[2] = veca[2]+vecb[2];
01235 }
01236
01237 void _VectorCopy( const vec3_t in, vec3_t out ) {
01238 out[0] = in[0];
01239 out[1] = in[1];
01240 out[2] = in[2];
01241 }
01242
01243 void _VectorScale( const vec3_t in, vec_t scale, vec3_t out ) {
01244 out[0] = in[0]*scale;
01245 out[1] = in[1]*scale;
01246 out[2] = in[2]*scale;
01247 }
01248
01249 void Vector4Scale( const vec4_t in, vec_t scale, vec4_t out ) {
01250 out[0] = in[0]*scale;
01251 out[1] = in[1]*scale;
01252 out[2] = in[2]*scale;
01253 out[3] = in[3]*scale;
01254 }
01255
01256
01257 int Q_log2( int val ) {
01258 int answer;
01259
01260 answer = 0;
01261 while ( ( val>>=1 ) != 0 ) {
01262 answer++;
01263 }
01264 return answer;
01265 }
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293 void MatrixMultiply(float in1[3][3], float in2[3][3], float out[3][3]) {
01294 out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
01295 in1[0][2] * in2[2][0];
01296 out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] +
01297 in1[0][2] * in2[2][1];
01298 out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] +
01299 in1[0][2] * in2[2][2];
01300 out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] +
01301 in1[1][2] * in2[2][0];
01302 out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] +
01303 in1[1][2] * in2[2][1];
01304 out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] +
01305 in1[1][2] * in2[2][2];
01306 out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] +
01307 in1[2][2] * in2[2][0];
01308 out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] +
01309 in1[2][2] * in2[2][1];
01310 out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] +
01311 in1[2][2] * in2[2][2];
01312 }
01313
01314
01315 void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) {
01316 float angle;
01317 static float sr, sp, sy, cr, cp, cy;
01318
01319
01320 angle = angles[YAW] * (M_PI*2 / 360);
01321 sy = sin(angle);
01322 cy = cos(angle);
01323 angle = angles[PITCH] * (M_PI*2 / 360);
01324 sp = sin(angle);
01325 cp = cos(angle);
01326 angle = angles[ROLL] * (M_PI*2 / 360);
01327 sr = sin(angle);
01328 cr = cos(angle);
01329
01330 if (forward)
01331 {
01332 forward[0] = cp*cy;
01333 forward[1] = cp*sy;
01334 forward[2] = -sp;
01335 }
01336 if (right)
01337 {
01338 right[0] = (-1*sr*sp*cy+-1*cr*-sy);
01339 right[1] = (-1*sr*sp*sy+-1*cr*cy);
01340 right[2] = -1*sr*cp;
01341 }
01342 if (up)
01343 {
01344 up[0] = (cr*sp*cy+-sr*-sy);
01345 up[1] = (cr*sp*sy+-sr*cy);
01346 up[2] = cr*cp;
01347 }
01348 }
01349
01350
01351
01352
01353 void PerpendicularVector( vec3_t dst, const vec3_t src )
01354 {
01355 int pos;
01356 int i;
01357 float minelem = 1.0F;
01358 vec3_t tempvec;
01359
01360
01361
01362
01363 for ( pos = 0, i = 0; i < 3; i++ )
01364 {
01365 if ( fabs( src[i] ) < minelem )
01366 {
01367 pos = i;
01368 minelem = fabs( src[i] );
01369 }
01370 }
01371 tempvec[0] = tempvec[1] = tempvec[2] = 0.0F;
01372 tempvec[pos] = 1.0F;
01373
01374
01375
01376
01377 ProjectPointOnPlane( dst, tempvec, src );
01378
01379
01380
01381
01382 VectorNormalize( dst );
01383 }
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394 void NormalToLatLong( const vec3_t normal, byte bytes[2] )
01395 {
01396
01397 if (!normal[0] && !normal[1])
01398 {
01399 if ( normal[2] > 0.0f )
01400 {
01401 bytes[0] = 0;
01402 bytes[1] = 0;
01403 }
01404 else
01405 {
01406 bytes[0] = 128;
01407 bytes[1] = 0;
01408 }
01409 }
01410 else
01411 {
01412 int a, b;
01413
01414 a = (int)(RAD2DEG( (vec_t)atan2( normal[1], normal[0] ) ) * (255.0f / 360.0f ));
01415 a &= 0xff;
01416
01417 b = (int)(RAD2DEG( (vec_t)acos( normal[2] ) ) * ( 255.0f / 360.0f ));
01418 b &= 0xff;
01419
01420 bytes[0] = b;
01421 bytes[1] = a;
01422 }
01423 }
01424
01425
01426
01427
01428
01429
01430
01431
01432 static unsigned long holdrand = 0x89abcdef;
01433
01434 void Rand_Init(int seed)
01435 {
01436 holdrand = seed;
01437 }
01438
01439
01440
01441 float flrand(float min, float max)
01442 {
01443 float result;
01444
01445 holdrand = (holdrand * 214013L) + 2531011L;
01446 result = (float)(holdrand >> 17);
01447 result = ((result * (max - min)) / 32768.0F) + min;
01448
01449 return(result);
01450 }
01451 float Q_flrand(float min, float max)
01452 {
01453 return flrand(min,max);
01454 }
01455
01456
01457
01458 int irand(int min, int max)
01459 {
01460 int result;
01461
01462 assert((max - min) < 32768);
01463
01464 max++;
01465 holdrand = (holdrand * 214013L) + 2531011L;
01466 result = holdrand >> 17;
01467 result = ((result * (max - min)) >> 15) + min;
01468 return(result);
01469 }
01470
01471 int Q_irand(int value1, int value2)
01472 {
01473 return irand(value1, value2);
01474 }
01475
01476 float powf ( float x, int y )
01477 {
01478 float r = x;
01479 for ( y--; y>0; y-- )
01480 r = r * r;
01481 return r;
01482 }
01483
01484 #ifdef Q3_VM
01485
01486 double fmod( double x, double y )
01487 {
01488 int result;
01489
01490 if (y == 0.0)
01491 {
01492 return 0.0;
01493 }
01494
01495 result = x / y;
01496
01497 return x - (result * y);
01498 }
01499
01500 #endif // Q3_VM
01501
01502
01503
01504
01505
01506
01507
01508 float DotProductNormalize( const vec3_t inVec1, const vec3_t inVec2 )
01509 {
01510 vec3_t v1, v2;
01511
01512 VectorNormalize2( inVec1, v1 );
01513 VectorNormalize2( inVec2, v2 );
01514
01515 return DotProduct(v1, v2);
01516 }
01517
01518
01519
01520
01521
01522
01523
01524 qboolean G_FindClosestPointOnLineSegment( const vec3_t start, const vec3_t end, const vec3_t from, vec3_t result )
01525 {
01526 vec3_t vecStart2From, vecStart2End, vecEnd2Start, vecEnd2From;
01527 float distEnd2From, distEnd2Result, theta, cos_theta, dot;
01528
01529
01530 VectorSubtract( from, start, vecStart2From);
01531 VectorSubtract( end, start, vecStart2End);
01532
01533 dot = DotProductNormalize( vecStart2From, vecStart2End );
01534
01535 if ( dot <= 0 )
01536 {
01537
01538 VectorCopy( start, result );
01539 return qfalse;
01540 }
01541
01542 if ( dot == 1 )
01543 {
01544
01545 if( (VectorLengthSquared( vecStart2From )) < (VectorLengthSquared( vecStart2End )) )
01546 {
01547 VectorCopy( from, result );
01548 }
01549 else
01550 {
01551 VectorCopy( end, result );
01552 }
01553 return qfalse;
01554 }
01555
01556
01557 VectorSubtract( from, end, vecEnd2From);
01558 VectorSubtract( start, end, vecEnd2Start);
01559
01560 dot = DotProductNormalize( vecEnd2From, vecEnd2Start );
01561
01562 if ( dot <= 0 )
01563 {
01564 VectorCopy( end, result );
01565 return qfalse;
01566 }
01567
01568 if ( dot == 1 )
01569 {
01570 if( (VectorLengthSquared( vecEnd2From )) < (VectorLengthSquared( vecEnd2Start )))
01571 {
01572 VectorCopy( from, result );
01573 }
01574 else
01575 {
01576 VectorCopy( end, result );
01577 }
01578 return qfalse;
01579 }
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591 theta = 90 * (1 - dot);
01592
01593
01594 distEnd2From = VectorLength( vecEnd2From );
01595 cos_theta = cos(DEG2RAD(theta));
01596 distEnd2Result = cos_theta * distEnd2From;
01597
01598
01599 VectorNormalize( vecEnd2Start );
01600 VectorMA( end, distEnd2Result, vecEnd2Start, result );
01601
01602
01603 return qtrue;
01604 }
01605
01606 float G_PointDistFromLineSegment( const vec3_t start, const vec3_t end, const vec3_t from )
01607 {
01608 vec3_t vecStart2From, vecStart2End, vecEnd2Start, vecEnd2From, intersection;
01609 float distEnd2From, distStart2From, distEnd2Result, theta, cos_theta, dot;
01610
01611
01612 VectorSubtract( from, start, vecStart2From);
01613 VectorSubtract( end, start, vecStart2End);
01614 VectorSubtract( from, end, vecEnd2From);
01615 VectorSubtract( start, end, vecEnd2Start);
01616
01617 dot = DotProductNormalize( vecStart2From, vecStart2End );
01618
01619 distStart2From = Distance( start, from );
01620 distEnd2From = Distance( end, from );
01621
01622 if ( dot <= 0 )
01623 {
01624
01625 return distStart2From;
01626 }
01627
01628 if ( dot == 1 )
01629 {
01630
01631 return ((distStart2From<distEnd2From)?distStart2From:distEnd2From);
01632 }
01633
01634
01635
01636 dot = DotProductNormalize( vecEnd2From, vecEnd2Start );
01637
01638 if ( dot <= 0 )
01639 {
01640 return distEnd2From;
01641 }
01642
01643 if ( dot == 1 )
01644 {
01645 return ((distStart2From<distEnd2From)?distStart2From:distEnd2From);
01646 }
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658 theta = 90 * (1 - dot);
01659
01660
01661 cos_theta = cos(DEG2RAD(theta));
01662 distEnd2Result = cos_theta * distEnd2From;
01663
01664
01665 VectorNormalize( vecEnd2Start );
01666 VectorMA( end, distEnd2Result, vecEnd2Start, intersection );
01667
01668
01669 return Distance( intersection, from );
01670 }