00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00040 #include "omicron/internal.h"
00041 #include <math.h>
00042
00043 const vec3_t vec3_c::vec3x = { 1, 0, 0 };
00044 const vec3_t vec3_c::vec3y = { 0, 1, 0 };
00045 const vec3_t vec3_c::vec3z = { 0, 0, 1 };
00046 const vec3_t vec3_c::vec30 = { 0, 0, 0 };
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 vec3_c vec3_c::project_on_plane
00061 (
00062 const vec3_t normal
00063 )
00064 {
00065 float d;
00066 vec3_c n;
00067 float inv_denom;
00068
00069 AssertReturnValue1(normal, vec3_c());
00070
00071 inv_denom = 1.0f / vec3_c(normal).length_squared();
00072
00073 d = dot(normal) * inv_denom;
00074 n = vec3_c(normal);
00075
00076 return vec3_c(vec[0] - d * n[0], vec[1] - d * n[1], vec[2] - d * n[2]);
00077 }
00078
00079
00080
00081
00082
00083 vec3_c vec3_c::perpendicular
00084 (
00085 )
00086 {
00087 ulong pos;
00088 ulong i;
00089 float minelem = 1.0F;
00090 vec3_t tempvec;
00091 vec3_c res;
00092
00093
00094 for ( pos = 0, i = 0; i < 3; i++ )
00095 {
00096 if ( fabs( vec[i] ) < minelem )
00097 {
00098 pos = i;
00099 minelem = (float)fabs( vec[i] );
00100 }
00101 }
00102
00103 tempvec[0] = tempvec[1] = tempvec[2] = 0.0f;
00104 tempvec[pos] = 1.0f;
00105
00106
00107 res = vec3_c(tempvec).project_on_plane( vec );
00108
00109
00110 return res.normalize();
00111 }
00112
00113
00114
00115
00116 vec3_c vec3_c::rotate_vec
00117 (
00118 float degrees,
00119 const vec3_t dir
00120 )
00121 {
00122 matrix3_t m;
00123 matrix3_t im;
00124 matrix3_t zrot;
00125 matrix3_t tmpmat;
00126 matrix3_t rot;
00127 vec3_c vr, vup;
00128 vec3_t tmp;
00129
00130 AssertReturnValue1(dir, vec3_c());
00131
00132 vr = vec3_c(dir).perpendicular();
00133 vup = vr.cross(dir);
00134
00135 m[0][0] = vr[0]; m[1][0] = vr[1]; m[2][0] = vr[2];
00136 m[0][1] = vup[0]; m[1][1] = vup[1]; m[2][1] = vup[2];
00137 m[0][2] = dir[0]; m[1][2] = dir[1]; m[2][2] = dir[2];
00138
00139 memcpy( im, m, sizeof( im ) );
00140
00141 im[0][1] = m[1][0]; im[0][2] = m[2][0]; im[1][0] = m[0][1];
00142 im[1][2] = m[2][1]; im[2][0] = m[0][2]; im[2][1] = m[1][2];
00143
00144 memset( zrot, 0, sizeof( zrot ) );
00145 zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F;
00146
00147 zrot[0][0] = fcos(DEG2RAD * degrees);
00148 zrot[0][1] = fsin(DEG2RAD * degrees);
00149 zrot[1][0] = -zrot[0][1];
00150 zrot[1][1] = zrot[0][0];
00151
00152 matrix3_mult( m, zrot, tmpmat );
00153 matrix3_mult( tmpmat, im, rot );
00154
00155 tmp[0] = rot[0][0] * vec[0] + rot[0][1] * vec[1] + rot[0][2] * vec[2];
00156 tmp[1] = rot[1][0] * vec[0] + rot[1][1] * vec[1] + rot[1][2] * vec[2];
00157 tmp[2] = rot[2][0] * vec[0] + rot[2][1] * vec[1] + rot[2][2] * vec[2];
00158
00159 return vec3_c(tmp);
00160 }
00161
00162
00163
00164
00165 void vec3_c::get_view_from_angles
00166 (
00167 vec3_c &forward,
00168 vec3_c &right,
00169 vec3_c &up
00170 )
00171 {
00172 float angle;
00173 static float sr, sp, sy, cr, cp, cy;
00174
00175
00176
00177
00178 angle = vec[ANGLE_YAW] * DEG2RAD;
00179 sy = fsin(angle);
00180 cy = fcos(angle);
00181 angle = vec[ANGLE_PITCH] * DEG2RAD;
00182 sp = fsin(angle);
00183 cp = fcos(angle);
00184 angle = vec[ANGLE_ROLL] * DEG2RAD;
00185 sr = fsin(angle);
00186 cr = fcos(angle);
00187
00188 if (forward)
00189 forward.set(cp*cy, cp*sy, -sp);
00190
00191 if (right)
00192 right.set( (-1*sr*sp*cy+-1*cr*-sy), (-1*sr*sp*sy+-1*cr*cy), -1*sr*cp);
00193
00194 if (up)
00195 up.set( (cr*sp*cy+-sr*-sy), (cr*sp*sy+-sr*cy), cr*cp);
00196 }
00197
00198 ushort vec3_c::pack_normal()
00199 {
00200 ulong nx, ny, nz = 0;
00201 nx = (ulong)((vec[0]*63)+63)&127;
00202 ny = (ulong)((vec[1]*63)+63)&127;
00203
00204 if (vec[2]<0)
00205 nz = 0x8000;
00206
00207 return (ushort)((nx << 7) | ny | nz);
00208 }
00209
00210 vec3_c vec3_c::unpack_normal(ushort in)
00211 {
00212 ulong nx, ny, nz;
00213 vec3_c vec;
00214
00215 nx = (in>>7) & 127;
00216 ny = (in) & 127;
00217 nz = in & 0x8000;
00218
00219 vec.set( ((float)nx - 63)/64.0f, ((float)ny - 63)/64.0f, 0);
00220
00221 if (!vec[0] && !vec[1])
00222 vec.set_component(2, 1);
00223 else
00224 vec.set_component(2, (float)sqrt(1-vec.length_squared()));
00225
00226 if (nz)
00227 vec.set_component(2, -vec[2]);
00228
00229 return vec.normalize();
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 vec3_c vec3_c::bezier_spline
00311 (
00312 const spline_t sp,
00313 float frac
00314 )
00315 {
00316 float invfrac = 1-frac;
00317 float b0 = invfrac * invfrac;
00318 float b1 = 2.0f * frac * invfrac;
00319 float b2 = frac * frac;
00320
00321 spline_t spline;
00322
00323 spline[0] = sp[0];
00324 spline[1] = sp[1];
00325 spline[2] = sp[2];
00326
00327 return spline[0] * b0 + spline[1] * b1 + spline[2] * b2;
00328 }
00329
00330 vec3_c vec3_c::bezier_patch
00331 (
00332 const patch_t patch,
00333 float u,
00334 float v
00335 )
00336 {
00337 AssertReturnValue1(patch, vec3_c());
00338
00339 spline_t spline;
00340
00341 spline[0] = bezier_spline(patch[0], u);
00342 spline[1] = bezier_spline(patch[1], u);
00343 spline[2] = bezier_spline(patch[2], u);
00344
00345 return bezier_spline(spline, v);
00346 }
00347
00349
00350 vec3_c::vec3_c()
00351 {
00352 set(0,0,0);
00353 }
00354
00355 vec3_c::vec3_c(const vec3_t v)
00356 {
00357 set(v[0], v[1], v[2]);
00358 }
00359
00360 vec3_c::vec3_c(const vec3_c &v)
00361 {
00362 set(v.vec[0], v.vec[1], v.vec[2]);
00363 }
00364
00365 vec3_c::vec3_c(float x, float y, float z)
00366 {
00367 set(x,y,z);
00368 }
00369
00370 vec3_c::~vec3_c()
00371 {
00372 }
00373
00374 vec3_c::operator const float*()
00375 {
00376 return vec;
00377 }
00378
00379
00380
00381 void vec3_c::set(float x, float y, float z)
00382 {
00383 vec[0] = x;
00384 vec[1] = y;
00385 vec[2] = z;
00386 }
00387
00388 void vec3_c::set_component(int n, float x)
00389 {
00390 vec[n] = x;
00391 }
00392
00393 void vec3_c::clear()
00394 {
00395 set(0,0,0);
00396 }
00397
00398 float vec3_c::length()
00399 {
00400 return (float)sqrt(
00401 vec[VECT_X]*vec[VECT_X] +
00402 vec[VECT_Y]*vec[VECT_Y] +
00403 vec[VECT_Z]*vec[VECT_Z]);
00404 }
00405
00406 float vec3_c::length_squared()
00407 {
00408 return
00409 vec[VECT_X]*vec[VECT_X] +
00410 vec[VECT_Y]*vec[VECT_Y] +
00411 vec[VECT_Z]*vec[VECT_Z];
00412 }
00413
00414 bool vec3_c::operator ==(const vec3_t v)
00415 {
00416 ulong i;
00417
00418 AssertReturnValue1(v, false);
00419
00420 for (i=0 ; ++i<3;)
00421 if (fabs(vec[i]-v[i]) > EQUAL_EPSILON)
00422 return false;
00423
00424 return true;
00425 }
00426
00427
00428
00429
00430
00431
00432 vec3_c operator +(const vec3_t vec, vec3_c v)
00433 {
00434 return vec3_c(v[0]+vec[0], v[1]+vec[1], v[2]+vec[2]);
00435 }
00436
00437 vec3_c vec3_c::operator -(const vec3_t v)
00438 {
00439 return vec3_c(vec[0]-v[0], vec[1]-v[1], vec[2]-v[2]);
00440 }
00441
00442 vec3_c vec3_c::operator *(const float f)
00443 {
00444 return vec3_c(f*vec[0], f*vec[1], f*vec[2]);
00445 }
00446
00447 vec3_c vec3_c::operator *(const vec3_t v)
00448 {
00449 return vec3_c(vec[0]*v[0], vec[1]*v[1], vec[2]*v[2]);
00450 }
00451
00452
00453
00454
00455 vec3_c vec3_c::cross
00456 (
00457 const vec3_t v
00458 )
00459 {
00460 AssertReturnValue1(v, vec3_c(0,0,0));
00461
00462 return vec3_c( vec[VECT_Y]*v[VECT_Z] - vec[VECT_Z]*v[VECT_Y],
00463 vec[VECT_Z]*v[VECT_X] - vec[VECT_X]*v[VECT_Z],
00464 vec[VECT_X]*v[VECT_Y] - vec[VECT_Y]*v[VECT_X]);
00465 }
00466
00467
00468
00469
00470 float vec3_c::dot
00471 (
00472 const vec3_t v
00473 )
00474 {
00475 AssertReturnValue1(v, 0);
00476
00477 return v[VECT_X]*vec[VECT_X] +
00478 v[VECT_Y]*vec[VECT_Y] +
00479 v[VECT_Z]*vec[VECT_Z];
00480 }
00481
00482 vec3_c vec3_c::operator =(const vec3_t v)
00483 {
00484 vec[0] = v[0];
00485 vec[1] = v[1];
00486 vec[2] = v[2];
00487
00488 return *this;
00489 }
00490
00491 vec3_c vec3_c::normalize()
00492 {
00493 return *this * (1/length());
00494 }
00495
00496 vec3_c vec3_c::project()
00497 {
00498 double matModel[16], matProj[16];
00499 int viewport[4];
00500 GLdouble o[3];
00501
00502
00503
00504 glGetDoublev( GL_MODELVIEW_MATRIX, matModel );
00505 glGetDoublev( GL_PROJECTION_MATRIX, matProj );
00506 glGetIntegerv( GL_VIEWPORT, viewport);
00507 gluProject( vec[0], vec[1], vec[2], matModel, matProj, viewport, &o[0], &o[1], &o[2] );
00508
00509 return vec3_c((float)o[0],(float)o[1],(float)o[2]);
00510 }
00511
00512 vec3_c vec3_c::project_ex
00513 (
00514 ulong w,
00515 ulong h
00516 )
00517 {
00518 double matModel[16], matProj[16];
00519 int viewport[4];
00520 GLdouble o[3];
00521
00522 glGetDoublev( GL_MODELVIEW_MATRIX, matModel );
00523 glGetDoublev( GL_PROJECTION_MATRIX, matProj );
00524 viewport[0] = viewport[1] = 0;
00525 viewport[2] = (int)w;
00526 viewport[3] = (int)h;
00527 gluProject( vec[0], vec[1], vec[2], matModel, matProj, viewport, &o[0], &o[1], &o[2] );
00528
00529 return vec3_c((float)o[0],(float)o[1],(float)o[2]);
00530 }
00531
00532 vec3_c vec3_c::unproject()
00533 {
00534 double matModel[16], matProj[16];
00535 int viewport[4];
00536 GLdouble o[3];
00537
00538 glGetDoublev( GL_MODELVIEW_MATRIX, matModel );
00539 glGetDoublev( GL_PROJECTION_MATRIX, matProj );
00540 glGetIntegerv( GL_VIEWPORT, viewport);
00541 gluUnProject( vec[0], vec[1], vec[2], matModel, matProj, viewport, &o[0], &o[1], &o[2] );
00542
00543 return vec3_c((float)o[0],(float)o[1],(float)o[2]);
00544 }
00545
00546
00547
00548
00549
00550 vec3_c vec3_c::unproject_ex(ulong w, ulong h)
00551 {
00552 double matModel[16], matProj[16];
00553 int viewport[4];
00554 GLdouble o[3];
00555
00556 glGetDoublev( GL_MODELVIEW_MATRIX, matModel );
00557 glGetDoublev( GL_PROJECTION_MATRIX, matProj );
00558 viewport[0] = viewport[1] = 0;
00559 viewport[2] = (int)w;
00560 viewport[3] = (int)h;
00561 gluUnProject( vec[0], vec[1], vec[2], matModel, matProj, viewport, &o[0], &o[1], &o[2] );
00562
00563 return vec3_c((float)o[0],(float)o[1],(float)o[2]);
00564 }
00565
00566
00567
00568
00569 vec3_c vec3_c::rotate
00570 (
00571 const vec3_t angles
00572 )
00573 {
00574 float rad;
00575 float radsin;
00576 float radcos;
00577
00578 vec3_t tmp,tmp2;
00579
00580 AssertReturnValue1(angles, vec3_c());
00581
00582 rad = (float)(-angles[ANGLE_ROLL] * DEG2RAD);
00583
00584 radsin = (float)(sin(rad)); radcos = (float)(cos(rad));
00585
00586 tmp2[0] = vec[0]*radcos-vec[2]*radsin;
00587 tmp2[1] = vec[1];
00588 tmp2[2] = vec[0]*radsin+vec[2]*radcos;
00589
00590 rad = (float)(-angles[ANGLE_PITCH] * DEG2RAD);
00591
00592 radsin = (float)(sin(rad)); radcos = (float)(cos(rad));
00593
00594 tmp[0] = tmp2[0];
00595 tmp[2] = tmp2[2]*radcos-vec[1]*radsin;
00596 tmp[1] = tmp2[2]*radsin+vec[1]*radcos;
00597
00598 rad = (float)(-angles[ANGLE_YAW] * DEG2RAD);
00599
00600 radsin = (float)(sin(rad)); radcos = (float)(cos(rad));
00601
00602 return vec3_c( tmp[0]*radcos-tmp[1]*radsin,
00603 tmp[0]*radsin+tmp[1]*radcos,
00604 tmp[2] );
00605 }
00606
00607
00608
00609
00610 vec3_c vec3_c::linear
00611 (
00612 const vec3_t p1,
00613 const vec3_t p2,
00614 float frac
00615 )
00616 {
00617 AssertReturnValue2(p1,p2, vec3_c());
00618
00619 vec3_c vec;
00620
00621 for (ulong i=0; i<3; i++)
00622 vec.set_component(i, _interpolate_float_linear(p1[i], p2[i], frac));
00623
00624 return vec;
00625 }
00626
00627
00628
00629
00630 vec3_c vec3_c::hermite
00631 (
00632 const vec3_t p1,
00633 const vec3_t t1,
00634 const vec3_t p2,
00635 const vec3_t t2,
00636 float frac
00637 )
00638 {
00639 AssertReturnValue4(p1,p2,t1,t2, vec3_c());
00640
00641 vec3_c vec;
00642
00643 float tsquared = frac*frac;
00644 float tsquared3 = tsquared*3;
00645 float tcubed = frac*tsquared;
00646 float tcubed2 = tcubed*2;
00647 float t = frac;
00648
00649 float a = (tcubed2-tsquared3+1);
00650 float b = (tcubed-(2*tsquared)+t);
00651 float c = (tcubed-tsquared);
00652 float d = (-tcubed2+tsquared3);
00653
00654 for (ulong i=0; i<3; i++)
00655 {
00656 float pa = p1[i];
00657 float pb = p2[i];
00658 float ma = t1[i];
00659 float mb = t2[i];
00660
00661 vec.set_component(i, a*pa+b*ma+c*mb+d*pb);
00662 }
00663
00664 return vec;
00665 }