diff options
Diffstat (limited to 'indra/newview/llvoavatar.cpp')
-rw-r--r-- | indra/newview/llvoavatar.cpp | 441 |
1 files changed, 257 insertions, 184 deletions
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 868d26d5c6..2ef45442ee 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -617,7 +617,6 @@ bool LLVOAvatar::sVisibleInFirstPerson = false; F32 LLVOAvatar::sLODFactor = 1.f; F32 LLVOAvatar::sPhysicsLODFactor = 1.f; bool LLVOAvatar::sJointDebug = false; -bool LLVOAvatar::sLipSyncEnabled = false; F32 LLVOAvatar::sUnbakedTime = 0.f; F32 LLVOAvatar::sUnbakedUpdateTime = 0.f; F32 LLVOAvatar::sGreyTime = 0.f; @@ -1193,7 +1192,6 @@ void LLVOAvatar::initClass() LLControlAvatar::sRegionChangedSlot = gAgent.addRegionChangedCallback(&LLControlAvatar::onRegionChanged); sCloudTexture = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c"); - gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&LLVOAvatar::handleVOAvatarPrefsChanged, _2)); } @@ -1201,12 +1199,6 @@ void LLVOAvatar::cleanupClass() { } -bool LLVOAvatar::handleVOAvatarPrefsChanged(const LLSD &newvalue) -{ - sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled"); - return true; -} - // virtual void LLVOAvatar::initInstance() { @@ -1570,7 +1562,8 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) size.setSub(newMax,newMin); size.mul(0.5f); - mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); + F32 pixel_area = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); + setCorrectedPixelArea(pixel_area); } void render_sphere_and_line(const LLVector3& begin_pos, const LLVector3& end_pos, F32 sphere_scale, const LLVector3& occ_color, const LLVector3& visible_color) @@ -1669,6 +1662,9 @@ void LLVOAvatar::renderCollisionVolumes() } } +// defined in llspatialpartition.cpp -- draw a box outline in the current GL context from given center and half-size +void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size); + void LLVOAvatar::renderBones(const std::string &selected_joint) { LLGLEnable blend(GL_BLEND); @@ -1745,6 +1741,88 @@ void LLVOAvatar::renderBones(const std::string &selected_joint) gGL.popMatrix(); } + + + // draw joint space bounding boxes of rigged attachments in yellow + gGL.color3f(1.f, 1.f, 0.f); + for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) + { + LLJoint* joint = getJoint(joint_num); + LLJointRiggingInfo* rig_info = NULL; + if (joint_num < mJointRiggingInfoTab.size()) + { + rig_info = &mJointRiggingInfoTab[joint_num]; + } + + if (joint && rig_info && rig_info->isRiggedTo()) + { + LLViewerJointAttachment* as_joint_attach = dynamic_cast<LLViewerJointAttachment*>(joint); + if (as_joint_attach && as_joint_attach->getIsHUDAttachment()) + { + // Ignore bounding box of HUD joints + continue; + } + gGL.pushMatrix(); + gGL.multMatrix(&joint->getXform()->getWorldMatrix().mMatrix[0][0]); + + LLVector4a pos; + LLVector4a size; + + const LLVector4a* extents = rig_info->getRiggedExtents(); + + pos.setAdd(extents[0], extents[1]); + pos.mul(0.5f); + size.setSub(extents[1], extents[0]); + size.mul(0.5f); + + drawBoxOutline(pos, size); + + gGL.popMatrix(); + } + } + + // draw world space attachment rigged bounding boxes in cyan + gGL.color3f(0.f, 1.f, 1.f); + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + + if (attachment->getValid()) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* attached_object = attachment_iter->get(); + if (attached_object && !attached_object->isHUDAttachment()) + { + LLDrawable* drawable = attached_object->mDrawable; + if (drawable && drawable->isState(LLDrawable::RIGGED | LLDrawable::RIGGED_CHILD)) + { + // get face rigged extents + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + LLFace* facep = drawable->getFace(i); + if (facep && facep->isState(LLFace::RIGGED)) + { + LLVector4a center, size; + + LLVector4a* extents = facep->mRiggedExtents; + + center.setAdd(extents[0], extents[1]); + center.mul(0.5f); + size.setSub(extents[1], extents[0]); + size.mul(0.5f); + drawBoxOutline(center, size); + } + } + } + } + } + } + } } @@ -1862,36 +1940,36 @@ bool LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& { mCollisionVolumes[i].updateWorldMatrix(); - glh::matrix4f mat((F32*) mCollisionVolumes[i].getXform()->getWorldMatrix().mMatrix); - glh::matrix4f inverse = mat.inverse(); - glh::matrix4f norm_mat = inverse.transpose(); + glm::mat4 mat(glm::make_mat4((F32*) mCollisionVolumes[i].getXform()->getWorldMatrix().mMatrix)); + glm::mat4 inverse = glm::inverse(mat); + glm::mat4 norm_mat = glm::transpose(inverse); - glh::vec3f p1(start.getF32ptr()); - glh::vec3f p2(end.getF32ptr()); + glm::vec3 p1(glm::make_vec3(start.getF32ptr())); + glm::vec3 p2(glm::make_vec3(end.getF32ptr())); - inverse.mult_matrix_vec(p1); - inverse.mult_matrix_vec(p2); + p1 = mul_mat4_vec3(inverse, p1); + p2 = mul_mat4_vec3(inverse, p2); LLVector3 position; LLVector3 norm; - if (linesegment_sphere(LLVector3(p1.v), LLVector3(p2.v), LLVector3(0,0,0), 1.f, position, norm)) + if (linesegment_sphere(LLVector3(glm::value_ptr(p1)), LLVector3(glm::value_ptr(p2)), LLVector3(0,0,0), 1.f, position, norm)) { - glh::vec3f res_pos(position.mV); - mat.mult_matrix_vec(res_pos); + glm::vec3 res_pos(glm::make_vec3(position.mV)); + res_pos = mul_mat4_vec3(mat, res_pos); - norm.normalize(); - glh::vec3f res_norm(norm.mV); - norm_mat.mult_matrix_dir(res_norm); + glm::vec3 res_norm(glm::make_vec3(norm.mV)); + res_norm = glm::normalize(res_norm); + res_norm = glm::mat3(norm_mat) * res_norm; if (intersection) { - intersection->load3(res_pos.v); + intersection->load3(glm::value_ptr(res_pos)); } if (normal) { - normal->load3(res_norm.v); + normal->load3(glm::value_ptr(res_norm)); } return true; @@ -2344,8 +2422,6 @@ void LLVOAvatar::updateMeshData() { if (mDrawable.notNull()) { - stop_glerror(); - S32 f_num = 0 ; const U32 VERTEX_NUMBER_THRESHOLD = 128 ;//small number of this means each part of an avatar has its own vertex buffer. const auto num_parts = mMeshLOD.size(); @@ -2472,7 +2548,6 @@ void LLVOAvatar::updateMeshData() } } - stop_glerror(); buff->unmapBuffer(); if(!f_num) @@ -2923,7 +2998,7 @@ static void override_bbox(LLDrawable* drawable, LLVector4a* extents) { LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; drawable->setSpatialExtents(extents[0], extents[1]); - drawable->setPositionGroup(LLVector4a(0, 0, 0)); + drawable->setPositionGroup(LLVector4a(0.f, 0.f, 0.f)); drawable->movePartition(); } @@ -2944,19 +3019,12 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) if (detailed_update) { U32 draw_order = 0; - S32 attachment_selected = LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment(); - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) + bool attachment_selected = LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 0 && LLSelectMgr::getInstance()->getSelection()->isAttachment(); + for (const auto& [attachment_point_id, attachment] : mAttachmentPoints) { - LLViewerJointAttachment* attachment = iter->second; - - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) + for (auto& attached_object : attachment->mAttachedObjects) { - LLViewerObject* attached_object = attachment_iter->get(); - if (!attached_object + if (attached_object.isNull() || attached_object->isDead() || !attachment->getValid() || attached_object->mDrawable.isNull()) @@ -3161,7 +3229,7 @@ void LLVOAvatar::idleUpdateLipSync(bool voice_enabled) // Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync if ( voice_enabled && mLastRezzedStatus > 0 // no point updating lip-sync for clouds - && sLipSyncEnabled + && LLVoiceVisualizer::getLipSyncEnabled() && LLVoiceClient::getInstance()->getIsSpeaking( mID ) ) { F32 ooh_morph_amount = 0.0f; @@ -3738,21 +3806,22 @@ LLVector3 LLVOAvatar::idleCalcNameTagPosition(const LLVector3 &root_pos_last) name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av)); name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET; - const F32 water_height = getRegion()->getWaterHeight(); - static const F32 WATER_HEIGHT_DELTA = 0.25f; - if (name_position[VZ] < water_height + WATER_HEIGHT_DELTA) + // Avoid of crossing the name tag by the water surface + if (mNameText) { - if (LLViewerCamera::getInstance()->getOrigin()[VZ] >= water_height) + F32 water_height = getRegion()->getWaterHeight(); + static const F32 WATER_HEIGHT_ABOVE_DELTA = 0.25; + if (name_position[VZ] < water_height + WATER_HEIGHT_ABOVE_DELTA) { - name_position[VZ] = water_height; - } - else if (mNameText) // both camera and HUD are below watermark - { - F32 name_world_height = mNameText->getWorldHeight(); - F32 max_z_position = water_height - name_world_height; - if (name_position[VZ] > max_z_position) + F32 camera_height = LLViewerCamera::getInstance()->getOrigin()[VZ]; + if (camera_height >= water_height) { - name_position[VZ] = max_z_position; + F32 name_world_height = mNameText->getWorldHeight(); + static const F32 WATER_HEIGHT_BELOW_DELTA = 0.5; + if (name_position[VZ] + name_world_height > water_height - WATER_HEIGHT_BELOW_DELTA) + { + name_position[VZ] = water_height + WATER_HEIGHT_ABOVE_DELTA; + } } } } @@ -4978,27 +5047,22 @@ void LLVOAvatar::updateVisibility() { visible = true; } - else - { - visible = false; - } - if(isSelf()) + if (isSelf()) { if (!gAgentWearables.areWearablesLoaded()) { visible = false; } } - else if( !mFirstAppearanceMessageReceived ) + else if (!mFirstAppearanceMessageReceived) { visible = false; } if (sDebugInvisible) { - LLNameValue* firstname = getNVPair("FirstName"); - if (firstname) + if (LLNameValue* firstname = getNVPair("FirstName")) { LL_DEBUGS("Avatar") << avString() << " updating visibility" << LL_ENDL; } @@ -5087,11 +5151,14 @@ void LLVOAvatar::updateVisibility() } } - if ( visible != mVisible ) + if (visible != mVisible) { LL_DEBUGS("AvatarRender") << "visible was " << mVisible << " now " << visible << LL_ENDL; } + mVisible = visible; + + mVisibilityPreference = visible ? getPixelArea() : 0; } // private @@ -5400,14 +5467,6 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel) gGL.setSceneBlendType(LLRender::BT_ADD); gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); - // gGL.begin(LLRender::QUADS); - // gGL.vertex3fv((pos+left-up).mV); - // gGL.vertex3fv((pos-left-up).mV); - // gGL.vertex3fv((pos-left+up).mV); - // gGL.vertex3fv((pos+left+up).mV); - // gGL.end(); - - gGL.begin(LLRender::LINES); gGL.color4f(1.f,1.f,1.f,1.f); F32 thickness = llmax(F32(5.0f-5.0f*(gFrameTimeSeconds-mLastImpostorUpdateFrameTime)),1.0f); @@ -5428,15 +5487,22 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel) gGL.color4ubv(color.mV); gGL.getTexUnit(diffuse_channel)->bind(&mImpostor); - gGL.begin(LLRender::QUADS); - gGL.texCoord2f(0,0); - gGL.vertex3fv((pos+left-up).mV); - gGL.texCoord2f(1,0); - gGL.vertex3fv((pos-left-up).mV); - gGL.texCoord2f(1,1); - gGL.vertex3fv((pos-left+up).mV); - gGL.texCoord2f(0,1); - gGL.vertex3fv((pos+left+up).mV); + gGL.begin(LLRender::TRIANGLES); + { + gGL.texCoord2f(0.f, 0.f); + gGL.vertex3fv((pos + left - up).mV); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3fv((pos - left - up).mV); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex3fv((pos - left + up).mV); + + gGL.texCoord2f(0.f, 0.f); + gGL.vertex3fv((pos + left - up).mV); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex3fv((pos - left + up).mV); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3fv((pos + left + up).mV); + } gGL.end(); gGL.flush(); } @@ -7153,6 +7219,18 @@ void LLVOAvatar::updateVisualParams() dirtyMesh(); updateHeadOffset(); } + +void LLVOAvatar::setCorrectedPixelArea(F32 area) +{ + // We always want to look good to ourselves + if (isSelf()) + { + area = llmax(area, F32(getTexImageSize() / 16)); + } + + setPixelArea(area); +} + //----------------------------------------------------------------------------- // isActive() //----------------------------------------------------------------------------- @@ -7180,7 +7258,7 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) size.mul(0.5f); mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); - mPixelArea = mImpostorPixelArea; + setCorrectedPixelArea(mImpostorPixelArea); F32 range = mDrawable->mDistanceWRTCamera; @@ -7193,12 +7271,6 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) F32 radius = size.getLength3().getF32(); mAppAngle = (F32) atan2( radius, range) * RAD_TO_DEG; } - - // We always want to look good to ourselves - if( isSelf() ) - { - mPixelArea = llmax( mPixelArea, F32(getTexImageSize() / 16) ); - } } //----------------------------------------------------------------------------- @@ -8487,14 +8559,14 @@ bool LLVOAvatar::isFullyLoaded() const bool LLVOAvatar::isTooComplex() const { bool too_complex; - static LLCachedControl<S32> compelxity_render_mode(gSavedSettings, "RenderAvatarComplexityMode"); - bool render_friend = (isBuddy() && compelxity_render_mode > AV_RENDER_LIMIT_BY_COMPLEXITY); + static LLCachedControl<S32> complexity_render_mode(gSavedSettings, "RenderAvatarComplexityMode"); + bool render_friend = (isBuddy() && complexity_render_mode > AV_RENDER_LIMIT_BY_COMPLEXITY); if (isSelf() || render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER) { too_complex = false; } - else if (compelxity_render_mode == AV_RENDER_ONLY_SHOW_FRIENDS && !mIsControlAvatar) + else if (complexity_render_mode == AV_RENDER_ONLY_SHOW_FRIENDS && !mIsControlAvatar) { too_complex = true; } @@ -8522,16 +8594,16 @@ bool LLVOAvatar::isTooSlow() const return mTooSlow; } - static LLCachedControl<S32> compelxity_render_mode(gSavedSettings, "RenderAvatarComplexityMode"); + static LLCachedControl<S32> complexity_render_mode(gSavedSettings, "RenderAvatarComplexityMode"); static LLCachedControl<bool> friends_only(gSavedSettings, "RenderAvatarFriendsOnly", false); bool is_friend = isBuddy(); - bool render_friend = is_friend && compelxity_render_mode > AV_RENDER_LIMIT_BY_COMPLEXITY; + bool render_friend = is_friend && complexity_render_mode > AV_RENDER_LIMIT_BY_COMPLEXITY; if (render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER) { return false; } - else if (compelxity_render_mode == AV_RENDER_ONLY_SHOW_FRIENDS) + else if (complexity_render_mode == AV_RENDER_ONLY_SHOW_FRIENDS) { return true; } @@ -8547,7 +8619,7 @@ bool LLVOAvatar::isTooSlow() const void LLVOAvatar::updateTooSlow() { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - static LLCachedControl<S32> compelxity_render_mode(gSavedSettings, "RenderAvatarComplexityMode"); + static LLCachedControl<S32> complexity_render_mode(gSavedSettings, "RenderAvatarComplexityMode"); static LLCachedControl<bool> allowSelfImpostor(gSavedSettings, "AllowSelfImpostor"); const auto id = getID(); @@ -8580,14 +8652,14 @@ void LLVOAvatar::updateTooSlow() if(!mTooSlowWithoutShadows) // if we were not previously above the full impostor cap { - bool always_render_friends = compelxity_render_mode > AV_RENDER_LIMIT_BY_COMPLEXITY; + bool always_render_friends = complexity_render_mode > AV_RENDER_LIMIT_BY_COMPLEXITY; bool render_friend_or_exception = (always_render_friends && isBuddy()) || ( getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER ); if( (!isSelf() || allowSelfImpostor) && !render_friend_or_exception) { // Note: slow rendering Friends still get their shadows zapped. mTooSlowWithoutShadows = (getGPURenderTime()*2.f >= max_art_ms) // NOTE: assumes shadow rendering doubles render time - || (compelxity_render_mode == AV_RENDER_ONLY_SHOW_FRIENDS && !mIsControlAvatar); + || (complexity_render_mode == AV_RENDER_ONLY_SHOW_FRIENDS && !mIsControlAvatar); } } } @@ -8653,60 +8725,53 @@ void LLVOAvatar::updateMeshVisibility() if (getOverallAppearance() == AOA_NORMAL) { - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) + for (const auto& [attachment_point_id, attachment] : mAttachmentPoints) { - LLViewerJointAttachment* attachment = iter->second; - if (attachment) + if (!attachment) + continue; + + for (const auto& objectp : attachment->mAttachedObjects) { - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) + if (objectp.isNull()) + continue; + + for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++) { - LLViewerObject *objectp = attachment_iter->get(); - if (objectp) - { - for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++) - { - LLTextureEntry* tex_entry = objectp->getTE(face_index); - bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); - bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); - bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); - bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); - bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); - bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); - bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM); - bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG); - bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1); - bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2); - bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); - } - } + LLTextureEntry* tex_entry = objectp->getTE(face_index); + const auto& tex_id = tex_entry->getID(); + bake_flag[BAKED_HEAD] |= (tex_id == IMG_USE_BAKED_HEAD); + bake_flag[BAKED_EYES] |= (tex_id == IMG_USE_BAKED_EYES); + bake_flag[BAKED_HAIR] |= (tex_id == IMG_USE_BAKED_HAIR); + bake_flag[BAKED_LOWER] |= (tex_id == IMG_USE_BAKED_LOWER); + bake_flag[BAKED_UPPER] |= (tex_id == IMG_USE_BAKED_UPPER); + bake_flag[BAKED_SKIRT] |= (tex_id == IMG_USE_BAKED_SKIRT); + bake_flag[BAKED_LEFT_ARM] |= (tex_id == IMG_USE_BAKED_LEFTARM); + bake_flag[BAKED_LEFT_LEG] |= (tex_id == IMG_USE_BAKED_LEFTLEG); + bake_flag[BAKED_AUX1] |= (tex_id == IMG_USE_BAKED_AUX1); + bake_flag[BAKED_AUX2] |= (tex_id == IMG_USE_BAKED_AUX2); + bake_flag[BAKED_AUX3] |= (tex_id == IMG_USE_BAKED_AUX3); + } - LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); - iter1 != child_list.end(); ++iter1) + for (const auto& objectchild : objectp->getChildren()) + { + if (objectchild.isNull()) + continue; + + for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++) { - LLViewerObject* objectchild = *iter1; - if (objectchild) - { - for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++) - { - LLTextureEntry* tex_entry = objectchild->getTE(face_index); - bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); - bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); - bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); - bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); - bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); - bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); - bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM); - bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG); - bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1); - bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2); - bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); - } - } + LLTextureEntry* tex_entry = objectchild->getTE(face_index); + const auto& tex_id = tex_entry->getID(); + bake_flag[BAKED_HEAD] |= (tex_id == IMG_USE_BAKED_HEAD); + bake_flag[BAKED_EYES] |= (tex_id == IMG_USE_BAKED_EYES); + bake_flag[BAKED_HAIR] |= (tex_id == IMG_USE_BAKED_HAIR); + bake_flag[BAKED_LOWER] |= (tex_id == IMG_USE_BAKED_LOWER); + bake_flag[BAKED_UPPER] |= (tex_id == IMG_USE_BAKED_UPPER); + bake_flag[BAKED_SKIRT] |= (tex_id == IMG_USE_BAKED_SKIRT); + bake_flag[BAKED_LEFT_ARM] |= (tex_id == IMG_USE_BAKED_LEFTARM); + bake_flag[BAKED_LEFT_LEG] |= (tex_id == IMG_USE_BAKED_LEFTLEG); + bake_flag[BAKED_AUX1] |= (tex_id == IMG_USE_BAKED_AUX1); + bake_flag[BAKED_AUX2] |= (tex_id == IMG_USE_BAKED_AUX2); + bake_flag[BAKED_AUX3] |= (tex_id == IMG_USE_BAKED_AUX3); } } } @@ -9830,7 +9895,7 @@ void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& conte setCompositeUpdatesEnabled( true ); // If all of the avatars are completely baked, release the global image caches to conserve memory. - LLVOAvatar::cullAvatarsByPixelArea(); + cullAvatarsByPixelArea(); if (isSelf()) { @@ -10462,12 +10527,10 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara void LLVOAvatar::setVisibilityRank(U32 rank) { - if (mDrawable.isNull() || mDrawable->isDead()) + if (mDrawable.notNull() && !mDrawable->isDead()) { - // do nothing - return; + mVisibilityRank = rank; } - mVisibilityRank = rank; } // Assumes LLVOAvatar::sInstances has already been sorted. @@ -10498,32 +10561,34 @@ void LLVOAvatar::cullAvatarsByPixelArea() { LLCharacter::sInstances.sort([](LLCharacter* lhs, LLCharacter* rhs) { - return lhs->getPixelArea() > rhs->getPixelArea(); + return ((LLVOAvatar*)lhs)->mVisibilityPreference > ((LLVOAvatar*)rhs)->mVisibilityPreference; }); // Update the avatars that have changed status + U32 rank = 2; // Rank 1 is reserved for self. + for (LLCharacter* character : LLCharacter::sInstances) { - U32 rank = 2; //1 is reserved for self. - for (LLCharacter* character : LLCharacter::sInstances) - { - LLVOAvatar* inst = (LLVOAvatar*)character; - bool culled = !inst->isSelf() && !inst->isFullyBaked(); + LLVOAvatar* inst = (LLVOAvatar*)character; + bool culled = !inst->isSelf() && !inst->isFullyBaked(); - if (inst->mCulled != culled) - { - inst->mCulled = culled; - LL_DEBUGS() << "avatar " << inst->getID() << (culled ? " start culled" : " start not culled" ) << LL_ENDL; - inst->updateMeshTextures(); - } + if (inst->mCulled != culled) + { + inst->mCulled = culled; + LL_DEBUGS() << "avatar " << inst->getID() << (culled ? " start culled" : " start not culled" ) << LL_ENDL; + inst->updateMeshTextures(); + } - if (inst->isSelf()) - { - inst->setVisibilityRank(1); - } - else if (inst->mDrawable.notNull() && inst->mDrawable->isVisible()) - { - inst->setVisibilityRank(rank++); - } + if (inst->isSelf()) + { + inst->setVisibilityRank(1); + } + else if (inst->mDrawable.notNull() && inst->mDrawable->isVisible()) + { + inst->setVisibilityRank(rank++); + } + else + { + inst->setVisibilityRank(sMaxNonImpostors * 5); } } @@ -10721,31 +10786,39 @@ void LLVOAvatar::updateRiggingInfo() LL_DEBUGS("RigSpammish") << getFullname() << " updating rig tab" << LL_ENDL; - std::vector<LLVOVolume*> volumes; + // use a local static for scratch space to avoid reallocation here + static std::vector<LLVOVolume*> volumes; + volumes.resize(0); getAssociatedVolumes(volumes); - std::map<LLUUID, S32> curr_rigging_info_key; - - // Get current rigging info key - for (LLVOVolume* vol : volumes) { - if (vol->isMesh() && vol->getVolume()) + LL_PROFILE_ZONE_NAMED_CATEGORY_AVATAR("update rig info - get key"); + size_t hash = 0; + // Get current rigging info key + for (LLVOVolume* vol : volumes) + { + if (vol->isRiggedMesh()) + { + const LLUUID& mesh_id = vol->getVolume()->getParams().getSculptID(); + S32 max_lod = llmax(vol->getLOD(), vol->mLastRiggingInfoLOD); + + boost::hash_combine(hash, mesh_id); + boost::hash_combine(hash, max_lod); + } + } + + // Check for key change, which indicates some change in volume composition or LOD. + if (hash == mLastRiggingInfoKey) { - const LLUUID& mesh_id = vol->getVolume()->getParams().getSculptID(); - S32 max_lod = llmax(vol->getLOD(), vol->mLastRiggingInfoLOD); - curr_rigging_info_key[mesh_id] = max_lod; + return; } - } - // Check for key change, which indicates some change in volume composition or LOD. - if (curr_rigging_info_key == mLastRiggingInfoKey) - { - return; + + // Something changed. Update. + mLastRiggingInfoKey = hash; } - // Something changed. Update. - mLastRiggingInfoKey = curr_rigging_info_key; mJointRiggingInfoTab.clear(); for (LLVOVolume* vol : volumes) { |