From d196348d0f4bd542eee3702329dab28952b8a5e5 Mon Sep 17 00:00:00 2001 From: leyla_linden Date: Fri, 31 Dec 2010 12:53:39 -0800 Subject: Physics stage of wizard --- indra/newview/llfloatermodelpreview.cpp | 58 +- indra/newview/llfloatermodelpreview.h | 668 +++++----- indra/newview/llfloatermodelwizard.cpp | 223 +++- indra/newview/llfloatermodelwizard.h | 36 +- .../skins/default/xui/en/floater_model_wizard.xml | 1392 +++++++++++--------- 5 files changed, 1368 insertions(+), 1009 deletions(-) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 2f1ce25511..41fbdab2de 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -276,7 +276,10 @@ BOOL LLFloaterModelPreview::postBuild() return FALSE; } - setViewOption("show_textures", true); + + + + childSetAction("lod_browse", onBrowseLOD, this); @@ -393,13 +396,22 @@ LLFloaterModelPreview::~LLFloaterModelPreview() void LLFloaterModelPreview::onViewOptionChecked(const LLSD& userdata) { - mViewOption[userdata.asString()] = !mViewOption[userdata.asString()]; - mModelPreview->refresh(); + if (mModelPreview) + { + mModelPreview->mViewOption[userdata.asString()] = !mModelPreview->mViewOption[userdata.asString()]; + + mModelPreview->refresh(); + } } bool LLFloaterModelPreview::isViewOptionChecked(const LLSD& userdata) { - return mViewOption[userdata.asString()]; + if (mModelPreview) + { + return mModelPreview->mViewOption[userdata.asString()]; + } + + return false; } bool LLFloaterModelPreview::isViewOptionEnabled(const LLSD& userdata) @@ -422,11 +434,6 @@ void LLFloaterModelPreview::disableViewOption(const std::string& option) setViewOptionEnabled(option, false); } -void LLFloaterModelPreview::setViewOption(const std::string& option, bool value) -{ - mViewOption[option] = value; -} - void LLFloaterModelPreview::loadModel(S32 lod) { mModelPreview->mLoading = true; @@ -2017,7 +2024,9 @@ 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_HALF_EDGE_COLLAPSE; + + mViewOption["show_textures"] = false; mFMP = fmp; @@ -3258,13 +3267,14 @@ void LLModelPreview::updateStatusMessages() if (!fmp->isViewOptionEnabled("show_physics")) { fmp->enableViewOption("show_physics"); - fmp->setViewOption("show_physics", true); + mViewOption["show_physics"] = true; } } else { fmp->disableViewOption("show_physics"); - fmp->setViewOption("show_physics", false); + mViewOption["show_physics"] = false; + } //bool use_hull = fmp->childGetValue("physics_use_hull").asBoolean(); @@ -3589,21 +3599,11 @@ BOOL LLModelPreview::render() LLMutexLock lock(this); mNeedsUpdate = FALSE; - bool edges = false; - bool joint_positions = false; - bool skin_weight = false; - bool textures = false; - bool physics = false; - - LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; - if (fmp) - { - edges = fmp->isViewOptionChecked("show_edges"); - joint_positions = fmp->isViewOptionChecked("show_joint_positions"); - skin_weight = fmp->isViewOptionChecked("show_skin_weight"); - textures = fmp->isViewOptionChecked("show_textures"); - physics = fmp->isViewOptionChecked("show_physics"); - } + bool edges = mViewOption["show_edges"]; + bool joint_positions = mViewOption["show_joint_positions"]; + bool skin_weight = mViewOption["show_skin_weight"]; + bool textures = mViewOption["show_textures"]; + bool physics = mViewOption["show_physics"]; S32 width = getWidth(); S32 height = getHeight(); @@ -3636,6 +3636,8 @@ BOOL LLModelPreview::render() gGL.popMatrix(); } + LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; + bool has_skin_weights = false; bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean(); bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean(); @@ -3667,7 +3669,7 @@ BOOL LLModelPreview::render() mFMP->childDisable("upload_skin"); if (fmp) { - fmp->setViewOption("show_skin_weight", false); + mViewOption["show_skin_weight"] = false; fmp->disableViewOption("show_skin_weight"); fmp->disableViewOption("show_joint_positions"); } diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 48263d493a..df1b06aeaf 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -1,337 +1,333 @@ -/** - * @file llfloatermodelpreview.h - * @brief LLFloaterModelPreview class definition - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLFLOATERMODELPREVIEW_H -#define LL_LLFLOATERMODELPREVIEW_H - -#include "llfloaternamedesc.h" - -#include "lldynamictexture.h" -#include "llquaternion.h" -#include "llmeshrepository.h" -#include "llmodel.h" -#include "llthread.h" -#include "llviewermenufile.h" - -class LLComboBox; -class LLJoint; -class LLViewerJointMesh; -class LLVOAvatar; -class LLTextBox; -class LLVertexBuffer; -class LLModelPreview; -class LLFloaterModelPreview; -class daeElement; -class domProfile_COMMON; -class domInstance_geometry; -class domNode; -class domTranslate; -class LLMenuButton; -class LLToggleableMenu; - -const S32 NUM_LOD = 4; - -class LLModelLoader : public LLThread -{ -public: - typedef enum - { - STARTING = 0, - READING_FILE, - CREATING_FACES, - GENERATING_VERTEX_BUFFERS, - GENERATING_LOD, - DONE, - ERROR_PARSING, //basically loading failed - } eLoadState; - - U32 mState; - std::string mFilename; - S32 mLod; - LLModelPreview* mPreview; - LLMatrix4 mTransform; - BOOL mFirstTransform; - LLVector3 mExtents[2]; - - std::map > mModel; - - typedef std::vector > model_list; - model_list mModelList; - - typedef std::vector model_instance_list; - - typedef std::map scene; - - scene mScene; - - typedef std::queue > model_queue; - - //queue of models that need a physics rep - model_queue mPhysicsQ; - - LLModelLoader(std::string filename, S32 lod, LLModelPreview* preview); - - virtual void run(); - - void processElement(daeElement* element); - std::vector getMaterials(LLModel* model, domInstance_geometry* instance_geo); - LLImportMaterial profileToMaterial(domProfile_COMMON* material); - std::string getElementLabel(daeElement *element); - LLColor4 getDaeColor(daeElement* element); - - daeElement* getChildFromElement( daeElement* pElement, std::string const & name ); - - bool isNodeAJoint( domNode* pNode ); - void processJointNode( domNode* pNode, std::map& jointTransforms ); - void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ); - void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ); - - void setLoadState( U32 state ) { mState = state; } - U32 getLoadState( void ) { return mState; } - - //map of avatar joints as named in COLLADA assets to internal joint names - std::map mJointMap; -}; - -class LLFloaterModelPreview : public LLFloater -{ -public: - - class DecompRequest : public LLPhysicsDecomp::Request - { - public: - S32 mContinue; - LLPointer mModel; - - DecompRequest(const std::string& stage, LLModel* mdl); - virtual S32 statusCallback(const char* status, S32 p1, S32 p2); - virtual void completed(); - - }; - static LLFloaterModelPreview* sInstance; - - LLFloaterModelPreview(const LLSD& key); - virtual ~LLFloaterModelPreview(); - - virtual BOOL postBuild(); - - BOOL handleMouseDown(S32 x, S32 y, MASK mask); - BOOL handleMouseUp(S32 x, S32 y, MASK mask); - BOOL handleHover(S32 x, S32 y, MASK mask); - BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); - - static void onMouseCaptureLostModelPreview(LLMouseHandler*); - static void setUploadAmount(S32 amount) { sUploadAmount = amount; } - - static void onBrowseLOD(void* data); - - static void onUpload(void* data); - - static void onClearMaterials(void* data); - static void onModelDecompositionComplete(LLModel* model, std::vector >& physics_mesh); - - static void refresh(LLUICtrl* ctrl, void* data); - - void updateResourceCost(); - - void loadModel(S32 lod); - - void onViewOptionChecked(const LLSD& userdata); - bool isViewOptionChecked(const LLSD& userdata); - bool isViewOptionEnabled(const LLSD& userdata); - void setViewOptionEnabled(const std::string& option, bool enabled); - void enableViewOption(const std::string& option); - void disableViewOption(const std::string& option); - void setViewOption(const std::string& option, bool value); - -protected: - friend class LLModelPreview; - friend class LLMeshFilePicker; - friend class LLPhysicsDecomp; - - static void onImportScaleCommit(LLUICtrl*, void*); - static void onUploadJointsCommit(LLUICtrl*,void*); - static void onUploadSkinCommit(LLUICtrl*,void*); - - static void onPreviewLODCommit(LLUICtrl*,void*); - - static void onGenerateNormalsCommit(LLUICtrl*,void*); - - static void onAutoFillCommit(LLUICtrl*,void*); - static void onLODParamCommit(LLUICtrl*,void*); - - static void onExplodeCommit(LLUICtrl*, void*); - - static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata); - static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata); - static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata); - - static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata); - static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata); - static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata); - static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata); - static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata); - - void draw(); - - void initDecompControls(); - - void setStatusMessage(const std::string& msg); - - LLModelPreview* mModelPreview; - - LLPhysicsDecomp::decomp_params mDecompParams; - - S32 mLastMouseX; - S32 mLastMouseY; - LLRect mPreviewRect; - U32 mGLName; - static S32 sUploadAmount; - - std::set > mCurRequest; - std::string mStatusMessage; - +/** + * @file llfloatermodelpreview.h + * @brief LLFloaterModelPreview class definition + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERMODELPREVIEW_H +#define LL_LLFLOATERMODELPREVIEW_H + +#include "llfloaternamedesc.h" + +#include "lldynamictexture.h" +#include "llquaternion.h" +#include "llmeshrepository.h" +#include "llmodel.h" +#include "llthread.h" +#include "llviewermenufile.h" + +class LLComboBox; +class LLJoint; +class LLViewerJointMesh; +class LLVOAvatar; +class LLTextBox; +class LLVertexBuffer; +class LLModelPreview; +class LLFloaterModelPreview; +class daeElement; +class domProfile_COMMON; +class domInstance_geometry; +class domNode; +class domTranslate; +class LLMenuButton; +class LLToggleableMenu; + +const S32 NUM_LOD = 4; + +class LLModelLoader : public LLThread +{ +public: + typedef enum + { + STARTING = 0, + READING_FILE, + CREATING_FACES, + GENERATING_VERTEX_BUFFERS, + GENERATING_LOD, + DONE, + ERROR_PARSING, //basically loading failed + } eLoadState; + + U32 mState; + std::string mFilename; + S32 mLod; + LLModelPreview* mPreview; + LLMatrix4 mTransform; + BOOL mFirstTransform; + LLVector3 mExtents[2]; + + std::map > mModel; + + typedef std::vector > model_list; + model_list mModelList; + + typedef std::vector model_instance_list; + + typedef std::map scene; + + scene mScene; + + typedef std::queue > model_queue; + + //queue of models that need a physics rep + model_queue mPhysicsQ; + + LLModelLoader(std::string filename, S32 lod, LLModelPreview* preview); + + virtual void run(); + + void processElement(daeElement* element); + std::vector getMaterials(LLModel* model, domInstance_geometry* instance_geo); + LLImportMaterial profileToMaterial(domProfile_COMMON* material); + std::string getElementLabel(daeElement *element); + LLColor4 getDaeColor(daeElement* element); + + daeElement* getChildFromElement( daeElement* pElement, std::string const & name ); + + bool isNodeAJoint( domNode* pNode ); + void processJointNode( domNode* pNode, std::map& jointTransforms ); + void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ); + void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ); + + void setLoadState( U32 state ) { mState = state; } + U32 getLoadState( void ) { return mState; } + + //map of avatar joints as named in COLLADA assets to internal joint names + std::map mJointMap; +}; + +class LLFloaterModelPreview : public LLFloater +{ +public: + + class DecompRequest : public LLPhysicsDecomp::Request + { + public: + S32 mContinue; + LLPointer mModel; + + DecompRequest(const std::string& stage, LLModel* mdl); + virtual S32 statusCallback(const char* status, S32 p1, S32 p2); + virtual void completed(); + + }; + static LLFloaterModelPreview* sInstance; + + LLFloaterModelPreview(const LLSD& key); + virtual ~LLFloaterModelPreview(); + + virtual BOOL postBuild(); + + BOOL handleMouseDown(S32 x, S32 y, MASK mask); + BOOL handleMouseUp(S32 x, S32 y, MASK mask); + BOOL handleHover(S32 x, S32 y, MASK mask); + BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + + static void onMouseCaptureLostModelPreview(LLMouseHandler*); + static void setUploadAmount(S32 amount) { sUploadAmount = amount; } + + static void onBrowseLOD(void* data); + + static void onUpload(void* data); + + static void onClearMaterials(void* data); + + static void refresh(LLUICtrl* ctrl, void* data); + + void updateResourceCost(); + + void loadModel(S32 lod); + + void onViewOptionChecked(const LLSD& userdata); + bool isViewOptionChecked(const LLSD& userdata); + bool isViewOptionEnabled(const LLSD& userdata); + void setViewOptionEnabled(const std::string& option, bool enabled); + void enableViewOption(const std::string& option); + void disableViewOption(const std::string& option); + +protected: + friend class LLModelPreview; + friend class LLMeshFilePicker; + friend class LLPhysicsDecomp; + + static void onImportScaleCommit(LLUICtrl*, void*); + static void onUploadJointsCommit(LLUICtrl*,void*); + static void onUploadSkinCommit(LLUICtrl*,void*); + + static void onPreviewLODCommit(LLUICtrl*,void*); + + static void onGenerateNormalsCommit(LLUICtrl*,void*); + + static void onAutoFillCommit(LLUICtrl*,void*); + static void onLODParamCommit(LLUICtrl*,void*); + + static void onExplodeCommit(LLUICtrl*, void*); + + static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata); + static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata); + static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata); + + static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata); + static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata); + static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata); + static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata); + static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata); + + void draw(); + + void initDecompControls(); + + void setStatusMessage(const std::string& msg); + + LLModelPreview* mModelPreview; + + LLPhysicsDecomp::decomp_params mDecompParams; + + S32 mLastMouseX; + S32 mLastMouseY; + LLRect mPreviewRect; + U32 mGLName; + static S32 sUploadAmount; + + std::set > mCurRequest; + std::string mStatusMessage; + + //use "disabled" as false by default + std::map mViewOptionDisabled; + + //store which lod mode each LOD is using + // 0 - load from file + // 1 - auto generate + // 2 - None + S32 mLODMode[4]; + + LLMenuButton* mViewOptionMenuButton; + LLToggleableMenu* mViewOptionMenu; + LLMutex* mStatusLock; +}; + +class LLMeshFilePicker : public LLFilePickerThread +{ +public: + LLMeshFilePicker(LLModelPreview* mp, S32 lod); + virtual void notify(const std::string& filename); + +private: + LLModelPreview* mMP; + S32 mLOD; +}; + + +class LLModelPreview : public LLViewerDynamicTexture, public LLMutex +{ + public: + + LLModelPreview(S32 width, S32 height, LLFloater* fmp); + virtual ~LLModelPreview(); + + void resetPreviewTarget(); + void setPreviewTarget(F32 distance); + void setTexture(U32 name) { mTextureName = name; } + + void setPhysicsFromLOD(S32 lod); + BOOL render(); + void update(); + void genBuffers(S32 lod, bool skinned); + void clearBuffers(); + void refresh(); + void rotate(F32 yaw_radians, F32 pitch_radians); + void zoom(F32 zoom_amt); + void pan(F32 right, F32 up); + virtual BOOL needsRender() { return mNeedsUpdate; } + void setPreviewLOD(S32 lod); + void clearModel(S32 lod); + void loadModel(std::string filename, S32 lod); + void loadModelCallback(S32 lod); + void genLODs(S32 which_lod = -1, U32 decimation = 3); + void generateNormals(); + void consolidate(); + void clearMaterials(); + U32 calcResourceCost(); + void rebuildUploadData(); + void clearIncompatible(S32 lod); + void updateStatusMessages(); + bool containsRiggedAsset( void ); + void clearGLODGroup(); + + + static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); + + protected: + friend class LLFloaterModelPreview; + friend class LLFloaterModelWizard; + friend class LLFloaterModelPreview::DecompRequest; + friend class LLPhysicsDecomp; + + LLFloater* mFMP; + + BOOL mNeedsUpdate; + bool mDirty; + bool mGenLOD; + U32 mTextureName; + F32 mCameraDistance; + F32 mCameraYaw; + F32 mCameraPitch; + F32 mCameraZoom; + LLVector3 mCameraOffset; + LLVector3 mPreviewTarget; + LLVector3 mPreviewScale; + S32 mPreviewLOD; + U32 mResourceCost; + std::string mLODFile[LLModel::NUM_LODS]; + bool mLoading; + std::map mViewOption; - - //use "disabled" as false by default - std::map mViewOptionDisabled; - - //store which lod mode each LOD is using - // 0 - load from file - // 1 - auto generate - // 2 - None - S32 mLODMode[4]; - - LLMenuButton* mViewOptionMenuButton; - LLToggleableMenu* mViewOptionMenu; - LLMutex* mStatusLock; -}; - -class LLMeshFilePicker : public LLFilePickerThread -{ -public: - LLMeshFilePicker(LLModelPreview* mp, S32 lod); - virtual void notify(const std::string& filename); - -private: - LLModelPreview* mMP; - S32 mLOD; -}; - - -class LLModelPreview : public LLViewerDynamicTexture, public LLMutex -{ - public: - - LLModelPreview(S32 width, S32 height, LLFloater* fmp); - virtual ~LLModelPreview(); - - void resetPreviewTarget(); - void setPreviewTarget(F32 distance); - void setTexture(U32 name) { mTextureName = name; } - - void setPhysicsFromLOD(S32 lod); - BOOL render(); - void update(); - void genBuffers(S32 lod, bool skinned); - void clearBuffers(); - void refresh(); - void rotate(F32 yaw_radians, F32 pitch_radians); - void zoom(F32 zoom_amt); - void pan(F32 right, F32 up); - virtual BOOL needsRender() { return mNeedsUpdate; } - void setPreviewLOD(S32 lod); - void clearModel(S32 lod); - void loadModel(std::string filename, S32 lod); - void loadModelCallback(S32 lod); - void genLODs(S32 which_lod = -1, U32 decimation = 3); - void generateNormals(); - void consolidate(); - void clearMaterials(); - U32 calcResourceCost(); - void rebuildUploadData(); - void clearIncompatible(S32 lod); - void updateStatusMessages(); - bool containsRiggedAsset( void ); - void clearGLODGroup(); - - - static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); - - protected: - friend class LLFloaterModelPreview; - friend class LLFloaterModelWizard; - friend class LLFloaterModelPreview::DecompRequest; - friend class LLPhysicsDecomp; - - LLFloater* mFMP; - - BOOL mNeedsUpdate; - bool mDirty; - bool mGenLOD; - U32 mTextureName; - F32 mCameraDistance; - F32 mCameraYaw; - F32 mCameraPitch; - F32 mCameraZoom; - LLVector3 mCameraOffset; - LLVector3 mPreviewTarget; - LLVector3 mPreviewScale; - S32 mPreviewLOD; - U32 mResourceCost; - std::string mLODFile[LLModel::NUM_LODS]; - bool mLoading; - - //GLOD object parameters (must rebuild object if these change) - F32 mBuildShareTolerance; - U32 mBuildQueueMode; - U32 mBuildOperator; - U32 mBuildBorderMode; - - - LLModelLoader* mModelLoader; - - - LLModelLoader::scene mScene[LLModel::NUM_LODS]; - LLModelLoader::scene mBaseScene; - - LLModelLoader::model_list mModel[LLModel::NUM_LODS]; - LLModelLoader::model_list mBaseModel; - - U32 mGroup; - std::map, U32> mObject; - U32 mMaxTriangleLimit; - std::map, std::vector > > mPhysicsMesh; - - LLMeshUploadThread::instance_list mUploadData; - std::set > mTextureSet; - - //map of vertex buffers to models (one vertex buffer in vector per face in model - std::map > > mVertexBuffer[LLModel::NUM_LODS+1]; -}; - - -#endif // LL_LLFLOATERMODELPREVIEW_H + + //GLOD object parameters (must rebuild object if these change) + F32 mBuildShareTolerance; + U32 mBuildQueueMode; + U32 mBuildOperator; + U32 mBuildBorderMode; + + LLModelLoader* mModelLoader; + + LLModelLoader::scene mScene[LLModel::NUM_LODS]; + LLModelLoader::scene mBaseScene; + + LLModelLoader::model_list mModel[LLModel::NUM_LODS]; + LLModelLoader::model_list mBaseModel; + + U32 mGroup; + std::map, U32> mObject; + U32 mMaxTriangleLimit; + std::map, std::vector > > mPhysicsMesh; + + LLMeshUploadThread::instance_list mUploadData; + std::set > mTextureSet; + + //map of vertex buffers to models (one vertex buffer in vector per face in model + std::map > > mVertexBuffer[LLModel::NUM_LODS+1]; +}; + + +#endif // LL_LLFLOATERMODELPREVIEW_H diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp index aca5d67e60..fe53eafa40 100644 --- a/indra/newview/llfloatermodelwizard.cpp +++ b/indra/newview/llfloatermodelwizard.cpp @@ -35,10 +35,11 @@ #include "llfloatermodelwizard.h" #include "llfloatermodelpreview.h" #include "llfloaterreg.h" -#include "llslider.h" +#include "llsliderctrl.h" #include "lltoolmgr.h" #include "llviewerwindow.h" +LLFloaterModelWizard* LLFloaterModelWizard::sInstance = NULL; static const std::string stateNames[]={ "choose_file", @@ -50,8 +51,12 @@ static const std::string stateNames[]={ LLFloaterModelWizard::LLFloaterModelWizard(const LLSD& key) : LLFloater(key) { + sInstance = this; +} +LLFloaterModelWizard::~LLFloaterModelWizard() +{ + sInstance = NULL; } - void LLFloaterModelWizard::setState(int state) { mState = state; @@ -69,6 +74,34 @@ void LLFloaterModelWizard::setState(int state) if (state == OPTIMIZE) { mModelPreview->genLODs(-1); + mModelPreview->mViewOption["show_physics"] = false; + } + + if (state == PHYSICS) + { + mModelPreview->setPhysicsFromLOD(1); + mModelPreview->mViewOption["show_physics"] = true; + + getChild("next")->setVisible(true); + getChild("upload")->setVisible(false); + } + + if (state == REVIEW) + { + executePhysicsStage("Decompose"); + getChild("close")->setVisible(false); + getChild("next")->setVisible(false); + getChild("back")->setVisible(true); + getChild("upload")->setVisible(true); + getChild("cancel")->setVisible(true); + } + + if (state == UPLOAD) + { + getChild("close")->setVisible(true); + getChild("back")->setVisible(false); + getChild("upload")->setVisible(false); + getChild("cancel")->setVisible(false); } } @@ -227,6 +260,161 @@ BOOL LLFloaterModelWizard::handleScrollWheel(S32 x, S32 y, S32 clicks) return TRUE; } +void LLFloaterModelWizard::initDecompControls() +{ + LLSD key; + + static const LLCDStageData* stage = NULL; + static S32 stage_count = 0; + + if (!stage && LLConvexDecomposition::getInstance() != NULL) + { + stage_count = LLConvexDecomposition::getInstance()->getStages(&stage); + } + + static const LLCDParam* param = NULL; + static S32 param_count = 0; + if (!param && LLConvexDecomposition::getInstance() != NULL) + { + param_count = LLConvexDecomposition::getInstance()->getParameters(¶m); + } + + for (S32 j = stage_count-1; j >= 0; --j) + { + gMeshRepo.mDecompThread->mStageID[stage[j].mName] = j; + // protected against stub by stage_count being 0 for stub above + LLConvexDecomposition::getInstance()->registerCallback(j, LLPhysicsDecomp::llcdCallback); + + for (S32 i = 0; i < param_count; ++i) + { + if (param[i].mStage != j) + { + continue; + } + + std::string name(param[i].mName ? param[i].mName : ""); + std::string description(param[i].mDescription ? param[i].mDescription : ""); + + if (param[i].mType == LLCDParam::LLCD_FLOAT) + { + mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat); + } + else if (param[i].mType == LLCDParam::LLCD_INTEGER) + { + mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue); + } + else if (param[i].mType == LLCDParam::LLCD_BOOLEAN) + { + mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool); + } + else if (param[i].mType == LLCDParam::LLCD_ENUM) + { + mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue); + } + } + } + + mDecompParams["Simplify Method"] = 0; // set it to retain % +} + +//static +void LLFloaterModelWizard::executePhysicsStage(std::string stage_name) +{ + if (sInstance) + { + F64 physics_accuracy = sInstance->getChild("physics_slider")->getValue().asReal(); + + sInstance->mDecompParams["Retain%"] = physics_accuracy; + + if (!sInstance->mCurRequest.empty()) + { + llinfos << "Decomposition request still pending." << llendl; + return; + } + + if (sInstance->mModelPreview) + { + 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_name, mdl); + sInstance->mCurRequest.insert(request); + gMeshRepo.mDecompThread->submitRequest(request); + } + } + } +} + +LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLModel* mdl) +{ + mStage = stage; + mContinue = 1; + mModel = mdl; + mDecompID = &mdl->mDecompID; + mParams = sInstance->mDecompParams; + + //copy out positions and indices + if (mdl) + { + U16 index_offset = 0; + + mPositions.clear(); + mIndices.clear(); + + //queue up vertex positions and indices + for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = mdl->getVolumeFace(i); + if (mPositions.size() + face.mNumVertices > 65535) + { + continue; + } + + for (U32 j = 0; j < face.mNumVertices; ++j) + { + mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); + } + + for (U32 j = 0; j < face.mNumIndices; ++j) + { + mIndices.push_back(face.mIndices[j]+index_offset); + } + + index_offset += face.mNumVertices; + } + } +} + + +S32 LLFloaterModelWizard::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2) +{ + setStatusMessage(llformat("%s: %d/%d", status, p1, p2)); + + return mContinue; +} + +void LLFloaterModelWizard::DecompRequest::completed() +{ //called from the main thread + mModel->setConvexHullDecomposition(mHull); + + if (sInstance) + { + if (sInstance->mModelPreview) + { + sInstance->mModelPreview->mPhysicsMesh[mModel] = mHullMesh; + sInstance->mModelPreview->mDirty = true; + LLFloaterModelWizard::sInstance->mModelPreview->refresh(); + } + + sInstance->mCurRequest.erase(this); + } + + if (mStage == "Decompose") + { + executePhysicsStage("Simplify"); + } +} + BOOL LLFloaterModelWizard::postBuild() { @@ -236,13 +424,13 @@ BOOL LLFloaterModelWizard::postBuild() getChild("browse")->setCommitCallback(boost::bind(&LLFloaterModelWizard::loadModel, this)); getChild("cancel")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCancel, this)); + getChild("close")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCancel, this)); getChild("back")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickBack, this)); getChild("next")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickNext, this)); - childSetCommitCallback("preview_lod_combo", onPreviewLODCommit, this); + getChild("preview_lod_combo")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1)); getChild("accuracy_slider")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onAccuracyPerformance, this, _2)); - - childSetAction("ok_btn", onUpload, this); - + getChild("upload")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onUpload, this)); + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; enable_registrar.add("Next.OnEnable", boost::bind(&LLFloaterModelWizard::onEnableNext, this)); @@ -262,19 +450,20 @@ BOOL LLFloaterModelWizard::postBuild() childSetTextArg("import_dimensions", "[Y]", LLStringUtil::null); childSetTextArg("import_dimensions", "[Z]", LLStringUtil::null); + initDecompControls(); + return TRUE; } -void LLFloaterModelWizard::onUpload(void* user_data) -{ - LLFloaterModelWizard* mp = (LLFloaterModelWizard*) user_data; +void LLFloaterModelWizard::onUpload() +{ + mModelPreview->rebuildUploadData(); - mp->mModelPreview->rebuildUploadData(); + gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, + childGetValue("upload_textures").asBoolean(), childGetValue("upload_skin"), childGetValue("upload_joints")); - gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale, - mp->childGetValue("upload_textures").asBoolean(), mp->childGetValue("upload_skin"), mp->childGetValue("upload_joints")); + setState(UPLOAD); - mp->closeFloater(false); } @@ -287,11 +476,9 @@ void LLFloaterModelWizard::onAccuracyPerformance(const LLSD& data) mModelPreview->refresh(); } -void LLFloaterModelWizard::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata) +void LLFloaterModelWizard::onPreviewLODCommit(LLUICtrl* ctrl) { - LLFloaterModelWizard *fp =(LLFloaterModelWizard *)userdata; - - if (!fp->mModelPreview) + if (!mModelPreview) { return; } @@ -302,7 +489,7 @@ void LLFloaterModelWizard::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata) which_mode = (NUM_LOD-1)-combo->getFirstSelectedIndex(); // combo box list of lods is in reverse order - fp->mModelPreview->setPreviewLOD(which_mode); + mModelPreview->setPreviewLOD(which_mode); } void LLFloaterModelWizard::draw() diff --git a/indra/newview/llfloatermodelwizard.h b/indra/newview/llfloatermodelwizard.h index b7fd28aa9d..eaf188ed40 100644 --- a/indra/newview/llfloatermodelwizard.h +++ b/indra/newview/llfloatermodelwizard.h @@ -26,13 +26,35 @@ #ifndef LLFLOATERMODELWIZARD_H #define LLFLOATERMODELWIZARD_H + +#include "llmeshrepository.h" +#include "llmodel.h" +#include "llthread.h" + + class LLModelPreview; + class LLFloaterModelWizard : public LLFloater { public: + + class DecompRequest : public LLPhysicsDecomp::Request + { + public: + S32 mContinue; + LLPointer mModel; + + DecompRequest(const std::string& stage, LLModel* mdl); + virtual S32 statusCallback(const char* status, S32 p1, S32 p2); + virtual void completed(); + + }; + + static LLFloaterModelWizard* sInstance; + LLFloaterModelWizard(const LLSD& key); - virtual ~LLFloaterModelWizard() {}; + virtual ~LLFloaterModelWizard(); /*virtual*/ BOOL postBuild(); void draw(); @@ -41,6 +63,14 @@ public: BOOL handleHover(S32 x, S32 y, MASK mask); BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + + void initDecompControls(); + + LLPhysicsDecomp::decomp_params mDecompParams; + std::set > mCurRequest; + std::string mStatusMessage; + static void executePhysicsStage(std::string stage_name); + private: enum EWizardState { @@ -59,9 +89,9 @@ private: bool onEnableNext(); bool onEnableBack(); void loadModel(); - static void onPreviewLODCommit(LLUICtrl*,void*); + void onPreviewLODCommit(LLUICtrl*); void onAccuracyPerformance(const LLSD& data); - static void onUpload(void* data); + void onUpload(); LLModelPreview* mModelPreview; LLRect mPreviewRect; diff --git a/indra/newview/skins/default/xui/en/floater_model_wizard.xml b/indra/newview/skins/default/xui/en/floater_model_wizard.xml index 0f8844519a..e2ec557b06 100644 --- a/indra/newview/skins/default/xui/en/floater_model_wizard.xml +++ b/indra/newview/skins/default/xui/en/floater_model_wizard.xml @@ -1,624 +1,768 @@ - - - - - Model Preview: - - - - - - Dimensions (meters): - - - X: [X] |Y: [Y] |Z: [Z] - - - Note: - - -Advanced users familiar with 3d content creation tools may prefer to use the [secondlife:///app/floater/upload_model Advanced Mesh Import Window] . - - - - - - - - - Optimize - - - - This wizard is optimizing your model. This may take several minutes. To stop the process click the back button - - - Generating Level of Detail - - - Generate Level of Detail: High - - Generate Level of Detail: Medium - - Generate Level of Detail: Low - - Generate Level of Detail: Lowest - - - - Model Preview: - - - - High - - - Medium - - - Lowest - - - Low - - - - - Performance - Faster rendering but less detailed; lowers Resource (prim) cost. - Accuracy - More detailed model but slower; increases Resource (prim) cost. - - - ' ' ' - Resource Cost: - Upload Fee: - - Dimensions (meters): - - - X: [X] |Y: [Y] |Z: [Z] - - - - - - - - - - Physics - - - - The wizard will create a physical shape, which determines how the object interacts with other objects and avatars. Set the slider to the detail level most appropriate for how your object will be used: - - - - - - - - - Review - - - - Review the details below then click. Upload to upload your model. Your L$ balance will be charged when you click Upload. - - - - - - - - - - - Upload Complete! - - - - Congratulations! Your model has been sucessfully uploaded. You will find the model in the Objects folder in your inventory. - - - + + Model Preview: + + + + + + Dimensions (meters): + + + X: [X] |Y: [Y] |Z: [Z] + + + Note: + + +Advanced users familiar with 3d content creation tools may prefer to use the [secondlife:///app/floater/upload_model Advanced Mesh Import Window] . + + + + + + + + + Optimize + + + + This wizard is optimizing your model. This may take several minutes. To stop the process click the back button + + + Generating Level of Detail + + + Generate Level of Detail: High + + Generate Level of Detail: Medium + + Generate Level of Detail: Low + + Generate Level of Detail: Lowest + + + + Model Preview: + + + + High + + + Medium + + + Lowest + + + Low + + + + + Performance + Faster rendering but less detailed; lowers Resource (prim) cost. + Accuracy + More detailed model but slower; increases Resource (prim) cost. + + + ' ' ' + Resource Cost: + Upload Fee: + + Dimensions (meters): + + + X: [X] |Y: [Y] |Z: [Z] + + + + + + + + + + Physics + + + + The wizard will create a physical shape, which determines how the object interacts with other objects and avatars. Set the slider to the detail level most appropriate for how your object will be used: + + + Performance + Faster rendering but less detailed; lowers Resource (prim) cost. + Accuracy + More detailed model but slower; increases Resource (prim) cost. + + + ' ' ' ' ' ' ' ' ' ' ' + Recommended for solid objects + Recommended for buildings + Recommended for vehicles + Resource Cost: + Physics Cost: + Upload Fee: + + + + + + + + + Review + + + + Review the details below then click. Upload to upload your model. Your L$ balance will be charged when you click Upload. + + + + Model Preview: + + + + High + + + Medium + + + Lowest + + + Low + + + + + + Dimensions (meters): + + + X: [X] |Y: [Y] |Z: [Z] + + + Resource Cost: + This is the cost to your Region's prim/object limit, at default scale + Physics Cost: + This is the cost to your Region's prim/object limit, at default scale + Upload Fee: + This is the amount the upload will cost. + + I confirm that I have the appropriate rights to the material contained in this model. [secondlife:///app/floater/learn_more Learn more] + + + + + + + + + Upload Complete! + + + + Congratulations! Your model has been sucessfully uploaded. You will find the model in the Objects folder in your inventory. + + + + + + +