From 77869c9c1d80998055d35fa099dcb77f45699257 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 17 Mar 2011 17:17:31 -0500 Subject: SH-587 Fix for crash when clicking cancel in model importer. --- indra/newview/llfloatermodelpreview.cpp | 928 +++++++++++++++++--------------- indra/newview/llfloatermodelpreview.h | 14 +- indra/newview/llfloatermodelwizard.cpp | 2 +- 3 files changed, 495 insertions(+), 449 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 6bf9fdfb9b..eb0816adb5 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"; @@ -1085,6 +1085,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) @@ -1151,273 +1156,304 @@ 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(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(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(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(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 model = LLModel::loadModelFromDomMesh(mesh); - if (mesh) + if (model.notNull() && validate_model(model)) { - LLPointer 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(skin->getSource().getElement()); - if (skin) + if (geom) { - domGeometry* geom = daeSafeCast(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; + 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(); - 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(); - - 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 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( 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 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( pElement ); + bool missingSkeletonOrScene = false; + + //If no skeleton, do a breadth-first search to get at specific joints + if ( !pSkeleton ) + { + daeElement* pScene = root->getDescendant("visual_scene"); + if ( !pScene ) { - daeElement* pScene = root->getDescendant("visual_scene"); - if ( !pScene ) - { - llwarns<<"No visual scene - unable to parse bone offsets "< > 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 > 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(children[i]); + if ( isNodeAJoint( pNode ) ) { - domNode* pNode = daeSafeCast(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 :: 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 :: 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 <( resolver.getElement() ); + if ( pJoint ) + { + //Pull out the translate id and store it in the jointTranslations map + daeSIDResolver jointResolver( pJoint, "./translate" ); + domTranslate* pTranslate = daeSafeCast( jointResolver.getElement() ); - //Setup the resolver - daeSIDResolver resolver( pSkeletonRootNode, str ); + LLMatrix4 workingTransform; - //Look for the joint - domNode* pJoint = daeSafeCast( resolver.getElement() ); - if ( pJoint ) - { - //Pull out the translate id and store it in the jointTranslations map - daeSIDResolver jointResolver( pJoint, "./translate" ); - domTranslate* pTranslate = daeSafeCast( 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" <typeID() != domTranslate::ID() ) - { - llwarns<< "The found element is not a translate node" <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(elem); + if (source) + { - domSource* source = daeSafeCast(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,279 +1462,284 @@ 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(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(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 :: const_iterator masterJointIt = mJointMap.begin(); - std::map :: 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 ( !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 :: const_iterator masterJointIt = mJointMap.begin(); + std::map :: 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 "<getJoint( lookingForJoint ); + if ( pJoint ) + { + pJoint->storeCurrentXform( jointTransform.getTranslation() ); + } + else { - //llinfos<<"joint "<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 :: const_iterator jointIt = model->mJointList.begin(); - const int jointCnt = model->mJointList.size(); - for ( int i=0; i :: const_iterator jointIt = model->mJointList.begin(); + const int jointCnt = model->mJointList.size(); + for ( int i=0; imInvBindMatrix[i]; - newInverse.setTranslation( jointTransforms[lookingForJoint].getTranslation() ); - model->mAlternateBindMatrix.push_back( newInverse ); - } - else - { - llwarns<<"Possibly misnamed/missing joint [" <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 [" <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(inputs[i]->getSource().getElement()); + if (pos_source) { - domSource* pos_source = daeSafeCast(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(inputs[i]->getSource().getElement()); + if (weight_source) { - domSource* weight_source = daeSafeCast(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 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()); + + std::vector wght; - LLMatrix4 transformation = mTransform; - // adjust the transformation to compensate for mesh normalization + F32 total = 0.f; - LLMatrix4 mesh_translation; - mesh_translation.setTranslation(mesh_translation_vector); - mesh_translation *= transformation; - transformation = mesh_translation; + 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; + } + } - LLMatrix4 mesh_scale; - mesh_scale.initScale(mesh_scale_vector); - mesh_scale *= transformation; - transformation = mesh_scale; + 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 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 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 ) @@ -2248,6 +2289,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 +2315,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 +2329,7 @@ U32 LLModelPreview::calcResourceCost() if (mFMP && mModelLoader) { - if ( mModelLoader->getLoadState() != LLModelLoader::ERROR_PARSING ) + if ( getLoadState() != LLModelLoader::ERROR_PARSING ) { mFMP->childEnable("ok_btn"); } @@ -2541,10 +2581,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 +2600,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 +3345,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 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 mJointMap; std::deque 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 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; } -- cgit v1.2.3