summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rwxr-xr-xindra/llprimitive/llmodel.cpp16
-rwxr-xr-xindra/llprimitive/llmodel.h2
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp84
-rw-r--r--indra/newview/llfloatermodelpreview.h13
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;
};