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:
Robert Osfield
2002-06-23 21:43:46 +00:00
parent bbc129e5c6
commit f2e215bf44
10 changed files with 1022 additions and 88 deletions

View File

@@ -12,6 +12,10 @@
namespace osg { namespace osg {
// forward declare so that we don't need to include the header.
class Geometry;
/** Encapsulates OpenGL drawing primitives, geometry and /** Encapsulates OpenGL drawing primitives, geometry and
optional binding of normal, color and texture coordinates. Used optional binding of normal, color and texture coordinates. Used
for representing the visible objects in the scene. State attributes 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); virtual AttributeBitMask applyAttributeOperation(AttributeFunctor& auf);
/** convinience function for converting GeoSet's to equivilant Geometry nodes.*/
Geometry* convertToGeometry();
protected: protected:

View File

@@ -88,8 +88,18 @@ class TemplateArray : public AttributeArray, public std::vector<T>
TemplateArray() : AttributeArray(ARRAYTYPE,DataSize,DataType) {} 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* cloneType() const { return osgNew TemplateArray(); }
virtual Object* clone(const CopyOp& copyop) const { return osgNew TemplateArray(*this,copyop); } virtual Object* clone(const CopyOp& copyop) const { return osgNew TemplateArray(*this,copyop); }
virtual const char* libraryName() const { return "osg"; } virtual const char* libraryName() const { return "osg"; }
@@ -115,7 +125,7 @@ typedef TemplateArray<Vec4,Vec4ArrayType,4,GL_FLOAT> Vec4Ar
enum PrimitiveType enum PrimitiveType
{ {
PrimitivePrimitiveType = 0, PrimitivePrimitiveType = 0,
DrawArrayPrimitiveType = 1, DrawArraysPrimitiveType = 1,
UByteDrawElementsPrimitiveType = 2, UByteDrawElementsPrimitiveType = 2,
UShortDrawElementsPrimitiveType = 3, UShortDrawElementsPrimitiveType = 3,
UIntDrawElementsPrimitiveType = 4, UIntDrawElementsPrimitiveType = 4,
@@ -124,7 +134,7 @@ enum PrimitiveType
static char* s_PrimitiveNames[] = static char* s_PrimitiveNames[] =
{ {
"Primitive", // 0 "Primitive", // 0
"DrawArray", // 1 "DrawArrays", // 1
"UByteDrawElements", // 2 "UByteDrawElements", // 2
"UShortDrawElements", // 3 "UShortDrawElements", // 3
"UIntDrawElements" // 4 "UIntDrawElements" // 4
@@ -164,31 +174,31 @@ class Primitive : public Object
PrimitiveType _primitiveType; PrimitiveType _primitiveType;
}; };
class DrawArray : public Primitive class DrawArrays : public Primitive
{ {
public: public:
DrawArray(): DrawArrays():
Primitive(DrawArrayPrimitiveType) Primitive(DrawArraysPrimitiveType)
{} {}
DrawArray(GLenum mode, GLint first, GLsizei count): DrawArrays(GLenum mode, GLint first, GLsizei count):
Primitive(DrawArrayPrimitiveType), Primitive(DrawArraysPrimitiveType),
_mode(mode), _mode(mode),
_first(first), _first(first),
_count(count) {} _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), Primitive(da,copyop),
_mode(da._mode), _mode(da._mode),
_first(da._first), _first(da._first),
_count(da._count) {} _count(da._count) {}
virtual Object* cloneType() const { return osgNew DrawArray(); } virtual Object* cloneType() const { return osgNew DrawArrays(); }
virtual Object* clone(const CopyOp& copyop) const { return osgNew DrawArray(*this,copyop); } virtual Object* clone(const CopyOp& copyop) const { return osgNew DrawArrays(*this,copyop); }
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const DrawArray*>(obj)!=NULL; } virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const DrawArrays*>(obj)!=NULL; }
virtual const char* libraryName() const { return "osg"; } 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 virtual void draw() const
{ {
@@ -200,15 +210,33 @@ class DrawArray : public Primitive
GLsizei _count; GLsizei _count;
}; };
template<typename T, int PRIMTYPE, int DataType> template<typename T, PrimitiveType PRIMTYPE, int DataType>
class DrawElements : public Primitive, public std::vector<T> class DrawElements : public Primitive, public std::vector<T>
{ {
public: 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): 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* cloneType() const { return osgNew DrawElements(); }
virtual Object* clone(const CopyOp& copyop) const { return osgNew DrawElements(*this,copyop); } virtual Object* clone(const CopyOp& copyop) const { return osgNew DrawElements(*this,copyop); }
@@ -252,10 +280,10 @@ class SG_EXPORT Geometry : public Drawable
enum AttributeBinding enum AttributeBinding
{ {
OFF=0, BIND_OFF=0,
OVERALL, BIND_OVERALL,
PER_PRIMITIVE, BIND_PER_PRIMITIVE,
PER_VERTEX, BIND_PER_VERTEX,
}; };
void setVertexArray(Vec3Array* array) { _vertexArray = array; } void setVertexArray(Vec3Array* array) { _vertexArray = array; }
@@ -266,7 +294,7 @@ class SG_EXPORT Geometry : public Drawable
void setNormalBinding(AttributeBinding ab) { _normalBinding = ab; } void setNormalBinding(AttributeBinding ab) { _normalBinding = ab; }
AttributeBinding getNormalBinding() const { return _normalBinding; } 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(); } Vec3Array* getNormalArray() { return _normalArray.get(); }
const Vec3Array* getNormalArray() const { 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; } void setColorBinding(AttributeBinding ab) { _colorBinding = ab; }
AttributeBinding getColorBinding() const { return _colorBinding; } 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(); } AttributeArray* getColorArray() { return _colorArray.get(); }
const AttributeArray* getColorArray() const { return _colorArray.get(); } const AttributeArray* getColorArray() const { return _colorArray.get(); }
@@ -292,7 +320,7 @@ class SG_EXPORT Geometry : public Drawable
PrimitiveList& getPrimitiveList() { return _primitives; } PrimitiveList& getPrimitiveList() { return _primitives; }
const PrimitiveList& getPrimitiveList() const { 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); }

View File

@@ -274,7 +274,7 @@ class SG_EXPORT Texture : public StateAttribute
{ {
// pad out handle list if required. // pad out handle list if required.
if (_handleList.size()<=contextID) if (_handleList.size()<=contextID)
_handleList.resize(contextID,0); _handleList.resize(contextID+1,0);
// get the globj for the current contextID. // get the globj for the current contextID.
return _handleList[contextID]; return _handleList[contextID];

View File

@@ -95,6 +95,12 @@ class ref_ptr
inline const T* get() const { return _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: private:
T* _ptr; T* _ptr;
}; };

View File

@@ -42,7 +42,19 @@ class OSGUTIL_EXPORT Optimizer
virtual void optimize(osg::Node* node, unsigned int options = ALL_OPTIMIZATIONS); 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 /** Flatten Static Trasform nodes by applying their transform to the
* geometry on the leaves of the scene graph, then removing the * geometry on the leaves of the scene graph, then removing the
* now redundent transforms.*/ * 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.*/ /** Remove rendundent nodes, such as groups with one single child.*/
class OSGUTIL_EXPORT RemoveRedundentNodesVisitor : public osg::NodeVisitor class OSGUTIL_EXPORT RemoveRedundentNodesVisitor : public osg::NodeVisitor
{ {
@@ -142,8 +261,9 @@ class OSGUTIL_EXPORT Optimizer
NodeList _redundentNodeList; NodeList _redundentNodeList;
RemoveRedundentNodesVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} RemoveRedundentNodesVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
virtual void apply(osg::Group& group); virtual void apply(osg::Group& group);
virtual void apply(osg::Transform& transform);
void removeRedundentNodes(); void removeRedundentNodes();

View File

@@ -13,7 +13,7 @@
#include <osg/Math> #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 // set up the primitives
cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,0,4)); cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,0,4));
cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,4,4)); cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,4,4));
cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,8,4)); cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,8,4));
cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,12,4)); cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,12,4));
cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,16,4)); cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,16,4));
cube->addPrimtive(new osg::DrawArray(osg::Primitive::POLYGON,20,4)); cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,20,4));
// set up coords. // set up coords.
@@ -244,7 +244,7 @@ osg::Geode* createGeometryCube()
(*cubeNormals)[5].set(0.0f,-1.0f,0.0f); (*cubeNormals)[5].set(0.0f,-1.0f,0.0f);
cube->setNormalArray( cubeNormals ); 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 // Set up a StateSet to make the cube red

View File

@@ -9,6 +9,9 @@
#include <osg/Notify> #include <osg/Notify>
#include <osg/Statistics> #include <osg/Statistics>
#include <osg/Geometry>
#include <osg/ShadeModel>
//#include <osg/mem_ptr> //#include <osg/mem_ptr>
using namespace osg; using namespace osg;
@@ -975,3 +978,367 @@ bool GeoSet::getStats(Statistics &stat)
stat.addNumPrims(type, nprimlens, numprimtypes, primverts); stat.addNumPrims(type, nprimlens, numprimtypes, primverts);
return true; 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();
}

View File

@@ -4,8 +4,8 @@ using namespace osg;
Geometry::Geometry() Geometry::Geometry()
{ {
_normalBinding = OFF; _normalBinding = BIND_OFF;
_colorBinding = OFF; _colorBinding = BIND_OFF;
} }
Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop): Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop):
@@ -70,17 +70,17 @@ void Geometry::drawImmediateMode(State& /*state*/)
switch (_normalBinding) switch (_normalBinding)
{ {
case(OFF): case(BIND_OFF):
glDisableClientState( GL_NORMAL_ARRAY ); glDisableClientState( GL_NORMAL_ARRAY );
break; break;
case(OVERALL): case(BIND_OVERALL):
glDisableClientState( GL_NORMAL_ARRAY );
if (normalPointer) glNormal3fv(reinterpret_cast<const GLfloat*>(normalPointer)); if (normalPointer) glNormal3fv(reinterpret_cast<const GLfloat*>(normalPointer));
break;
case(BIND_PER_PRIMITIVE):
glDisableClientState( GL_NORMAL_ARRAY ); glDisableClientState( GL_NORMAL_ARRAY );
break; break;
case(PER_PRIMITIVE): case(BIND_PER_VERTEX):
glDisableClientState( GL_NORMAL_ARRAY );
break;
case(PER_VERTEX):
glEnableClientState( GL_NORMAL_ARRAY ); glEnableClientState( GL_NORMAL_ARRAY );
if (normalPointer) glNormalPointer(GL_FLOAT,0,normalPointer); if (normalPointer) glNormalPointer(GL_FLOAT,0,normalPointer);
break; break;
@@ -121,10 +121,10 @@ void Geometry::drawImmediateMode(State& /*state*/)
switch (_colorBinding) switch (_colorBinding)
{ {
case(OFF): case(BIND_OFF):
glDisableClientState( GL_COLOR_ARRAY ); glDisableClientState( GL_COLOR_ARRAY );
break; break;
case(OVERALL): case(BIND_OVERALL):
glDisableClientState( GL_COLOR_ARRAY ); glDisableClientState( GL_COLOR_ARRAY );
if (colorPointer) if (colorPointer)
{ {
@@ -142,10 +142,10 @@ void Geometry::drawImmediateMode(State& /*state*/)
} }
} }
break; break;
case(PER_PRIMITIVE): case(BIND_PER_PRIMITIVE):
glDisableClientState( GL_COLOR_ARRAY ); glDisableClientState( GL_COLOR_ARRAY );
break; break;
case(PER_VERTEX): case(BIND_PER_VERTEX):
glEnableClientState( GL_COLOR_ARRAY ); glEnableClientState( GL_COLOR_ARRAY );
if (colorPointer) glColorPointer(_colorArray->dataSize(),_colorArray->dataType(),0,colorPointer); if (colorPointer) glColorPointer(_colorArray->dataSize(),_colorArray->dataType(),0,colorPointer);
} }
@@ -156,12 +156,12 @@ void Geometry::drawImmediateMode(State& /*state*/)
itr!=_primitives.end(); itr!=_primitives.end();
++itr) ++itr)
{ {
if (_normalBinding==PER_PRIMITIVE) if (_normalBinding==BIND_PER_PRIMITIVE)
{ {
glNormal3fv((const GLfloat *)normalPointer++); glNormal3fv((const GLfloat *)normalPointer++);
} }
if (_colorBinding==PER_PRIMITIVE) if (_colorBinding==BIND_PER_PRIMITIVE)
{ {
switch(colorType) switch(colorType)
{ {

View File

@@ -4,6 +4,8 @@
#include <osg/LOD> #include <osg/LOD>
#include <osg/Impostor> #include <osg/Impostor>
#include <osg/Billboard> #include <osg/Billboard>
#include <osg/Geometry>
#include <osg/GeoSet>
#include <osg/Notify> #include <osg/Notify>
#include <typeinfo> #include <typeinfo>
@@ -18,6 +20,7 @@ using namespace osgUtil;
void Optimizer::optimize(osg::Node* node, unsigned int options) void Optimizer::optimize(osg::Node* node, unsigned int options)
{ {
if (options & COMBINE_ADJACENT_LODS) if (options & COMBINE_ADJACENT_LODS)
{ {
CombineLODsVisitor clv; CombineLODsVisitor clv;
@@ -30,15 +33,42 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
FlattenStaticTransformsVisitor fstv; FlattenStaticTransformsVisitor fstv;
node->accept(fstv); node->accept(fstv);
fstv.removeTransforms(); 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) if (options & REMOVE_REDUNDENT_NODES)
{ {
RemoveEmptyNodesVisitor renv;
node->accept(renv);
renv.removeEmptyNodes();
RemoveRedundentNodesVisitor rrnv; RemoveRedundentNodesVisitor rrnv;
node->accept(rrnv); node->accept(rrnv);
rrnv.removeRedundentNodes(); rrnv.removeRedundentNodes();
} }
// // convert the old style GeoSet to Geometry
// ConvertGeoSetsToGeometryVisitor cgtg;
// node->accept(cgtg);
if (options & SHARE_DUPLICATE_STATE) if (options & SHARE_DUPLICATE_STATE)
{ {
#if (defined(_MSC_VER) && _MSC_VER<1300 && !defined(_STLPORT_VERSION)) #if (defined(_MSC_VER) && _MSC_VER<1300 && !defined(_STLPORT_VERSION))
@@ -50,6 +80,9 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
#endif #endif
} }
} }
class TransformFunctor : public osg::Drawable::AttributeFunctor 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 // Optimize State Visitor
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -153,7 +214,6 @@ void Optimizer::StateVisitor::optimize()
{ {
osg::notify(osg::INFO) << "Num of StateSet="<<_statesets.size()<< std::endl; osg::notify(osg::INFO) << "Num of StateSet="<<_statesets.size()<< std::endl;
{ {
// create map from state attributes to stateset which contain them. // create map from state attributes to stateset which contain them.
typedef std::set<osg::StateSet*> StateSetList; typedef std::set<osg::StateSet*> StateSetList;
@@ -335,13 +395,18 @@ void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Transform& transform)
} }
else 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); transform.getLocalToWorldMatrix(*matrix,this);
if (!_matrixStack.empty())
{
matrix->postMult(_matrixStack.back());
}
_matrixStack.push_back(*matrix); _matrixStack.push_back(*matrix);
_transformStack.push_back(&transform); _transformStack.push_back(&transform);
@@ -523,8 +588,6 @@ void Optimizer::FlattenStaticTransformsVisitor::removeTransforms()
{ {
if (titr->second._canBeApplied) if (titr->second._canBeApplied)
{ {
osg::ref_ptr<osg::Transform> transform = titr->first; osg::ref_ptr<osg::Transform> transform = titr->first;
osg::ref_ptr<osg::Group> group = osgNew osg::Group; osg::ref_ptr<osg::Group> group = osgNew osg::Group;
group->setDataVariance(osg::Object::STATIC); group->setDataVariance(osg::Object::STATIC);
@@ -548,6 +611,342 @@ void Optimizer::FlattenStaticTransformsVisitor::removeTransforms()
_matrixStack.clear(); _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. // RemoveRedundentNodes.
@@ -555,24 +954,42 @@ void Optimizer::FlattenStaticTransformsVisitor::removeTransforms()
void Optimizer::RemoveRedundentNodesVisitor::apply(osg::Group& group) 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() && if (group.getNumParents()>0 && group.getNumChildren()<=1)
!group.getAppCallback() &&
!group.getStateSet() &&
group.getNodeMask()==0xffffffff)
{ {
_redundentNodeList.insert(&group); if (!group.getUserData() &&
!group.getAppCallback() &&
!group.getStateSet() &&
group.getNodeMask()==0xffffffff)
{
_redundentNodeList.insert(&group);
}
} }
} }
} }
traverse(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() void Optimizer::RemoveRedundentNodesVisitor::removeRedundentNodes()
{ {
for(NodeList::iterator itr=_redundentNodeList.begin(); for(NodeList::iterator itr=_redundentNodeList.begin();
itr!=_redundentNodeList.end(); itr!=_redundentNodeList.end();
++itr) ++itr)
@@ -582,17 +999,8 @@ void Optimizer::RemoveRedundentNodesVisitor::removeRedundentNodes()
{ {
// take a copy of parents list since subsequent removes will modify the original one. // take a copy of parents list since subsequent removes will modify the original one.
osg::Node::ParentList parents = group->getParents(); osg::Node::ParentList parents = group->getParents();
if (group->getNumChildren()==0) if (group->getNumChildren()==1)
{
for(osg::Node::ParentList::iterator pitr=parents.begin();
pitr!=parents.end();
++pitr)
{
(*pitr)->removeChild(group.get());
}
}
else if (group->getNumChildren()==1)
{ {
osg::Node* child = group->getChild(0); osg::Node* child = group->getChild(0);
for(osg::Node::ParentList::iterator pitr=parents.begin(); for(osg::Node::ParentList::iterator pitr=parents.begin();
@@ -601,14 +1009,13 @@ void Optimizer::RemoveRedundentNodesVisitor::removeRedundentNodes()
{ {
(*pitr)->replaceChild(group.get(),child); (*pitr)->replaceChild(group.get(),child);
} }
} }
else // (group->getNumChildren()>1)
{ }
osg::notify(osg::WARN)<<"Warning: Optimizer::RemoveRedundentNodesVisitor has incorrectly assigned Group to remove."<<std::endl; else
osg::notify(osg::WARN)<<" Safely ignoring remove operation for this group."<<std::endl; {
} std::cout<<"failed dynamic_cast"<<endl;
} }
} }
_redundentNodeList.clear(); _redundentNodeList.clear();
@@ -616,7 +1023,6 @@ void Optimizer::RemoveRedundentNodesVisitor::removeRedundentNodes()
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// combine LOD's. // combine LOD's.
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////

View File

@@ -48,20 +48,20 @@ void Tesselator::tesselate(osg::Vec3* coords,int numIndices, int* indices,InputB
{ {
init(); init();
_coordVec.reserve(numIndices); _coordVec.reserve(numIndices);
if (ibd==COUNTER_CLOCK_WISE) if (ibd==COUNTER_CLOCK_WISE)
{ {
for(int i=0;i<numIndices;++i) for(int i=0;i<numIndices;++i)
{ {
_coordVec.push_back(VertexIndexSet(this,coords[indices[i]],indices[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])); _coordVec.push_back(VertexIndexSet(this,coords[indices[i]],indices[i]));
} }
} }
do_it(); do_it();
} }