diff options
author | prep linden <prep@lindenlab.com> | 2011-02-28 12:20:31 -0500 |
---|---|---|
committer | prep linden <prep@lindenlab.com> | 2011-02-28 12:20:31 -0500 |
commit | 4abb8b33fa0c3b5e5f809a783cfc62a9e02af338 (patch) | |
tree | 90d472cdc1d9aa8af8bb9fc3989dab4b86c0f778 /indra | |
parent | 3ce756e44cca0cf6f9860871789e348647800e45 (diff) |
sh-517 Content authors can specify a pivot node (Assetpivot).
Diffstat (limited to 'indra')
-rwxr-xr-x | indra/llprimitive/llmodel.cpp | 16 | ||||
-rwxr-xr-x | indra/llprimitive/llmodel.h | 2 | ||||
-rwxr-xr-x | indra/newview/llfloatermodelpreview.cpp | 84 | ||||
-rw-r--r-- | indra/newview/llfloatermodelpreview.h | 13 |
4 files changed, 111 insertions, 4 deletions
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 3d03209eaf..a9101378a4 100755 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -810,6 +810,22 @@ BOOL LLModel::createVolumeFacesFromFile(const std::string& file_name) return FALSE; } +void LLModel::offsetMesh( const LLVector3& pivotPoint ) +{ + LLVector4a pivot( pivotPoint[VX], pivotPoint[VY], pivotPoint[VZ] ); + + for (std::vector<LLVolumeFace>::iterator faceIt = mVolumeFaces.begin(); faceIt != mVolumeFaces.end(); ) + { + std::vector<LLVolumeFace>:: iterator currentFaceIt = faceIt++; + LLVolumeFace& face = *currentFaceIt; + LLVector4a *pos = (LLVector4a*) face.mPositions; + + for (U32 i=0; i<face.mNumVertices; ++i ) + { + pos[i].add( pivot ); + } + } +} void LLModel::optimizeVolumeFaces() { diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index ebf37904d4..c10ca1c11b 100755 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -123,7 +123,7 @@ public: void normalizeVolumeFaces(); void optimizeVolumeFaces(); - + void offsetMesh( const LLVector3& pivotPoint ); void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out); std::vector<std::string> mMaterialList; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index ef7d1425c7..e33ce055f6 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -174,7 +174,6 @@ std::string lod_label_name[NUM_LOD+1] = "I went off the end of the lod_label_name array. Me so smart." }; - bool validate_face(const LLVolumeFace& face) { for (U32 i = 0; i < face.mNumIndices; ++i) @@ -1675,10 +1674,42 @@ void LLModelLoader::run() processElement(scene); + handlePivotPoint( root ); + doOnIdleOneTime(boost::bind(&LLModelPreview::loadModelCallback,mPreview,mLod)); } } +void LLModelLoader::handlePivotPoint( daeElement* pRoot ) +{ + //Import an optional pivot point - a pivot point is just a node in the visual scene named "AssetPivot" + //If no assetpivot is found then the asset will use the SL default + daeElement* pScene = pRoot->getDescendant("visual_scene"); + if ( pScene ) + { + daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren(); + S32 childCount = children.getCount(); + for (S32 i = 0; i < childCount; ++i) + { + domNode* pNode = daeSafeCast<domNode>(children[i]); + if ( pNode && isNodeAPivotPoint( pNode ) ) + { + LLMatrix4 workingTransform; + daeSIDResolver nodeResolver( pNode, "./translate" ); + domTranslate* pTranslate = daeSafeCast<domTranslate>( nodeResolver.getElement() ); + //Translation via SID was successful + //todo#extract via element as well + if ( pTranslate ) + { + extractTranslation( pTranslate, workingTransform ); + mPreview->setModelPivot( workingTransform.getTranslation() ); + mPreview->setHasPivot( true ); + } + } + } + } +} + bool LLModelLoader::doesJointArrayContainACompleteRig( const std::vector<std::string> &jointListFromModel ) { std::deque<std::string> :: const_iterator masterJointIt = mMasterJointList.begin(); @@ -1754,6 +1785,25 @@ bool LLModelLoader::isNodeAJoint( domNode* pNode ) return false; } +bool LLModelLoader::isNodeAPivotPoint( domNode* pNode ) +{ + bool result = false; + + if ( pNode && pNode->getName() ) + { + std::string name = pNode->getName(); + if ( name == "AssetPivot" ) + { + result = true; + } + else + { + result = false; + } + } + return result; +} + void LLModelLoader::extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ) { domFloat3 jointTrans = pTranslate->getValue(); @@ -2185,6 +2235,9 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) mFMP = fmp; + mHasPivot = false; + mModelPivot = LLVector3( 0.0f, 0.0f, 0.0f ); + glodInit(); } @@ -2292,6 +2345,28 @@ void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, childSetTextArg("physics cost", "[COST]", llformat("%.3f", physics_cost)); } +void LLModelPreview::alterModelsPivot( void ) +{ + for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter) + { + if ( *iter ) + { + (*iter)->offsetMesh( mModelPivot ); + } + } + + for ( int i=0;i<LLModel::NUM_LODS;++i ) + { + for (LLModelLoader::model_list::iterator iter = mModel[i].begin(); iter != mModel[i].end(); ++iter) + { + if ( *iter ) + { + (*iter)->offsetMesh( mModelPivot ); + } + } + } +} + void LLModelPreview::rebuildUploadData() { assert_main_thread(); @@ -2347,6 +2422,7 @@ void LLModelPreview::rebuildUploadData() LLModelInstance instance = *model_iter; LLModel* base_model = instance.mModel; + if (base_model) { base_model->mRequestedLabel = requested_name; @@ -3441,6 +3517,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) U32 vertex_count = 0; U32 mesh_count = 0; + LLModelLoader::model_list* model = NULL; if (lod < 0 || lod > 4) @@ -4129,6 +4206,11 @@ void LLFloaterModelPreview::onUpload(void* user_data) LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data; + if ( mp && mp->mModelPreview->mHasPivot ) + { + mp->mModelPreview->alterModelsPivot(); + } + mp->mModelPreview->rebuildUploadData(); gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale, diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index e1c520134b..8a01f7db2c 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -114,6 +114,9 @@ public: bool doesJointArrayContainACompleteRig( const std::vector<std::string> &modelJointList ); bool checkForCompleteRig( const std::vector<std::string> &jointListFromModel ); + void handlePivotPoint( daeElement* pRoot ); + bool isNodeAPivotPoint( domNode* pNode ); + void setLoadState( U32 state ) { mState = state; } U32 getLoadState( void ) { return mState; } @@ -279,7 +282,7 @@ public: void loadModelCallback(S32 lod); void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false); void generateNormals(); - + void alterModelsPivot( void ); void clearMaterials(); U32 calcResourceCost(); void rebuildUploadData(); @@ -287,7 +290,10 @@ public: void updateStatusMessages(); void clearGLODGroup(); void onLODParamCommit(bool enforce_tri_limit); - + const bool getModelPivot( void ) const { return mHasPivot; } + void setHasPivot( bool val ) { mHasPivot = val; } + void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; } + static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){ return mDetailsSignal.connect(cb); } @@ -347,6 +353,9 @@ public: details_signal_t mDetailsSignal; model_loaded_signal_t mModelLoadedSignal; + + LLVector3 mModelPivot; + bool mHasPivot; }; |