diff options
Diffstat (limited to 'indra/newview/llfloatermodelpreview.cpp')
-rwxr-xr-x | indra/newview/llfloatermodelpreview.cpp | 399 |
1 files changed, 260 insertions, 139 deletions
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 46c7cba53a..c948efe17f 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -283,6 +283,7 @@ BOOL LLFloaterModelPreview::postBuild() childSetAction("lod_browse", onBrowseLOD, this); + childSetCommitCallback("cancel_btn", onCancel, this); childSetCommitCallback("crease_angle", onGenerateNormalsCommit, this); childSetCommitCallback("generate_normals", onGenerateNormalsCommit, this); @@ -379,7 +380,7 @@ LLFloaterModelPreview::~LLFloaterModelPreview() { sInstance = NULL; - if ( mModelPreview->containsRiggedAsset() ) + if ( mModelPreview->mModelLoader->mResetJoints ) { gAgentAvatarp->resetJointPositions(); } @@ -560,7 +561,14 @@ void LLFloaterModelPreview::draw() LLMutexLock lock(mStatusLock); childSetTextArg("status", "[STATUS]", mStatusMessage); } - + else + { + childSetVisible("Simplify", true); + childSetVisible("simplify_cancel", false); + childSetVisible("Decompose", true); + childSetVisible("decompose_cancel", false); + } + U32 resource_cost = mModelPreview->mResourceCost*10; if (childGetValue("upload_textures").asBoolean()) @@ -736,7 +744,8 @@ void LLFloaterModelPreview::onPhysicsParamCommit(LLUICtrl* ctrl, void* data) //static void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data) { - LLCDStageData* stage = (LLCDStageData*) data; + LLCDStageData* stage_data = (LLCDStageData*) data; + std::string stage = stage_data->mName; if (sInstance) { @@ -751,11 +760,22 @@ void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data) for (S32 i = 0; i < sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS].size(); ++i) { LLModel* mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][i]; - DecompRequest* request = new DecompRequest(stage->mName, mdl); + DecompRequest* request = new DecompRequest(stage, mdl); sInstance->mCurRequest.insert(request); gMeshRepo.mDecompThread->submitRequest(request); } } + + if (stage == "Decompose") + { + sInstance->childSetVisible("Decompose", false); + sInstance->childSetVisible("decompose_cancel", true); + } + else if (stage == "Simplify") + { + sInstance->childSetVisible("Simplify", false); + sInstance->childSetVisible("simplify_cancel", true); + } } } @@ -778,6 +798,15 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata) sInstance->mModelPreview->setPhysicsFromLOD(which_mode); } +//static +void LLFloaterModelPreview::onCancel(LLUICtrl* ctrl, void* data) +{ + if (sInstance) + { + sInstance->closeFloater(false); + } +} + //static void LLFloaterModelPreview::onPhysicsStageCancel(LLUICtrl* ctrl, void*data) { @@ -796,7 +825,9 @@ void LLFloaterModelPreview::initDecompControls() { LLSD key; - childSetCommitCallback("cancel_btn", onPhysicsStageCancel, NULL); + childSetCommitCallback("simplify_cancel", onPhysicsStageCancel, NULL); + childSetCommitCallback("decompose_cancel", onPhysicsStageCancel, NULL); + childSetCommitCallback("physics_lod_combo", onPhysicsUseLOD, NULL); childSetCommitCallback("physics_browse", onPhysicsBrowse, NULL); @@ -929,7 +960,7 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl // LLModelLoader //----------------------------------------------------------------------------- LLModelLoader::LLModelLoader(std::string filename, S32 lod, LLModelPreview* preview) -: LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mState(STARTING), mFirstTransform(TRUE) +: LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mState(STARTING), mFirstTransform(TRUE), mResetJoints( FALSE ) { mJointMap["mPelvis"] = "mPelvis"; mJointMap["mTorso"] = "mTorso"; @@ -1006,6 +1037,28 @@ LLModelLoader::LLModelLoader(std::string filename, S32 lod, LLModelPreview* prev mJointMap["lThigh"] = "mHipLeft"; mJointMap["lShin"] = "mKneeLeft"; mJointMap["lFoot"] = "mFootLeft"; + + //move into joint mapper class + mMasterJointList.push_front("mPelvis"); + mMasterJointList.push_front("mTorso"); + mMasterJointList.push_front("mChest"); + mMasterJointList.push_front("mNeck"); + mMasterJointList.push_front("mHead"); + mMasterJointList.push_front("mSkull"); + mMasterJointList.push_front("mCollarLeft"); + mMasterJointList.push_front("mShoulderLeft"); + mMasterJointList.push_front("mElbowLeft"); + mMasterJointList.push_front("mWristLeft"); + mMasterJointList.push_front("mCollarRight"); + mMasterJointList.push_front("mShoulderRight"); + mMasterJointList.push_front("mElbowRight"); + mMasterJointList.push_front("mWristRight"); + mMasterJointList.push_front("mHipRight"); + mMasterJointList.push_front("mKneeRight"); + mMasterJointList.push_front("mFootRight"); + mMasterJointList.push_front("mHipLeft"); + mMasterJointList.push_front("mKneeLeft"); + mMasterJointList.push_front("mFootLeft"); } void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4a& max, BOOL& first_transform) @@ -1075,32 +1128,32 @@ void LLModelLoader::run() { DAE dae; domCOLLADA* dom = dae.open(mFilename); - + if (dom) { daeDatabase* db = dae.getDatabase(); - + daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH); - + daeDocument* doc = dae.getDoc(mFilename); if (!doc) { llwarns << "can't find internal doc" << llendl; return; } - + daeElement* root = doc->getDomRoot(); if (!root) { llwarns << "document has no root" << llendl; return; } - + //get unit scale mTransform.setIdentity(); - + domAsset::domUnit* unit = daeSafeCast<domAsset::domUnit>(root->getDescendant(daeElement::matchType(domAsset::domUnit::ID()))); - + if (unit) { F32 meter = unit->getMeter(); @@ -1108,19 +1161,19 @@ void LLModelLoader::run() mTransform.mMatrix[1][1] = meter; mTransform.mMatrix[2][2] = meter; } - + //get up axis rotation LLMatrix4 rotation; - + domUpAxisType up = UPAXISTYPE_Y_UP; // default is Y_UP domAsset::domUp_axis* up_axis = daeSafeCast<domAsset::domUp_axis>(root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID()))); - + if (up_axis) { up = up_axis->getValue(); } - + if (up == UPAXISTYPE_X_UP) { rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f); @@ -1129,20 +1182,20 @@ void LLModelLoader::run() { rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f); } - + rotation *= mTransform; mTransform = rotation; - - + + for (daeInt idx = 0; idx < count; ++idx) { //build map of domEntities to LLModel domMesh* mesh = NULL; db->getElement((daeElement**) &mesh, idx, NULL, COLLADA_TYPE_MESH); - + if (mesh) { LLPointer<LLModel> model = LLModel::loadModelFromDomMesh(mesh); - + if (model.notNull() && validate_model(model)) { mModelList.push_back(model); @@ -1150,17 +1203,17 @@ void LLModelLoader::run() } } } - + count = db->getElementCount(NULL, COLLADA_TYPE_SKIN); for (daeInt idx = 0; idx < count; ++idx) { //add skinned meshes as instances domSkin* skin = NULL; db->getElement((daeElement**) &skin, idx, NULL, COLLADA_TYPE_SKIN); - + if (skin) { domGeometry* geom = daeSafeCast<domGeometry>(skin->getSource().getElement()); - + if (geom) { domMesh* mesh = geom->getMesh(); @@ -1172,25 +1225,25 @@ void LLModelLoader::run() LLVector3 mesh_scale_vector; LLVector3 mesh_translation_vector; model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); - + LLMatrix4 normalized_transformation; normalized_transformation.setTranslation(mesh_translation_vector); - + LLMatrix4 mesh_scale; mesh_scale.initScale(mesh_scale_vector); mesh_scale *= normalized_transformation; normalized_transformation = mesh_scale; - + glh::matrix4f inv_mat((F32*) normalized_transformation.mMatrix); inv_mat = inv_mat.inverse(); LLMatrix4 inverse_normalized_transformation(inv_mat.m); - + domSkin::domBind_shape_matrix* bind_mat = skin->getBind_shape_matrix(); - + if (bind_mat) { //get bind shape matrix domFloat4x4& dom_value = bind_mat->getValue(); - + for (int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) @@ -1198,26 +1251,26 @@ void LLModelLoader::run() model->mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4]; } } - + LLMatrix4 trans = normalized_transformation; trans *= model->mBindShapeMatrix; model->mBindShapeMatrix = trans; - + } - - + + //The joint transfom map that we'll populate below std::map<std::string,LLMatrix4> jointTransforms; jointTransforms.clear(); - + //Some collada setup for accessing the skeleton daeElement* pElement = 0; dae.getDatabase()->getElement( &pElement, 0, 0, "skeleton" ); - + //Try to get at the skeletal instance controller domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement ); bool missingSkeletonOrScene = false; - + //If no skeleton, do a breadth-first search to get at specific joints if ( !pSkeleton ) { @@ -1232,7 +1285,7 @@ void LLModelLoader::run() //Get the children at this level daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren(); S32 childCount = children.getCount(); - + //Process any children that are joints //Not all children are joints, some code be ambient lights, cameras, geometry etc.. for (S32 i = 0; i < childCount; ++i) @@ -1246,7 +1299,7 @@ void LLModelLoader::run() } } else - //Has Skeleton + //Has Skeleton { //Get the root node of the skeleton daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); @@ -1255,7 +1308,7 @@ void LLModelLoader::run() //Once we have the root node - start acccessing it's joint components const int jointCnt = mJointMap.size(); std::map<std::string, std::string> :: const_iterator jointIt = mJointMap.begin(); - + //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor. for ( int i=0; i<jointCnt; ++i, ++jointIt ) { @@ -1263,10 +1316,10 @@ void LLModelLoader::run() char str[64]={0}; sprintf(str,"./%s",(*jointIt).second.c_str() ); //llwarns<<"Joint "<< str <<llendl; - + //Setup the resolver daeSIDResolver resolver( pSkeletonRootNode, str ); - + //Look for the joint domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() ); if ( pJoint ) @@ -1274,9 +1327,9 @@ void LLModelLoader::run() //Pull out the translate id and store it in the jointTranslations map daeSIDResolver jointResolver( pJoint, "./translate" ); domTranslate* pTranslate = daeSafeCast<domTranslate>( jointResolver.getElement() ); - + LLMatrix4 workingTransform; - + //Translation via SID if ( pTranslate ) { @@ -1296,12 +1349,12 @@ void LLModelLoader::run() extractTranslationViaElement( pTranslateElement, workingTransform ); } } - + //Store the joint transform w/respect to it's name. jointTransforms[(*jointIt).second.c_str()] = workingTransform; } } - + //If anything failed in regards to extracting the skeleton, joints or translation id, //mention it if ( missingSkeletonOrScene ) @@ -1310,64 +1363,32 @@ void LLModelLoader::run() } }//got skeleton? } - - if ( !missingSkeletonOrScene ) - { - //Set the joint translations on the avatar - //The joints are reset in the dtor - const int jointCnt = mJointMap.size(); - std::map<std::string, std::string> :: const_iterator jointIt = mJointMap.begin(); - for ( int i=0; i<jointCnt; ++i, ++jointIt ) - { - std::string lookingForJoint = (*jointIt).first.c_str(); - if ( jointTransforms.find( lookingForJoint ) != jointTransforms.end() ) - { - LLMatrix4 jointTransform = jointTransforms[lookingForJoint]; - LLJoint* pJoint = gAgentAvatarp->getJoint( lookingForJoint ); - if ( pJoint ) - { - pJoint->storeCurrentXform( jointTransform.getTranslation() ); - } - else - { - //Most likely an error in the asset. - llwarns<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << llendl; - } - //Reposition the avatars pelvis (avPos+offset) - //if ( lookingForJoint == "mPelvis" ) - //{ - // const LLVector3& pos = gAgentAvatarp->getCharacterPosition(); - // gAgentAvatarp->setPelvisOffset( true, jointTransform.getTranslation() ); - // gAgentAvatarp->setPosition( pos + jointTransform.getTranslation() ); - //} - } - } - } //missingSkeletonOrScene - + + domSkin::domJoints* joints = skin->getJoints(); - + domInputLocal_Array& joint_input = joints->getInput_array(); - + for (size_t i = 0; i < joint_input.getCount(); ++i) { domInputLocal* input = joint_input.get(i); xsNMTOKEN semantic = input->getSemantic(); - + if (strcmp(semantic, COMMON_PROFILE_INPUT_JOINT) == 0) { //found joint source, fill model->mJointMap and model->mJointList daeElement* elem = input->getSource().getElement(); - + domSource* source = daeSafeCast<domSource>(elem); if (source) { - - + + domName_array* names_source = source->getName_array(); - + if (names_source) { domListOfNames &names = names_source->getValue(); - + for (size_t j = 0; j < names.getCount(); ++j) { std::string name(names.get(j)); @@ -1385,7 +1406,7 @@ void LLModelLoader::run() if (names_source) { xsIDREFS& names = names_source->getValue(); - + for (size_t j = 0; j < names.getCount(); ++j) { std::string name(names.get(j).getID()); @@ -1410,11 +1431,11 @@ void LLModelLoader::run() { domListOfFloats& transform = t->getValue(); S32 count = transform.getCount()/16; - + for (S32 k = 0; k < count; ++k) { LLMatrix4 mat; - + for (int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) @@ -1422,14 +1443,55 @@ void LLModelLoader::run() mat.mMatrix[i][j] = transform[k*16 + i + j*4]; } } - + model->mInvBindMatrix.push_back(mat); } } } } } - + + //Now that we've parsed the joint array, let's determine if we have a full rig + //(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). + + if ( !model->mJointList.empty() && doesJointArrayContainACompleteRig( model->mJointList ) ) + { + mResetJoints = true; + } + + if ( !missingSkeletonOrScene ) + { + //Set the joint translations on the avatar - if it's a full mapping + //The joints are reset in the dtor + if ( mResetJoints ) + { + std::map<std::string, std::string> :: const_iterator masterJointIt = mJointMap.begin(); + std::map<std::string, std::string> :: const_iterator masterJointItEnd = mJointMap.end(); + for (;masterJointIt!=masterJointItEnd;++masterJointIt ) + { + std::string lookingForJoint = (*masterJointIt).first.c_str(); + + if ( jointTransforms.find( lookingForJoint ) != jointTransforms.end() ) + { + //llinfos<<"joint "<<lookingForJoint.c_str()<<llendl; + LLMatrix4 jointTransform = jointTransforms[lookingForJoint]; + LLJoint* pJoint = gAgentAvatarp->getJoint( lookingForJoint ); + if ( pJoint ) + { + pJoint->storeCurrentXform( jointTransform.getTranslation() ); + } + else + { + //Most likely an error in the asset. + llwarns<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << llendl; + } + } + } + } + } //missingSkeletonOrScene + //We need to construct the alternate bind matrix (which contains the new joint positions) //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. @@ -1453,9 +1515,9 @@ void LLModelLoader::run() llwarns<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<" ] "<<llendl; } } - + //grab raw position array - + domVertices* verts = mesh->getVertices(); if (verts) { @@ -1471,19 +1533,19 @@ void LLModelLoader::run() if (pos_array) { domListOfFloats& pos = pos_array->getValue(); - + for (size_t j = 0; j < pos.getCount(); j += 3) { if (pos.getCount() <= j+2) { llerrs << "WTF?" << llendl; } - + LLVector3 v(pos[j], pos[j+1], pos[j+2]); - + //transform from COLLADA space to volume space v = v * inverse_normalized_transformation; - + model->mPosition.push_back(v); } } @@ -1491,7 +1553,7 @@ void LLModelLoader::run() } } } - + //grab skin weights array domSkin::domVertex_weights* weights = skin->getVertex_weights(); if (weights) @@ -1509,44 +1571,44 @@ void LLModelLoader::run() } } } - + if (vertex_weights) { domListOfFloats& w = vertex_weights->getValue(); domListOfUInts& vcount = weights->getVcount()->getValue(); domListOfInts& v = weights->getV()->getValue(); - + U32 c_idx = 0; for (size_t vc_idx = 0; vc_idx < vcount.getCount(); ++vc_idx) { //for each vertex daeUInt count = vcount[vc_idx]; - + //create list of weights that influence this vertex LLModel::weight_list weight_list; - + for (daeUInt i = 0; i < count; ++i) { //for each weight daeInt joint_idx = v[c_idx++]; daeInt weight_idx = v[c_idx++]; - + if (joint_idx == -1) { //ignore bindings to bind_shape_matrix continue; } - + F32 weight_value = w[weight_idx]; - + weight_list.push_back(LLModel::JointWeight(joint_idx, weight_value)); } - + //sort by joint weight std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater()); - + std::vector<LLModel::JointWeight> wght; - + F32 total = 0.f; - + for (U32 i = 0; i < llmin((U32) 4, (U32) weight_list.size()); ++i) { //take up to 4 most significant weights if (weight_list[i].mWeight > 0.f) @@ -1555,7 +1617,7 @@ void LLModelLoader::run() total += weight_list[i].mWeight; } } - + F32 scale = 1.f/total; if (scale != 1.f) { //normalize weights @@ -1564,12 +1626,12 @@ void LLModelLoader::run() wght[i].mWeight *= scale; } } - + model->mSkinWeights[model->mPosition[vc_idx]] = wght; } - + //add instance to scene for this model - + LLMatrix4 transformation = mTransform; // adjust the transformation to compensate for mesh normalization @@ -1577,12 +1639,12 @@ void LLModelLoader::run() mesh_translation.setTranslation(mesh_translation_vector); mesh_translation *= transformation; transformation = mesh_translation; - + LLMatrix4 mesh_scale; mesh_scale.initScale(mesh_scale_vector); mesh_scale *= transformation; transformation = mesh_scale; - + std::vector<LLImportMaterial> materials; materials.resize(model->getNumVolumeFaces()); mScene[transformation].push_back(LLModelInstance(model, transformation, materials)); @@ -1594,24 +1656,83 @@ void LLModelLoader::run() } } } - + daeElement* scene = root->getDescendant("visual_scene"); - + if (!scene) { llwarns << "document has no visual_scene" << llendl; setLoadState( ERROR_PARSING ); return; } - setLoadState( DONE ); processElement(scene); - + doOnIdleOneTime(boost::bind(&LLModelPreview::loadModelCallback,mPreview,mLod)); } } +bool LLModelLoader::doesJointArrayContainACompleteRig( const std::vector<std::string> &jointListFromModel ) +{ + std::deque<std::string> :: const_iterator masterJointIt = mMasterJointList.begin(); + std::deque<std::string> :: const_iterator masterJointEndIt = mMasterJointList.end(); + + std::vector<std::string> :: const_iterator modelJointIt = jointListFromModel.begin(); + std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromModel.end(); + + bool found = false; + for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) + { + found = false; + modelJointIt = jointListFromModel.begin(); + for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt ) + { + if ( *masterJointIt == *modelJointIt ) + { + found = true; + break; + } + } + if ( !found ) + { + llinfos<<" Asset did not contain the joint (if you're u/l a fully rigged asset - it is required)." << *masterJointIt<< llendl; + break; + } + } + + return found; +} + +//called in the main thread +void LLModelLoader::loadTextures() +{ + BOOL is_paused = isPaused() ; + pause() ; //pause the loader + + for(scene::iterator iter = mScene.begin(); iter != mScene.end(); ++iter) + { + for(U32 i = 0 ; i < iter->second.size(); i++) + { + for(U32 j = 0 ; j < iter->second[i].mMaterial.size() ; j++) + { + if(!iter->second[i].mMaterial[j].mDiffuseMapFilename.empty()) + { + iter->second[i].mMaterial[j].mDiffuseMap = + LLViewerTextureManager::getFetchedTextureFromUrl("file://" + iter->second[i].mMaterial[j].mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW); + iter->second[i].mMaterial[j].mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE); + iter->second[i].mMaterial[j].mDiffuseMap->forceToSaveRawImage(); + } + } + } + } + + if(!is_paused) + { + unpause() ; + } +} + bool LLModelLoader::isNodeAJoint( domNode* pNode ) { if ( pNode->getName() == NULL) @@ -1917,14 +2038,8 @@ LLImportMaterial LLModelLoader::profileToMaterial(domProfile_COMMON* material) // we only support init_from now - embedded data will come later domImage::domInit_from* init = image->getInit_from(); if (init) - { - std::string filename = cdom::uriToNativePath(init->getValue().str()); - - mat.mDiffuseMap = LLViewerTextureManager::getFetchedTextureFromUrl("file://" + filename, TRUE, LLViewerTexture::BOOST_PREVIEW); - mat.mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, this->mPreview, NULL, FALSE); - - mat.mDiffuseMap->forceToSaveRawImage(); - mat.mDiffuseMapFilename = filename; + { + mat.mDiffuseMapFilename = cdom::uriToNativePath(init->getValue().str()); mat.mDiffuseMapLabel = getElementLabel(material); } } @@ -2039,7 +2154,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) mBuildShareTolerance = 0.f; mBuildQueueMode = GLOD_QUEUE_GREEDY; mBuildBorderMode = GLOD_BORDER_UNLOCK; - mBuildOperator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE; + mBuildOperator = GLOD_OPERATOR_EDGE_COLLAPSE; mViewOption["show_textures"] = false; @@ -2386,6 +2501,7 @@ void LLModelPreview::loadModelCallback(S32 lod) return; } + mModelLoader->loadTextures() ; mModel[lod] = mModelLoader->mModelList; mScene[lod] = mModelLoader->mScene; mVertexBuffer[lod].clear(); @@ -2752,7 +2868,9 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation) lod_mode = GLOD_TRIANGLE_BUDGET; if (which_lod != -1) { - limit = mFMP->childGetValue("lod_triangle_limit").asInteger(); + //SH-632 take budget as supplied limit+1 to prevent GLOD from creating a smaller + //decimation when the given decimation is possible + limit = mFMP->childGetValue("lod_triangle_limit").asInteger(); //+1; } } else @@ -2770,11 +2888,11 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation) if (build_operator == 0) { - build_operator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE; + build_operator = GLOD_OPERATOR_EDGE_COLLAPSE; } else { - build_operator = GLOD_OPERATOR_EDGE_COLLAPSE; + build_operator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE; } U32 queue_mode=0; @@ -3828,7 +3946,7 @@ BOOL LLModelPreview::render() gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true); if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1) { - mTextureSet.insert(instance.mMaterial[i].mDiffuseMap); + mTextureSet.insert(instance.mMaterial[i].mDiffuseMap.get()); } } } @@ -4261,11 +4379,14 @@ void LLFloaterModelPreview::DecompRequest::completed() if (sInstance) { - if (sInstance->mModelPreview) + if (mContinue) { - sInstance->mModelPreview->mPhysicsMesh[mModel] = mHullMesh; - sInstance->mModelPreview->mDirty = true; - LLFloaterModelPreview::sInstance->mModelPreview->refresh(); + if (sInstance->mModelPreview) + { + sInstance->mModelPreview->mPhysicsMesh[mModel] = mHullMesh; + sInstance->mModelPreview->mDirty = true; + LLFloaterModelPreview::sInstance->mModelPreview->refresh(); + } } sInstance->mCurRequest.erase(this); |