diff options
author | Dave Parks <davep@lindenlab.com> | 2011-03-30 18:38:22 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2011-03-30 18:38:22 -0500 |
commit | 6b9a2d24cce8efaa72c2fd60655998844394312d (patch) | |
tree | 77438ba1c0e742c2acf7372b968f32368290fa8a /indra | |
parent | 1aecac62eb88125546057be2a2a70a6b2eba1a57 (diff) |
SH-477 Better mesh streaming cost estimation.
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llcommon/llsdserialize.cpp | 5 | ||||
-rwxr-xr-x | indra/llprimitive/llmodel.cpp | 360 | ||||
-rwxr-xr-x | indra/llprimitive/llmodel.h | 103 | ||||
-rwxr-xr-x | indra/newview/app_settings/settings.xml | 2 | ||||
-rwxr-xr-x | indra/newview/llfloatermodelpreview.cpp | 34 | ||||
-rwxr-xr-x | indra/newview/llmeshrepository.cpp | 109 | ||||
-rw-r--r-- | indra/newview/llmeshrepository.h | 7 | ||||
-rw-r--r-- | indra/newview/llselectmgr.cpp | 18 | ||||
-rw-r--r-- | indra/newview/llselectmgr.h | 4 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 2 | ||||
-rw-r--r-- | indra/newview/llviewerwindow.cpp | 21 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llvovolume.h | 2 |
14 files changed, 351 insertions, 324 deletions
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index f3cbfab77a..5be5ecc492 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -2095,11 +2095,6 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size) S32 ret = inflateInit(&strm); - if (ret != Z_OK) - { - llerrs << "WTF?" << llendl; - } - do { strm.avail_out = CHUNK; diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 595f9aa307..049cf6b71f 100755 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1333,70 +1333,6 @@ std::string LLModel::getName() const return mLabel; } -//static -LLSD LLModel::writeModel( - std::string filename, - LLModel* physics, - LLModel* high, - LLModel* medium, - LLModel* low, - LLModel* impostor, - const convex_hull_decomposition& decomp, - BOOL upload_skin, - BOOL upload_joints, - BOOL nowrite) -{ - LLModel::hull dummy_hull; - return writeModel( - filename, - physics, - high, - medium, - low, - impostor, - decomp, - dummy_hull, - upload_skin, - upload_joints, - nowrite); -} - -//static -LLSD LLModel::writeModel( - std::string filename, - LLModel* physics, - LLModel* high, - LLModel* medium, - LLModel* low, - LLModel* impostor, - const convex_hull_decomposition& decomp, - const hull& base_hull, - BOOL upload_skin, - BOOL upload_joints, - BOOL nowrite) -{ - std::ofstream os( - filename.c_str(), - std::ofstream::out | std::ofstream::binary); - - LLSD header = writeModel( - os, - physics, - high, - medium, - low, - impostor, - decomp, - base_hull, - upload_skin, - upload_joints, - nowrite); - - os.close(); - - return header; -} - //static LLSD LLModel::writeModel( std::ostream& ostr, @@ -1405,8 +1341,7 @@ LLSD LLModel::writeModel( LLModel* medium, LLModel* low, LLModel* impostor, - const convex_hull_decomposition& decomp, - const hull& base_hull, + const LLModel::Decomposition& decomp, BOOL upload_skin, BOOL upload_joints, BOOL nowrite) @@ -1429,119 +1364,10 @@ LLSD LLModel::writeModel( mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints); } - if (!decomp.empty() || !base_hull.empty()) + if (!decomp.mBaseHull.empty() || + !decomp.mHull.empty()) { - //write decomposition block - // ["decomposition"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points - // ["decomposition"]["PositionDomain"]["Min"/"Max"] - // ["decomposition"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points - // ["decomposition"]["Hull"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape - - - //get minimum and maximum - LLVector3 min; - - if (decomp.empty()) - { - min = base_hull[0]; - } - else - { - min = decomp[0][0]; - } - - LLVector3 max = min; - - LLSD::Binary hulls(decomp.size()); - - U32 total = 0; - - for (U32 i = 0; i < decomp.size(); ++i) - { - U32 size = decomp[i].size(); - total += size; - hulls[i] = (U8) (size); - - for (U32 j = 0; j < decomp[i].size(); ++j) - { - update_min_max(min, max, decomp[i][j]); - } - - } - - for (U32 i = 0; i < base_hull.size(); ++i) - { - update_min_max(min, max, base_hull[i]); - } - - mdl["decomposition"]["Min"] = min.getValue(); - mdl["decomposition"]["Max"] = max.getValue(); - - if (!hulls.empty()) - { - mdl["decomposition"]["HullList"] = hulls; - } - - if (total > 0) - { - LLSD::Binary p(total*3*2); - - LLVector3 range = max-min; - - U32 vert_idx = 0; - for (U32 i = 0; i < decomp.size(); ++i) - { - for (U32 j = 0; j < decomp[i].size(); ++j) - { - for (U32 k = 0; k < 3; k++) - { - //convert to 16-bit normalized across domain - U16 val = (U16) (((decomp[i][j].mV[k]-min.mV[k])/range.mV[k])*65535); - - U8* buff = (U8*) &val; - //write to binary buffer - p[vert_idx++] = buff[0]; - p[vert_idx++] = buff[1]; - - if (vert_idx > p.size()) - { - llerrs << "WTF?" << llendl; - } - } - } - } - - mdl["decomposition"]["Position"] = p; - } - - if (!base_hull.empty()) - { - LLSD::Binary p(base_hull.size()*3*2); - - LLVector3 range = max-min; - - U32 vert_idx = 0; - for (U32 j = 0; j < base_hull.size(); ++j) - { - for (U32 k = 0; k < 3; k++) - { - //convert to 16-bit normalized across domain - U16 val = (U16) (((base_hull[j].mV[k]-min.mV[k])/range.mV[k])*65535); - - U8* buff = (U8*) &val; - //write to binary buffer - p[vert_idx++] = buff[0]; - p[vert_idx++] = buff[1]; - - if (vert_idx > p.size()) - { - llerrs << "WTF?" << llendl; - } - } - } - - mdl["decomposition"]["Hull"] = p; - } + mdl["decomposition"] = decomp.asLLSD(); } for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx) @@ -1906,7 +1732,11 @@ void LLModel::updateHullCenters() mHullPoints += mPhysics.mHull[i].size(); } - mCenterOfHullCenters *= 1.f / mHullPoints; + if (mHullPoints > 0) + { + mCenterOfHullCenters *= 1.f / mHullPoints; + llassert(mPhysics.asLLSD().has("HullList")); + } } bool LLModel::loadModel(std::istream& is)
@@ -2182,19 +2012,33 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp) max.setValue(decomp["Max"]); range = max-min; + for (U32 i = 0; i < hulls.size(); ++i) { U16 count = (hulls[i] == 0) ? 256 : hulls[i]; + std::set<U64> valid; + + //must have at least 4 points + llassert(count > 3); + for (U32 j = 0; j < count; ++j) { + U64 test = (U64) p[0] | ((U64) p[1] << 16) | ((U64) p[2] << 32); + //point must be unique + //llassert(valid.find(test) == valid.end()); + valid.insert(test); mHull[i].push_back(LLVector3( (F32) p[0]/65535.f*range.mV[0]+min.mV[0], (F32) p[1]/65535.f*range.mV[1]+min.mV[1], (F32) p[2]/65535.f*range.mV[2]+min.mV[2])); p += 3; - } + + } + + //each hull must contain at least 4 unique points + llassert(valid.size() > 3); } } @@ -2208,8 +2052,17 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp) LLVector3 max; LLVector3 range; - min.setValue(decomp["Min"]); - max.setValue(decomp["Max"]); + if (decomp.has("Min")) + { + min.setValue(decomp["Min"]); + max.setValue(decomp["Max"]); + } + else + { + min.set(-0.5f, -0.5f, -0.5f); + max.set(0.5f, 0.5f, 0.5f); + } + range = max-min; U16 count = position.size()/6; @@ -2229,7 +2082,145 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp) //but contains no base hull mBaseHullMesh.clear();; } +} + +LLSD LLModel::Decomposition::asLLSD() const +{ + LLSD ret; + + if (mBaseHull.empty() && mHull.empty()) + { //nothing to write + return ret; + } + + //write decomposition block + // ["decomposition"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points + // ["decomposition"]["PositionDomain"]["Min"/"Max"] + // ["decomposition"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points + // ["decomposition"]["Hull"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape + + + //get minimum and maximum + LLVector3 min; + + if (mHull.empty()) + { + min = mBaseHull[0]; + } + else + { + min = mHull[0][0]; + } + + LLVector3 max = min; + + LLSD::Binary hulls(mHull.size()); + + U32 total = 0; + + for (U32 i = 0; i < mHull.size(); ++i) + { + U32 size = mHull[i].size(); + total += size; + hulls[i] = (U8) (size); + + for (U32 j = 0; j < mHull[i].size(); ++j) + { + update_min_max(min, max, mHull[i][j]); + } + } + + for (U32 i = 0; i < mBaseHull.size(); ++i) + { + update_min_max(min, max, mBaseHull[i]); + } + ret["Min"] = min.getValue(); + ret["Max"] = max.getValue(); + + if (!hulls.empty()) + { + ret["HullList"] = hulls; + } + + if (total > 0) + { + LLSD::Binary p(total*3*2); + + LLVector3 range = max-min; + + U32 vert_idx = 0; + + for (U32 i = 0; i < mHull.size(); ++i) + { + std::set<U64> valid; + + llassert(!mHull[i].empty()); + + for (U32 j = 0; j < mHull[i].size(); ++j) + { + U64 test = 0; + for (U32 k = 0; k < 3; k++) + { + //convert to 16-bit normalized across domain + U16 val = (U16) (((mHull[i][j].mV[k]-min.mV[k])/range.mV[k])*65535); + + switch (k) + { + case 0: test = test | (U64) val; break; + case 1: test = test | ((U64) val << 16); break; + case 2: test = test | ((U64) val << 32); break; + }; + + valid.insert(test); + + U8* buff = (U8*) &val; + //write to binary buffer + p[vert_idx++] = buff[0]; + p[vert_idx++] = buff[1]; + + //makes sure we haven't run off the end of the array + llassert(vert_idx <= p.size()); + } + } + + //must have at least 4 unique points + llassert(valid.size() > 3); + } + + ret["Position"] = p; + } + + if (!mBaseHull.empty()) + { + LLSD::Binary p(mBaseHull.size()*3*2); + + LLVector3 range = max-min; + + U32 vert_idx = 0; + for (U32 j = 0; j < mBaseHull.size(); ++j) + { + for (U32 k = 0; k < 3; k++) + { + //convert to 16-bit normalized across domain + U16 val = (U16) (((mBaseHull[j].mV[k]-min.mV[k])/range.mV[k])*65535); + + U8* buff = (U8*) &val; + //write to binary buffer + p[vert_idx++] = buff[0]; + p[vert_idx++] = buff[1]; + + if (vert_idx > p.size()) + { + llerrs << "WTF?" << llendl; + } + } + } + + ret["Hull"] = p; + } + + return ret; } void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs) @@ -2256,5 +2247,10 @@ void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs) { //take physics shape mesh from rhs mPhysicsShapeMesh = rhs->mPhysicsShapeMesh; } + + if (!mHull.empty()) + { //verify + llassert(asLLSD().has("HullList")); + } } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index e9450d2967..962e422a26 100755 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -71,38 +71,53 @@ public: //convex_hull_decomposition is a vector of convex hulls //each convex hull is a set of points - typedef std::vector<std::vector<LLVector3> > convex_hull_decomposition; + typedef std::vector<std::vector<LLVector3> > convex_hull_decomposition; typedef std::vector<LLVector3> hull; + class PhysicsMesh + { + public: + std::vector<LLVector3> mPositions; + std::vector<LLVector3> mNormals; + + void clear() + { + mPositions.clear(); + mNormals.clear(); + } + + bool empty() const + { + return mPositions.empty(); + } + }; + + class Decomposition + { + public: + Decomposition() { } + Decomposition(LLSD& data); + void fromLLSD(LLSD& data); + LLSD asLLSD() const; + + void merge(const Decomposition* rhs); + + LLUUID mMeshID; + LLModel::convex_hull_decomposition mHull; + LLModel::hull mBaseHull; + + std::vector<LLModel::PhysicsMesh> mMesh; + LLModel::PhysicsMesh mBaseHullMesh; + LLModel::PhysicsMesh mPhysicsShapeMesh; + }; + LLModel(LLVolumeParams& params, F32 detail); ~LLModel(); bool loadModel(std::istream& is); bool loadSkinInfo(LLSD& header, std::istream& is); bool loadDecomposition(LLSD& header, std::istream& is); - static LLSD writeModel( - std::string filename, - LLModel* physics, - LLModel* high, - LLModel* medium, - LLModel* low, - LLModel* imposotr, - const LLModel::convex_hull_decomposition& convex_hull_decomposition, - const LLModel::hull& base_hull, - BOOL upload_skin, - BOOL upload_joints, - BOOL nowrite = FALSE); - static LLSD writeModel( - std::string filename, - LLModel* physics, - LLModel* high, - LLModel* medium, - LLModel* low, - LLModel* imposotr, - const LLModel::convex_hull_decomposition& convex_hull_decomposition, - BOOL upload_skin, - BOOL upload_joints, - BOOL nowrite = FALSE); + static LLSD writeModel( std::ostream& ostr, LLModel* physics, @@ -110,11 +125,11 @@ public: LLModel* medium, LLModel* low, LLModel* imposotr, - const LLModel::convex_hull_decomposition& convex_hull_decomposition, - const LLModel::hull& base_hull, + const LLModel::Decomposition& decomp, BOOL upload_skin, BOOL upload_joints, BOOL nowrite = FALSE); + static LLSD writeModelToStream( std::ostream& ostr, LLSD& mdl, @@ -220,42 +235,6 @@ public: //ID for storing this model in a .slm file S32 mLocalID; - class PhysicsMesh - { - public: - std::vector<LLVector3> mPositions; - std::vector<LLVector3> mNormals; - - void clear() - { - mPositions.clear(); - mNormals.clear(); - } - - bool empty() const - { - return mPositions.empty(); - } - }; - - class Decomposition - { - public: - Decomposition() { } - Decomposition(LLSD& data); - void fromLLSD(LLSD& data); - - void merge(const Decomposition* rhs); - - LLUUID mMeshID; - LLModel::convex_hull_decomposition mHull; - LLModel::hull mBaseHull; - - std::vector<LLModel::PhysicsMesh> mMesh; - LLModel::PhysicsMesh mBaseHullMesh; - LLModel::PhysicsMesh mPhysicsShapeMesh; - }; - Decomposition mPhysics; protected: diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c11de57c42..4c042435f2 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8974,7 +8974,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>2.0</real> + <real>3.0</real> </map> <key>MeshThreadCount</key> <map> diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 541511e448..243f301e9d 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1093,7 +1093,7 @@ LLModelLoader::LLModelLoader(std::string filename, S32 lod, LLModelPreview* prev {
//only try to load from slm if viewer is configured to do so and this is the
//initial model load (not an LoD or physics shape)
- mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mPreview->mBaseModel.empty();
+ mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mPreview->mUploadData.empty();
mPreview->setLoadState(STARTING);
}
else
@@ -1889,6 +1889,14 @@ void LLModelLoader::loadModelCallback() { //wait until this thread is stopped before deleting self
apr_sleep(100);
}
+
+ //cleanup model loader
+ if (mPreview)
+ {
+ mPreview->mModelLoader = NULL;
+ }
+
+ delete this;
}
void LLModelLoader::handlePivotPoint( daeElement* pRoot )
@@ -2518,13 +2526,13 @@ U32 LLModelPreview::calcResourceCost() {
accounted.insert(instance.mModel);
- LLModel::convex_hull_decomposition& decomp =
+ LLModel::Decomposition& decomp =
instance.mLOD[LLModel::LOD_PHYSICS] ?
- instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics.mHull :
- instance.mModel->mPhysics.mHull;
+ instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics :
+ instance.mModel->mPhysics;
- LLSD ret = LLModel::writeModel(
- "",
+ std::stringstream ostr;
+ LLSD ret = LLModel::writeModel(ostr,
instance.mLOD[4],
instance.mLOD[3],
instance.mLOD[2],
@@ -2536,10 +2544,10 @@ U32 LLModelPreview::calcResourceCost() TRUE);
cost += gMeshRepo.calcResourceCost(ret);
- num_hulls += decomp.size();
- for (U32 i = 0; i < decomp.size(); ++i)
+ num_hulls += decomp.mHull.size();
+ for (U32 i = 0; i < decomp.mHull.size(); ++i)
{
- num_points += decomp[i].size();
+ num_points += decomp.mHull[i].size();
}
//calculate streaming cost
@@ -2737,10 +2745,10 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw std::stringstream str;
- LLModel::convex_hull_decomposition& decomp =
+ LLModel::Decomposition& decomp =
instance.mLOD[LLModel::LOD_PHYSICS].notNull() ?
- instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics.mHull :
- instance.mModel->mPhysics.mHull;
+ instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics :
+ instance.mModel->mPhysics;
LLModel::writeModel(str,
instance.mLOD[LLModel::LOD_PHYSICS],
@@ -2749,7 +2757,7 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw instance.mLOD[LLModel::LOD_LOW],
instance.mLOD[LLModel::LOD_IMPOSTOR],
decomp,
- empty_hull, save_skinweights, save_joint_positions);
+ save_skinweights, save_joint_positions);
data["mesh"][instance.mModel->mLocalID] = str.str();
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 752e4c8744..78943ef1b6 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1535,8 +1535,6 @@ void LLMeshRepoThread::notifyLoadedMeshes() S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod) { //only ever called from main thread - lod = llclamp(lod, 0, 3); - LLMutexLock lock(mHeaderMutex); mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID()); @@ -1544,40 +1542,48 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo { LLSD& header = iter->second; - if (header.has("404")) - { - return -1; - } + return LLMeshRepository::getActualMeshLOD(header, lod); + } - if (header[header_lod[lod]]["size"].asInteger() > 0) - { - return lod; - } + return lod; +} + +//static +S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod) +{ + lod = llclamp(lod, 0, 3); + + if (header.has("404")) + { + return -1; + } - //search down to find the next available lower lod - for (S32 i = lod-1; i >= 0; --i) + if (header[header_lod[lod]]["size"].asInteger() > 0) + { + return lod; + } + + //search down to find the next available lower lod + for (S32 i = lod-1; i >= 0; --i) + { + if (header[header_lod[i]]["size"].asInteger() > 0) { - if (header[header_lod[i]]["size"].asInteger() > 0) - { - return i; - } + return i; } + } - //search up to find then ext available higher lod - for (S32 i = lod+1; i < 4; ++i) + //search up to find then ext available higher lod + for (S32 i = lod+1; i < 4; ++i) + { + if (header[header_lod[i]]["size"].asInteger() > 0) { - if (header[header_lod[i]]["size"].asInteger() > 0) - { - return i; - } + return i; } - - //header exists and no good lod found, treat as 404 - header["404"] = 1; - return -1; } - return lod; + //header exists and no good lod found, treat as 404 + header["404"] = 1; + return -1; } U32 LLMeshRepoThread::getResourceCost(const LLUUID& mesh_id) @@ -2514,12 +2520,12 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id) return mesh.has("physics_shape") && mesh["physics_shape"].has("size") && (mesh["physics_shape"]["size"].asInteger() > 0); } -const LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id) +LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id) { return mThread->getMeshHeader(mesh_id); } -const LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id) +LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id) { static LLSD dummy_ret; if (mesh_id.notNull()) @@ -2577,12 +2583,10 @@ void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data) //write model file to memory buffer std::stringstream ostr; - LLModel::convex_hull_decomposition& decomp = + LLModel::Decomposition& decomp = data.mModel[LLModel::LOD_PHYSICS].notNull() ? - data.mModel[LLModel::LOD_PHYSICS]->mPhysics.mHull : - data.mBaseModel->mPhysics.mHull; - - LLModel::hull dummy_hull; + data.mModel[LLModel::LOD_PHYSICS]->mPhysics : + data.mBaseModel->mPhysics; LLSD header = LLModel::writeModel( ostr, @@ -2592,7 +2596,6 @@ void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data) data.mModel[LLModel::LOD_LOW], data.mModel[LLModel::LOD_IMPOSTOR], decomp, - dummy_hull, mUploadSkin, mUploadJoints, true); @@ -2678,10 +2681,12 @@ void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data) { std::stringstream ostr; - LLModel::convex_hull_decomposition& decomp = + LLModel::Decomposition& decomp = data.mModel[LLModel::LOD_PHYSICS].notNull() ? - data.mModel[LLModel::LOD_PHYSICS]->mPhysics.mHull : - data.mBaseModel->mPhysics.mHull; + data.mModel[LLModel::LOD_PHYSICS]->mPhysics : + data.mBaseModel->mPhysics; + + decomp.mBaseHull = mHullMap[data.mBaseModel]; LLModel::writeModel( ostr, @@ -2691,7 +2696,6 @@ void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data) data.mModel[LLModel::LOD_LOW], data.mModel[LLModel::LOD_IMPOSTOR], decomp, - mHullMap[data.mBaseModel], mUploadSkin, mUploadJoints); @@ -2939,17 +2943,36 @@ void LLMeshRepository::uploadError(LLSD& args) } //static -F32 LLMeshRepository::getStreamingCost(const LLSD& header, F32 radius) +F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod) { - F32 dlowest = llmin(radius/0.06f, 256.f); - F32 dlow = llmin(radius/0.24f, 256.f); - F32 dmid = llmin(radius/1.0f, 256.f); + F32 dlowest = llmin(radius/0.03f, 256.f); + F32 dlow = llmin(radius/0.06f, 256.f); + F32 dmid = llmin(radius/0.24f, 256.f); F32 bytes_lowest = header["lowest_lod"]["size"].asReal()/1024.f; F32 bytes_low = header["low_lod"]["size"].asReal()/1024.f; F32 bytes_mid = header["medium_lod"]["size"].asReal()/1024.f; F32 bytes_high = header["high_lod"]["size"].asReal()/1024.f; + if (bytes) + { + *bytes = 0; + *bytes += header["lowest_lod"]["size"].asInteger(); + *bytes += header["low_lod"]["size"].asInteger(); + *bytes += header["medium_lod"]["size"].asInteger(); + *bytes += header["high_lod"]["size"].asInteger(); + } + + + if (bytes_visible) + { + lod = LLMeshRepository::getActualMeshLOD(header, lod); + if (lod >= 0 && lod <= 3) + { + *bytes_visible = header[header_lod[lod]]["size"].asInteger(); + } + } + if (bytes_high == 0.f) { return 0.f; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 31c2049c32..5983a282a2 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -318,7 +318,7 @@ public: bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size); bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size); bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size); - const LLSD& getMeshHeader(const LLUUID& mesh_id); + LLSD& getMeshHeader(const LLUUID& mesh_id); void notifyLoadedMeshes(); S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); @@ -434,7 +434,7 @@ public: static U32 sCacheBytesWritten; static U32 sPeakKbps; - static F32 getStreamingCost(const LLSD& header, F32 radius); + static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1); LLMeshRepository(); @@ -452,6 +452,7 @@ public: void notifyDecompositionReceived(LLModel::Decomposition* info); S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); + static S32 getActualMeshLOD(LLSD& header, S32 lod); U32 calcResourceCost(LLSD& header); U32 getResourceCost(const LLUUID& mesh_params); const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id); @@ -462,7 +463,7 @@ public: void buildHull(const LLVolumeParams& params, S32 detail); void buildPhysicsMesh(LLModel::Decomposition& decomp); - const LLSD& getMeshHeader(const LLUUID& mesh_id); + LLSD& getMeshHeader(const LLUUID& mesh_id); void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index b139ba361e..78ffc7908d 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -6374,7 +6374,7 @@ BOOL LLObjectSelection::isEmpty() const //----------------------------------------------------------------------------- // getObjectCount() - returns number of non null objects //----------------------------------------------------------------------------- -S32 LLObjectSelection::getObjectCount(BOOL mesh_adjust) +S32 LLObjectSelection::getObjectCount() { cleanupNodes(); S32 count = mList.size(); @@ -6478,7 +6478,7 @@ F32 LLObjectSelection::getSelectedLinksetPhysicsCost() return cost; } -F32 LLObjectSelection::getSelectedObjectStreamingCost() +F32 LLObjectSelection::getSelectedObjectStreamingCost(S32* total_bytes, S32* visible_bytes) { F32 cost = 0.f; for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) @@ -6488,7 +6488,19 @@ F32 LLObjectSelection::getSelectedObjectStreamingCost() if (object) { - cost += object->getStreamingCost(); + S32 bytes = 0; + S32 visible = 0; + cost += object->getStreamingCost(&bytes, &visible); + + if (total_bytes) + { + *total_bytes += bytes; + } + + if (visible_bytes) + { + *visible_bytes += visible; + } } } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 031898d7c5..166616e13e 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -278,14 +278,14 @@ public: LLSelectNode* findNode(LLViewerObject* objectp); // count members - S32 getObjectCount(BOOL mesh_adjust = FALSE); + S32 getObjectCount(); F32 getSelectedObjectCost(); F32 getSelectedLinksetCost(); F32 getSelectedPhysicsCost(); F32 getSelectedLinksetPhysicsCost(); S32 getSelectedObjectRenderCost(); - F32 getSelectedObjectStreamingCost(); + F32 getSelectedObjectStreamingCost(S32* total_bytes = NULL, S32* visible_bytes = NULL); U32 getSelectedObjectTriangleCount(); S32 getTECount(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index bcdc774c5e..70b1809033 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3134,7 +3134,7 @@ F32 LLViewerObject::getLinksetPhysicsCost() return mLinksetPhysicsCost; } -F32 LLViewerObject::getStreamingCost() +F32 LLViewerObject::getStreamingCost(S32* bytes, S32* visible_bytes) { return 0.f; } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 2b2b7bd59d..44f46b8c0f 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -326,7 +326,7 @@ public: virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE); - virtual F32 getStreamingCost(); + virtual F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL); virtual U32 getTriangleCount(); void setObjectCost(F32 cost); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 39ef56d156..141ade8079 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -493,6 +493,10 @@ public: { 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 @@ -506,8 +510,13 @@ public: object->getRegion() == region && object->getVolume()) { - cost += object->getStreamingCost(); + object_count++; + S32 bytes = 0; + S32 visible = 0; + cost += object->getStreamingCost(&bytes, &visible); count += object->getTriangleCount(); + total_bytes += bytes; + visible_bytes += visible; } } } @@ -515,12 +524,16 @@ public: else { label = "Selection"; - cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(); + 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 (%.1f KTris)", - label, cost, count/1000.f)); + addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost)); + ypos += y_inc; + + addText(xpos, ypos, llformat(" %.1f KTris, %.1f/%.1f KB, %d objects", + count/1024.f, visible_bytes/1024.f, total_bytes/1024.f, object_count)); ypos += y_inc; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 98e5e4c6de..7c4a4c13ba 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3082,15 +3082,15 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const }
-F32 LLVOVolume::getStreamingCost()
+F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes)
{
if (isMesh())
{
- const LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
+ LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
F32 radius = getScale().length();
- return LLMeshRepository::getStreamingCost(header, radius);
+ return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD);
}
return 0.f;
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index b09243055c..029811886d 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -130,7 +130,7 @@ public: const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; } /*virtual*/ const LLMatrix4 getRenderMatrix() const; U32 getRenderCost(std::set<LLUUID> &textures) const; - /*virtual*/ F32 getStreamingCost(); + /*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL); /*virtual*/ U32 getTriangleCount(); /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES |