diff options
Diffstat (limited to 'indra/newview/llfloatermodelpreview.cpp')
-rw-r--r-- | indra/newview/llfloatermodelpreview.cpp | 583 |
1 files changed, 398 insertions, 185 deletions
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index ab6753b4be..203be5bb1f 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -71,6 +71,7 @@ #include "llmatrix4a.h" #include "llmenubutton.h" #include "llmeshrepository.h" +#include "llnotificationsutil.h" #include "llsdutil_math.h" #include "lltextbox.h" #include "lltoolmgr.h" @@ -100,7 +101,12 @@ #include "llcallbacklist.h" #include "llviewerobjectlist.h" #include "llanimationstates.h" +#include "llviewernetwork.h" #include "glod/glod.h" +#include <boost/algorithm/string.hpp> + + +const S32 SLM_SUPPORTED_VERSION = 2; //static S32 LLFloaterModelPreview::sUploadAmount = 10; @@ -353,13 +359,16 @@ void LLMeshFilePicker::notify(const std::string& filename) // LLFloaterModelPreview() //----------------------------------------------------------------------------- LLFloaterModelPreview::LLFloaterModelPreview(const LLSD& key) : -LLFloater(key) +LLFloaterModelUploadBase(key), +mUploadBtn(NULL), +mCalculateBtn(NULL) { sInstance = this; mLastMouseX = 0; mLastMouseY = 0; mGLName = 0; mStatusLock = new LLMutex(NULL); + mModelPreview = NULL; mLODMode[LLModel::LOD_HIGH] = 0; for (U32 i = 0; i < LLModel::LOD_HIGH; i++) @@ -394,16 +403,17 @@ BOOL LLFloaterModelPreview::postBuild() childSetCommitCallback("border_mode", onLODParamCommit, this); childSetCommitCallback("share_tolerance", onLODParamCommit, this); + childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); + childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); + childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); + childSetTextArg("status", "[STATUS]", getString("status_idle")); - //childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount)); childSetAction("ok_btn", onUpload, this); childDisable("ok_btn"); childSetAction("reset_btn", onReset, this); - childSetAction("clear_materials", onClearMaterials, this); - childSetCommitCallback("preview_lod_combo", onPreviewLODCommit, this); childSetCommitCallback("upload_skin", onUploadSkinCommit, this); @@ -422,8 +432,6 @@ BOOL LLFloaterModelPreview::postBuild() childDisable("ok_btn"); - childSetCommitCallback("confirm_checkbox", refresh, this); - mViewOptionMenuButton = getChild<LLMenuButton>("options_gear_btn"); mCommitCallbackRegistrar.add("ModelImport.ViewOption.Action", boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _2)); @@ -441,9 +449,7 @@ BOOL LLFloaterModelPreview::postBuild() mPreviewRect = preview_panel->getRect(); - mModelPreview = new LLModelPreview(512, 512, this ); - mModelPreview->setPreviewTarget(16.f); - mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5)); + initModelPreview(); //set callbacks for left click on line editor rows for (U32 i = 0; i <= LLModel::LOD_HIGH; i++) @@ -472,6 +478,25 @@ BOOL LLFloaterModelPreview::postBuild() text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i)); } } + std::string current_grid = LLGridManager::getInstance()->getGridLabel(); + std::transform(current_grid.begin(),current_grid.end(),current_grid.begin(),::tolower); + std::string validate_url; + if (current_grid == "agni") + { + validate_url = "http://secondlife.com/my/account/mesh.php"; + } + else + { + validate_url = llformat("http://secondlife.%s.lindenlab.com/my/account/mesh.php",current_grid.c_str()); + } + getChild<LLTextBox>("warning_message")->setTextArg("[VURL]", validate_url); + + mUploadBtn = getChild<LLButton>("ok_btn"); + mCalculateBtn = getChild<LLButton>("calculate_btn"); + + mCalculateBtn->setClickedCallback(boost::bind(&LLFloaterModelPreview::onClickCalculateBtn, this)); + + toggleCalculateButton(true); return TRUE; } @@ -497,6 +522,19 @@ LLFloaterModelPreview::~LLFloaterModelPreview() mStatusLock = NULL; } +void LLFloaterModelPreview::initModelPreview() +{ + if (mModelPreview) + { + delete mModelPreview; + } + + mModelPreview = new LLModelPreview(512, 512, this ); + mModelPreview->setPreviewTarget(16.f); + mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5)); + mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1)); +} + void LLFloaterModelPreview::onViewOptionChecked(const LLSD& userdata) { if (mModelPreview) @@ -544,6 +582,30 @@ void LLFloaterModelPreview::loadModel(S32 lod) (new LLMeshFilePicker(mModelPreview, lod))->getFile(); } +void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm) +{ + mModelPreview->mLoading = true; + + mModelPreview->loadModel(file_name, lod, force_disable_slm); +} + +void LLFloaterModelPreview::onClickCalculateBtn() +{ + mModelPreview->rebuildUploadData(); + + bool upload_skinweights = childGetValue("upload_skin").asBoolean(); + bool upload_joint_positions = childGetValue("upload_joints").asBoolean(); + + mUploadModelUrl.clear(); + + gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, + childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mUploadModelUrl, false, + getWholeModelFeeObserverHandle()); + + toggleCalculateButton(false); + mUploadBtn->setEnabled(false); +} + //static void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata) { @@ -554,7 +616,10 @@ void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata) return; } - fp->mModelPreview->calcResourceCost(); + fp->mModelPreview->mDirty = true; + + fp->toggleCalculateButton(true); + fp->mModelPreview->refresh(); } //static @@ -566,7 +631,11 @@ void LLFloaterModelPreview::onPelvisOffsetCommit( LLUICtrl*, void* userdata ) { return; } - fp->mModelPreview->calcResourceCost(); + + fp->mModelPreview->mDirty = true; + + fp->toggleCalculateButton(true); + fp->mModelPreview->refresh(); } @@ -615,8 +684,6 @@ void LLFloaterModelPreview::onUploadSkinCommit(LLUICtrl*,void* userdata) { return; } - - fp->mModelPreview->calcResourceCost(); fp->mModelPreview->refresh(); fp->mModelPreview->resetPreviewTarget(); fp->mModelPreview->clearBuffers(); @@ -669,6 +736,7 @@ void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata) void LLFloaterModelPreview::onLODParamCommit(LLUICtrl* ctrl, void* userdata) { LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; + fp->mModelPreview->onLODParamCommit(false); } @@ -707,31 +775,11 @@ void LLFloaterModelPreview::draw() } } + childSetEnabled("ok_btn", mHasUploadPerm && !mUploadModelUrl.empty()); + childSetTextArg("prim_cost", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost)); childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size())); - if (!mCurRequest.empty()) - { - 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()) - { - resource_cost += mModelPreview->mTextureSet.size()*10; - } - - childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d", resource_cost)); - if (mModelPreview) { gGL.color3f(1.f, 1.f, 1.f); @@ -864,6 +912,12 @@ BOOL LLFloaterModelPreview::handleScrollWheel(S32 x, S32 y, S32 clicks) return TRUE; } +/*virtual*/ +void LLFloaterModelPreview::onOpen(const LLSD& key) +{ + requestAgentUploadPermissions(); +} + //static void LLFloaterModelPreview::onPhysicsParamCommit(LLUICtrl* ctrl, void* data) { @@ -925,12 +979,14 @@ void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data) sInstance->setStatusMessage(sInstance->getString("decomposing")); sInstance->childSetVisible("Decompose", false); sInstance->childSetVisible("decompose_cancel", true); + sInstance->childDisable("Simplify"); } else if (stage == "Simplify") { sInstance->setStatusMessage(sInstance->getString("simplifying")); sInstance->childSetVisible("Simplify", false); sInstance->childSetVisible("simplify_cancel", true); + sInstance->childDisable("Decompose"); } } } @@ -1329,6 +1385,8 @@ bool LLModelLoader::doLoadModel() if (!dom) { + llinfos<<" Error with dae - traditionally indicates a corrupt file."<<llendl; + setLoadState( ERROR_PARSING ); return false; } @@ -1883,8 +1941,11 @@ bool LLModelLoader::doLoadModel() mesh_scale *= transformation; transformation = mesh_scale; - std::vector<LLImportMaterial> materials; - materials.resize(model->getNumVolumeFaces()); + std::map<std::string, LLImportMaterial> materials; + for (U32 i = 0; i < model->mMaterialList.size(); ++i) + { + materials[model->mMaterialList[i]] = LLImportMaterial(); + } mScene[transformation].push_back(LLModelInstance(model, model->mLabel, transformation, materials)); stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform); } @@ -1946,6 +2007,11 @@ bool LLModelLoader::loadFromSLM(const std::string& filename) //build model list for each LoD model_list model[LLModel::NUM_LODS]; + if (data["version"].asInteger() != SLM_SUPPORTED_VERSION) + { //unsupported version + return false; + } + LLSD& mesh = data["mesh"]; LLVolumeParams volume_params; @@ -1968,10 +2034,6 @@ bool LLModelLoader::loadFromSLM(const std::string& filename) mPreview->critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames ); } } - else - { - llassert(model[lod].empty()); - } } } @@ -2125,15 +2187,11 @@ void LLModelPreview::critiqueRigForUploadApplicability( const std::vector<std::s setRigValidForJointPositionUpload( true ); } - if ( isRigLegacyOK ) - { + if ( isRigLegacyOK) + { setLegacyRigValid( true ); } - if ( getRigWithSceneParity() && isJointPositionUploadOK ) - { - setResetJointFlag( true ); - } } //----------------------------------------------------------------------------- // critiqueJointToNodeMappingFromScene() @@ -2173,12 +2231,7 @@ void LLModelPreview::critiqueJointToNodeMappingFromScene( void ) //2. Partial rig but w/o parity between the scene and joint array if ( result ) { - setResetJointFlag( true ); setRigWithSceneParity( true ); - } - else - { - setResetJointFlag( false ); } } //----------------------------------------------------------------------------- @@ -2267,14 +2320,17 @@ void LLModelLoader::loadTextures() { for(U32 i = 0 ; i < iter->second.size(); i++) { - for(U32 j = 0 ; j < iter->second[i].mMaterial.size() ; j++) + for(std::map<std::string, LLImportMaterial>::iterator j = iter->second[i].mMaterial.begin(); + j != iter->second[i].mMaterial.end(); ++j) { - if(!iter->second[i].mMaterial[j].mDiffuseMapFilename.empty()) + LLImportMaterial& material = j->second; + + if(!material.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(0, F32_MAX); + material.mDiffuseMap = + LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW); + material.mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE); + material.mDiffuseMap->forceToSaveRawImage(0, F32_MAX); mNumOfFetchingTextures++ ; } } @@ -2574,7 +2630,7 @@ void LLModelLoader::processElement( daeElement* element, bool& badElement ) { LLMatrix4 transformation = mTransform; - std::vector<LLImportMaterial> materials = getMaterials(model, instance_geo); + std::map<std::string, LLImportMaterial> materials = getMaterials(model, instance_geo); // adjust the transformation to compensate for mesh normalization LLVector3 mesh_scale_vector; @@ -2630,9 +2686,9 @@ void LLModelLoader::processElement( daeElement* element, bool& badElement ) } } -std::vector<LLImportMaterial> LLModelLoader::getMaterials(LLModel* model, domInstance_geometry* instance_geo) +std::map<std::string, LLImportMaterial> LLModelLoader::getMaterials(LLModel* model, domInstance_geometry* instance_geo) { - std::vector<LLImportMaterial> materials; + std::map<std::string, LLImportMaterial> materials; for (int i = 0; i < model->mMaterialList.size(); i++) { LLImportMaterial import_material; @@ -2679,7 +2735,8 @@ std::vector<LLImportMaterial> LLModelLoader::getMaterials(LLModel* model, domIns } } - materials.push_back(import_material); + import_material.mBinding = model->mMaterialList[i]; + materials[model->mMaterialList[i]] = import_material; } return materials; @@ -2919,8 +2976,7 @@ U32 LLModelPreview::calcResourceCost() if (mFMP && mModelLoader) { - const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean(); - if ( getLoadState() < LLModelLoader::ERROR_PARSING && confirmed_checkbox ) + if ( getLoadState() < LLModelLoader::ERROR_PARSING) { mFMP->childEnable("ok_btn"); } @@ -2933,16 +2989,9 @@ U32 LLModelPreview::calcResourceCost() if ( uploadingJointPositions && !isRigValidForJointPositionUpload() ) { mFMP->childDisable("ok_btn"); - } - else - if ( !isLegacyRigValid() ) - { - mFMP->childDisable("ok_btn"); - } - //ok_btn should not have been changed unless something was wrong with joint list + } } - U32 cost = 0; std::set<LLModel*> accounted; U32 num_points = 0; U32 num_hulls = 0; @@ -2990,8 +3039,7 @@ U32 LLModelPreview::calcResourceCost() mFMP->childGetValue("upload_skin").asBoolean(), mFMP->childGetValue("upload_joints").asBoolean(), TRUE); - cost += gMeshRepo.calcResourceCost(ret); - + num_hulls += decomp.mHull.size(); for (U32 i = 0; i < decomp.mHull.size(); ++i) { @@ -3011,7 +3059,7 @@ U32 LLModelPreview::calcResourceCost() F32 z_length = z_transformed.normalize(); LLVector3 scale = LLVector3(x_length, y_length, z_length); - F32 radius = scale.length()*debug_scale; + F32 radius = scale.length()*0.5f*debug_scale; streaming_cost += LLMeshRepository::getStreamingCost(ret, radius); } @@ -3023,7 +3071,7 @@ U32 LLModelPreview::calcResourceCost() updateStatusMessages(); - return cost; + return (U32) streaming_cost; } void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost) @@ -3031,8 +3079,6 @@ void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, childSetTextArg("import_dimensions", "[X]", llformat("%.3f", x)); childSetTextArg("import_dimensions", "[Y]", llformat("%.3f", y)); childSetTextArg("import_dimensions", "[Z]", llformat("%.3f", z)); - childSetTextArg("streaming cost", "[COST]", llformat("%.3f", streaming_cost)); - childSetTextArg("physics cost", "[COST]", llformat("%.3f", physics_cost)); } @@ -3062,12 +3108,24 @@ void LLModelPreview::rebuildUploadData() F32 max_scale = 0.f; - const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean(); - if ( mBaseScene.size() > 0 && confirmed_checkbox ) + if ( mBaseScene.size() > 0) { mFMP->childEnable("ok_btn"); } + //reorder materials to match mBaseModel + for (U32 i = 0; i < LLModel::NUM_LODS; i++) + { + if (mBaseModel.size() == mModel[i].size()) + { + for (U32 j = 0; j < mBaseModel.size(); ++j) + { + mModel[i][j]->matchMaterialOrder(mBaseModel[j]); + llassert(mModel[i][j]->mMaterialList == mBaseModel[j]->mMaterialList); + } + } + } + for (LLModelLoader::scene::iterator iter = mBaseScene.begin(); iter != mBaseScene.end(); ++iter) { //for each transform in scene LLMatrix4 mat = iter->first; @@ -3107,18 +3165,20 @@ void LLModelPreview::rebuildUploadData() } } - for (U32 i = 0; i < LLModel::NUM_LODS; i++) - { //fill LOD slots based on reference model index - if (!mModel[i].empty()) - { - instance.mLOD[i] = mModel[i][idx]; - } - else - { - instance.mLOD[i] = NULL; + if(idx < mBaseModel.size()) + { + for (U32 i = 0; i < LLModel::NUM_LODS; i++) + { //fill LOD slots based on reference model index + if (mModel[i].size() > idx) + { + instance.mLOD[i] = mModel[i][idx]; + } + else + { + instance.mLOD[i] = NULL; + } } } - instance.mTransform = mat; mUploadData.push_back(instance); } @@ -3164,6 +3224,8 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw LLSD data; + data["version"] = SLM_SUPPORTED_VERSION; + S32 mesh_id = 0; //build list of unique models and initialize local id @@ -3190,7 +3252,7 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw instance.mLOD[LLModel::LOD_LOW], instance.mLOD[LLModel::LOD_IMPOSTOR], decomp, - save_skinweights, save_joint_positions); + save_skinweights, save_joint_positions, FALSE, TRUE); data["mesh"][instance.mModel->mLocalID] = str.str(); @@ -3217,7 +3279,7 @@ void LLModelPreview::clearModel(S32 lod) mScene[lod].clear(); } -void LLModelPreview::loadModel(std::string filename, S32 lod) +void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable_slm) { assert_main_thread(); @@ -3254,6 +3316,11 @@ void LLModelPreview::loadModel(std::string filename, S32 lod) mModelLoader = new LLModelLoader(filename, lod, this, mJointTransformMap, mJointsFromNode ); + if (force_disable_slm) + { + mModelLoader->mTrySLM = false; + } + mModelLoader->start(); mFMP->childSetTextArg("status", "[STATUS]", mFMP->getString("status_reading_file")); @@ -3263,6 +3330,7 @@ void LLModelPreview::loadModel(std::string filename, S32 lod) if ( getLoadState() >= LLModelLoader::ERROR_PARSING ) { mFMP->childDisable("ok_btn"); + mFMP->childDisable( "calculate_btn" ); } if (lod == mPreviewLOD) @@ -3468,7 +3536,17 @@ void LLModelPreview::loadModelCallback(S32 lod) mLoading = false; if (mFMP) + { mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->set(FALSE); + if (!mBaseModel.empty()) + { + if (mFMP->getChild<LLUICtrl>("description_form")->getValue().asString().empty()) + { + const std::string& model_name = mBaseModel[0]->getName(); + mFMP->getChild<LLUICtrl>("description_form")->setValue(model_name); + } + } + } refresh(); mModelLoadedSignal(); @@ -3524,43 +3602,6 @@ void LLModelPreview::generateNormals() updateStatusMessages(); } -void LLModelPreview::clearMaterials() -{ - for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) - { //for each transform in current scene - for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) - { //for each instance with that transform - LLModelInstance& source_instance = *model_iter; - LLModel* source = source_instance.mModel; - - for (S32 i = 0; i < source->getNumVolumeFaces(); ++i) - { //for each face in instance - LLImportMaterial& source_material = source_instance.mMaterial[i]; - - //clear material info - source_material.mDiffuseColor = LLColor4(1,1,1,1); - source_material.mDiffuseMap = NULL; - source_material.mDiffuseMapFilename.clear(); - source_material.mDiffuseMapLabel.clear(); - source_material.mFullbright = false; - } - } - } - - mVertexBuffer[mPreviewLOD].clear(); - - if (mPreviewLOD == LLModel::LOD_HIGH) - { - mBaseScene = mScene[mPreviewLOD]; - mBaseModel = mModel[mPreviewLOD]; - clearGLODGroup(); - mVertexBuffer[5].clear(); - } - - mResourceCost = calcResourceCost(); - refresh(); -} - void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_limit) { if (mBaseModel.empty()) @@ -3734,7 +3775,9 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim U32 tri_count = 0; for (U32 i = 0; i < mVertexBuffer[5][mdl].size(); ++i) { - mVertexBuffer[5][mdl][i]->setBuffer(type_mask); + LLVertexBuffer* buff = mVertexBuffer[5][mdl][i]; + buff->setBuffer(type_mask & buff->getTypeMask()); + U32 num_indices = mVertexBuffer[5][mdl][i]->getNumIndices(); if (num_indices > 2) { @@ -3856,6 +3899,8 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim for (GLint i = 0; i < patch_count; ++i) { + type_mask = mVertexBuffer[5][base][i]->getTypeMask(); + LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0); if (sizes[i*2+1] > 0 && sizes[i*2] > 0) @@ -3880,8 +3925,15 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim LLStrider<U16> index; buff->getVertexStrider(pos); - buff->getNormalStrider(norm); - buff->getTexCoord0Strider(tc); + if (type_mask & LLVertexBuffer::MAP_NORMAL) + { + buff->getNormalStrider(norm); + } + if (type_mask & LLVertexBuffer::MAP_TEXCOORD0) + { + buff->getTexCoord0Strider(tc); + } + buff->getIndexStrider(index); target_model->setVolumeFaceData(names[i], pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices()); @@ -4087,18 +4139,20 @@ void LLModelPreview::updateStatusMessages() } else if (!verts[lod].empty()) { + S32 sum_verts_higher_lod = 0; + S32 sum_verts_this_lod = 0; for (U32 i = 0; i < verts[lod].size(); ++i) { - S32 max_verts = i < verts[lod+1].size() ? verts[lod+1][i] : 0; + sum_verts_higher_lod += ((i < verts[lod+1].size()) ? verts[lod+1][i] : 0); + sum_verts_this_lod += verts[lod][i]; + } - if (max_verts > 0) - { - if (verts[lod][i] > max_verts) - { //too many vertices in this lod - message = "mesh_status_too_many_vertices"; - upload_status[lod] = 2; - } - } + if ((sum_verts_higher_lod > 0) && + (sum_verts_this_lod > sum_verts_higher_lod)) + { + //too many vertices in this lod + message = "mesh_status_too_many_vertices"; + upload_status[lod] = 2; } } } @@ -4147,12 +4201,7 @@ void LLModelPreview::updateStatusMessages() if ( uploadingJointPositions && !isRigValidForJointPositionUpload() ) { skinAndRigOk = false; - } - else - if ( !isLegacyRigValid() ) - { - skinAndRigOk = false; - } + } } if(upload_ok && mModelLoader) @@ -4163,8 +4212,7 @@ void LLModelPreview::updateStatusMessages() } } - const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean(); - if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate && confirmed_checkbox) + if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate) { mFMP->childEnable("ok_btn"); } @@ -4269,6 +4317,24 @@ void LLModelPreview::updateStatusMessages() child->setEnabled(enable); child = panel->findNextSibling(child); } + + if (fmp->mCurRequest.empty()) + { + fmp->childSetVisible("Simplify", true); + fmp->childSetVisible("simplify_cancel", false); + fmp->childSetVisible("Decompose", true); + fmp->childSetVisible("decompose_cancel", false); + + if (phys_hulls > 0) + { + fmp->childEnable("Simplify"); + } + + if (phys_tris || phys_hulls > 0) + { + fmp->childEnable("Decompose"); + } + } } const char* lod_controls[] = @@ -4412,6 +4478,8 @@ void LLModelPreview::updateStatusMessages() crease->forceSetValue(mRequestedCreaseAngle[mPreviewLOD]); } + mModelUpdatedSignal(true); + } void LLModelPreview::setPreviewTarget(F32 distance) @@ -4485,7 +4553,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) bool skinned = include_skin_weights && !mdl->mSkinWeights.empty(); - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0 ; if (skinned) { @@ -4503,8 +4571,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) LLStrider<LLVector4> weights_strider; vb->getVertexStrider(vertex_strider); - vb->getNormalStrider(normal_strider); - vb->getTexCoord0Strider(tc_strider); vb->getIndexStrider(index_strider); if (skinned) @@ -4513,8 +4579,18 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) } LLVector4a::memcpyNonAliased16((F32*) vertex_strider.get(), (F32*) vf.mPositions, num_vertices*4*sizeof(F32)); - LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); - LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32)); + + if (vf.mTexCoords) + { + vb->getTexCoord0Strider(tc_strider); + LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); + } + + if (vf.mNormals) + { + vb->getNormalStrider(normal_strider); + LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32)); + } if (skinned) { @@ -4721,14 +4797,29 @@ BOOL LLModelPreview::render() mFMP->childSetValue("upload_joints", false); upload_joints = false; } - - mFMP->childSetEnabled("upload_joints", upload_skin); + + //Only enable joint offsets if it passed the earlier critiquing + if ( isRigValidForJointPositionUpload() ) + { + mFMP->childSetEnabled("upload_joints", upload_skin); + } F32 explode = mFMP->childGetValue("physics_explode").asReal(); glClear(GL_DEPTH_BUFFER_BIT); - LLRect preview_rect = mFMP->getChildView("preview_panel")->getRect(); + LLRect preview_rect; + + LLFloaterModelWizard* floater_wizard = dynamic_cast<LLFloaterModelWizard*>(mFMP); + if (floater_wizard) + { + preview_rect = floater_wizard->getPreviewRect(); + } + else + { + preview_rect = mFMP->getChildView("preview_panel")->getRect(); + } + F32 aspect = (F32) preview_rect.getWidth()/preview_rect.getHeight(); LLViewerCamera::getInstance()->setAspect(aspect); @@ -4773,6 +4864,8 @@ BOOL LLModelPreview::render() const F32 BRIGHTNESS = 0.9f; gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); + const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; + LLGLEnable normalize(GL_NORMALIZE); if (!mBaseModel.empty() && mVertexBuffer[5].empty()) @@ -4795,6 +4888,19 @@ BOOL LLModelPreview::render() } } + //make sure material lists all match + for (U32 i = 0; i < LLModel::NUM_LODS; i++) + { + if (mBaseModel.size() == mModel[i].size()) + { + for (U32 j = 0; j < mBaseModel.size(); ++j) + { + mModel[i][j]->matchMaterialOrder(mBaseModel[j]); + llassert(mModel[i][j]->mMaterialList == mBaseModel[j]->mMaterialList); + } + } + } + if (regen) { genBuffers(mPreviewLOD, skin_weight); @@ -4821,18 +4927,23 @@ BOOL LLModelPreview::render() for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i) { LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; - - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + + buffer->setBuffer(type_mask & buffer->getTypeMask()); if (textures) { - glColor4fv(instance.mMaterial[i].mDiffuseColor.mV); - if (i < instance.mMaterial.size() && instance.mMaterial[i].mDiffuseMap.notNull()) + const std::string& binding = instance.mModel->mMaterialList[i]; + const LLImportMaterial& material = instance.mMaterial[binding]; + + llassert(binding == model->mMaterialList[i]); + + glColor4fv(material.mDiffuseColor.mV); + if (material.mDiffuseMap.notNull()) { - if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1) + if (material.mDiffuseMap->getDiscardLevel() > -1) { - gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true); - mTextureSet.insert(instance.mMaterial[i].mDiffuseMap.get()); + gGL.getTexUnit(0)->bind(material.mDiffuseMap, true); + mTextureSet.insert(material.mDiffuseMap.get()); } } } @@ -4941,7 +5052,7 @@ BOOL LLModelPreview::render() { LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + buffer->setBuffer(type_mask & buffer->getTypeMask()); buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -5007,7 +5118,7 @@ BOOL LLModelPreview::render() { LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + buffer->setBuffer(type_mask & buffer->getTypeMask()); LLStrider<LLVector3> pos_strider; buffer->getVertexStrider(pos_strider, 0); @@ -5132,8 +5243,10 @@ BOOL LLModelPreview::render() position[j] = v; } - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); - glColor4fv(instance.mMaterial[i].mDiffuseColor.mV); + const std::string& binding = instance.mModel->mMaterialList[i]; + const LLImportMaterial& material = instance.mMaterial[binding]; + buffer->setBuffer(type_mask & buffer->getTypeMask()); + glColor4fv(material.mDiffuseColor.mV); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); glColor3f(0.4f, 0.4f, 0.4f); @@ -5253,7 +5366,12 @@ void LLFloaterModelPreview::onReset(void* user_data) LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) user_data; LLModelPreview* mp = fmp->mModelPreview; std::string filename = mp->mLODFile[3]; - mp->loadModel(filename,3); + + //reset model preview + fmp->initModelPreview(); + + mp = fmp->mModelPreview; + mp->loadModel(filename,3,true); } //static @@ -5271,31 +5389,18 @@ void LLFloaterModelPreview::onUpload(void* user_data) mp->mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions); gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale, - mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions); - - mp->closeFloater(false); + mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mp->mUploadModelUrl, + true, LLHandle<LLWholeModelFeeObserver>(), mp->getWholeModelUploadObserverHandle()); } //static -void LLFloaterModelPreview::onClearMaterials(void* user_data) -{ - LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data; - mp->mModelPreview->clearMaterials(); -} - -//static void LLFloaterModelPreview::refresh(LLUICtrl* ctrl, void* user_data) { + sInstance->toggleCalculateButton(true); sInstance->mModelPreview->mDirty = true; } -void LLFloaterModelPreview::updateResourceCost() -{ - U32 cost = mModelPreview->mResourceCost; - childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",cost)); -} - //static void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ) { @@ -5339,6 +5444,92 @@ void LLFloaterModelPreview::setStatusMessage(const std::string& msg) mStatusMessage = msg; } +void LLFloaterModelPreview::toggleCalculateButton() +{ + toggleCalculateButton(true); +} + +void LLFloaterModelPreview::toggleCalculateButton(bool visible) +{ + mCalculateBtn->setVisible(visible); + + bool uploadingSkin = childGetValue("upload_skin").asBoolean(); + bool uploadingJointPositions = childGetValue("upload_joints").asBoolean(); + if ( uploadingSkin ) + { + //Disable the calculate button *if* the rig is invalid - which is determined during the critiquing process + if ( uploadingJointPositions && !mModelPreview->isRigValidForJointPositionUpload() ) + { + mCalculateBtn->setVisible( false ); + } + } + + mUploadBtn->setVisible(!visible); + mUploadBtn->setEnabled(mHasUploadPerm && !mUploadModelUrl.empty()); + + if (visible) + { + std::string tbd = getString("tbd"); + childSetTextArg("weights", "[EQ]", tbd); + childSetTextArg("weights", "[ST]", tbd); + childSetTextArg("weights", "[SIM]", tbd); + childSetTextArg("weights", "[PH]", tbd); + childSetTextArg("upload_fee", "[FEE]", tbd); + childSetTextArg("price_breakdown", "[STREAMING]", tbd); + childSetTextArg("price_breakdown", "[PHYSICS]", tbd); + childSetTextArg("price_breakdown", "[INSTANCES]", tbd); + childSetTextArg("price_breakdown", "[TEXTURES]", tbd); + childSetTextArg("price_breakdown", "[MODEL]", tbd); + } +} + +void LLFloaterModelPreview::onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url) +{ + mModelPhysicsFee = result; + mModelPhysicsFee["url"] = upload_url; + + doOnIdleOneTime(boost::bind(&LLFloaterModelPreview::handleModelPhysicsFeeReceived,this)); +} + +void LLFloaterModelPreview::handleModelPhysicsFeeReceived() +{ + const LLSD& result = mModelPhysicsFee; + mUploadModelUrl = result["url"].asString(); + + childSetTextArg("weights", "[EQ]", llformat("%0.3f", result["resource_cost"].asReal())); + childSetTextArg("weights", "[ST]", llformat("%0.3f", result["model_streaming_cost"].asReal())); + childSetTextArg("weights", "[SIM]", llformat("%0.3f", result["simulation_cost"].asReal())); + childSetTextArg("weights", "[PH]", llformat("%0.3f", result["physics_cost"].asReal())); + childSetTextArg("upload_fee", "[FEE]", llformat("%d", result["upload_price"].asInteger())); + childSetTextArg("price_breakdown", "[STREAMING]", llformat("%d", result["upload_price_breakdown"]["mesh_streaming"].asInteger())); + childSetTextArg("price_breakdown", "[PHYSICS]", llformat("%d", result["upload_price_breakdown"]["mesh_physics"].asInteger())); + childSetTextArg("price_breakdown", "[INSTANCES]", llformat("%d", result["upload_price_breakdown"]["mesh_instance"].asInteger())); + childSetTextArg("price_breakdown", "[TEXTURES]", llformat("%d", result["upload_price_breakdown"]["texture"].asInteger())); + childSetTextArg("price_breakdown", "[MODEL]", llformat("%d", result["upload_price_breakdown"]["model"].asInteger())); + childSetVisible("weights", true); + childSetVisible("upload_fee", true); + childSetVisible("price_breakdown", true); + mUploadBtn->setEnabled(mHasUploadPerm && !mUploadModelUrl.empty()); +} + +void LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason) +{ + toggleCalculateButton(true); + llwarns << "LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(" << status << " : " << reason << ")" << llendl; +} + +/*virtual*/ +void LLFloaterModelPreview::onModelUploadSuccess() +{ + closeFloater(false); +} + +/*virtual*/ +void LLFloaterModelPreview::onModelUploadFailure() +{ + toggleCalculateButton(true); +} + S32 LLFloaterModelPreview::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2) { if (mContinue) @@ -5378,3 +5569,25 @@ void LLFloaterModelPreview::DecompRequest::completed() llassert(sInstance->mCurRequest.find(this) == sInstance->mCurRequest.end()); } } + +void dump_llsd_to_file(const LLSD& content, std::string filename); + +void LLFloaterModelPreview::onPermissionsReceived(const LLSD& result) +{ + dump_llsd_to_file(result,"perm_received.xml"); + std::string upload_status = result["mesh_upload_status"].asString(); + // BAP HACK: handle "" for case that MeshUploadFlag cap is broken. + mHasUploadPerm = (("" == upload_status) || ("valid" == upload_status)); + + //mUploadBtn->setEnabled(mHasUploadPerm); + mUploadBtn->setEnabled(mHasUploadPerm && !mUploadModelUrl.empty()); + getChild<LLTextBox>("warning_title")->setVisible(!mHasUploadPerm); + getChild<LLTextBox>("warning_message")->setVisible(!mHasUploadPerm); +} + +void LLFloaterModelPreview::setPermissonsErrorStatus(U32 status, const std::string& reason) +{ + llwarns << "LLFloaterModelPreview::setPermissonsErrorStatus(" << status << " : " << reason << ")" << llendl; + + LLNotificationsUtil::add("MeshUploadPermError"); +} |