diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 640295f5c37ecf1d87d18396b04ab2903dc3ba57..ecc0e8d144dc89d7a0342e95f0cb626b3e68ffe4 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -994,6 +994,8 @@ bool LLDAELoader::OpenFile(const std::string& filename) mTransform.condition(); + mBindTransform.setIdentity(); + U32 submodel_limit = count > 0 ? mGeneratedModelLimit/count : 0; for (daeInt idx = 0; idx < count; ++idx) { //build map of domEntities to LLModel @@ -1049,33 +1051,7 @@ bool LLDAELoader::OpenFile(const std::string& filename) } 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 (geom) - { - domMesh* mesh = geom->getMesh(); - if (mesh) - { - std::vector< LLPointer< LLModel > >::iterator i = mModelsMap[mesh].begin(); - while (i != mModelsMap[mesh].end()) - { - LLPointer<LLModel> mdl = *i; - LLDAELoader::processDomModel(mdl, &dae, root, mesh, skin); - i++; - } - } - } - } - } - - LL_INFOS()<< "Collada skins processed: " << count <<LL_ENDL; + LL_INFOS()<< "Collada skins to be processed: " << count <<LL_ENDL; daeElement* scene = root->getDescendant("visual_scene"); @@ -1090,7 +1066,7 @@ bool LLDAELoader::OpenFile(const std::string& filename) bool badElement = false; - processElement( scene, badElement, &dae ); + processElement( scene, badElement, &dae, root); if ( badElement ) { @@ -1179,6 +1155,8 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do LLMatrix4 trans = normalized_transformation; trans *= mat; + trans *= mBindTransform; + skin_info.mBindShapeMatrix.loadu(trans); } @@ -1946,9 +1924,9 @@ daeElement* LLDAELoader::getChildFromElement( daeElement* pElement, std::string return NULL; } -void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* dae ) +void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* dae, daeElement* domRoot) { - LLMatrix4 saved_transform; + LLMatrix4 saved_transform, saved_bind_transform; bool pushed_mat = false; domNode* node = daeSafeCast<domNode>(element); @@ -1956,6 +1934,7 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da { pushed_mat = true; saved_transform = mTransform; + saved_bind_transform = mBindTransform; } domTranslate* translate = daeSafeCast<domTranslate>(element); @@ -1963,12 +1942,17 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da { domFloat3 dom_value = translate->getValue(); - LLMatrix4 translation; + LLMatrix4 translation, translation2; translation.setTranslation(LLVector3(dom_value[0], dom_value[1], dom_value[2])); + translation2 = translation; translation *= mTransform; mTransform = translation; mTransform.condition(); + + translation2 *= mBindTransform; + mBindTransform = translation2; + mBindTransform.condition(); } domRotate* rotate = daeSafeCast<domRotate>(element); @@ -1976,12 +1960,17 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da { domFloat4 dom_value = rotate->getValue(); - LLMatrix4 rotation; + LLMatrix4 rotation, rotation2; rotation.initRotTrans(dom_value[3] * DEG_TO_RAD, LLVector3(dom_value[0], dom_value[1], dom_value[2]), LLVector3(0, 0, 0)); + rotation2 = rotation; rotation *= mTransform; mTransform = rotation; mTransform.condition(); + + rotation2 *= mBindTransform; + mBindTransform = rotation2; + mBindTransform.condition(); } domScale* scale = daeSafeCast<domScale>(element); @@ -1992,12 +1981,17 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da LLVector3 scale_vector = LLVector3(dom_value[0], dom_value[1], dom_value[2]); scale_vector.abs(); // Set all values positive, since we don't currently support mirrored meshes - LLMatrix4 scaling; + LLMatrix4 scaling, scaling2; scaling.initScale(scale_vector); + scaling2 = scaling; scaling *= mTransform; mTransform = scaling; mTransform.condition(); + + scaling2 *= mBindTransform; + mBindTransform = scaling2; + mBindTransform.condition(); } domMatrix* matrix = daeSafeCast<domMatrix>(element); @@ -2005,7 +1999,7 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da { domFloat4x4 dom_value = matrix->getValue(); - LLMatrix4 matrix_transform; + LLMatrix4 matrix_transform, matrix_transform2; for (int i = 0; i < 4; i++) { @@ -2015,9 +2009,15 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da } } + matrix_transform2 = matrix_transform; + matrix_transform *= mTransform; mTransform = matrix_transform; mTransform.condition(); + + matrix_transform2 *= mBindTransform; + mBindTransform = matrix_transform2; + mBindTransform.condition(); } domInstance_geometry* instance_geo = daeSafeCast<domInstance_geometry>(element); @@ -2115,7 +2115,36 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da daeElement* instance = instance_node->getUrl().getElement(); if (instance) { - processElement(instance,badElement, dae); + processElement(instance,badElement, dae, domRoot); + } + } + + domInstance_controller* instance_ctl = daeSafeCast<domInstance_controller>(element); + if (instance_ctl) + { + domController* ctl = daeSafeCast<domController>(instance_ctl->getUrl().getElement()); + if (ctl) + { + domSkin* skin = ctl->getSkin(); + if (skin) + { + domGeometry* geom = daeSafeCast<domGeometry>(skin->getSource().getElement()); + + if (geom) + { + domMesh* mesh = geom->getMesh(); + if (mesh) + { + std::vector< LLPointer< LLModel > >::iterator i = mModelsMap[mesh].begin(); + while (i != mModelsMap[mesh].end()) + { + LLPointer<LLModel> mdl = *i; + LLDAELoader::processDomModel(mdl, dae, domRoot, mesh, skin); + i++; + } + } + } + } } } @@ -2124,12 +2153,13 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da int childCount = children.getCount(); for (S32 i = 0; i < childCount; i++) { - processElement(children[i],badElement, dae); + processElement(children[i],badElement, dae, domRoot); } if (pushed_mat) { //this element was a node, restore transform before processiing siblings mTransform = saved_transform; + mBindTransform = saved_bind_transform; } } diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 417597b52563d5176c206568075c5be18458b652..edb67b6867bfcd206d32471c4631fd63bef447a3 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -66,7 +66,7 @@ class LLDAELoader final : public LLModelLoader protected: - void processElement(daeElement* element, bool& badElement, DAE* dae); + void processElement(daeElement* element, bool& badElement, DAE* dae, daeElement* domRoot); void processDomModel(LLModel* model, DAE* dae, daeElement* pRoot, domMesh* mesh, domSkin* skin); material_map getMaterials(LLModel* model, domInstance_geometry* instance_geo, DAE* dae); diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index c3dd31be9fe0cf06728de585e1b95a37f37a11fc..d60fc1bdbcb81154d97d815ddef008be79d455d1 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -103,7 +103,7 @@ class LLModelLoader : public LLThread S32 mLod; - LLMatrix4 mTransform; + LLMatrix4 mTransform, mBindTransform; BOOL mFirstTransform; LLVector3 mExtents[2];