llviewerjoint.cpp

Go to the documentation of this file.
00001 
00032 //-----------------------------------------------------------------------------
00033 // Header Files
00034 //-----------------------------------------------------------------------------
00035 #include "llviewerprecompiledheaders.h"
00036 
00037 #include "llviewerjoint.h"
00038 
00039 #include "llgl.h"
00040 #include "llmath.h"
00041 #include "llglheaders.h"
00042 #include "llsphere.h"
00043 #include "llvoavatar.h"
00044 #include "pipeline.h"
00045 
00046 #define DEFAULT_LOD 0.0f
00047 
00048 const S32 MIN_PIXEL_AREA_3PASS_HAIR = 64*64;
00049 
00050 //-----------------------------------------------------------------------------
00051 // Static Data
00052 //-----------------------------------------------------------------------------
00053 BOOL                                    LLViewerJoint::sDisableLOD = FALSE;
00054 
00055 //-----------------------------------------------------------------------------
00056 // LLViewerJoint()
00057 // Class Constructor
00058 //-----------------------------------------------------------------------------
00059 LLViewerJoint::LLViewerJoint()
00060 {
00061         mUpdateXform = TRUE;
00062         mValid = FALSE;
00063         mComponents = SC_JOINT | SC_BONE | SC_AXES;
00064         mMinPixelArea = DEFAULT_LOD;
00065         mPickName = PN_DEFAULT;
00066         mVisible = TRUE;
00067 }
00068 
00069 
00070 //-----------------------------------------------------------------------------
00071 // LLViewerJoint()
00072 // Class Constructor
00073 //-----------------------------------------------------------------------------
00074 LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) :
00075         LLJoint(name, parent)
00076 {
00077         mValid = FALSE;
00078         mComponents = SC_JOINT | SC_BONE | SC_AXES;
00079         mMinPixelArea = DEFAULT_LOD;
00080         mPickName = PN_DEFAULT;
00081 }
00082 
00083 
00084 //-----------------------------------------------------------------------------
00085 // ~LLViewerJoint()
00086 // Class Destructor
00087 //-----------------------------------------------------------------------------
00088 LLViewerJoint::~LLViewerJoint()
00089 {
00090 }
00091 
00092 
00093 //--------------------------------------------------------------------
00094 // setValid()
00095 //--------------------------------------------------------------------
00096 void LLViewerJoint::setValid( BOOL valid, BOOL recursive )
00097 {
00098         //----------------------------------------------------------------
00099         // set visibility for this joint
00100         //----------------------------------------------------------------
00101         mValid = valid;
00102         
00103         //----------------------------------------------------------------
00104         // set visibility for children
00105         //----------------------------------------------------------------
00106         if (recursive)
00107         {
00108                 for (child_list_t::iterator iter = mChildren.begin();
00109                          iter != mChildren.end(); ++iter)
00110                 {
00111                         LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00112                         joint->setValid(valid, TRUE);
00113                 }
00114         }
00115 
00116 }
00117 
00118 //--------------------------------------------------------------------
00119 // renderSkeleton()
00120 //--------------------------------------------------------------------
00121 void LLViewerJoint::renderSkeleton(BOOL recursive)
00122 {
00123         F32 nc = 0.57735f;
00124 
00125         //----------------------------------------------------------------
00126         // push matrix stack
00127         //----------------------------------------------------------------
00128         glPushMatrix();
00129 
00130         //----------------------------------------------------------------
00131         // render the bone to my parent
00132         //----------------------------------------------------------------
00133         if (mComponents & SC_BONE)
00134         {
00135                 drawBone();
00136         }
00137 
00138         //----------------------------------------------------------------
00139         // offset to joint position and 
00140         // rotate to our orientation
00141         //----------------------------------------------------------------
00142         glLoadIdentity();
00143         glMultMatrixf( &getWorldMatrix().mMatrix[0][0] );
00144 
00145         //----------------------------------------------------------------
00146         // render joint axes
00147         //----------------------------------------------------------------
00148         if (mComponents & SC_AXES)
00149         {
00150                 glBegin(GL_LINES);
00151                 glColor3f( 1.0f, 0.0f, 0.0f );
00152                 glVertex3f( 0.0f,            0.0f, 0.0f );
00153                 glVertex3f( 0.1f, 0.0f, 0.0f );
00154 
00155                 glColor3f( 0.0f, 1.0f, 0.0f );
00156                 glVertex3f( 0.0f, 0.0f,            0.0f );
00157                 glVertex3f( 0.0f, 0.1f, 0.0f );
00158 
00159                 glColor3f( 0.0f, 0.0f, 1.0f );
00160                 glVertex3f( 0.0f, 0.0f, 0.0f );
00161                 glVertex3f( 0.0f, 0.0f, 0.1f );
00162                 glEnd();
00163         }
00164 
00165         //----------------------------------------------------------------
00166         // render the joint graphic
00167         //----------------------------------------------------------------
00168         if (mComponents & SC_JOINT)
00169         {
00170                 glColor3f( 1.0f, 1.0f, 0.0f );
00171 
00172                 glBegin(GL_TRIANGLES);
00173 
00174                 // joint top half
00175                 glNormal3f(nc, nc, nc);
00176                 glVertex3f(0.0f,             0.0f, 0.05f);
00177                 glVertex3f(0.05f,       0.0f,       0.0f);
00178                 glVertex3f(0.0f,       0.05f,       0.0f);
00179 
00180                 glNormal3f(-nc, nc, nc);
00181                 glVertex3f(0.0f,             0.0f, 0.05f);
00182                 glVertex3f(0.0f,       0.05f,       0.0f);
00183                 glVertex3f(-0.05f,      0.0f,       0.0f);
00184                 
00185                 glNormal3f(-nc, -nc, nc);
00186                 glVertex3f(0.0f,             0.0f, 0.05f);
00187                 glVertex3f(-0.05f,      0.0f,      0.0f);
00188                 glVertex3f(0.0f,      -0.05f,      0.0f);
00189 
00190                 glNormal3f(nc, -nc, nc);
00191                 glVertex3f(0.0f,              0.0f, 0.05f);
00192                 glVertex3f(0.0f,       -0.05f,       0.0f);
00193                 glVertex3f(0.05f,        0.0f,       0.0f);
00194                 
00195                 // joint bottom half
00196                 glNormal3f(nc, nc, -nc);
00197                 glVertex3f(0.0f,             0.0f, -0.05f);
00198                 glVertex3f(0.0f,       0.05f,        0.0f);
00199                 glVertex3f(0.05f,       0.0f,        0.0f);
00200 
00201                 glNormal3f(-nc, nc, -nc);
00202                 glVertex3f(0.0f,             0.0f, -0.05f);
00203                 glVertex3f(-0.05f,      0.0f,        0.0f);
00204                 glVertex3f(0.0f,       0.05f,        0.0f);
00205                 
00206                 glNormal3f(-nc, -nc, -nc);
00207                 glVertex3f(0.0f,              0.0f, -0.05f);
00208                 glVertex3f(0.0f,       -0.05f,        0.0f);
00209                 glVertex3f(-0.05f,       0.0f,        0.0f);
00210 
00211                 glNormal3f(nc, -nc, -nc);
00212                 glVertex3f(0.0f,             0.0f,  -0.05f);
00213                 glVertex3f(0.05f,       0.0f,         0.0f);
00214                 glVertex3f(0.0f,      -0.05f,         0.0f);
00215                 
00216                 glEnd();
00217         }
00218 
00219         //----------------------------------------------------------------
00220         // render children
00221         //----------------------------------------------------------------
00222         if (recursive)
00223         {
00224                 for (child_list_t::iterator iter = mChildren.begin();
00225                          iter != mChildren.end(); ++iter)
00226                 {
00227                         LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00228                         joint->renderSkeleton();
00229                 }
00230         }
00231 
00232         //----------------------------------------------------------------
00233         // pop matrix stack
00234         //----------------------------------------------------------------
00235         glPopMatrix();
00236 }
00237 
00238 
00239 //--------------------------------------------------------------------
00240 // render()
00241 //--------------------------------------------------------------------
00242 U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass )
00243 {
00244         U32 triangle_count = 0;
00245 
00246         //----------------------------------------------------------------
00247         // ignore invisible objects
00248         //----------------------------------------------------------------
00249         if ( mValid )
00250         {
00251 
00252 
00253                 //----------------------------------------------------------------
00254                 // if object is transparent, defer it, otherwise
00255                 // give the joint subclass a chance to draw itself
00256                 //----------------------------------------------------------------
00257                 if ( gRenderForSelect )
00258                 {
00259                         triangle_count += drawShape( pixelArea, first_pass );
00260                 }
00261                 else if ( isTransparent() )
00262                 {
00263                         // Hair and Skirt
00264                         if ((pixelArea > MIN_PIXEL_AREA_3PASS_HAIR))
00265                         {
00266                                 // render all three passes
00267                                 LLGLDisable cull(GL_CULL_FACE);
00268                                 // first pass renders without writing to the z buffer
00269                                 {
00270                                         LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
00271                                         triangle_count += drawShape( pixelArea, first_pass);
00272                                 }
00273                                 // second pass writes to z buffer only
00274                                 //********UMICH 3D LAB********
00275                                 // protect the color mask change for correct anaglyph render
00276                                 GLboolean mask[4];
00277                                 glGetBooleanv(GL_COLOR_WRITEMASK,mask);
00278                                 //********UMICH 3D LAB********
00279                                 glColorMask(FALSE, FALSE, FALSE, FALSE);
00280                                 {
00281                                         triangle_count += drawShape( pixelArea, FALSE );
00282                                 }
00283                                 // third past respects z buffer and writes color
00284                                 //********UMICH 3D LAB********
00285                                 glColorMask(mask[0], mask[1], mask[2], mask[3]);
00286                                 //********UMICH 3D LAB********
00287                                 {
00288                                         LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
00289                                         triangle_count += drawShape( pixelArea, FALSE );
00290                                 }
00291                         }
00292                         else
00293                         {
00294                                 // Render Inside (no Z buffer write)
00295                                 glCullFace(GL_FRONT);
00296                                 {
00297                                         LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
00298                                         triangle_count += drawShape( pixelArea, first_pass );
00299                                 }
00300                                 // Render Outside (write to the Z buffer)
00301                                 glCullFace(GL_BACK);
00302                                 {
00303                                         triangle_count += drawShape( pixelArea, FALSE );
00304                                 }
00305                         }
00306                 }
00307                 else
00308                 {
00309                         // set up render state
00310                         triangle_count += drawShape( pixelArea, first_pass );
00311                 }
00312         }
00313 
00314         //----------------------------------------------------------------
00315         // render children
00316         //----------------------------------------------------------------
00317         for (child_list_t::iterator iter = mChildren.begin();
00318                  iter != mChildren.end(); ++iter)
00319         {
00320                 LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00321                 F32 jointLOD = joint->getLOD();
00322                 if (pixelArea >= jointLOD || sDisableLOD)
00323                 {
00324                         triangle_count += joint->render( pixelArea );
00325 
00326                         if (jointLOD != DEFAULT_LOD)
00327                         {
00328                                 break;
00329                         }
00330                 }
00331         }
00332 
00333         return triangle_count;
00334 }
00335 
00336 
00337 //--------------------------------------------------------------------
00338 // drawBone()
00339 //--------------------------------------------------------------------
00340 void LLViewerJoint::drawBone()
00341 {
00342         if ( mParent == NULL )
00343                 return;
00344 
00345         F32 boneSize = 0.02f;
00346 
00347         // rotate to point to child (bone direction)
00348         glPushMatrix();
00349 
00350         LLVector3 boneX = getPosition();
00351         F32 length = boneX.normVec();
00352 
00353         LLVector3 boneZ(1.0f, 0.0f, 1.0f);
00354         
00355         LLVector3 boneY = boneZ % boneX;
00356         boneY.normVec();
00357 
00358         boneZ = boneX % boneY;
00359 
00360         LLMatrix4 rotateMat;
00361         rotateMat.setFwdRow( boneX );
00362         rotateMat.setLeftRow( boneY );
00363         rotateMat.setUpRow( boneZ );
00364         glMultMatrixf( &rotateMat.mMatrix[0][0] );
00365 
00366         // render the bone
00367         glColor3f( 0.5f, 0.5f, 0.0f );
00368 
00369         glBegin(GL_TRIANGLES);
00370 
00371         glVertex3f( length,     0.0f,       0.0f);
00372         glVertex3f( 0.0f,       boneSize,  0.0f);
00373         glVertex3f( 0.0f,       0.0f,       boneSize);
00374 
00375         glVertex3f( length,     0.0f,        0.0f);
00376         glVertex3f( 0.0f,       0.0f,        -boneSize);
00377         glVertex3f( 0.0f,       boneSize,   0.0f);
00378 
00379         glVertex3f( length,     0.0f,        0.0f);
00380         glVertex3f( 0.0f,       -boneSize,  0.0f);
00381         glVertex3f( 0.0f,       0.0f,        -boneSize);
00382 
00383         glVertex3f( length,     0.0f,        0.0f);
00384         glVertex3f( 0.0f,       0.0f,        boneSize);
00385         glVertex3f( 0.0f,       -boneSize,  0.0f);
00386 
00387         glEnd();
00388 
00389         // restore matrix
00390         glPopMatrix();
00391 }
00392 
00393 //--------------------------------------------------------------------
00394 // isTransparent()
00395 //--------------------------------------------------------------------
00396 BOOL LLViewerJoint::isTransparent()
00397 {
00398         return FALSE;
00399 }
00400 
00401 //--------------------------------------------------------------------
00402 // drawShape()
00403 //--------------------------------------------------------------------
00404 U32 LLViewerJoint::drawShape( F32 pixelArea, BOOL first_pass )
00405 {
00406         return 0;
00407 }
00408 
00409 //--------------------------------------------------------------------
00410 // setSkeletonComponents()
00411 //--------------------------------------------------------------------
00412 void LLViewerJoint::setSkeletonComponents( U32 comp, BOOL recursive )
00413 {
00414         mComponents = comp;
00415         if (recursive)
00416         {
00417                 for (child_list_t::iterator iter = mChildren.begin();
00418                          iter != mChildren.end(); ++iter)
00419                 {
00420                         LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00421                         joint->setSkeletonComponents(comp, recursive);
00422                 }
00423         }
00424 }
00425 
00426 void LLViewerJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
00427 {
00428         for (child_list_t::iterator iter = mChildren.begin();
00429                  iter != mChildren.end(); ++iter)
00430         {
00431                 LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00432                 //F32 jointLOD = joint->getLOD();
00433                 //if (pixel_area >= jointLOD || sDisableLOD)
00434                 {
00435                         joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
00436 
00437                 //      if (jointLOD != DEFAULT_LOD)
00438                 //      {
00439                 //              break;
00440                 //      }
00441                 }
00442         }
00443 }
00444 
00445 void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind)
00446 {
00447         for (child_list_t::iterator iter = mChildren.begin();
00448                  iter != mChildren.end(); ++iter)
00449         {
00450                 LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00451                 //F32 jointLOD = joint->getLOD();
00452                 //if (pixel_area >= jointLOD || sDisableLOD)
00453                 {
00454                         joint->updateFaceData(face, pixel_area, damp_wind);
00455 
00456                 //      if (jointLOD != DEFAULT_LOD)
00457                 //      {
00458                 //              break;
00459                 //      }
00460                 }
00461         }
00462 }
00463 
00464 void LLViewerJoint::updateGeometry()
00465 {
00466         for (child_list_t::iterator iter = mChildren.begin();
00467                  iter != mChildren.end(); ++iter)
00468         {
00469                 LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00470                 joint->updateGeometry();
00471         }
00472 }
00473 
00474 
00475 BOOL LLViewerJoint::updateLOD(F32 pixel_area, BOOL activate)
00476 {
00477         BOOL lod_changed = FALSE;
00478         BOOL found_lod = FALSE;
00479 
00480         for (child_list_t::iterator iter = mChildren.begin();
00481                  iter != mChildren.end(); ++iter)
00482         {
00483                 LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00484                 F32 jointLOD = joint->getLOD();
00485                 
00486                 if (found_lod || jointLOD == DEFAULT_LOD)
00487                 {
00488                         // we've already found a joint to enable, so enable the rest as alternatives
00489                         lod_changed |= joint->updateLOD(pixel_area, TRUE);
00490                 }
00491                 else
00492                 {
00493                         if (pixel_area >= jointLOD || sDisableLOD)
00494                         {
00495                                 lod_changed |= joint->updateLOD(pixel_area, TRUE);
00496                                 found_lod = TRUE;
00497                         }
00498                         else
00499                         {
00500                                 lod_changed |= joint->updateLOD(pixel_area, FALSE);
00501                         }
00502                 }
00503         }
00504         return lod_changed;
00505 }
00506 
00507 void LLViewerJoint::dump()
00508 {
00509         for (child_list_t::iterator iter = mChildren.begin();
00510                  iter != mChildren.end(); ++iter)
00511         {
00512                 LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00513                 joint->dump();
00514         }
00515 }
00516 
00517 void LLViewerJoint::setVisible(BOOL visible, BOOL recursive)
00518 {
00519         mVisible = visible;
00520 
00521         if (recursive)
00522         {
00523                 for (child_list_t::iterator iter = mChildren.begin();
00524                          iter != mChildren.end(); ++iter)
00525                 {
00526                         LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00527                         joint->setVisible(visible, recursive);
00528                 }
00529         }
00530 }
00531 
00532 void LLViewerJoint::writeCAL3D(apr_file_t* fp)
00533 {
00534         LLVector3 bone_pos = mXform.getPosition();
00535         if (mParent)
00536         {
00537                 bone_pos.scaleVec(mParent->getScale());
00538                 bone_pos *= 100.f;
00539         }
00540         else
00541         {
00542                 bone_pos.clearVec();
00543         }
00544         
00545         LLQuaternion bone_rot;
00546 
00547         S32 num_children = 0;
00548         for (child_list_t::iterator iter = mChildren.begin();
00549                  iter != mChildren.end(); ++iter)
00550         {
00551                 LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00552                 if (joint->mJointNum != -1)
00553                 {
00554                         num_children++;
00555                 }
00556         }
00557 
00558         LLJoint* cur_joint = this;
00559         LLVector3 rootSkinOffset;
00560         if (mParent)
00561         {
00562                 while (cur_joint)
00563                 {
00564                         rootSkinOffset -= cur_joint->getSkinOffset();
00565                         cur_joint = (LLViewerJoint*)cur_joint->getParent();
00566                 }
00567 
00568                 rootSkinOffset *= 100.f;
00569         }
00570 
00571         apr_file_printf(fp, "   <BONE ID=\"%d\" NAME=\"%s\" NUMCHILDS=\"%d\">\n", mJointNum + 1, mName.c_str(), num_children);
00572         apr_file_printf(fp, "           <TRANSLATION>%.6f %.6f %.6f</TRANSLATION>\n", bone_pos.mV[VX], bone_pos.mV[VY], bone_pos.mV[VZ]);
00573         apr_file_printf(fp, "           <ROTATION>%.6f %.6f %.6f %.6f</ROTATION>\n", bone_rot.mQ[VX], bone_rot.mQ[VY], bone_rot.mQ[VZ], bone_rot.mQ[VW]);
00574         apr_file_printf(fp, "           <LOCALTRANSLATION>%.6f %.6f %.6f</LOCALTRANSLATION>\n", rootSkinOffset.mV[VX], rootSkinOffset.mV[VY], rootSkinOffset.mV[VZ]);
00575         apr_file_printf(fp, "           <LOCALROTATION>0 0 0 1</LOCALROTATION>\n");
00576         apr_file_printf(fp, "           <PARENTID>%d</PARENTID>\n", mParent ? mParent->mJointNum + 1 : -1);
00577         
00578         for (child_list_t::iterator iter = mChildren.begin();
00579                  iter != mChildren.end(); ++iter)
00580         {
00581                 LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00582                 if (joint->mJointNum != -1)
00583                 {
00584                         apr_file_printf(fp, "           <CHILDID>%d</CHILDID>\n", joint->mJointNum + 1);
00585                 }
00586         }
00587         apr_file_printf(fp, "   </BONE>\n");
00588 
00589         // recurse
00590         for (child_list_t::iterator iter = mChildren.begin();
00591                  iter != mChildren.end(); ++iter)
00592         {
00593                 LLViewerJoint* joint = (LLViewerJoint*)(*iter);
00594                 if (joint->mJointNum != -1)
00595                 {
00596                         joint->writeCAL3D(fp);
00597                 }
00598         }
00599 
00600 }
00601 
00602 //-----------------------------------------------------------------------------
00603 // LLViewerJointCollisionVolume()
00604 //-----------------------------------------------------------------------------
00605 
00606 LLViewerJointCollisionVolume::LLViewerJointCollisionVolume()
00607 {
00608         mUpdateXform = FALSE;
00609 }
00610 
00611 LLViewerJointCollisionVolume::LLViewerJointCollisionVolume(const std::string &name, LLJoint *parent) : LLViewerJoint(name, parent)
00612 {
00613         
00614 }
00615 
00616 void LLViewerJointCollisionVolume::render()
00617 {
00618         updateWorldMatrix();
00619         glMatrixMode(GL_MODELVIEW);
00620         glPushMatrix();
00621         glMultMatrixf( &mXform.getWorldMatrix().mMatrix[0][0] );
00622 
00623         glColor3f( 0.f, 0.f, 1.f );
00624         gSphere.render();
00625 
00626         glPopMatrix();
00627 }
00628 
00629 LLVector3 LLViewerJointCollisionVolume::getVolumePos(LLVector3 &offset)
00630 {
00631         mUpdateXform = TRUE;
00632         
00633         LLVector3 result = offset;
00634         result.scaleVec(getScale());
00635         result.rotVec(getWorldRotation());
00636         result += getWorldPosition();
00637 
00638         return result;
00639 }
00640 
00641 // End

Generated on Thu Jul 1 06:09:28 2010 for Second Life Viewer by  doxygen 1.4.7