diff --git a/doc/doc++/osg/COMPARE_StateAttribute_Parameter.html b/doc/doc++/osg/COMPARE_StateAttribute_Parameter.html
new file mode 100644
index 000000000..8575d3d74
--- /dev/null
+++ b/doc/doc++/osg/COMPARE_StateAttribute_Parameter.html
@@ -0,0 +1,22 @@
+
+
+
+
+ #define osg::COMPARE_StateAttribute_Parameter
+
+
+
+
+(parameter)
COMPARE_StateAttribute_Parameter macro is a helper for implementing the StatateAtribute::compare() method.
+
+
+
+Documentation
+COMPARE_StateAttribute_Parameter macro is a helper for implementing the StatateAtribute::compare() method.
+Macro assumes that variable rhs has been corrected defined by code preceesing
+macro.
+
Alphabetic index HTML hierarchy of classes or Java
+
+This page was generated with the help of DOC++.
+
+
diff --git a/doc/doc++/osg/COMPARE_StateAttribute_Types.html b/doc/doc++/osg/COMPARE_StateAttribute_Types.html
new file mode 100644
index 000000000..26dc56e4b
--- /dev/null
+++ b/doc/doc++/osg/COMPARE_StateAttribute_Types.html
@@ -0,0 +1,20 @@
+
+
+
+
+ #define osg::COMPARE_StateAttribute_Types
+
+
+
+
+(TYPE, rhs_attribute)
COMPARE_StateAttribute_Types macro is a helper for implementing the StatateAtribute::compare() method
+
+
+
+Documentation
+COMPARE_StateAttribute_Types macro is a helper for implementing the StatateAtribute::compare() method
+
Alphabetic index HTML hierarchy of classes or Java
+
+This page was generated with the help of DOC++.
+
+
diff --git a/doc/doc++/osg/METANODE.html b/doc/doc++/osg/METANODE.html
new file mode 100644
index 000000000..ffd6a45b4
--- /dev/null
+++ b/doc/doc++/osg/METANODE.html
@@ -0,0 +1,22 @@
+
+
+
+
+ #define osg::METANODE
+
+
+
+
+(name)
Use METAOBJ macro when subclassing from Node to make it more convinient to define the standard clone, isSameKindAs, className and accept methods which are required for all Node subclasses
+
+
+
+Documentation
+Use METAOBJ macro when subclassing from Node to make it more
+convinient to define the standard clone, isSameKindAs, className
+and accept methods which are required for all Node subclasses
+
Alphabetic index HTML hierarchy of classes or Java
+
+This page was generated with the help of DOC++.
+
+
diff --git a/doc/doc++/osg/METAOBJ.html b/doc/doc++/osg/METAOBJ.html
new file mode 100644
index 000000000..a4a38eeba
--- /dev/null
+++ b/doc/doc++/osg/METAOBJ.html
@@ -0,0 +1,22 @@
+
+
+
+
+ #define osg::METAOBJ
+
+
+
+
+(name)
Use METAOBJ macro when subclassing from Object to make it more convinient to define the standard clone, isSameKindAs and className methods which are required for all Object subclasses
+
+
+
+Documentation
+Use METAOBJ macro when subclassing from Object to make it more
+convinient to define the standard clone, isSameKindAs and className
+methods which are required for all Object subclasses
+
Alphabetic index HTML hierarchy of classes or Java
+
+This page was generated with the help of DOC++.
+
+
diff --git a/doc/doc++/osg/META_Node.html b/doc/doc++/osg/META_Node.html
new file mode 100644
index 000000000..0220fb70e
--- /dev/null
+++ b/doc/doc++/osg/META_Node.html
@@ -0,0 +1,22 @@
+
+
+
+
+ #define osg::META_Node
+
+
+
+
+(name)
META_Node macro define the standard clone, isSameKindAs, className and accept methods.
+
+
+
+Documentation
+META_Node macro define the standard clone, isSameKindAs, className
+and accept methods. Use when subclassing from Node to make it
+more convinient to define the required pure virtual methods.
+
Alphabetic index HTML hierarchy of classes or Java
+
+This page was generated with the help of DOC++.
+
+
diff --git a/doc/doc++/osg/META_Object.html b/doc/doc++/osg/META_Object.html
new file mode 100644
index 000000000..bbd13a94c
--- /dev/null
+++ b/doc/doc++/osg/META_Object.html
@@ -0,0 +1,23 @@
+
+
+
+
+ #define osg::META_Object
+
+
+
+
+(name)
META_Object macro define the standard clone, isSameKindAs and className methods.
+
+
+
+Documentation
+META_Object macro define the standard clone, isSameKindAs and className methods.
+Use when subclassing from Object to make it more convinient to define
+the standard pure virtual clone, isSameKindAs and className methods
+which are required for all Object subclasses.
+
Alphabetic index HTML hierarchy of classes or Java
+
+This page was generated with the help of DOC++.
+
+
diff --git a/doc/doc++/osg/META_StateAttribute.html b/doc/doc++/osg/META_StateAttribute.html
new file mode 100644
index 000000000..73a11aed1
--- /dev/null
+++ b/doc/doc++/osg/META_StateAttribute.html
@@ -0,0 +1,24 @@
+
+
+
+
+ #define osg::META_StateAttribute
+
+
+
+
+(name, type)
META_StateAttribute macro define the standard clone, isSameKindAs, className and getType methods.
+
+
+
+Documentation
+META_StateAttribute macro define the standard clone, isSameKindAs,
+className and getType methods.
+Use when subclassing from Object to make it more convinient to define
+the standard pure virtual methods which are required for all Object
+subclasses.
+
Alphabetic index HTML hierarchy of classes or Java
+
+This page was generated with the help of DOC++.
+
+
diff --git a/doc/doc++/osgUtil/OptimizeStateVisitor.html b/doc/doc++/osgUtil/OptimizeStateVisitor.html
new file mode 100644
index 000000000..d7a0914b9
--- /dev/null
+++ b/doc/doc++/osgUtil/OptimizeStateVisitor.html
@@ -0,0 +1,92 @@
+
+
+
+
+ class OSGUTIL_EXPORT osgUtil::OptimizeStateVisitor
+
+
+
+
+Insert impostor nodes into scene graph.
+
+
+Inheritance:
+
+
+
+
+
+Public Methods
-
+
OptimizeStateVisitor()
+ - default to traversing all children
+
-
+
virtual void reset()
+ - empty visitor, make it ready for next traversal
+
-
+
void addStateSet(osg::StateSet* stateset)
+-
+
virtual void apply(osg::Node& node)
+-
+
virtual void apply(osg::Geode& geode)
+-
+
void optimize()
+
+
+
+Protected Members
-
+
typedef std::set<osg::StateSet*> StateSetList StateSetList _statesets
+
+
+
+
+
+
+Documentation
+Insert impostor nodes into scene graph.
+For example of usage see src/Demos/osgimpostor.
+
+
+
+
+
OptimizeStateVisitor()
+- default to traversing all children
+
+
+
+
virtual void reset()
+- empty visitor, make it ready for next traversal
+
+
+
+
void addStateSet(osg::StateSet* stateset)
+
+
+
+
virtual void apply(osg::Node& node)
+
+
+
+
virtual void apply(osg::Geode& geode)
+
+
+
+
void optimize()
+
+
+
+
typedef std::set<osg::StateSet*> StateSetList StateSetList _statesets
+
+
+
- This class has no child classes.
+
+
Alphabetic index HTML hierarchy of classes or Java
+
+This page was generated with the help of DOC++.
+
+
diff --git a/include/osgUtil/OptimizeStateVisitor b/include/osgUtil/OptimizeStateVisitor
new file mode 100644
index 000000000..47639710c
--- /dev/null
+++ b/include/osgUtil/OptimizeStateVisitor
@@ -0,0 +1,40 @@
+#ifndef OSGUTIL_OPTIMIZESTATEVISITOR
+#define OSGUTIL_OPTIMIZESTATEVISITOR
+
+#include
+
+#include
+
+namespace osgUtil {
+
+/** Insert impostor nodes into scene graph.
+ * For example of usage see src/Demos/osgimpostor.
+ */
+class OSGUTIL_EXPORT OptimizeStateVisitor : public osg::NodeVisitor
+{
+ public:
+
+ /// default to traversing all children.
+ OptimizeStateVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {}
+
+ /** empty visitor, make it ready for next traversal.*/
+ virtual void reset();
+
+ void addStateSet(osg::StateSet* stateset);
+
+ virtual void apply(osg::Node& node);
+
+ virtual void apply(osg::Geode& geode);
+
+ void optimize();
+
+ protected:
+
+ typedef std::set StateSetList;
+ StateSetList _statesets;
+
+};
+
+};
+
+#endif
diff --git a/src/osgUtil/OptimizeStateVisitor.cpp b/src/osgUtil/OptimizeStateVisitor.cpp
new file mode 100644
index 000000000..2e353e722
--- /dev/null
+++ b/src/osgUtil/OptimizeStateVisitor.cpp
@@ -0,0 +1,132 @@
+#include
+#include
+
+#include
+
+#include
+#include
+
+using namespace osgUtil;
+
+
+struct LessAttributeFunctor
+{
+ bool operator () (const osg::StateAttribute* lhs,const osg::StateAttribute* rhs) const
+ {
+ return (*lhs<*rhs);
+ }
+};
+/*
+struct LessStateSetFunctor
+{
+ bool operator () (const osg::StateSet* lhs,const osg::StateSet* rhs) const
+ {
+ return (*lhs<*rhs);
+ }
+};
+*/
+void OptimizeStateVisitor::reset()
+{
+ _statesets.clear();
+}
+
+void OptimizeStateVisitor::addStateSet(osg::StateSet* stateset)
+{
+ _statesets.insert(stateset);
+}
+
+void OptimizeStateVisitor::apply(osg::Node& node)
+{
+ osg::StateSet* ss = node.getStateSet();
+ if (ss) addStateSet(ss);
+
+ traverse(node);
+}
+
+void OptimizeStateVisitor::apply(osg::Geode& geode)
+{
+ osg::StateSet* ss = geode.getStateSet();
+ if (ss) addStateSet(ss);
+ for(int i=0;igetStateSet();
+ if (ss) addStateSet(ss);
+ }
+}
+
+void OptimizeStateVisitor::optimize()
+{
+ osg::notify(osg::INFO) << "Num of StateSet="<<_statesets.size()< AttributeToStateSetMap;
+ AttributeToStateSetMap _attributeToStateSetMap;
+
+ // NOTE will need to track state attribute override value too.
+
+ for(StateSetList::iterator sitr=_statesets.begin();
+ sitr!=_statesets.end();
+ ++sitr)
+ {
+ osg::StateSet::AttributeList& attributes = (*sitr)->getAttributeList();
+ for(osg::StateSet::AttributeList::iterator aitr= attributes.begin();
+ aitr!=attributes.end();
+ ++aitr)
+ {
+ _attributeToStateSetMap[aitr->second.first.get()].insert(*sitr);
+ }
+ }
+
+ if (_attributeToStateSetMap.size()<2)
+ {
+ osg::notify(osg::INFO) << "Too few state attributes to optimize."< AttributeList;
+ AttributeList _attributeList;
+
+ for(AttributeToStateSetMap::iterator aitr=_attributeToStateSetMap.begin();
+ aitr!=_attributeToStateSetMap.end();
+ ++aitr)
+ {
+ _attributeList.push_back(aitr->first);
+ }
+
+ // sort the attributes so that equal attributes sit along side each
+ // other.
+ std::sort(_attributeList.begin(),_attributeList.end(),LessAttributeFunctor());
+
+
+ osg::notify(osg::INFO) << "state attribute list"<className()<className()<<" first="<<*first_unique<<" current="<<*current<setAttribute(*first_unique);
+ }
+ }
+ else first_unique = current;
+ }
+
+}