00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 # include <simgear_config.h>
00026 #endif
00027
00028 #include <simgear/compiler.h>
00029 #include <simgear/constants.h>
00030 #include <simgear/structure/exception.hxx>
00031
00032 #include <string.h>
00033 #include <string>
00034
00035 #include <osgDB/Registry>
00036
00037 #include <simgear/debug/logstream.hxx>
00038 #include <simgear/misc/sg_path.hxx>
00039 #include <simgear/misc/sgstream.hxx>
00040 #include <simgear/props/props_io.hxx>
00041 #include <simgear/props/condition.hxx>
00042 #include <simgear/scene/tgdb/userdata.hxx>
00043
00044 #include "mat.hxx"
00045
00046 #include "Effect.hxx"
00047 #include "Technique.hxx"
00048 #include "matlib.hxx"
00049
00050 using std::string;
00051
00052
00053 SGMaterialLib::SGMaterialLib ( void ) {
00054 }
00055
00056
00057 bool SGMaterialLib::load( const string &fg_root, const string& mpath,
00058 SGPropertyNode *prop_root )
00059 {
00060 SGPropertyNode materials;
00061
00062 SG_LOG( SG_INPUT, SG_INFO, "Reading materials from " << mpath );
00063 try {
00064 readProperties( mpath, &materials );
00065 } catch (const sg_exception &ex) {
00066 SG_LOG( SG_INPUT, SG_ALERT, "Error reading materials: "
00067 << ex.getMessage() );
00068 throw;
00069 }
00070 osg::ref_ptr<osgDB::ReaderWriter::Options> options
00071 = new osgDB::ReaderWriter::Options;
00072 options->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_ALL);
00073 options->setDatabasePath(fg_root);
00074 int nMaterials = materials.nChildren();
00075 for (int i = 0; i < nMaterials; i++) {
00076 const SGPropertyNode *node = materials.getChild(i);
00077 if (!strcmp(node->getName(), "material")) {
00078 const SGPropertyNode *conditionNode = node->getChild("condition");
00079 if (conditionNode) {
00080 SGSharedPtr<const SGCondition> condition = sgReadCondition(prop_root, conditionNode);
00081 if (!condition->test()) {
00082 SG_LOG(SG_INPUT, SG_DEBUG, "Skipping material entry #"
00083 << i << " (condition false)");
00084 continue;
00085 }
00086 }
00087
00088 SGSharedPtr<SGMaterial> m = new SGMaterial(options.get(), node);
00089
00090 vector<SGPropertyNode_ptr>names = node->getChildren("name");
00091 for ( unsigned int j = 0; j < names.size(); j++ ) {
00092 string name = names[j]->getStringValue();
00093
00094 matlib[name] = m;
00095 m->add_name(name);
00096 SG_LOG( SG_TERRAIN, SG_DEBUG, " Loading material "
00097 << names[j]->getStringValue() );
00098 }
00099 } else {
00100 SG_LOG(SG_INPUT, SG_WARN,
00101 "Skipping bad material entry " << node->getName());
00102 }
00103 }
00104
00105 return true;
00106 }
00107
00108
00109 SGMaterial *SGMaterialLib::find( const string& material ) {
00110 SGMaterial *result = NULL;
00111 material_map_iterator it = matlib.find( material );
00112 if ( it != end() ) {
00113 result = it->second;
00114 return result;
00115 }
00116
00117 return NULL;
00118 }
00119
00120
00121 SGMaterialLib::~SGMaterialLib ( void ) {
00122 SG_LOG( SG_GENERAL, SG_INFO, "SGMaterialLib::~SGMaterialLib() size=" << matlib.size());
00123 }
00124
00125 const SGMaterial*
00126 SGMaterialLib::findMaterial(const osg::Geode* geode)
00127 {
00128 if (!geode)
00129 return 0;
00130 const simgear::EffectGeode* effectGeode;
00131 effectGeode = dynamic_cast<const simgear::EffectGeode*>(geode);
00132 if (!effectGeode)
00133 return 0;
00134 const simgear::Effect* effect = effectGeode->getEffect();
00135 if (!effect)
00136 return 0;
00137 const SGMaterialUserData* userData;
00138 userData = dynamic_cast<const SGMaterialUserData*>(effect->getUserData());
00139 if (!userData)
00140 return 0;
00141 return userData->getMaterial();
00142 }