]> git.mxchange.org Git - simgear.git/commitdiff
wip for effects in models
authorTim Moore <timoore@redhat.com>
Sat, 15 Aug 2009 12:00:51 +0000 (14:00 +0200)
committerTim Moore <timoore@redhat.com>
Fri, 13 Nov 2009 21:41:10 +0000 (22:41 +0100)
multi-index for effect attributes

simgear/scene/material/Effect.cxx
simgear/scene/material/EffectBuilder.hxx
simgear/scene/material/TextureBuilder.cxx
simgear/scene/material/makeEffect.cxx
simgear/scene/model/ModelRegistry.cxx
simgear/scene/model/SGReaderWriterXML.cxx

index 14ad2022c059465423136695ec363c1ab6e50bc6..3bd14cc3ab11efa1393f53ba55a5967d0a57506a 100644 (file)
@@ -73,6 +73,8 @@ using namespace std;
 using namespace osg;
 using namespace osgUtil;
 
+using namespace effect;
+
 Effect::Effect()
 {
 }
@@ -305,7 +307,7 @@ struct MaterialBuilder : public PassAttributeBuilder
                         const osgDB::ReaderWriter::Options* options);
 };
 
-EffectNameValue<Material::ColorMode> colorModes[] =
+EffectNameValue<Material::ColorMode> colorModeInit[] =
 {
     { "ambient", Material::AMBIENT },
     { "ambient-and-diffuse", Material::AMBIENT_AND_DIFFUSE },
@@ -314,6 +316,7 @@ EffectNameValue<Material::ColorMode> colorModes[] =
     { "specular", Material::SPECULAR },
     { "off", Material::OFF }
 };
+EffectPropertyMap<Material::ColorMode> colorModes(colorModeInit);
 
 void MaterialBuilder::buildAttribute(Effect* effect, Pass* pass,
                                      const SGPropertyNode* prop,
@@ -394,7 +397,7 @@ struct AlphaTestBuilder : public PassAttributeBuilder
 
 InstallAttributeBuilder<AlphaTestBuilder> installAlphaTest("alpha-test");
 
-EffectNameValue<TexEnv::Mode> texEnvModes[] =
+EffectNameValue<TexEnv::Mode> texEnvModesInit[] =
 {
     {"add", TexEnv::ADD},
     {"blend", TexEnv::BLEND},
@@ -402,6 +405,7 @@ EffectNameValue<TexEnv::Mode> texEnvModes[] =
     {"modulate", TexEnv::MODULATE},
     {"replace", TexEnv::REPLACE}
 };
+EffectPropertyMap<TexEnv::Mode> texEnvModes(texEnvModesInit);
 
 TexEnv* buildTexEnv(Effect* effect, const SGPropertyNode* prop)
 {
@@ -564,7 +568,7 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
 
 InstallAttributeBuilder<ShaderProgramBuilder> installShaderProgram("program");
 
-EffectNameValue<Uniform::Type> uniformTypes[] =
+EffectNameValue<Uniform::Type> uniformTypesInit[] =
 {
     {"float", Uniform::FLOAT},
     {"float-vec3", Uniform::FLOAT_VEC3},
@@ -573,6 +577,7 @@ EffectNameValue<Uniform::Type> uniformTypes[] =
     {"sampler-2d", Uniform::SAMPLER_2D},
     {"sampler-3d", Uniform::SAMPLER_3D}
 };
+EffectPropertyMap<Uniform::Type> uniformTypes(uniformTypesInit);
 
 struct UniformBuilder :public PassAttributeBuilder
 {
@@ -660,12 +665,13 @@ struct NameBuilder : public PassAttributeBuilder
 
 InstallAttributeBuilder<NameBuilder> installName("name");
 
-EffectNameValue<PolygonMode::Mode> polygonModeModes[] =
+EffectNameValue<PolygonMode::Mode> polygonModeModesInit[] =
 {
     {"fill", PolygonMode::FILL},
     {"line", PolygonMode::LINE},
     {"point", PolygonMode::POINT}
 };
+EffectPropertyMap<PolygonMode::Mode> polygonModeModes(polygonModeModesInit);
 
 struct PolygonModeBuilder : public PassAttributeBuilder
 {
index 831c9fabe078a60f02662e9540f024a7230b624e..e263f6efb2fb01f3a8188fc56d0a0ae452370935 100644 (file)
 
 #include <osgDB/Registry>
 
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+
 #include <simgear/props/props.hxx>
 #include <simgear/structure/exception.hxx>
 #include <simgear/structure/SGSharedPtr.hxx>
@@ -79,57 +83,112 @@ protected:
     }
 };
 
-// Simple tables of strings and constants. The table intialization
-// *must* be in alphabetical order.
+// Tables of strings and constants. We want to reconstruct the effect
+// property tree from OSG state sets, so the tables should be bi-directional.
+
+// two-way map for building StateSets from property descriptions, and
+// vice versa. Mostly copied from the boost documentation.
+
+namespace effect
+{
+using boost::multi_index_container;
+using namespace boost::multi_index;
+
+// tags for accessing both sides of a bidirectional map
+
+struct from{};
+struct to{};
+
 template <typename T>
 struct EffectNameValue
 {
     // Don't use std::pair because we want to use aggregate intialization.
-
     const char* first;
     T second;
-    class Compare
-    {
-    private:
-        static bool compare(const char* lhs, const char* rhs)
-        {
-            return std::strcmp(lhs, rhs) < 0;
-        }
-    public:
-        bool operator()(const EffectNameValue& lhs,
-                        const EffectNameValue& rhs) const
-        {
-            return compare(lhs.first, rhs.first);
-        }
-        bool operator()(const char* lhs, const EffectNameValue& rhs) const
-        {
-            return compare(lhs, rhs.first);
-        }
-        bool operator()(const EffectNameValue& lhs, const char* rhs) const
-        {
-            return compare (lhs.first, rhs);
-        }
-    };
 };
 
-template<typename ENV, typename T, int N>
-bool findAttr(const ENV (&attrs)[N], const SGPropertyNode* prop, T& result)
+// The class template bidirectional_map wraps the specification
+// of a bidirectional map based on multi_index_container.
+
+template<typename FromType,typename ToType>
+struct bidirectional_map
 {
+    typedef std::pair<FromType,ToType> value_type;
+
+    /* A bidirectional map can be simulated as a multi_index_container
+     * of pairs of (FromType,ToType) with two unique indices, one
+     * for each member of the pair.
+     */
+
+    typedef multi_index_container<
+        value_type,
+        indexed_by<
+            ordered_unique<
+                tag<from>, member<value_type, FromType, &value_type::first> >,
+            ordered_unique<
+                tag<to>,  member<value_type, ToType, &value_type::second> >
+            >
+        > type;
+};
+
+template<typename T>
+struct EffectPropertyMap
+{
+    typedef typename bidirectional_map<std::string, T>::type BMap;
+    BMap _map;
+    template<int N>
+    EffectPropertyMap(const EffectNameValue<T> (&attrs)[N]);
+};
+
+template<typename T>
+template<int N>
+EffectPropertyMap<T>::EffectPropertyMap(const EffectNameValue<T> (&attrs)[N])
+{
+    for (int i = 0; i < N; ++i)
+        _map.insert(typename BMap::value_type(attrs[i].first, attrs[i].second));
+}
+
+}
+
+template<typename T>
+bool findAttr(const effect::EffectPropertyMap<T>& pMap,
+              const SGPropertyNode* prop,
+              T& result)
+{
+    using namespace effect;
     if (!prop)
         return false;
     const char* name = prop->getStringValue();
     if (!name)
         return false;
-    std::pair<const ENV*, const ENV*> itrs
-        = std::equal_range(&attrs[0], &attrs[N], name, typename ENV::Compare());
-    if (itrs.first == itrs.second) {
+    typename EffectPropertyMap<T>::BMap::iterator itr
+        = pMap._map.get<from>().find(name);
+    if (itr == pMap._map.end()) {
         return false;
     } else {
-        result = itrs.first->second;
+        result = itr->second;
         return true;
     }
 }
 
+template<typename T>
+std::string findName(const effect::EffectPropertyMap<T>& pMap, T value)
+{
+    using namespace effect;
+    std::string result;
+    typename EffectPropertyMap<T>::BMap::template index_iterator<to>::type itr
+        = pMap._map.get<to>().find(value);
+    if (itr != pMap._map.get<to>().end())
+        result = itr->first;
+    return result;
+}
+
+template<typename T>
+std::string findName(const effect::EffectPropertyMap<T>& pMap, GLenum value)
+{
+    return findName(pMap, static_cast<T>(value));
+}
+
 /**
  * Given a property node from a pass, get its value either from it or
  * from the effect parameters.
index a6490c92d32ac44c10707df5426302b72c0a6452..cc927341ede6c631247c6e3d92739e95fc347370 100644 (file)
@@ -41,6 +41,8 @@ namespace simgear
 using namespace std;
 using namespace osg;
 
+using namespace effect;
+
 // Hack to force inclusion of TextureBuilder.cxx in library
 osg::Texture* TextureBuilder::buildFromType(Effect* effect, const string& type,
                                             const SGPropertyNode*props,
@@ -56,7 +58,7 @@ typedef boost::tuple<string, Texture::FilterMode, Texture::FilterMode,
 
 namespace
 {
-EffectNameValue<Texture::FilterMode> filterModes[] =
+EffectNameValue<Texture::FilterMode> filterModesInit[] =
 {
     { "linear", Texture::LINEAR },
     { "linear-mipmap-linear", Texture::LINEAR_MIPMAP_LINEAR},
@@ -65,8 +67,9 @@ EffectNameValue<Texture::FilterMode> filterModes[] =
     { "nearest-mipmap-linear", Texture::NEAREST_MIPMAP_LINEAR},
     { "nearest-mipmap-nearest", Texture::NEAREST_MIPMAP_NEAREST}
 };
+EffectPropertyMap<Texture::FilterMode> filterModes(filterModesInit);
 
-EffectNameValue<Texture::WrapMode> wrapModes[] =
+EffectNameValue<Texture::WrapMode> wrapModesInit[] =
 {
     {"clamp", Texture::CLAMP},
     {"clamp-to-border", Texture::CLAMP_TO_BORDER},
@@ -74,7 +77,7 @@ EffectNameValue<Texture::WrapMode> wrapModes[] =
     {"mirror", Texture::MIRROR},
     {"repeat", Texture::REPEAT}
 };
-
+EffectPropertyMap<Texture::WrapMode> wrapModes(wrapModesInit);
 
 
 TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props,
index b2d37ff21e8e683c964829aa85969a99e6b098aa..786fc2f579411bffc7d2bdfb759602762eed62fe 100644 (file)
@@ -32,6 +32,7 @@
 #include <simgear/debug/logstream.hxx>
 #include <simgear/props/props_io.hxx>
 #include <simgear/scene/util/SGSceneFeatures.hxx>
+#include <simgear/scene/util/SplicingVisitor.hxx>
 #include <simgear/structure/SGExpression.hxx>
 
 namespace simgear
index 1728020d64df06be17b7337d1ecb036b0dc90726..8a13c7624b2c86ec0dfa5614f6975634504691bb 100644 (file)
@@ -208,7 +208,6 @@ ModelRegistry::readImage(const string& fileName,
     ScopedLock<ReentrantMutex> lock(readerMutex);
     CallbackMap::iterator iter
         = imageCallbackMap.find(getFileExtension(fileName));
-    // XXX Workaround for OSG plugin bug
     {
         if (iter != imageCallbackMap.end() && iter->second.valid())
             return iter->second->readImage(fileName, opt);
@@ -357,8 +356,6 @@ ModelRegistry::readNode(const string& fileName,
 {
     ScopedLock<ReentrantMutex> lock(readerMutex);
 
-    // XXX Workaround for OSG plugin bug.
-//    Registry* registry = Registry::instance();
     ReaderWriter::ReadResult res;
     CallbackMap::iterator iter
         = nodeCallbackMap.find(getFileExtension(fileName));
index 75026bcfebad5a807b3720bff60b783e39bc88cf..2a4d612e6f2f485939dc79499b6a438993a430d4 100644 (file)
@@ -193,6 +193,9 @@ sgLoad3DModel_internal(const string &path,
         SGPropertyNode *mp = props->getNode("multiplay");
         if (mp && prop_root && prop_root->getParent())
             copyProperties(mp, prop_root);
+    } else {
+        SG_LOG(SG_INPUT, SG_DEBUG, "model without wrapper: "
+               << modelpath.str());
     }
 
     osg::ref_ptr<SGReaderWriterXMLOptions> options