Meshy update. Mostly related to cost calculations... mostly.
This commit is contained in:
@@ -7233,7 +7233,40 @@
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.25</real>
|
||||
</map>
|
||||
</map>
|
||||
<key>Jpeg2000AdvancedCompression</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use advanced Jpeg2000 compression options (precincts, blocks, ordering, markers)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>Jpeg2000PrecinctsSize</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Size of image precincts. Assumed square and same for all levels. Must be power of 2.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>256</integer>
|
||||
</map>
|
||||
<key>Jpeg2000BlocksSize</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Size of encoding blocks. Assumed square and same for all levels. Must be power of 2. Max 64, Min 4.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>64</integer>
|
||||
</map>
|
||||
<key>KeepAspectForSnapshot</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -11207,28 +11240,51 @@
|
||||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>MeshStreamingCostScaler</key>
|
||||
<key>MeshTriangleBudget</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>DEBUG</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>2.0</real>
|
||||
</map>
|
||||
<key>MeshThreadCount</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Number of threads to use for loading meshes.</string>
|
||||
<string>Target visible triangle budget to use when estimating streaming cost.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>8</integer>
|
||||
<real>250000</real>
|
||||
</map>
|
||||
<key>MeshMetaDataDiscount</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Number of bytes to deduct for metadata when determining streaming cost.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<real>384</real>
|
||||
</map>
|
||||
<key>MeshMinimumByteSize</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Minimum number of bytes per LoD block when determining streaming cost.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<real>16</real>
|
||||
</map>
|
||||
<key>MeshBytesPerTriangle</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Approximation of bytes per triangle to use for determining mesh streaming cost.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<real>16</real>
|
||||
</map>
|
||||
|
||||
<key>MeshMaxConcurrentRequests</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -171,7 +171,7 @@ void LLDrawPoolTree::endDeferredPass(S32 pass)
|
||||
void LLDrawPoolTree::beginShadowPass(S32 pass)
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE);
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
|
||||
|
||||
static const LLCachedControl<F32> render_deferred_offset("RenderDeferredTreeShadowOffset",1.f);
|
||||
static const LLCachedControl<F32> render_deferred_bias("RenderDeferredTreeShadowBias",1.f);
|
||||
glPolygonOffset(render_deferred_offset,render_deferred_bias);
|
||||
@@ -187,12 +187,10 @@ void LLDrawPoolTree::renderShadow(S32 pass)
|
||||
void LLDrawPoolTree::endShadowPass(S32 pass)
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE);
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
|
||||
static const LLCachedControl<F32> render_deferred_offset("RenderDeferredTreeShadowOffset",1.f);
|
||||
static const LLCachedControl<F32> render_deferred_bias("RenderDeferredTreeShadowBias",1.f);
|
||||
glPolygonOffset(render_deferred_offset,render_deferred_bias);
|
||||
|
||||
//gDeferredShadowProgram.unbind();
|
||||
static const LLCachedControl<F32> render_deferred_offset("RenderDeferredSpotShadowOffset",1.f);
|
||||
static const LLCachedControl<F32> render_deferred_bias("RenderDeferredSpotShadowBias",1.f);
|
||||
glPolygonOffset(render_deferred_offset,render_deferred_bias);
|
||||
}
|
||||
|
||||
void LLDrawPoolTree::renderTree(BOOL selecting)
|
||||
|
||||
@@ -1717,6 +1717,7 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
|
||||
if (data.mModel[i].notNull())
|
||||
{
|
||||
LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
|
||||
volume->copyVolumeFaces(data.mModel[i]);
|
||||
volume->setMeshAssetLoaded(TRUE);
|
||||
}
|
||||
}
|
||||
@@ -2552,7 +2553,7 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
|
||||
return mThread->getActualMeshLOD(mesh_params, lod);
|
||||
}
|
||||
|
||||
const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj)
|
||||
const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj)
|
||||
{
|
||||
if (mesh_id.notNull())
|
||||
{
|
||||
@@ -2813,7 +2814,7 @@ void LLMeshRepository::uploadError(LLSD& args)
|
||||
}
|
||||
|
||||
//static
|
||||
F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod)
|
||||
F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
|
||||
{
|
||||
F32 max_distance = 512.f;
|
||||
|
||||
@@ -2821,10 +2822,15 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32
|
||||
F32 dlow = llmin(radius/0.06f, max_distance);
|
||||
F32 dmid = llmin(radius/0.24f, max_distance);
|
||||
|
||||
F32 METADATA_DISCOUNT = (F32) gSavedSettings.getU32("MeshMetaDataDiscount"); //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead
|
||||
F32 MINIMUM_SIZE = (F32) gSavedSettings.getU32("MeshMinimumByteSize"); //make sure nothing is "free"
|
||||
static const LLCachedControl<U32> mesh_meta_data_discount("MeshMetaDataDiscount");
|
||||
static const LLCachedControl<U32> mesh_minimum_byte_size("MeshMinimumByteSize");
|
||||
static const LLCachedControl<U32> mesh_bytes_per_triangle("MeshBytesPerTriangle");
|
||||
static const LLCachedControl<U32> mesh_triangle_budget("MeshTriangleBudget");
|
||||
|
||||
F32 bytes_per_triangle = (F32) gSavedSettings.getU32("MeshBytesPerTriangle");
|
||||
F32 METADATA_DISCOUNT = (F32) mesh_meta_data_discount.get(); //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead
|
||||
F32 MINIMUM_SIZE = (F32) mesh_minimum_byte_size.get(); //make sure nothing is "free"
|
||||
|
||||
F32 bytes_per_triangle = (F32) mesh_bytes_per_triangle.get();
|
||||
|
||||
S32 bytes_lowest = header["lowest_lod"]["size"].asInteger();
|
||||
S32 bytes_low = header["low_lod"]["size"].asInteger();
|
||||
@@ -2902,7 +2908,12 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32
|
||||
triangles_low*low_area +
|
||||
triangles_lowest*lowest_area;
|
||||
|
||||
return weighted_avg/gSavedSettings.getU32("MeshTriangleBudget")*15000.f;
|
||||
if (unscaled_value)
|
||||
{
|
||||
*unscaled_value = weighted_avg;
|
||||
}
|
||||
|
||||
return weighted_avg/mesh_triangle_budget*15000.f;
|
||||
}
|
||||
|
||||
|
||||
@@ -3204,32 +3215,33 @@ void LLPhysicsDecomp::doDecompositionSingleHull()
|
||||
llwarns << "Could not execute decomposition stage when attempting to create single hull." << llendl;
|
||||
make_box(mCurRequest);
|
||||
}
|
||||
|
||||
mMutex->lock();
|
||||
mCurRequest->mHull.clear();
|
||||
mCurRequest->mHull.resize(1);
|
||||
mCurRequest->mHullMesh.clear();
|
||||
mMutex->unlock();
|
||||
|
||||
std::vector<LLVector3> p;
|
||||
LLCDHull hull;
|
||||
|
||||
// if LLConvexDecomposition is a stub, num_hulls should have been set to 0 above, and we should not reach this code
|
||||
decomp->getSingleHull(&hull);
|
||||
|
||||
const F32* v = hull.mVertexBase;
|
||||
|
||||
for (S32 j = 0; j < hull.mNumVertices; ++j)
|
||||
else
|
||||
{
|
||||
LLVector3 vert(v[0], v[1], v[2]);
|
||||
p.push_back(vert);
|
||||
v = (F32*) (((U8*) v) + hull.mVertexStrideBytes);
|
||||
}
|
||||
mMutex->lock();
|
||||
mCurRequest->mHull.clear();
|
||||
mCurRequest->mHull.resize(1);
|
||||
mCurRequest->mHullMesh.clear();
|
||||
mMutex->unlock();
|
||||
|
||||
std::vector<LLVector3> p;
|
||||
LLCDHull hull;
|
||||
|
||||
// if LLConvexDecomposition is a stub, num_hulls should have been set to 0 above, and we should not reach this code
|
||||
decomp->getSingleHull(&hull);
|
||||
|
||||
const F32* v = hull.mVertexBase;
|
||||
|
||||
for (S32 j = 0; j < hull.mNumVertices; ++j)
|
||||
{
|
||||
LLVector3 vert(v[0], v[1], v[2]);
|
||||
p.push_back(vert);
|
||||
v = (F32*) (((U8*) v) + hull.mVertexStrideBytes);
|
||||
}
|
||||
|
||||
mMutex->lock();
|
||||
mCurRequest->mHull[0] = p;
|
||||
mMutex->unlock();
|
||||
|
||||
mMutex->lock();
|
||||
mCurRequest->mHull[0] = p;
|
||||
mMutex->unlock();
|
||||
}
|
||||
#else
|
||||
setMeshData(mesh, false);
|
||||
|
||||
|
||||
@@ -474,7 +474,7 @@ public:
|
||||
static U32 sCacheBytesWritten;
|
||||
static U32 sPeakKbps;
|
||||
|
||||
static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1);
|
||||
static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
|
||||
|
||||
LLMeshRepository();
|
||||
|
||||
@@ -493,7 +493,7 @@ public:
|
||||
|
||||
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
|
||||
static S32 getActualMeshLOD(LLSD& header, S32 lod);
|
||||
const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj);
|
||||
const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj);
|
||||
LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
|
||||
void fetchPhysicsShape(const LLUUID& mesh_id);
|
||||
bool hasPhysicsShape(const LLUUID& mesh_id);
|
||||
|
||||
@@ -6536,31 +6536,77 @@ U32 LLObjectSelection::getSelectedObjectTriangleCount()
|
||||
return count;
|
||||
}
|
||||
|
||||
/*S32 LLObjectSelection::getSelectedObjectRenderCost()
|
||||
|
||||
S32 LLObjectSelection::getSelectedObjectRenderCost()
|
||||
{
|
||||
S32 cost = 0;
|
||||
LLVOVolume::texture_cost_t textures;
|
||||
typedef std::set<LLUUID> uuid_list_t;
|
||||
uuid_list_t computed_objects;
|
||||
|
||||
typedef std::list<LLPointer<LLViewerObject> > child_list_t;
|
||||
typedef const child_list_t const_child_list_t;
|
||||
|
||||
// add render cost of complete linksets first, to get accurate texture counts
|
||||
for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
|
||||
{
|
||||
LLSelectNode* node = *iter;
|
||||
|
||||
LLVOVolume* object = (LLVOVolume*)node->getObject();
|
||||
|
||||
if (object)
|
||||
if (object && object->isRootEdit())
|
||||
{
|
||||
cost += object->getRenderCost(textures);
|
||||
}
|
||||
cost += object->getRenderCost(textures);
|
||||
computed_objects.insert(object->getID());
|
||||
|
||||
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;
|
||||
const_child_list_t children = object->getChildren();
|
||||
for (const_child_list_t::const_iterator child_iter = children.begin();
|
||||
child_iter != children.end();
|
||||
++child_iter)
|
||||
{
|
||||
LLViewerObject* child_obj = *child_iter;
|
||||
LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
|
||||
if (child)
|
||||
{
|
||||
cost += child->getRenderCost(textures);
|
||||
computed_objects.insert(child->getID());
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
textures.clear();
|
||||
}
|
||||
textures.clear();
|
||||
}
|
||||
|
||||
// add any partial linkset objects, texture cost may be slightly misleading
|
||||
for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter)
|
||||
{
|
||||
LLSelectNode* node = *iter;
|
||||
LLVOVolume* object = (LLVOVolume*)node->getObject();
|
||||
|
||||
if (object && computed_objects.find(object->getID()) == computed_objects.end() )
|
||||
{
|
||||
cost += object->getRenderCost(textures);
|
||||
computed_objects.insert(object->getID());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
textures.clear();
|
||||
}
|
||||
|
||||
return cost;
|
||||
}*/
|
||||
}
|
||||
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
|
||||
|
||||
@@ -3167,12 +3167,12 @@ F32 LLViewerObject::getLinksetPhysicsCost()
|
||||
return mLinksetPhysicsCost;
|
||||
}
|
||||
|
||||
F32 LLViewerObject::getStreamingCost(S32* bytes, S32* visible_bytes)
|
||||
F32 LLViewerObject::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_value) const
|
||||
{
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
U32 LLViewerObject::getTriangleCount()
|
||||
U32 LLViewerObject::getTriangleCount() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -328,8 +328,8 @@ public:
|
||||
virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE);
|
||||
|
||||
#if MESH_ENABLED
|
||||
virtual F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL);
|
||||
virtual U32 getTriangleCount();
|
||||
virtual F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL, F32* unscaled_value = NULL) const;
|
||||
virtual U32 getTriangleCount() const;
|
||||
virtual U32 getHighLODTriangleCount();
|
||||
|
||||
void setObjectCost(F32 cost);
|
||||
|
||||
@@ -966,99 +966,54 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
|
||||
BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
|
||||
const std::string& out_filename,
|
||||
const U8 codec)
|
||||
{
|
||||
// First, load the image.
|
||||
{
|
||||
// Load the image
|
||||
LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
|
||||
if (image.isNull())
|
||||
{
|
||||
image->setLastError("Couldn't open the image to be uploaded.");
|
||||
return FALSE;
|
||||
}
|
||||
if (!image->load(filename))
|
||||
{
|
||||
image->setLastError("Couldn't load the image to be uploaded.");
|
||||
return FALSE;
|
||||
}
|
||||
// Decompress or expand it in a raw image structure
|
||||
LLPointer<LLImageRaw> raw_image = new LLImageRaw;
|
||||
|
||||
switch (codec)
|
||||
if (!image->decode(raw_image, 0.0f))
|
||||
{
|
||||
case IMG_CODEC_BMP:
|
||||
{
|
||||
LLPointer<LLImageBMP> bmp_image = new LLImageBMP;
|
||||
|
||||
if (!bmp_image->load(filename))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!bmp_image->decode(raw_image, 0.0f))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IMG_CODEC_TGA:
|
||||
{
|
||||
LLPointer<LLImageTGA> tga_image = new LLImageTGA;
|
||||
|
||||
if (!tga_image->load(filename))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!tga_image->decode(raw_image))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( (tga_image->getComponents() != 3) &&
|
||||
(tga_image->getComponents() != 4) )
|
||||
{
|
||||
tga_image->setLastError( "Image files with less than 3 or more than 4 components are not supported." );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IMG_CODEC_JPEG:
|
||||
{
|
||||
LLPointer<LLImageJPEG> jpeg_image = new LLImageJPEG;
|
||||
|
||||
if (!jpeg_image->load(filename))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!jpeg_image->decode(raw_image, 0.0f))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IMG_CODEC_PNG:
|
||||
{
|
||||
LLPointer<LLImagePNG> png_image = new LLImagePNG;
|
||||
|
||||
if (!png_image->load(filename))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!png_image->decode(raw_image, 0.0f))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);
|
||||
|
||||
if( !compressedImage->save(out_filename) )
|
||||
{
|
||||
llinfos << "Couldn't create output file " << out_filename << llendl;
|
||||
image->setLastError("Couldn't decode the image to be uploaded.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// test to see if the encode and save worked.
|
||||
// Check the image constraints
|
||||
if ((image->getComponents() != 3) && (image->getComponents() != 4))
|
||||
{
|
||||
image->setLastError("Image files with less than 3 or more than 4 components are not supported.");
|
||||
return FALSE;
|
||||
}
|
||||
// Convert to j2c (JPEG2000) and save the file locally
|
||||
LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);
|
||||
if (compressedImage.isNull())
|
||||
{
|
||||
image->setLastError("Couldn't convert the image to jpeg2000.");
|
||||
llinfos << "Couldn't convert to j2c, file : " << filename << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
if (!compressedImage->save(out_filename))
|
||||
{
|
||||
image->setLastError("Couldn't create the jpeg2000 image for upload.");
|
||||
llinfos << "Couldn't create output file : " << out_filename << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
// Test to see if the encode and save worked
|
||||
LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
|
||||
if( !integrity_test->loadAndValidate( out_filename ) )
|
||||
if (!integrity_test->loadAndValidate( out_filename ))
|
||||
{
|
||||
llinfos << "Image: " << out_filename << " is corrupt." << llendl;
|
||||
image->setLastError("The created jpeg2000 image is corrupt.");
|
||||
llinfos << "Image file : " << out_filename << " is corrupt" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1073,7 +1028,25 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
|
||||
(raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF))
|
||||
compressedImage->setReversible(TRUE);
|
||||
|
||||
compressedImage->encode(raw_image, 0.0f);
|
||||
|
||||
/* if (gSavedSettings.getBOOL("Jpeg2000AdvancedCompression"))
|
||||
{
|
||||
// This test option will create jpeg2000 images with precincts for each level, RPCL ordering
|
||||
// and PLT markers. The block size is also optionally modifiable.
|
||||
// Note: the images hence created are compatible with older versions of the viewer.
|
||||
// Read the blocks and precincts size settings
|
||||
S32 block_size = gSavedSettings.getS32("Jpeg2000BlocksSize");
|
||||
S32 precinct_size = gSavedSettings.getS32("Jpeg2000PrecinctsSize");
|
||||
llinfos << "Advanced JPEG2000 Compression: precinct = " << precinct_size << ", block = " << block_size << llendl;
|
||||
compressedImage->initEncode(*raw_image, block_size, precinct_size, 0);
|
||||
}*/
|
||||
|
||||
if (!compressedImage->encode(raw_image, 0.0f))
|
||||
{
|
||||
llinfos << "convertToUploadFile : encode returns with error!!" << llendl;
|
||||
// Clear up the pointer so we don't leak that one
|
||||
compressedImage = NULL;
|
||||
}
|
||||
|
||||
return compressedImage;
|
||||
}
|
||||
|
||||
@@ -311,7 +311,8 @@ public:
|
||||
U32 ypos = 64;
|
||||
const U32 y_inc = 20;
|
||||
|
||||
if (gSavedSettings.getBOOL("DebugShowTime"))
|
||||
static const LLCachedControl<bool> debug_show_time("DebugShowTime");
|
||||
if (debug_show_time)
|
||||
{
|
||||
const U32 y_inc2 = 15;
|
||||
for (std::map<S32,LLFrameTimer>::reverse_iterator iter = gDebugTimers.rbegin();
|
||||
@@ -336,7 +337,8 @@ public:
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
if (gSavedSettings.getBOOL("DebugShowMemory"))
|
||||
static const LLCachedControl<bool> debug_show_memory("DebugShowMemory");
|
||||
if (debug_show_memory)
|
||||
{
|
||||
addText(xpos, ypos, llformat("Memory: %d (KB)", LLMemory::getWorkingSetSize() / 1024));
|
||||
ypos += y_inc;
|
||||
@@ -426,7 +428,8 @@ public:
|
||||
ypos += y_inc;
|
||||
}*/
|
||||
|
||||
if (gSavedSettings.getBOOL("DebugShowRenderInfo"))
|
||||
static const LLCachedControl<bool> debug_show_render_info("DebugShowRenderInfo");
|
||||
if (debug_show_render_info)
|
||||
{
|
||||
if (gPipeline.getUseVertexShaders() == 0)
|
||||
{
|
||||
@@ -456,6 +459,59 @@ public:
|
||||
addText(xpos, ypos, llformat("%.2f MB Video Memory Free", free_memory/1024.f));
|
||||
ypos += y_inc;
|
||||
}
|
||||
|
||||
#if MESH_ENABLED
|
||||
//show streaming cost/triangle count of known prims in current region OR selection
|
||||
//Note: This is SUPER slow
|
||||
{
|
||||
F32 cost = 0.f;
|
||||
S32 count = 0;
|
||||
S32 object_count = 0;
|
||||
S32 total_bytes = 0;
|
||||
S32 visible_bytes = 0;
|
||||
|
||||
const char* label = "Region";
|
||||
if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 0)
|
||||
{ //region
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region)
|
||||
{
|
||||
for (U32 i = 0; i < (U32)gObjectList.getNumObjects(); ++i)
|
||||
{
|
||||
LLViewerObject* object = gObjectList.getObject(i);
|
||||
if (object &&
|
||||
object->getRegion() == region &&
|
||||
object->getVolume())
|
||||
{
|
||||
object_count++;
|
||||
S32 bytes = 0;
|
||||
S32 visible = 0;
|
||||
cost += object->getStreamingCost(&bytes, &visible);
|
||||
count += object->getTriangleCount();
|
||||
total_bytes += bytes;
|
||||
visible_bytes += visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
label = "Selection";
|
||||
cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(&total_bytes, &visible_bytes);
|
||||
count = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectTriangleCount();
|
||||
object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
|
||||
}
|
||||
|
||||
addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost));
|
||||
ypos += y_inc;
|
||||
|
||||
addText(xpos, ypos, llformat(" %.3f KTris, %.1f/%.1f KB, %d objects",
|
||||
count/1000.f, visible_bytes/1024.f, total_bytes/1024.f, object_count));
|
||||
ypos += y_inc;
|
||||
|
||||
}
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
addText(xpos, ypos, llformat("%d MB Vertex Data", LLVertexBuffer::sAllocatedBytes/(1024*1024)));
|
||||
ypos += y_inc;
|
||||
|
||||
@@ -520,7 +576,7 @@ public:
|
||||
ypos += y_inc;
|
||||
|
||||
#if MESH_ENABLED
|
||||
if (gSavedSettings.getBOOL("MeshEnabled"))
|
||||
if (gMeshRepo.meshRezEnabled())
|
||||
{
|
||||
addText(xpos, ypos, llformat("%.3f MB Mesh Data Received", LLMeshRepository::sBytesReceived/(1024.f*1024.f)));
|
||||
|
||||
@@ -541,7 +597,8 @@ public:
|
||||
LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount =
|
||||
gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0;
|
||||
}
|
||||
if (gSavedSettings.getBOOL("DebugShowRenderMatrices"))
|
||||
static const LLCachedControl<bool> debug_show_render_matrices("DebugShowRenderMatrices");
|
||||
if (debug_show_render_matrices)
|
||||
{
|
||||
addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[12], gGLProjection[13], gGLProjection[14], gGLProjection[15]));
|
||||
ypos += y_inc;
|
||||
@@ -574,7 +631,8 @@ public:
|
||||
addText(xpos, ypos, "View Matrix");
|
||||
ypos += y_inc;
|
||||
}
|
||||
if (gSavedSettings.getBOOL("DebugShowColor"))
|
||||
static const LLCachedControl<bool> debug_show_color("DebugShowColor");
|
||||
if (debug_show_color)
|
||||
{
|
||||
U8 color[4];
|
||||
LLCoordGL coord = gViewerWindow->getCurrentMouse();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -90,6 +90,7 @@ public:
|
||||
// Class which embodies all Volume objects (with pcode LL_PCODE_VOLUME)
|
||||
class LLVOVolume : public LLViewerObject
|
||||
{
|
||||
LOG_CLASS(LLVOVolume);
|
||||
protected:
|
||||
virtual ~LLVOVolume();
|
||||
|
||||
@@ -131,11 +132,12 @@ public:
|
||||
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
|
||||
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
|
||||
/*virtual*/ const LLMatrix4 getRenderMatrix() const;
|
||||
|
||||
typedef std::map<LLUUID, S32> texture_cost_t;
|
||||
U32 getRenderCost(texture_cost_t &textures) const;
|
||||
#if MESH_ENABLED
|
||||
/*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL);
|
||||
/*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL, F32* unscaled_value = NULL) const;
|
||||
#endif //MESH_ENABLED
|
||||
/*virtual*/ U32 getTriangleCount();
|
||||
/*virtual*/ U32 getTriangleCount() const;
|
||||
/*virtual*/ U32 getHighLODTriangleCount();
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
S32 face = -1, // which face to check, -1 = ALL_SIDES
|
||||
@@ -210,7 +212,7 @@ public:
|
||||
/*virtual*/ BOOL updateLOD();
|
||||
void updateRadius();
|
||||
/*virtual*/ void updateTextures();
|
||||
void updateTextureVirtualSize();
|
||||
void updateTextureVirtualSize(bool forced = false);
|
||||
|
||||
void updateFaceFlags();
|
||||
void regenFaces();
|
||||
@@ -291,7 +293,13 @@ protected:
|
||||
LLFace* addFace(S32 face_index);
|
||||
void updateTEData();
|
||||
|
||||
// stats tracking for render complexity
|
||||
static S32 mRenderComplexity_last;
|
||||
static S32 mRenderComplexity_current;
|
||||
public:
|
||||
|
||||
static S32 getRenderComplexityMax() {return mRenderComplexity_last;}
|
||||
static void updateRenderComplexity();
|
||||
LLViewerTextureAnim *mTextureAnimp;
|
||||
U8 mTexAnimMode;
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user