From fbfecd49c7f8f6dafc36cf56c0331a1207765f22 Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Thu, 3 Feb 2011 19:45:29 -0500 Subject: SH-861 FIX update render cost algorithm to use geometry triangle counts base cost is now geometry-based, for both meshes and prims Some of the previous weights have been recalibrated based on testing. Code reviewed by davep. Deferring QA for now until the other parts of the algorithm are updated, as re-generating the test takes time each time the algorithm changes. --- indra/newview/llvovolume.cpp | 224 ++++++++++++++++--------------------------- indra/newview/llvovolume.h | 2 +- 2 files changed, 84 insertions(+), 142 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 55e68d61f9..a388d2ef30 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2933,44 +2933,32 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const // children, and cost should only be increased for unique textures -Nyx U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const { - // base cost of each prim should be 10 points - static const U32 ARC_PRIM_COST = 10; - // 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). - const BOOL has_volume = (getVolume() != NULL); + BOOL has_volume = (getVolume() != NULL); LLVolumeParams volume_params; LLPathParams path_params; LLProfileParams profile_params; - if (has_volume) - { - volume_params = getVolume()->getParams(); - path_params = volume_params.getPathParams(); - profile_params = volume_params.getProfileParams(); - } - + U32 num_triangles = 0; + // per-prim costs - static const U32 ARC_INVISI_COST = 1; static const U32 ARC_PARTICLE_COST = 100; - static const U32 ARC_CUT_COST = 1; static const U32 ARC_TEXTURE_COST = 5; // per-prim multipliers - static const U32 ARC_HOLLOW_MULT = 2; - static const U32 ARC_CIRC_PROF_MULT = 2; - static const U32 ARC_CIRC_PATH_MULT = 2; - static const U32 ARC_GLOW_MULT = 2; - static const U32 ARC_BUMP_MULT = 2; - static const U32 ARC_FLEXI_MULT = 4; - static const U32 ARC_SHINY_MULT = 2; + static const F32 ARC_GLOW_MULT = 1.5f; // tested based on performance + static const F32 ARC_BUMP_MULT = 1.25f; // tested based on performance + static const F32 ARC_FLEXI_MULT = 4; + static const F32 ARC_SHINY_MULT = 1.6f; // tested based on performance + static const F32 ARC_INVISI_COST = 1.2f; // tested based on performance + static const F32 ARC_WEIGHTED_MESH = 1.2f; - // per-face costs - static const U32 ARC_PLANAR_COST = 1; - static const U32 ARC_ANIM_TEX_COST = 4; - static const U32 ARC_ALPHA_COST = 4; + static const F32 ARC_PLANAR_COST = 1.2f; // 1.2x max + static const F32 ARC_ANIM_TEX_COST = 1.4f; // 1.4x max + static const F32 ARC_ALPHA_COST = 4.f; // 4x max - U32 shame = ARC_PRIM_COST; + F32 shame = 0; U32 invisi = 0; U32 shiny = 0; @@ -2981,18 +2969,41 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const U32 particles = 0; U32 bump = 0; U32 planar = 0; - U32 cuts = 0; - U32 hollow = 0; - U32 circular_profile = 0; - U32 circular_path = 0; + U32 weighted_mesh = 0; // these multipliers are variable and can be floating point F32 scale = 0.f; - F32 twist = 0.f; - F32 revolutions = 0.f; - const LLDrawable* drawablep = mDrawable; + U32 num_faces = drawablep->getNumFaces(); + + if (has_volume) + { + volume_params = getVolume()->getParams(); + path_params = volume_params.getPathParams(); + profile_params = volume_params.getProfileParams(); + + F32 radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length(); + S32 default_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3); + if (default_detail == getLOD()) + { + num_triangles = getTriangleCount(); + } + else + { + LLVolume* default_volume = LLPrimitive::getVolumeManager()->refVolume(volume_params, default_detail); + if(default_volume != NULL) + { + num_triangles = default_volume->getNumTriangles(); + LLPrimitive::getVolumeManager()->unrefVolume(default_volume); + default_volume = NULL; + } + else + { + has_volume = false; + } + } + } if (isSculpted()) { @@ -3003,21 +3014,17 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(),3); if ( size > 0) { + num_triangles = (U32)(size / 10.f); // avg 1 triangle per 10 bytes if (gMeshRepo.getSkinInfo(volume_params.getSculptID())) { // weighted attachment - 1 point for every 3 bytes - shame = (U32)(size / 3.f); - } - else - { - // non-weighted attachment - 1 point for every 4 bytes - shame = (U32)(size / 4.f); + weighted_mesh = 1; } - if (shame == 0) + if (num_triangles == 0) { - // someone made a really tiny mesh. - shame = 1; + // someone made a really tiny mesh. Approximate with a tetrahedron. + num_triangles = 4; } } else @@ -3052,70 +3059,12 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const } const LLVector3& sc = getScale(); - scale += sc.mV[0] + sc.mV[1] + sc.mV[2]; - if (scale > 4.f) - { - // scale is a multiplier, cap it at 4. - scale = 4.f; - } - - // add points for cut prims - if (path_params.getBegin() != 0.f || path_params.getEnd() != 1.f) - { - ++cuts; - } - - if (profile_params.getBegin() != 0.f || profile_params.getEnd() != 1.f) - { - ++cuts; - } - - // double cost for hollow prims / sculpties - if (volume_params.getHollow() != 0.f) - { - hollow = 1; - } - - F32 twist_mag = path_params.getTwistBegin() - path_params.getTwistEnd(); - if (twist_mag < 0) - { - twist_mag *= -1.f; - } - - // note magnitude of twist is [-1.f, 1.f]. which translates to [-180, 180] degrees. - // scale to degrees / 90 by multiplying by 2. - twist = twist_mag * 2.f; - - // multiply by the number of revolutions in the prim. cap at 4. - revolutions = path_params.getRevolutions(); - if (revolutions > 4.f) - { - revolutions = 4.f; - } - - // double cost for circular profiles / sculpties - if (profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE || - profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE_HALF) - { - circular_profile = 1; - } - - // double cost for circular paths / sculpties - if (path_params.getCurveType() == LL_PCODE_PATH_CIRCLE || - path_params.getCurveType() == LL_PCODE_PATH_CIRCLE2) - { - circular_path = 1; - } - - // treat sculpties as hollow prims with circular paths & profiles - if (isSculpted() && !isMesh()) - { - hollow = 1; - circular_profile = 1; - circular_path = 1; - } + scale += (sc.mV[0] + sc.mV[1] + sc.mV[2]) / 4.f; // scale to 1/4 the sum of the size + // enforce scale multiplier to be in the range [1,7] (7 was determined to experimentally be a reasonable max) + scale = scale > 7.f ? 7.f : scale; + scale = scale < 1.f ? 1.f : scale; - for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + for (S32 i = 0; i < num_faces; ++i) { const LLFace* face = drawablep->getFace(i); const LLTextureEntry* te = face->getTextureEntry(); @@ -3132,11 +3081,11 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const if (face->getPoolType() == LLDrawPool::POOL_ALPHA) { - alpha++; + alpha = 1; } else if (img && img->getPrimaryFormat() == GL_ALPHA) { - invisi++; + invisi = 1; } if (te) @@ -3158,38 +3107,41 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const } if (face->mTextureMatrix != NULL) { - animtex++; + animtex = 1; } if (te->getTexGen()) { - planar++; + planar = 1; } } } - // shame currently has the "base" cost of 10 for normal prims, variable for mesh + // shame currently has the "base" cost of 1 point per 50 triangles, min 2. + shame = num_triangles / 50.f; + shame = shame < 2.f ? 2.f : shame; - // add modifier settings - shame += cuts * ARC_CUT_COST; - shame += planar * ARC_PLANAR_COST; - shame += animtex * ARC_ANIM_TEX_COST; - shame += alpha * ARC_ALPHA_COST; - shame += invisi * ARC_INVISI_COST; + // factor in scale + shame *= scale; - // multiply shame by multipliers - if (hollow) + // multiply by per-face modifiers + if (planar) + { + shame *= planar * ARC_PLANAR_COST; + } + + if (animtex) { - shame *= hollow * ARC_HOLLOW_MULT; + shame *= animtex * ARC_ANIM_TEX_COST; } - if (circular_profile) + if (alpha) { - shame *= circular_profile * ARC_CIRC_PROF_MULT; + shame *= alpha * ARC_ALPHA_COST; } - if (circular_path) + if(invisi) { - shame *= circular_path * ARC_CIRC_PATH_MULT; + shame *= invisi * ARC_INVISI_COST; } if (glow) @@ -3202,35 +3154,28 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const shame *= bump * ARC_BUMP_MULT; } - if (flexi) - { - shame *= flexi * ARC_FLEXI_MULT; - } - if (shiny) { shame *= shiny * ARC_SHINY_MULT; } - if (twist > 1.f) - { - shame = (U32)(shame * twist); - } - if (scale > 1.f) + // multiply shame by multipliers + if (weighted_mesh) { - shame = (U32)(shame *scale); + shame *= weighted_mesh * ARC_WEIGHTED_MESH; } - if (revolutions > 1.f) + if (flexi) { - shame = (U32)(shame * revolutions); + shame *= flexi * ARC_FLEXI_MULT; } + // add additional costs shame += particles * ARC_PARTICLE_COST; - return shame; + return (U32)shame; } F32 LLVOVolume::getStreamingCost() @@ -3247,16 +3192,13 @@ F32 LLVOVolume::getStreamingCost() return 0.f; } -U32 LLVOVolume::getTriangleCount() +U32 LLVOVolume::getTriangleCount() const { U32 count = 0; LLVolume* volume = getVolume(); if (volume) { - for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) - { - count += volume->getVolumeFace(i).mNumIndices/3; - } + count = volume->getNumTriangles(); } return count; diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 5af88c6cbd..e02a5d5675 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -132,7 +132,7 @@ public: typedef std::map texture_cost_t; U32 getRenderCost(texture_cost_t &textures) const; /*virtual*/ F32 getStreamingCost(); - /*virtual*/ U32 getTriangleCount(); + /*virtual*/ U32 getTriangleCount() const; /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, -- cgit v1.2.3 From 44308a6693d1c79433db1dcad25f9846601f1c6c Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Mon, 7 Feb 2011 20:12:42 -0500 Subject: SH-923 FIX particle render cost does not appear to be functioning properly was checking the age of the particle system, not the individual particles. This appears to fix the problem. Deferring QA on the new algorithm until it is completed. --- indra/newview/llvovolume.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index a388d2ef30..c65b888bf9 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2943,7 +2943,8 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const U32 num_triangles = 0; // per-prim costs - static const U32 ARC_PARTICLE_COST = 100; + static const U32 ARC_PARTICLE_COST = 1; + static const U32 ARC_PARTICLE_MAX = 2048; static const U32 ARC_TEXTURE_COST = 5; // per-prim multipliers @@ -3173,7 +3174,15 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const // add additional costs - shame += particles * ARC_PARTICLE_COST; + if (particles) + { + const LLPartSysData *part_sys_data = &(mPartSourcep->mPartSysData); + const LLPartData *part_data = &(part_sys_data->mPartData); + U32 num_particles = (U32)(part_sys_data->mBurstPartCount * llceil( part_data->mMaxAge / part_sys_data->mBurstRate)); + num_particles = num_particles > ARC_PARTICLE_MAX ? ARC_PARTICLE_MAX : num_particles; + F32 part_size = (llmax(part_data->mStartScale[0], part_data->mEndScale[0]) + llmax(part_data->mStartScale[1], part_data->mEndScale[1])) / 2.f; + shame += num_particles * part_size * ARC_PARTICLE_COST; + } return (U32)shame; } -- cgit v1.2.3 From 8b15ca8d6b9cf516670e66ee57591e79b898394d Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Mon, 7 Feb 2011 21:03:10 -0500 Subject: SH-930 FIX revert ARC algorithm for merge to viewer-development Reverting incomplete changes to ARC so that we don't change RC when we merge down. --- indra/newview/llfloatertools.cpp | 32 +++++- indra/newview/llfloatertools.h | 1 + indra/newview/llselectmgr.cpp | 4 +- indra/newview/llvoavatar.cpp | 16 +-- indra/newview/llvovolume.cpp | 237 +++++++++------------------------------ indra/newview/llvovolume.h | 5 +- 6 files changed, 97 insertions(+), 198 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index c9b99d83ff..f5e3d160fc 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -451,8 +451,7 @@ void LLFloaterTools::refresh() if (sShowObjectCost) { std::string prim_cost_string; - S32 cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost(); - LLResMgr::getInstance()->getIntegerString(prim_cost_string, cost); + LLResMgr::getInstance()->getIntegerString(prim_cost_string, calcRenderCost()); getChild("RenderingCost")->setTextArg("[COUNT]", prim_cost_string); } @@ -1010,6 +1009,35 @@ void LLFloaterTools::onClickGridOptions() //floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE); } +S32 LLFloaterTools::calcRenderCost() +{ + S32 cost = 0; + std::set textures; + + for (LLObjectSelection::iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->begin(); + selection_iter != LLSelectMgr::getInstance()->getSelection()->end(); + ++selection_iter) + { + LLSelectNode *select_node = *selection_iter; + if (select_node) + { + LLViewerObject *vobj = select_node->getObject(); + if (vobj->getVolume()) + { + LLVOVolume* volume = (LLVOVolume*) vobj; + + cost += volume->getRenderCost(textures); + cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST; + textures.clear(); + } + } + } + + + return cost; +} + + // static void LLFloaterTools::setEditTool(void* tool_pointer) { diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index d5595445e0..87c3d2ab47 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -114,6 +114,7 @@ private: static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response); static void setObjectType( LLPCode pcode ); void onClickGridOptions(); + S32 calcRenderCost(); public: LLButton *mBtnFocus; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 8ffbd5510d..e0b9f1d736 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -6395,7 +6395,7 @@ U32 LLObjectSelection::getSelectedObjectTriangleCount() return count; } -S32 LLObjectSelection::getSelectedObjectRenderCost() +/*S32 LLObjectSelection::getSelectedObjectRenderCost() { S32 cost = 0; LLVOVolume::texture_cost_t textures; @@ -6419,7 +6419,7 @@ S32 LLObjectSelection::getSelectedObjectRenderCost() return cost; -} +}*/ //----------------------------------------------------------------------------- diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index dd6f7011a1..ec264b1f07 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -8241,7 +8241,7 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d void LLVOAvatar::idleUpdateRenderCost() { - static const U32 ARC_BODY_PART_COST = 200; + static const U32 ARC_BODY_PART_COST = 20; static const U32 ARC_LIMIT = 2048; static std::set all_textures; @@ -8252,7 +8252,7 @@ void LLVOAvatar::idleUpdateRenderCost() } U32 cost = 0; - LLVOVolume::texture_cost_t textures; + std::set textures; for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { @@ -8293,21 +8293,15 @@ void LLVOAvatar::idleUpdateRenderCost() } - for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) - { - // add the cost of each individual texture in the linkset - cost += iter->second; - } - // Diagnostic output to identify all avatar-related textures. // Does not affect rendering cost calculation. // Could be wrapped in a debug option if output becomes problematic. if (isSelf()) { // print any attachment textures we didn't already know about. - for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it) + for (std::set::iterator it = textures.begin(); it != textures.end(); ++it) { - LLUUID image_id = it->first; + LLUUID image_id = *it; if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) continue; if (all_textures.find(image_id) == all_textures.end()) @@ -8339,6 +8333,8 @@ void LLVOAvatar::idleUpdateRenderCost() } } + cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST; + setDebugText(llformat("%d", cost)); F32 green = 1.f-llclamp(((F32) cost-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f); F32 red = llmin((F32) cost/(F32)ARC_LIMIT, 1.f); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c65b888bf9..8f1a761549 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2931,35 +2931,24 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const // total cost is returned value + 5 * size of the resulting set. // Cannot include cost of textures, as they may be re-used in linked // children, and cost should only be increased for unique textures -Nyx -U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const +U32 LLVOVolume::getRenderCost(std::set &textures) const { - // 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); - LLVolumeParams volume_params; - LLPathParams path_params; - LLProfileParams profile_params; - - U32 num_triangles = 0; - + // base cost of each prim should be 10 points + static const U32 ARC_PRIM_COST = 10; // per-prim costs - static const U32 ARC_PARTICLE_COST = 1; - static const U32 ARC_PARTICLE_MAX = 2048; - static const U32 ARC_TEXTURE_COST = 5; + static const U32 ARC_INVISI_COST = 1; + static const U32 ARC_SHINY_COST = 1; + static const U32 ARC_GLOW_COST = 1; + static const U32 ARC_FLEXI_COST = 8; + static const U32 ARC_PARTICLE_COST = 16; + static const U32 ARC_BUMP_COST = 4; - // per-prim multipliers - static const F32 ARC_GLOW_MULT = 1.5f; // tested based on performance - static const F32 ARC_BUMP_MULT = 1.25f; // tested based on performance - static const F32 ARC_FLEXI_MULT = 4; - static const F32 ARC_SHINY_MULT = 1.6f; // tested based on performance - static const F32 ARC_INVISI_COST = 1.2f; // tested based on performance - static const F32 ARC_WEIGHTED_MESH = 1.2f; + // per-face costs + static const U32 ARC_PLANAR_COST = 1; + static const U32 ARC_ANIM_TEX_COST = 4; + static const U32 ARC_ALPHA_COST = 4; - static const F32 ARC_PLANAR_COST = 1.2f; // 1.2x max - static const F32 ARC_ANIM_TEX_COST = 1.4f; // 1.4x max - static const F32 ARC_ALPHA_COST = 4.f; // 4x max - - F32 shame = 0; + U32 shame = ARC_PRIM_COST; U32 invisi = 0; U32 shiny = 0; @@ -2968,87 +2957,9 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const U32 flexi = 0; U32 animtex = 0; U32 particles = 0; + U32 scale = 0; U32 bump = 0; U32 planar = 0; - U32 weighted_mesh = 0; - - // these multipliers are variable and can be floating point - F32 scale = 0.f; - - const LLDrawable* drawablep = mDrawable; - U32 num_faces = drawablep->getNumFaces(); - - if (has_volume) - { - volume_params = getVolume()->getParams(); - path_params = volume_params.getPathParams(); - profile_params = volume_params.getProfileParams(); - - F32 radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length(); - S32 default_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3); - if (default_detail == getLOD()) - { - num_triangles = getTriangleCount(); - } - else - { - LLVolume* default_volume = LLPrimitive::getVolumeManager()->refVolume(volume_params, default_detail); - if(default_volume != NULL) - { - num_triangles = default_volume->getNumTriangles(); - LLPrimitive::getVolumeManager()->unrefVolume(default_volume); - default_volume = NULL; - } - else - { - has_volume = false; - } - } - } - - if (isSculpted()) - { - if (isMesh()) - { - // 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); - if ( size > 0) - { - num_triangles = (U32)(size / 10.f); // avg 1 triangle per 10 bytes - if (gMeshRepo.getSkinInfo(volume_params.getSculptID())) - { - // weighted attachment - 1 point for every 3 bytes - weighted_mesh = 1; - } - - if (num_triangles == 0) - { - // someone made a really tiny mesh. Approximate with a tetrahedron. - num_triangles = 4; - } - } - else - { - // something went wrong - user should know their content isn't render-free - return 0; - } - } - else - { - const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID sculpt_id = sculpt_params->getSculptTexture(); - if (textures.find(sculpt_id) == textures.end()) - { - LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(sculpt_id); - if (texture) - { - S32 texture_cost = (S32)(ARC_TEXTURE_COST * (texture->getFullHeight() / 128.f + texture->getFullWidth() / 128.f + 1)); - textures.insert(texture_cost_t::value_type(sculpt_id, texture_cost)); - } - } - } - } if (isFlexible()) { @@ -3060,12 +2971,18 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const } const LLVector3& sc = getScale(); - scale += (sc.mV[0] + sc.mV[1] + sc.mV[2]) / 4.f; // scale to 1/4 the sum of the size - // enforce scale multiplier to be in the range [1,7] (7 was determined to experimentally be a reasonable max) - scale = scale > 7.f ? 7.f : scale; - scale = scale < 1.f ? 1.f : scale; + scale += (U32) sc.mV[0] + (U32) sc.mV[1] + (U32) sc.mV[2]; + + const LLDrawable* drawablep = mDrawable; - for (S32 i = 0; i < num_faces; ++i) + if (isSculpted()) + { + const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT); + LLUUID sculpt_id = sculpt_params->getSculptTexture(); + textures.insert(sculpt_id); + } + + for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { const LLFace* face = drawablep->getFace(i); const LLTextureEntry* te = face->getTextureEntry(); @@ -3073,16 +2990,12 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const if (img) { - if (textures.find(img->getID()) == textures.end()) - { - S32 texture_cost = (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f + 1)); - textures.insert(texture_cost_t::value_type(img->getID(), texture_cost)); - } + textures.insert(img->getID()); } if (face->getPoolType() == LLDrawPool::POOL_ALPHA) { - alpha = 1; + alpha++; } else if (img && img->getPrimaryFormat() == GL_ALPHA) { @@ -3093,98 +3006,58 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const { if (te->getBumpmap()) { - // bump is a multiplier, don't add per-face bump = 1; } if (te->getShiny()) { - // shiny is a multiplier, don't add per-face shiny = 1; } if (te->getGlow() > 0.f) { - // glow is a multiplier, don't add per-face glow = 1; } if (face->mTextureMatrix != NULL) { - animtex = 1; + animtex++; } if (te->getTexGen()) { - planar = 1; + planar++; } } } - // shame currently has the "base" cost of 1 point per 50 triangles, min 2. - shame = num_triangles / 50.f; - shame = shame < 2.f ? 2.f : shame; - - // factor in scale - shame *= scale; - - // multiply by per-face modifiers - if (planar) - { - shame *= planar * ARC_PLANAR_COST; - } - - if (animtex) - { - shame *= animtex * ARC_ANIM_TEX_COST; - } - - if (alpha) - { - shame *= alpha * ARC_ALPHA_COST; - } - - if(invisi) - { - shame *= invisi * ARC_INVISI_COST; - } - - if (glow) - { - shame *= glow * ARC_GLOW_MULT; - } - - if (bump) - { - shame *= bump * ARC_BUMP_MULT; - } - - if (shiny) - { - shame *= shiny * ARC_SHINY_MULT; - } + shame += invisi * ARC_INVISI_COST; + shame += shiny * ARC_SHINY_COST; + shame += glow * ARC_GLOW_COST; + shame += alpha * ARC_ALPHA_COST; + shame += flexi * ARC_FLEXI_COST; + shame += animtex * ARC_ANIM_TEX_COST; + shame += particles * ARC_PARTICLE_COST; + shame += bump * ARC_BUMP_COST; + shame += planar * ARC_PLANAR_COST; + shame += scale; - // multiply shame by multipliers - if (weighted_mesh) + LLViewerObject::const_child_list_t& child_list = getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); + ++iter) { - shame *= weighted_mesh * ARC_WEIGHTED_MESH; - } - - if (flexi) - { - shame *= flexi * ARC_FLEXI_MULT; + const LLViewerObject* child_objectp = *iter; + const LLDrawable* child_drawablep = child_objectp->mDrawable; + if (child_drawablep) + { + const LLVOVolume* child_volumep = child_drawablep->getVOVolume(); + if (child_volumep) + { + shame += child_volumep->getRenderCost(textures); + } + } } + return shame; - // add additional costs - if (particles) - { - const LLPartSysData *part_sys_data = &(mPartSourcep->mPartSysData); - const LLPartData *part_data = &(part_sys_data->mPartData); - U32 num_particles = (U32)(part_sys_data->mBurstPartCount * llceil( part_data->mMaxAge / part_sys_data->mBurstRate)); - num_particles = num_particles > ARC_PARTICLE_MAX ? ARC_PARTICLE_MAX : num_particles; - F32 part_size = (llmax(part_data->mStartScale[0], part_data->mEndScale[0]) + llmax(part_data->mStartScale[1], part_data->mEndScale[1])) / 2.f; - shame += num_particles * part_size * ARC_PARTICLE_COST; - } - - return (U32)shame; } F32 LLVOVolume::getStreamingCost() diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index e02a5d5675..0c12f14832 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -129,8 +129,7 @@ public: const LLMatrix4& getRelativeXform() const { return mRelativeXform; } const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; } /*virtual*/ const LLMatrix4 getRenderMatrix() const; - typedef std::map texture_cost_t; - U32 getRenderCost(texture_cost_t &textures) const; + U32 getRenderCost(std::set &textures) const; /*virtual*/ F32 getStreamingCost(); /*virtual*/ U32 getTriangleCount() const; /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, @@ -359,6 +358,8 @@ public: static LLPointer sObjectMediaClient; static LLPointer sObjectMediaNavigateClient; + static const U32 ARC_TEXTURE_COST = 5; + protected: static S32 sNumLODChanges; -- cgit v1.2.3