Automated merge with https://hg.secondlife.com/mesh-development
commit
af5cdbbb96
|
|
@ -2933,44 +2933,33 @@ 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_PARTICLE_COST = 1;
|
||||
static const U32 ARC_PARTICLE_MAX = 2048;
|
||||
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 +2970,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 +3015,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 +3060,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;
|
||||
}
|
||||
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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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 +3082,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 +3108,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 *= hollow * ARC_HOLLOW_MULT;
|
||||
shame *= planar * ARC_PLANAR_COST;
|
||||
}
|
||||
|
||||
if (circular_profile)
|
||||
if (animtex)
|
||||
{
|
||||
shame *= circular_profile * ARC_CIRC_PROF_MULT;
|
||||
shame *= animtex * ARC_ANIM_TEX_COST;
|
||||
}
|
||||
|
||||
if (circular_path)
|
||||
if (alpha)
|
||||
{
|
||||
shame *= circular_path * ARC_CIRC_PATH_MULT;
|
||||
shame *= alpha * ARC_ALPHA_COST;
|
||||
}
|
||||
|
||||
if(invisi)
|
||||
{
|
||||
shame *= invisi * ARC_INVISI_COST;
|
||||
}
|
||||
|
||||
if (glow)
|
||||
|
|
@ -3202,35 +3155,36 @@ 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)
|
||||
|
||||
// multiply shame by multipliers
|
||||
if (weighted_mesh)
|
||||
{
|
||||
shame = (U32)(shame * twist);
|
||||
shame *= weighted_mesh * ARC_WEIGHTED_MESH;
|
||||
}
|
||||
|
||||
if (scale > 1.f)
|
||||
if (flexi)
|
||||
{
|
||||
shame = (U32)(shame *scale);
|
||||
shame *= flexi * ARC_FLEXI_MULT;
|
||||
}
|
||||
|
||||
if (revolutions > 1.f)
|
||||
{
|
||||
shame = (U32)(shame * revolutions);
|
||||
}
|
||||
|
||||
// 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 shame;
|
||||
return (U32)shame;
|
||||
}
|
||||
|
||||
F32 LLVOVolume::getStreamingCost()
|
||||
|
|
@ -3247,16 +3201,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;
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ public:
|
|||
typedef std::map<LLUUID, S32> 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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue