Added conversion to osg::GeoSet::converToGeometry() utility to help the
migration to and testing of the new osg::Geometry class.
This commit is contained in:
@@ -12,6 +12,10 @@
|
||||
|
||||
namespace osg {
|
||||
|
||||
|
||||
// forward declare so that we don't need to include the header.
|
||||
class Geometry;
|
||||
|
||||
/** Encapsulates OpenGL drawing primitives, geometry and
|
||||
optional binding of normal, color and texture coordinates. Used
|
||||
for representing the visible objects in the scene. State attributes
|
||||
@@ -334,6 +338,9 @@ class SG_EXPORT GeoSet : public Drawable
|
||||
virtual AttributeBitMask applyAttributeOperation(AttributeFunctor& auf);
|
||||
|
||||
|
||||
/** convinience function for converting GeoSet's to equivilant Geometry nodes.*/
|
||||
Geometry* convertToGeometry();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -88,8 +88,18 @@ class TemplateArray : public AttributeArray, public std::vector<T>
|
||||
|
||||
TemplateArray() : AttributeArray(ARRAYTYPE,DataSize,DataType) {}
|
||||
|
||||
TemplateArray(const TemplateArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : AttributeArray(ta,copyop), std::vector<T>(ta) {}
|
||||
TemplateArray(const TemplateArray& ta,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
|
||||
AttributeArray(ta,copyop),
|
||||
std::vector<T>(ta) {}
|
||||
|
||||
TemplateArray(unsigned int no,T* ptr) :
|
||||
AttributeArray(ARRAYTYPE,DataSize,DataType),
|
||||
std::vector<T>(ptr,ptr+no) {}
|
||||
|
||||
TemplateArray(T* first,T* last) :
|
||||
AttributeArray(ARRAYTYPE,DataSize,DataType),
|
||||
std::vector<T>(first,last) {}
|
||||
|
||||
virtual Object* cloneType() const { return osgNew TemplateArray(); }
|
||||
virtual Object* clone(const CopyOp& copyop) const { return osgNew TemplateArray(*this,copyop); }
|
||||
virtual const char* libraryName() const { return "osg"; }
|
||||
@@ -115,7 +125,7 @@ typedef TemplateArray<Vec4,Vec4ArrayType,4,GL_FLOAT> Vec4Ar
|
||||
enum PrimitiveType
|
||||
{
|
||||
PrimitivePrimitiveType = 0,
|
||||
DrawArrayPrimitiveType = 1,
|
||||
DrawArraysPrimitiveType = 1,
|
||||
UByteDrawElementsPrimitiveType = 2,
|
||||
UShortDrawElementsPrimitiveType = 3,
|
||||
UIntDrawElementsPrimitiveType = 4,
|
||||
@@ -124,7 +134,7 @@ enum PrimitiveType
|
||||
static char* s_PrimitiveNames[] =
|
||||
{
|
||||
"Primitive", // 0
|
||||
"DrawArray", // 1
|
||||
"DrawArrays", // 1
|
||||
"UByteDrawElements", // 2
|
||||
"UShortDrawElements", // 3
|
||||
"UIntDrawElements" // 4
|
||||
@@ -164,31 +174,31 @@ class Primitive : public Object
|
||||
PrimitiveType _primitiveType;
|
||||
};
|
||||
|
||||
class DrawArray : public Primitive
|
||||
class DrawArrays : public Primitive
|
||||
{
|
||||
public:
|
||||
|
||||
DrawArray():
|
||||
Primitive(DrawArrayPrimitiveType)
|
||||
DrawArrays():
|
||||
Primitive(DrawArraysPrimitiveType)
|
||||
{}
|
||||
|
||||
DrawArray(GLenum mode, GLint first, GLsizei count):
|
||||
Primitive(DrawArrayPrimitiveType),
|
||||
DrawArrays(GLenum mode, GLint first, GLsizei count):
|
||||
Primitive(DrawArraysPrimitiveType),
|
||||
_mode(mode),
|
||||
_first(first),
|
||||
_count(count) {}
|
||||
|
||||
DrawArray(const DrawArray& da,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
|
||||
DrawArrays(const DrawArrays& da,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
|
||||
Primitive(da,copyop),
|
||||
_mode(da._mode),
|
||||
_first(da._first),
|
||||
_count(da._count) {}
|
||||
|
||||
virtual Object* cloneType() const { return osgNew DrawArray(); }
|
||||
virtual Object* clone(const CopyOp& copyop) const { return osgNew DrawArray(*this,copyop); }
|
||||
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const DrawArray*>(obj)!=NULL; }
|
||||
virtual Object* cloneType() const { return osgNew DrawArrays(); }
|
||||
virtual Object* clone(const CopyOp& copyop) const { return osgNew DrawArrays(*this,copyop); }
|
||||
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const DrawArrays*>(obj)!=NULL; }
|
||||
virtual const char* libraryName() const { return "osg"; }
|
||||
virtual const char* className() const { return "DrawArray"; }
|
||||
virtual const char* className() const { return "DrawArrays"; }
|
||||
|
||||
virtual void draw() const
|
||||
{
|
||||
@@ -200,15 +210,33 @@ class DrawArray : public Primitive
|
||||
GLsizei _count;
|
||||
};
|
||||
|
||||
template<typename T, int PRIMTYPE, int DataType>
|
||||
template<typename T, PrimitiveType PRIMTYPE, int DataType>
|
||||
class DrawElements : public Primitive, public std::vector<T>
|
||||
{
|
||||
public:
|
||||
|
||||
DrawElements():Primitive(PRIMTYPE),_dataType(_dataType) {}
|
||||
DrawElements(GLenum mode=0):
|
||||
Primitive(PRIMTYPE),
|
||||
_mode(mode),
|
||||
_dataType(DataType) {}
|
||||
|
||||
DrawElements(const DrawElements& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
|
||||
Primitive(array,copyop) {}
|
||||
Primitive(array,copyop),
|
||||
std::vector<T>(array),
|
||||
_mode(array._mode),
|
||||
_dataType(array._dataType) {}
|
||||
|
||||
DrawElements(GLenum mode,unsigned int no,T* ptr) :
|
||||
Primitive(PRIMTYPE),
|
||||
std::vector<T>(ptr,ptr+no),
|
||||
_mode(mode),
|
||||
_dataType(DataType) {}
|
||||
|
||||
DrawElements(GLenum mode, T* first,T* last) :
|
||||
Primitive(PRIMTYPE),
|
||||
std::vector<T>(first,last),
|
||||
_mode(mode),
|
||||
_dataType(DataType) {}
|
||||
|
||||
virtual Object* cloneType() const { return osgNew DrawElements(); }
|
||||
virtual Object* clone(const CopyOp& copyop) const { return osgNew DrawElements(*this,copyop); }
|
||||
@@ -252,10 +280,10 @@ class SG_EXPORT Geometry : public Drawable
|
||||
|
||||
enum AttributeBinding
|
||||
{
|
||||
OFF=0,
|
||||
OVERALL,
|
||||
PER_PRIMITIVE,
|
||||
PER_VERTEX,
|
||||
BIND_OFF=0,
|
||||
BIND_OVERALL,
|
||||
BIND_PER_PRIMITIVE,
|
||||
BIND_PER_VERTEX,
|
||||
};
|
||||
|
||||
void setVertexArray(Vec3Array* array) { _vertexArray = array; }
|
||||
@@ -266,7 +294,7 @@ class SG_EXPORT Geometry : public Drawable
|
||||
void setNormalBinding(AttributeBinding ab) { _normalBinding = ab; }
|
||||
AttributeBinding getNormalBinding() const { return _normalBinding; }
|
||||
|
||||
void setNormalArray(Vec3Array* array) { _normalArray = array; if (!_normalArray.valid()) _normalBinding=OFF; }
|
||||
void setNormalArray(Vec3Array* array) { _normalArray = array; if (!_normalArray.valid()) _normalBinding=BIND_OFF; }
|
||||
Vec3Array* getNormalArray() { return _normalArray.get(); }
|
||||
const Vec3Array* getNormalArray() const { return _normalArray.get(); }
|
||||
|
||||
@@ -274,7 +302,7 @@ class SG_EXPORT Geometry : public Drawable
|
||||
void setColorBinding(AttributeBinding ab) { _colorBinding = ab; }
|
||||
AttributeBinding getColorBinding() const { return _colorBinding; }
|
||||
|
||||
void setColorArray(AttributeArray* array) { _colorArray = array; if (!_colorArray.valid()) _colorBinding=OFF; }
|
||||
void setColorArray(AttributeArray* array) { _colorArray = array; if (!_colorArray.valid()) _colorBinding=BIND_OFF; }
|
||||
AttributeArray* getColorArray() { return _colorArray.get(); }
|
||||
const AttributeArray* getColorArray() const { return _colorArray.get(); }
|
||||
|
||||
@@ -292,7 +320,7 @@ class SG_EXPORT Geometry : public Drawable
|
||||
PrimitiveList& getPrimitiveList() { return _primitives; }
|
||||
const PrimitiveList& getPrimitiveList() const { return _primitives; }
|
||||
|
||||
void addPrimtive(Primitive* primitive) { if (primitive) _primitives.push_back(primitive); }
|
||||
void addPrimitive(Primitive* primitive) { if (primitive) _primitives.push_back(primitive); }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -274,7 +274,7 @@ class SG_EXPORT Texture : public StateAttribute
|
||||
{
|
||||
// pad out handle list if required.
|
||||
if (_handleList.size()<=contextID)
|
||||
_handleList.resize(contextID,0);
|
||||
_handleList.resize(contextID+1,0);
|
||||
|
||||
// get the globj for the current contextID.
|
||||
return _handleList[contextID];
|
||||
|
||||
@@ -95,6 +95,12 @@ class ref_ptr
|
||||
|
||||
inline const T* get() const { return _ptr; }
|
||||
|
||||
/** take control over the object pointed to by ref_ptr, unreference but do not delete even if ref count goes to 0,
|
||||
* return the pointer to the object.
|
||||
* Note, do not use this unless you are 100% sure your code handles the deletion of the object correctly, and
|
||||
* only use when absolutely required.*/
|
||||
inline T* take() { T* tmp=_ptr; if (_ptr) _ptr->unref_nodelete(); _ptr=0; return tmp;}
|
||||
|
||||
private:
|
||||
T* _ptr;
|
||||
};
|
||||
|
||||
@@ -42,7 +42,19 @@ class OSGUTIL_EXPORT Optimizer
|
||||
virtual void optimize(osg::Node* node, unsigned int options = ALL_OPTIMIZATIONS);
|
||||
|
||||
|
||||
|
||||
/** ConvertGeoSetsToGeometryVisitor all the old GeoSet Drawables to the new Geometry Drawables.*/
|
||||
class OSGUTIL_EXPORT ConvertGeoSetsToGeometryVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
ConvertGeoSetsToGeometryVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
|
||||
|
||||
virtual void apply(osg::Geode& geode);
|
||||
virtual void apply(osg::Node& node) { traverse(node); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Flatten Static Trasform nodes by applying their transform to the
|
||||
* geometry on the leaves of the scene graph, then removing the
|
||||
* now redundent transforms.*/
|
||||
@@ -133,6 +145,113 @@ class OSGUTIL_EXPORT Optimizer
|
||||
|
||||
};
|
||||
|
||||
/** Remove the lowest static transforms in the scene.*/
|
||||
class OSGUTIL_EXPORT RemoveLowestStaticTransformsVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
|
||||
RemoveLowestStaticTransformsVisitor(bool ignoreDynamicTransforms=true):
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_ignoreDynamicTransforms(ignoreDynamicTransforms) {}
|
||||
|
||||
virtual void apply(osg::Geode& geode);
|
||||
virtual void apply(osg::Billboard& billboard);
|
||||
virtual void apply(osg::LOD& lod);
|
||||
virtual void apply(osg::Transform& transform);
|
||||
|
||||
bool removeTransforms();
|
||||
|
||||
|
||||
typedef std::vector<osg::Transform*> TransformStack;
|
||||
typedef std::vector<osg::Matrix> MatrixStack;
|
||||
|
||||
protected:
|
||||
|
||||
struct TransformStruct
|
||||
{
|
||||
typedef std::set<osg::Object*> ObjectSet;
|
||||
|
||||
TransformStruct():_containsTransform(false),_canBeApplied(true) {}
|
||||
|
||||
void add(osg::Object* obj) { _objectSet.insert(obj); }
|
||||
|
||||
bool _containsTransform;
|
||||
bool _canBeApplied;
|
||||
ObjectSet _objectSet;
|
||||
};
|
||||
|
||||
struct ObjectStruct
|
||||
{
|
||||
typedef std::set<osg::Transform*> TransformSet;
|
||||
|
||||
ObjectStruct():_canBeApplied(true),_matrixSet(false),_moreThanOneMatrixRequired(false) {}
|
||||
|
||||
void add(osg::Transform* transform,osg::Matrix& matrix)
|
||||
{
|
||||
_transformSet.insert(transform);
|
||||
if (!_matrixSet)
|
||||
{
|
||||
_matrixSet = true;
|
||||
_moreThanOneMatrixRequired = false;
|
||||
_matrix = matrix;
|
||||
}
|
||||
else if (_matrix!=matrix)
|
||||
{
|
||||
_moreThanOneMatrixRequired = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool _canBeApplied;
|
||||
bool _matrixSet;
|
||||
bool _moreThanOneMatrixRequired;
|
||||
osg::Matrix _matrix;
|
||||
TransformSet _transformSet;
|
||||
|
||||
};
|
||||
|
||||
typedef std::map<osg::Transform*,TransformStruct> TransformMap;
|
||||
typedef std::map<osg::Object*,ObjectStruct> ObjectMap;
|
||||
|
||||
void disableObject(osg::Object* object)
|
||||
{
|
||||
disableObject(_objectMap.find(object));
|
||||
}
|
||||
|
||||
void disableObject(ObjectMap::iterator itr);
|
||||
void disableTransform(osg::Transform* transform);
|
||||
void doTransform(osg::Object* obj,osg::Matrix& matrix);
|
||||
|
||||
bool _ignoreDynamicTransforms;
|
||||
MatrixStack _matrixStack;
|
||||
TransformStack _transformStack;
|
||||
|
||||
TransformMap _transformMap;
|
||||
ObjectMap _objectMap;
|
||||
|
||||
|
||||
};
|
||||
|
||||
/** Remove rendundent nodes, such as groups with one single child.*/
|
||||
class OSGUTIL_EXPORT RemoveEmptyNodesVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
typedef std::set<osg::Node*> NodeList;
|
||||
NodeList _redundentNodeList;
|
||||
|
||||
RemoveEmptyNodesVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
|
||||
|
||||
virtual void apply(osg::Geode& geode);
|
||||
virtual void apply(osg::Group& group);
|
||||
|
||||
void removeEmptyNodes();
|
||||
|
||||
};
|
||||
|
||||
/** Remove rendundent nodes, such as groups with one single child.*/
|
||||
class OSGUTIL_EXPORT RemoveRedundentNodesVisitor : public osg::NodeVisitor
|
||||
{
|
||||
@@ -142,8 +261,9 @@ class OSGUTIL_EXPORT Optimizer
|
||||
NodeList _redundentNodeList;
|
||||
|
||||
RemoveRedundentNodesVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
|
||||
|
||||
|
||||
virtual void apply(osg::Group& group);
|
||||
virtual void apply(osg::Transform& transform);
|
||||
|
||||
void removeRedundentNodes();
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <osg/Math>
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Global variables - this is basically the stuff which will be animated
|
||||
// Global variables - this is basically the stuff wh ich will be animated
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -186,12 +186,12 @@ osg::Geode* createGeometryCube()
|
||||
|
||||
// set up the primitives
|
||||
|
||||
cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,0,4));
|
||||
cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,4,4));
|
||||
cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,8,4));
|
||||
cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,12,4));
|
||||
cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,16,4));
|
||||
cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,20,4));
|
||||
cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,0,4));
|
||||
cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,4,4));
|
||||
cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,8,4));
|
||||
cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,12,4));
|
||||
cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,16,4));
|
||||
cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,20,4));
|
||||
|
||||
|
||||
// set up coords.
|
||||
@@ -244,7 +244,7 @@ osg::Geode* createGeometryCube()
|
||||
(*cubeNormals)[5].set(0.0f,-1.0f,0.0f);
|
||||
|
||||
cube->setNormalArray( cubeNormals );
|
||||
cube->setNormalBinding( osg::Geometry::PER_PRIMITIVE );
|
||||
cube->setNormalBinding( osg::Geometry::BIND_PER_PRIMITIVE );
|
||||
|
||||
// ---------------------------------------
|
||||
// Set up a StateSet to make the cube red
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#include <osg/Notify>
|
||||
#include <osg/Statistics>
|
||||
|
||||
#include <osg/Geometry>
|
||||
#include <osg/ShadeModel>
|
||||
|
||||
//#include <osg/mem_ptr>
|
||||
|
||||
using namespace osg;
|
||||
@@ -975,3 +978,367 @@ bool GeoSet::getStats(Statistics &stat)
|
||||
stat.addNumPrims(type, nprimlens, numprimtypes, primverts);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Geometry* GeoSet::convertToGeometry()
|
||||
{
|
||||
set_fast_path();
|
||||
computeNumVerts();
|
||||
|
||||
ref_ptr<Geometry> geom = osgNew Geometry;
|
||||
geom->setStateSet(getStateSet());
|
||||
|
||||
if (_flat_shaded_skip)
|
||||
{
|
||||
// will need to add flat shading to primitive.
|
||||
|
||||
StateSet* stateset = geom->getStateSet();
|
||||
if (!stateset)
|
||||
{
|
||||
stateset = osgNew StateSet;
|
||||
geom->setStateSet(stateset);
|
||||
}
|
||||
ShadeModel* shademodel = dynamic_cast<ShadeModel*>(stateset->getAttribute(StateAttribute::SHADEMODEL));
|
||||
if (!shademodel)
|
||||
{
|
||||
shademodel = osgNew osg::ShadeModel;
|
||||
stateset->setAttribute(shademodel,StateAttribute::OVERRIDE);
|
||||
}
|
||||
|
||||
shademodel->setMode( ShadeModel::FLAT );
|
||||
}
|
||||
|
||||
switch(_normal_binding)
|
||||
{
|
||||
case(BIND_OFF):
|
||||
geom->setNormalBinding(Geometry::BIND_OFF);
|
||||
break;
|
||||
case(BIND_OVERALL):
|
||||
geom->setNormalBinding(Geometry::BIND_OVERALL);
|
||||
break;
|
||||
case(BIND_PERPRIM):
|
||||
geom->setNormalBinding(Geometry::BIND_PER_PRIMITIVE);
|
||||
break;
|
||||
case(BIND_PERVERTEX):
|
||||
geom->setNormalBinding(Geometry::BIND_PER_VERTEX);
|
||||
break;
|
||||
default:
|
||||
geom->setNormalBinding(Geometry::BIND_OFF);
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_color_binding)
|
||||
{
|
||||
case(BIND_OFF):
|
||||
geom->setColorBinding(Geometry::BIND_OFF);
|
||||
break;
|
||||
case(BIND_OVERALL):
|
||||
geom->setColorBinding(Geometry::BIND_OVERALL);
|
||||
break;
|
||||
case(BIND_PERPRIM):
|
||||
geom->setColorBinding(Geometry::BIND_PER_PRIMITIVE);
|
||||
break;
|
||||
case(BIND_PERVERTEX):
|
||||
geom->setColorBinding(Geometry::BIND_PER_VERTEX);
|
||||
break;
|
||||
default:
|
||||
geom->setColorBinding(Geometry::BIND_OFF);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (_fast_path)
|
||||
{
|
||||
// will easily convert into a Geometry.
|
||||
|
||||
if (_coords) geom->setVertexArray(osgNew Vec3Array(_numcoords,_coords));
|
||||
|
||||
if (_normals) geom->setNormalArray(osgNew Vec3Array(_numnormals,_normals));
|
||||
|
||||
if (_colors) geom->setColorArray(osgNew Vec4Array(_numcolors,_colors));
|
||||
|
||||
if (_tcoords) geom->setTexCoordArray(0,osgNew Vec2Array(_numtcoords,_tcoords));
|
||||
|
||||
if( _needprimlen ) // LINE_STRIP, LINE_LOOP, TRIANGLE_STRIP,
|
||||
// TRIANGLE_FAN, QUAD_STRIP, POLYGONS
|
||||
{
|
||||
int index = 0;
|
||||
if( _primLengths == (int *)0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( int i = 0; i < _numprims; i++ )
|
||||
{
|
||||
if( _cindex.valid() )
|
||||
{
|
||||
UShortDrawElements* n = new UShortDrawElements;
|
||||
geom->addPrimitive(n);
|
||||
|
||||
if (_cindex._is_ushort)
|
||||
geom->addPrimitive(osgNew UShortDrawElements( (GLenum)_oglprimtype, _primLengths[i],&_cindex._ptr._ushort[index] ));
|
||||
else
|
||||
geom->addPrimitive(osgNew UIntDrawElements( (GLenum)_oglprimtype, _primLengths[i], &_cindex._ptr._uint[index] ));
|
||||
}
|
||||
else
|
||||
geom->addPrimitive(osgNew DrawArrays( (GLenum)_oglprimtype, index, _primLengths[i] ));
|
||||
|
||||
index += _primLengths[i];
|
||||
}
|
||||
}
|
||||
else // POINTS, LINES, TRIANGLES, QUADS
|
||||
{
|
||||
if( _cindex.valid())
|
||||
{
|
||||
if (_cindex._is_ushort)
|
||||
geom->addPrimitive(osgNew UShortDrawElements( (GLenum)_oglprimtype, _cindex._size, _cindex._ptr._ushort ));
|
||||
else
|
||||
geom->addPrimitive(osgNew UIntDrawElements( (GLenum)_oglprimtype, _cindex._size, _cindex._ptr._uint ));
|
||||
}
|
||||
else
|
||||
geom->addPrimitive(new DrawArrays( (GLenum)_oglprimtype, 0, _numcoords ));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if( _needprimlen )
|
||||
{
|
||||
// slow path, and needing handling of primlen array.
|
||||
//
|
||||
// LINE_STRIP, LINE_LOOP, TRIANGLE_STRIP,
|
||||
// TRIANGLE_FAN, QUAD_STRIP, POLYGONS
|
||||
// FLAT_LINE_STRIP, FLAT_TRIANGLE_STRIP, FLAT_TRIANGLE_FAN
|
||||
|
||||
int i, j;
|
||||
int index = 0;
|
||||
int ai = 0;
|
||||
int ci = 0;
|
||||
int ni = 0;
|
||||
int ti = 0;
|
||||
|
||||
if( _primLengths == (int *)0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Vec3Array* coords = osgNew Vec3Array;
|
||||
Vec3Array* normals = 0;
|
||||
Vec4Array* colors = 0;
|
||||
Vec2Array* texcoords = 0;
|
||||
|
||||
if (_colors) colors = osgNew Vec4Array;
|
||||
if (_normals) normals = osgNew Vec3Array;
|
||||
if (_tcoords) texcoords = osgNew Vec2Array;
|
||||
|
||||
geom->setVertexArray(coords);
|
||||
geom->setColorArray(colors);
|
||||
geom->setNormalArray(normals);
|
||||
geom->setTexCoordArray(0,texcoords);
|
||||
|
||||
if (_color_binding == BIND_OVERALL)
|
||||
{
|
||||
if( _colindex.valid() )
|
||||
colors->push_back( _colors[_colindex[0]] );
|
||||
else
|
||||
colors->push_back( _colors[0] );
|
||||
}
|
||||
|
||||
if (_normal_binding == BIND_OVERALL)
|
||||
{
|
||||
if( _nindex.valid() )
|
||||
normals->push_back( _normals[0] );
|
||||
else
|
||||
normals->push_back( _normals[0] );
|
||||
}
|
||||
|
||||
for( i = 0; i < _numprims; i++ )
|
||||
{
|
||||
if (_color_binding == BIND_PERPRIM && colors)
|
||||
{
|
||||
if( _colindex.valid() )
|
||||
colors->push_back( _colors[_colindex[ci++]] );
|
||||
else
|
||||
colors->push_back( _colors[ci++] );
|
||||
}
|
||||
|
||||
if (_normal_binding == BIND_PERPRIM && normals)
|
||||
{
|
||||
if( _nindex.valid() )
|
||||
normals->push_back( _normals[_nindex[ni++]] );
|
||||
else
|
||||
normals->push_back( _normals[ni++] );
|
||||
}
|
||||
|
||||
unsigned int first = coords->size();
|
||||
unsigned int count = 0;
|
||||
|
||||
|
||||
for( j = 0; j < _primLengths[i]; j++ )
|
||||
{
|
||||
if( j >= _flat_shaded_skip )
|
||||
{
|
||||
if( _color_binding == BIND_PERVERTEX && colors)
|
||||
{
|
||||
if( (_colindex.valid()) )
|
||||
colors->push_back( _colors[_colindex[ci++]] );
|
||||
else
|
||||
colors->push_back( _colors[ci++] );
|
||||
}
|
||||
|
||||
if( _normal_binding == BIND_PERVERTEX && normals)
|
||||
{
|
||||
if(_nindex.valid())
|
||||
normals->push_back( _normals[_nindex[ni++]] );
|
||||
else
|
||||
normals->push_back( _normals[ni++] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// note don't increment ci & ni as we want to make multiple copies it when in _flat_shaded_skip
|
||||
if( _color_binding == BIND_PERVERTEX && colors)
|
||||
{
|
||||
if( (_colindex.valid()) )
|
||||
colors->push_back( _colors[_colindex[ci]] );
|
||||
else
|
||||
colors->push_back( _colors[ci] );
|
||||
}
|
||||
|
||||
if( _normal_binding == BIND_PERVERTEX && normals )
|
||||
{
|
||||
if(_nindex.valid())
|
||||
normals->push_back( _normals[_nindex[ni]] );
|
||||
else
|
||||
normals->push_back( _normals[ni] );
|
||||
}
|
||||
}
|
||||
|
||||
if( _texture_binding == BIND_PERVERTEX && texcoords)
|
||||
{
|
||||
if( _tindex.valid() )
|
||||
texcoords->push_back( _tcoords[_tindex[ti++]] );
|
||||
else
|
||||
texcoords->push_back( _tcoords[ti++] );
|
||||
}
|
||||
|
||||
if( _cindex.valid() )
|
||||
coords->push_back( _coords[_cindex[ai++]] );
|
||||
else
|
||||
coords->push_back( _coords[ai++] );
|
||||
|
||||
++count;
|
||||
|
||||
}
|
||||
|
||||
geom->addPrimitive(osgNew DrawArrays(_oglprimtype,first,count));
|
||||
|
||||
index += _primLengths[i];
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Vec3Array* coords = osgNew Vec3Array;
|
||||
Vec3Array* normals = 0;
|
||||
Vec4Array* colors = 0;
|
||||
Vec2Array* texcoords = 0;
|
||||
|
||||
if (_colors) colors = osgNew Vec4Array;
|
||||
if (_normals) normals = osgNew Vec3Array;
|
||||
if (_tcoords) texcoords = osgNew Vec2Array;
|
||||
|
||||
geom->setVertexArray(coords);
|
||||
geom->setColorArray(colors);
|
||||
geom->setNormalArray(normals);
|
||||
geom->setTexCoordArray(0,texcoords);
|
||||
|
||||
if (_color_binding == BIND_OVERALL)
|
||||
{
|
||||
if( _colindex.valid() )
|
||||
colors->push_back( _colors[_colindex[0]] );
|
||||
else
|
||||
colors->push_back( _colors[0] );
|
||||
}
|
||||
|
||||
if (_normal_binding == BIND_OVERALL)
|
||||
{
|
||||
if( _nindex.valid() )
|
||||
normals->push_back( _normals[_nindex[0]] );
|
||||
else
|
||||
normals->push_back( _normals[0] );
|
||||
}
|
||||
|
||||
for(int i = 0; i < _numprims; i++ )
|
||||
{
|
||||
if (_color_binding == BIND_PERPRIM && colors)
|
||||
{
|
||||
if( _colindex.valid() )
|
||||
colors->push_back( _colors[_colindex[i]] );
|
||||
else
|
||||
colors->push_back( _colors[i] );
|
||||
}
|
||||
|
||||
if (_normal_binding == BIND_PERPRIM && normals)
|
||||
{
|
||||
if( _nindex.valid() )
|
||||
normals->push_back( _normals[_nindex[i]] );
|
||||
else
|
||||
normals->push_back( _normals[i] );
|
||||
}
|
||||
|
||||
unsigned int first = coords->size();
|
||||
unsigned int count = 0;
|
||||
|
||||
for(int j = 0; j < _primlength; j++ )
|
||||
{
|
||||
if( _color_binding == BIND_PERVERTEX && colors)
|
||||
{
|
||||
if( (_colindex.valid()) )
|
||||
colors->push_back( _colors[_colindex[i*_primlength+j]] );
|
||||
else
|
||||
colors->push_back( _colors[i*_primlength+j] );
|
||||
}
|
||||
|
||||
if( _normal_binding == BIND_PERVERTEX && normals )
|
||||
{
|
||||
if(_nindex.valid())
|
||||
normals->push_back( _normals[_nindex[i*_primlength+j]] );
|
||||
else
|
||||
normals->push_back( _normals[i*_primlength+j] );
|
||||
}
|
||||
|
||||
if( _texture_binding == BIND_PERVERTEX && texcoords)
|
||||
{
|
||||
if( _tindex.valid() )
|
||||
texcoords->push_back( _tcoords[_tindex[i*_primlength+j]] );
|
||||
else
|
||||
texcoords->push_back( _tcoords[i*_primlength+j] );
|
||||
}
|
||||
|
||||
if( _cindex.valid() )
|
||||
coords->push_back( _coords[_cindex[i*_primlength+j]] );
|
||||
else
|
||||
coords->push_back( _coords[i*_primlength+j] );
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
geom->addPrimitive(osgNew DrawArrays(_oglprimtype,first,count));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return geom.take();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ using namespace osg;
|
||||
|
||||
Geometry::Geometry()
|
||||
{
|
||||
_normalBinding = OFF;
|
||||
_colorBinding = OFF;
|
||||
_normalBinding = BIND_OFF;
|
||||
_colorBinding = BIND_OFF;
|
||||
}
|
||||
|
||||
Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop):
|
||||
@@ -70,17 +70,17 @@ void Geometry::drawImmediateMode(State& /*state*/)
|
||||
|
||||
switch (_normalBinding)
|
||||
{
|
||||
case(OFF):
|
||||
case(BIND_OFF):
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
break;
|
||||
case(OVERALL):
|
||||
case(BIND_OVERALL):
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
if (normalPointer) glNormal3fv(reinterpret_cast<const GLfloat*>(normalPointer));
|
||||
break;
|
||||
case(BIND_PER_PRIMITIVE):
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
break;
|
||||
case(PER_PRIMITIVE):
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
break;
|
||||
case(PER_VERTEX):
|
||||
case(BIND_PER_VERTEX):
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
if (normalPointer) glNormalPointer(GL_FLOAT,0,normalPointer);
|
||||
break;
|
||||
@@ -121,10 +121,10 @@ void Geometry::drawImmediateMode(State& /*state*/)
|
||||
|
||||
switch (_colorBinding)
|
||||
{
|
||||
case(OFF):
|
||||
case(BIND_OFF):
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
break;
|
||||
case(OVERALL):
|
||||
case(BIND_OVERALL):
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
if (colorPointer)
|
||||
{
|
||||
@@ -142,10 +142,10 @@ void Geometry::drawImmediateMode(State& /*state*/)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case(PER_PRIMITIVE):
|
||||
case(BIND_PER_PRIMITIVE):
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
break;
|
||||
case(PER_VERTEX):
|
||||
case(BIND_PER_VERTEX):
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
if (colorPointer) glColorPointer(_colorArray->dataSize(),_colorArray->dataType(),0,colorPointer);
|
||||
}
|
||||
@@ -156,12 +156,12 @@ void Geometry::drawImmediateMode(State& /*state*/)
|
||||
itr!=_primitives.end();
|
||||
++itr)
|
||||
{
|
||||
if (_normalBinding==PER_PRIMITIVE)
|
||||
if (_normalBinding==BIND_PER_PRIMITIVE)
|
||||
{
|
||||
glNormal3fv((const GLfloat *)normalPointer++);
|
||||
}
|
||||
|
||||
if (_colorBinding==PER_PRIMITIVE)
|
||||
if (_colorBinding==BIND_PER_PRIMITIVE)
|
||||
{
|
||||
switch(colorType)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <osg/LOD>
|
||||
#include <osg/Impostor>
|
||||
#include <osg/Billboard>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <typeinfo>
|
||||
@@ -18,6 +20,7 @@ using namespace osgUtil;
|
||||
void Optimizer::optimize(osg::Node* node, unsigned int options)
|
||||
{
|
||||
|
||||
|
||||
if (options & COMBINE_ADJACENT_LODS)
|
||||
{
|
||||
CombineLODsVisitor clv;
|
||||
@@ -30,15 +33,42 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
|
||||
FlattenStaticTransformsVisitor fstv;
|
||||
node->accept(fstv);
|
||||
fstv.removeTransforms();
|
||||
|
||||
// the following RemoveLowestStaticTransformVisitor doesn't yet work
|
||||
// properly, will need further work.... Robert Osfield, June 2002.
|
||||
// int i=0;
|
||||
// bool result = false;
|
||||
// do
|
||||
// {
|
||||
// cout << "************ RemoveLowestStaticTransformsVisitor "<<i<<endl;
|
||||
// RemoveLowestStaticTransformsVisitor fstv;
|
||||
// node->accept(fstv);
|
||||
// result = fstv.removeTransforms();
|
||||
// ++i;
|
||||
// } while (result);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (options & REMOVE_REDUNDENT_NODES)
|
||||
{
|
||||
|
||||
RemoveEmptyNodesVisitor renv;
|
||||
node->accept(renv);
|
||||
renv.removeEmptyNodes();
|
||||
|
||||
RemoveRedundentNodesVisitor rrnv;
|
||||
node->accept(rrnv);
|
||||
rrnv.removeRedundentNodes();
|
||||
|
||||
}
|
||||
|
||||
// // convert the old style GeoSet to Geometry
|
||||
// ConvertGeoSetsToGeometryVisitor cgtg;
|
||||
// node->accept(cgtg);
|
||||
|
||||
|
||||
if (options & SHARE_DUPLICATE_STATE)
|
||||
{
|
||||
#if (defined(_MSC_VER) && _MSC_VER<1300 && !defined(_STLPORT_VERSION))
|
||||
@@ -50,6 +80,9 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
class TransformFunctor : public osg::Drawable::AttributeFunctor
|
||||
@@ -94,6 +127,34 @@ class TransformFunctor : public osg::Drawable::AttributeFunctor
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Convert GeoSet To Geometry Visitor.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Optimizer::ConvertGeoSetsToGeometryVisitor::apply(osg::Geode& geode)
|
||||
{
|
||||
for(int i=0;i<geode.getNumDrawables();++i)
|
||||
{
|
||||
osg::GeoSet* geoset = dynamic_cast<osg::GeoSet*>(geode.getDrawable(i));
|
||||
if (geoset)
|
||||
{
|
||||
osg::Geometry* geom = geoset->convertToGeometry();
|
||||
if (geom)
|
||||
{
|
||||
std::cout<<"Successfully converted GeoSet to Geometry"<<std::endl;
|
||||
geode.replaceDrawable(geoset,geom);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout<<"*** Failed to convert GeoSet to Geometry"<<std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Optimize State Visitor
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -153,7 +214,6 @@ void Optimizer::StateVisitor::optimize()
|
||||
{
|
||||
osg::notify(osg::INFO) << "Num of StateSet="<<_statesets.size()<< std::endl;
|
||||
|
||||
|
||||
{
|
||||
// create map from state attributes to stateset which contain them.
|
||||
typedef std::set<osg::StateSet*> StateSetList;
|
||||
@@ -335,13 +395,18 @@ void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Transform& transform)
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::ref_ptr<osg::Matrix> matrix = osgNew osg::Matrix;
|
||||
osg::ref_ptr<osg::Matrix> matrix;
|
||||
if (_matrixStack.empty())
|
||||
{
|
||||
matrix = osgNew osg::Matrix;
|
||||
}
|
||||
else
|
||||
{
|
||||
matrix = osgNew osg::Matrix(_matrixStack.back());
|
||||
}
|
||||
|
||||
transform.getLocalToWorldMatrix(*matrix,this);
|
||||
|
||||
if (!_matrixStack.empty())
|
||||
{
|
||||
matrix->postMult(_matrixStack.back());
|
||||
}
|
||||
_matrixStack.push_back(*matrix);
|
||||
|
||||
_transformStack.push_back(&transform);
|
||||
@@ -523,8 +588,6 @@ void Optimizer::FlattenStaticTransformsVisitor::removeTransforms()
|
||||
{
|
||||
if (titr->second._canBeApplied)
|
||||
{
|
||||
|
||||
|
||||
osg::ref_ptr<osg::Transform> transform = titr->first;
|
||||
osg::ref_ptr<osg::Group> group = osgNew osg::Group;
|
||||
group->setDataVariance(osg::Object::STATIC);
|
||||
@@ -548,6 +611,342 @@ void Optimizer::FlattenStaticTransformsVisitor::removeTransforms()
|
||||
_matrixStack.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Flatten static transforms
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Optimizer::RemoveLowestStaticTransformsVisitor::apply(osg::Geode& geode)
|
||||
{
|
||||
osg::Transform* transform = NULL;
|
||||
if (!_transformStack.back()) transform = _transformStack.back();
|
||||
|
||||
osg::Matrix matrix;
|
||||
if (!_matrixStack.empty()) matrix = _matrixStack.back();
|
||||
|
||||
for(int i=0;i<geode.getNumDrawables();++i)
|
||||
{
|
||||
// register each drawable with the objectMap.
|
||||
_objectMap[geode.getDrawable(i)].add(transform,matrix);
|
||||
}
|
||||
}
|
||||
|
||||
void Optimizer::RemoveLowestStaticTransformsVisitor::apply(osg::Billboard& billboard)
|
||||
{
|
||||
if (!_matrixStack.empty())
|
||||
{
|
||||
// register ourselves with the objectMap.
|
||||
_objectMap[&billboard].add(_transformStack.back(),_matrixStack.back());
|
||||
}
|
||||
}
|
||||
|
||||
void Optimizer::RemoveLowestStaticTransformsVisitor::apply(osg::LOD& lod)
|
||||
{
|
||||
if (!_matrixStack.empty())
|
||||
{
|
||||
// register ourselves with the objectMap.
|
||||
_objectMap[&lod].add(_transformStack.back(),_matrixStack.back());
|
||||
}
|
||||
|
||||
traverse(lod);
|
||||
}
|
||||
|
||||
void Optimizer::RemoveLowestStaticTransformsVisitor::apply(osg::Transform& transform)
|
||||
{
|
||||
|
||||
|
||||
if (_ignoreDynamicTransforms && transform.getDataVariance()==osg::Object::DYNAMIC)
|
||||
{
|
||||
// simple traverse the children as if this Transform didn't exist.
|
||||
traverse(transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_matrixStack.empty())
|
||||
{
|
||||
_transformMap[&transform]._containsTransform=false;
|
||||
}
|
||||
|
||||
osg::Matrix matrix;
|
||||
transform.getLocalToWorldMatrix(matrix,this);
|
||||
|
||||
_matrixStack.push_back(matrix);
|
||||
|
||||
_transformStack.push_back(&transform);
|
||||
|
||||
// simple traverse the children as if this Transform didn't exist.
|
||||
traverse(transform);
|
||||
|
||||
_transformStack.pop_back();
|
||||
|
||||
_matrixStack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void Optimizer::RemoveLowestStaticTransformsVisitor::doTransform(osg::Object* obj,osg::Matrix& matrix)
|
||||
{
|
||||
osg::Drawable* drawable = dynamic_cast<osg::Drawable*>(obj);
|
||||
if (drawable)
|
||||
{
|
||||
TransformFunctor tf(matrix);
|
||||
drawable->applyAttributeOperation(tf);
|
||||
drawable->dirtyBound();
|
||||
return;
|
||||
}
|
||||
|
||||
osg::LOD* lod = dynamic_cast<osg::LOD*>(obj);
|
||||
if (lod)
|
||||
{
|
||||
osg::Matrix matrix_no_trans = matrix;
|
||||
matrix_no_trans.setTrans(0.0f,0.0f,0.0f);
|
||||
|
||||
osg::Vec3 v111(1.0f,1.0f,1.0f);
|
||||
osg::Vec3 new_v111 = v111*matrix_no_trans;
|
||||
float ratio = new_v111.length()/v111.length();
|
||||
|
||||
// move center point.
|
||||
lod->setCenter(lod->getCenter()*matrix);
|
||||
|
||||
// adjust ranges to new scale.
|
||||
for(unsigned int i=0;i<lod->getNumRanges();++i)
|
||||
{
|
||||
lod->setRange(i,lod->getRange(i)*ratio);
|
||||
}
|
||||
|
||||
lod->dirtyBound();
|
||||
return;
|
||||
}
|
||||
|
||||
osg::Billboard* billboard = dynamic_cast<osg::Billboard*>(obj);
|
||||
if (billboard)
|
||||
{
|
||||
osg::Matrix matrix_no_trans = matrix;
|
||||
matrix_no_trans.setTrans(0.0f,0.0f,0.0f);
|
||||
|
||||
TransformFunctor tf(matrix_no_trans);
|
||||
|
||||
osg::Vec3 axis = osg::Matrix::transform3x3(tf._im,billboard->getAxis());
|
||||
axis.normalize();
|
||||
billboard->setAxis(axis);
|
||||
|
||||
for(int i=0;i<billboard->getNumDrawables();++i)
|
||||
{
|
||||
billboard->setPos(i,billboard->getPos(i)*matrix);
|
||||
billboard->getDrawable(i)->applyAttributeOperation(tf);
|
||||
}
|
||||
|
||||
billboard->dirtyBound();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Optimizer::RemoveLowestStaticTransformsVisitor::disableObject(ObjectMap::iterator itr)
|
||||
{
|
||||
if (itr==_objectMap.end())
|
||||
{
|
||||
// Euston we have a problem..
|
||||
osg::notify(osg::WARN)<<"Warning: internal error Optimizer::RemoveLowestStaticTransformsVisitor::disableObject()"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (itr->second._canBeApplied)
|
||||
{
|
||||
// we havn't been disabled yet so we need to disable,
|
||||
itr->second._canBeApplied = false;
|
||||
|
||||
// and then inform everybody we have been disabled.
|
||||
for(ObjectStruct::TransformSet::iterator titr = itr->second._transformSet.begin();
|
||||
titr != itr->second._transformSet.end();
|
||||
++titr)
|
||||
{
|
||||
disableTransform(*titr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Optimizer::RemoveLowestStaticTransformsVisitor::disableTransform(osg::Transform* transform)
|
||||
{
|
||||
TransformMap::iterator itr=_transformMap.find(transform);
|
||||
if (itr==_transformMap.end())
|
||||
{
|
||||
// Euston we have a problem..
|
||||
osg::notify(osg::WARN)<<"Warning: internal error Optimizer::RemoveLowestStaticTransformsVisitor::disableTransform()"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (itr->second._canBeApplied)
|
||||
{
|
||||
|
||||
// we havn't been disabled yet so we need to disable,
|
||||
itr->second._canBeApplied = false;
|
||||
// and then inform everybody we have been disabled.
|
||||
for(TransformStruct::ObjectSet::iterator oitr = itr->second._objectSet.begin();
|
||||
oitr != itr->second._objectSet.end();
|
||||
++oitr)
|
||||
{
|
||||
disableObject(*oitr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Optimizer::RemoveLowestStaticTransformsVisitor::removeTransforms()
|
||||
{
|
||||
|
||||
// create the TransformMap from the ObjectMap
|
||||
ObjectMap::iterator oitr;
|
||||
for(oitr=_objectMap.begin();
|
||||
oitr!=_objectMap.end();
|
||||
++oitr)
|
||||
{
|
||||
osg::Object* object = oitr->first;
|
||||
ObjectStruct& os = oitr->second;
|
||||
|
||||
for(ObjectStruct::TransformSet::iterator titr = os._transformSet.begin();
|
||||
titr != os._transformSet.end();
|
||||
++titr)
|
||||
{
|
||||
_transformMap[*titr].add(object);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(TransformMap::iterator titr=_transformMap.begin();
|
||||
titr!=_transformMap.end();
|
||||
++titr)
|
||||
{
|
||||
TransformStruct& ts = titr->second;
|
||||
if (ts._containsTransform)
|
||||
{
|
||||
disableTransform(titr->first);
|
||||
}
|
||||
}
|
||||
|
||||
// disable all the objects which have more than one matrix associated
|
||||
// with them, and then disable all transforms which have an object associated
|
||||
// them that can't be applied, and then disable all objects which have
|
||||
// disabled transforms associated, recursing until all disabled
|
||||
// associativity.
|
||||
for(oitr=_objectMap.begin();
|
||||
oitr!=_objectMap.end();
|
||||
++oitr)
|
||||
{
|
||||
ObjectStruct& os = oitr->second;
|
||||
if (os._canBeApplied)
|
||||
{
|
||||
if (os._moreThanOneMatrixRequired)
|
||||
{
|
||||
disableObject(oitr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// transform the objects that can be applied.
|
||||
for(oitr=_objectMap.begin();
|
||||
oitr!=_objectMap.end();
|
||||
++oitr)
|
||||
{
|
||||
osg::Object* object = oitr->first;
|
||||
ObjectStruct& os = oitr->second;
|
||||
if (os._canBeApplied)
|
||||
{
|
||||
doTransform(object,os._matrix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool transformsRemoved = false;
|
||||
|
||||
// clean up the transforms.
|
||||
for(TransformMap::iterator titr=_transformMap.begin();
|
||||
titr!=_transformMap.end();
|
||||
++titr)
|
||||
{
|
||||
if (titr->second._canBeApplied && titr->first)
|
||||
{
|
||||
osg::ref_ptr<osg::Transform> transform = titr->first;
|
||||
osg::ref_ptr<osg::Group> group = osgNew osg::Group;
|
||||
group->setDataVariance(osg::Object::STATIC);
|
||||
for(unsigned int i=0;i<transform->getNumChildren();++i)
|
||||
{
|
||||
for(unsigned int j=0;j<transform->getNumParents();++j)
|
||||
{
|
||||
group->addChild(transform->getChild(i));
|
||||
}
|
||||
}
|
||||
|
||||
for(int i2=transform->getNumParents()-1;i2>=0;--i2)
|
||||
{
|
||||
transform->getParent(i2)->replaceChild(transform.get(),group.get());
|
||||
}
|
||||
transformsRemoved = true;
|
||||
}
|
||||
}
|
||||
_objectMap.clear();
|
||||
_transformMap.clear();
|
||||
_transformStack.clear();
|
||||
_matrixStack.clear();
|
||||
|
||||
return transformsRemoved;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// RemoveEmptyNodes.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Geode& geode)
|
||||
{
|
||||
if (geode.getNumParents()>0)
|
||||
{
|
||||
if (geode.getNumDrawables()==0) _redundentNodeList.insert(&geode);
|
||||
}
|
||||
}
|
||||
|
||||
void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Group& group)
|
||||
{
|
||||
if (group.getNumParents()>0)
|
||||
{
|
||||
if (group.getNumChildren()==0)
|
||||
{
|
||||
_redundentNodeList.insert(&group);
|
||||
}
|
||||
}
|
||||
traverse(group);
|
||||
}
|
||||
|
||||
void Optimizer::RemoveEmptyNodesVisitor::removeEmptyNodes()
|
||||
{
|
||||
|
||||
NodeList newEmptyGroups;
|
||||
|
||||
// keep iterator through until scene graph is cleaned of empty nodes.
|
||||
while (!_redundentNodeList.empty())
|
||||
{
|
||||
for(NodeList::iterator itr=_redundentNodeList.begin();
|
||||
itr!=_redundentNodeList.end();
|
||||
++itr)
|
||||
{
|
||||
|
||||
osg::Node* nodeToRemove = (*itr);
|
||||
|
||||
// take a copy of parents list since subsequent removes will modify the original one.
|
||||
osg::Node::ParentList parents = nodeToRemove->getParents();
|
||||
|
||||
for(osg::Node::ParentList::iterator pitr=parents.begin();
|
||||
pitr!=parents.end();
|
||||
++pitr)
|
||||
{
|
||||
(*pitr)->removeChild(nodeToRemove);
|
||||
if ((*pitr)->getNumChildren()==0) newEmptyGroups.insert(*pitr);
|
||||
}
|
||||
}
|
||||
|
||||
_redundentNodeList.clear();
|
||||
_redundentNodeList.swap(newEmptyGroups);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// RemoveRedundentNodes.
|
||||
@@ -555,24 +954,42 @@ void Optimizer::FlattenStaticTransformsVisitor::removeTransforms()
|
||||
|
||||
void Optimizer::RemoveRedundentNodesVisitor::apply(osg::Group& group)
|
||||
{
|
||||
if (typeid(group)==typeid(osg::Group))
|
||||
if (group.getNumParents()>0)
|
||||
{
|
||||
if (group.getNumParents()>0 && group.getNumChildren()<=1)
|
||||
if (group.getNumChildren()==1 && typeid(group)==typeid(osg::Group))
|
||||
{
|
||||
if (!group.getUserData() &&
|
||||
!group.getAppCallback() &&
|
||||
!group.getStateSet() &&
|
||||
group.getNodeMask()==0xffffffff)
|
||||
if (group.getNumParents()>0 && group.getNumChildren()<=1)
|
||||
{
|
||||
_redundentNodeList.insert(&group);
|
||||
if (!group.getUserData() &&
|
||||
!group.getAppCallback() &&
|
||||
!group.getStateSet() &&
|
||||
group.getNodeMask()==0xffffffff)
|
||||
{
|
||||
_redundentNodeList.insert(&group);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
traverse(group);
|
||||
}
|
||||
|
||||
void Optimizer::RemoveRedundentNodesVisitor::apply(osg::Transform& transform)
|
||||
{
|
||||
if (transform.getNumParents()>0)
|
||||
{
|
||||
static osg::Matrix identity;
|
||||
if (transform.getMatrix()==identity && transform.getDataVariance()==osg::Object::STATIC)
|
||||
{
|
||||
_redundentNodeList.insert(&transform);
|
||||
}
|
||||
}
|
||||
traverse(transform);
|
||||
}
|
||||
|
||||
|
||||
void Optimizer::RemoveRedundentNodesVisitor::removeRedundentNodes()
|
||||
{
|
||||
|
||||
for(NodeList::iterator itr=_redundentNodeList.begin();
|
||||
itr!=_redundentNodeList.end();
|
||||
++itr)
|
||||
@@ -582,17 +999,8 @@ void Optimizer::RemoveRedundentNodesVisitor::removeRedundentNodes()
|
||||
{
|
||||
// take a copy of parents list since subsequent removes will modify the original one.
|
||||
osg::Node::ParentList parents = group->getParents();
|
||||
|
||||
if (group->getNumChildren()==0)
|
||||
{
|
||||
for(osg::Node::ParentList::iterator pitr=parents.begin();
|
||||
pitr!=parents.end();
|
||||
++pitr)
|
||||
{
|
||||
(*pitr)->removeChild(group.get());
|
||||
}
|
||||
}
|
||||
else if (group->getNumChildren()==1)
|
||||
|
||||
if (group->getNumChildren()==1)
|
||||
{
|
||||
osg::Node* child = group->getChild(0);
|
||||
for(osg::Node::ParentList::iterator pitr=parents.begin();
|
||||
@@ -601,14 +1009,13 @@ void Optimizer::RemoveRedundentNodesVisitor::removeRedundentNodes()
|
||||
{
|
||||
(*pitr)->replaceChild(group.get(),child);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else // (group->getNumChildren()>1)
|
||||
{
|
||||
osg::notify(osg::WARN)<<"Warning: Optimizer::RemoveRedundentNodesVisitor has incorrectly assigned Group to remove."<<std::endl;
|
||||
osg::notify(osg::WARN)<<" Safely ignoring remove operation for this group."<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout<<"failed dynamic_cast"<<endl;
|
||||
}
|
||||
}
|
||||
_redundentNodeList.clear();
|
||||
@@ -616,7 +1023,6 @@ void Optimizer::RemoveRedundentNodesVisitor::removeRedundentNodes()
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// combine LOD's.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -48,20 +48,20 @@ void Tesselator::tesselate(osg::Vec3* coords,int numIndices, int* indices,InputB
|
||||
{
|
||||
init();
|
||||
_coordVec.reserve(numIndices);
|
||||
if (ibd==COUNTER_CLOCK_WISE)
|
||||
{
|
||||
if (ibd==COUNTER_CLOCK_WISE)
|
||||
{
|
||||
for(int i=0;i<numIndices;++i)
|
||||
{
|
||||
_coordVec.push_back(VertexIndexSet(this,coords[indices[i]],indices[i]));
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
for(int i=numIndices-1;i>=0;--i)
|
||||
{
|
||||
for(int i=numIndices-1;i>=0;--i)
|
||||
{
|
||||
_coordVec.push_back(VertexIndexSet(this,coords[indices[i]],indices[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
do_it();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user