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