00001
00032 #include "linden_common.h"
00033
00034
00035 #include "v3math.h"
00036 #include "m3math.h"
00037 #include "v4math.h"
00038 #include "m4math.h"
00039 #include "llquaternion.h"
00040 #include "llcoordframe.h"
00041
00042 #ifndef X_AXIS
00043 #define X_AXIS 1.0f,0.0f,0.0f
00044 #define Y_AXIS 0.0f,1.0f,0.0f
00045 #define Z_AXIS 0.0f,0.0f,1.0f
00046 #endif
00047
00048
00049
00050 LLCoordFrame::LLCoordFrame() :
00051 mOrigin(0.f, 0.f, 0.f),
00052 mXAxis(X_AXIS),
00053 mYAxis(Y_AXIS),
00054 mZAxis(Z_AXIS)
00055 {
00056 }
00057
00058 LLCoordFrame::LLCoordFrame(const LLVector3 &origin) :
00059 mOrigin(origin),
00060 mXAxis(X_AXIS),
00061 mYAxis(Y_AXIS),
00062 mZAxis(Z_AXIS)
00063 {
00064 if( !mOrigin.isFinite() )
00065 {
00066 reset();
00067 llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
00068 }
00069 }
00070
00071 LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLVector3 &direction) :
00072 mOrigin(origin)
00073 {
00074 lookDir(direction);
00075
00076 if( !isFinite() )
00077 {
00078 reset();
00079 llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
00080 }
00081 }
00082
00083 LLCoordFrame::LLCoordFrame(const LLVector3 &x_axis,
00084 const LLVector3 &y_axis,
00085 const LLVector3 &z_axis) :
00086 mOrigin(0.f, 0.f, 0.f),
00087 mXAxis(x_axis),
00088 mYAxis(y_axis),
00089 mZAxis(z_axis)
00090 {
00091 if( !isFinite() )
00092 {
00093 reset();
00094 llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
00095 }
00096 }
00097
00098 LLCoordFrame::LLCoordFrame(const LLVector3 &origin,
00099 const LLVector3 &x_axis,
00100 const LLVector3 &y_axis,
00101 const LLVector3 &z_axis) :
00102 mOrigin(origin),
00103 mXAxis(x_axis),
00104 mYAxis(y_axis),
00105 mZAxis(z_axis)
00106 {
00107 if( !isFinite() )
00108 {
00109 reset();
00110 llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
00111 }
00112 }
00113
00114
00115 LLCoordFrame::LLCoordFrame(const LLVector3 &origin,
00116 const LLMatrix3 &rotation) :
00117 mOrigin(origin),
00118 mXAxis(rotation.mMatrix[VX]),
00119 mYAxis(rotation.mMatrix[VY]),
00120 mZAxis(rotation.mMatrix[VZ])
00121 {
00122 if( !isFinite() )
00123 {
00124 reset();
00125 llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
00126 }
00127 }
00128
00129 LLCoordFrame::LLCoordFrame(const LLQuaternion &q) :
00130 mOrigin(0.f, 0.f, 0.f)
00131 {
00132 LLMatrix3 rotation_matrix(q);
00133 mXAxis.setVec(rotation_matrix.mMatrix[VX]);
00134 mYAxis.setVec(rotation_matrix.mMatrix[VY]);
00135 mZAxis.setVec(rotation_matrix.mMatrix[VZ]);
00136
00137 if( !isFinite() )
00138 {
00139 reset();
00140 llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
00141 }
00142 }
00143
00144 LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLQuaternion &q) :
00145 mOrigin(origin)
00146 {
00147 LLMatrix3 rotation_matrix(q);
00148 mXAxis.setVec(rotation_matrix.mMatrix[VX]);
00149 mYAxis.setVec(rotation_matrix.mMatrix[VY]);
00150 mZAxis.setVec(rotation_matrix.mMatrix[VZ]);
00151
00152 if( !isFinite() )
00153 {
00154 reset();
00155 llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
00156 }
00157 }
00158
00159 LLCoordFrame::LLCoordFrame(const LLMatrix4 &mat) :
00160 mOrigin(mat.mMatrix[VW]),
00161 mXAxis(mat.mMatrix[VX]),
00162 mYAxis(mat.mMatrix[VY]),
00163 mZAxis(mat.mMatrix[VZ])
00164 {
00165 if( !isFinite() )
00166 {
00167 reset();
00168 llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
00169 }
00170 }
00171
00172
00173
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 void LLCoordFrame::reset()
00206 {
00207 mOrigin.setVec(0.0f, 0.0f, 0.0f);
00208 resetAxes();
00209 }
00210
00211
00212 void LLCoordFrame::resetAxes()
00213 {
00214 mXAxis.setVec(1.0f, 0.0f, 0.0f);
00215 mYAxis.setVec(0.0f, 1.0f, 0.0f);
00216 mZAxis.setVec(0.0f, 0.0f, 1.0f);
00217 }
00218
00219
00220
00221 void LLCoordFrame::setOrigin(F32 x, F32 y, F32 z)
00222 {
00223 mOrigin.setVec(x, y, z);
00224
00225 if( !mOrigin.isFinite() )
00226 {
00227 reset();
00228 llwarns << "Non Finite in LLCoordFrame::setOrigin()" << llendl;
00229 }
00230 }
00231
00232 void LLCoordFrame::setOrigin(const LLVector3 &new_origin)
00233 {
00234 mOrigin = new_origin;
00235 if( !mOrigin.isFinite() )
00236 {
00237 reset();
00238 llwarns << "Non Finite in LLCoordFrame::setOrigin()" << llendl;
00239 }
00240 }
00241
00242 void LLCoordFrame::setOrigin(const F32 *origin)
00243 {
00244 mOrigin.mV[VX] = *(origin + VX);
00245 mOrigin.mV[VY] = *(origin + VY);
00246 mOrigin.mV[VZ] = *(origin + VZ);
00247
00248 if( !mOrigin.isFinite() )
00249 {
00250 reset();
00251 llwarns << "Non Finite in LLCoordFrame::setOrigin()" << llendl;
00252 }
00253 }
00254
00255 void LLCoordFrame::setOrigin(const LLCoordFrame &frame)
00256 {
00257 mOrigin = frame.getOrigin();
00258
00259 if( !mOrigin.isFinite() )
00260 {
00261 reset();
00262 llwarns << "Non Finite in LLCoordFrame::setOrigin()" << llendl;
00263 }
00264 }
00265
00266
00267
00268
00269 void LLCoordFrame::setAxes(const LLVector3 &x_axis,
00270 const LLVector3 &y_axis,
00271 const LLVector3 &z_axis)
00272 {
00273 mXAxis = x_axis;
00274 mYAxis = y_axis;
00275 mZAxis = z_axis;
00276 if( !isFinite() )
00277 {
00278 reset();
00279 llwarns << "Non Finite in LLCoordFrame::setAxes()" << llendl;
00280 }
00281 }
00282
00283
00284 void LLCoordFrame::setAxes(const LLMatrix3 &rotation_matrix)
00285 {
00286 mXAxis.setVec(rotation_matrix.mMatrix[VX]);
00287 mYAxis.setVec(rotation_matrix.mMatrix[VY]);
00288 mZAxis.setVec(rotation_matrix.mMatrix[VZ]);
00289 if( !isFinite() )
00290 {
00291 reset();
00292 llwarns << "Non Finite in LLCoordFrame::setAxes()" << llendl;
00293 }
00294 }
00295
00296
00297 void LLCoordFrame::setAxes(const LLQuaternion &q )
00298 {
00299 LLMatrix3 rotation_matrix(q);
00300 setAxes(rotation_matrix);
00301 if( !isFinite() )
00302 {
00303 reset();
00304 llwarns << "Non Finite in LLCoordFrame::setAxes()" << llendl;
00305 }
00306 }
00307
00308
00309 void LLCoordFrame::setAxes( const F32 *rotation_matrix )
00310 {
00311 mXAxis.mV[VX] = *(rotation_matrix + 3*VX + VX);
00312 mXAxis.mV[VY] = *(rotation_matrix + 3*VX + VY);
00313 mXAxis.mV[VZ] = *(rotation_matrix + 3*VX + VZ);
00314 mYAxis.mV[VX] = *(rotation_matrix + 3*VY + VX);
00315 mYAxis.mV[VY] = *(rotation_matrix + 3*VY + VY);
00316 mYAxis.mV[VZ] = *(rotation_matrix + 3*VY + VZ);
00317 mZAxis.mV[VX] = *(rotation_matrix + 3*VZ + VX);
00318 mZAxis.mV[VY] = *(rotation_matrix + 3*VZ + VY);
00319 mZAxis.mV[VZ] = *(rotation_matrix + 3*VZ + VZ);
00320
00321 if( !isFinite() )
00322 {
00323 reset();
00324 llwarns << "Non Finite in LLCoordFrame::setAxes()" << llendl;
00325 }
00326 }
00327
00328
00329 void LLCoordFrame::setAxes(const LLCoordFrame &frame)
00330 {
00331 mXAxis = frame.getXAxis();
00332 mYAxis = frame.getYAxis();
00333 mZAxis = frame.getZAxis();
00334
00335 if( !isFinite() )
00336 {
00337 reset();
00338 llwarns << "Non Finite in LLCoordFrame::setAxes()" << llendl;
00339 }
00340 }
00341
00342
00343
00344
00345 void LLCoordFrame::translate(F32 x, F32 y, F32 z)
00346 {
00347 mOrigin.mV[VX] += x;
00348 mOrigin.mV[VY] += y;
00349 mOrigin.mV[VZ] += z;
00350
00351 if( !mOrigin.isFinite() )
00352 {
00353 reset();
00354 llwarns << "Non Finite in LLCoordFrame::translate()" << llendl;
00355 }
00356 }
00357
00358
00359 void LLCoordFrame::translate(const LLVector3 &v)
00360 {
00361 mOrigin += v;
00362
00363 if( !mOrigin.isFinite() )
00364 {
00365 reset();
00366 llwarns << "Non Finite in LLCoordFrame::translate()" << llendl;
00367 }
00368 }
00369
00370
00371 void LLCoordFrame::translate(const F32 *origin)
00372 {
00373 mOrigin.mV[VX] += *(origin + VX);
00374 mOrigin.mV[VY] += *(origin + VY);
00375 mOrigin.mV[VZ] += *(origin + VZ);
00376
00377 if( !mOrigin.isFinite() )
00378 {
00379 reset();
00380 llwarns << "Non Finite in LLCoordFrame::translate()" << llendl;
00381 }
00382 }
00383
00384
00385
00386
00387 void LLCoordFrame::rotate(F32 angle, F32 x, F32 y, F32 z)
00388 {
00389 LLQuaternion q(angle, LLVector3(x,y,z));
00390 rotate(q);
00391 }
00392
00393
00394 void LLCoordFrame::rotate(F32 angle, const LLVector3 &rotation_axis)
00395 {
00396 LLQuaternion q(angle, rotation_axis);
00397 rotate(q);
00398 }
00399
00400
00401 void LLCoordFrame::rotate(const LLQuaternion &q)
00402 {
00403 LLMatrix3 rotation_matrix(q);
00404 rotate(rotation_matrix);
00405 }
00406
00407
00408 void LLCoordFrame::rotate(const LLMatrix3 &rotation_matrix)
00409 {
00410 mXAxis.rotVec(rotation_matrix);
00411 mYAxis.rotVec(rotation_matrix);
00412 orthonormalize();
00413
00414 if( !isFinite() )
00415 {
00416 reset();
00417 llwarns << "Non Finite in LLCoordFrame::rotate()" << llendl;
00418 }
00419 }
00420
00421
00422 void LLCoordFrame::roll(F32 angle)
00423 {
00424 LLQuaternion q(angle, mXAxis);
00425 LLMatrix3 rotation_matrix(q);
00426 rotate(rotation_matrix);
00427
00428 if( !mYAxis.isFinite() || !mZAxis.isFinite() )
00429 {
00430 reset();
00431 llwarns << "Non Finite in LLCoordFrame::roll()" << llendl;
00432 }
00433 }
00434
00435 void LLCoordFrame::pitch(F32 angle)
00436 {
00437 LLQuaternion q(angle, mYAxis);
00438 LLMatrix3 rotation_matrix(q);
00439 rotate(rotation_matrix);
00440
00441 if( !mXAxis.isFinite() || !mZAxis.isFinite() )
00442 {
00443 reset();
00444 llwarns << "Non Finite in LLCoordFrame::pitch()" << llendl;
00445 }
00446 }
00447
00448 void LLCoordFrame::yaw(F32 angle)
00449 {
00450 LLQuaternion q(angle, mZAxis);
00451 LLMatrix3 rotation_matrix(q);
00452 rotate(rotation_matrix);
00453
00454 if( !mXAxis.isFinite() || !mYAxis.isFinite() )
00455 {
00456 reset();
00457 llwarns << "Non Finite in LLCoordFrame::yaw()" << llendl;
00458 }
00459 }
00460
00461
00462
00463
00464 LLQuaternion LLCoordFrame::getQuaternion() const
00465 {
00466 LLQuaternion quat(mXAxis, mYAxis, mZAxis);
00467 return quat;
00468 }
00469
00470
00471 void LLCoordFrame::getMatrixToLocal(LLMatrix4& mat) const
00472 {
00473 mat.setFwdCol(mXAxis);
00474 mat.setLeftCol(mYAxis);
00475 mat.setUpCol(mZAxis);
00476
00477 mat.mMatrix[3][0] = -(mOrigin * LLVector3(mat.mMatrix[0][0], mat.mMatrix[1][0], mat.mMatrix[2][0]));
00478 mat.mMatrix[3][1] = -(mOrigin * LLVector3(mat.mMatrix[0][1], mat.mMatrix[1][1], mat.mMatrix[2][1]));
00479 mat.mMatrix[3][2] = -(mOrigin * LLVector3(mat.mMatrix[0][2], mat.mMatrix[1][2], mat.mMatrix[2][2]));
00480 }
00481
00482
00483 void LLCoordFrame::getRotMatrixToParent(LLMatrix4& mat) const
00484 {
00485
00486 mat.setFwdRow( -mYAxis );
00487 mat.setLeftRow( mZAxis );
00488 mat.setUpRow( -mXAxis );
00489 }
00490
00491 size_t LLCoordFrame::writeOrientation(char *buffer) const
00492 {
00493 memcpy(buffer, mOrigin.mV, 3*sizeof(F32));
00494 buffer += 3*sizeof(F32);
00495 memcpy(buffer, mXAxis.mV, 3*sizeof(F32));
00496 buffer += 3*sizeof(F32);
00497 memcpy(buffer, mYAxis.mV, 3*sizeof(F32));
00498 buffer += 3*sizeof(F32);
00499 memcpy(buffer, mZAxis.mV, 3*sizeof(F32));
00500 return 12*sizeof(F32);
00501 }
00502
00503
00504 size_t LLCoordFrame::readOrientation(const char *buffer)
00505 {
00506 memcpy(mOrigin.mV, buffer, 3*sizeof(F32));
00507 buffer += 3*sizeof(F32);
00508 memcpy(mXAxis.mV, buffer, 3*sizeof(F32));
00509 buffer += 3*sizeof(F32);
00510 memcpy(mYAxis.mV, buffer, 3*sizeof(F32));
00511 buffer += 3*sizeof(F32);
00512 memcpy(mZAxis.mV, buffer, 3*sizeof(F32));
00513
00514 if( !isFinite() )
00515 {
00516 reset();
00517 llwarns << "Non Finite in LLCoordFrame::readOrientation()" << llendl;
00518 }
00519
00520 return 12*sizeof(F32);
00521 }
00522
00523
00524
00525
00526 LLVector3 LLCoordFrame::rotateToLocal(const LLVector3 &absolute_vector) const
00527 {
00528 LLVector3 local_vector(mXAxis * absolute_vector,
00529 mYAxis * absolute_vector,
00530 mZAxis * absolute_vector);
00531 return local_vector;
00532 }
00533
00534
00535 LLVector4 LLCoordFrame::rotateToLocal(const LLVector4 &absolute_vector) const
00536 {
00537 LLVector4 local_vector;
00538 local_vector.mV[VX] = mXAxis.mV[VX] * absolute_vector.mV[VX] +
00539 mXAxis.mV[VY] * absolute_vector.mV[VY] +
00540 mXAxis.mV[VZ] * absolute_vector.mV[VZ];
00541 local_vector.mV[VY] = mYAxis.mV[VX] * absolute_vector.mV[VX] +
00542 mYAxis.mV[VY] * absolute_vector.mV[VY] +
00543 mYAxis.mV[VZ] * absolute_vector.mV[VZ];
00544 local_vector.mV[VZ] = mZAxis.mV[VX] * absolute_vector.mV[VX] +
00545 mZAxis.mV[VY] * absolute_vector.mV[VY] +
00546 mZAxis.mV[VZ] * absolute_vector.mV[VZ];
00547 local_vector.mV[VW] = absolute_vector.mV[VW];
00548 return local_vector;
00549 }
00550
00551
00552 LLVector3 LLCoordFrame::rotateToAbsolute(const LLVector3 &local_vector) const
00553 {
00554 LLVector3 absolute_vector;
00555 absolute_vector.mV[VX] = mXAxis.mV[VX] * local_vector.mV[VX] +
00556 mYAxis.mV[VX] * local_vector.mV[VY] +
00557 mZAxis.mV[VX] * local_vector.mV[VZ];
00558 absolute_vector.mV[VY] = mXAxis.mV[VY] * local_vector.mV[VX] +
00559 mYAxis.mV[VY] * local_vector.mV[VY] +
00560 mZAxis.mV[VY] * local_vector.mV[VZ];
00561 absolute_vector.mV[VZ] = mXAxis.mV[VZ] * local_vector.mV[VX] +
00562 mYAxis.mV[VZ] * local_vector.mV[VY] +
00563 mZAxis.mV[VZ] * local_vector.mV[VZ];
00564 return absolute_vector;
00565 }
00566
00567
00568 LLVector4 LLCoordFrame::rotateToAbsolute(const LLVector4 &local_vector) const
00569 {
00570 LLVector4 absolute_vector;
00571 absolute_vector.mV[VX] = mXAxis.mV[VX] * local_vector.mV[VX] +
00572 mYAxis.mV[VX] * local_vector.mV[VY] +
00573 mZAxis.mV[VX] * local_vector.mV[VZ];
00574 absolute_vector.mV[VY] = mXAxis.mV[VY] * local_vector.mV[VX] +
00575 mYAxis.mV[VY] * local_vector.mV[VY] +
00576 mZAxis.mV[VY] * local_vector.mV[VZ];
00577 absolute_vector.mV[VZ] = mXAxis.mV[VZ] * local_vector.mV[VX] +
00578 mYAxis.mV[VZ] * local_vector.mV[VY] +
00579 mZAxis.mV[VZ] * local_vector.mV[VZ];
00580 absolute_vector.mV[VW] = local_vector[VW];
00581 return absolute_vector;
00582 }
00583
00584
00585 void LLCoordFrame::orthonormalize()
00586
00587 {
00588 mXAxis.normVec();
00589 mYAxis -= mXAxis * (mXAxis * mYAxis);
00590 mYAxis.normVec();
00591 mZAxis = mXAxis % mYAxis;
00592 }
00593
00594
00595 LLVector3 LLCoordFrame::transformToLocal(const LLVector3 &absolute_vector) const
00596 {
00597 return rotateToLocal(absolute_vector - mOrigin);
00598 }
00599
00600
00601 LLVector4 LLCoordFrame::transformToLocal(const LLVector4 &absolute_vector) const
00602 {
00603 LLVector4 local_vector(absolute_vector);
00604 local_vector.mV[VX] -= mOrigin.mV[VX];
00605 local_vector.mV[VY] -= mOrigin.mV[VY];
00606 local_vector.mV[VZ] -= mOrigin.mV[VZ];
00607 return rotateToLocal(local_vector);
00608 }
00609
00610
00611 LLVector3 LLCoordFrame::transformToAbsolute(const LLVector3 &local_vector) const
00612 {
00613 return (rotateToAbsolute(local_vector) + mOrigin);
00614 }
00615
00616
00617 LLVector4 LLCoordFrame::transformToAbsolute(const LLVector4 &local_vector) const
00618 {
00619 LLVector4 absolute_vector;
00620 absolute_vector = rotateToAbsolute(local_vector);
00621 absolute_vector.mV[VX] += mOrigin.mV[VX];
00622 absolute_vector.mV[VY] += mOrigin.mV[VY];
00623 absolute_vector.mV[VZ] += mOrigin.mV[VZ];
00624 return absolute_vector;
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 void LLCoordFrame::getOpenGLTranslation(F32 *ogl_matrix) const
00645 {
00646 *(ogl_matrix + 0) = 1.0f;
00647 *(ogl_matrix + 1) = 0.0f;
00648 *(ogl_matrix + 2) = 0.0f;
00649 *(ogl_matrix + 3) = 0.0f;
00650
00651 *(ogl_matrix + 4) = 0.0f;
00652 *(ogl_matrix + 5) = 1.0f;
00653 *(ogl_matrix + 6) = 0.0f;
00654 *(ogl_matrix + 7) = 0.0f;
00655
00656 *(ogl_matrix + 8) = 0.0f;
00657 *(ogl_matrix + 9) = 0.0f;
00658 *(ogl_matrix + 10) = 1.0f;
00659 *(ogl_matrix + 11) = 0.0f;
00660
00661 *(ogl_matrix + 12) = -mOrigin.mV[VX];
00662 *(ogl_matrix + 13) = -mOrigin.mV[VY];
00663 *(ogl_matrix + 14) = -mOrigin.mV[VZ];
00664 *(ogl_matrix + 15) = 1.0f;
00665 }
00666
00667
00668 void LLCoordFrame::getOpenGLRotation(F32 *ogl_matrix) const
00669 {
00670 *(ogl_matrix + 0) = mXAxis.mV[VX];
00671 *(ogl_matrix + 4) = mXAxis.mV[VY];
00672 *(ogl_matrix + 8) = mXAxis.mV[VZ];
00673
00674 *(ogl_matrix + 1) = mYAxis.mV[VX];
00675 *(ogl_matrix + 5) = mYAxis.mV[VY];
00676 *(ogl_matrix + 9) = mYAxis.mV[VZ];
00677
00678 *(ogl_matrix + 2) = mZAxis.mV[VX];
00679 *(ogl_matrix + 6) = mZAxis.mV[VY];
00680 *(ogl_matrix + 10) = mZAxis.mV[VZ];
00681
00682 *(ogl_matrix + 3) = 0.0f;
00683 *(ogl_matrix + 7) = 0.0f;
00684 *(ogl_matrix + 11) = 0.0f;
00685
00686 *(ogl_matrix + 12) = 0.0f;
00687 *(ogl_matrix + 13) = 0.0f;
00688 *(ogl_matrix + 14) = 0.0f;
00689 *(ogl_matrix + 15) = 1.0f;
00690 }
00691
00692
00693 void LLCoordFrame::getOpenGLTransform(F32 *ogl_matrix) const
00694 {
00695 *(ogl_matrix + 0) = mXAxis.mV[VX];
00696 *(ogl_matrix + 4) = mXAxis.mV[VY];
00697 *(ogl_matrix + 8) = mXAxis.mV[VZ];
00698 *(ogl_matrix + 12) = -mOrigin * mXAxis;
00699
00700 *(ogl_matrix + 1) = mYAxis.mV[VX];
00701 *(ogl_matrix + 5) = mYAxis.mV[VY];
00702 *(ogl_matrix + 9) = mYAxis.mV[VZ];
00703 *(ogl_matrix + 13) = -mOrigin * mYAxis;
00704
00705 *(ogl_matrix + 2) = mZAxis.mV[VX];
00706 *(ogl_matrix + 6) = mZAxis.mV[VY];
00707 *(ogl_matrix + 10) = mZAxis.mV[VZ];
00708 *(ogl_matrix + 14) = -mOrigin * mZAxis;
00709
00710 *(ogl_matrix + 3) = 0.0f;
00711 *(ogl_matrix + 7) = 0.0f;
00712 *(ogl_matrix + 11) = 0.0f;
00713 *(ogl_matrix + 15) = 1.0f;
00714 }
00715
00716
00717
00718 void LLCoordFrame::lookDir(const LLVector3 &at, const LLVector3 &up_direction)
00719 {
00720
00721
00722 LLVector3 left(up_direction % at);
00723 if (left.isNull())
00724 {
00725
00726 LLVector3 tempat(at[VX] + 0.01f, at[VY], at[VZ]);
00727 tempat.normVec();
00728 left = (up_direction % tempat);
00729 }
00730 left.normVec();
00731
00732 LLVector3 up = at % left;
00733 setAxes(at, left, up);
00734 }
00735
00736 void LLCoordFrame::lookDir(const LLVector3 &xuv)
00737 {
00738 static LLVector3 up_direction(0.0f, 0.0f, 1.0f);
00739 lookDir(xuv, up_direction);
00740 }
00741
00742 void LLCoordFrame::lookAt(const LLVector3 &origin, const LLVector3 &point_of_interest, const LLVector3 &up_direction)
00743 {
00744 setOrigin(origin);
00745 LLVector3 at(point_of_interest - origin);
00746 at.normVec();
00747 lookDir(at, up_direction);
00748 }
00749
00750 void LLCoordFrame::lookAt(const LLVector3 &origin, const LLVector3 &point_of_interest)
00751 {
00752 static LLVector3 up_direction(0.0f, 0.0f, 1.0f);
00753
00754 setOrigin(origin);
00755 LLVector3 at(point_of_interest - origin);
00756 at.normVec();
00757 lookDir(at, up_direction);
00758 }
00759
00760
00761
00762
00763 std::ostream& operator<<(std::ostream &s, const LLCoordFrame &C)
00764 {
00765 s << "{ "
00766 << " origin = " << C.mOrigin
00767 << " x_axis = " << C.mXAxis
00768 << " y_axis = " << C.mYAxis
00769 << " z_axis = " << C.mZAxis
00770 << " }";
00771 return s;
00772 }
00773
00774
00775
00776
00777
00778
00779