00001 #include "quat.h"
00002
00003 #define DELTA 0.00001
00004
00005 void QUATERNION::LoadMultIdent()
00006 {
00007 w = 1.0f;
00008 x = y = z = 0.0f;
00009 cachematvalid = false;
00010 }
00011
00012 QUATERNION::QUATERNION()
00013 {
00014 LoadMultIdent();
00015 cachematvalid = false;
00016 }
00017
00018 float QUATERNION::Norm()
00019 {
00020 return sqrt(w*w+x*x+y*y+z*z);
00021 }
00022
00023 void QUATERNION::Normalize()
00024 {
00025 cachematvalid = false;
00026
00027 float len = Norm();
00028 w = w / len;
00029 x = x / len;
00030 y = y / len;
00031 z = z / len;
00032 }
00033
00034 void QUATERNION::GetMat(float * destmat)
00035 {
00036 if (!cachematvalid)
00037 {
00038 Normalize();
00039
00040
00041 float xx = x*x;
00042 float xy = x*y;
00043 float xz = x*z;
00044 float xw = x*w;
00045
00046 float yy = y*y;
00047 float yz = y*z;
00048 float yw = y*w;
00049
00050 float zz = z*z;
00051 float zw = z*w;
00052
00053 destmat[0] = 1.0f - 2.0f*(yy+zz);
00054 destmat[1] = 2.0f*(xy+zw);
00055 destmat[2] = 2.0f*(xz-yw);
00056 destmat[3] = 0;
00057
00058 destmat[4] = 2.0f*(xy-zw);
00059 destmat[5] = 1.0f-2.0f*(xx+zz);
00060 destmat[6] = 2.0f*(yz+xw);
00061 destmat[7] = 0;
00062
00063 destmat[8] = 2.0f*(xz+yw);
00064 destmat[9] = 2.0f*(yz-xw);
00065 destmat[10] = 1.0f-2.0f*(xx+yy);
00066 destmat[11] = 0;
00067
00068 destmat[12] = 0;
00069 destmat[13] = 0;
00070 destmat[14] = 0;
00071 destmat[15] = 1;
00072
00073
00074 for (int i = 0; i < 16; i++)
00075 {
00076 cachemat[i] = destmat[i];
00077 }
00078 cachematvalid = true;
00079 }
00080 else
00081 {
00082
00083 for (int i = 0; i < 16; i++)
00084 {
00085 destmat[i] = cachemat[i];
00086 }
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 }
00116
00117 void QUATERNION::GetMat(GLdouble * destmat)
00118 {
00119 if (!cachematvalid)
00120 {
00121 Normalize();
00122
00123
00124 GLdouble xx = x*x;
00125 GLdouble xy = x*y;
00126 GLdouble xz = x*z;
00127 GLdouble xw = x*w;
00128
00129 GLdouble yy = y*y;
00130 GLdouble yz = y*z;
00131 GLdouble yw = y*w;
00132
00133 GLdouble zz = z*z;
00134 GLdouble zw = z*w;
00135
00136 destmat[0] = 1.0f - 2.0f*(yy+zz);
00137 destmat[1] = 2.0f*(xy+zw);
00138 destmat[2] = 2.0f*(xz-yw);
00139 destmat[3] = 0;
00140
00141 destmat[4] = 2.0f*(xy-zw);
00142 destmat[5] = 1.0f-2.0f*(xx+zz);
00143 destmat[6] = 2.0f*(yz+xw);
00144 destmat[7] = 0;
00145
00146 destmat[8] = 2.0f*(xz+yw);
00147 destmat[9] = 2.0f*(yz-xw);
00148 destmat[10] = 1.0f-2.0f*(xx+yy);
00149 destmat[11] = 0;
00150
00151 destmat[12] = 0;
00152 destmat[13] = 0;
00153 destmat[14] = 0;
00154 destmat[15] = 1;
00155
00156
00157 for (int i = 0; i < 16; i++)
00158 {
00159 cachemat[i] = destmat[i];
00160 }
00161 cachematvalid = true;
00162 }
00163 else
00164 {
00165
00166 for (int i = 0; i < 16; i++)
00167 {
00168 destmat[i] = cachemat[i];
00169 }
00170 }
00171 }
00172
00173 void QUATERNION::GetAxisAngle(float * aangle)
00174 {
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 GLfloat len;
00209 GLfloat tx, ty, tz;
00210
00211
00212 tx = x;
00213 ty = y;
00214 tz = z;
00215
00216 len = tx * tx + ty * ty + tz * tz;
00217
00218 if (len > DELTA)
00219 {
00220 aangle[1] = tx * (1.0f / len);
00221 aangle[2] = ty * (1.0f / len);
00222 aangle[3] = tz * (1.0f / len);
00223 aangle[0] = (GLfloat)(2.0 * acos(w));
00224 }
00225
00226 else {
00227 aangle[1] = 0.0;
00228 aangle[2] = 0.0;
00229 aangle[3] = 1.0;
00230 aangle[0] = 0.0;
00231 }
00232 }
00233
00234
00235
00236 void QUATERNION::Multiply(QUATERNION quat2)
00237 {
00238 cachematvalid = false;
00239
00240
00241 float w2 = quat2.w;
00242 float x2 = quat2.x;
00243 float y2 = quat2.y;
00244 float z2 = quat2.z;
00245 w = w*w2 - x*x2 - y*y2 - z*z2;
00246 x = w*x2 + x*w2 + y*z2 - z*y2;
00247 y = w*y2 + y*w2 + z*x2 - x*z2;
00248 z = w*z2 + z*w2 + x*y2 - y*x2;
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 void QUATERNION::PostMultiply(QUATERNION quat2)
00280 {
00281 cachematvalid = false;
00282
00283
00284 float w1 = quat2.w;
00285 float x1 = quat2.x;
00286 float y1 = quat2.y;
00287 float z1 = quat2.z;
00288 float w2 = w;
00289 float x2 = x;
00290 float y2 = y;
00291 float z2 = z;
00292 w = w1*w2 - x1*x2 - y1*y2 - z1*z2;
00293 x = w1*x2 + x1*w2 + y1*z2 - z1*y2;
00294 y = w1*y2 + y1*w2 + z1*x2 - x1*z2;
00295 z = w1*z2 + z1*w2 + x1*y2 - y1*x2;
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 }
00321
00322 QUATERNION QUATERNION::operator* (const QUATERNION &quat2 )
00323 {
00324
00325
00326
00327 QUATERNION qout;
00328
00329
00330 float w2 = quat2.w;
00331 float x2 = quat2.x;
00332 float y2 = quat2.y;
00333 float z2 = quat2.z;
00334 qout.w = w*w2 - x*x2 - y*y2 - z*z2;
00335 qout.x = w*x2 + x*w2 + y*z2 - z*y2;
00336 qout.y = w*y2 + y*w2 + z*x2 - x*z2;
00337 qout.z = w*z2 + z*w2 + x*y2 - y*x2;
00338
00339 return qout;
00340 }
00341
00342
00343 void QUATERNION::SetAxisAngle(float a, float ax, float ay, float az)
00344 {
00345 cachematvalid = false;
00346
00347
00348 float temp = ax*ax + ay*ay + az*az;
00349 float dist = (GLfloat)(1.0 / sqrt(temp));
00350
00351 ax *= dist;
00352 ay *= dist;
00353 az *= dist;
00354
00355
00356
00357
00358
00359
00360 {
00361 float sina2 = sin(a/2);
00362
00363 w = cos(a/2);
00364 x = ax * sina2;
00365 y = ay * sina2;
00366 z = az * sina2;
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 }
00388
00389 void QUATERNION::SetEuler(float a, float b, float c)
00390 {
00391 cachematvalid = false;
00392
00393 QUATERNION qout;
00394
00395 QUATERNION Qx, Qy, Qz;
00396 Qx.w = cos(a/2); Qx.x = sin(a/2); Qx.y = Qx.z = 0.0f;
00397 Qy.w = cos(b/2); Qy.x = Qy.z = 0.0f; Qy.y = sin(b/2);
00398 Qz.w = cos(c/2); Qz.x = Qz.y = 0.0f; Qz.z = sin(c/2);
00399
00400 qout = Qx * Qy * Qz;
00401
00402 *this = qout;
00403 }
00404
00405 QUATERNION QUATERNION::ReturnConjugate()
00406 {
00407 QUATERNION qtemp;
00408 qtemp.w = w;
00409 qtemp.x = -x;
00410 qtemp.y = -y;
00411 qtemp.z = -z;
00412 return qtemp;
00413 }
00414
00415 void QUATERNION::LookAt(float eyeX,
00416 float eyeY,
00417 float eyeZ,
00418 float centerX,
00419 float centerY,
00420 float centerZ,
00421 float upX,
00422 float upY,
00423 float upZ)
00424 {
00425 float tempmat[16];
00426
00427 glPushMatrix();
00428 glLoadIdentity();
00429 gluLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
00430 glGetFloatv(GL_MODELVIEW_MATRIX , tempmat);
00431 glPopMatrix();
00432
00433 SetMat(tempmat);
00434 }
00435
00436 void QUATERNION::SetMat(float * mat)
00437 {
00438 float S;
00439
00440 float T = 1 + mat[0] + mat[5] + mat[10];
00441 if ( T > 0.00000001 )
00442 {
00443 S = sqrt(T) * 2;
00444 x = ( mat[9] - mat[6] ) / S;
00445 y = ( mat[2] - mat[8] ) / S;
00446 z = ( mat[4] - mat[1] ) / S;
00447 w = 0.25 * S;
00448 }
00449 else
00450 {
00451 if ( mat[0] > mat[5] && mat[0] > mat[10] ) {
00452 S = sqrt( 1.0 + mat[0] - mat[5] - mat[10] ) * 2;
00453 x = 0.25 * S;
00454 y = (mat[4] + mat[1] ) / S;
00455 z = (mat[2] + mat[8] ) / S;
00456 w = (mat[9] - mat[6] ) / S;
00457 } else if ( mat[5] > mat[10] ) {
00458 S = sqrt( 1.0 + mat[5] - mat[0] - mat[10] ) * 2;
00459 x = (mat[4] + mat[1] ) / S;
00460 y = 0.25 * S;
00461 z = (mat[9] + mat[6] ) / S;
00462 w = (mat[2] - mat[8] ) / S;
00463 } else {
00464 S = sqrt( 1.0 + mat[10] - mat[0] - mat[5] ) * 2;
00465 x = (mat[2] + mat[8] ) / S;
00466 y = (mat[9] + mat[6] ) / S;
00467 z = 0.25 * S;
00468 w = (mat[4] - mat[1] ) / S;
00469 }
00470 }
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 VERTEX QUATERNION::RotateVec(VERTEX vec)
00483 {
00484 QUATERNION dirconj;
00485
00486 QUATERNION dir;
00487 dir.w = w;
00488 dir.x = x;
00489 dir.y = y;
00490 dir.z = z;
00491
00492 dirconj = dir.ReturnConjugate();
00493 QUATERNION qtemp;
00494 qtemp.w = 0;
00495 qtemp.x = vec.x;
00496 qtemp.y = vec.y;
00497 qtemp.z = vec.z;
00498 QUATERNION qout;
00499 qout = dir * qtemp * dirconj;
00500
00501 VERTEX vout;
00502
00503 vout.x += qout.x;
00504 vout.y += qout.y;
00505 vout.z += qout.z;
00506
00507 return vout;
00508 }
00509
00510 float QUATERNION::GetAngleBetween(QUATERNION quat2)
00511 {
00512
00513 VERTEX forward;
00514 forward.x = 0;
00515 forward.y = 0;
00516 forward.z = 1;
00517
00518
00519 VERTEX vec1, vec2;
00520 vec1 = RotateVec(forward);
00521 vec2 = quat2.RotateVec(forward);
00522
00523
00524 return acos(vec1.dot(vec2));
00525 }
00526
00527 VERTEX QUATERNION::GetEuler()
00528 {
00529 VERTEX vout;
00530 QUATERNION q1 = *this;
00531
00532 float sqw = q1.w*q1.w;
00533 float sqx = q1.x*q1.x;
00534 float sqy = q1.y*q1.y;
00535 float sqz = q1.z*q1.z;
00536
00537 vout.z = atan(2.0 * (q1.x*q1.y + q1.z*q1.w)/(sqx - sqy - sqz + sqw));
00538 vout.x = atan(2.0 * (q1.y*q1.z + q1.x*q1.w)/(-sqx - sqy + sqz + sqw));
00539 vout.y = asin(-2.0 * (q1.x*q1.z - q1.y*q1.w));
00540
00541 return vout;
00542 }
00543
00544 QUATERNION QUATERNION::Slerp(QUATERNION quat2, float t)
00545 {
00546 QUATERNION qout, p1, p2;
00547 float theta = GetAngleBetween(quat2);
00548
00549
00550
00551 p1 = (*this).MultScalar((sin((1.0f-t)*theta))/sin(theta));
00552 p2 = quat2.MultScalar(sin(theta*t)/sinh(theta));
00553 qout = p1.Add(p2);
00554
00555
00556 return qout;
00557 }
00558
00559 QUATERNION QUATERNION::Add(QUATERNION quat2)
00560 {
00561 QUATERNION qout;
00562
00563 qout.w = w + quat2.w;
00564 qout.x = x + quat2.x;
00565 qout.y = y + quat2.y;
00566 qout.z = z + quat2.z;
00567
00568 return qout;
00569 }
00570
00571 QUATERNION QUATERNION::MultScalar(float scalar)
00572 {
00573 QUATERNION qout;
00574
00575 qout.w = w * scalar;
00576 qout.x = x * scalar;
00577 qout.y = y * scalar;
00578 qout.z = z * scalar;
00579
00580 return qout;
00581 }
00582
00583 QUATERNION QUATERNION::QuatSlerp(QUATERNION quat2, float t)
00584 {
00585 float to1[4];
00586 float omega, cosom, sinom, scale0, scale1;
00587
00588
00589
00590 cosom = x * quat2.x + y * quat2.y + z * quat2.z
00591 + w * quat2.w;
00592
00593
00594
00595 if ( cosom <0.0 ){ cosom = -cosom; to1[0] = - quat2.x;
00596 to1[1] = - quat2.y;
00597 to1[2] = - quat2.z;
00598 to1[3] = - quat2.w;
00599 } else {
00600 to1[0] = quat2.x;
00601 to1[1] = quat2.y;
00602 to1[2] = quat2.z;
00603 to1[3] = quat2.w;
00604 }
00605
00606
00607
00608
00609
00610 if ( (1.0 - cosom) > DELTA ) {
00611
00612 omega = acos(cosom);
00613 sinom = sin(omega);
00614 scale0 = sin((1.0 - t) * omega) / sinom;
00615 scale1 = sin(t * omega) / sinom;
00616
00617
00618 } else {
00619
00620
00621 scale0 = 1.0 - t;
00622 scale1 = t;
00623 }
00624
00625 QUATERNION qout;
00626 qout.x = scale0 * x + scale1 * to1[0];
00627 qout.y = scale0 * y + scale1 * to1[1];
00628 qout.z = scale0 * z + scale1 * to1[2];
00629 qout.w = scale0 * w + scale1 * to1[3];
00630 return qout;
00631 }
00632
00633
00634 void QUATERNION::Rotate(float a, float ax, float ay, float az)
00635 {
00636
00637
00638 QUATERNION qtemp;
00639 qtemp.SetAxisAngle(a, ax, ay, az);
00640 PostMultiply(qtemp);
00641 }
00642
00643 void QUATERNION::DebugPrint()
00644 {
00645 cout << x << "," << y << "," << z << "," << w << endl;
00646 }
00647
00648 VERTEX VERTEX::operator+ (VERTEX v)
00649 {
00650 VERTEX result;
00651
00652 result.x = x + v.x;
00653 result.y = y + v.y;
00654 result.z = z + v.z;
00655
00656 return result;
00657 }
00658
00659 VERTEX VERTEX::operator- (VERTEX v)
00660 {
00661 VERTEX result;
00662
00663 result.x = x - v.x;
00664 result.y = y - v.y;
00665 result.z = z - v.z;
00666
00667 return result;
00668 }
00669
00670 void VERTEX::Set(float nx, float ny, float nz)
00671 {
00672 x = nx;
00673 y = ny;
00674 z = nz;
00675 }
00676
00677 float VERTEX::len()
00678 {
00679
00680 if (x == 0 && y == 0 && z == 0)
00681 return 0;
00682
00683 float sl = x*x+y*y+z*z;
00684
00685 if (sl < 0)
00686 {
00687 ofstream err((settings.GetSettingsDir() + "/logs/vertex.log").c_str());
00688 err << x << endl << y << endl << z << endl << sl << endl;
00689 err.close();
00690 assert(0);
00691 }
00692 else if (sl >=0 )
00693 {
00694 return sqrt(sl);
00695 }
00696 else
00697 {
00698
00699 if (!(x < 0 || x >= 0))
00700 x = 1;
00701 if (!(y < 0 || y >= 0))
00702 y = 1;
00703 if (!(z < 0 || z >= 0))
00704 z = 1;
00705 sl = x*x+y*y+z*z;
00706
00707 if (!(sl >= 0))
00708 {
00709 ofstream err((settings.GetSettingsDir() + "/logs/vertex.log").c_str());
00710 err << x << endl << y << endl << z << endl << sl << endl;
00711 err.close();
00712 assert(0);
00713 return 0;
00714 }
00715 else
00716 return sqrt(sl);
00717 }
00718 }
00719
00720 VERTEX VERTEX::cross(VERTEX b)
00721 {
00722 VERTEX result;
00723
00724 result.x = y*b.z - z*b.y;
00725
00726 result.y = z*b.x - x*b.z;
00727 result.z = x*b.y - y*b.x;
00728
00729 return result;
00730 }
00731
00732 VERTEX VERTEX::normalize()
00733 {
00734 VERTEX new_vec;
00735 float vec_len = len();
00736
00737 if (vec_len == 0.0f)
00738 {
00739 new_vec.x = 0.0f;
00740 new_vec.y = 0.0f;
00741 new_vec.z = 0.0f;
00742 return new_vec;
00743 }
00744
00745 float inv_vec_len = 1.0f/vec_len;
00746
00747 new_vec.x = x*inv_vec_len;
00748 new_vec.y = y*inv_vec_len;
00749 new_vec.z = z*inv_vec_len;
00750
00751 return new_vec;
00752 }
00753
00754 VERTEX::VERTEX()
00755 {
00756 x = y = z = 0.0f;
00757 }
00758
00759 void VERTEX::Scale(float scalar)
00760 {
00761 x = x*scalar;
00762 y = y*scalar;
00763 z = z*scalar;
00764 }
00765
00766 VERTEX VERTEX::ScaleR(float scalar)
00767 {
00768 VERTEX result;
00769
00770 result.x = x*scalar;
00771 result.y = y*scalar;
00772 result.z = z*scalar;
00773
00774 return result;
00775 }
00776
00777 VERTEX VERTEX::InvertR()
00778 {
00779 VERTEX result;
00780
00781 result.x = -x;
00782 result.y = -y;
00783 result.z = -z;
00784
00785 return result;
00786 }
00787
00788 float VERTEX::dot(VERTEX b)
00789 {
00790 return x*b.x + y*b.y + z*b.z;
00791 }
00792
00793 VERTEX VERTEX::interpolatewith(VERTEX other, float percent)
00794 {
00795 VERTEX vout;
00796
00797 vout.x = (other.x - x)*percent + x;
00798 vout.y = (other.y - y)*percent + y;
00799 vout.z = (other.z - z)*percent + z;
00800
00801 return vout;
00802 }
00803
00804 float * VERTEX::v3()
00805 {
00806 float3[0] = x;
00807 float3[1] = y;
00808 float3[2] = z;
00809
00810 return float3;
00811 }
00812
00813 void VERTEX::DebugPrint(ostream & out)
00814 {
00815 out << x << "," << y << "," << z << endl;
00816 }
00817
00818 void VERTEX::zero()
00819 {
00820 x = y = z = 0.0f;
00821 }
00822
00823 void VERTEX::Set(float * f3)
00824 {
00825 x = f3[0];
00826 y = f3[1];
00827 z = f3[2];
00828 }
00829
00830 bool VERTEX::nan()
00831 {
00832 if (!(x < 0 || x >= 0) || !(y < 0 || y >= 0) || !(z < 0 || z >= 0))
00833 return true;
00834
00835 return false;
00836 }
00837
00838 bool VERTEX::equals(VERTEX other)
00839 {
00840 return (x == other.x && y == other.y && z == other.z);
00841 }
00842
00843 VERTEX QUATERNION::RelativeMove(VERTEX input)
00844 {
00845 QUATERNION dirconj, dir;
00846 VERTEX position;
00847
00848 dirconj = ReturnConjugate();
00849 dir.w = w;
00850 dir.x = x;
00851 dir.y = y;
00852 dir.z = z;
00853 QUATERNION qtemp;
00854 qtemp.w = 0;
00855 qtemp.x = input.x;
00856 qtemp.y = input.y;
00857 qtemp.z = input.z;
00858 QUATERNION qout;
00859 qout = dirconj * qtemp * dir;
00860
00861 position.x = qout.x;
00862 position.y = qout.y;
00863 position.z = qout.z;
00864 return position;
00865 }
00866
00867 void MATRIX3::ProjectionMatrix(VERTEX normal)
00868 {
00869 float a = normal.x;
00870 float b = normal.y;
00871 float c = normal.z;
00872
00873 row[0].x = b*b+c*c;
00874 row[0].y = -a*b;
00875 row[0].z = -a*c;
00876
00877 row[1].x = -b*a;
00878 row[1].y = a*a+c*c;
00879 row[1].z = -b*c;
00880
00881 row[2].x = -c*a;
00882 row[2].y = -c*b;
00883 row[2].z = a*a+b*b;
00884 }
00885
00886 VERTEX MATRIX3::Multiply(VERTEX vert)
00887 {
00888 VERTEX out;
00889
00890
00891
00892
00893
00894
00895 out.x = row[0].dot(vert);
00896 out.y = row[1].dot(vert);
00897 out.z = row[2].dot(vert);
00898
00899 return out;
00900 }
00901
00902
00903 VERTEXD VERTEXD::operator+ (VERTEXD v)
00904 {
00905 VERTEXD result;
00906
00907 result.x = x + v.x;
00908 result.y = y + v.y;
00909 result.z = z + v.z;
00910
00911 return result;
00912 }
00913
00914 VERTEXD VERTEXD::operator- (VERTEXD v)
00915 {
00916 VERTEXD result;
00917
00918 result.x = x - v.x;
00919 result.y = y - v.y;
00920 result.z = z - v.z;
00921
00922 return result;
00923 }
00924
00925 void VERTEXD::Set(double nx, double ny, double nz)
00926 {
00927 x = nx;
00928 y = ny;
00929 z = nz;
00930 }
00931
00932 double VERTEXD::len()
00933 {
00934
00935 if (x == 0 && y == 0 && z == 0)
00936 return 0;
00937
00938 double sl = x*x+y*y+z*z;
00939
00940 if (sl < 0)
00941 {
00942 ofstream err((settings.GetSettingsDir() + "/logs/vertex.log").c_str());
00943 err << x << endl << y << endl << z << endl << sl << endl;
00944 err.close();
00945 assert(0);
00946 }
00947 else if (sl >=0 )
00948 {
00949 return sqrt(sl);
00950 }
00951 else
00952 {
00953
00954 if (!(x < 0 || x >= 0))
00955 x = 1;
00956 if (!(y < 0 || y >= 0))
00957 y = 1;
00958 if (!(z < 0 || z >= 0))
00959 z = 1;
00960 sl = x*x+y*y+z*z;
00961
00962 if (!(sl >= 0))
00963 {
00964 ofstream err((settings.GetSettingsDir() + "/logs/vertex.log").c_str());
00965 err << x << endl << y << endl << z << endl << sl << endl;
00966 err.close();
00967 assert(0);
00968 return 0;
00969 }
00970 else
00971 return sqrt(sl);
00972 }
00973 }
00974
00975 VERTEXD VERTEXD::cross(VERTEXD b)
00976 {
00977 VERTEXD result;
00978
00979 result.x = y*b.z - z*b.y;
00980
00981 result.y = z*b.x - x*b.z;
00982 result.z = x*b.y - y*b.x;
00983
00984 return result;
00985 }
00986
00987 VERTEXD VERTEXD::normalize()
00988 {
00989 VERTEXD new_vec;
00990 double vec_len = len();
00991
00992 if (vec_len == 0.0f)
00993 {
00994 new_vec.x = 0.0f;
00995 new_vec.y = 0.0f;
00996 new_vec.z = 0.0f;
00997 return new_vec;
00998 }
00999
01000 new_vec.x = x/vec_len;
01001 new_vec.y = y/vec_len;
01002 new_vec.z = z/vec_len;
01003
01004 return new_vec;
01005 }
01006
01007 VERTEXD::VERTEXD()
01008 {
01009 x = y = z = 0.0f;
01010 }
01011
01012 void VERTEXD::Scale(double scalar)
01013 {
01014 x = x*scalar;
01015 y = y*scalar;
01016 z = z*scalar;
01017 }
01018
01019 VERTEXD VERTEXD::ScaleR(double scalar)
01020 {
01021 VERTEXD result;
01022
01023 result.x = x*scalar;
01024 result.y = y*scalar;
01025 result.z = z*scalar;
01026
01027 return result;
01028 }
01029
01030 VERTEXD VERTEXD::InvertR()
01031 {
01032 VERTEXD result;
01033
01034 result.x = -x;
01035 result.y = -y;
01036 result.z = -z;
01037
01038 return result;
01039 }
01040
01041 double VERTEXD::dot(VERTEXD b)
01042 {
01043 return x*b.x + y*b.y + z*b.z;
01044 }
01045
01046 VERTEXD VERTEXD::interpolatewith(VERTEXD other, double percent)
01047 {
01048 VERTEXD vout;
01049
01050 vout.x = (other.x - x)*percent + x;
01051 vout.y = (other.y - y)*percent + y;
01052 vout.z = (other.z - z)*percent + z;
01053
01054 return vout;
01055 }
01056
01057 double * VERTEXD::v3()
01058 {
01059 double3[0] = x;
01060 double3[1] = y;
01061 double3[2] = z;
01062
01063 return double3;
01064 }
01065
01066 void VERTEXD::DebugPrint()
01067 {
01068 cout << x << "," << y << "," << z << endl;
01069 }
01070
01071 void VERTEXD::zero()
01072 {
01073 x = y = z = 0.0f;
01074 }
01075
01076 void VERTEXD::Set(double * f3)
01077 {
01078 x = f3[0];
01079 y = f3[1];
01080 z = f3[2];
01081 }
01082
01083 void VERTEXD::Set(float * f3)
01084 {
01085 x = f3[0];
01086 y = f3[1];
01087 z = f3[2];
01088 }
01089
01090 bool VERTEXD::nan()
01091 {
01092 if (!(x < 0 || x >= 0) || !(y < 0 || y >= 0) || !(z < 0 || z >= 0))
01093 return true;
01094
01095 return false;
01096 }
01097
01098 VERTEXD::VERTEXD(VERTEX other)
01099 {
01100 x = other.x;
01101 y = other.y;
01102 z = other.z;
01103 }
01104
01105 VERTEXD& VERTEXD:: operator= (const VERTEX & other)
01106 {
01107 x = other.x;
01108 y = other.y;
01109 z = other.