diff options
author | Nyx (Neal Orman) <nyx@lindenlab.com> | 2011-02-03 19:45:29 -0500 |
---|---|---|
committer | Nyx (Neal Orman) <nyx@lindenlab.com> | 2011-02-03 19:45:29 -0500 |
commit | fbfecd49c7f8f6dafc36cf56c0331a1207765f22 (patch) | |
tree | ade21fd1a63d87d1cb318c7c4b3262c90e79aab9 /indra/newview/llvovolume.cpp | |
parent | 33f82d788502a036953b676bfcb709d968b2a569 (diff) |
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.
Diffstat (limited to 'indra/newview/llvovolume.cpp')
-rw-r--r-- | indra/newview/llvovolume.cpp | 224 |
1 files changed, 83 insertions, 141 deletions
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;
|