summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorTofu Buzzard <no-email>2011-03-18 12:17:07 +0000
committerTofu Buzzard <no-email>2011-03-18 12:17:07 +0000
commitaab1a01e319f9ee2ed75635e1c15d68bec0890a9 (patch)
tree837a217769320a31ab9391acf3e2322f6049b77a /indra
parent0671b6abc5acee0e7df879f9a10506aa42c2169c (diff)
parentc6b55f1f97774ebdf28fb16e2066bd98d3f6e08f (diff)
merge
Diffstat (limited to 'indra')
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp947
-rw-r--r--indra/newview/llfloatermodelpreview.h14
-rw-r--r--indra/newview/llfloatermodelwizard.cpp2
3 files changed, 513 insertions, 450 deletions
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 6bf9fdfb9b..ce977b33bb 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -986,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";
@@ -1070,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");
@@ -1085,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)
@@ -1152,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);
+ 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();
- domSkin::domBind_shape_matrix* bind_mat = skin->getBind_shape_matrix();
-
- 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];
@@ -1426,281 +1479,286 @@ 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).
- mPreview->setRigValid( doesJointArrayContainACompleteRig( model->mJointList ) );
- if ( !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 )
+ }
+
+ //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
+ {
+ 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)
{
- 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;
+ }
+ }
+
+ F32 scale = 1.f/total;
+ if (scale != 1.f)
+ { //normalize weights
+ for (U32 i = 0; i < wght.size(); ++i)
+ {
+ wght[i].mWeight *= 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);
+ 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);
-
- handlePivotPoint( root );
-
- 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"
@@ -2248,6 +2306,7 @@ 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;
@@ -2273,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();
}
@@ -2289,7 +2346,7 @@ U32 LLModelPreview::calcResourceCost()
if (mFMP && mModelLoader)
{
- if ( mModelLoader->getLoadState() != LLModelLoader::ERROR_PARSING )
+ if ( getLoadState() != LLModelLoader::ERROR_PARSING )
{
mFMP->childEnable("ok_btn");
}
@@ -2541,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)
@@ -2560,7 +2617,7 @@ 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");
}
@@ -3305,7 +3362,7 @@ void LLModelPreview::updateStatusMessages()
}
}
- bool errorStateFromLoader = mModelLoader->getLoadState() == LLModelLoader::ERROR_PARSING ? true : false;
+ bool errorStateFromLoader = getLoadState() == LLModelLoader::ERROR_PARSING ? true : false;
bool skinAndRigOk = true;
bool uploadingSkin = mFMP->childGetValue("upload_skin").asBoolean();
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index b3053fe73a..910a45f9fe 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -96,7 +96,9 @@ public:
LLModelLoader(std::string filename, S32 lod, LLModelPreview* preview);
virtual void run();
-
+ bool doLoadModel();
+ void loadModelCallback();
+
void loadTextures() ; //called in the main thread.
void processElement(daeElement* element);
std::vector<LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo);
@@ -117,9 +119,8 @@ public:
void handlePivotPoint( daeElement* pRoot );
bool isNodeAPivotPoint( domNode* pNode );
- void setLoadState( U32 state ) { mState = state; }
- U32 getLoadState( void ) { return mState; }
-
+ void setLoadState(U32 state);
+
//map of avatar joints as named in COLLADA assets to internal joint names
std::map<std::string, std::string> mJointMap;
std::deque<std::string> mMasterJointList;
@@ -302,7 +303,11 @@ public:
boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){ return mDetailsSignal.connect(cb); }
boost::signals2::connection setModelLoadedCallback( const model_loaded_signal_t::slot_type& cb ){ return mModelLoadedSignal.connect(cb); }
+ void setLoadState( U32 state ) { mLoadState = state; }
+ U32 getLoadState() { return mLoadState; }
+
protected:
+ friend class LLModelLoader;
friend class LLFloaterModelPreview;
friend class LLFloaterModelWizard;
friend class LLFloaterModelPreview::DecompRequest;
@@ -326,6 +331,7 @@ public:
U32 mResourceCost;
std::string mLODFile[LLModel::NUM_LODS];
bool mLoading;
+ U32 mLoadState;
std::map<std::string, bool> mViewOption;
diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp
index be43216b0e..eafea1fe03 100644
--- a/indra/newview/llfloatermodelwizard.cpp
+++ b/indra/newview/llfloatermodelwizard.cpp
@@ -590,7 +590,7 @@ void LLFloaterModelWizard::refresh()
{
bool model_loaded = false;
- if (mModelPreview && mModelPreview->mModelLoader && mModelPreview->mModelLoader->getLoadState() == LLModelLoader::DONE)
+ if (mModelPreview && mModelPreview->getLoadState() == LLModelLoader::DONE)
{
model_loaded = true;
}