Meshy update. Mostly related to cost calculations... mostly.
This commit is contained in:
@@ -93,6 +93,8 @@ F32 LLVOVolume::sLODFactor = 1.f;
|
||||
F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop
|
||||
F32 LLVOVolume::sDistanceFactor = 1.0f;
|
||||
S32 LLVOVolume::sNumLODChanges = 0;
|
||||
S32 LLVOVolume::mRenderComplexity_last = 0;
|
||||
S32 LLVOVolume::mRenderComplexity_current = 0;
|
||||
|
||||
LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
|
||||
: LLViewerObject(id, pcode, regionp),
|
||||
@@ -489,18 +491,24 @@ BOOL LLVOVolume::isVisible() const
|
||||
|
||||
return FALSE ;
|
||||
}
|
||||
void LLVOVolume::updateTextureVirtualSize()
|
||||
|
||||
void LLVOVolume::updateTextureVirtualSize(bool forced)
|
||||
{
|
||||
// Update the pixel area of all faces
|
||||
|
||||
if(!isVisible() || mDrawable.isNull())
|
||||
{
|
||||
if(mDrawable.isNull())
|
||||
return;
|
||||
}
|
||||
if(!forced)
|
||||
{
|
||||
if(!isVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE))
|
||||
{
|
||||
return;
|
||||
if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static LLCachedControl<bool> dont_load_textures(gSavedSettings,"TextureDisable");
|
||||
@@ -559,12 +567,12 @@ void LLVOVolume::updateTextureVirtualSize()
|
||||
// Animating textures also rez badly in Snowglobe because the
|
||||
// actual displayed area is only a fraction (corresponding to one
|
||||
// frame) of the animating texture. Let's fix that here:
|
||||
if (mTextureAnimp && mTextureAnimp->mScaleS > 0.0f && mTextureAnimp->mScaleT > 0.0f)
|
||||
/* if (mTextureAnimp && mTextureAnimp->mScaleS > 0.0f && mTextureAnimp->mScaleT > 0.0f)
|
||||
{
|
||||
// Adjust to take into account the actual frame size which is only a
|
||||
// portion of the animating texture
|
||||
vsize = vsize / mTextureAnimp->mScaleS / mTextureAnimp->mScaleT;
|
||||
}
|
||||
}*/
|
||||
|
||||
if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) ||
|
||||
(vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE))
|
||||
@@ -578,13 +586,17 @@ void LLVOVolume::updateTextureVirtualSize()
|
||||
if (vsize < min_vsize) min_vsize = vsize;
|
||||
if (vsize > max_vsize) max_vsize = vsize;
|
||||
}
|
||||
// else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
|
||||
// {
|
||||
// F32 pri = imagep->getDecodePriority();
|
||||
// pri = llmax(pri, 0.0f);
|
||||
// if (pri < min_vsize) min_vsize = pri;
|
||||
// if (pri > max_vsize) max_vsize = pri;
|
||||
// }
|
||||
else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
|
||||
{
|
||||
LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ;
|
||||
if(img)
|
||||
{
|
||||
F32 pri = img->getDecodePriority();
|
||||
pri = llmax(pri, 0.0f);
|
||||
if (pri < min_vsize) min_vsize = pri;
|
||||
if (pri > max_vsize) max_vsize = pri;
|
||||
}
|
||||
}
|
||||
else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
|
||||
{
|
||||
F32 pri = mPixelArea;
|
||||
@@ -657,10 +669,10 @@ void LLVOVolume::updateTextureVirtualSize()
|
||||
{
|
||||
setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
|
||||
}
|
||||
// else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
|
||||
// {
|
||||
// setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
|
||||
// }
|
||||
else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
|
||||
{
|
||||
setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
|
||||
}
|
||||
else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
|
||||
{
|
||||
setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
|
||||
@@ -995,19 +1007,11 @@ BOOL LLVOVolume::calcLOD()
|
||||
F32 distance;
|
||||
|
||||
#if MESH_ENABLED
|
||||
if (mDrawable->isState(LLDrawable::RIGGED))
|
||||
if (mDrawable->isState(LLDrawable::RIGGED) && getAvatar())
|
||||
{
|
||||
LLVOAvatar* avatar = getAvatar();
|
||||
if(avatar)
|
||||
{
|
||||
distance = avatar->mDrawable->mDistanceWRTCamera;
|
||||
radius = avatar->getBinRadius();
|
||||
}
|
||||
else
|
||||
{
|
||||
distance = mDrawable->mDistanceWRTCamera;
|
||||
radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length();
|
||||
}
|
||||
distance = avatar->mDrawable->mDistanceWRTCamera;
|
||||
radius = avatar->getBinRadius();
|
||||
}
|
||||
else
|
||||
#endif //MESH_ENABLED
|
||||
@@ -2211,8 +2215,270 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const
|
||||
return mDrawable->getWorldMatrix();
|
||||
}
|
||||
|
||||
// Returns a base cost and adds textures to passed in set.
|
||||
// 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
|
||||
{
|
||||
// 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;
|
||||
|
||||
// per-prim costs
|
||||
static const U32 ARC_PARTICLE_COST = 1; // determined experimentally
|
||||
static const U32 ARC_PARTICLE_MAX = 2048; // default values
|
||||
static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested
|
||||
static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims
|
||||
static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face
|
||||
|
||||
|
||||
// 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 = 5; // tested based on performance
|
||||
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; // tested based on performance
|
||||
|
||||
static const F32 ARC_PLANAR_COST = 1.0f; // tested based on performance to have negligible impact
|
||||
static const F32 ARC_ANIM_TEX_COST = 4.f; // tested based on performance
|
||||
static const F32 ARC_ALPHA_COST = 4.f; // 4x max - based on performance
|
||||
|
||||
F32 shame = 0;
|
||||
|
||||
U32 invisi = 0;
|
||||
U32 shiny = 0;
|
||||
U32 glow = 0;
|
||||
U32 alpha = 0;
|
||||
U32 flexi = 0;
|
||||
U32 animtex = 0;
|
||||
U32 particles = 0;
|
||||
U32 bump = 0;
|
||||
U32 planar = 0;
|
||||
U32 weighted_mesh = 0;
|
||||
U32 produces_light = 0;
|
||||
U32 media_faces = 0;
|
||||
|
||||
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 weighted_triangles = -1.0;
|
||||
getStreamingCost(NULL, NULL, &weighted_triangles);
|
||||
|
||||
if (weighted_triangles > 0.0)
|
||||
{
|
||||
num_triangles = (U32)(weighted_triangles);
|
||||
}
|
||||
}
|
||||
|
||||
if (num_triangles == 0)
|
||||
{
|
||||
num_triangles = 4;
|
||||
}
|
||||
|
||||
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(), this))
|
||||
{
|
||||
// weighted attachment - 1 point for every 3 bytes
|
||||
weighted_mesh = 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 = 256 + (S32)(ARC_TEXTURE_COST * (texture->getFullHeight() / 128.f + texture->getFullWidth() / 128.f));
|
||||
textures.insert(texture_cost_t::value_type(sculpt_id, texture_cost));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isFlexible())
|
||||
{
|
||||
flexi = 1;
|
||||
}
|
||||
if (isParticleSource())
|
||||
{
|
||||
particles = 1;
|
||||
}
|
||||
|
||||
if (getIsLight())
|
||||
{
|
||||
produces_light = 1;
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < num_faces; ++i)
|
||||
{
|
||||
const LLFace* face = drawablep->getFace(i);
|
||||
const LLTextureEntry* te = face->getTextureEntry();
|
||||
const LLViewerTexture* img = face->getTexture();
|
||||
|
||||
if (img)
|
||||
{
|
||||
if (textures.find(img->getID()) == textures.end())
|
||||
{
|
||||
S32 texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f));
|
||||
textures.insert(texture_cost_t::value_type(img->getID(), texture_cost));
|
||||
}
|
||||
}
|
||||
|
||||
if (face->getPoolType() == LLDrawPool::POOL_ALPHA)
|
||||
{
|
||||
alpha = 1;
|
||||
}
|
||||
else if (img && img->getPrimaryFormat() == GL_ALPHA)
|
||||
{
|
||||
invisi = 1;
|
||||
}
|
||||
/*if (face->hasMedia())
|
||||
{
|
||||
media_faces++;
|
||||
}*/
|
||||
|
||||
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)
|
||||
{
|
||||
animtex = 1;
|
||||
}
|
||||
if (te->getTexGen())
|
||||
{
|
||||
planar = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// shame currently has the "base" cost of 1 point per 15 triangles, min 2.
|
||||
shame = num_triangles * 5.f;
|
||||
shame = shame < 2.f ? 2.f : shame;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
// multiply shame by multipliers
|
||||
if (weighted_mesh)
|
||||
{
|
||||
shame *= weighted_mesh * ARC_WEIGHTED_MESH;
|
||||
}
|
||||
|
||||
if (flexi)
|
||||
{
|
||||
shame *= flexi * ARC_FLEXI_MULT;
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (produces_light)
|
||||
{
|
||||
shame += ARC_LIGHT_COST;
|
||||
}
|
||||
|
||||
if (media_faces)
|
||||
{
|
||||
shame += media_faces * ARC_MEDIA_FACE_COST;
|
||||
}
|
||||
|
||||
if (shame > mRenderComplexity_current)
|
||||
{
|
||||
mRenderComplexity_current = (S32)shame;
|
||||
}
|
||||
|
||||
return (U32)shame;
|
||||
}
|
||||
#if MESH_ENABLED
|
||||
F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes)
|
||||
F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_value) const
|
||||
{
|
||||
F32 radius = getScale().length()*0.5f;
|
||||
|
||||
@@ -2220,7 +2486,7 @@ F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes)
|
||||
{
|
||||
LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
|
||||
|
||||
return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD);
|
||||
return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD, unscaled_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2234,12 +2500,18 @@ F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes)
|
||||
header["medium_lod"]["size"] = counts[2] * 10;
|
||||
header["high_lod"]["size"] = counts[3] * 10;
|
||||
|
||||
return LLMeshRepository::getStreamingCost(header, radius);
|
||||
return LLMeshRepository::getStreamingCost(header, radius, NULL, NULL, -1, unscaled_value);
|
||||
}
|
||||
}
|
||||
#endif //MESH_ENABLED
|
||||
//static
|
||||
void LLVOVolume::updateRenderComplexity()
|
||||
{
|
||||
mRenderComplexity_last = mRenderComplexity_current;
|
||||
mRenderComplexity_current = 0;
|
||||
}
|
||||
|
||||
U32 LLVOVolume::getTriangleCount()
|
||||
U32 LLVOVolume::getTriangleCount() const
|
||||
{
|
||||
U32 count = 0;
|
||||
LLVolume* volume = getVolume();
|
||||
@@ -3137,7 +3409,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
||||
}
|
||||
#endif //MESH_ENABLED
|
||||
llassert_always(vobj);
|
||||
vobj->updateTextureVirtualSize();
|
||||
vobj->updateTextureVirtualSize(true);
|
||||
vobj->preRebuild();
|
||||
|
||||
drawablep->clearState(LLDrawable::HAS_ALPHA);
|
||||
|
||||
Reference in New Issue
Block a user