Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00015 #include "ModelLoader_impl.h"
00016
00017 #include <iostream>
00018 #include <sys/types.h>
00019 #include <sys/stat.h>
00020
00021 #include "VrmlUtil.h"
00022
00023 using namespace std;
00024
00025 #ifdef OPENHRP_COLLADA_FOUND
00026 #include <boost/foreach.hpp>
00027 #include "ColladaWriter.h"
00028 #include "BodyInfoCollada_impl.h"
00029 #include "SceneInfoCollada_impl.h"
00030
00031 static bool IsColladaFile(const std::string& filename)
00032 {
00033 size_t len = filename.size();
00034 if( len < 4 ) {
00035 return false;
00036 }
00037 if( filename[len-4] == '.' && ::tolower(filename[len-3]) == 'd' && ::tolower(filename[len-2]) == 'a' && ::tolower(filename[len-1]) == 'e' ) {
00038 return true;
00039 }
00040 if( filename[len-4] == '.' && ::tolower(filename[len-3]) == 'z' && ::tolower(filename[len-2]) == 'a' && ::tolower(filename[len-1]) == 'e' ) {
00041 return true;
00042 }
00043 return false;
00044 }
00045
00046 #endif
00047
00048 std::string replaceProjectDir(std::string url) {
00049 std::string path = url;
00050 if ( path.find("$(PROJECT_DIR)") != std::string::npos ) {
00051 std::string shdir = OPENHRP_SHARE_DIR;
00052 std::string pjdir = shdir + "/sample/project";
00053 path.replace(path.find("$(PROJECT_DIR)"),14, pjdir);
00054 }
00055 return path;
00056 }
00057
00058 ModelLoader_impl::ModelLoader_impl(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa)
00059 :
00060 orb(CORBA::ORB::_duplicate(orb)),
00061 poa(PortableServer::POA::_duplicate(poa))
00062 {
00063
00064 }
00065
00066
00067 ModelLoader_impl::~ModelLoader_impl()
00068 {
00069 clearData();
00070 }
00071
00072
00073 PortableServer::POA_ptr ModelLoader_impl::_default_POA()
00074 {
00075 return PortableServer::POA::_duplicate(poa);
00076 }
00077
00078
00079 static void setLastUpdateTime(POA_OpenHRP::BodyInfo* bodyInfo, time_t time)
00080 {
00081 BodyInfo_impl* pBodyInfo_impl = dynamic_cast<BodyInfo_impl*>(bodyInfo);
00082 if( !!pBodyInfo_impl ) {
00083 pBodyInfo_impl->setLastUpdateTime(time);
00084 return;
00085 }
00086 #ifdef OPENHRP_COLLADA_FOUND
00087 BodyInfoCollada_impl* pBodyInfoCollada_impl = dynamic_cast<BodyInfoCollada_impl*>(bodyInfo);
00088 if( !!pBodyInfoCollada_impl ) {
00089 pBodyInfoCollada_impl->setLastUpdateTime(time);
00090 return;
00091 }
00092 #endif
00093 throw ModelLoader::ModelLoaderException("setLastUpdateTime invalid pointer");
00094 };
00095
00096 static time_t getLastUpdateTime(POA_OpenHRP::BodyInfo* bodyInfo) {
00097 BodyInfo_impl* pBodyInfo_impl = dynamic_cast<BodyInfo_impl*>(bodyInfo);
00098 if( !!pBodyInfo_impl ) {
00099 return pBodyInfo_impl->getLastUpdateTime();
00100 }
00101 #ifdef OPENHRP_COLLADA_FOUND
00102 BodyInfoCollada_impl* pBodyInfoCollada_impl = dynamic_cast<BodyInfoCollada_impl*>(bodyInfo);
00103 if( !!pBodyInfoCollada_impl ) {
00104 return pBodyInfoCollada_impl->getLastUpdateTime();
00105 }
00106 #endif
00107 throw ModelLoader::ModelLoaderException("getLastUpdateTime invalid pointer");
00108 }
00109
00110 static bool checkInlineFileUpdateTime(POA_OpenHRP::BodyInfo* bodyInfo)
00111 {
00112 BodyInfo_impl* pBodyInfo_impl = dynamic_cast<BodyInfo_impl*>(bodyInfo);
00113 if( !!pBodyInfo_impl ) {
00114 return pBodyInfo_impl->checkInlineFileUpdateTime();
00115 }
00116 #ifdef OPENHRP_COLLADA_FOUND
00117 BodyInfoCollada_impl* pBodyInfoCollada_impl = dynamic_cast<BodyInfoCollada_impl*>(bodyInfo);
00118 if( !!pBodyInfoCollada_impl ) {
00119 return pBodyInfoCollada_impl->checkInlineFileUpdateTime();
00120 }
00121 #endif
00122 throw ModelLoader::ModelLoaderException("checkInlineFileUpdateTime invalid pointer");
00123 }
00124
00125 static void setParam(POA_OpenHRP::BodyInfo* bodyInfo, std::string param, int value)
00126 {
00127 BodyInfo_impl* pBodyInfo_impl = dynamic_cast<BodyInfo_impl*>(bodyInfo);
00128 if( !!pBodyInfo_impl ) {
00129 pBodyInfo_impl->setParam(param,value);
00130 return;
00131 }
00132 #ifdef OPENHRP_COLLADA_FOUND
00133 BodyInfoCollada_impl* pBodyInfoCollada_impl = dynamic_cast<BodyInfoCollada_impl*>(bodyInfo);
00134 if( !!pBodyInfoCollada_impl ) {
00135 pBodyInfoCollada_impl->setParam(param,value);
00136 return;
00137 }
00138 #endif
00139 throw ModelLoader::ModelLoaderException("setParam(param,value) invalid pointer");
00140 }
00141
00142 static void changetoBoundingBox(POA_OpenHRP::BodyInfo* bodyInfo, unsigned int* depth)
00143 {
00144 BodyInfo_impl* pBodyInfo_impl = dynamic_cast<BodyInfo_impl*>(bodyInfo);
00145 if( !!pBodyInfo_impl ) {
00146 pBodyInfo_impl->changetoBoundingBox(depth);
00147 return;
00148 }
00149 #ifdef OPENHRP_COLLADA_FOUND
00150 BodyInfoCollada_impl* pBodyInfoCollada_impl = dynamic_cast<BodyInfoCollada_impl*>(bodyInfo);
00151 if( !!pBodyInfoCollada_impl ) {
00152 pBodyInfoCollada_impl->changetoBoundingBox(depth);
00153 return;
00154 }
00155 #endif
00156 throw ModelLoader::ModelLoaderException("changetoBoundingBox(depth) invalid pointer");
00157 }
00158
00159 BodyInfo_ptr ModelLoader_impl::loadBodyInfo(const char* url)
00160 throw (CORBA::SystemException, OpenHRP::ModelLoader::ModelLoaderException)
00161 {
00162 OpenHRP::ModelLoader::ModelLoadOption option;
00163 option.readImage = false;
00164 option.AABBdata.length(0);
00165 option.AABBtype = OpenHRP::ModelLoader::AABB_NUM;
00166 POA_OpenHRP::BodyInfo* bodyInfo = loadBodyInfoFromModelFile(replaceProjectDir(std::string(url)), option);
00167 return bodyInfo->_this();
00168 }
00169
00170 BodyInfo_ptr ModelLoader_impl::loadBodyInfoEx(const char* url, const OpenHRP::ModelLoader::ModelLoadOption& option)
00171 throw (CORBA::SystemException, OpenHRP::ModelLoader::ModelLoaderException)
00172 {
00173 POA_OpenHRP::BodyInfo* bodyInfo = loadBodyInfoFromModelFile(replaceProjectDir(std::string(url)), option);
00174 if(option.AABBdata.length()){
00175 setParam(bodyInfo,"AABBType", (int)option.AABBtype);
00176 int length=option.AABBdata.length();
00177 unsigned int* _AABBdata = new unsigned int[length];
00178 for(int i=0; i<length; i++)
00179 _AABBdata[i] = option.AABBdata[i];
00180 changetoBoundingBox(bodyInfo,_AABBdata);
00181 delete[] _AABBdata;
00182 }
00183 return bodyInfo->_this();
00184 }
00185
00186 BodyInfo_ptr ModelLoader_impl::getBodyInfoEx(const char* url0, const OpenHRP::ModelLoader::ModelLoadOption& option)
00187 throw (CORBA::SystemException, OpenHRP::ModelLoader::ModelLoaderException)
00188 {
00189 string url(url0);
00190
00191 BodyInfo_ptr bodyInfo = 0;
00192 string filename(deleteURLScheme(replaceProjectDir(url)));
00193 struct stat statbuff;
00194 time_t mtime = 0;
00195
00196
00197 if( stat( filename.c_str(), &statbuff ) == 0 ){
00198 mtime = statbuff.st_mtime;
00199 }
00200
00201 UrlToBodyInfoMap::iterator p = urlToBodyInfoMap.find(url);
00202 if(p != urlToBodyInfoMap.end() && mtime == getLastUpdateTime(p->second) && checkInlineFileUpdateTime(p->second)){
00203 bodyInfo = p->second->_this();
00204 cout << string("cache found for ") + url << endl;
00205 if(option.AABBdata.length()){
00206 setParam(p->second,"AABBType", (int)option.AABBtype);
00207 int length=option.AABBdata.length();
00208 unsigned int* _AABBdata = new unsigned int[length];
00209 for(int i=0; i<length; i++)
00210 _AABBdata[i] = option.AABBdata[i];
00211 changetoBoundingBox(p->second,_AABBdata);
00212 delete[] _AABBdata;
00213 }
00214 return bodyInfo;
00215 }
00216 return loadBodyInfoEx(url0, option);
00217 }
00218
00219 BodyInfo_ptr ModelLoader_impl::getBodyInfo(const char* url)
00220 throw (CORBA::SystemException, OpenHRP::ModelLoader::ModelLoaderException)
00221 {
00222 OpenHRP::ModelLoader::ModelLoadOption option;
00223 option.readImage = false;
00224 option.AABBdata.length(0);
00225 option.AABBtype = OpenHRP::ModelLoader::AABB_NUM;
00226 return getBodyInfoEx(url, option);
00227 }
00228
00229 POA_OpenHRP::BodyInfo* ModelLoader_impl::loadBodyInfoFromModelFile(const string url, const OpenHRP::ModelLoader::ModelLoadOption option)
00230 {
00231 cout << "loading " << url << endl;
00232 POA_OpenHRP::BodyInfo* bodyInfo;
00233 try {
00234 #ifdef OPENHRP_COLLADA_FOUND
00235 if( IsColladaFile(url) ) {
00236 BodyInfoCollada_impl* p = new BodyInfoCollada_impl(poa);
00237 p->setParam("readImage", option.readImage);
00238 p->loadModelFile(url);
00239 bodyInfo = p;
00240 }
00241 else
00242 #endif
00243 {
00244 BodyInfo_impl* p = new BodyInfo_impl(poa);
00245 p->setParam("readImage", option.readImage);
00246 p->loadModelFile(url);
00247 bodyInfo = p;
00248 }
00249 }
00250 catch(OpenHRP::ModelLoader::ModelLoaderException& ex){
00251 cout << "loading failed.\n";
00252 cout << ex.description << endl;
00253
00254 throw;
00255 }
00256
00257 cout << "The model was successfully loaded ! " << endl;
00258
00259 #ifdef OPENHRP_COLLADA_FOUND
00260
00261
00262
00263
00264 #endif
00265
00266
00267 urlToBodyInfoMap[url] = bodyInfo;
00268
00269 string filename(deleteURLScheme(url));
00270 struct stat statbuff;
00271 time_t mtime = 0;
00272
00273
00274 if( stat( filename.c_str(), &statbuff ) == 0 ){
00275 mtime = statbuff.st_mtime;
00276 }
00277 setLastUpdateTime(bodyInfo, mtime );
00278
00279 return bodyInfo;
00280 }
00281
00282
00283
00284 SceneInfo_ptr ModelLoader_impl::loadSceneInfo(const char* url)
00285 throw (CORBA::SystemException, OpenHRP::ModelLoader::ModelLoaderException)
00286 {
00287 cout << "loading " << url << endl;
00288
00289 SceneInfo_impl* sceneInfo;
00290 try {
00291 #ifdef OPENHRP_COLLADA_FOUND
00292 if( IsColladaFile(url) ) {
00293 SceneInfoCollada_impl* p = new SceneInfoCollada_impl(poa);
00294 p->load(url);
00295 sceneInfo = p;
00296 }
00297 else
00298 #endif
00299 {
00300 SceneInfo_impl* p = new SceneInfo_impl(poa);
00301 p->load(url);
00302 sceneInfo = p;
00303 }
00304 }
00305 catch(OpenHRP::ModelLoader::ModelLoaderException& ex){
00306 cout << "loading failed.\n";
00307 cout << ex.description << endl;
00308
00309 throw;
00310 }
00311 cout << url << " was successfully loaded ! " << endl;
00312
00313
00314
00315 return sceneInfo->_this();
00316 }
00317
00318
00319 void ModelLoader_impl::clearData()
00320 {
00321
00322
00323
00324
00325
00326
00327
00328 urlToBodyInfoMap.clear();
00329 }
00330
00331
00332 void ModelLoader_impl::shutdown()
00333 {
00334 clearData();
00335 orb->shutdown(false);
00336 }