Merge branch 'timoore/effects-anim-rebase' into next
This commit is contained in:
@@ -1027,17 +1027,22 @@ SGPropertyNode::getDisplayName (bool simplify) const
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
string
|
||||
SGPropertyNode::getPath (bool simplify) const
|
||||
{
|
||||
// Calculate the complete path only once.
|
||||
if (_parent != 0 && _path.empty()) {
|
||||
_path = _parent->getPath(simplify);
|
||||
_path += '/';
|
||||
_path += getDisplayName(simplify);
|
||||
typedef std::vector<SGConstPropertyNode_ptr> PList;
|
||||
PList pathList;
|
||||
for (const SGPropertyNode* node = this; node->_parent; node = node->_parent)
|
||||
pathList.push_back(node);
|
||||
string result;
|
||||
for (PList::reverse_iterator itr = pathList.rbegin(),
|
||||
rend = pathList.rend();
|
||||
itr != rend;
|
||||
++itr) {
|
||||
result += '/';
|
||||
result += (*itr)->getDisplayName(simplify);
|
||||
}
|
||||
|
||||
return _path.c_str();
|
||||
return result;
|
||||
}
|
||||
|
||||
props::Type
|
||||
|
||||
@@ -994,7 +994,7 @@ public:
|
||||
/**
|
||||
* 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 _removedChildren;
|
||||
std::vector<hash_table *> _linkedNodes;
|
||||
mutable std::string _path;
|
||||
mutable std::string _buffer;
|
||||
hash_table * _path_cache;
|
||||
simgear::props::Type _type;
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/Registry>
|
||||
|
||||
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
|
||||
#include <simgear/scene/tgdb/userdata.hxx>
|
||||
#include <simgear/scene/util/SGSceneFeatures.hxx>
|
||||
#include <simgear/scene/util/StateAttributeFactory.hxx>
|
||||
@@ -143,7 +144,7 @@ Effect::~Effect()
|
||||
}
|
||||
|
||||
void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
Pass* pass = new 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)
|
||||
{
|
||||
if (prop->nChildren() == 0) {
|
||||
@@ -188,12 +193,12 @@ osg::Vec4f getColor(const SGPropertyNode* prop)
|
||||
struct LightingBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options);
|
||||
const SGReaderWriterXMLOptions* options);
|
||||
};
|
||||
|
||||
void LightingBuilder::buildAttribute(Effect* effect, Pass* pass,
|
||||
const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
|
||||
if (!realProp)
|
||||
@@ -207,7 +212,7 @@ InstallAttributeBuilder<LightingBuilder> installLighting("lighting");
|
||||
struct ShadeModelBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
|
||||
if (!realProp)
|
||||
@@ -229,7 +234,7 @@ InstallAttributeBuilder<ShadeModelBuilder> installShadeModel("shade-model");
|
||||
struct CullFaceBuilder : PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
|
||||
if (!realProp) {
|
||||
@@ -257,7 +262,7 @@ InstallAttributeBuilder<CullFaceBuilder> installCullFace("cull-face");
|
||||
struct ColorMaskBuilder : PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
|
||||
if (!realProp)
|
||||
@@ -284,7 +289,7 @@ EffectPropertyMap<StateSet::RenderingHint> renderingHints(renderingHintInit);
|
||||
struct HintBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
|
||||
if (!realProp)
|
||||
@@ -300,7 +305,7 @@ InstallAttributeBuilder<HintBuilder> installHint("rendering-hint");
|
||||
struct RenderBinBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
if (!isAttributeActive(effect, prop))
|
||||
return;
|
||||
@@ -327,7 +332,7 @@ InstallAttributeBuilder<RenderBinBuilder> installRenderBin("render-bin");
|
||||
struct MaterialBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options);
|
||||
const SGReaderWriterXMLOptions* options);
|
||||
};
|
||||
|
||||
EffectNameValue<Material::ColorMode> colorModeInit[] =
|
||||
@@ -343,7 +348,7 @@ EffectPropertyMap<Material::ColorMode> colorModes(colorModeInit);
|
||||
|
||||
void MaterialBuilder::buildAttribute(Effect* effect, Pass* pass,
|
||||
const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
if (!isAttributeActive(effect, prop))
|
||||
return;
|
||||
@@ -413,7 +418,7 @@ EffectPropertyMap<BlendFunc::BlendFuncMode> blendFuncModes(blendFuncModesInit);
|
||||
struct BlendBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
if (!isAttributeActive(effect, prop))
|
||||
return;
|
||||
@@ -526,7 +531,7 @@ EffectPropertyMap<Stencil::Operation> stencilOperation(stencilOperationInit);
|
||||
struct StencilBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
if (!isAttributeActive(effect, prop))
|
||||
return;
|
||||
@@ -604,7 +609,7 @@ alphaComparison(alphaComparisonInit);
|
||||
struct AlphaTestBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
if (!isAttributeActive(effect, prop))
|
||||
return;
|
||||
@@ -715,12 +720,12 @@ void reload_shaders()
|
||||
struct ShaderProgramBuilder : PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options);
|
||||
const SGReaderWriterXMLOptions* options);
|
||||
};
|
||||
|
||||
void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
|
||||
const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options*
|
||||
const SGReaderWriterXMLOptions*
|
||||
options)
|
||||
{
|
||||
using namespace boost;
|
||||
@@ -807,15 +812,18 @@ EffectNameValue<Uniform::Type> uniformTypesInit[] =
|
||||
{"float-vec3", Uniform::FLOAT_VEC3},
|
||||
{"float-vec4", Uniform::FLOAT_VEC4},
|
||||
{"sampler-1d", Uniform::SAMPLER_1D},
|
||||
{"sampler-1d-shadow", Uniform::SAMPLER_1D_SHADOW},
|
||||
{"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);
|
||||
|
||||
struct UniformBuilder :public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
if (!isAttributeActive(effect, prop))
|
||||
return;
|
||||
@@ -861,18 +869,29 @@ struct UniformBuilder :public PassAttributeBuilder
|
||||
uniform->setType(uniformType);
|
||||
switch (uniformType) {
|
||||
case Uniform::FLOAT:
|
||||
uniform->set(valProp->getValue<float>());
|
||||
initFromParameters(effect, valProp, uniform.get(),
|
||||
static_cast<bool (Uniform::*)(float)>(&Uniform::set),
|
||||
options);
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
case Uniform::SAMPLER_1D:
|
||||
case Uniform::SAMPLER_2D:
|
||||
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;
|
||||
default: // avoid compiler warning
|
||||
break;
|
||||
@@ -889,7 +908,7 @@ InstallAttributeBuilder<UniformBuilder> installUniform("uniform");
|
||||
struct NameBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
// name can't use <use>
|
||||
string name = prop->getStringValue();
|
||||
@@ -911,7 +930,7 @@ EffectPropertyMap<PolygonMode::Mode> polygonModeModes(polygonModeModesInit);
|
||||
struct PolygonModeBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
if (!isAttributeActive(effect, prop))
|
||||
return;
|
||||
@@ -939,7 +958,7 @@ InstallAttributeBuilder<PolygonModeBuilder> installPolygonMode("polygon-mode");
|
||||
struct VertexProgramTwoSideBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
|
||||
if (!realProp)
|
||||
@@ -956,7 +975,7 @@ installTwoSide("vertex-program-two-side");
|
||||
struct VertexProgramPointSizeBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
|
||||
if (!realProp)
|
||||
@@ -986,7 +1005,7 @@ EffectPropertyMap<Depth::Function> depthFunction(depthFunctionInit);
|
||||
struct DepthBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
if (!isAttributeActive(effect, prop))
|
||||
return;
|
||||
@@ -1017,7 +1036,7 @@ struct DepthBuilder : public PassAttributeBuilder
|
||||
InstallAttributeBuilder<DepthBuilder> installDepth("depth");
|
||||
|
||||
void buildTechnique(Effect* effect, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
Technique* tniq = new Technique;
|
||||
effect->techniques.push_back(tniq);
|
||||
@@ -1123,7 +1142,7 @@ bool makeParametersFromStateSet(SGPropertyNode* effectRoot, const StateSet* ss)
|
||||
|
||||
// Walk the techniques property tree, building techniques and
|
||||
// passes.
|
||||
bool Effect::realizeTechniques(const osgDB::ReaderWriter::Options* options)
|
||||
bool Effect::realizeTechniques(const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
if (_isRealized)
|
||||
return true;
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace simgear
|
||||
{
|
||||
class Technique;
|
||||
class Effect;
|
||||
class SGReaderWriterXMLOptions;
|
||||
|
||||
/**
|
||||
* Object to be initialized at some point after an effect -- and its
|
||||
@@ -89,7 +90,7 @@ public:
|
||||
/**
|
||||
* 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
|
||||
* deleted. Updaters arrange to be run by listening on properties
|
||||
@@ -144,7 +145,7 @@ protected:
|
||||
Cache* _cache;
|
||||
friend size_t hash_value(const Key& key);
|
||||
friend Effect* makeEffect(SGPropertyNode* prop, bool realizeTechniques,
|
||||
const osgDB::ReaderWriter::Options* options);
|
||||
const SGReaderWriterXMLOptions* options);
|
||||
bool _isRealized;
|
||||
};
|
||||
// Automatic support for boost hash function
|
||||
@@ -153,11 +154,11 @@ size_t hash_value(const Effect::Key&);
|
||||
|
||||
Effect* makeEffect(const std::string& name,
|
||||
bool realizeTechniques,
|
||||
const osgDB::ReaderWriter::Options* options = 0);
|
||||
const SGReaderWriterXMLOptions* options = 0);
|
||||
|
||||
Effect* makeEffect(SGPropertyNode* prop,
|
||||
bool realizeTechniques,
|
||||
const osgDB::ReaderWriter::Options* options = 0);
|
||||
const SGReaderWriterXMLOptions* options = 0);
|
||||
|
||||
bool makeParametersFromStateSet(SGPropertyNode* paramRoot,
|
||||
const osg::StateSet* ss);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
|
||||
#include <simgear/scene/tgdb/userdata.hxx>
|
||||
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
@@ -41,13 +42,29 @@ const SGPropertyNode* getEffectPropertyChild(Effect* effect,
|
||||
return getEffectPropertyNode(effect, child);
|
||||
}
|
||||
|
||||
string getGlobalProperty(const SGPropertyNode* prop)
|
||||
string getGlobalProperty(const SGPropertyNode* prop,
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
if (!prop)
|
||||
return string();
|
||||
const SGPropertyNode* useProp = prop->getChild("use");
|
||||
if (!useProp)
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
#include <simgear/props/AtomicChangeListener.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
#include <simgear/structure/Singleton.hxx>
|
||||
@@ -46,6 +47,7 @@ namespace simgear
|
||||
{
|
||||
class Effect;
|
||||
class Pass;
|
||||
class SGReaderWriterXMLOptions;
|
||||
|
||||
/**
|
||||
* Builder that returns an object, probably an OSG object.
|
||||
@@ -56,10 +58,10 @@ class EffectBuilder : public SGReferenced
|
||||
public:
|
||||
virtual ~EffectBuilder() {}
|
||||
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,
|
||||
const SGPropertyNode*props,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
BuilderMap& builderMap = getMap();
|
||||
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));
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
@@ -201,6 +218,42 @@ void findAttr(const effect::EffectPropertyMap<T>& pMap,
|
||||
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>
|
||||
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
|
||||
* 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
|
||||
{
|
||||
@@ -255,7 +346,7 @@ protected:
|
||||
public:
|
||||
virtual void buildAttribute(Effect* effect, Pass* pass,
|
||||
const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
= 0;
|
||||
static PassAttributeBuilder* find(const std::string& str)
|
||||
{
|
||||
@@ -289,64 +380,116 @@ bool isAttributeActive(Effect* effect, const SGPropertyNode* prop);
|
||||
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>
|
||||
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<>
|
||||
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<>
|
||||
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<>
|
||||
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;
|
||||
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&))
|
||||
OSGFunctor(Obj* obj, const 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;
|
||||
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
|
||||
: public SGPropertyChangeListener, public InitializeWhenAdded,
|
||||
public Effect::Updater
|
||||
{
|
||||
public:
|
||||
typedef void (ObjType::*setter_type)(const OSGParamType);
|
||||
ScalarChangeListener(ObjType* obj, setter_type setter,
|
||||
ScalarChangeListener(ObjType* obj, const F& setter,
|
||||
const std::string& propName)
|
||||
: _obj(obj), _setter(setter)
|
||||
{
|
||||
@@ -359,7 +502,7 @@ public:
|
||||
}
|
||||
void valueChanged(SGPropertyNode* node)
|
||||
{
|
||||
_obj->*setter(node->getValue<OSGParamType>());
|
||||
_setter(_obj.get(), node->getValue<OSGParamType>());
|
||||
}
|
||||
void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot)
|
||||
{
|
||||
@@ -371,7 +514,7 @@ public:
|
||||
}
|
||||
private:
|
||||
osg::ref_ptr<ObjType> _obj;
|
||||
setter_type _setter;
|
||||
F _setter;
|
||||
std::string* _propName;
|
||||
};
|
||||
|
||||
@@ -382,11 +525,12 @@ class EffectExtendedPropListener : public InitializeWhenAdded,
|
||||
public:
|
||||
template<typename Itr>
|
||||
EffectExtendedPropListener(const Func& func,
|
||||
const std::string& propName, Itr childNamesBegin,
|
||||
const std::string* propName, Itr childNamesBegin,
|
||||
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,
|
||||
childNamesEnd);
|
||||
}
|
||||
@@ -397,7 +541,11 @@ public:
|
||||
}
|
||||
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
|
||||
= new ExtendedPropListener<T, Func>(parent, _childNames->begin(),
|
||||
_childNames->end(),
|
||||
@@ -414,6 +562,15 @@ private:
|
||||
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
|
||||
* 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;
|
||||
* 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 ObjType, typename OSGParamType>
|
||||
template<typename OSGParamType, typename ObjType, typename F>
|
||||
void
|
||||
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);
|
||||
if (!valProp)
|
||||
return;
|
||||
if (valProp->nChildren() == 0) {
|
||||
obj->*setter(valProp->getValue<OSGParamType>());
|
||||
setter(obj, valProp->getValue<OSGParamType>());
|
||||
} else {
|
||||
std::string propName = getGlobalProperty(prop);
|
||||
ScalarChangeListener<ObjType, OSGParamType>* listener
|
||||
= new ScalarChangeListener<ObjType, OSGParamType>(obj, setter,
|
||||
propName);
|
||||
std::string propName = getGlobalProperty(prop, options);
|
||||
ScalarChangeListener<OSGParamType, ObjType, F>* listener
|
||||
= new ScalarChangeListener<OSGParamType, ObjType, F>(obj, setter,
|
||||
propName);
|
||||
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
|
||||
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
||||
void (ObjType::*setter)(const OSGParamType&),
|
||||
NameItrType nameItr)
|
||||
const F& setter,
|
||||
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);
|
||||
if (!valProp)
|
||||
return;
|
||||
if (valProp->nChildren() == 0) {
|
||||
(obj->*setter)(OSGBridge<OSGParamType>
|
||||
::getOsgType(valProp->getValue<sg_type>()));
|
||||
if (valProp->nChildren() == 0) { // Has <use>?
|
||||
setter(obj, Bridge<OSGParamType>::get(valProp->getValue<sg_type>()));
|
||||
} else {
|
||||
string listenPropName = getGlobalProperty(valProp);
|
||||
if (listenPropName.empty())
|
||||
return;
|
||||
typedef OSGFunctor<ObjType, OSGParamType> Functor;
|
||||
std::vector<std::string> paramNames
|
||||
= getVectorProperties(valProp, options,numComponents, nameItr);
|
||||
if (paramNames.empty())
|
||||
throw BuilderException();
|
||||
std::vector<std::string>::const_iterator pitr = paramNames.begin();
|
||||
Effect::Updater* listener
|
||||
= new EffectExtendedPropListener<sg_type, Functor>
|
||||
(Functor(obj, setter), listenPropName, nameItr,
|
||||
nameItr + props::NumComponents<sg_type>::num_components);
|
||||
= new_EEPropListener<sg_type>(make_OSGFunctor<OSGParamType>
|
||||
(obj, setter),
|
||||
0, pitr, pitr + numComponents);
|
||||
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[];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/tuple/tuple_comparison.hpp>
|
||||
|
||||
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
|
||||
#include <simgear/scene/util/SGSceneFeatures.hxx>
|
||||
#include <simgear/scene/util/StateAttributeFactory.hxx>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
@@ -50,13 +51,14 @@ using namespace osg;
|
||||
using namespace effect;
|
||||
|
||||
TexEnvCombine* buildTexEnvCombine(Effect* effect,
|
||||
const SGPropertyNode* envProp);
|
||||
const SGPropertyNode* envProp,
|
||||
const SGReaderWriterXMLOptions* options);
|
||||
TexGen* buildTexGen(Effect* Effect, const SGPropertyNode* tgenProp);
|
||||
|
||||
// Hack to force inclusion of TextureBuilder.cxx in library
|
||||
osg::Texture* TextureBuilder::buildFromType(Effect* effect, const string& type,
|
||||
const SGPropertyNode*props,
|
||||
const osgDB::ReaderWriter::Options*
|
||||
const SGReaderWriterXMLOptions*
|
||||
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,
|
||||
const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
if (!isAttributeActive(effect, prop))
|
||||
return;
|
||||
@@ -141,7 +143,8 @@ void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass,
|
||||
}
|
||||
const SGPropertyNode* combineProp = prop->getChild("texenv-combine");
|
||||
TexEnvCombine* combiner = 0;
|
||||
if (combineProp && ((combiner = buildTexEnvCombine(effect, combineProp))))
|
||||
if (combineProp && ((combiner = buildTexEnvCombine(effect, combineProp,
|
||||
options))))
|
||||
pass->setTextureAttributeAndModes(unit, combiner);
|
||||
const SGPropertyNode* tgenProp = prop->getChild("texgen");
|
||||
TexGen* tgen = 0;
|
||||
@@ -177,7 +180,7 @@ EffectPropertyMap<Texture::WrapMode> wrapModes(wrapModesInit);
|
||||
|
||||
|
||||
TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props,
|
||||
const osgDB::ReaderWriter::Options* options,
|
||||
const SGReaderWriterXMLOptions* options,
|
||||
const string& texType)
|
||||
{
|
||||
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,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
const string& imageName = attrs.get<0>();
|
||||
if (imageName.empty()) {
|
||||
@@ -253,7 +256,7 @@ class TexBuilder : public TextureBuilder
|
||||
public:
|
||||
TexBuilder(const string& texType) : _type(texType) {}
|
||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
||||
const osgDB::ReaderWriter::Options* options);
|
||||
const SGReaderWriterXMLOptions* options);
|
||||
protected:
|
||||
typedef map<TexTuple, ref_ptr<T> > TexMap;
|
||||
TexMap texMap;
|
||||
@@ -262,7 +265,7 @@ protected:
|
||||
|
||||
template<typename T>
|
||||
Texture* TexBuilder<T>::build(Effect* effect, const SGPropertyNode* props,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
TexTuple attrs = makeTexTuple(effect, props, options, _type);
|
||||
typename TexMap::iterator itr = texMap.find(attrs);
|
||||
@@ -286,11 +289,11 @@ class WhiteTextureBuilder : public TextureBuilder
|
||||
{
|
||||
public:
|
||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
||||
const osgDB::ReaderWriter::Options* options);
|
||||
const SGReaderWriterXMLOptions* options);
|
||||
};
|
||||
|
||||
Texture* WhiteTextureBuilder::build(Effect* effect, const SGPropertyNode*,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
return StateAttributeFactory::instance()->getWhiteTexture();
|
||||
}
|
||||
@@ -304,11 +307,11 @@ class TransparentTextureBuilder : public TextureBuilder
|
||||
{
|
||||
public:
|
||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
||||
const osgDB::ReaderWriter::Options* options);
|
||||
const SGReaderWriterXMLOptions* options);
|
||||
};
|
||||
|
||||
Texture* TransparentTextureBuilder::build(Effect* effect, const SGPropertyNode*,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
return StateAttributeFactory::instance()->getTransparentTexture();
|
||||
}
|
||||
@@ -368,14 +371,14 @@ class NoiseBuilder : public TextureBuilder
|
||||
{
|
||||
public:
|
||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
||||
const osgDB::ReaderWriter::Options* options);
|
||||
const SGReaderWriterXMLOptions* options);
|
||||
protected:
|
||||
typedef map<int, ref_ptr<Texture3D> > NoiseMap;
|
||||
NoiseMap _noises;
|
||||
};
|
||||
|
||||
Texture* NoiseBuilder::build(Effect* effect, const SGPropertyNode* props,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
int texSize = 64;
|
||||
const SGPropertyNode* sizeProp = getEffectPropertyChild(effect, props,
|
||||
@@ -443,7 +446,8 @@ EffectNameValue<TexEnvCombine::OperandParam> 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))
|
||||
return 0;
|
||||
@@ -538,7 +542,8 @@ TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp)
|
||||
const SGPropertyNode* colorNode = envProp->getChild("constant-color");
|
||||
if (colorNode)
|
||||
initFromParameters(effect, colorNode, result,
|
||||
&TexEnvCombine::setConstantColor, colorFields);
|
||||
&TexEnvCombine::setConstantColor, colorFields,
|
||||
options);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,13 +29,13 @@ public:
|
||||
// Hack to force inclusion of TextureBuilder.cxx in library
|
||||
static osg::Texture* buildFromType(Effect* effect, const std::string& type,
|
||||
const SGPropertyNode*props,
|
||||
const osgDB::ReaderWriter::Options* options);
|
||||
const SGReaderWriterXMLOptions* options);
|
||||
};
|
||||
|
||||
struct TextureUnitBuilder : public PassAttributeBuilder
|
||||
{
|
||||
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||
const osgDB::ReaderWriter::Options* options);
|
||||
const SGReaderWriterXMLOptions* options);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <osgDB/Registry>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
|
||||
#include <simgear/props/props_io.hxx>
|
||||
#include <simgear/scene/util/SGSceneFeatures.hxx>
|
||||
#include <simgear/scene/util/SplicingVisitor.hxx>
|
||||
@@ -116,7 +117,7 @@ void mergePropertyTrees(SGPropertyNode* resultNode,
|
||||
|
||||
Effect* makeEffect(const string& name,
|
||||
bool realizeTechniques,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(effectMutex);
|
||||
@@ -159,7 +160,7 @@ Effect* makeEffect(const string& name,
|
||||
|
||||
Effect* makeEffect(SGPropertyNode* prop,
|
||||
bool realizeTechniques,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
// Give default names to techniques and passes
|
||||
vector<SGPropertyNode_ptr> techniques = prop->getChildren("technique");
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/misc/sgstream.hxx>
|
||||
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
|
||||
#include <simgear/props/props_io.hxx>
|
||||
#include <simgear/scene/model/model.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,
|
||||
const osgDB::ReaderWriter::Options* o ) :
|
||||
effect(e), texture_path(t), effect_realized(l), options(o)
|
||||
const SGReaderWriterXMLOptions* 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 )
|
||||
{
|
||||
init();
|
||||
@@ -81,6 +82,17 @@ SGMaterial::SGMaterial( const osgDB::ReaderWriter::Options* 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)
|
||||
{
|
||||
}
|
||||
@@ -91,7 +103,7 @@ SGMaterial::~SGMaterial (void)
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
SGMaterial::read_properties(const osgDB::ReaderWriter::Options* options,
|
||||
SGMaterial::read_properties(const SGReaderWriterXMLOptions* options,
|
||||
const SGPropertyNode *props)
|
||||
{
|
||||
// Gather the path(s) to the texture(s)
|
||||
@@ -245,10 +257,12 @@ Effect* SGMaterial::get_effect(int n)
|
||||
return _status[i].effect.get();
|
||||
}
|
||||
|
||||
void SGMaterial::buildEffectProperties(const osgDB::ReaderWriter::Options*
|
||||
options)
|
||||
void SGMaterial::buildEffectProperties(const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
using namespace osg;
|
||||
ref_ptr<SGReaderWriterXMLOptions> xmlOptions;
|
||||
if (options)
|
||||
xmlOptions = new SGReaderWriterXMLOptions(*options);
|
||||
ref_ptr<SGMaterialUserData> user = new SGMaterialUserData(this);
|
||||
SGPropertyNode_ptr propRoot = new SGPropertyNode();
|
||||
makeChild(propRoot, "inherits-from")->setStringValue(effect);
|
||||
@@ -279,7 +293,7 @@ void SGMaterial::buildEffectProperties(const osgDB::ReaderWriter::Options*
|
||||
->setStringValue(wrapu ? "repeat" : "clamp");
|
||||
makeChild(texProp, "wrap-t")
|
||||
->setStringValue(wrapv ? "repeat" : "clamp");
|
||||
matState.effect = makeEffect(effectProp, false, options);
|
||||
matState.effect = makeEffect(effectProp, false, xmlOptions.get());
|
||||
matState.effect->setUserData(user.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,13 +39,13 @@
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osgDB/ReaderWriter>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class StateSet;
|
||||
}
|
||||
|
||||
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
#include <simgear/scene/util/SGSceneFeatures.hxx>
|
||||
@@ -87,6 +87,8 @@ public:
|
||||
*/
|
||||
SGMaterial( const osgDB::ReaderWriter::Options*, const SGPropertyNode *props);
|
||||
|
||||
SGMaterial(const simgear::SGReaderWriterXMLOptions*,
|
||||
const SGPropertyNode *props);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
@@ -271,11 +273,11 @@ protected:
|
||||
|
||||
struct _internal_state {
|
||||
_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;
|
||||
std::string texture_path;
|
||||
bool effect_realized;
|
||||
osg::ref_ptr<const osgDB::ReaderWriter::Options> options;
|
||||
osg::ref_ptr<const simgear::SGReaderWriterXMLOptions> options;
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -361,9 +363,9 @@ private:
|
||||
// Internal constructors and methods.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
void read_properties(const osgDB::ReaderWriter::Options* options,
|
||||
void read_properties(const simgear::SGReaderWriterXMLOptions* options,
|
||||
const SGPropertyNode *props);
|
||||
void buildEffectProperties(const osgDB::ReaderWriter::Options* options);
|
||||
void buildEffectProperties(const simgear::SGReaderWriterXMLOptions* options);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef SGREADERWRITERXMLOPTIONS_HXX
|
||||
#define SGREADERWRITERXMLOPTIONS_HXX 1
|
||||
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <osgDB/Registry>
|
||||
#include <simgear/scene/model/modellib.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <simgear/props/props_io.hxx>
|
||||
#include <simgear/props/condition.hxx>
|
||||
|
||||
#include "SGReaderWriterXMLOptions.hxx"
|
||||
#include "model.hxx"
|
||||
|
||||
using std::vector;
|
||||
@@ -209,7 +210,7 @@ class MakeEffectVisitor : public SplicingVisitor
|
||||
public:
|
||||
typedef std::map<string, SGPropertyNode_ptr> EffectMap;
|
||||
using SplicingVisitor::apply;
|
||||
MakeEffectVisitor(const osgDB::ReaderWriter::Options* options = 0)
|
||||
MakeEffectVisitor(const SGReaderWriterXMLOptions* options = 0)
|
||||
: _options(options)
|
||||
{
|
||||
}
|
||||
@@ -225,7 +226,7 @@ public:
|
||||
protected:
|
||||
EffectMap _effectMap;
|
||||
SGPropertyNode_ptr _currentEffectParent;
|
||||
osg::ref_ptr<const osgDB::ReaderWriter::Options> _options;
|
||||
osg::ref_ptr<const SGReaderWriterXMLOptions> _options;
|
||||
};
|
||||
|
||||
void MakeEffectVisitor::apply(osg::Group& node)
|
||||
@@ -302,7 +303,7 @@ protected:
|
||||
|
||||
ref_ptr<Node> instantiateEffects(osg::Node* modelGroup,
|
||||
PropertyList& effectProps,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
SGPropertyNode_ptr defaultEffectPropRoot;
|
||||
MakeEffectVisitor visitor(options);
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/scene/util/NodeAndDrawableVisitor.hxx>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
class SGReaderWriterXMLOptions;
|
||||
}
|
||||
|
||||
osg::Texture2D*
|
||||
SGLoadTexture2D(bool staticTexture, const std::string& path,
|
||||
const osgDB::ReaderWriter::Options* options = 0,
|
||||
@@ -97,7 +102,7 @@ public:
|
||||
osg::ref_ptr<osg::Node>
|
||||
instantiateEffects(osg::Node* model,
|
||||
PropertyList& effectProps,
|
||||
const osgDB::ReaderWriter::Options* options);
|
||||
const SGReaderWriterXMLOptions* options);
|
||||
|
||||
/**
|
||||
* Transform an OSG subgraph by substituting the Effects and
|
||||
@@ -110,7 +115,7 @@ instantiateEffects(osg::Node* model,
|
||||
|
||||
inline osg::ref_ptr<osg::Node>
|
||||
instantiateEffects(osg::Node* model,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
{
|
||||
PropertyList effectProps;
|
||||
return instantiateEffects(model, effectProps, options);
|
||||
|
||||
@@ -71,8 +71,12 @@ osg::Node* loadFile(const string& path, osgDB::ReaderWriter::Options* options)
|
||||
ref_ptr<Node> model = readRefNodeFile(path, options);
|
||||
if (!model)
|
||||
return 0;
|
||||
if (boost::iends_with(path, ".ac"))
|
||||
model = instantiateEffects(model.get(), options);
|
||||
if (boost::iends_with(path, ".ac")) {
|
||||
ref_ptr<SGReaderWriterXMLOptions> sgOptions;
|
||||
if (options)
|
||||
sgOptions = new SGReaderWriterXMLOptions(*options);
|
||||
model = instantiateEffects(model.get(), sgOptions.get());
|
||||
}
|
||||
return model.release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <simgear/misc/PathOptions.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/scene/model/model.hxx>
|
||||
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
|
||||
#include <simgear/scene/util/StateAttributeFactory.hxx>
|
||||
#include <simgear/scene/util/SGUpdateVisitor.hxx>
|
||||
|
||||
@@ -108,9 +109,11 @@ SGNewCloud::SGNewCloud(string type,
|
||||
"texture"),
|
||||
"image"),
|
||||
texture);
|
||||
osg::ref_ptr<osgDB::ReaderWriter::Options> options
|
||||
ref_ptr<osgDB::ReaderWriter::Options> options
|
||||
= 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));
|
||||
} else {
|
||||
effect = iter->second.get();
|
||||
|
||||
Reference in New Issue
Block a user