00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "../common/common.h"
00027
00028 #ifndef logf
00029 #define logf(x) ((float)log((double)(x)))
00030 #endif
00031
00032 const vec2_t vec2_origin = { 0, 0 };
00033 const vec3_t vec3_origin = { 0, 0, 0 };
00034 const vec4_t vec4_origin = { 0, 0, 0, 0 };
00035
00037 #define RT2 0.70710678118654752440084436210485
00038
00053 const vec4_t dvecs[PATHFINDING_DIRECTIONS] = {
00054 { 1, 0, 0, 0},
00055 {-1, 0, 0, 0},
00056 { 0, 1, 0, 0},
00057 { 0, -1, 0, 0},
00058 { 1, 1, 0, 0},
00059 {-1, -1, 0, 0},
00060 {-1, 1, 0, 0},
00061 { 1, -1, 0, 0},
00062 { 0, 0, 1, 0},
00063 { 0, 0, -1, 0},
00064 { 0, 0, 0, -1},
00065 { 0, 0, 0, 1},
00066 { 0, 0, 0, 0},
00067 { 0, 0, -1, 0},
00068 { 0, 0, 0, 0},
00069 { 0, 0, 0, 0},
00070 { 1, 0, 1, 0},
00071 {-1, 0, 1, 0},
00072 { 0, 1, 1, 0},
00073 { 0, -1, 1, 0},
00074 { 1, 1, 1, 0},
00075 {-1, -1, 1, 0},
00076 {-1, 1, 1, 0},
00077 { 1, -1, 1, 0},
00078 { 1, 0, 0, 0},
00079 {-1, 0, 0, 0},
00080 { 0, 1, 0, 0},
00081 { 0, -1, 0, 0},
00082 { 1, 1, 0, 0},
00083 {-1, -1, 0, 0},
00084 {-1, 1, 0, 0},
00085 { 1, -1, 0, 0},
00086 { 1, 0, -1, 0},
00087 {-1, 0, -1, 0},
00088 { 0, 1, -1, 0},
00089 { 0, -1, -1, 0},
00090 { 1, 1, -1, 0},
00091 {-1, -1, -1, 0},
00092 {-1, 1, -1, 0},
00093 { 1, -1, -1, 0},
00094 };
00095
00096
00097 const float dvecsn[CORE_DIRECTIONS][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1}, {RT2, RT2}, {-RT2, -RT2}, {-RT2, RT2}, {RT2, -RT2} };
00099
00100 const float directionAngles[CORE_DIRECTIONS] = { 0, 180.0f, 90.0f, 270.0f, 45.0f, 225.0f, 135.0f, 315.0f };
00101
00102 const byte dvright[CORE_DIRECTIONS] = { 7, 6, 4, 5, 0, 1, 2, 3 };
00103 const byte dvleft[CORE_DIRECTIONS] = { 4, 5, 6, 7, 2, 3, 1, 0 };
00104
00105
00112 int AngleToDir (int angle)
00113 {
00114 static const int anglesToDV[8] = {0, 4, 2, 6, 1, 5, 3, 7};
00115
00116 angle += 22;
00117
00118 angle %= 360;
00119
00120
00121 if (angle < 0)
00122 angle += 360;
00123
00124
00125 angle /= 45;
00126
00127 if (angle >= 0 && angle < CORE_DIRECTIONS)
00128 return anglesToDV[angle];
00129
00130
00131 Com_Printf("Error in AngleToDV: shouldn't have reached this line\n");
00132 return 0;
00133 }
00134
00138 vec_t Q_rint (const vec_t in)
00139 {
00140
00141 return floor(in + 0.5);
00142 }
00143
00144
00154 float GetDistanceOnGlobe (const vec2_t pos1, const vec2_t pos2)
00155 {
00156
00157 const float latitude1 = pos1[1] * torad;
00158 const float latitude2 = pos2[1] * torad;
00159 const float deltaLongitude = (pos1[0] - pos2[0]) * torad;
00160 float distance;
00161
00162 distance = cos(latitude1) * cos(latitude2) * cos(deltaLongitude) + sin(latitude1) * sin(latitude2);
00163 distance = min(max(-1, distance), 1);
00164 distance = acos(distance) * todeg;
00165
00166 return distance;
00167 }
00168
00172 vec_t ColorNormalize (const vec3_t in, vec3_t out)
00173 {
00174 float max;
00175
00176
00177 max = in[0];
00178 if (in[1] > max)
00179 max = in[1];
00180 if (in[2] > max)
00181 max = in[2];
00182
00183
00184 if (max == 0.0) {
00185 VectorClear(out);
00186 return 0;
00187 }
00188
00189 VectorScale(in, 1.0 / max, out);
00190
00191 return max;
00192 }
00193
00201 qboolean VectorNearer (const vec3_t v1, const vec3_t v2, const vec3_t comp)
00202 {
00203 vec3_t d1, d2;
00204
00205 VectorSubtract(comp, v1, d1);
00206 VectorSubtract(comp, v2, d2);
00207
00208 return VectorLength(d1) < VectorLength(d2);
00209 }
00210
00219 vec_t VectorNormalize2 (const vec3_t v, vec3_t out)
00220 {
00221 float length;
00222
00223 length = DotProduct(v, v);
00224 length = sqrt(length);
00226 if (length) {
00227 const float ilength = 1.0 / length;
00228 out[0] = v[0] * ilength;
00229 out[1] = v[1] * ilength;
00230 out[2] = v[2] * ilength;
00231 }
00232
00233 return length;
00234 }
00235
00243 void VectorMA (const vec3_t veca, const float scale, const vec3_t vecb, vec3_t outVector)
00244 {
00245 outVector[0] = veca[0] + scale * vecb[0];
00246 outVector[1] = veca[1] + scale * vecb[1];
00247 outVector[2] = veca[2] + scale * vecb[2];
00248 }
00249
00250 void VectorClampMA (vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc)
00251 {
00252 int i;
00253
00254
00255 for (i = 0; i < 3; i++)
00256 if (veca[i] > 4094.0)
00257 veca[i] = 4094.0;
00258 else if (veca[i] < -4094.0)
00259 veca[i] = -4094.0;
00260
00261
00262 for (i = 0; i < 3; i++) {
00263 const float test = veca[i] + scale * vecb[i];
00264 if (test < -4095.0f) {
00265 const float newScale = (-4094.0 - veca[i]) / vecb[i];
00266 if (fabs(newScale) < fabs(scale))
00267 scale = newScale;
00268 } else if (test > 4095.0f) {
00269 const float newScale = (4094.0 - veca[i]) / vecb[i];
00270 if (fabs(newScale) < fabs(scale))
00271 scale = newScale;
00272 }
00273 }
00274
00275
00276 VectorMA(veca, scale, vecb, vecc);
00277 }
00278
00286 void MatrixMultiply (const vec3_t a[3], const vec3_t b[3], vec3_t c[3])
00287 {
00288 c[0][0] = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2];
00289 c[0][1] = a[0][1] * b[0][0] + a[1][1] * b[0][1] + a[2][1] * b[0][2];
00290 c[0][2] = a[0][2] * b[0][0] + a[1][2] * b[0][1] + a[2][2] * b[0][2];
00291
00292 c[1][0] = a[0][0] * b[1][0] + a[1][0] * b[1][1] + a[2][0] * b[1][2];
00293 c[1][1] = a[0][1] * b[1][0] + a[1][1] * b[1][1] + a[2][1] * b[1][2];
00294 c[1][2] = a[0][2] * b[1][0] + a[1][2] * b[1][1] + a[2][2] * b[1][2];
00295
00296 c[2][0] = a[0][0] * b[2][0] + a[1][0] * b[2][1] + a[2][0] * b[2][2];
00297 c[2][1] = a[0][1] * b[2][0] + a[1][1] * b[2][1] + a[2][1] * b[2][2];
00298 c[2][2] = a[0][2] * b[2][0] + a[1][2] * b[2][1] + a[2][2] * b[2][2];
00299 }
00300
00307 void GLMatrixAssemble (const vec3_t origin, const vec3_t angles, float* matrix)
00308 {
00309
00310 matrix[3] = matrix[7] = matrix[11] = 0.0;
00311 matrix[15] = 1.0;
00312
00313
00314 AngleVectors(angles, &matrix[0], &matrix[4], &matrix[8]);
00315
00316 VectorInverse(&matrix[4]);
00317
00318
00319 matrix[12] = origin[0];
00320 matrix[13] = origin[1];
00321 matrix[14] = origin[2];
00322 }
00323
00332 void GLMatrixMultiply (const float a[16], const float b[16], float c[16])
00333 {
00334 int i, j, k;
00335
00336 for (j = 0; j < 4; j++) {
00337 k = j * 4;
00338 for (i = 0; i < 4; i++)
00339 c[i + k] = a[i] * b[k] + a[i + 4] * b[k + 1] + a[i + 8] * b[k + 2] + a[i + 12] * b[k + 3];
00340 }
00341 }
00342
00350 void GLVectorTransform (const float m[16], const vec4_t in, vec4_t out)
00351 {
00352 int i;
00353
00354 for (i = 0; i < 4; i++)
00355 out[i] = m[i] * in[0] + m[i + 4] * in[1] + m[i + 8] * in[2] + m[i + 12] * in[3];
00356 }
00357
00367 void VectorRotate (vec3_t m[3], const vec3_t va, vec3_t vb)
00368 {
00369 vb[0] = m[0][0] * va[0] + m[1][0] * va[1] + m[2][0] * va[2];
00370 vb[1] = m[0][1] * va[0] + m[1][1] * va[1] + m[2][1] * va[2];
00371 vb[2] = m[0][2] * va[0] + m[1][2] * va[1] + m[2][2] * va[2];
00372 }
00373
00385 int VectorCompareEps (const vec3_t v1, const vec3_t v2, float epsilon)
00386 {
00387 vec3_t d;
00388
00389 VectorSubtract(v1, v2, d);
00390 d[0] = fabs(d[0]);
00391 d[1] = fabs(d[1]);
00392 d[2] = fabs(d[2]);
00393
00394 if (d[0] > epsilon || d[1] > epsilon || d[2] > epsilon)
00395 return 0;
00396
00397 return 1;
00398 }
00399
00406 vec_t VectorLength (const vec3_t v)
00407 {
00408 return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
00409 }
00410
00419 void VectorMix (const vec3_t v1, const vec3_t v2, float mix, vec3_t out)
00420 {
00421 int i;
00422
00423 for (i = 0; i < 3; i++)
00424 out[i] = v1[i] * (1.0 - mix) + v2[i] * mix;
00425 }
00426
00431 void VectorInverse (vec3_t v)
00432 {
00433 v[0] = -v[0];
00434 v[1] = -v[1];
00435 v[2] = -v[2];
00436 }
00437
00444 void VectorMidpoint (const vec3_t point1, const vec3_t point2, vec3_t midpoint)
00445 {
00446 VectorAdd(point1, point2, midpoint);
00447 VectorScale(midpoint, 0.5f, midpoint);
00448 }
00449
00455 float VectorAngleBetween (const vec3_t vec1, const vec3_t vec2)
00456 {
00457 const float dot = DotProduct(vec1, vec2);
00458 const float angle = acos(dot);
00459 return angle;
00460 }
00461
00462
00463 int Q_log2 (int val)
00464 {
00465 int answer = 0;
00466
00467 while (val >>= 1)
00468 answer++;
00469 return answer;
00470 }
00471
00477 float frand (void)
00478 {
00479 return (rand() & 32767) * (1.0 / 32767);
00480 }
00481
00482
00488 float crand (void)
00489 {
00490 return (rand() & 32767) * (2.0 / 32767) - 1;
00491 }
00492
00500 void gaussrand (float *gauss1, float *gauss2)
00501 {
00502 float x1, x2, w, tmp;
00503
00504 do {
00505 x1 = crand();
00506 x2 = crand();
00507 w = x1 * x1 + x2 * x2;
00508 } while (w >= 1.0);
00509
00510 tmp = -2 * logf(w);
00511 w = sqrt(tmp / w);
00512 *gauss1 = x1 * w;
00513 *gauss2 = x2 * w;
00514 }
00515
00523 void VectorCreateRotationMatrix (const vec3_t angles, vec3_t matrix[3])
00524 {
00525 AngleVectors(angles, matrix[0], matrix[1], matrix[2]);
00526 VectorInverse(matrix[1]);
00527 }
00528
00534 void VectorRotatePoint (vec3_t point, vec3_t matrix[3])
00535 {
00536 vec3_t tvec;
00537
00538 VectorCopy(point, tvec);
00539
00540 point[0] = DotProduct(matrix[0], tvec);
00541 point[1] = DotProduct(matrix[1], tvec);
00542 point[2] = DotProduct(matrix[2], tvec);
00543 }
00544
00562 void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
00563 {
00564 const float anglePitch = angles[PITCH] * torad;
00565 const float sp = sin(anglePitch);
00566 const float cp = cos(anglePitch);
00567 const float angleYaw = angles[YAW] * torad;
00568 const float sy = sin(angleYaw);
00569 const float cy = cos(angleYaw);
00570 const float angleRoll = angles[ROLL] * torad;
00571 const float sr = sin(angleRoll);
00572 const float cr = cos(angleRoll);
00573
00574 if (forward) {
00575 forward[0] = cp * cy;
00576 forward[1] = cp * sy;
00577 forward[2] = -sp;
00578 }
00579 if (right) {
00580 right[0] = (-1 * sr * sp * cy + -1 * cr * -sy);
00581 right[1] = (-1 * sr * sp * sy + -1 * cr * cy);
00582 right[2] = -1 * sr * cp;
00583 }
00584 if (up) {
00585 up[0] = (cr * sp * cy + -sr * -sy);
00586 up[1] = (cr * sp * sy + -sr * cy);
00587 up[2] = cr * cp;
00588 }
00589 }
00590
00597 qboolean FrustumVis (const vec3_t origin, int dir, const vec3_t point)
00598 {
00599
00600 vec3_t delta;
00601 byte dv;
00602
00603 delta[0] = point[0] - origin[0];
00604 delta[1] = point[1] - origin[1];
00605 delta[2] = 0;
00606 VectorNormalize(delta);
00607 dv = dir & (DIRECTIONS - 1);
00608
00609
00610 if ((delta[0] * dvecsn[dv][0] + delta[1] * dvecsn[dv][1]) < 0.5)
00611 return qfalse;
00612 else
00613 return qtrue;
00614 }
00615
00623 static inline void ProjectPointOnPlane (vec3_t dst, const vec3_t point, const vec3_t normal)
00624 {
00625 float distance;
00627 #if 0
00628 vec3_t n;
00629 float inv_denom;
00630
00631
00632 inv_denom = 1.0F / sqrt(DotProduct(normal, normal));
00633 #endif
00634
00635 distance = DotProduct(normal, point);
00636 #if 0
00637 n[0] = normal[0] * inv_denom;
00638 n[1] = normal[1] * inv_denom;
00639 n[2] = normal[2] * inv_denom;
00640 #endif
00641
00642 dst[0] = point[0] - distance * normal[0];
00643 dst[1] = point[1] - distance * normal[1];
00644 dst[2] = point[2] - distance * normal[2];
00645 }
00646
00653 vec_t VectorNormalize (vec3_t v)
00654 {
00655 float length;
00660 if ((length = DotProduct(v, v))) {
00661 const float ilength = 1.0 / (length = sqrtf(length));
00662 v[0] *= ilength;
00663 v[1] *= ilength;
00664 v[2] *= ilength;
00665 }
00666
00667 return length;
00668 }
00669
00680 void PerpendicularVector (vec3_t dst, const vec3_t src)
00681 {
00682 int pos;
00683 int i;
00684 float minelem = 1.0F;
00685 vec3_t tempvec;
00686
00687
00688 for (pos = 0, i = 0; i < 3; i++) {
00689 if (fabs(src[i]) < minelem) {
00690 pos = i;
00691 minelem = fabs(src[i]);
00692 }
00693 }
00694 tempvec[0] = tempvec[1] = tempvec[2] = 0.0F;
00695 tempvec[pos] = 1.0F;
00696
00697
00698 ProjectPointOnPlane(dst, tempvec, src);
00699
00700
00701 VectorNormalize(dst);
00702 }
00703
00719 void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross)
00720 {
00721 cross[0] = v1[1] * v2[2] - v1[2] * v2[1];
00722 cross[1] = v1[2] * v2[0] - v1[0] * v2[2];
00723 cross[2] = v1[0] * v2[1] - v1[1] * v2[0];
00724 }
00725
00726 static inline void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3])
00727 {
00728 out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0];
00729 out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1];
00730 out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2];
00731 out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0];
00732 out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1];
00733 out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2];
00734 out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0];
00735 out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1];
00736 out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2];
00737 }
00738
00748 void RotatePointAroundVector (vec3_t dst, const vec3_t dir, const vec3_t point, float degrees)
00749 {
00750 float m[3][3];
00751 float im[3][3];
00752 float zrot[3][3];
00753 float tmpmat[3][3];
00754 float rot[3][3];
00755 int i;
00756 vec3_t vr, vup, vf;
00757
00758 vf[0] = dir[0];
00759 vf[1] = dir[1];
00760 vf[2] = dir[2];
00761
00762 PerpendicularVector(vr, dir);
00763 CrossProduct(vr, vf, vup);
00764
00765 m[0][0] = vr[0];
00766 m[1][0] = vr[1];
00767 m[2][0] = vr[2];
00768
00769 m[0][1] = vup[0];
00770 m[1][1] = vup[1];
00771 m[2][1] = vup[2];
00772
00773 m[0][2] = vf[0];
00774 m[1][2] = vf[1];
00775 m[2][2] = vf[2];
00776
00777 memcpy(im, m, sizeof(im));
00778
00779 im[0][1] = m[1][0];
00780 im[0][2] = m[2][0];
00781 im[1][0] = m[0][1];
00782 im[1][2] = m[2][1];
00783 im[2][0] = m[0][2];
00784 im[2][1] = m[1][2];
00785
00786 memset(zrot, 0, sizeof(zrot));
00787 zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F;
00788
00789 zrot[0][0] = cos(degrees * torad);
00790 zrot[0][1] = sin(degrees * torad);
00791 zrot[1][0] = -sin(degrees * torad);
00792 zrot[1][1] = cos(degrees * torad);
00793
00794 R_ConcatRotations(m, zrot, tmpmat);
00795 R_ConcatRotations(tmpmat, im, rot);
00796
00797 for (i = 0; i < 3; i++) {
00798 dst[i] = DotProduct(rot[i], point);
00799 }
00800 }
00801
00806 void Print3Vector (const vec3_t v)
00807 {
00808 Com_Printf("(%f, %f, %f)\n", v[0], v[1], v[2]);
00809 }
00810
00815 void Print2Vector (const vec2_t v)
00816 {
00817 Com_Printf("(%f, %f)\n", v[0], v[1]);
00818 }
00819
00827 void PolarToVec (const vec2_t a, vec3_t v)
00828 {
00829 const float p = a[0] * torad;
00830 const float t = a[1] * torad;
00831
00832 VectorSet(v, cos(p) * cos(t), sin(p) * cos(t), sin(t));
00833 }
00834
00839 void VecToPolar (const vec3_t v, vec2_t a)
00840 {
00841 a[0] = todeg * atan2(v[1], v[0]);
00842 a[1] = 90 - todeg * acos(v[2]);
00843 }
00844
00851 void VecToAngles (const vec3_t value1, vec3_t angles)
00852 {
00853 float yaw, pitch;
00854
00855 if (value1[1] == 0 && value1[0] == 0) {
00856 yaw = 0;
00857 if (value1[2] > 0)
00858 pitch = 90;
00859 else
00860 pitch = 270;
00861 } else {
00862 const float forward = sqrt(value1[0] * value1[0] + value1[1] * value1[1]);
00863 if (value1[0])
00864 yaw = (int) (atan2(value1[1], value1[0]) * todeg);
00865 else if (value1[1] > 0)
00866 yaw = 90;
00867 else
00868 yaw = -90;
00869 if (yaw < 0)
00870 yaw += 360;
00871
00872 pitch = (int) (atan2(value1[2], forward) * todeg);
00873 if (pitch < 0)
00874 pitch += 360;
00875 }
00876
00877
00878 angles[PITCH] = -pitch;
00879
00880 angles[YAW] = yaw;
00881
00882 angles[ROLL] = 0;
00883 }
00884
00885
00889 qboolean Q_IsPowerOfTwo (int i)
00890 {
00891 return (i > 0 && !(i & (i - 1)));
00892 }
00893
00898 float LerpAngle (float a2, float a1, float frac)
00899 {
00900 if (a1 - a2 > 180)
00901 a1 -= 360;
00902 if (a1 - a2 < -180)
00903 a1 += 360;
00904 return a2 + frac * (a1 - a2);
00905 }
00906
00912 float AngleNormalize360 (float angle)
00913 {
00914 return (360.0 / 65536) * ((int)(angle * (65536 / 360.0)) & 65535);
00915 }
00916
00921 float AngleNormalize180 (float angle)
00922 {
00923 angle = AngleNormalize360(angle);
00924 if (angle > 180.0)
00925 angle -= 360.0;
00926 return angle;
00927 }
00928
00935 void VectorCenterFromMinsMaxs (const vec3_t mins, const vec3_t maxs, vec3_t center)
00936 {
00937 VectorAdd(mins, maxs, center);
00938 VectorScale(center, 0.5, center);
00939 }
00940
00945 void ClearBounds (vec3_t mins, vec3_t maxs)
00946 {
00947 mins[0] = mins[1] = mins[2] = 99999;
00948 maxs[0] = maxs[1] = maxs[2] = -99999;
00949 }
00950
00955 void AddPointToBounds (const vec3_t v, vec3_t mins, vec3_t maxs)
00956 {
00957 int i;
00958 vec_t val;
00959
00960 for (i = 0; i < 3; i++) {
00961 val = v[i];
00962 if (val < mins[i])
00963 mins[i] = val;
00964 if (val > maxs[i])
00965 maxs[i] = val;
00966 }
00967 }
00968
00973 void TangentVectors (const vec3_t normal, const vec3_t sdir, const vec3_t tdir, vec4_t tangent, vec3_t binormal)
00974 {
00975 vec3_t s, t;
00976
00977
00978 VectorCopy(sdir, s);
00979 VectorNormalize(s);
00980
00981 VectorCopy(tdir, t);
00982 VectorNormalize(t);
00983
00984
00985 VectorMA(s, -DotProduct(s, normal), normal, tangent);
00986 VectorNormalize(tangent);
00987
00988
00989 CrossProduct(normal, tangent, binormal);
00990
00991 if (DotProduct(t, binormal) < 0.0)
00992 tangent[3] = -1.0;
00993 else
00994 tangent[3] = 1.0;
00995
00996 VectorScale(binormal, tangent[3], binormal);
00997 }
00998
01004 void Orthogonalize (vec3_t v1, const vec3_t v2)
01005 {
01006 vec3_t tmp;
01007 VectorMul(DotProduct(v1, v2), v2, tmp);
01008 VectorSubtract(v1, tmp, v1);
01009 VectorNormalize(v1);
01010 }
01011
01017 void MatrixTranspose (const vec3_t m[3], vec3_t t[3])
01018 {
01019 int i, j;
01020
01021 for (i = 0; i < 3; i++) {
01022 for(j = 0; j < 3; j++) {
01023 t[i][j] = m[j][i];
01024 }
01025 }
01026 }