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 {
|
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:
|
||||||
|
|
||||||
|
|||||||
@@ -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); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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.
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user