00001
00032
00033
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
00052
00053 BOOL LLViewerJoint::sDisableLOD = FALSE;
00054
00055
00056
00057
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
00072
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
00086
00087
00088 LLViewerJoint::~LLViewerJoint()
00089 {
00090 }
00091
00092
00093
00094
00095
00096 void LLViewerJoint::setValid( BOOL valid, BOOL recursive )
00097 {
00098
00099
00100
00101 mValid = valid;
00102
00103
00104
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
00120
00121 void LLViewerJoint::renderSkeleton(BOOL recursive)
00122 {
00123 F32 nc = 0.57735f;
00124
00125
00126
00127
00128 glPushMatrix();
00129
00130
00131
00132
00133 if (mComponents & SC_BONE)
00134 {
00135 drawBone();
00136 }
00137
00138
00139
00140
00141
00142 glLoadIdentity();
00143 glMultMatrixf( &getWorldMatrix().mMatrix[0][0] );
00144
00145
00146
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
00167
00168 if (mComponents & SC_JOINT)
00169 {
00170 glColor3f( 1.0f, 1.0f, 0.0f );
00171
00172 glBegin(GL_TRIANGLES);
00173
00174
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
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
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
00234
00235 glPopMatrix();
00236 }
00237
00238
00239
00240
00241
00242 U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass )
00243 {
00244 U32 triangle_count = 0;
00245
00246
00247
00248
00249 if ( mValid )
00250 {
00251
00252
00253
00254
00255
00256
00257 if ( gRenderForSelect )
00258 {
00259 triangle_count += drawShape( pixelArea, first_pass );
00260 }
00261 else if ( isTransparent() )
00262 {
00263
00264 if ((pixelArea > MIN_PIXEL_AREA_3PASS_HAIR))
00265 {
00266
00267 LLGLDisable cull(GL_CULL_FACE);
00268
00269 {
00270 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
00271 triangle_count += drawShape( pixelArea, first_pass);
00272 }
00273
00274
00275
00276 GLboolean mask[4];
00277 glGetBooleanv(GL_COLOR_WRITEMASK,mask);
00278
00279 glColorMask(FALSE, FALSE, FALSE, FALSE);
00280 {
00281 triangle_count += drawShape( pixelArea, FALSE );
00282 }
00283
00284
00285 glColorMask(mask[0], mask[1], mask[2], mask[3]);
00286
00287 {
00288 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
00289 triangle_count += drawShape( pixelArea, FALSE );
00290 }
00291 }
00292 else
00293 {
00294
00295 glCullFace(GL_FRONT);
00296 {
00297 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
00298 triangle_count += drawShape( pixelArea, first_pass );
00299 }
00300
00301 glCullFace(GL_BACK);
00302 {
00303 triangle_count += drawShape( pixelArea, FALSE );
00304 }
00305 }
00306 }
00307 else
00308 {
00309
00310 triangle_count += drawShape( pixelArea, first_pass );
00311 }
00312 }
00313
00314
00315
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
00339
00340 void LLViewerJoint::drawBone()
00341 {
00342 if ( mParent == NULL )
00343 return;
00344
00345 F32 boneSize = 0.02f;
00346
00347
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
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
00390 glPopMatrix();
00391 }
00392
00393
00394
00395
00396 BOOL LLViewerJoint::isTransparent()
00397 {
00398 return FALSE;
00399 }
00400
00401
00402
00403
00404 U32 LLViewerJoint::drawShape( F32 pixelArea, BOOL first_pass )
00405 {
00406 return 0;
00407 }
00408
00409
00410
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
00433
00434 {
00435 joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
00436
00437
00438
00439
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
00452
00453 {
00454 joint->updateFaceData(face, pixel_area, damp_wind);
00455
00456
00457
00458
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
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
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
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