From 542124e90cf467e590c4493774210f1e025cdc96 Mon Sep 17 00:00:00 2001 From: fredb Date: Sat, 10 Apr 2010 09:23:12 +0000 Subject: [PATCH 1/4] materials.xml format update Allow to declare sets of textures that can be used as parameters for effects. Syntax is: Terrain/city1.png Terrain/city1-relief-light.png Terrain/city2.png Terrain/city2-relief-light.png --- simgear/scene/material/mat.cxx | 61 ++++++++++++++++++++++++++++------ simgear/scene/material/mat.hxx | 5 ++- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/simgear/scene/material/mat.cxx b/simgear/scene/material/mat.cxx index 5947579e..8d53f861 100644 --- a/simgear/scene/material/mat.cxx +++ b/simgear/scene/material/mat.cxx @@ -68,10 +68,22 @@ using namespace simgear; // Constructors and destructor. //////////////////////////////////////////////////////////////////////// +SGMaterial::_internal_state::_internal_state(Effect *e, bool l, + const SGReaderWriterXMLOptions* o) + : effect(e), effect_realized(l), options(o) +{ +} + SGMaterial::_internal_state::_internal_state(Effect *e, const string &t, bool l, const SGReaderWriterXMLOptions* o) - : effect(e), texture_path(t), effect_realized(l), options(o) + : effect(e), effect_realized(l), options(o) { + texture_paths.push_back(std::make_pair(t,0)); +} + +void SGMaterial::_internal_state::add_texture(const std::string &t, int i) +{ + texture_paths.push_back(std::make_pair(t,i)); } SGMaterial::SGMaterial( const SGReaderWriterXMLOptions* options, @@ -129,7 +141,34 @@ SGMaterial::read_properties(const SGReaderWriterXMLOptions* options, } } - if (textures.size() == 0) { + vector texturesets = props->getChildren("texture-set"); + for (unsigned int i = 0; i < texturesets.size(); i++) + { + _internal_state st( NULL, false, options ); + vector textures = texturesets[i]->getChildren("texture"); + for (unsigned int j = 0; j < textures.size(); j++) + { + string tname = textures[j]->getStringValue(); + if (tname.empty()) { + tname = "unknown.rgb"; + } + SGPath tpath("Textures.high"); + tpath.append(tname); + string fullTexPath = osgDB::findDataFile(tpath.str(), options); + if (fullTexPath.empty()) { + tpath = SGPath("Textures"); + tpath.append(tname); + fullTexPath = osgDB::findDataFile(tpath.str(), options); + } + st.add_texture(fullTexPath, textures[j]->getIndex()); + } + + if (!st.texture_paths.empty() ) { + _status.push_back( st ); + } + } + + if (textures.size() == 0 && texturesets.size() == 0) { SGPath tpath("Textures"); tpath.append("Terrain"); tpath.append("unknown.rgb"); @@ -285,14 +324,16 @@ void SGMaterial::buildEffectProperties(const SGReaderWriterXMLOptions* options) SGPropertyNode_ptr effectProp = new SGPropertyNode(); copyProperties(propRoot, effectProp); SGPropertyNode* effectParamProp = effectProp->getChild("parameters", 0); - SGPropertyNode* texProp = makeChild(effectParamProp, "texture"); - makeChild(texProp, "image")->setStringValue(matState.texture_path); - makeChild(texProp, "filter") - ->setStringValue(mipmap ? "linear-mipmap-linear" : "nearest"); - makeChild(texProp, "wrap-s") - ->setStringValue(wrapu ? "repeat" : "clamp"); - makeChild(texProp, "wrap-t") - ->setStringValue(wrapv ? "repeat" : "clamp"); + for (unsigned int i = 0; i < matState.texture_paths.size(); i++) { + SGPropertyNode* texProp = makeChild(effectParamProp, "texture", matState.texture_paths[i].second); + makeChild(texProp, "image")->setStringValue(matState.texture_paths[i].first); + makeChild(texProp, "filter") + ->setStringValue(mipmap ? "linear-mipmap-linear" : "nearest"); + makeChild(texProp, "wrap-s") + ->setStringValue(wrapu ? "repeat" : "clamp"); + makeChild(texProp, "wrap-t") + ->setStringValue(wrapv ? "repeat" : "clamp"); + } matState.effect = makeEffect(effectProp, false, xmlOptions.get()); matState.effect->setUserData(user.get()); } diff --git a/simgear/scene/material/mat.hxx b/simgear/scene/material/mat.hxx index 619ae8da..9e2d06e4 100644 --- a/simgear/scene/material/mat.hxx +++ b/simgear/scene/material/mat.hxx @@ -272,10 +272,13 @@ protected: protected: struct _internal_state { + _internal_state(simgear::Effect *e, bool l, + const simgear::SGReaderWriterXMLOptions *o); _internal_state(simgear::Effect *e, const std::string &t, bool l, const simgear::SGReaderWriterXMLOptions *o); + void add_texture(const std::string &t, int i); osg::ref_ptr effect; - std::string texture_path; + std::vector > texture_paths; bool effect_realized; osg::ref_ptr options; }; From 7c4e5309fc4b447cbd737d2cbfe9dd168ab866c0 Mon Sep 17 00:00:00 2001 From: fredb Date: Sat, 10 Apr 2010 10:06:25 +0000 Subject: [PATCH 2/4] Declare some material parameters as implicit effect parameters --- simgear/scene/material/mat.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/simgear/scene/material/mat.cxx b/simgear/scene/material/mat.cxx index 8d53f861..9a1497e6 100644 --- a/simgear/scene/material/mat.cxx +++ b/simgear/scene/material/mat.cxx @@ -334,6 +334,10 @@ void SGMaterial::buildEffectProperties(const SGReaderWriterXMLOptions* options) makeChild(texProp, "wrap-t") ->setStringValue(wrapv ? "repeat" : "clamp"); } + makeChild(effectParamProp, "xsize")->setDoubleValue(xsize); + makeChild(effectParamProp, "ysize")->setDoubleValue(ysize); + makeChild(effectParamProp, "light-coverage")->setDoubleValue(light_coverage); + matState.effect = makeEffect(effectProp, false, xmlOptions.get()); matState.effect->setUserData(user.get()); } From caabe8fc876498beab85ebe357b446a7bd0448dc Mon Sep 17 00:00:00 2001 From: fredb Date: Sat, 10 Apr 2010 10:52:11 +0000 Subject: [PATCH 3/4] Add a "scale" parameter that combine xsize and ysize in a vec3 property. There is no vec2 property, so the third component is zero --- simgear/scene/material/mat.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/simgear/scene/material/mat.cxx b/simgear/scene/material/mat.cxx index 9a1497e6..83b1a9fa 100644 --- a/simgear/scene/material/mat.cxx +++ b/simgear/scene/material/mat.cxx @@ -336,6 +336,7 @@ void SGMaterial::buildEffectProperties(const SGReaderWriterXMLOptions* options) } makeChild(effectParamProp, "xsize")->setDoubleValue(xsize); makeChild(effectParamProp, "ysize")->setDoubleValue(ysize); + makeChild(effectParamProp, "scale")->setValue(SGVec3d(xsize,ysize,0.0)); makeChild(effectParamProp, "light-coverage")->setDoubleValue(light_coverage); matState.effect = makeEffect(effectProp, false, xmlOptions.get()); From f19e83dcf10d5fced3d799c884a4654d7ada6548 Mon Sep 17 00:00:00 2001 From: fredb Date: Sat, 10 Apr 2010 11:15:32 +0000 Subject: [PATCH 4/4] Add a new node "float-property" to be used in float comparision in effect predicates --- simgear/scene/material/Effect.cxx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/simgear/scene/material/Effect.cxx b/simgear/scene/material/Effect.cxx index 3b5728ac..33ceacda 100644 --- a/simgear/scene/material/Effect.cxx +++ b/simgear/scene/material/Effect.cxx @@ -1279,14 +1279,15 @@ osgDB::RegisterDotOsgWrapperProxy effectProxy } // Property expressions for technique predicates -class PropertyExpression : public SGExpression +template +class PropertyExpression : public SGExpression { public: PropertyExpression(SGPropertyNode* pnode) : _pnode(pnode) {} - void eval(bool& value, const expression::Binding*) const + void eval(T& value, const expression::Binding*) const { - value = _pnode->getValue(); + value = _pnode->getValue(); } protected: SGPropertyNode_ptr _pnode; @@ -1305,12 +1306,13 @@ protected: osg::ref_ptr _tniq; }; +template Expression* propertyExpressionParser(const SGPropertyNode* exp, expression::Parser* parser) { SGPropertyNode_ptr pnode = getPropertyRoot()->getNode(exp->getStringValue(), true); - PropertyExpression* pexp = new PropertyExpression(pnode); + PropertyExpression* pexp = new PropertyExpression(pnode); TechniquePredParser* predParser = dynamic_cast(parser); if (predParser) @@ -1320,6 +1322,9 @@ Expression* propertyExpressionParser(const SGPropertyNode* exp, } expression::ExpParserRegistrar propertyRegistrar("property", - propertyExpressionParser); + propertyExpressionParser); + +expression::ExpParserRegistrar propvalueRegistrar("float-property", + propertyExpressionParser); }