From 51a4867ae6bcf0ec71882ba77b1c995d98834126 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 21 Mar 2011 17:31:25 -0500 Subject: SH-1168 Export upload data to disk on upload. --- indra/llmath/m4math.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ indra/llmath/m4math.h | 2 ++ 2 files changed, 52 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index 8741400e52..bad4deb4de 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -829,4 +829,54 @@ std::ostream& operator<<(std::ostream& s, const LLMatrix4 &a) return s; } +LLSD LLMatrix4::getValue() const +{ + LLSD ret; + + ret[0] = mMatrix[0][0]; + ret[1] = mMatrix[0][1]; + ret[2] = mMatrix[0][2]; + ret[3] = mMatrix[0][3]; + + ret[4] = mMatrix[1][0]; + ret[5] = mMatrix[1][1]; + ret[6] = mMatrix[1][2]; + ret[7] = mMatrix[1][3]; + + ret[8] = mMatrix[2][0]; + ret[9] = mMatrix[2][1]; + ret[10] = mMatrix[2][2]; + ret[11] = mMatrix[2][3]; + + ret[12] = mMatrix[3][0]; + ret[13] = mMatrix[3][1]; + ret[14] = mMatrix[3][2]; + ret[15] = mMatrix[3][3]; + + return ret; +} + +void LLMatrix4::setValue(const LLSD& data) +{ + mMatrix[0][0] = data[0].asReal(); + mMatrix[0][1] = data[1].asReal(); + mMatrix[0][2] = data[2].asReal(); + mMatrix[0][3] = data[3].asReal(); + + mMatrix[1][0] = data[4].asReal(); + mMatrix[1][1] = data[5].asReal(); + mMatrix[1][2] = data[6].asReal(); + mMatrix[1][3] = data[7].asReal(); + + mMatrix[2][0] = data[8].asReal(); + mMatrix[2][1] = data[9].asReal(); + mMatrix[2][2] = data[10].asReal(); + mMatrix[2][3] = data[11].asReal(); + + mMatrix[3][0] = data[12].asReal(); + mMatrix[3][1] = data[13].asReal(); + mMatrix[3][2] = data[14].asReal(); + mMatrix[3][3] = data[15].asReal(); +} + diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index 3588f36758..a7dce10397 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -119,6 +119,8 @@ public: ~LLMatrix4(void); // Destructor + LLSD getValue() const; + void setValue(const LLSD&); ////////////////////////////// // -- cgit v1.3 From 6ff87e2840c585711e2927028a11ba5ce78a192a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 22 Mar 2011 17:23:48 -0500 Subject: SH-1169 Import from slm instead of dae when appropriate. --- indra/llmath/llvolume.cpp | 34 ++--- indra/newview/app_settings/settings.xml | 11 ++ indra/newview/llfloatermodelpreview.cpp | 226 ++++++++++++++++++++++++++++---- indra/newview/llfloatermodelpreview.h | 2 + indra/newview/llmeshrepository.cpp | 22 ++++ indra/newview/llmeshrepository.h | 6 + 6 files changed, 252 insertions(+), 49 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c4be176353..7a2f06da8f 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2162,7 +2162,7 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) LLSD header; { - if (!LLSDSerialize::deserialize(header, is, 1024*1024*1024)) + if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024)) { llwarns << "Mesh header parse error. Not a valid mesh asset!" << llendl; return FALSE; @@ -2174,34 +2174,18 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) "lowest_lod", "low_lod", "medium_lod", - "high_lod" + "high_lod", + "physics_shape", }; - S32 lod = llclamp((S32) mDetail, 0, 3); + const S32 MODEL_LODS = 5; - while (lod < 4 && - (header[nm[lod]]["offset"].asInteger() == -1 || - header[nm[lod]]["size"].asInteger() == 0 )) - { - ++lod; - } - - if (lod >= 4) - { - lod = llclamp((S32) mDetail, 0, 3); + S32 lod = llclamp((S32) mDetail, 0, MODEL_LODS); - while (lod >= 0 && - (header[nm[lod]]["offset"].asInteger() == -1 || - header[nm[lod]]["size"].asInteger() == 0) ) - { - --lod; - } - - if (lod < 0) - { - llwarns << "Mesh header missing LOD offsets. Not a valid mesh asset!" << llendl; - return FALSE; - } + if (header[nm[lod]]["offset"].asInteger() == -1 || + header[nm[lod]]["size"].asInteger() == 0 ) + { //cannot load requested LOD + return FALSE; } is.seekg(header[nm[lod]]["offset"].asInteger(), std::ios_base::cur); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e27397ab1a..c11de57c42 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5523,6 +5523,17 @@ Value 1 + MeshImportUseSLM + + Comment + Use cached copy of last upload for a dae if available instead of loading dae file from scratch. + Persist + 1 + Type + Boolean + Value + 0 + MigrateCacheDirectory Comment diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 04dfcac20b..6145c6c16d 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -82,6 +82,7 @@ #include "llvoavatarself.h" #include "pipeline.h" #include "lluictrlfactory.h" +#include "llviewercontrol.h" #include "llviewermenu.h" #include "llviewermenufile.h" #include "llviewerregion.h" @@ -1088,8 +1089,15 @@ LLModelLoader::LLModelLoader(std::string filename, S32 lod, LLModelPreview* prev if (mPreview) { + //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(); mPreview->setLoadState(STARTING); } + else + { + mTrySLM = false; + } } void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4a& max, BOOL& first_transform) @@ -1167,6 +1175,38 @@ void LLModelLoader::run() bool LLModelLoader::doLoadModel() { + //first, look for a .slm file of the same name that was modified later + //than the .dae + + if (mTrySLM) + { + std::string filename = mFilename; + + std::string::size_type i = filename.rfind("."); + if (i != std::string::npos) + { + filename.replace(i, filename.size()-1, ".slm"); + llstat slm_status; + if (LLFile::stat(filename, &slm_status) == 0) + { //slm file exists + llstat dae_status; + if (LLFile::stat(mFilename, &dae_status) != 0 || + dae_status.st_mtime < slm_status.st_mtime) + { + if (loadFromSLM(filename)) + { //slm successfully loaded, if this fails, fall through and + //try loading from dae + + mLod = -1; //successfully loading from an slm implicitly sets all + //LoDs + return true; + } + } + } + } + } + + //no suitable slm exists, load from the .dae file DAE dae; domCOLLADA* dom = dae.open(mFilename); @@ -1744,6 +1784,91 @@ void LLModelLoader::setLoadState(U32 state) } } +bool LLModelLoader::loadFromSLM(const std::string& filename) +{ + //only need to populate mScene with data from slm + llstat stat; + + if (LLFile::stat(filename, &stat)) + { //file does not exist + return false; + } + + S32 file_size = (S32) stat.st_size; + + llifstream ifstream(filename, std::ifstream::in | std::ifstream::binary); + LLSD data; + LLSDSerialize::fromBinary(data, ifstream, file_size); + ifstream.close(); + + //build model list for each LoD + model_list model[LLModel::NUM_LODS]; + + LLSD& mesh = data["mesh"]; + + LLVolumeParams volume_params; + volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + + for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) + { + for (U32 i = 0; i < mesh.size(); ++i) + { + std::stringstream str(mesh[i].asString()); + LLPointer loaded_model = new LLModel(volume_params, (F32) lod); + if (loaded_model->createVolumeFacesFromStream(str)) + { + loaded_model->mLocalID = i; + model[lod].push_back(loaded_model); + } + else + { + llassert(model[lod].empty()); + } + } + } + + if (model[LLModel::LOD_HIGH].empty()) + { //failed to load high lod + return false; + } + + //load instance list + model_instance_list instance_list; + + LLSD& instance = data["instance"]; + + for (U32 i = 0; i < instance.size(); ++i) + { + //deserialize instance list + instance_list.push_back(LLModelInstance(instance[i])); + + //match up model instance pointers + S32 idx = instance_list[i].mLocalMeshID; + + for (U32 lod = 0; lod < LLModel::NUM_LODS; ++lod) + { + if (!model[lod].empty()) + { + instance_list[i].mLOD[lod] = model[lod][idx]; + } + } + + instance_list[i].mModel = model[LLModel::LOD_HIGH][idx]; + } + + + //convert instance_list to mScene + mFirstTransform = TRUE; + for (U32 i = 0; i < instance_list.size(); ++i) + { + LLModelInstance& cur_instance = instance_list[i]; + mScene[cur_instance.mTransform].push_back(cur_instance); + stretch_extents(cur_instance.mModel, cur_instance.mTransform, mExtents[0], mExtents[1], mFirstTransform); + } + + return true; +} + void LLModelLoader::loadModelCallback() { if (mPreview) @@ -2614,6 +2739,7 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw decomp, empty_hull, save_skinweights, save_joint_positions); + data["mesh"][instance.mModel->mLocalID] = str.str(); } @@ -2626,8 +2752,6 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw out.close(); } - - void LLModelPreview::clearModel(S32 lod) { if (lod < 0 || lod > LLModel::LOD_PHYSICS) @@ -2769,39 +2893,93 @@ void LLModelPreview::loadModelCallback(S32 lod) } mModelLoader->loadTextures() ; - mModel[lod] = mModelLoader->mModelList; - mScene[lod] = mModelLoader->mScene; - mVertexBuffer[lod].clear(); - if (lod == LLModel::LOD_PHYSICS) - { - mPhysicsMesh.clear(); - } + if (lod == -1) + { //populate all LoDs from model loader scene + mBaseModel.clear(); + mBaseScene.clear(); - setPreviewLOD(lod); + for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) + { //for each LoD + //clear scene and model info + mScene[lod].clear(); + mModel[lod].clear(); + mVertexBuffer[lod].clear(); + + if (mModelLoader->mScene.begin()->second[0].mLOD[lod].notNull()) + { //if this LoD exists in the loaded scene - if (lod == LLModel::LOD_HIGH) - { //save a copy of the highest LOD for automatic LOD manipulation - if (mBaseModel.empty()) - { //first time we've loaded a model, auto-gen LoD - mGenLOD = true; + //copy scene to current LoD + mScene[lod] = mModelLoader->mScene; + + //touch up copied scene to look like current LoD + for (LLModelLoader::scene::iterator iter = mScene[lod].begin(); iter != mScene[lod].end(); ++iter) + { + LLModelLoader::model_instance_list& list = iter->second; + + for (LLModelLoader::model_instance_list::iterator list_iter = list.begin(); list_iter != list.end(); ++list_iter) + { + //override displayed model with current LoD + list_iter->mModel = list_iter->mLOD[lod]; + + //add current model to current LoD's model list (LLModel::mLocalID makes a good vector index) + S32 idx = list_iter->mModel->mLocalID; + + if (mModel[lod].size() <= idx) + { //stretch model list to fit model at given index + mModel[lod].resize(idx+1); + } + + mModel[lod][idx] = list_iter->mModel; + } + } + } } - mBaseModel = mModel[lod]; - clearGLODGroup(); + //copy high lod to base scene for LoD generation + mBaseScene = mScene[LLModel::LOD_HIGH]; + mBaseModel = mModel[LLModel::LOD_HIGH]; - mBaseScene = mScene[lod]; - mVertexBuffer[5].clear(); + mDirty = true; + resetPreviewTarget(); } + else + { //only replace given LoD + mModel[lod] = mModelLoader->mModelList; + mScene[lod] = mModelLoader->mScene; + mVertexBuffer[lod].clear(); - clearIncompatible(lod); + if (lod == LLModel::LOD_PHYSICS) + { + mPhysicsMesh.clear(); + } - mDirty = true; + setPreviewLOD(lod); - if (lod == LLModel::LOD_HIGH) - { - resetPreviewTarget(); + + if (lod == LLModel::LOD_HIGH) + { //save a copy of the highest LOD for automatic LOD manipulation + if (mBaseModel.empty()) + { //first time we've loaded a model, auto-gen LoD + mGenLOD = true; + } + + mBaseModel = mModel[lod]; + clearGLODGroup(); + + mBaseScene = mScene[lod]; + mVertexBuffer[5].clear(); + } + + clearIncompatible(lod); + + mDirty = true; + + if (lod == LLModel::LOD_HIGH) + { + resetPreviewTarget(); + } } mLoading = false; diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 5efac91ba3..68fa0fa4c1 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -76,6 +76,7 @@ public: LLMatrix4 mTransform; BOOL mFirstTransform; LLVector3 mExtents[2]; + bool mTrySLM; std::map > mModel; @@ -97,6 +98,7 @@ public: virtual void run(); bool doLoadModel(); + bool loadFromSLM(const std::string& filename); void loadModelCallback(); void loadTextures() ; //called in the main thread. diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 47dc343f5e..a227627bc1 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3584,6 +3584,19 @@ void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg) mStatusMessage = msg; } +LLModelInstance::LLModelInstance(LLSD& data) +{ + mLocalMeshID = data["mesh_id"].asInteger(); + mLabel = data["label"].asString(); + mTransform.setValue(data["transform"]); + + for (U32 i = 0; i < data["material"].size(); ++i) + { + mMaterial.push_back(LLImportMaterial(data["material"][i])); + } +} + + LLSD LLModelInstance::asLLSD() { LLSD ret; @@ -3600,6 +3613,15 @@ LLSD LLModelInstance::asLLSD() return ret; } +LLImportMaterial::LLImportMaterial(LLSD& data) +{ + mDiffuseMapFilename = data["diffuse"]["filename"].asString(); + mDiffuseMapLabel = data["diffuse"]["label"].asString(); + mDiffuseColor.setValue(data["diffuse"]["color"]); + mFullbright = data["fullbright"].asBoolean(); +} + + LLSD LLImportMaterial::asLLSD() { LLSD ret; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 4d727bf1f2..f0c0f308d5 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -102,6 +102,8 @@ public: mDiffuseColor.set(1,1,1,1); } + LLImportMaterial(LLSD& data); + LLSD asLLSD(); }; @@ -114,6 +116,7 @@ public: std::string mLabel; LLUUID mMeshID; + S32 mLocalMeshID; LLMatrix4 mTransform; std::vector mMaterial; @@ -121,8 +124,11 @@ public: LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, std::vector& materials) : mModel(model), mLabel(label), mTransform(transform), mMaterial(materials) { + mLocalMeshID = -1; } + LLModelInstance(LLSD& data); + LLSD asLLSD(); }; -- cgit v1.3 From 1ff79683128f09baf6dbaf081092fda7e5f2fe65 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 28 Mar 2011 23:50:23 -0500 Subject: SH-1225 Add skinning info to import path of .slm files. --- indra/llmath/llvolume.cpp | 50 ----- indra/llmath/llvolume.h | 2 - indra/llprimitive/llmodel.cpp | 325 ++++++++++++++++++++++---------- indra/llprimitive/llmodel.h | 38 ++-- indra/newview/llfloatermodelpreview.cpp | 88 ++++++--- indra/newview/llmeshrepository.cpp | 59 +----- indra/newview/llmeshrepository.h | 12 -- 7 files changed, 315 insertions(+), 259 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 7a2f06da8f..dc360818d6 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2143,56 +2143,6 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs return retval; } -BOOL LLVolume::createVolumeFacesFromFile(const std::string& file_name) -{ - std::ifstream is; - - is.open(file_name.c_str(), std::ifstream::in | std::ifstream::binary); - - BOOL success = createVolumeFacesFromStream(is); - - is.close(); - - return success; -} - -BOOL LLVolume::createVolumeFacesFromStream(std::istream& is) -{ - mSculptLevel = -1; // default is an error occured - - LLSD header; - { - if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024)) - { - llwarns << "Mesh header parse error. Not a valid mesh asset!" << llendl; - return FALSE; - } - } - - std::string nm[] = - { - "lowest_lod", - "low_lod", - "medium_lod", - "high_lod", - "physics_shape", - }; - - const S32 MODEL_LODS = 5; - - S32 lod = llclamp((S32) mDetail, 0, MODEL_LODS); - - if (header[nm[lod]]["offset"].asInteger() == -1 || - header[nm[lod]]["size"].asInteger() == 0 ) - { //cannot load requested LOD - return FALSE; - } - - is.seekg(header[nm[lod]]["offset"].asInteger(), std::ios_base::cur); - - return unpackVolumeFaces(is, header[nm[lod]]["size"].asInteger()); -} - bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) { //input stream is now pointing at a zlib compressed block of LLSD diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 60b64b1285..01bfbd858b 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1048,8 +1048,6 @@ protected: BOOL generate(); void createVolumeFaces(); public: - virtual BOOL createVolumeFacesFromFile(const std::string& file_name); - virtual BOOL createVolumeFacesFromStream(std::istream& is); virtual bool unpackVolumeFaces(std::istream& is, S32 size); virtual void makeTetrahedron(); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 3669fef0dc..81420fadb7 100755 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -775,43 +775,6 @@ BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh) return FALSE; } - -BOOL LLModel::createVolumeFacesFromFile(const std::string& file_name) -{ - DAE dae; - domCOLLADA* dom = dae.open(file_name); - if (dom) - { - daeDatabase* db = dae.getDatabase(); - - daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH); - - mVolumeFaces.clear(); - mMaterialList.clear(); - - for (daeInt idx = 0; idx < count; ++idx) - { - domMesh* mesh = NULL; - - db->getElement((daeElement**) &mesh, idx, NULL, COLLADA_TYPE_MESH); - - if (mesh) - { - addVolumeFacesFromDomMesh(mesh); - } - } - - if (getNumVolumeFaces() > 0) - { - optimizeVolumeFaces(); - normalizeVolumeFaces(); - return TRUE; - } - } - - return FALSE; -} - void LLModel::offsetMesh( const LLVector3& pivotPoint ) { LLVector4a pivot( pivotPoint[VX], pivotPoint[VY], pivotPoint[VZ] ); @@ -1351,16 +1314,6 @@ std::string LLModel::getElementLabel(daeElement *element) return std::string("object"); } -//static -LLModel* LLModel::loadModelFromDae(std::string filename) -{ - LLVolumeParams volume_params; - volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - LLModel* ret = new LLModel(volume_params, 0.f); - ret->createVolumeFacesFromFile(filename); - return ret; -} - //static LLModel* LLModel::loadModelFromDomMesh(domMesh *mesh) { @@ -1473,49 +1426,7 @@ LLSD LLModel::writeModel( if (skinning) { //write skinning block - if (high->mJointList.size() != high->mInvBindMatrix.size()) - { - llerrs << "WTF?" << llendl; - } - - for (U32 i = 0; i < high->mJointList.size(); ++i) - { - mdl["skin"]["joint_names"][i] = high->mJointList[i]; - - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - mdl["skin"]["inverse_bind_matrix"][i][j*4+k] = high->mInvBindMatrix[i].mMatrix[j][k]; - } - } - } - - for (U32 i = 0; i < 4; i++) - { - for (U32 j = 0; j < 4; j++) - { - mdl["skin"]["bind_shape_matrix"][i*4+j] = high->mBindShapeMatrix.mMatrix[i][j]; - } - } - - - if ( upload_joints && high->mAlternateBindMatrix.size() > 0 ) - { - for (U32 i = 0; i < high->mJointList.size(); ++i) - { - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - mdl["skin"]["alt_inverse_bind_matrix"][i][j*4+k] = high->mAlternateBindMatrix[i].mMatrix[j][k]; - } - } - } - - mdl["skin"]["pelvis_offset"] = high->mPelvisOffset; - } - + mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints); } if (!decomp.empty() || !base_hull.empty()) @@ -1897,12 +1808,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite) return header; } -//static -LLModel* LLModel::loadModelFromAsset(std::string filename, S32 lod) -{ - return NULL; -} - LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) { weight_map::iterator iter = mSkinWeights.find(pos); @@ -1999,4 +1904,232 @@ void LLModel::setConvexHullDecomposition( mCenterOfHullCenters *= 1.f / mHullPoints; } +bool LLModel::loadModel(std::istream& is) +{ + mSculptLevel = -1; // default is an error occured + + LLSD header; + { + if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024)) + { + llwarns << "Mesh header parse error. Not a valid mesh asset!" << llendl; + return false; + } + } + + std::string nm[] = + { + "lowest_lod", + "low_lod", + "medium_lod", + "high_lod", + "physics_shape", + }; + + const S32 MODEL_LODS = 5; + + S32 lod = llclamp((S32) mDetail, 0, MODEL_LODS); + + if (header[nm[lod]]["offset"].asInteger() == -1 || + header[nm[lod]]["size"].asInteger() == 0 ) + { //cannot load requested LOD + return false; + } + + bool has_skin = header["skin"]["offset"].asInteger() >=0 && + header["skin"]["size"].asInteger() > 0; + + if (lod == LLModel::LOD_HIGH) + { //try to load skin info and decomp info + std::ios::pos_type cur_pos = is.tellg(); + loadSkinInfo(header, is); + is.seekg(cur_pos); + loadDecomposition(header, is); + is.seekg(cur_pos); + } + + + + is.seekg(header[nm[lod]]["offset"].asInteger(), std::ios_base::cur); + + if (unpackVolumeFaces(is, header[nm[lod]]["size"].asInteger())) + { + if (has_skin) + { + //build out mSkinWeight from face info + for (S32 i = 0; i < getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = getVolumeFace(i); + + if (face.mWeights) + { + for (S32 j = 0; j < face.mNumVertices; ++j) + { + LLVector4a& w = face.mWeights[j]; + + std::vector wght; + + for (S32 k = 0; k < 4; ++k) + { + S32 idx = (S32) w[k]; + F32 f = w[k] - idx; + if (f > 0.f) + { + wght.push_back(JointWeight(idx, f)); + } + } + + if (!wght.empty()) + { + LLVector3 pos(face.mPositions[j].getF32ptr()); + mSkinWeights[pos] = wght; + } + } + } + } + } + return true; + } + + return false; + +} + + +bool LLModel::loadSkinInfo(LLSD& header, std::istream &is) +{ + S32 offset = header["skin"]["offset"].asInteger(); + S32 size = header["skin"]["size"].asInteger(); + + if (offset >= 0 && size > 0) + { + is.seekg(offset, std::ios_base::cur); + + LLSD skin_data; + + if (unzip_llsd(skin_data, is, size)) + { + mSkinInfo.fromLLSD(skin_data); + return true; + } + } + + return false; +} + +bool LLModel::loadDecomposition(LLSD& header, std::istream& is) +{ + return true; +} + + +LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin) +{ + fromLLSD(skin); +} + +void LLMeshSkinInfo::fromLLSD(LLSD& skin) +{ + if (skin.has("joint_names")) + { + for (U32 i = 0; i < skin["joint_names"].size(); ++i) + { + mJointNames.push_back(skin["joint_names"][i]); + } + } + + if (skin.has("inverse_bind_matrix")) + { + for (U32 i = 0; i < skin["inverse_bind_matrix"].size(); ++i) + { + LLMatrix4 mat; + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + mat.mMatrix[j][k] = skin["inverse_bind_matrix"][i][j*4+k].asReal(); + } + } + + mInvBindMatrix.push_back(mat); + } + } + + if (skin.has("bind_shape_matrix")) + { + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + mBindShapeMatrix.mMatrix[j][k] = skin["bind_shape_matrix"][j*4+k].asReal(); + } + } + } + + if (skin.has("alt_inverse_bind_matrix")) + { + for (U32 i = 0; i < skin["alt_inverse_bind_matrix"].size(); ++i) + { + LLMatrix4 mat; + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + mat.mMatrix[j][k] = skin["alt_inverse_bind_matrix"][i][j*4+k].asReal(); + } + } + + mAlternateBindMatrix.push_back(mat); + } + } + + if (skin.has("pelvis_offset")) + { + mPelvisOffset = skin["pelvis_offset"].asReal(); + } +} + +LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const +{ + LLSD ret; + + for (U32 i = 0; i < mJointNames.size(); ++i) + { + ret["joint_names"][i] = mJointNames[i]; + + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + ret["inverse_bind_matrix"][i][j*4+k] = mInvBindMatrix[i].mMatrix[j][k]; + } + } + } + + for (U32 i = 0; i < 4; i++) + { + for (U32 j = 0; j < 4; j++) + { + ret["bind_shape_matrix"][i*4+j] = mBindShapeMatrix.mMatrix[i][j]; + } + } + + if ( include_joints && mAlternateBindMatrix.size() > 0 ) + { + for (U32 i = 0; i < mJointNames.size(); ++i) + { + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + ret["alt_inverse_bind_matrix"][i][j*4+k] = mAlternateBindMatrix[i].mMatrix[j][k]; + } + } + } + + ret["pelvis_offset"] = mPelvisOffset; + } + + return ret; +} diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index addf527d8d..81be9d1835 100755 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -36,6 +36,25 @@ class domMesh; #define MAX_MODEL_FACES 8 + +class LLMeshSkinInfo +{ +public: + LLUUID mMeshID; + std::vector mJointNames; + std::vector mInvBindMatrix; + std::vector mAlternateBindMatrix; + std::map mJointMap; + + LLMeshSkinInfo() { } + LLMeshSkinInfo(LLSD& data); + void fromLLSD(LLSD& data); + LLSD asLLSD(bool include_joints) const; + LLMatrix4 mBindShapeMatrix; + float mPelvisOffset; +}; + + class LLModel : public LLVolume { public: @@ -58,6 +77,9 @@ public: 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, @@ -98,8 +120,6 @@ public: LLSD& mdl, BOOL nowrite = FALSE); - static LLModel* loadModelFromAsset(std::string filename, S32 lod); - static LLModel* loadModelFromDae(std::string filename); static LLModel* loadModelFromDomMesh(domMesh* mesh); static std::string getElementLabel(daeElement* element); std::string getName() const; @@ -177,17 +197,8 @@ public: //get list of weight influences closest to given position weight_list& getJointInfluences(const LLVector3& pos); - //should always be true that mJointList[mJointMap["foo"]] == "foo" - - //map of joint names to joint index - std::map mJointMap; - - //list of joint names - std::vector mJointList; - - LLMatrix4 mBindShapeMatrix; - std::vector mInvBindMatrix; - std::vector mAlternateBindMatrix; + LLMeshSkinInfo mSkinInfo; + std::string mRequestedLabel; // name requested in UI, if any. std::string mLabel; // name computed from dae. @@ -210,7 +221,6 @@ public: protected: void addVolumeFacesFromDomMesh(domMesh* mesh); - virtual BOOL createVolumeFacesFromFile(const std::string& file_name); virtual BOOL createVolumeFacesFromDomMesh(domMesh *mesh); }; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index e440fa52d4..2204908bdf 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1326,17 +1326,19 @@ bool LLModelLoader::doLoadModel() { //get bind shape matrix domFloat4x4& dom_value = bind_mat->getValue(); + LLMeshSkinInfo& skin_info = model->mSkinInfo; + for (int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) { - model->mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4]; + skin_info.mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4]; } } LLMatrix4 trans = normalized_transformation; - trans *= model->mBindShapeMatrix; - model->mBindShapeMatrix = trans; + trans *= skin_info.mBindShapeMatrix; + skin_info.mBindShapeMatrix = trans; } @@ -1475,7 +1477,7 @@ bool LLModelLoader::doLoadModel() xsNMTOKEN semantic = input->getSemantic(); if (strcmp(semantic, COMMON_PROFILE_INPUT_JOINT) == 0) - { //found joint source, fill model->mJointMap and model->mJointList + { //found joint source, fill model->mJointMap and model->mSkinInfo.mJointNames daeElement* elem = input->getSource().getElement(); domSource* source = daeSafeCast(elem); @@ -1496,8 +1498,8 @@ bool LLModelLoader::doLoadModel() { name = mJointMap[name]; } - model->mJointList.push_back(name); - model->mJointMap[name] = j; + model->mSkinInfo.mJointNames.push_back(name); + model->mSkinInfo.mJointMap[name] = j; } } else @@ -1514,8 +1516,8 @@ bool LLModelLoader::doLoadModel() { name = mJointMap[name]; } - model->mJointList.push_back(name); - model->mJointMap[name] = j; + model->mSkinInfo.mJointNames.push_back(name); + model->mSkinInfo.mJointMap[name] = j; } } } @@ -1544,7 +1546,7 @@ bool LLModelLoader::doLoadModel() } } - model->mInvBindMatrix.push_back(mat); + model->mSkinInfo.mInvBindMatrix.push_back(mat); } } } @@ -1555,8 +1557,8 @@ bool LLModelLoader::doLoadModel() //(which means we have all the joints that are required for an avatar versus //a skinned asset attached to a node in a file that contains an entire skeleton, //but does not use the skeleton). - mPreview->setRigValid( doesJointArrayContainACompleteRig( model->mJointList ) ); - if ( !skeletonWithNoRootNode && !model->mJointList.empty() && mPreview->isRigValid() ) + mPreview->setRigValid( doesJointArrayContainACompleteRig( model->mSkinInfo.mJointNames ) ); + if ( !skeletonWithNoRootNode && !model->mSkinInfo.mJointNames.empty() && mPreview->isRigValid() ) { mResetJoints = true; } @@ -1596,8 +1598,8 @@ bool LLModelLoader::doLoadModel() //in the same order as they were stored in the joint buffer. The joints associated //with the skeleton are not stored in the same order as they are in the exported joint buffer. //This remaps the skeletal joints to be in the same order as the joints stored in the model. - std::vector :: const_iterator jointIt = model->mJointList.begin(); - const int jointCnt = model->mJointList.size(); + std::vector :: const_iterator jointIt = model->mSkinInfo.mJointNames.begin(); + const int jointCnt = model->mSkinInfo.mJointNames.size(); for ( int i=0; imInvBindMatrix[i]; + LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i]; newInverse.setTranslation( jointTransforms[lookingForJoint].getTranslation() ); - model->mAlternateBindMatrix.push_back( newInverse ); + model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse ); } else { @@ -1813,10 +1815,15 @@ bool LLModelLoader::loadFromSLM(const std::string& filename) { std::stringstream str(mesh[i].asString()); LLPointer loaded_model = new LLModel(volume_params, (F32) lod); - if (loaded_model->createVolumeFacesFromStream(str)) + if (loaded_model->loadModel(str)) { loaded_model->mLocalID = i; model[lod].push_back(loaded_model); + + if (lod == LLModel::LOD_HIGH && !loaded_model->mSkinInfo.mJointNames.empty()) + { //check to see if rig is valid + mPreview->setRigValid( doesJointArrayContainACompleteRig( loaded_model->mSkinInfo.mJointNames ) ); + } } else { @@ -1871,7 +1878,7 @@ void LLModelLoader::loadModelCallback() { if (mPreview) { - mPreview->loadModelCallback(mLod); + mPreview->loadModelCallback(mLod); } while (!isStopped()) @@ -2901,6 +2908,9 @@ void LLModelPreview::loadModelCallback(S32 lod) mBaseModel.clear(); mBaseScene.clear(); + bool skin_weights = false; + bool joint_positions = false; + for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) { //for each LoD @@ -2933,12 +2943,40 @@ void LLModelPreview::loadModelCallback(S32 lod) mModel[lod].resize(idx+1); } - mModel[lod][idx] = list_iter->mModel; + mModel[lod][idx] = list_iter->mModel; + if (!list_iter->mModel->mSkinWeights.empty()) + { + skin_weights = true; + + if (!list_iter->mModel->mSkinInfo.mAlternateBindMatrix.empty()) + { + joint_positions = true; + } + } } } } } + if (mFMP) + { + LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) mFMP; + + if (skin_weights) + { //enable uploading/previewing of skin weights if present in .slm file + fmp->enableViewOption("show_skin_weight"); + mViewOption["show_skin_weight"] = true; + fmp->childSetValue("upload_skin", true); + } + + if (joint_positions) + { + fmp->enableViewOption("show_joint_positions"); + mViewOption["show_joint_positions"] = true; + fmp->childSetValue("upload_joints", true); + } + } + //copy high lod to base scene for LoD generation mBaseScene = mScene[LLModel::LOD_HIGH]; mBaseModel = mModel[LLModel::LOD_HIGH]; @@ -3415,11 +3453,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim //of an open problem). target_model->mPosition = base->mPosition; target_model->mSkinWeights = base->mSkinWeights; - target_model->mJointMap = base->mJointMap; - target_model->mJointList = base->mJointList; - target_model->mInvBindMatrix = base->mInvBindMatrix; - target_model->mBindShapeMatrix = base->mBindShapeMatrix; - target_model->mAlternateBindMatrix = base->mAlternateBindMatrix; + target_model->mSkinInfo = base->mSkinInfo; //copy material list target_model->mMaterialList = base->mMaterialList; @@ -4391,12 +4425,12 @@ BOOL LLModelPreview::render() //build matrix palette LLMatrix4 mat[64]; - for (U32 j = 0; j < model->mJointList.size(); ++j) + for (U32 j = 0; j < model->mSkinInfo.mJointNames.size(); ++j) { - LLJoint* joint = avatar->getJoint(model->mJointList[j]); + LLJoint* joint = avatar->getJoint(model->mSkinInfo.mJointNames[j]); if (joint) { - mat[j] = model->mInvBindMatrix[j]; + mat[j] = model->mSkinInfo.mInvBindMatrix[j]; mat[j] *= joint->getWorldMatrix(); } } @@ -4437,7 +4471,7 @@ BOOL LLModelPreview::render() //VECTORIZE THIS LLVector3 v(face.mPositions[j].getF32ptr()); - v = v * model->mBindShapeMatrix; + v = v * model->mSkinInfo.mBindShapeMatrix; v = v * final_mat; position[j] = v; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index a2792bcdc6..f5fc0de0d3 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1111,66 +1111,9 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat } { - LLMeshSkinInfo info; + LLMeshSkinInfo info(skin); info.mMeshID = mesh_id; - if (skin.has("joint_names")) - { - for (U32 i = 0; i < skin["joint_names"].size(); ++i) - { - info.mJointNames.push_back(skin["joint_names"][i]); - } - } - - if (skin.has("inverse_bind_matrix")) - { - for (U32 i = 0; i < skin["inverse_bind_matrix"].size(); ++i) - { - LLMatrix4 mat; - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - mat.mMatrix[j][k] = skin["inverse_bind_matrix"][i][j*4+k].asReal(); - } - } - - info.mInvBindMatrix.push_back(mat); - } - } - - if (skin.has("bind_shape_matrix")) - { - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - info.mBindShapeMatrix.mMatrix[j][k] = skin["bind_shape_matrix"][j*4+k].asReal(); - } - } - } - - if (skin.has("alt_inverse_bind_matrix")) - { - for (U32 i = 0; i < skin["alt_inverse_bind_matrix"].size(); ++i) - { - LLMatrix4 mat; - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - mat.mMatrix[j][k] = skin["alt_inverse_bind_matrix"][i][j*4+k].asReal(); - } - } - - info.mAlternateBindMatrix.push_back(mat); - } - } - - if (skin.has("pelvis_offset")) - { - info.mPelvisOffset = skin["pelvis_offset"].asReal(); - } //llinfos<<"info pelvis offset"< mJointNames; - std::vector mInvBindMatrix; - std::vector mAlternateBindMatrix; - - LLMatrix4 mBindShapeMatrix; - float mPelvisOffset; -}; - class LLMeshDecomposition { public: -- cgit v1.3 From f90eb750f1e8c3e300d1a079fe99d15f35201072 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 7 Apr 2011 00:29:02 -0500 Subject: SH-1292 Remove outliers from graphs in scene console to make a more useful view. --- indra/llmath/llmath.h | 39 +++++++++++++++++++++++ indra/newview/llfasttimerview.cpp | 45 +++------------------------ indra/newview/llsceneview.cpp | 65 +++++++++++++++++++-------------------- 3 files changed, 75 insertions(+), 74 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index 25b29ac1a8..97001b4062 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -29,6 +29,7 @@ #include #include +#include #include "lldefs.h" //#include "llstl.h" // *TODO: Remove when LLString is gone //#include "llstring.h" // *TODO: Remove when LLString is gone @@ -497,6 +498,44 @@ inline F32 llgaussian(F32 x, F32 o) return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2*o*o)); } +//helper function for removing outliers +template +inline void ll_remove_outliers(std::vector& data, F32 k) +{ + if (data.size() < 100) + { //not enough samples + return; + } + + VEC_TYPE Q1 = data[data.size()/4]; + VEC_TYPE Q3 = data[data.size()-data.size()/4-1]; + + VEC_TYPE min = Q1-k*(Q3-Q1); + VEC_TYPE max = Q3+k*(Q3-Q1); + + U32 i = 0; + while (i < data.size() && data[i] < min) + { + i++; + } + + S32 j = data.size()-1; + while (j > 0 && data[j] > max) + { + j--; + } + + if (j < data.size()-1) + { + data.erase(data.begin()+j, data.end()); + } + + if (i > 0) + { + data.erase(data.begin(), data.begin()+i); + } +} + // Include simd math header #include "llsimdmath.h" diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 6e78ea6bbe..35712163eb 100755 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -1040,43 +1040,6 @@ void saveChart(const std::string& label, const char* suffix, LLImageRaw* scratch result->save(out_file); } -template -void removeOutliers(std::vector& data, F32 k) -{ - if (data.size() < 100) - { //not enough samples - return; - } - - VEC_TYPE Q1 = data[data.size()/4]; - VEC_TYPE Q3 = data[data.size()-data.size()/4-1]; - - VEC_TYPE min = Q1-k*(Q3-Q1); - VEC_TYPE max = Q3+k*(Q3-Q1); - - U32 i = 0; - while (i < data.size() && data[i] < min) - { - i++; - } - - S32 j = data.size()-1; - while (j > 0 && data[j] > max) - { - j--; - } - - if (j < data.size()-1) - { - data.erase(data.begin()+j, data.end()); - } - - if (i > 0) - { - data.erase(data.begin(), data.begin()+i); - } -} - //static void LLFastTimerView::exportCharts(const std::string& base, const std::string& target) { @@ -1206,22 +1169,22 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t const U32 OUTLIER_CUTOFF = 512; if (base_times.size() > OUTLIER_CUTOFF) { - removeOutliers(base_times, 1.f); + ll_remove_outliers(base_times, 1.f); } if (base_execution.size() > OUTLIER_CUTOFF) { - removeOutliers(base_execution, 1.f); + ll_remove_outliers(base_execution, 1.f); } if (cur_times.size() > OUTLIER_CUTOFF) { - removeOutliers(cur_times, 1.f); + ll_remove_outliers(cur_times, 1.f); } if (cur_execution.size() > OUTLIER_CUTOFF) { - removeOutliers(cur_execution, 1.f); + ll_remove_outliers(cur_execution, 1.f); } diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp index dfc13bc9b8..25a7373018 100644 --- a/indra/newview/llsceneview.cpp +++ b/indra/newview/llsceneview.cpp @@ -36,6 +36,11 @@ LLSceneView* gSceneView = NULL; +//borrow this helper function from llfasttimerview.cpp +template +void removeOutliers(std::vector& data, F32 k); + + LLSceneView::LLSceneView(const LLRect& rect) : LLFloater(LLSD()) { @@ -72,8 +77,11 @@ void LLSceneView::draw() //object sizes std::vector size[2]; - std::vector triangles[2]; - std::vector visible_triangles[2]; + std::vector triangles[2]; + std::vector visible_triangles[2]; + + S32 total_visible_triangles[] = {0, 0}; + S32 total_triangles[] = {0, 0}; U32 object_count = 0; @@ -97,9 +105,14 @@ void LLSceneView::draw() F32 radius = object->getScale().magVec(); size[idx].push_back(radius); - visible_triangles[idx].push_back(volume->getNumTriangles()); - - triangles[idx].push_back(object->getHighLODTriangleCount()); + S32 visible = volume->getNumTriangles(); + S32 high_triangles = object->getHighLODTriangleCount(); + + total_visible_triangles[idx] += visible; + total_triangles[idx] += high_triangles; + + visible_triangles[idx].push_back(visible); + triangles[idx].push_back(high_triangles); } } } @@ -116,6 +129,8 @@ void LLSceneView::draw() { //display graph of object sizes std::sort(size[idx].begin(), size[idx].end()); + ll_remove_outliers(size[idx], 1.f); + LLRect size_rect; if (idx == 0) @@ -180,8 +195,9 @@ void LLSceneView::draw() if (!triangles[idx].empty()) { //plot graph of visible/total triangles std::sort(triangles[idx].begin(), triangles[idx].end()); - std::sort(visible_triangles[idx].begin(), visible_triangles[idx].end()); - + + ll_remove_outliers(triangles[idx], 1.f); + LLRect tri_rect; if (idx == 0) { @@ -194,19 +210,17 @@ void LLSceneView::draw() gl_rect_2d(tri_rect, LLColor4::white, false); - U32 tri_domain[] = { 65536, 0 }; - - llassert(triangles[idx].size() == visible_triangles[idx].size()); - - //get domain of sizes + S32 tri_domain[] = { 65536, 0 }; + + //get domain of triangle counts for (U32 i = 0; i < triangles[idx].size(); ++i) { - tri_domain[0] = llmin(visible_triangles[idx][i], llmin(tri_domain[0], triangles[idx][i])); - tri_domain[1] = llmax(visible_triangles[idx][i], llmax(tri_domain[1], triangles[idx][i])); + tri_domain[0] = llmin(tri_domain[0], triangles[idx][i]); + tri_domain[1] = llmax(tri_domain[1], triangles[idx][i]); } U32 triangle_range = tri_domain[1]-tri_domain[0]; - + U32 count = triangles[idx].size(); U32 total = 0; @@ -234,31 +248,16 @@ void LLSceneView::draw() gGL.flush(); U32 total_visible = 0; - gGL.begin(LLRender::LINE_STRIP); - //plot visible triangles + count = visible_triangles[idx].size(); + for (U32 i = 0; i < count; ++i) { U32 tri_count = visible_triangles[idx][i]; total_visible += tri_count; - F32 y = (F32) (tri_count-tri_domain[0])/triangle_range*tri_rect.getHeight()+tri_rect.mBottom; - F32 x = (F32) i / count * tri_rect.getWidth() + tri_rect.mLeft; - - gGL.vertex2f(x,y); - - if (i%4096 == 0) - { - gGL.end(); - gGL.flush(); - gGL.begin(LLRender::LINE_STRIP); - } } - gGL.end(); - gGL.flush(); - - std::string label = llformat("%s Object Triangle Counts (Ktris) -- Min: %.2f Max: %.2f Mean: %.2f Median: %.2f (%.2f/%.2f visible) -- %d samples", - category[idx], tri_domain[0]/1024.f, tri_domain[1]/1024.f, (total/count)/1024.f, triangles[idx][count/2]/1024.f, total_visible/1024.f, total/1024.f, count); + category[idx], tri_domain[0]/1024.f, tri_domain[1]/1024.f, (total/count)/1024.f, triangles[idx][count/2]/1024.f, total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f, count); LLFontGL::getFontMonospace()->renderUTF8(label, 0 , tri_rect.mLeft, tri_rect.mTop+margin, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); -- cgit v1.3 From 8807496ed78b36658f488d901842852d63f73cb9 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 8 Apr 2011 02:11:46 -0500 Subject: attempted fix for linux build --- indra/llmath/llmath.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index 97001b4062..eea7c977fb 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -510,8 +510,8 @@ inline void ll_remove_outliers(std::vector& data, F32 k) VEC_TYPE Q1 = data[data.size()/4]; VEC_TYPE Q3 = data[data.size()-data.size()/4-1]; - VEC_TYPE min = Q1-k*(Q3-Q1); - VEC_TYPE max = Q3+k*(Q3-Q1); + VEC_TYPE min = (VEC_TYPE) ((F32) Q1-k * (F32) (Q3-Q1)); + VEC_TYPE max = (VEC_TYPE) ((F32) Q3+k * (F32) (Q3-Q1)); U32 i = 0; while (i < data.size() && data[i] < min) -- cgit v1.3