diff options
Diffstat (limited to 'indra/newview/llvovolume.cpp')
-rw-r--r--[-rwxr-xr-x] | indra/newview/llvovolume.cpp | 219 |
1 files changed, 111 insertions, 108 deletions
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 5e010a4712..465f8fe0d6 100755..100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -54,6 +54,7 @@ #include "llspatialpartition.h" #include "llhudmanager.h" #include "llflexibleobject.h" +#include "llskinningutil.h" #include "llsky.h" #include "lltexturefetch.h" #include "llvector4a.h" @@ -80,7 +81,7 @@ const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; -U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 20; +U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1; BOOL gAnimateTextures = TRUE; //extern BOOL gHideSelectedObjects; @@ -1624,6 +1625,66 @@ static LLTrace::BlockTimerStatHandle FTM_GEN_FLEX("Generate Flexies"); static LLTrace::BlockTimerStatHandle FTM_UPDATE_PRIMITIVES("Update Primitives"); static LLTrace::BlockTimerStatHandle FTM_UPDATE_RIGGED_VOLUME("Update Rigged"); +bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled) +{ + bool regen_faces = false; + + LLVolume *old_volumep, *new_volumep; + F32 old_lod, new_lod; + S32 old_num_faces, new_num_faces; + + old_volumep = getVolume(); + old_lod = old_volumep->getDetail(); + old_num_faces = old_volumep->getNumFaces(); + old_volumep = NULL; + + { + LL_RECORD_BLOCK_TIME(FTM_GEN_VOLUME); + const LLVolumeParams &volume_params = getVolume()->getParams(); + setVolume(volume_params, 0); + } + + new_volumep = getVolume(); + new_lod = new_volumep->getDetail(); + new_num_faces = new_volumep->getNumFaces(); + new_volumep = NULL; + + if ((new_lod != old_lod) || mSculptChanged) + { + compiled = TRUE; + sNumLODChanges += new_num_faces; + + if ((S32)getNumTEs() != getVolume()->getNumFaces()) + { + setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces. + } + + drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles() + + { + LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES); + regen_faces = new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs(); + if (regen_faces) + { + regenFaces(); + } + + if (mSculptChanged) + { //changes in sculpt maps can thrash an object bounding box without + //triggering a spatial group bounding box update -- force spatial group + //to update bounding boxes + LLSpatialGroup* group = mDrawable->getSpatialGroup(); + if (group) + { + group->unbound(); + } + } + } + } + + return regen_faces; +} + BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) { LL_RECORD_BLOCK_TIME(FTM_UPDATE_PRIMITIVES); @@ -1664,83 +1725,35 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) return TRUE; // No update to complete } - if (mVolumeChanged || mFaceMappingChanged ) + if (mVolumeChanged || mFaceMappingChanged) { dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); - compiled = TRUE; + bool was_regen_faces = false; if (mVolumeChanged) { - LL_RECORD_BLOCK_TIME(FTM_GEN_VOLUME); - LLVolumeParams volume_params = getVolume()->getParams(); - setVolume(volume_params, 0); + was_regen_faces = lodOrSculptChanged(drawable, compiled); drawable->setState(LLDrawable::REBUILD_VOLUME); } - + else if (mSculptChanged || mLODChanged) { + compiled = TRUE; + was_regen_faces = lodOrSculptChanged(drawable, compiled); + } + + if (!was_regen_faces) { LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES); regenFaces(); - genBBoxes(FALSE); } + + genBBoxes(FALSE); } - else if ((mLODChanged) || (mSculptChanged)) + else if (mLODChanged || mSculptChanged) { dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); - - LLVolume *old_volumep, *new_volumep; - F32 old_lod, new_lod; - S32 old_num_faces, new_num_faces ; - - old_volumep = getVolume(); - old_lod = old_volumep->getDetail(); - old_num_faces = old_volumep->getNumFaces() ; - old_volumep = NULL ; - - { - LL_RECORD_BLOCK_TIME(FTM_GEN_VOLUME); - LLVolumeParams volume_params = getVolume()->getParams(); - setVolume(volume_params, 0); - } - - new_volumep = getVolume(); - new_lod = new_volumep->getDetail(); - new_num_faces = new_volumep->getNumFaces() ; - new_volumep = NULL ; - - if ((new_lod != old_lod) || mSculptChanged) - { - compiled = TRUE; - sNumLODChanges += new_num_faces ; - - if((S32)getNumTEs() != getVolume()->getNumFaces()) - { - setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces. - } - - drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles() - - { - LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES); - if (new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs()) - { - regenFaces(); - } - genBBoxes(FALSE); - - if (mSculptChanged) - { //changes in sculpt maps can thrash an object bounding box without - //triggering a spatial group bounding box update -- force spatial group - //to update bounding boxes - LLSpatialGroup* group = mDrawable->getSpatialGroup(); - if (group) - { - group->unbound(); - } - } - } - } - + compiled = TRUE; + lodOrSculptChanged(drawable, compiled); genBBoxes(FALSE); } // it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local @@ -2103,6 +2116,8 @@ bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture) for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it) { LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); + if (cur_material.isNull()) + continue; switch(range_it->second.map) { @@ -3343,6 +3358,13 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const // children, and cost should only be increased for unique textures -Nyx U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const { + /***************************************************************** + * This calculation should not be modified by third party viewers, + * since it is used to limit rendering and should be uniform for + * everyone. If you have suggested improvements, submit them to + * the official viewer for consideration. + *****************************************************************/ + // Get access to params we'll need at various points. // Skip if this is object doesn't have a volume (e.g. is an avatar). BOOL has_volume = (getVolume() != NULL); @@ -3416,7 +3438,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const { // base cost is dependent on mesh complexity // note that 3 is the highest LOD as of the time of this coding. - S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(),3); + S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(), getLOD()); if ( size > 0) { if (gMeshRepo.getSkinInfo(volume_params.getSculptID(), this)) @@ -3871,7 +3893,7 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const } -BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp, LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) { @@ -3890,9 +3912,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& if (mDrawable->isState(LLDrawable::RIGGED)) { - if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf()) + if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) { - updateRiggedVolume(); + updateRiggedVolume(true); volume = mRiggedVolume; transform = false; } @@ -4071,10 +4093,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& bool LLVOVolume::treatAsRigged() { - return LLFloater::isVisible(gFloaterTools) && - isAttachment() && - getAvatar() && - getAvatar()->isSelf() && + return isSelected() && + isAttachment() && mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED); } @@ -4093,12 +4113,12 @@ void LLVOVolume::clearRiggedVolume() } } -void LLVOVolume::updateRiggedVolume() +void LLVOVolume::updateRiggedVolume(bool force_update) { //Update mRiggedVolume to match current animation frame of avatar. //Also update position/size in octree. - if (!treatAsRigged()) + if ((!force_update) && (!treatAsRigged())) { clearRiggedVolume(); @@ -4163,12 +4183,11 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } //build matrix palette - // BENTO JOINT COUNT LIMIT static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT; LLMatrix4a mat[kMaxJoints]; - U32 maxJoints = llmin(skin->mJointNames.size(), kMaxJoints); - LLDrawPoolAvatar::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar); + U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin); + LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar); for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) { @@ -4180,6 +4199,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if ( weight ) { + LLSkinningUtil::checkSkinWeights(weight, dst_face.mNumVertices, skin); LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); @@ -4189,10 +4209,11 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons { LL_RECORD_BLOCK_TIME(FTM_SKIN_RIGGED); + U32 max_joints = LLSkinningUtil::getMaxJointCount(); for (U32 j = 0; j < dst_face.mNumVertices; ++j) { LLMatrix4a final_mat; - LLDrawPoolAvatar::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat); + LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints); LLVector4a& v = vol_face.mPositions[j]; LLVector4a t; @@ -4665,10 +4686,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (pAvatarVO) { - pAvatarVO->mAttachmentGeometryBytes -= group->mGeometryBytes; - pAvatarVO->mAttachmentGeometryBytes = llmax(pAvatarVO->mAttachmentGeometryBytes, 0); - pAvatarVO->mAttachmentSurfaceArea -= group->mSurfaceArea; - pAvatarVO->mAttachmentSurfaceArea = llmax(pAvatarVO->mAttachmentSurfaceArea, 0.f); + pAvatarVO->subtractAttachmentArea( group->mSurfaceArea ); } group->mGeometryBytes = 0; @@ -4753,13 +4771,22 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) drawablep->clearState(LLDrawable::HAS_ALPHA); bool rigged = vobj->isAttachment() && - vobj->isMesh() && - gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); + vobj->isMesh() && + gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); bool is_rigged = false; + if (rigged && pAvatarVO) + { + pAvatarVO->addAttachmentPosOverridesForObject(vobj); + if (pAvatarVO->isSelf()) + { + //pAvatarVO->showAttachmentPosOverrides(); + } + } + //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) { @@ -4776,8 +4803,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //sum up face verts and indices drawablep->updateFaceSize(i); - - if (rigged) { if (!facep->isState(LLFace::RIGGED)) @@ -4791,13 +4816,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //get drawpool of avatar with rigged face LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); - // FIXME should this be inside the face loop? - // doesn't seem to depend on any per-face state. - if ( pAvatarVO ) - { - pAvatarVO->addAttachmentPosOverridesForObject(vobj); - } - if (pool) { const LLTextureEntry* te = facep->getTextureEntry(); @@ -5222,24 +5240,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (pAvatarVO) { - if (pAvatarVO->mAttachmentGeometryBytes < 0) - { // First time through value is -1 - pAvatarVO->mAttachmentGeometryBytes = group->mGeometryBytes; - } - else - { - pAvatarVO->mAttachmentGeometryBytes += group->mGeometryBytes; - } - if (pAvatarVO->mAttachmentSurfaceArea < 0.f) - { // First time through value is -1 - pAvatarVO->mAttachmentSurfaceArea = group->mSurfaceArea; - } - else - { - pAvatarVO->mAttachmentSurfaceArea += group->mSurfaceArea; + pAvatarVO->addAttachmentArea( group->mSurfaceArea ); } } -} static LLTrace::BlockTimerStatHandle FTM_REBUILD_MESH_FLUSH("Flush Mesh"); |