Index: /OpenSceneGraph/trunk/include/osgUtil/Optimizer
===================================================================
--- /OpenSceneGraph/trunk/include/osgUtil/Optimizer (revision 9245)
+++ /OpenSceneGraph/trunk/include/osgUtil/Optimizer (revision 9886)
@@ -75,14 +75,15 @@
             MERGE_GEOMETRY =            (1 << 5),
             CHECK_GEOMETRY =            (1 << 6),
-            SPATIALIZE_GROUPS =         (1 << 7),
-            COPY_SHARED_NODES =         (1 << 8),
-            TRISTRIP_GEOMETRY =         (1 << 9),
-            TESSELLATE_GEOMETRY =       (1 << 10),
-            OPTIMIZE_TEXTURE_SETTINGS = (1 << 11),
-            MERGE_GEODES =              (1 << 12),
-            FLATTEN_BILLBOARDS =        (1 << 13),
-            TEXTURE_ATLAS_BUILDER =     (1 << 14),
-            STATIC_OBJECT_DETECTION =   (1 << 15),
-            FLATTEN_STATIC_TRANSFORMS_DUPLICATING_SHARED_SUBGRAPHS = (1 << 16),
+            MAKE_FAST_GEOMETRY =        (1 << 7),
+            SPATIALIZE_GROUPS =         (1 << 8),
+            COPY_SHARED_NODES =         (1 << 9),
+            TRISTRIP_GEOMETRY =         (1 << 10),
+            TESSELLATE_GEOMETRY =       (1 << 11),
+            OPTIMIZE_TEXTURE_SETTINGS = (1 << 12),
+            MERGE_GEODES =              (1 << 13),
+            FLATTEN_BILLBOARDS =        (1 << 14),
+            TEXTURE_ATLAS_BUILDER =     (1 << 15),
+            STATIC_OBJECT_DETECTION =   (1 << 16),
+            FLATTEN_STATIC_TRANSFORMS_DUPLICATING_SHARED_SUBGRAPHS = (1 << 17),
             DEFAULT_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS |
                                 REMOVE_REDUNDANT_NODES |
@@ -91,4 +92,5 @@
                                 SHARE_DUPLICATE_STATE |
                                 MERGE_GEOMETRY |
+                                MAKE_FAST_GEOMETRY |
                                 CHECK_GEOMETRY |
                                 OPTIMIZE_TEXTURE_SETTINGS |
@@ -101,4 +103,5 @@
                                 MERGE_GEODES |
                                 MERGE_GEOMETRY |
+                                MAKE_FAST_GEOMETRY |
                                 CHECK_GEOMETRY |
                                 SPATIALIZE_GROUPS |
@@ -507,4 +510,18 @@
         };
         
+        class OSGUTIL_EXPORT MakeFastGeometryVisitor : public BaseOptimizerVisitor
+        {
+            public:
+
+                /// default to traversing all children.
+                MakeFastGeometryVisitor(Optimizer* optimizer=0):
+                    BaseOptimizerVisitor(optimizer, MAKE_FAST_GEOMETRY) {}
+
+                virtual void apply(osg::Geode& geode) { checkGeode(geode); }
+
+                void checkGeode(osg::Geode& geode);
+                
+        };        
+        
         class OSGUTIL_EXPORT MergeGeometryVisitor : public BaseOptimizerVisitor
         {
Index: /OpenSceneGraph/trunk/include/osgUtil/Statistics
===================================================================
--- /OpenSceneGraph/trunk/include/osgUtil/Statistics (revision 9552)
+++ /OpenSceneGraph/trunk/include/osgUtil/Statistics (revision 9886)
@@ -202,4 +202,5 @@
     unsigned int _numInstancedDrawable;
     unsigned int _numInstancedGeometry;
+    unsigned int _numInstancedFastGeometry;
     unsigned int _numInstancedStateSet;
 
@@ -211,4 +212,5 @@
     DrawableSet _drawableSet;
     DrawableSet _geometrySet;
+    DrawableSet _fastGeometrySet;
     StateSetSet _statesetSet;
 
Index: /OpenSceneGraph/trunk/include/osg/Geometry
===================================================================
--- /OpenSceneGraph/trunk/include/osg/Geometry (revision 9599)
+++ /OpenSceneGraph/trunk/include/osg/Geometry (revision 9886)
@@ -332,5 +332,11 @@
           * arrays will drop the rendering path off the fast path.
         */
-        inline bool areFastPathsUsed() const { return _fastPath && _fastPathHint; }
+        inline bool areFastPathsUsed() const
+        {
+            if (_internalOptimizedGeometry.valid())
+                return _internalOptimizedGeometry->areFastPathsUsed();
+            else
+                return _fastPath && _fastPathHint;
+        }
 
         bool computeFastPathsUsed();
Index: /OpenSceneGraph/trunk/src/osgUtil/Optimizer.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgUtil/Optimizer.cpp (revision 9703)
+++ /OpenSceneGraph/trunk/src/osgUtil/Optimizer.cpp (revision 9886)
@@ -22,4 +22,5 @@
 #include <osg/LOD>
 #include <osg/Billboard>
+#include <osg/CameraView>
 #include <osg/Geometry>
 #include <osg/Notify>
@@ -110,4 +111,7 @@
         if(str.find("~CHECK_GEOMETRY")!=std::string::npos) options ^= CHECK_GEOMETRY;
         else if(str.find("CHECK_GEOMETRY")!=std::string::npos) options |= CHECK_GEOMETRY;
+
+        if(str.find("~MAKE_FAST_GEOMETRY")!=std::string::npos) options ^= MAKE_FAST_GEOMETRY;
+        else if(str.find("MAKE_FAST_GEOMETRY")!=std::string::npos) options |= MAKE_FAST_GEOMETRY;
         
         if(str.find("~FLATTEN_BILLBOARDS")!=std::string::npos) options ^= FLATTEN_BILLBOARDS;
@@ -277,4 +281,12 @@
 
         CheckGeometryVisitor mgv(this);
+        node->accept(mgv);
+    }
+
+    if (options & MAKE_FAST_GEOMETRY)
+    {
+        osg::notify(osg::INFO)<<"Optimizer::optimize() doing MAKE_FAST_GEOMETRY"<<std::endl;
+
+        MakeFastGeometryVisitor mgv(this);
         node->accept(mgv);
     }
@@ -1309,5 +1321,5 @@
         // only remove empty groups, but not empty occluders.
         if (group.getNumChildren()==0 && isOperationPermissibleForObject(&group) && 
-            (typeid(group)==typeid(osg::Group) || dynamic_cast<osg::Transform*>(&group)))
+            (typeid(group)==typeid(osg::Group) || (dynamic_cast<osg::Transform*>(&group) && !dynamic_cast<osg::CameraView*>(&group))))
         {
             _redundantNodeList.insert(&group);
@@ -1781,4 +1793,22 @@
             {
                 geom->computeCorrectBindingsAndArraySizes();
+            }
+        }
+    }
+}
+
+void Optimizer::MakeFastGeometryVisitor::checkGeode(osg::Geode& geode)
+{
+    if (isOperationPermissibleForObject(&geode))
+    {
+        for(unsigned int i=0;i<geode.getNumDrawables();++i)
+        {
+            osg::Geometry* geom = geode.getDrawable(i)->asGeometry();
+            if (geom && isOperationPermissibleForObject(geom))
+            {
+                if (!geom->areFastPathsUsed() && !geom->getInternalOptimizedGeometry())
+                {
+                    geom->computeInternalOptimizedGeometry();
+                }
             }
         }
Index: /OpenSceneGraph/trunk/src/osgUtil/Statistics.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgUtil/Statistics.cpp (revision 6461)
+++ /OpenSceneGraph/trunk/src/osgUtil/Statistics.cpp (revision 9886)
@@ -26,4 +26,5 @@
 #include <set>
 #include <ostream>
+#include <iomanip>
 
 using namespace osgUtil;
@@ -144,4 +145,5 @@
     _numInstancedDrawable(0),
     _numInstancedGeometry(0),
+    _numInstancedFastGeometry(0),
     _numInstancedStateSet(0)
 {}
@@ -156,4 +158,5 @@
     _numInstancedDrawable = 0;
     _numInstancedGeometry = 0;
+    _numInstancedFastGeometry = 0;
     _numInstancedStateSet = 0;
 
@@ -165,4 +168,5 @@
     _drawableSet.clear();
     _geometrySet.clear();
+    _fastGeometrySet.clear();
     _statesetSet.clear();
 
@@ -265,10 +269,16 @@
 
     _drawableSet.insert(&drawable);
-
-    osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(&drawable);
+    
+    osg::Geometry* geometry = drawable.asGeometry();
     if (geometry)
     {
         ++_numInstancedGeometry;
         _geometrySet.insert(geometry);
+
+        if (geometry->areFastPathsUsed())
+        {
+            ++_numInstancedFastGeometry;
+            _fastGeometrySet.insert(geometry);
+        }
     }
 }
@@ -306,15 +316,18 @@
     }
 
-    out<<"Object Type\t#Unique\t#Instanced"<<std::endl;
-    out<<"StateSet      \t"<<_statesetSet.size()<<"\t"<<_numInstancedStateSet<<std::endl;
-    out<<"Group      \t"<<_groupSet.size()<<"\t"<<_numInstancedGroup<<std::endl;
-    out<<"Transform  \t"<<_transformSet.size()<<"\t"<<_numInstancedTransform<<std::endl;
-    out<<"LOD        \t"<<_lodSet.size()<<"\t"<<_numInstancedLOD<<std::endl;
-    out<<"Switch     \t"<<_switchSet.size()<<"\t"<<_numInstancedSwitch<<std::endl;
-    out<<"Geode      \t"<<_geodeSet.size()<<"\t"<<_numInstancedGeode<<std::endl;
-    out<<"Drawable   \t"<<_drawableSet.size()<<"\t"<<_numInstancedDrawable<<std::endl;
-    out<<"Geometry   \t"<<_geometrySet.size()<<"\t"<<_numInstancedGeometry<<std::endl;
-    out<<"Vertices   \t"<<_uniqueStats._vertexCount<<"\t"<<_instancedStats._vertexCount<<std::endl;
-    out<<"Primitives \t"<<unique_primitives<<"\t"<<instanced_primitives<<std::endl;
+
+    out << std::setw(12) << "Object Type" << std::setw(10) << "Unique"                  << std::setw(10) << "Instanced" << std::endl;
+    out << std::setw(12) << "-----------" << std::setw(10) << "------"                  << std::setw(10) << "---------" << std::endl;
+    out << std::setw(12) << "StateSet   " << std::setw(10) << _statesetSet.size()       << std::setw(10) << _numInstancedStateSet << std::endl;
+    out << std::setw(12) << "Group      " << std::setw(10) << _groupSet.size()          << std::setw(10) << _numInstancedGroup << std::endl;
+    out << std::setw(12) << "Transform  " << std::setw(10) << _transformSet.size()      << std::setw(10) << _numInstancedTransform << std::endl;
+    out << std::setw(12) << "LOD        " << std::setw(10) << _lodSet.size()            << std::setw(10) << _numInstancedLOD << std::endl;
+    out << std::setw(12) << "Switch     " << std::setw(10) << _switchSet.size()         << std::setw(10) << _numInstancedSwitch << std::endl;
+    out << std::setw(12) << "Geode      " << std::setw(10) << _geodeSet.size()          << std::setw(10) << _numInstancedGeode << std::endl;
+    out << std::setw(12) << "Drawable   " << std::setw(10) << _drawableSet.size()       << std::setw(10) << _numInstancedDrawable << std::endl;
+    out << std::setw(12) << "Geometry   " << std::setw(10) << _geometrySet.size()       << std::setw(10) << _numInstancedGeometry << std::endl;
+    out << std::setw(12) << "Fast geom. " << std::setw(10) << _fastGeometrySet.size()   << std::setw(10) << _numInstancedFastGeometry << std::endl;
+    out << std::setw(12) << "Vertices   " << std::setw(10) << _uniqueStats._vertexCount << std::setw(10) << _instancedStats._vertexCount << std::endl;
+    out << std::setw(12) << "Primitives " << std::setw(10) << unique_primitives         << std::setw(10) << instanced_primitives << std::endl;
 }
     
Index: /OpenSceneGraph/trunk/src/osgViewer/ViewerBase.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgViewer/ViewerBase.cpp (revision 9868)
+++ /OpenSceneGraph/trunk/src/osgViewer/ViewerBase.cpp (revision 9886)
@@ -376,5 +376,5 @@
         if (!gc->isRealized())
         {
-            osg::notify(osg::INFO)<<"ViewerBase::startThreading() : Realizing window "<<gc<<std::endl;
+            osg::notify(osg::INFO)<<"ViewerBase::startThreading() : Realizng window "<<gc<<std::endl;
             gc->realize();
         }
