00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _SG_MODELREGISTRY_HXX
00020 #define _SG_MODELREGISTRY_HXX 1
00021
00022 #include <osg/ref_ptr>
00023 #include <osg/Node>
00024 #include <osgDB/FileUtils>
00025 #include <osgDB/FileNameUtils>
00026 #include <osgDB/ReaderWriter>
00027 #include <osgDB/Registry>
00028
00029 #include <simgear/compiler.h>
00030 #include <simgear/structure/Singleton.hxx>
00031
00032 #include <string>
00033 #include <map>
00034
00035
00036
00037
00038 namespace simgear
00039 {
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 template <typename ProcessPolicy, typename CachePolicy, typename OptimizePolicy,
00062 typename SubstitutePolicy, typename BVHPolicy>
00063 class ModelRegistryCallback : public osgDB::Registry::ReadFileCallback {
00064 public:
00065 ModelRegistryCallback(const std::string& extension) :
00066 _processPolicy(extension), _cachePolicy(extension),
00067 _optimizePolicy(extension),
00068 _substitutePolicy(extension), _bvhPolicy(extension)
00069 {
00070 }
00071 virtual osgDB::ReaderWriter::ReadResult
00072 readNode(const std::string& fileName,
00073 const osgDB::ReaderWriter::Options* opt)
00074 {
00075 using namespace osg;
00076 using namespace osgDB;
00077 using osgDB::ReaderWriter;
00078
00079 ref_ptr<osg::Node> optimizedNode = _cachePolicy.find(fileName, opt);
00080 if (!optimizedNode.valid()) {
00081 std::string otherFileName = _substitutePolicy.substitute(fileName,
00082 opt);
00083 ReaderWriter::ReadResult res;
00084 if (!otherFileName.empty()) {
00085 res = loadUsingReaderWriter(otherFileName, opt);
00086 if (res.validNode())
00087 optimizedNode = res.getNode();
00088 }
00089 if (!optimizedNode.valid()) {
00090 res = loadUsingReaderWriter(fileName, opt);
00091 if (!res.validNode())
00092 return res;
00093 ref_ptr<osg::Node> processedNode
00094 = _processPolicy.process(res.getNode(), fileName, opt);
00095 optimizedNode = _optimizePolicy.optimize(processedNode.get(),
00096 fileName, opt);
00097 }
00098 _bvhPolicy.buildBVH(fileName, optimizedNode.get());
00099 _cachePolicy.addToCache(fileName, optimizedNode.get());
00100 }
00101 return ReaderWriter::ReadResult(optimizedNode);
00102 }
00103 protected:
00104 static osgDB::ReaderWriter::ReadResult
00105 loadUsingReaderWriter(const std::string& fileName,
00106 const osgDB::ReaderWriter::Options* opt)
00107 {
00108 using namespace osgDB;
00109 ReaderWriter* rw = Registry::instance()
00110 ->getReaderWriterForExtension(osgDB::getFileExtension(fileName));
00111 if (!rw)
00112 return ReaderWriter::ReadResult();
00113 return rw->readNode(fileName, opt);
00114 }
00115
00116 ProcessPolicy _processPolicy;
00117 CachePolicy _cachePolicy;
00118 OptimizePolicy _optimizePolicy;
00119 SubstitutePolicy _substitutePolicy;
00120 BVHPolicy _bvhPolicy;
00121 virtual ~ModelRegistryCallback() {}
00122 };
00123
00124
00125
00126 struct DefaultProcessPolicy {
00127 DefaultProcessPolicy(const std::string& extension) {}
00128 osg::Node* process(osg::Node* node, const std::string& filename,
00129 const osgDB::ReaderWriter::Options* opt);
00130 };
00131
00132 struct DefaultCachePolicy {
00133 DefaultCachePolicy(const std::string& extension) {}
00134 osg::Node* find(const std::string& fileName,
00135 const osgDB::ReaderWriter::Options* opt);
00136 void addToCache(const std::string& filename, osg::Node* node);
00137 };
00138
00139 struct NoCachePolicy {
00140 NoCachePolicy(const std::string& extension) {}
00141 osg::Node* find(const std::string& fileName,
00142 const osgDB::ReaderWriter::Options* opt)
00143 {
00144 return 0;
00145 }
00146 void addToCache(const std::string& filename, osg::Node* node) {}
00147 };
00148
00149 class OptimizeModelPolicy {
00150 public:
00151 OptimizeModelPolicy(const std::string& extension);
00152 osg::Node* optimize(osg::Node* node, const std::string& fileName,
00153 const osgDB::ReaderWriter::Options* opt);
00154 protected:
00155 unsigned _osgOptions;
00156 };
00157
00158 struct NoOptimizePolicy {
00159 NoOptimizePolicy(const std::string& extension) {}
00160 osg::Node* optimize(osg::Node* node, const std::string& fileName,
00161 const osgDB::ReaderWriter::Options* opt)
00162 {
00163 return node;
00164 }
00165 };
00166
00167 struct OSGSubstitutePolicy {
00168 OSGSubstitutePolicy(const std::string& extension) {}
00169 std::string substitute(const std::string& name,
00170 const osgDB::ReaderWriter::Options* opt);
00171 };
00172
00173 struct NoSubstitutePolicy {
00174 NoSubstitutePolicy(const std::string& extension) {}
00175 std::string substitute(const std::string& name,
00176 const osgDB::ReaderWriter::Options* opt)
00177 {
00178 return std::string();
00179 }
00180 };
00181
00182 struct BuildLeafBVHPolicy {
00183 BuildLeafBVHPolicy(const std::string& extension) {}
00184 void buildBVH(const std::string& fileName, osg::Node* node);
00185 };
00186
00187 struct BuildGroupBVHPolicy {
00188 BuildGroupBVHPolicy(const std::string& extension) {}
00189 void buildBVH(const std::string& fileName, osg::Node* node);
00190 };
00191
00192 struct NoBuildBVHPolicy {
00193 NoBuildBVHPolicy(const std::string& extension) {}
00194 void buildBVH(const std::string& fileName, osg::Node* node);
00195 };
00196
00197 typedef ModelRegistryCallback<DefaultProcessPolicy, DefaultCachePolicy,
00198 OptimizeModelPolicy,
00199 OSGSubstitutePolicy, BuildLeafBVHPolicy>
00200 DefaultCallback;
00201
00202
00203 class ModelRegistry : public osgDB::Registry::ReadFileCallback,
00204 public ReferencedSingleton<ModelRegistry> {
00205 public:
00206 ModelRegistry();
00207 virtual osgDB::ReaderWriter::ReadResult
00208 readImage(const std::string& fileName,
00209 const osgDB::ReaderWriter::Options* opt);
00210 virtual osgDB::ReaderWriter::ReadResult
00211 readNode(const std::string& fileName,
00212 const osgDB::ReaderWriter::Options* opt);
00213 void addImageCallbackForExtension(const std::string& extension,
00214 osgDB::Registry::ReadFileCallback*
00215 callback);
00216 void addNodeCallbackForExtension(const std::string& extension,
00217 osgDB::Registry::ReadFileCallback*
00218 callback);
00219 virtual ~ModelRegistry() {}
00220 protected:
00221 typedef std::map<std::string, osg::ref_ptr<osgDB::Registry::ReadFileCallback> >
00222 CallbackMap;
00223 CallbackMap imageCallbackMap;
00224 CallbackMap nodeCallbackMap;
00225 osg::ref_ptr<DefaultCallback> _defaultCallback;
00226 };
00227
00228
00229
00230 typedef ModelRegistryCallback<DefaultProcessPolicy, NoCachePolicy,
00231 NoOptimizePolicy,
00232 NoSubstitutePolicy, BuildLeafBVHPolicy>
00233 LoadOnlyCallback;
00234
00235
00236
00237 template<typename T>
00238 class ModelRegistryCallbackProxy
00239 {
00240 public:
00241 ModelRegistryCallbackProxy(std::string extension)
00242 {
00243 ModelRegistry::instance()
00244 ->addNodeCallbackForExtension(extension, new T(extension));
00245 }
00246 };
00247 }
00248 #endif // _SG_MODELREGISTRY_HXX