summaryrefslogtreecommitdiff
path: root/indra/newview/llfloatermodelpreview.cpp
diff options
context:
space:
mode:
authorNyx (Neal Orman) <nyx@lindenlab.com>2011-03-21 17:56:11 -0400
committerNyx (Neal Orman) <nyx@lindenlab.com>2011-03-21 17:56:11 -0400
commit955b727550e8595fd67c55775d8f0fe249826277 (patch)
treef4ac70eb36bcb14d44fad4199811d365eb4b788f /indra/newview/llfloatermodelpreview.cpp
parent77fff26431671ffef8cf482044b1fcd98262d3e0 (diff)
parent5b9ee2a9d5687eae6fd48ee6038cd2f7ed1d9a53 (diff)
merge
Diffstat (limited to 'indra/newview/llfloatermodelpreview.cpp')
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp1353
1 files changed, 686 insertions, 667 deletions
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index dde470693c..ce977b33bb 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)
@@ -311,6 +310,7 @@ BOOL LLFloaterModelPreview::postBuild()
childSetCommitCallback("upload_joints", onUploadJointsCommit, this);
childSetCommitCallback("import_scale", onImportScaleCommit, this);
+ childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this);
childSetCommitCallback("lod_file_or_limit", refresh, this);
childSetCommitCallback("physics_load_radio", refresh, this);
@@ -319,6 +319,9 @@ BOOL LLFloaterModelPreview::postBuild()
childDisable("upload_skin");
childDisable("upload_joints");
+
+ childDisable("pelvis_offset");
+
childDisable("ok_btn");
mViewOptionMenuButton = getChild<LLMenuButton>("options_gear_btn");
@@ -457,6 +460,18 @@ void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata)
fp->mModelPreview->calcResourceCost();
fp->mModelPreview->refresh();
}
+//static
+void LLFloaterModelPreview::onPelvisOffsetCommit( LLUICtrl*, void* userdata )
+{
+ LLFloaterModelPreview *fp =(LLFloaterModelPreview*)userdata;
+
+ if (!fp->mModelPreview)
+ {
+ return;
+ }
+ fp->mModelPreview->calcResourceCost();
+ fp->mModelPreview->refresh();
+}
//static
void LLFloaterModelPreview::onUploadJointsCommit(LLUICtrl*,void* userdata)
@@ -480,7 +495,8 @@ void LLFloaterModelPreview::onUploadSkinCommit(LLUICtrl*,void* userdata)
{
return;
}
-
+
+ fp->mModelPreview->calcResourceCost();
fp->mModelPreview->refresh();
fp->mModelPreview->resetPreviewTarget();
fp->mModelPreview->clearBuffers();
@@ -603,13 +619,13 @@ void LLFloaterModelPreview::draw()
gGL.begin( LLRender::QUADS );
{
gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop);
+ gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1);
gGL.texCoord2f(0.f, 0.f);
gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom);
gGL.texCoord2f(1.f, 0.f);
- gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom);
+ gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom);
gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mTop);
+ gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mTop-1);
}
gGL.end();
@@ -774,11 +790,13 @@ void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data)
if (stage == "Decompose")
{
+ sInstance->setStatusMessage(sInstance->getString("decomposing"));
sInstance->childSetVisible("Decompose", false);
sInstance->childSetVisible("decompose_cancel", true);
}
else if (stage == "Simplify")
{
+ sInstance->setStatusMessage(sInstance->getString("simplifying"));
sInstance->childSetVisible("Simplify", false);
sInstance->childSetVisible("simplify_cancel", true);
}
@@ -824,6 +842,8 @@ void LLFloaterModelPreview::onPhysicsStageCancel(LLUICtrl* ctrl, void*data)
DecompRequest* req = *iter;
req->mContinue = 0;
}
+
+ sInstance->mCurRequest.clear();
}
}
@@ -966,7 +986,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), mResetJoints( FALSE )
+: LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mFirstTransform(TRUE), mResetJoints( FALSE )
{
mJointMap["mPelvis"] = "mPelvis";
mJointMap["mTorso"] = "mTorso";
@@ -1050,7 +1070,6 @@ LLModelLoader::LLModelLoader(std::string filename, S32 lod, LLModelPreview* prev
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");
@@ -1065,6 +1084,11 @@ LLModelLoader::LLModelLoader(std::string filename, S32 lod, LLModelPreview* prev
mMasterJointList.push_front("mHipLeft");
mMasterJointList.push_front("mKneeLeft");
mMasterJointList.push_front("mFootLeft");
+
+ if (mPreview)
+ {
+ mPreview->setLoadState(STARTING);
+ }
}
void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4a& max, BOOL& first_transform)
@@ -1132,272 +1156,321 @@ void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3&
void LLModelLoader::run()
{
+ if (!doLoadModel())
+ {
+ mPreview = NULL;
+ }
+
+ doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this));
+}
+
+bool LLModelLoader::doLoadModel()
+{
DAE dae;
domCOLLADA* dom = dae.open(mFilename);
- if (dom)
+ 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();
- mTransform.mMatrix[0][0] = meter;
- 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();
- }
+ return false;
+ }
+
+ 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 false;
+ }
+
+ daeElement* root = doc->getDomRoot();
+ if (!root)
+ {
+ llwarns << "document has no root" << llendl;
+ return false;
+ }
+
+ //get unit scale
+ mTransform.setIdentity();
+
+ domAsset::domUnit* unit = daeSafeCast<domAsset::domUnit>(root->getDescendant(daeElement::matchType(domAsset::domUnit::ID())));
+
+ if (unit)
+ {
+ F32 meter = unit->getMeter();
+ mTransform.mMatrix[0][0] = meter;
+ 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);
+ }
+ else if (up == UPAXISTYPE_Y_UP)
+ {
+ 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 (up == UPAXISTYPE_X_UP)
+ if (mesh)
{
- rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f);
- }
- else if (up == UPAXISTYPE_Y_UP)
- {
- 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);
+ LLPointer<LLModel> model = LLModel::loadModelFromDomMesh(mesh);
- if (mesh)
+ if (model.notNull() && validate_model(model))
{
- LLPointer<LLModel> model = LLModel::loadModelFromDomMesh(mesh);
-
- if (model.notNull() && validate_model(model))
- {
- mModelList.push_back(model);
- mModel[mesh] = model;
- }
+ mModelList.push_back(model);
+ mModel[mesh] = model;
}
}
+ }
+
+ 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);
- 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 (skin)
+ if (geom)
{
- domGeometry* geom = daeSafeCast<domGeometry>(skin->getSource().getElement());
-
- if (geom)
+ domMesh* mesh = geom->getMesh();
+ if (mesh)
{
- domMesh* mesh = geom->getMesh();
- if (mesh)
+ LLModel* model = mModel[mesh];
+ if (model)
{
- LLModel* model = mModel[mesh];
- if (model)
- {
- 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();
+ 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();
- if (bind_mat)
- { //get bind shape matrix
- domFloat4x4& dom_value = bind_mat->getValue();
-
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++)
+ {
+ for(int j = 0; j < 4; j++)
{
- for(int j = 0; j < 4; j++)
- {
- model->mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4];
- }
+ model->mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4];
}
-
- LLMatrix4 trans = normalized_transformation;
- trans *= model->mBindShapeMatrix;
- model->mBindShapeMatrix = trans;
-
}
+ 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 )
+ }
+
+
+ //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
+ bool rootNode = false;
+ bool skeletonWithNoRootNode = false;
+
+ //Need to test for a skeleton that does not have a root node
+ //This occurs when your instance controller does not have an associated scene
+ if ( pSkeleton )
+ {
+ daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement();
+ if ( pSkeletonRootNode )
{
- daeElement* pScene = root->getDescendant("visual_scene");
- if ( !pScene )
- {
- llwarns<<"No visual scene - unable to parse bone offsets "<<llendl;
- missingSkeletonOrScene = true;
- }
- else
+ rootNode = true;
+ }
+ else
+ {
+ skeletonWithNoRootNode = true;
+ }
+
+ }
+ if ( !pSkeleton || !rootNode )
+ {
+ daeElement* pScene = root->getDescendant("visual_scene");
+ if ( !pScene )
+ {
+ llwarns<<"No visual scene - unable to parse bone offsets "<<llendl;
+ missingSkeletonOrScene = true;
+ }
+ else
+ {
+ //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)
{
- //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)
+ domNode* pNode = daeSafeCast<domNode>(children[i]);
+ if ( isNodeAJoint( pNode ) )
{
- domNode* pNode = daeSafeCast<domNode>(children[i]);
- if ( isNodeAJoint( pNode ) )
- {
- processJointNode( pNode, jointTransforms );
- }
+ processJointNode( pNode, jointTransforms );
}
}
}
- else
- //Has Skeleton
+ }
+ else
+ //Has Skeleton
+ {
+ //Get the root node of the skeleton
+ daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement();
+ if ( pSkeletonRootNode )
{
- //Get the root node of the skeleton
- daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement();
- if ( pSkeletonRootNode )
+ //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 )
{
- //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();
+ //Build a joint for the resolver to work with
+ char str[64]={0};
+ sprintf(str,"./%s",(*jointIt).second.c_str() );
+ //llwarns<<"Joint "<< str <<llendl;
- //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 )
- {
- //Build a joint for the resolver to work with
- 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 )
+ {
+ //Pull out the translate id and store it in the jointTranslations map
+ daeSIDResolver jointResolver( pJoint, "./translate" );
+ domTranslate* pTranslate = daeSafeCast<domTranslate>( jointResolver.getElement() );
- //Setup the resolver
- daeSIDResolver resolver( pSkeletonRootNode, str );
+ LLMatrix4 workingTransform;
- //Look for the joint
- domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() );
- if ( pJoint )
- {
- //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 )
+ //Translation via SID
+ if ( pTranslate )
+ {
+ extractTranslation( pTranslate, workingTransform );
+ }
+ else
+ {
+ //Translation via child from element
+ daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" );
+ if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() )
{
- extractTranslation( pTranslate, workingTransform );
+ llwarns<< "The found element is not a translate node" <<llendl;
+ missingSkeletonOrScene = true;
}
else
{
- //Translation via child from element
- daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" );
- if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() )
- {
- llwarns<< "The found element is not a translate node" <<llendl;
- missingSkeletonOrScene = true;
- }
- else
- {
- extractTranslationViaElement( pTranslateElement, workingTransform );
- }
+ 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 )
- {
- llwarns<< "Partial jointmap found in asset - did you mean to just have a partial map?" << llendl;
- }
- }//got skeleton?
- }
-
-
- domSkin::domJoints* joints = skin->getJoints();
-
- domInputLocal_Array& joint_input = joints->getInput_array();
+ }
+
+ //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 )
+ {
+ llwarns<< "Partial jointmap found in asset - did you mean to just have a partial map?" << llendl;
+ }
+ }//got skeleton?
+ }
+
+
+ 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();
- 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();
- 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)
+ {
- domSource* source = daeSafeCast<domSource>(elem);
- if (source)
+
+ domName_array* names_source = source->getName_array();
+
+ if (names_source)
{
+ domListOfNames &names = names_source->getValue();
-
- domName_array* names_source = source->getName_array();
-
+ for (size_t j = 0; j < names.getCount(); ++j)
+ {
+ std::string name(names.get(j));
+ if (mJointMap.find(name) != mJointMap.end())
+ {
+ name = mJointMap[name];
+ }
+ model->mJointList.push_back(name);
+ model->mJointMap[name] = j;
+ }
+ }
+ else
+ {
+ domIDREF_array* names_source = source->getIDREF_array();
if (names_source)
{
- domListOfNames &names = names_source->getValue();
+ xsIDREFS& names = names_source->getValue();
for (size_t j = 0; j < names.getCount(); ++j)
{
- std::string name(names.get(j));
+ std::string name(names.get(j).getID());
if (mJointMap.find(name) != mJointMap.end())
{
name = mJointMap[name];
@@ -1406,277 +1479,314 @@ void LLModelLoader::run()
model->mJointMap[name] = j;
}
}
- else
- {
- domIDREF_array* names_source = source->getIDREF_array();
- if (names_source)
- {
- xsIDREFS& names = names_source->getValue();
-
- for (size_t j = 0; j < names.getCount(); ++j)
- {
- std::string name(names.get(j).getID());
- if (mJointMap.find(name) != mJointMap.end())
- {
- name = mJointMap[name];
- }
- model->mJointList.push_back(name);
- model->mJointMap[name] = j;
- }
- }
- }
}
}
- else if (strcmp(semantic, COMMON_PROFILE_INPUT_INV_BIND_MATRIX) == 0)
- { //found inv_bind_matrix array, fill model->mInvBindMatrix
- domSource* source = daeSafeCast<domSource>(input->getSource().getElement());
- if (source)
+ }
+ else if (strcmp(semantic, COMMON_PROFILE_INPUT_INV_BIND_MATRIX) == 0)
+ { //found inv_bind_matrix array, fill model->mInvBindMatrix
+ domSource* source = daeSafeCast<domSource>(input->getSource().getElement());
+ if (source)
+ {
+ domFloat_array* t = source->getFloat_array();
+ if (t)
{
- domFloat_array* t = source->getFloat_array();
- if (t)
+ domListOfFloats& transform = t->getValue();
+ S32 count = transform.getCount()/16;
+
+ for (S32 k = 0; k < count; ++k)
{
- domListOfFloats& transform = t->getValue();
- S32 count = transform.getCount()/16;
+ LLMatrix4 mat;
- for (S32 k = 0; k < count; ++k)
+ for (int i = 0; i < 4; i++)
{
- LLMatrix4 mat;
-
- for (int i = 0; i < 4; i++)
+ for(int j = 0; j < 4; j++)
{
- for(int j = 0; j < 4; j++)
- {
- mat.mMatrix[i][j] = transform[k*16 + i + j*4];
- }
+ mat.mMatrix[i][j] = transform[k*16 + i + j*4];
}
-
- model->mInvBindMatrix.push_back(mat);
}
+
+ 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 )
+ }
+
+ //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).
+ mPreview->setRigValid( doesJointArrayContainACompleteRig( model->mJointList ) );
+ if ( !skeletonWithNoRootNode && !model->mJointList.empty() && mPreview->isRigValid() )
+ {
+ 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() )
{
- 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
{
- //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;
- }
+ //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.
- //This remaps the skeletal joints to be in the same order as the joints stored in the model.
- std::vector<std::string> :: const_iterator jointIt = model->mJointList.begin();
- const int jointCnt = model->mJointList.size();
- for ( int i=0; i<jointCnt; ++i, ++jointIt )
+ }
+ } //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.
+ //This remaps the skeletal joints to be in the same order as the joints stored in the model.
+ std::vector<std::string> :: const_iterator jointIt = model->mJointList.begin();
+ const int jointCnt = model->mJointList.size();
+ for ( int i=0; i<jointCnt; ++i, ++jointIt )
+ {
+ std::string lookingForJoint = (*jointIt).c_str();
+ //Look for the joint xform that we extracted from the skeleton, using the jointIt as the key
+ //and store it in the alternate bind matrix
+ if ( jointTransforms.find( lookingForJoint ) != jointTransforms.end() )
{
- std::string lookingForJoint = (*jointIt).c_str();
- //Look for the joint xform that we extracted from the skeleton, using the jointIt as the key
- //and store it in the alternate bind matrix
- if ( jointTransforms.find( lookingForJoint ) != jointTransforms.end() )
- {
- LLMatrix4 jointTransform = jointTransforms[lookingForJoint];
- LLMatrix4 newInverse = model->mInvBindMatrix[i];
- newInverse.setTranslation( jointTransforms[lookingForJoint].getTranslation() );
- model->mAlternateBindMatrix.push_back( newInverse );
- }
- else
- {
- llwarns<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<" ] "<<llendl;
- }
+ LLMatrix4 jointTransform = jointTransforms[lookingForJoint];
+ LLMatrix4 newInverse = model->mInvBindMatrix[i];
+ newInverse.setTranslation( jointTransforms[lookingForJoint].getTranslation() );
+ model->mAlternateBindMatrix.push_back( newInverse );
}
-
- //grab raw position array
-
- domVertices* verts = mesh->getVertices();
- if (verts)
+ else
{
- domInputLocal_Array& inputs = verts->getInput_array();
- for (size_t i = 0; i < inputs.getCount() && model->mPosition.empty(); ++i)
+ llwarns<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<" ] "<<llendl;
+ }
+ }
+
+ //grab raw position array
+
+ domVertices* verts = mesh->getVertices();
+ if (verts)
+ {
+ domInputLocal_Array& inputs = verts->getInput_array();
+ for (size_t i = 0; i < inputs.getCount() && model->mPosition.empty(); ++i)
+ {
+ if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_POSITION) == 0)
{
- if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_POSITION) == 0)
+ domSource* pos_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement());
+ if (pos_source)
{
- domSource* pos_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement());
- if (pos_source)
+ domFloat_array* pos_array = pos_source->getFloat_array();
+ if (pos_array)
{
- domFloat_array* pos_array = pos_source->getFloat_array();
- if (pos_array)
+ domListOfFloats& pos = pos_array->getValue();
+
+ for (size_t j = 0; j < pos.getCount(); j += 3)
{
- domListOfFloats& pos = pos_array->getValue();
-
- for (size_t j = 0; j < pos.getCount(); j += 3)
+ if (pos.getCount() <= j+2)
{
- 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);
+ 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);
}
}
}
}
}
-
- //grab skin weights array
- domSkin::domVertex_weights* weights = skin->getVertex_weights();
- if (weights)
+ }
+
+ //grab skin weights array
+ domSkin::domVertex_weights* weights = skin->getVertex_weights();
+ if (weights)
+ {
+ domInputLocalOffset_Array& inputs = weights->getInput_array();
+ domFloat_array* vertex_weights = NULL;
+ for (size_t i = 0; i < inputs.getCount(); ++i)
{
- domInputLocalOffset_Array& inputs = weights->getInput_array();
- domFloat_array* vertex_weights = NULL;
- for (size_t i = 0; i < inputs.getCount(); ++i)
+ if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_WEIGHT) == 0)
{
- if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_WEIGHT) == 0)
+ domSource* weight_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement());
+ if (weight_source)
{
- domSource* weight_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement());
- if (weight_source)
- {
- vertex_weights = weight_source->getFloat_array();
- }
+ vertex_weights = weight_source->getFloat_array();
}
}
+ }
+
+ if (vertex_weights)
+ {
+ domListOfFloats& w = vertex_weights->getValue();
+ domListOfUInts& vcount = weights->getVcount()->getValue();
+ domListOfInts& v = weights->getV()->getValue();
- 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];
- 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;
+ //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++];
- 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)
- {
- wght.push_back( weight_list[i] );
- total += weight_list[i].mWeight;
- }
+ if (joint_idx == -1)
+ {
+ //ignore bindings to bind_shape_matrix
+ continue;
}
- F32 scale = 1.f/total;
- if (scale != 1.f)
- { //normalize weights
- for (U32 i = 0; i < wght.size(); ++i)
- {
- wght[i].mWeight *= scale;
- }
- }
+ F32 weight_value = w[weight_idx];
- model->mSkinWeights[model->mPosition[vc_idx]] = wght;
+ weight_list.push_back(LLModel::JointWeight(joint_idx, weight_value));
}
- //add instance to scene for this model
+ //sort by joint weight
+ std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater());
- LLMatrix4 transformation = mTransform;
- // adjust the transformation to compensate for mesh normalization
+ std::vector<LLModel::JointWeight> wght;
- LLMatrix4 mesh_translation;
- mesh_translation.setTranslation(mesh_translation_vector);
- mesh_translation *= transformation;
- transformation = mesh_translation;
+ F32 total = 0.f;
- LLMatrix4 mesh_scale;
- mesh_scale.initScale(mesh_scale_vector);
- mesh_scale *= transformation;
- transformation = mesh_scale;
+ 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)
+ {
+ wght.push_back( weight_list[i] );
+ total += weight_list[i].mWeight;
+ }
+ }
- std::vector<LLImportMaterial> materials;
- materials.resize(model->getNumVolumeFaces());
- mScene[transformation].push_back(LLModelInstance(model, transformation, materials));
- stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform);
+ F32 scale = 1.f/total;
+ if (scale != 1.f)
+ { //normalize weights
+ for (U32 i = 0; i < wght.size(); ++i)
+ {
+ 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
+
+ LLMatrix4 mesh_translation;
+ 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, model->mLabel, transformation, materials));
+ stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform);
}
}
}
}
}
}
-
- daeElement* scene = root->getDescendant("visual_scene");
-
- if (!scene)
- {
- llwarns << "document has no visual_scene" << llendl;
- setLoadState( ERROR_PARSING );
- return;
- }
- setLoadState( DONE );
+ }
+
+ daeElement* scene = root->getDescendant("visual_scene");
+
+ if (!scene)
+ {
+ llwarns << "document has no visual_scene" << llendl;
+ setLoadState( ERROR_PARSING );
+ return false;
+ }
+ setLoadState( DONE );
- processElement(scene);
-
- doOnIdleOneTime(boost::bind(&LLModelPreview::loadModelCallback,mPreview,mLod));
+ processElement(scene);
+
+ handlePivotPoint( root );
+
+ return true;
+}
+
+void LLModelLoader::setLoadState(U32 state)
+{
+ if (mPreview)
+ {
+ mPreview->setLoadState(state);
+ }
+}
+
+void LLModelLoader::loadModelCallback()
+{
+ if (mPreview)
+ {
+ mPreview->loadModelCallback(mLod);
+ mPreview->mModelLoader = NULL;
+ }
+
+ while (!isStopped())
+ { //wait until this thread is stopped before deleting self
+ apr_sleep(100);
}
+
+ delete this;
+}
+
+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 )
@@ -1754,6 +1864,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();
@@ -1944,7 +2073,8 @@ void LLModelLoader::processElement(daeElement* element)
mesh_scale *= transformation;
transformation = mesh_scale;
- mScene[transformation].push_back(LLModelInstance(model, transformation, materials));
+ std::string label = getElementLabel(instance_geo);
+ mScene[transformation].push_back(LLModelInstance(model, label, transformation, materials));
stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform);
}
@@ -2161,6 +2291,8 @@ LLColor4 LLModelLoader::getDaeColor(daeElement* element)
LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex(NULL)
+, mPelvisZOffset( 0.0f )
+, mRigValid( false )
{
mNeedsUpdate = TRUE;
mCameraDistance = 0.f;
@@ -2174,16 +2306,25 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
mDirty = false;
mGenLOD = false;
mLoading = false;
+ mLoadState = LLModelLoader::STARTING;
mGroup = 0;
mBuildShareTolerance = 0.f;
mBuildQueueMode = GLOD_QUEUE_GREEDY;
mBuildBorderMode = GLOD_BORDER_UNLOCK;
mBuildOperator = GLOD_OPERATOR_EDGE_COLLAPSE;
+ for (U32 i = 0; i < LLModel::NUM_LODS; ++i)
+ {
+ mRequestedTriangleCount[i] = 0;
+ }
+
mViewOption["show_textures"] = false;
mFMP = fmp;
+ mHasPivot = false;
+ mModelPivot = LLVector3( 0.0f, 0.0f, 0.0f );
+
glodInit();
}
@@ -2191,10 +2332,8 @@ LLModelPreview::~LLModelPreview()
{
if (mModelLoader)
{
- delete mModelLoader;
- mModelLoader = NULL;
+ mModelLoader->mPreview = NULL;
}
-
//*HACK : *TODO : turn this back on when we understand why this crashes
//glodShutdown();
}
@@ -2207,25 +2346,36 @@ U32 LLModelPreview::calcResourceCost()
if (mFMP && mModelLoader)
{
- if ( mModelLoader->getLoadState() != LLModelLoader::ERROR_PARSING )
+ if ( getLoadState() != LLModelLoader::ERROR_PARSING )
{
mFMP->childEnable("ok_btn");
}
}
+ //Upload skin is selected BUT the joints coming in from the asset
+ //were malformed.
+ if ( mFMP && mFMP->childGetValue("upload_skin").asBoolean() )
+ {
+ if ( !isRigValid() )
+ {
+ mFMP->childDisable("ok_btn");
+ }
+ }
+
U32 cost = 0;
std::set<LLModel*> accounted;
U32 num_points = 0;
U32 num_hulls = 0;
F32 debug_scale = mFMP ? mFMP->childGetValue("import_scale").asReal() : 1.f;
-
+ mPelvisZOffset = mFMP ? mFMP->childGetValue("pelvis_offset").asReal() : 32.0f;
+
F32 streaming_cost = 0.f;
F32 physics_cost = 0.f;
for (U32 i = 0; i < mUploadData.size(); ++i)
{
LLModelInstance& instance = mUploadData[i];
-
+
if (accounted.find(instance.mModel) == accounted.end())
{
accounted.insert(instance.mModel);
@@ -2291,6 +2441,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();
@@ -2346,6 +2518,7 @@ void LLModelPreview::rebuildUploadData()
LLModelInstance instance = *model_iter;
LLModel* base_model = instance.mModel;
+
if (base_model)
{
base_model->mRequestedLabel = requested_name;
@@ -2425,10 +2598,10 @@ void LLModelPreview::loadModel(std::string filename, S32 lod)
if (mModelLoader)
{
- delete mModelLoader;
- mModelLoader = NULL;
+ llwarns << "Incompleted model load operation pending." << llendl;
+ return;
}
-
+
mLODFile[lod] = filename;
if (lod == LLModel::LOD_HIGH)
@@ -2444,11 +2617,11 @@ void LLModelPreview::loadModel(std::string filename, S32 lod)
setPreviewLOD(lod);
- if ( mModelLoader->getLoadState() == LLModelLoader::ERROR_PARSING )
+ if ( getLoadState() == LLModelLoader::ERROR_PARSING )
{
mFMP->childDisable("ok_btn");
}
-
+
if (lod == mPreviewLOD)
{
mFMP->childSetText("lod_file", mLODFile[mPreviewLOD]);
@@ -2615,188 +2788,6 @@ void LLModelPreview::generateNormals()
}
-void LLModelPreview::consolidate()
-{
- std::map<LLImportMaterial, std::vector<LLModelInstance> > composite;
-
- LLMatrix4 identity;
-
- //bake out each node in current scene to composite
- for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
- { //for each transform in current scene
- LLMatrix4 mat = iter->first;
- glh::matrix4f inv_trans = glh::matrix4f((F32*) mat.mMatrix).inverse().transpose();
- LLMatrix4 norm_mat(inv_trans.m);
-
- 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;
-
- if (!validate_model(source))
- {
- llerrs << "Invalid model found!" << llendl;
- }
-
- for (S32 i = 0; i < source->getNumVolumeFaces(); ++i)
- { //for each face in instance
- const LLVolumeFace& src_face = source->getVolumeFace(i);
- LLImportMaterial& source_material = source_instance.mMaterial[i];
-
- //get model in composite that is composite for this material
- LLModel* model = NULL;
-
- if (composite.find(source_material) != composite.end())
- {
- model = composite[source_material].rbegin()->mModel;
- if (model->getVolumeFace(0).mNumVertices + src_face.mNumVertices > 65535)
- {
- model = NULL;
- }
- }
-
- if (model == NULL)
- { //no model found, make new model
- std::vector<LLImportMaterial> materials;
- materials.push_back(source_material);
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
- model = new LLModel(volume_params, 0.f);
- model->mLabel = source->mLabel;
- model->setNumVolumeFaces(0);
- composite[source_material].push_back(LLModelInstance(model, identity, materials));
- }
-
- model->appendFace(src_face, source->mMaterialList[i], mat, norm_mat);
- }
- }
- }
-
-
- //condense composite into as few LLModel instances as possible
- LLModelLoader::model_list new_model;
- std::vector<LLModelInstance> instance_list;
-
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
-
- std::vector<LLImportMaterial> empty_material;
- LLModelInstance cur_instance(new LLModel(volume_params, 0.f), identity, empty_material);
- cur_instance.mModel->setNumVolumeFaces(0);
-
- BOOL first_transform = TRUE;
-
- LLModelLoader::scene new_scene;
- LLVector3 min,max;
-
- for (std::map<LLImportMaterial, std::vector<LLModelInstance> >::iterator iter = composite.begin();
- iter != composite.end();
- ++iter)
- {
- std::map<LLImportMaterial, std::vector<LLModelInstance> >::iterator next_iter = iter; ++next_iter;
-
- for (std::vector<LLModelInstance>::iterator instance_iter = iter->second.begin();
- instance_iter != iter->second.end();
- ++instance_iter)
- {
- LLModel* source = instance_iter->mModel;
-
- if (instance_iter->mMaterial.size() != 1)
- {
- llerrs << "WTF?" << llendl;
- }
-
- if (source->getNumVolumeFaces() != 1)
- {
- llerrs << "WTF?" << llendl;
- }
-
- if (source->mMaterialList.size() != 1)
- {
- llerrs << "WTF?" << llendl;
- }
-
- cur_instance.mModel->addFace(source->getVolumeFace(0));
- cur_instance.mMaterial.push_back(instance_iter->mMaterial[0]);
- cur_instance.mModel->mMaterialList.push_back(source->mMaterialList[0]);
-
- BOOL last_model = FALSE;
-
- std::vector<LLModelInstance>::iterator next_instance = instance_iter; ++next_instance;
-
- if (next_iter == composite.end() &&
- next_instance == iter->second.end())
- {
- last_model = TRUE;
- }
-
- if (last_model || cur_instance.mModel->getNumVolumeFaces() >= MAX_MODEL_FACES)
- {
- cur_instance.mModel->mLabel = source->mLabel;
-
- cur_instance.mModel->optimizeVolumeFaces();
- cur_instance.mModel->normalizeVolumeFaces();
-
- if (!validate_model(cur_instance.mModel))
- {
- llerrs << "Invalid model detected." << llendl;
- }
-
- new_model.push_back(cur_instance.mModel);
-
- LLMatrix4 transformation = LLMatrix4();
-
- // adjust the transformation to compensate for mesh normalization
- LLVector3 mesh_scale_vector;
- LLVector3 mesh_translation_vector;
- cur_instance.mModel->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector);
-
- LLMatrix4 mesh_translation;
- 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;
-
- cur_instance.mTransform = transformation;
-
- new_scene[transformation].push_back(cur_instance);
- stretch_extents(cur_instance.mModel, transformation, min, max, first_transform);
-
- if (!last_model)
- {
- cur_instance = LLModelInstance(new LLModel(volume_params, 0.f), identity, empty_material);
- cur_instance.mModel->setNumVolumeFaces(0);
- }
- }
- }
- }
-
- mScene[mPreviewLOD] = new_scene;
- mModel[mPreviewLOD] = new_model;
- mVertexBuffer[mPreviewLOD].clear();
-
- if (mPreviewLOD == LLModel::LOD_HIGH)
- {
- mBaseScene = new_scene;
- mBaseModel = new_model;
- clearGLODGroup();
- mVertexBuffer[5].clear();
- }
-
- mPreviewTarget = (min+max)*0.5f;
- mPreviewScale = (max-min)*0.5f;
- setPreviewTarget(mPreviewScale.magVec()*2.f);
-
- clearIncompatible(mPreviewLOD);
-
- mResourceCost = calcResourceCost();
- refresh();
-}
-
void LLModelPreview::clearMaterials()
{
for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
@@ -2883,9 +2874,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
lod_mode = GLOD_TRIANGLE_BUDGET;
if (which_lod != -1)
{
- //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;
+ limit = mFMP->childGetValue("lod_triangle_limit").asInteger();
}
}
else
@@ -3044,13 +3033,6 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
{
start = end = which_lod;
}
- else
- {
- //SH-632 -- incremenet triangle count to avoid removing any triangles from
- //highest LoD when auto-generating LoD
- triangle_count++;
- }
-
mMaxTriangleLimit = base_triangle_count;
@@ -3086,21 +3068,33 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
U32 actual_verts = 0;
U32 submeshes = 0;
+ mRequestedTriangleCount[lod] = triangle_count;
+
glodGroupParameteri(mGroup, GLOD_ADAPT_MODE, lod_mode);
stop_gloderror();
glodGroupParameteri(mGroup, GLOD_ERROR_MODE, GLOD_OBJECT_SPACE_ERROR);
stop_gloderror();
- glodGroupParameteri(mGroup, GLOD_MAX_TRIANGLES, triangle_count);
+ glodGroupParameterf(mGroup, GLOD_OBJECT_SPACE_ERROR_THRESHOLD, lod_error_threshold);
stop_gloderror();
- glodGroupParameterf(mGroup, GLOD_OBJECT_SPACE_ERROR_THRESHOLD, lod_error_threshold);
+ glodGroupParameteri(mGroup, GLOD_MAX_TRIANGLES, 0);
stop_gloderror();
glodAdaptGroup(mGroup);
stop_gloderror();
+ if (lod_mode == GLOD_TRIANGLE_BUDGET)
+ { //SH-632 Always adapt to 0 before adapting to actual desired amount, and always
+ //add 1 to desired amount to avoid decimating below desired amount
+ glodGroupParameteri(mGroup, GLOD_MAX_TRIANGLES, triangle_count+1);
+ stop_gloderror();
+
+ glodAdaptGroup(mGroup);
+ stop_gloderror();
+ }
+
for (U32 mdl_idx = 0; mdl_idx < mBaseModel.size(); ++mdl_idx)
{
LLModel* base = mBaseModel[mdl_idx];
@@ -3368,17 +3362,20 @@ void LLModelPreview::updateStatusMessages()
}
}
- bool errorStateFromLoader = mModelLoader->getLoadState() == LLModelLoader::ERROR_PARSING ? true : false;
+ bool errorStateFromLoader = getLoadState() == LLModelLoader::ERROR_PARSING ? true : false;
- if ( upload_ok && !errorStateFromLoader )
+ bool skinAndRigOk = true;
+ bool uploadingSkin = mFMP->childGetValue("upload_skin").asBoolean();
+ if ( uploadingSkin && !isRigValid() )
{
- mFMP->childEnable("ok_btn");
+ skinAndRigOk = false;
}
- else
+
+ if ( upload_ok && !errorStateFromLoader && skinAndRigOk )
{
- mFMP->childDisable("ok_btn");
+ mFMP->childEnable("ok_btn");
}
-
+
//add up physics triangles etc
S32 start = 0;
S32 end = mModel[LLModel::LOD_PHYSICS].size();
@@ -3567,7 +3564,7 @@ void LLModelPreview::updateStatusMessages()
LLSpinCtrl* limit = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit");
limit->setMaxValue(mMaxTriangleLimit);
- limit->setValue(total_tris[mPreviewLOD]);
+ limit->setValue(mRequestedTriangleCount[mPreviewLOD]);
if (lod_mode == 0)
{
@@ -3575,6 +3572,7 @@ void LLModelPreview::updateStatusMessages()
threshold->setVisible(false);
limit->setMaxValue(mMaxTriangleLimit);
+ limit->setIncrement(mMaxTriangleLimit/32);
}
else
{
@@ -3622,6 +3620,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)
@@ -3798,7 +3797,7 @@ BOOL LLModelPreview::render()
gGL.pushMatrix();
glLoadIdentity();
- gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
+ gGL.color4f(0.169f, 0.169f, 0.169f, 1.f);
gl_rect_2d_simple( width, height );
@@ -3821,6 +3820,7 @@ BOOL LLModelPreview::render()
{
LLModelInstance& instance = *model_iter;
LLModel* model = instance.mModel;
+ model->mPelvisOffset = mPelvisZOffset;
if (!model->mSkinWeights.empty())
{
has_skin_weights = true;
@@ -3833,7 +3833,7 @@ BOOL LLModelPreview::render()
if (fmp)
{
fmp->enableViewOption("show_skin_weight");
- fmp->setViewOptionEnabled("show_joint_positions", skin_weight);
+ fmp->setViewOptionEnabled("show_joint_positions", skin_weight);
}
mFMP->childEnable("upload_skin");
}
@@ -4266,6 +4266,10 @@ void LLModelPreview::setPreviewLOD(S32 lod)
mFMP->childSetTextArg("lod_table_footer", "[DETAIL]", mFMP->getString(lod_name[mPreviewLOD]));
mFMP->childSetText("lod_file", mLODFile[mPreviewLOD]);
+ // the wizard has two lod drop downs
+ LLComboBox* combo_box2 = mFMP->getChild<LLComboBox>("preview_lod_combo2");
+ combo_box2->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
+
LLColor4 highlight_color = LLUIColorTable::instance().getColor("MeshImportTableHighlightColor");
LLColor4 normal_color = LLUIColorTable::instance().getColor("MeshImportTableNormalColor");
@@ -4306,6 +4310,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,
@@ -4396,10 +4405,13 @@ void LLFloaterModelPreview::setStatusMessage(const std::string& msg)
S32 LLFloaterModelPreview::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2)
{
- setStatusMessage(llformat("%s: %d/%d", status, p1, p2));
- if (LLFloaterModelPreview::sInstance)
+ if (mContinue)
{
- LLFloaterModelPreview::sInstance->setStatusMessage(mStatusMessage);
+ setStatusMessage(llformat("%s: %d/%d", status, p1, p2));
+ if (LLFloaterModelPreview::sInstance)
+ {
+ LLFloaterModelPreview::sInstance->setStatusMessage(mStatusMessage);
+ }
}
return mContinue;
@@ -4407,20 +4419,27 @@ S32 LLFloaterModelPreview::DecompRequest::statusCallback(const char* status, S32
void LLFloaterModelPreview::DecompRequest::completed()
{ //called from the main thread
- mModel->setConvexHullDecomposition(mHull);
-
- if (sInstance)
+ if (mContinue)
{
- if (mContinue)
+ mModel->setConvexHullDecomposition(mHull);
+
+ 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);
+ sInstance->mCurRequest.erase(this);
+ }
+ }
+ else if (sInstance)
+ {
+ llassert(sInstance->mCurRequest.find(this) == sInstance->mCurRequest.end());
}
}