Merge branch 'timoore/effects-anim-rebase' into next

This commit is contained in:
Tim Moore
2010-03-09 11:03:25 +01:00
16 changed files with 422 additions and 144 deletions
+13 -8
View File
@@ -1027,17 +1027,22 @@ SGPropertyNode::getDisplayName (bool simplify) const
} }
const char * string
SGPropertyNode::getPath (bool simplify) const SGPropertyNode::getPath (bool simplify) const
{ {
// Calculate the complete path only once. typedef std::vector<SGConstPropertyNode_ptr> PList;
if (_parent != 0 && _path.empty()) { PList pathList;
_path = _parent->getPath(simplify); for (const SGPropertyNode* node = this; node->_parent; node = node->_parent)
_path += '/'; pathList.push_back(node);
_path += getDisplayName(simplify); string result;
for (PList::reverse_iterator itr = pathList.rbegin(),
rend = pathList.rend();
itr != rend;
++itr) {
result += '/';
result += (*itr)->getDisplayName(simplify);
} }
return result;
return _path.c_str();
} }
props::Type props::Type
+1 -2
View File
@@ -994,7 +994,7 @@ public:
/** /**
* Get the path to this node from the root. * Get the path to this node from the root.
*/ */
const char * getPath (bool simplify = false) const; std::string getPath (bool simplify = false) const;
/** /**
@@ -1675,7 +1675,6 @@ private:
simgear::PropertyList _children; simgear::PropertyList _children;
simgear::PropertyList _removedChildren; simgear::PropertyList _removedChildren;
std::vector<hash_table *> _linkedNodes; std::vector<hash_table *> _linkedNodes;
mutable std::string _path;
mutable std::string _buffer; mutable std::string _buffer;
hash_table * _path_cache; hash_table * _path_cache;
simgear::props::Type _type; simgear::props::Type _type;
+47 -28
View File
@@ -66,6 +66,7 @@
#include <osgDB/ReadFile> #include <osgDB/ReadFile>
#include <osgDB/Registry> #include <osgDB/Registry>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/tgdb/userdata.hxx> #include <simgear/scene/tgdb/userdata.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx> #include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx> #include <simgear/scene/util/StateAttributeFactory.hxx>
@@ -143,7 +144,7 @@ Effect::~Effect()
} }
void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop, void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
Pass* pass = new Pass; Pass* pass = new Pass;
tniq->passes.push_back(pass); tniq->passes.push_back(pass);
@@ -159,6 +160,10 @@ void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop,
} }
} }
// Default names for vector property components
const char* vec3Names[] = {"x", "y", "z"};
const char* vec4Names[] = {"x", "y", "z", "w"};
osg::Vec4f getColor(const SGPropertyNode* prop) osg::Vec4f getColor(const SGPropertyNode* prop)
{ {
if (prop->nChildren() == 0) { if (prop->nChildren() == 0) {
@@ -188,12 +193,12 @@ osg::Vec4f getColor(const SGPropertyNode* prop)
struct LightingBuilder : public PassAttributeBuilder struct LightingBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
void LightingBuilder::buildAttribute(Effect* effect, Pass* pass, void LightingBuilder::buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) if (!realProp)
@@ -207,7 +212,7 @@ InstallAttributeBuilder<LightingBuilder> installLighting("lighting");
struct ShadeModelBuilder : public PassAttributeBuilder struct ShadeModelBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) if (!realProp)
@@ -229,7 +234,7 @@ InstallAttributeBuilder<ShadeModelBuilder> installShadeModel("shade-model");
struct CullFaceBuilder : PassAttributeBuilder struct CullFaceBuilder : PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) { if (!realProp) {
@@ -257,7 +262,7 @@ InstallAttributeBuilder<CullFaceBuilder> installCullFace("cull-face");
struct ColorMaskBuilder : PassAttributeBuilder struct ColorMaskBuilder : PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) if (!realProp)
@@ -284,7 +289,7 @@ EffectPropertyMap<StateSet::RenderingHint> renderingHints(renderingHintInit);
struct HintBuilder : public PassAttributeBuilder struct HintBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) if (!realProp)
@@ -300,7 +305,7 @@ InstallAttributeBuilder<HintBuilder> installHint("rendering-hint");
struct RenderBinBuilder : public PassAttributeBuilder struct RenderBinBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -327,7 +332,7 @@ InstallAttributeBuilder<RenderBinBuilder> installRenderBin("render-bin");
struct MaterialBuilder : public PassAttributeBuilder struct MaterialBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
EffectNameValue<Material::ColorMode> colorModeInit[] = EffectNameValue<Material::ColorMode> colorModeInit[] =
@@ -343,7 +348,7 @@ EffectPropertyMap<Material::ColorMode> colorModes(colorModeInit);
void MaterialBuilder::buildAttribute(Effect* effect, Pass* pass, void MaterialBuilder::buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -413,7 +418,7 @@ EffectPropertyMap<BlendFunc::BlendFuncMode> blendFuncModes(blendFuncModesInit);
struct BlendBuilder : public PassAttributeBuilder struct BlendBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -526,7 +531,7 @@ EffectPropertyMap<Stencil::Operation> stencilOperation(stencilOperationInit);
struct StencilBuilder : public PassAttributeBuilder struct StencilBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -604,7 +609,7 @@ alphaComparison(alphaComparisonInit);
struct AlphaTestBuilder : public PassAttributeBuilder struct AlphaTestBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -715,12 +720,12 @@ void reload_shaders()
struct ShaderProgramBuilder : PassAttributeBuilder struct ShaderProgramBuilder : PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass, void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* const SGReaderWriterXMLOptions*
options) options)
{ {
using namespace boost; using namespace boost;
@@ -807,15 +812,18 @@ EffectNameValue<Uniform::Type> uniformTypesInit[] =
{"float-vec3", Uniform::FLOAT_VEC3}, {"float-vec3", Uniform::FLOAT_VEC3},
{"float-vec4", Uniform::FLOAT_VEC4}, {"float-vec4", Uniform::FLOAT_VEC4},
{"sampler-1d", Uniform::SAMPLER_1D}, {"sampler-1d", Uniform::SAMPLER_1D},
{"sampler-1d-shadow", Uniform::SAMPLER_1D_SHADOW},
{"sampler-2d", Uniform::SAMPLER_2D}, {"sampler-2d", Uniform::SAMPLER_2D},
{"sampler-3d", Uniform::SAMPLER_3D} {"sampler-2d-shadow", Uniform::SAMPLER_2D_SHADOW},
{"sampler-3d", Uniform::SAMPLER_3D},
{"sampler-cube", Uniform::SAMPLER_CUBE}
}; };
EffectPropertyMap<Uniform::Type> uniformTypes(uniformTypesInit); EffectPropertyMap<Uniform::Type> uniformTypes(uniformTypesInit);
struct UniformBuilder :public PassAttributeBuilder struct UniformBuilder :public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -861,18 +869,29 @@ struct UniformBuilder :public PassAttributeBuilder
uniform->setType(uniformType); uniform->setType(uniformType);
switch (uniformType) { switch (uniformType) {
case Uniform::FLOAT: case Uniform::FLOAT:
uniform->set(valProp->getValue<float>()); initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(float)>(&Uniform::set),
options);
break; break;
case Uniform::FLOAT_VEC3: case Uniform::FLOAT_VEC3:
uniform->set(toOsg(valProp->getValue<SGVec3d>())); initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(const Vec3&)>(&Uniform::set),
vec3Names, options);
break; break;
case Uniform::FLOAT_VEC4: case Uniform::FLOAT_VEC4:
uniform->set(toOsg(valProp->getValue<SGVec4d>())); initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(const Vec4&)>(&Uniform::set),
vec4Names, options);
break; break;
case Uniform::SAMPLER_1D: case Uniform::SAMPLER_1D:
case Uniform::SAMPLER_2D: case Uniform::SAMPLER_2D:
case Uniform::SAMPLER_3D: case Uniform::SAMPLER_3D:
uniform->set(valProp->getValue<int>()); case Uniform::SAMPLER_1D_SHADOW:
case Uniform::SAMPLER_2D_SHADOW:
case Uniform::SAMPLER_CUBE:
initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(int)>(&Uniform::set),
options);
break; break;
default: // avoid compiler warning default: // avoid compiler warning
break; break;
@@ -889,7 +908,7 @@ InstallAttributeBuilder<UniformBuilder> installUniform("uniform");
struct NameBuilder : public PassAttributeBuilder struct NameBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
// name can't use <use> // name can't use <use>
string name = prop->getStringValue(); string name = prop->getStringValue();
@@ -911,7 +930,7 @@ EffectPropertyMap<PolygonMode::Mode> polygonModeModes(polygonModeModesInit);
struct PolygonModeBuilder : public PassAttributeBuilder struct PolygonModeBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -939,7 +958,7 @@ InstallAttributeBuilder<PolygonModeBuilder> installPolygonMode("polygon-mode");
struct VertexProgramTwoSideBuilder : public PassAttributeBuilder struct VertexProgramTwoSideBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) if (!realProp)
@@ -956,7 +975,7 @@ installTwoSide("vertex-program-two-side");
struct VertexProgramPointSizeBuilder : public PassAttributeBuilder struct VertexProgramPointSizeBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) if (!realProp)
@@ -986,7 +1005,7 @@ EffectPropertyMap<Depth::Function> depthFunction(depthFunctionInit);
struct DepthBuilder : public PassAttributeBuilder struct DepthBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -1017,7 +1036,7 @@ struct DepthBuilder : public PassAttributeBuilder
InstallAttributeBuilder<DepthBuilder> installDepth("depth"); InstallAttributeBuilder<DepthBuilder> installDepth("depth");
void buildTechnique(Effect* effect, const SGPropertyNode* prop, void buildTechnique(Effect* effect, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
Technique* tniq = new Technique; Technique* tniq = new Technique;
effect->techniques.push_back(tniq); effect->techniques.push_back(tniq);
@@ -1123,7 +1142,7 @@ bool makeParametersFromStateSet(SGPropertyNode* effectRoot, const StateSet* ss)
// Walk the techniques property tree, building techniques and // Walk the techniques property tree, building techniques and
// passes. // passes.
bool Effect::realizeTechniques(const osgDB::ReaderWriter::Options* options) bool Effect::realizeTechniques(const SGReaderWriterXMLOptions* options)
{ {
if (_isRealized) if (_isRealized)
return true; return true;
+5 -4
View File
@@ -45,6 +45,7 @@ namespace simgear
{ {
class Technique; class Technique;
class Effect; class Effect;
class SGReaderWriterXMLOptions;
/** /**
* Object to be initialized at some point after an effect -- and its * Object to be initialized at some point after an effect -- and its
@@ -89,7 +90,7 @@ public:
/** /**
* Build the techniques from the effect properties. * Build the techniques from the effect properties.
*/ */
bool realizeTechniques(const osgDB::ReaderWriter::Options* options = 0); bool realizeTechniques(const SGReaderWriterXMLOptions* options = 0);
/** /**
* Updaters that should be derefed when the effect is * Updaters that should be derefed when the effect is
* deleted. Updaters arrange to be run by listening on properties * deleted. Updaters arrange to be run by listening on properties
@@ -144,7 +145,7 @@ protected:
Cache* _cache; Cache* _cache;
friend size_t hash_value(const Key& key); friend size_t hash_value(const Key& key);
friend Effect* makeEffect(SGPropertyNode* prop, bool realizeTechniques, friend Effect* makeEffect(SGPropertyNode* prop, bool realizeTechniques,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
bool _isRealized; bool _isRealized;
}; };
// Automatic support for boost hash function // Automatic support for boost hash function
@@ -153,11 +154,11 @@ size_t hash_value(const Effect::Key&);
Effect* makeEffect(const std::string& name, Effect* makeEffect(const std::string& name,
bool realizeTechniques, bool realizeTechniques,
const osgDB::ReaderWriter::Options* options = 0); const SGReaderWriterXMLOptions* options = 0);
Effect* makeEffect(SGPropertyNode* prop, Effect* makeEffect(SGPropertyNode* prop,
bool realizeTechniques, bool realizeTechniques,
const osgDB::ReaderWriter::Options* options = 0); const SGReaderWriterXMLOptions* options = 0);
bool makeParametersFromStateSet(SGPropertyNode* paramRoot, bool makeParametersFromStateSet(SGPropertyNode* paramRoot,
const osg::StateSet* ss); const osg::StateSet* ss);
+18 -1
View File
@@ -2,6 +2,7 @@
# include <simgear_config.h> # include <simgear_config.h>
#endif #endif
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/tgdb/userdata.hxx> #include <simgear/scene/tgdb/userdata.hxx>
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
@@ -41,13 +42,29 @@ const SGPropertyNode* getEffectPropertyChild(Effect* effect,
return getEffectPropertyNode(effect, child); return getEffectPropertyNode(effect, child);
} }
string getGlobalProperty(const SGPropertyNode* prop) string getGlobalProperty(const SGPropertyNode* prop,
const SGReaderWriterXMLOptions* options)
{ {
if (!prop) if (!prop)
return string(); return string();
const SGPropertyNode* useProp = prop->getChild("use"); const SGPropertyNode* useProp = prop->getChild("use");
if (!useProp) if (!useProp)
return string(); return string();
string propName = useProp->getStringValue();
SGPropertyNode_ptr propRoot;
if (propName[0] == '/') {
return propName;
} else if ((propRoot = options->getPropRoot())) {
string result = propRoot->getPath();
result.append("/");
result.append(propName);
return result;
} else {
throw effect::
BuilderException("No property root to use with relative name "
+ propName);
}
return useProp->getStringValue(); return useProp->getStringValue();
} }
+261 -59
View File
@@ -33,6 +33,7 @@
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
#include <simgear/props/AtomicChangeListener.hxx> #include <simgear/props/AtomicChangeListener.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/structure/exception.hxx> #include <simgear/structure/exception.hxx>
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/structure/Singleton.hxx> #include <simgear/structure/Singleton.hxx>
@@ -46,6 +47,7 @@ namespace simgear
{ {
class Effect; class Effect;
class Pass; class Pass;
class SGReaderWriterXMLOptions;
/** /**
* Builder that returns an object, probably an OSG object. * Builder that returns an object, probably an OSG object.
@@ -56,10 +58,10 @@ class EffectBuilder : public SGReferenced
public: public:
virtual ~EffectBuilder() {} virtual ~EffectBuilder() {}
virtual T* build(Effect* effect, const SGPropertyNode*, virtual T* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options) = 0; const SGReaderWriterXMLOptions* options) = 0;
static T* buildFromType(Effect* effect, const std::string& type, static T* buildFromType(Effect* effect, const std::string& type,
const SGPropertyNode*props, const SGPropertyNode*props,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
BuilderMap& builderMap = getMap(); BuilderMap& builderMap = getMap();
typename BuilderMap::iterator iter = builderMap.find(type); typename BuilderMap::iterator iter = builderMap.find(type);
@@ -154,6 +156,21 @@ EffectPropertyMap<T>::EffectPropertyMap(const EffectNameValue<T> (&attrs)[N])
_map.insert(typename BMap::value_type(attrs[i].first, attrs[i].second)); _map.insert(typename BMap::value_type(attrs[i].first, attrs[i].second));
} }
// A one-way map that can be initialized using an array
template<typename T>
struct SimplePropertyMap
{
typedef std::map<string, T> map_type;
map_type _map;
template<int N>
SimplePropertyMap(const EffectNameValue<T> (&attrs)[N])
{
for (int i = 0; i < N; ++i)
_map.insert(typename map_type::value_type(attrs[i].first,
attrs[i].second));
}
};
class BuilderException : public sg_exception class BuilderException : public sg_exception
{ {
public: public:
@@ -201,6 +218,42 @@ void findAttr(const effect::EffectPropertyMap<T>& pMap,
findAttr(pMap, name, result); findAttr(pMap, name, result);
} }
// Versions that don't throw an error
template<typename T>
const T* findAttr(const effect::EffectPropertyMap<T>& pMap,
const char* name)
{
using namespace effect;
typename EffectPropertyMap<T>::BMap::iterator itr
= pMap._map.get<from>().find(name);
if (itr == pMap._map.end())
return 0;
else
return &itr->second;
}
template<typename T>
const T* findAttr(const effect::SimplePropertyMap<T>& pMap,
const char* name)
{
using namespace effect;
typename SimplePropertyMap<T>::map_type::const_iterator itr
= pMap._map.find(name);
if (itr == pMap._map.end())
return 0;
else
return &itr->second;
}
template<typename T, template<class> class Map>
const T* findAttr(const Map<T>& pMap,
const std::string& name)
{
return findAttr(pMap, name.c_str());
}
template<typename T> template<typename T>
std::string findName(const effect::EffectPropertyMap<T>& pMap, T value) std::string findName(const effect::EffectPropertyMap<T>& pMap, T value)
{ {
@@ -240,7 +293,45 @@ const SGPropertyNode* getEffectPropertyChild(Effect* effect,
* @return empty if prop doesn't contain a <use> clause; otherwise the * @return empty if prop doesn't contain a <use> clause; otherwise the
* mentioned node name. * mentioned node name.
*/ */
std::string getGlobalProperty(const SGPropertyNode* prop); std::string getGlobalProperty(const SGPropertyNode* prop,
const SGReaderWriterXMLOptions *);
template<typename NameItr>
std::vector<std::string>
getVectorProperties(const SGPropertyNode* prop,
const SGReaderWriterXMLOptions *options, size_t vecSize,
NameItr defaultNames)
{
using namespace std;
vector<string> result;
if (!prop)
return result;
PropertyList useProps = prop->getChildren("use");
if (useProps.size() == 1) {
string parentName = useProps[0]->getStringValue();
if (parentName.size() == 0 || parentName[0] != '/')
parentName = options->getPropRoot()->getPath() + "/" + parentName;
if (parentName[parentName.size() - 1] != '/')
parentName.append("/");
NameItr itr = defaultNames;
for (int i = 0; i < vecSize; ++i, ++itr)
result.push_back(parentName + *itr);
} else if (useProps.size() == vecSize) {
string parentName = useProps[0]->getStringValue();
parentName += "/";
for (PropertyList::const_iterator itr = useProps.begin(),
end = useProps.end();
itr != end;
++itr) {
string childName = (*itr)->getStringValue();
if (childName.size() == 0 || childName[0] != '/')
result.push_back(parentName + childName);
else
result.push_back(childName);
}
}
return result;
}
class PassAttributeBuilder : public SGReferenced class PassAttributeBuilder : public SGReferenced
{ {
@@ -255,7 +346,7 @@ protected:
public: public:
virtual void buildAttribute(Effect* effect, Pass* pass, virtual void buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
= 0; = 0;
static PassAttributeBuilder* find(const std::string& str) static PassAttributeBuilder* find(const std::string& str)
{ {
@@ -289,64 +380,116 @@ bool isAttributeActive(Effect* effect, const SGPropertyNode* prop);
namespace effect namespace effect
{ {
/** /**
* Bridge between types stored in properties and what OSG wants. * Bridge between types stored in properties and what OSG or the
* effects code want.
*/ */
template<typename T> struct OSGBridge; template<typename T> struct Bridge;
/**
* Default just passes on the same type.
*
*/
template<typename T>
struct Bridge
{
typedef T sg_type;
static T get(const T& val) { return val; }
};
template<typename T> template<typename T>
struct OSGBridge<const T> : public OSGBridge<T> struct Bridge<const T> : public Bridge<T>
{
};
// Save some typing...
template<typename InType, typename OutType>
struct BridgeOSGVec
{
typedef InType sg_type;
static OutType get(const InType& val) { return toOsg(val); }
};
template<>
struct Bridge<osg::Vec3f> : public BridgeOSGVec<SGVec3d, osg::Vec3f>
{ {
}; };
template<> template<>
struct OSGBridge<osg::Vec3f> struct Bridge<osg::Vec3d> : public BridgeOSGVec<SGVec3d, osg::Vec3d>
{ {
typedef SGVec3d sg_type;
static osg::Vec3f getOsgType(const SGVec3d& val) { return toOsg(val); }
}; };
template<> template<>
struct OSGBridge<osg::Vec3d> struct Bridge<osg::Vec4f> : public BridgeOSGVec<SGVec4d, osg::Vec4f>
{ {
typedef SGVec3d sg_type;
static osg::Vec3d getOsgType(const SGVec3d& val) { return toOsg(val); }
}; };
template<> template<>
struct OSGBridge<osg::Vec4f> struct Bridge<osg::Vec4d> : public BridgeOSGVec<SGVec4d, osg::Vec4d>
{ {
typedef SGVec4d sg_type;
static osg::Vec4f getOsgType(const SGVec4d& val) { return toOsg(val); }
}; };
template<> /**
struct OSGBridge<osg::Vec4d> * Functor for calling a function on an osg::Referenced object and a
* value (e.g., an SGVec4d from a property) which will be converted to
* the equivalent OSG type.
*
* General version, function takes obj, val
*/
template<typename OSGParam, typename Obj, typename Func>
struct OSGFunctor : public Bridge<OSGParam>
{ {
typedef SGVec4d sg_type; OSGFunctor(Obj* obj, const Func& func)
static osg::Vec4d getOsgType(const SGVec4d& val) { return toOsg(val); }
};
template<typename Obj, typename OSGParam>
struct OSGFunctor : public OSGBridge<OSGParam>
{
OSGFunctor(Obj* obj, void (Obj::*func)(const OSGParam&))
: _obj(obj), _func(func) {} : _obj(obj), _func(func) {}
void operator()(const typename OSGBridge<OSGParam>::sg_type& val) const void operator()(const typename Bridge<OSGParam>::sg_type& val) const
{ {
((_obj.get())->*_func)(this->getOsgType(val)); _func(_obj, this->get(val));
} }
osg::ref_ptr<Obj>_obj; osg::ref_ptr<Obj>_obj;
void (Obj::*_func)(const OSGParam&); const Func _func;
}; };
template<typename ObjType, typename OSGParamType> /**
* Version which uses a pointer to member function instead.
*/
template<typename OSGParam, typename Obj>
struct OSGFunctor<OSGParam, Obj, void (Obj::* const)(const OSGParam&)>
: public Bridge<OSGParam>
{
typedef void (Obj::*const MemFunc)(const OSGParam&);
OSGFunctor(Obj* obj, MemFunc func)
: _obj(obj), _func(func) {}
void operator()(const typename Bridge<OSGParam>::sg_type& val) const
{
(_obj->*_func)(this->get(val));
}
osg::ref_ptr<Obj>_obj;
MemFunc _func;
};
/**
* Typical convenience constructors
*/
template<typename OSGParam, typename Obj, typename Func>
OSGFunctor<OSGParam, Obj, Func> make_OSGFunctor(Obj* obj, const Func& func)
{
return OSGFunctor<OSGParam, Obj, Func>(obj, func);
}
template<typename OSGParam, typename Obj>
OSGFunctor<OSGParam, Obj, void (Obj::*const)(const OSGParam&)>
make_OSGFunctor(Obj* obj, void (Obj::*const func)(const OSGParam&))
{
return OSGFunctor<OSGParam, Obj,
void (Obj::* const)(const OSGParam&)>(obj, func);
}
template<typename OSGParamType, typename ObjType, typename F>
class ScalarChangeListener class ScalarChangeListener
: public SGPropertyChangeListener, public InitializeWhenAdded, : public SGPropertyChangeListener, public InitializeWhenAdded,
public Effect::Updater public Effect::Updater
{ {
public: public:
typedef void (ObjType::*setter_type)(const OSGParamType); ScalarChangeListener(ObjType* obj, const F& setter,
ScalarChangeListener(ObjType* obj, setter_type setter,
const std::string& propName) const std::string& propName)
: _obj(obj), _setter(setter) : _obj(obj), _setter(setter)
{ {
@@ -359,7 +502,7 @@ public:
} }
void valueChanged(SGPropertyNode* node) void valueChanged(SGPropertyNode* node)
{ {
_obj->*setter(node->getValue<OSGParamType>()); _setter(_obj.get(), node->getValue<OSGParamType>());
} }
void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot)
{ {
@@ -371,7 +514,7 @@ public:
} }
private: private:
osg::ref_ptr<ObjType> _obj; osg::ref_ptr<ObjType> _obj;
setter_type _setter; F _setter;
std::string* _propName; std::string* _propName;
}; };
@@ -382,11 +525,12 @@ class EffectExtendedPropListener : public InitializeWhenAdded,
public: public:
template<typename Itr> template<typename Itr>
EffectExtendedPropListener(const Func& func, EffectExtendedPropListener(const Func& func,
const std::string& propName, Itr childNamesBegin, const std::string* propName, Itr childNamesBegin,
Itr childNamesEnd) Itr childNamesEnd)
: _func(func) : _propName(0), _func(func)
{ {
_propName = new std::string(propName); if (propName)
_propName = new std::string(*propName);
_childNames = new std::vector<std::string>(childNamesBegin, _childNames = new std::vector<std::string>(childNamesBegin,
childNamesEnd); childNamesEnd);
} }
@@ -397,7 +541,11 @@ public:
} }
void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot)
{ {
SGPropertyNode* parent = propRoot->getNode(*_propName, true); SGPropertyNode* parent = 0;
if (_propName)
parent = propRoot->getNode(*_propName, true);
else
parent = propRoot;
_propListener _propListener
= new ExtendedPropListener<T, Func>(parent, _childNames->begin(), = new ExtendedPropListener<T, Func>(parent, _childNames->begin(),
_childNames->end(), _childNames->end(),
@@ -414,6 +562,15 @@ private:
Func _func; Func _func;
}; };
template<typename T, typename Func, typename Itr>
Effect::Updater*
new_EEPropListener(const Func& func, const std::string* propName,
const Itr& namesBegin, const Itr& namesEnd)
{
return new EffectExtendedPropListener<T, Func>
(func, 0, namesBegin, namesEnd);
}
/** /**
* Initialize the value and the possible updating of an effect * Initialize the value and the possible updating of an effect
* attribute. If the value is specified directly, set it. Otherwise, * attribute. If the value is specified directly, set it. Otherwise,
@@ -422,52 +579,97 @@ private:
* own <use> tag referring to a property in the global property tree; * own <use> tag referring to a property in the global property tree;
* install a change listener that will set the attribute when the * install a change listener that will set the attribute when the
* property changes. * property changes.
*
* For relative property names, the property root found in options is
* used.
*/ */
template<typename ObjType, typename OSGParamType> template<typename OSGParamType, typename ObjType, typename F>
void void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj, initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
void (ObjType::*setter)(const OSGParamType)) const F& setter, const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
if (!valProp) if (!valProp)
return; return;
if (valProp->nChildren() == 0) { if (valProp->nChildren() == 0) {
obj->*setter(valProp->getValue<OSGParamType>()); setter(obj, valProp->getValue<OSGParamType>());
} else { } else {
std::string propName = getGlobalProperty(prop); std::string propName = getGlobalProperty(prop, options);
ScalarChangeListener<ObjType, OSGParamType>* listener ScalarChangeListener<OSGParamType, ObjType, F>* listener
= new ScalarChangeListener<ObjType, OSGParamType>(obj, setter, = new ScalarChangeListener<OSGParamType, ObjType, F>(obj, setter,
propName); propName);
effect->addUpdater(listener); effect->addUpdater(listener);
} }
} }
template<typename ObjType, typename OSGParamType, typename NameItrType> template<typename OSGParamType, typename ObjType, typename SetterReturn>
inline void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
SetterReturn (ObjType::*setter)(const OSGParamType),
const SGReaderWriterXMLOptions* options)
{
initFromParameters<OSGParamType>(effect, prop, obj,
boost::bind(setter, _1, _2), options);
}
/*
* Initialize vector parameters from individual properties.
* The parameter may be updated at runtime.
*
* If the value is specified directly, set it. Otherwise, use the
* <use> tag to look at the parameters. Again, if there is a value
* there set it directly. Otherwise, the parameter contains one or several
* <use> tags. If there is one tag, it is a property that is the root
* for the values needed to update the parameter; nameIter holds the
* names of the properties relative to the root. If there are several
* <use> tags, they each hold the name of the property holding the
* value for the corresponding vector member.
*
* Install a change listener that will set the attribute when the
* property changes.
*
* For relative property names, the property root found in options is
* used.
*/
template<typename OSGParamType, typename ObjType, typename NameItrType,
typename F>
void void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj, initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
void (ObjType::*setter)(const OSGParamType&), const F& setter,
NameItrType nameItr) NameItrType nameItr, const SGReaderWriterXMLOptions* options)
{ {
typedef typename OSGBridge<OSGParamType>::sg_type sg_type; typedef typename Bridge<OSGParamType>::sg_type sg_type;
const int numComponents = props::NumComponents<sg_type>::num_components;
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
if (!valProp) if (!valProp)
return; return;
if (valProp->nChildren() == 0) { if (valProp->nChildren() == 0) { // Has <use>?
(obj->*setter)(OSGBridge<OSGParamType> setter(obj, Bridge<OSGParamType>::get(valProp->getValue<sg_type>()));
::getOsgType(valProp->getValue<sg_type>()));
} else { } else {
string listenPropName = getGlobalProperty(valProp); std::vector<std::string> paramNames
if (listenPropName.empty()) = getVectorProperties(valProp, options,numComponents, nameItr);
return; if (paramNames.empty())
typedef OSGFunctor<ObjType, OSGParamType> Functor; throw BuilderException();
std::vector<std::string>::const_iterator pitr = paramNames.begin();
Effect::Updater* listener Effect::Updater* listener
= new EffectExtendedPropListener<sg_type, Functor> = new_EEPropListener<sg_type>(make_OSGFunctor<OSGParamType>
(Functor(obj, setter), listenPropName, nameItr, (obj, setter),
nameItr + props::NumComponents<sg_type>::num_components); 0, pitr, pitr + numComponents);
effect->addUpdater(listener); effect->addUpdater(listener);
} }
} }
template<typename OSGParamType, typename ObjType, typename NameItrType,
typename SetterReturn>
inline void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
SetterReturn (ObjType::*setter)(const OSGParamType&),
NameItrType nameItr, const SGReaderWriterXMLOptions* options)
{
initFromParameters<OSGParamType>(effect, prop, obj,
boost::bind(setter, _1, _2), nameItr,
options);
}
extern const char* colorFields[]; extern const char* colorFields[];
} }
} }
+21 -16
View File
@@ -35,6 +35,7 @@
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp> #include <boost/tuple/tuple_comparison.hpp>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx> #include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx> #include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
@@ -50,13 +51,14 @@ using namespace osg;
using namespace effect; using namespace effect;
TexEnvCombine* buildTexEnvCombine(Effect* effect, TexEnvCombine* buildTexEnvCombine(Effect* effect,
const SGPropertyNode* envProp); const SGPropertyNode* envProp,
const SGReaderWriterXMLOptions* options);
TexGen* buildTexGen(Effect* Effect, const SGPropertyNode* tgenProp); TexGen* buildTexGen(Effect* Effect, const SGPropertyNode* tgenProp);
// Hack to force inclusion of TextureBuilder.cxx in library // Hack to force inclusion of TextureBuilder.cxx in library
osg::Texture* TextureBuilder::buildFromType(Effect* effect, const string& type, osg::Texture* TextureBuilder::buildFromType(Effect* effect, const string& type,
const SGPropertyNode*props, const SGPropertyNode*props,
const osgDB::ReaderWriter::Options* const SGReaderWriterXMLOptions*
options) options)
{ {
return EffectBuilder<Texture>::buildFromType(effect, type, props, options); return EffectBuilder<Texture>::buildFromType(effect, type, props, options);
@@ -98,7 +100,7 @@ TexEnv* buildTexEnv(Effect* effect, const SGPropertyNode* prop)
void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass, void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -141,7 +143,8 @@ void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass,
} }
const SGPropertyNode* combineProp = prop->getChild("texenv-combine"); const SGPropertyNode* combineProp = prop->getChild("texenv-combine");
TexEnvCombine* combiner = 0; TexEnvCombine* combiner = 0;
if (combineProp && ((combiner = buildTexEnvCombine(effect, combineProp)))) if (combineProp && ((combiner = buildTexEnvCombine(effect, combineProp,
options))))
pass->setTextureAttributeAndModes(unit, combiner); pass->setTextureAttributeAndModes(unit, combiner);
const SGPropertyNode* tgenProp = prop->getChild("texgen"); const SGPropertyNode* tgenProp = prop->getChild("texgen");
TexGen* tgen = 0; TexGen* tgen = 0;
@@ -177,7 +180,7 @@ EffectPropertyMap<Texture::WrapMode> wrapModes(wrapModesInit);
TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props, TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props,
const osgDB::ReaderWriter::Options* options, const SGReaderWriterXMLOptions* options,
const string& texType) const string& texType)
{ {
Texture::FilterMode minFilter = Texture::LINEAR_MIPMAP_LINEAR; Texture::FilterMode minFilter = Texture::LINEAR_MIPMAP_LINEAR;
@@ -213,7 +216,7 @@ TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props,
} }
void setAttrs(const TexTuple& attrs, Texture* tex, void setAttrs(const TexTuple& attrs, Texture* tex,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const string& imageName = attrs.get<0>(); const string& imageName = attrs.get<0>();
if (imageName.empty()) { if (imageName.empty()) {
@@ -253,7 +256,7 @@ class TexBuilder : public TextureBuilder
public: public:
TexBuilder(const string& texType) : _type(texType) {} TexBuilder(const string& texType) : _type(texType) {}
Texture* build(Effect* effect, const SGPropertyNode*, Texture* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
protected: protected:
typedef map<TexTuple, ref_ptr<T> > TexMap; typedef map<TexTuple, ref_ptr<T> > TexMap;
TexMap texMap; TexMap texMap;
@@ -262,7 +265,7 @@ protected:
template<typename T> template<typename T>
Texture* TexBuilder<T>::build(Effect* effect, const SGPropertyNode* props, Texture* TexBuilder<T>::build(Effect* effect, const SGPropertyNode* props,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
TexTuple attrs = makeTexTuple(effect, props, options, _type); TexTuple attrs = makeTexTuple(effect, props, options, _type);
typename TexMap::iterator itr = texMap.find(attrs); typename TexMap::iterator itr = texMap.find(attrs);
@@ -286,11 +289,11 @@ class WhiteTextureBuilder : public TextureBuilder
{ {
public: public:
Texture* build(Effect* effect, const SGPropertyNode*, Texture* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
Texture* WhiteTextureBuilder::build(Effect* effect, const SGPropertyNode*, Texture* WhiteTextureBuilder::build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
return StateAttributeFactory::instance()->getWhiteTexture(); return StateAttributeFactory::instance()->getWhiteTexture();
} }
@@ -304,11 +307,11 @@ class TransparentTextureBuilder : public TextureBuilder
{ {
public: public:
Texture* build(Effect* effect, const SGPropertyNode*, Texture* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
Texture* TransparentTextureBuilder::build(Effect* effect, const SGPropertyNode*, Texture* TransparentTextureBuilder::build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
return StateAttributeFactory::instance()->getTransparentTexture(); return StateAttributeFactory::instance()->getTransparentTexture();
} }
@@ -368,14 +371,14 @@ class NoiseBuilder : public TextureBuilder
{ {
public: public:
Texture* build(Effect* effect, const SGPropertyNode*, Texture* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
protected: protected:
typedef map<int, ref_ptr<Texture3D> > NoiseMap; typedef map<int, ref_ptr<Texture3D> > NoiseMap;
NoiseMap _noises; NoiseMap _noises;
}; };
Texture* NoiseBuilder::build(Effect* effect, const SGPropertyNode* props, Texture* NoiseBuilder::build(Effect* effect, const SGPropertyNode* props,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
int texSize = 64; int texSize = 64;
const SGPropertyNode* sizeProp = getEffectPropertyChild(effect, props, const SGPropertyNode* sizeProp = getEffectPropertyChild(effect, props,
@@ -443,7 +446,8 @@ EffectNameValue<TexEnvCombine::OperandParam> opParamInit[] =
EffectPropertyMap<TexEnvCombine::OperandParam> operandParams(opParamInit); EffectPropertyMap<TexEnvCombine::OperandParam> operandParams(opParamInit);
TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp) TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp,
const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, envProp)) if (!isAttributeActive(effect, envProp))
return 0; return 0;
@@ -538,7 +542,8 @@ TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp)
const SGPropertyNode* colorNode = envProp->getChild("constant-color"); const SGPropertyNode* colorNode = envProp->getChild("constant-color");
if (colorNode) if (colorNode)
initFromParameters(effect, colorNode, result, initFromParameters(effect, colorNode, result,
&TexEnvCombine::setConstantColor, colorFields); &TexEnvCombine::setConstantColor, colorFields,
options);
return result; return result;
} }
+2 -2
View File
@@ -29,13 +29,13 @@ public:
// Hack to force inclusion of TextureBuilder.cxx in library // Hack to force inclusion of TextureBuilder.cxx in library
static osg::Texture* buildFromType(Effect* effect, const std::string& type, static osg::Texture* buildFromType(Effect* effect, const std::string& type,
const SGPropertyNode*props, const SGPropertyNode*props,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
struct TextureUnitBuilder : public PassAttributeBuilder struct TextureUnitBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
+3 -2
View File
@@ -31,6 +31,7 @@
#include <osgDB/Registry> #include <osgDB/Registry>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx> #include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/util/SplicingVisitor.hxx> #include <simgear/scene/util/SplicingVisitor.hxx>
@@ -116,7 +117,7 @@ void mergePropertyTrees(SGPropertyNode* resultNode,
Effect* makeEffect(const string& name, Effect* makeEffect(const string& name,
bool realizeTechniques, bool realizeTechniques,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
{ {
OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(effectMutex); OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(effectMutex);
@@ -159,7 +160,7 @@ Effect* makeEffect(const string& name,
Effect* makeEffect(SGPropertyNode* prop, Effect* makeEffect(SGPropertyNode* prop,
bool realizeTechniques, bool realizeTechniques,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
// Give default names to techniques and passes // Give default names to techniques and passes
vector<SGPropertyNode_ptr> techniques = prop->getChildren("technique"); vector<SGPropertyNode_ptr> techniques = prop->getChildren("technique");
+21 -7
View File
@@ -49,6 +49,7 @@
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sgstream.hxx> #include <simgear/misc/sgstream.hxx>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/scene/model/model.hxx> #include <simgear/scene/model/model.hxx>
#include <simgear/scene/util/RenderConstants.hxx> #include <simgear/scene/util/RenderConstants.hxx>
@@ -68,12 +69,12 @@ using namespace simgear;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
SGMaterial::_internal_state::_internal_state(Effect *e, const string &t, bool l, SGMaterial::_internal_state::_internal_state(Effect *e, const string &t, bool l,
const osgDB::ReaderWriter::Options* o ) : const SGReaderWriterXMLOptions* o)
effect(e), texture_path(t), effect_realized(l), options(o) : effect(e), texture_path(t), effect_realized(l), options(o)
{ {
} }
SGMaterial::SGMaterial( const osgDB::ReaderWriter::Options* options, SGMaterial::SGMaterial( const SGReaderWriterXMLOptions* options,
const SGPropertyNode *props ) const SGPropertyNode *props )
{ {
init(); init();
@@ -81,6 +82,17 @@ SGMaterial::SGMaterial( const osgDB::ReaderWriter::Options* options,
buildEffectProperties(options); buildEffectProperties(options);
} }
SGMaterial::SGMaterial( const osgDB::ReaderWriter::Options* options,
const SGPropertyNode *props )
{
osg::ref_ptr<const SGReaderWriterXMLOptions> sgOptions;
if (options)
sgOptions = new SGReaderWriterXMLOptions(*options);
init();
read_properties( sgOptions.get(), props );
buildEffectProperties(sgOptions.get());
}
SGMaterial::~SGMaterial (void) SGMaterial::~SGMaterial (void)
{ {
} }
@@ -91,7 +103,7 @@ SGMaterial::~SGMaterial (void)
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
void void
SGMaterial::read_properties(const osgDB::ReaderWriter::Options* options, SGMaterial::read_properties(const SGReaderWriterXMLOptions* options,
const SGPropertyNode *props) const SGPropertyNode *props)
{ {
// Gather the path(s) to the texture(s) // Gather the path(s) to the texture(s)
@@ -245,10 +257,12 @@ Effect* SGMaterial::get_effect(int n)
return _status[i].effect.get(); return _status[i].effect.get();
} }
void SGMaterial::buildEffectProperties(const osgDB::ReaderWriter::Options* void SGMaterial::buildEffectProperties(const SGReaderWriterXMLOptions* options)
options)
{ {
using namespace osg; using namespace osg;
ref_ptr<SGReaderWriterXMLOptions> xmlOptions;
if (options)
xmlOptions = new SGReaderWriterXMLOptions(*options);
ref_ptr<SGMaterialUserData> user = new SGMaterialUserData(this); ref_ptr<SGMaterialUserData> user = new SGMaterialUserData(this);
SGPropertyNode_ptr propRoot = new SGPropertyNode(); SGPropertyNode_ptr propRoot = new SGPropertyNode();
makeChild(propRoot, "inherits-from")->setStringValue(effect); makeChild(propRoot, "inherits-from")->setStringValue(effect);
@@ -279,7 +293,7 @@ void SGMaterial::buildEffectProperties(const osgDB::ReaderWriter::Options*
->setStringValue(wrapu ? "repeat" : "clamp"); ->setStringValue(wrapu ? "repeat" : "clamp");
makeChild(texProp, "wrap-t") makeChild(texProp, "wrap-t")
->setStringValue(wrapv ? "repeat" : "clamp"); ->setStringValue(wrapv ? "repeat" : "clamp");
matState.effect = makeEffect(effectProp, false, options); matState.effect = makeEffect(effectProp, false, xmlOptions.get());
matState.effect->setUserData(user.get()); matState.effect->setUserData(user.get());
} }
} }
+7 -5
View File
@@ -39,13 +39,13 @@
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <osgDB/ReaderWriter>
namespace osg namespace osg
{ {
class StateSet; class StateSet;
} }
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx> #include <simgear/scene/util/SGSceneFeatures.hxx>
@@ -87,6 +87,8 @@ public:
*/ */
SGMaterial( const osgDB::ReaderWriter::Options*, const SGPropertyNode *props); SGMaterial( const osgDB::ReaderWriter::Options*, const SGPropertyNode *props);
SGMaterial(const simgear::SGReaderWriterXMLOptions*,
const SGPropertyNode *props);
/** /**
* Destructor. * Destructor.
*/ */
@@ -271,11 +273,11 @@ protected:
struct _internal_state { struct _internal_state {
_internal_state(simgear::Effect *e, const std::string &t, bool l, _internal_state(simgear::Effect *e, const std::string &t, bool l,
const osgDB::ReaderWriter::Options *o); const simgear::SGReaderWriterXMLOptions *o);
osg::ref_ptr<simgear::Effect> effect; osg::ref_ptr<simgear::Effect> effect;
std::string texture_path; std::string texture_path;
bool effect_realized; bool effect_realized;
osg::ref_ptr<const osgDB::ReaderWriter::Options> options; osg::ref_ptr<const simgear::SGReaderWriterXMLOptions> options;
}; };
private: private:
@@ -361,9 +363,9 @@ private:
// Internal constructors and methods. // Internal constructors and methods.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void read_properties(const osgDB::ReaderWriter::Options* options, void read_properties(const simgear::SGReaderWriterXMLOptions* options,
const SGPropertyNode *props); const SGPropertyNode *props);
void buildEffectProperties(const osgDB::ReaderWriter::Options* options); void buildEffectProperties(const simgear::SGReaderWriterXMLOptions* options);
}; };
@@ -18,7 +18,7 @@
#ifndef SGREADERWRITERXMLOPTIONS_HXX #ifndef SGREADERWRITERXMLOPTIONS_HXX
#define SGREADERWRITERXMLOPTIONS_HXX 1 #define SGREADERWRITERXMLOPTIONS_HXX 1
#include <osgDB/ReaderWriter> #include <osgDB/Registry>
#include <simgear/scene/model/modellib.hxx> #include <simgear/scene/model/modellib.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
+4 -3
View File
@@ -33,6 +33,7 @@
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/props/condition.hxx> #include <simgear/props/condition.hxx>
#include "SGReaderWriterXMLOptions.hxx"
#include "model.hxx" #include "model.hxx"
using std::vector; using std::vector;
@@ -209,7 +210,7 @@ class MakeEffectVisitor : public SplicingVisitor
public: public:
typedef std::map<string, SGPropertyNode_ptr> EffectMap; typedef std::map<string, SGPropertyNode_ptr> EffectMap;
using SplicingVisitor::apply; using SplicingVisitor::apply;
MakeEffectVisitor(const osgDB::ReaderWriter::Options* options = 0) MakeEffectVisitor(const SGReaderWriterXMLOptions* options = 0)
: _options(options) : _options(options)
{ {
} }
@@ -225,7 +226,7 @@ public:
protected: protected:
EffectMap _effectMap; EffectMap _effectMap;
SGPropertyNode_ptr _currentEffectParent; SGPropertyNode_ptr _currentEffectParent;
osg::ref_ptr<const osgDB::ReaderWriter::Options> _options; osg::ref_ptr<const SGReaderWriterXMLOptions> _options;
}; };
void MakeEffectVisitor::apply(osg::Group& node) void MakeEffectVisitor::apply(osg::Group& node)
@@ -302,7 +303,7 @@ protected:
ref_ptr<Node> instantiateEffects(osg::Node* modelGroup, ref_ptr<Node> instantiateEffects(osg::Node* modelGroup,
PropertyList& effectProps, PropertyList& effectProps,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
SGPropertyNode_ptr defaultEffectPropRoot; SGPropertyNode_ptr defaultEffectPropRoot;
MakeEffectVisitor visitor(options); MakeEffectVisitor visitor(options);
+7 -2
View File
@@ -23,6 +23,11 @@
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/scene/util/NodeAndDrawableVisitor.hxx> #include <simgear/scene/util/NodeAndDrawableVisitor.hxx>
namespace simgear
{
class SGReaderWriterXMLOptions;
}
osg::Texture2D* osg::Texture2D*
SGLoadTexture2D(bool staticTexture, const std::string& path, SGLoadTexture2D(bool staticTexture, const std::string& path,
const osgDB::ReaderWriter::Options* options = 0, const osgDB::ReaderWriter::Options* options = 0,
@@ -97,7 +102,7 @@ public:
osg::ref_ptr<osg::Node> osg::ref_ptr<osg::Node>
instantiateEffects(osg::Node* model, instantiateEffects(osg::Node* model,
PropertyList& effectProps, PropertyList& effectProps,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
/** /**
* Transform an OSG subgraph by substituting the Effects and * Transform an OSG subgraph by substituting the Effects and
@@ -110,7 +115,7 @@ instantiateEffects(osg::Node* model,
inline osg::ref_ptr<osg::Node> inline osg::ref_ptr<osg::Node>
instantiateEffects(osg::Node* model, instantiateEffects(osg::Node* model,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
PropertyList effectProps; PropertyList effectProps;
return instantiateEffects(model, effectProps, options); return instantiateEffects(model, effectProps, options);
+6 -2
View File
@@ -71,8 +71,12 @@ osg::Node* loadFile(const string& path, osgDB::ReaderWriter::Options* options)
ref_ptr<Node> model = readRefNodeFile(path, options); ref_ptr<Node> model = readRefNodeFile(path, options);
if (!model) if (!model)
return 0; return 0;
if (boost::iends_with(path, ".ac")) if (boost::iends_with(path, ".ac")) {
model = instantiateEffects(model.get(), options); ref_ptr<SGReaderWriterXMLOptions> sgOptions;
if (options)
sgOptions = new SGReaderWriterXMLOptions(*options);
model = instantiateEffects(model.get(), sgOptions.get());
}
return model.release(); return model.release();
} }
} }
+5 -2
View File
@@ -46,6 +46,7 @@
#include <simgear/misc/PathOptions.hxx> #include <simgear/misc/PathOptions.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/scene/model/model.hxx> #include <simgear/scene/model/model.hxx>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx> #include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/scene/util/SGUpdateVisitor.hxx> #include <simgear/scene/util/SGUpdateVisitor.hxx>
@@ -108,9 +109,11 @@ SGNewCloud::SGNewCloud(string type,
"texture"), "texture"),
"image"), "image"),
texture); texture);
osg::ref_ptr<osgDB::ReaderWriter::Options> options ref_ptr<osgDB::ReaderWriter::Options> options
= makeOptionsFromPath(tex_path); = makeOptionsFromPath(tex_path);
if ((effect = makeEffect(pcloudEffect, true, options))) ref_ptr<SGReaderWriterXMLOptions> sgOptions
= new SGReaderWriterXMLOptions(*options.get());
if ((effect = makeEffect(pcloudEffect, true, sgOptions.get())))
effectMap.insert(EffectMap::value_type(texture, effect)); effectMap.insert(EffectMap::value_type(texture, effect));
} else { } else {
effect = iter->second.get(); effect = iter->second.get();