diff options
Diffstat (limited to 'indra/newview/llvovolume.cpp')
-rw-r--r-- | indra/newview/llvovolume.cpp | 211 |
1 files changed, 191 insertions, 20 deletions
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 0a7611c527..bf4cfc870f 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2872,17 +2872,31 @@ 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(std::set<LLUUID> &textures) const +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 + LLVolumeParams volume_params = getVolume()->getParams(); + LLPathParams path_params = volume_params.getPathParams(); + LLProfileParams profile_params = volume_params.getProfileParams(); + // per-prim costs 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; + 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_TWIST_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; // per-face costs static const U32 ARC_PLANAR_COST = 1; @@ -2901,6 +2915,61 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const U32 scale = 0; U32 bump = 0; U32 planar = 0; + U32 cuts = 0; + U32 hollow = 0; + U32 twist = 0; + U32 circular_profile = 0; + U32 circular_path = 0; + + const LLDrawable* drawablep = mDrawable; + + 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) + { + 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); + } + + if (shame == 0) + { + // someone made a really tiny mesh. + shame = 1; + } + } + 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 = ARC_TEXTURE_COST * (texture->getFullHeight() / 128 + texture->getFullWidth() / 128 + 1); + textures.insert(texture_cost_t::value_type(sculpt_id, texture_cost)); + } + } + } + } if (isFlexible()) { @@ -2913,14 +2982,63 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const const LLVector3& sc = getScale(); scale += (U32) sc.mV[0] + (U32) sc.mV[1] + (U32) sc.mV[2]; + if (scale > 4) + { + // scale is a multiplier, cap it at 4. + scale = 4; + } - const LLDrawable* drawablep = mDrawable; + // add points for cut prims + if (path_params.getBegin() != 0.f || path_params.getEnd() != 1.f) + { + ++cuts; + } - if (isSculpted()) + if (profile_params.getBegin() != 0.f || profile_params.getEnd() != 1.f) + { + ++cuts; + } + + // double cost for hollow prims / sculpties + if (volume_params.getHollow() != 0.f) { - const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID sculpt_id = sculpt_params->getSculptTexture(); - textures.insert(sculpt_id); + hollow = 1; + } + + // twist - scale by twist extent / 90 + if (volume_params.getTwistBegin() != 0.f) + { + U32 scale = abs((S32)(volume_params.getTwistBegin() / 90.f) + 1); + twist += scale; + } + + // twist - scale by twist extent / 90 + if (volume_params.getTwist() != 0.f) + { + U32 scale = abs((S32)(volume_params.getTwist() / 90.f) + 1); + twist += scale; + } + + // 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; } for (S32 i = 0; i < drawablep->getNumFaces(); ++i) @@ -2931,7 +3049,11 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const if (img) { - textures.insert(img->getID()); + if (textures.find(img->getID()) == textures.end()) + { + S32 texture_cost = ARC_TEXTURE_COST * (img->getFullHeight() / 128 + img->getFullWidth() / 128 + 1); + textures.insert(texture_cost_t::value_type(img->getID(), texture_cost)); + } } if (face->getPoolType() == LLDrawPool::POOL_ALPHA) @@ -2940,21 +3062,24 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const } else if (img && img->getPrimaryFormat() == GL_ALPHA) { - invisi = 1; + invisi++; } if (te) { 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) @@ -2968,17 +3093,63 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const } } + // shame currently has the "base" cost of 10 for normal prims, variable for mesh - 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; + // 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; + + // multiply shame by multipliers + if (hollow) + { + shame *= hollow * ARC_HOLLOW_MULT; + } + + if (twist) + { + shame *= twist * ARC_TWIST_MULT; + } + + if (circular_profile) + { + shame *= circular_profile * ARC_CIRC_PROF_MULT; + } + + if (circular_path) + { + shame *= circular_path * ARC_CIRC_PATH_MULT; + } + + if (glow) + { + shame *= glow * ARC_GLOW_MULT; + } + + if (bump) + { + shame *= bump * ARC_BUMP_MULT; + } + + if (flexi) + { + shame *= flexi * ARC_FLEXI_MULT; + } + + if (shiny) + { + shame *= shiny * ARC_SHINY_MULT; + } + + if (scale) + { + shame *= scale; + } + + // add additional costs shame += particles * ARC_PARTICLE_COST; - shame += bump * ARC_BUMP_COST; - shame += planar * ARC_PLANAR_COST; - shame += scale; LLViewerObject::const_child_list_t& child_list = getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); |