From 1510076b657b1f20dc587c0d1ceed9432bf365e6 Mon Sep 17 00:00:00 2001 From: granzuglia Date: Sun, 5 Nov 2006 19:09:04 +0000 Subject: [PATCH] added support for transformations --- wrap/io_trimesh/import_dae.h | 28 +++++++++++++---- wrap/io_trimesh/util_dae.h | 59 ++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/wrap/io_trimesh/import_dae.h b/wrap/io_trimesh/import_dae.h index 9b690d4e..dba32ddb 100644 --- a/wrap/io_trimesh/import_dae.h +++ b/wrap/io_trimesh/import_dae.h @@ -14,7 +14,8 @@ namespace io { { private: - static int LoadMesh(OpenMeshType& m,InfoDAE* info,const QDomNode& geo) + + static int LoadMesh(OpenMeshType& m,InfoDAE* info,const QDomNode& geo,const vcg::Matrix44f& t) { if (isThereTag(geo,"mesh")) { @@ -61,12 +62,20 @@ namespace io { for(size_t vv = offset;vv < m.vert.size();++vv) { assert((ii * 3 < geosrcposarr_size) && (ii * 3 + 1 < geosrcposarr_size) && (ii * 3 + 2 < geosrcposarr_size)); - m.vert[vv].P() = vcg::Point3f(geosrcposarr[ii * 3].toFloat(),geosrcposarr[ii * 3 + 1].toFloat(),geosrcposarr[ii * 3 + 2].toFloat()); + vcg::Point4f tmp = t * vcg::Point4f(geosrcposarr[ii * 3].toFloat(),geosrcposarr[ii * 3 + 1].toFloat(),geosrcposarr[ii * 3 + 2].toFloat(),1.0f); + m.vert[vv].P() = vcg::Point3f(tmp.X(),tmp.Y(),tmp.Z()); if (!srcnodenorm.isNull()) { assert((ii * 3 < geosrcvertnorm.size()) && (ii * 3 + 1 < geosrcvertnorm.size()) && (ii * 3 + 2 < geosrcvertnorm.size())); - m.vert[vv].N() = vcg::Point3f(geosrcvertnorm[ii * 3].toFloat(),geosrcvertnorm[ii * 3 + 1].toFloat(),geosrcvertnorm[ii * 3 + 2].toFloat()); + vcg::Matrix44f intr44 = vcg::Transpose(vcg::Inverse(t)); + Matrix33f intr33; + for(unsigned int rr = 0; rr < 2; ++rr) + { + for(unsigned int cc = 0;cc < 2;++cc) + intr33[rr][cc] = intr44[rr][cc]; + } + m.vert[vv].N() = (intr33 * vcg::Point3f(geosrcvertnorm[ii * 3].toFloat(),geosrcvertnorm[ii * 3 + 1].toFloat(),geosrcvertnorm[ii * 3 + 2].toFloat())).Normalize(); } /*if (!srcnodecolor.isNull()) @@ -288,20 +297,25 @@ namespace io { int geoinst_size = geoinst.size(); if (geoinst_size != 0) { + geoinst_found |= true; QDomNodeList& geolib = info->doc->elementsByTagName("library_geometries"); int geolib_size = geolib.size(); assert(geolib_size == 1); //!!!!!!!!!!!!!!!!!here will be the code for geometry transformations!!!!!!!!!!!!!!!!!!!!!! + for(int geoinst_ind = 0;geoinst_ind < geoinst_size;++geoinst_ind) { QString geo_url; referenceToANodeAttribute(geoinst.at(geoinst_ind),"url",geo_url); - + QDomNode geo = findNodeBySpecificAttributeValue(geolib.at(0),"geometry","id",geo_url); if (geo.isNull()) return E_UNREFERENCEBLEDCOLLADAATTRIBUTE; - problem |= LoadMesh(m,info,geo); + vcg::Matrix44f tr; + tr.SetIdentity(); + TransfMatrix(visscn,geoinst.at(geoinst_ind),tr); + problem |= LoadMesh(m,info,geo,tr); if (problem) return problem; } } @@ -319,7 +333,9 @@ namespace io { int problem = 0; for(int chd = 0;chd < geochild_size;++chd) { - problem |= LoadMesh(m,info,geochild.at(chd)); + vcg::Matrix44f tmp; + tmp.SetIdentity(); + problem |= LoadMesh(m,info,geochild.at(chd),tmp); if (problem) return problem; } } diff --git a/wrap/io_trimesh/util_dae.h b/wrap/io_trimesh/util_dae.h index ae9a1d63..ed1aa9df 100644 --- a/wrap/io_trimesh/util_dae.h +++ b/wrap/io_trimesh/util_dae.h @@ -193,6 +193,65 @@ namespace io { } return true; } + + static void ParseRotationMatrix(vcg::Matrix44f& m,const std::vector& t) + { + vcg::Matrix44f tmp; + tmp.SetIdentity(); + for(unsigned int ii = 0;ii < t.size();++ii) + { + QString rt = t[ii].firstChild().nodeValue(); + QStringList rtl = rt.split(" "); + if (rtl.last() == "") rtl.removeLast(); + assert(rtl.size() == 4); + tmp.SetRotate(rtl.at(3).toFloat(),vcg::Point3f(rtl.at(0).toFloat(),rtl.at(1).toFloat(),rtl.at(2).toFloat())); + tmp *= tmp; + } + m = m * tmp; + } + + static void AddTranslation(vcg::Matrix44f& m,const QDomNode& t) + { + QDomNode tr = t.firstChild(); + QString coord = tr.nodeValue(); + QStringList coordlist = coord.split(" "); + if (coordlist.last() == "") + coordlist.removeLast(); + assert(coordlist.size() == 3); + m[0][0] = 1.0f; + m[1][1] = 1.0f; + m[2][2] = 1.0f; + m[3][3] = 1.0f; + m[0][3] = coordlist.at(0).toFloat(); + m[1][3] = coordlist.at(1).toFloat(); + m[2][3] = coordlist.at(2).toFloat(); + } + + static void TransfMatrix(const QDomNode& parentnode,const QDomNode& presentnode,vcg::Matrix44f& m) + { + if (presentnode == parentnode) return; + else + { + QDomNode par = presentnode.parentNode(); + std::vector rotlist; + QDomNode trans; + for(int ch = 0;ch < par.childNodes().size();++ch) + { + if (par.childNodes().at(ch).nodeName() == "rotate") + rotlist.push_back(par.childNodes().at(ch)); + else if (par.childNodes().at(ch).nodeName() == "translate") + { + trans = par.childNodes().at(ch); + } + } + vcg::Matrix44f tmp; + tmp.SetIdentity(); + if (!trans.isNull()) AddTranslation(tmp,trans); + ParseRotationMatrix(tmp,rotlist); + m = m * tmp; + TransfMatrix(parentnode,par,m); + } + } }; } }