Added osg::Drawable::PrimitiveFunctor and TriangleFunctor subclass for

querrying the primitive data inside Drawables.  Moved various support
classes over from being osg::GeoSet based to osg::Geometry based.
This commit is contained in:
Robert Osfield
2002-06-25 20:27:51 +00:00
parent 336c47e5fe
commit cbeeeefdab
20 changed files with 737 additions and 651 deletions

View File

@@ -15,7 +15,7 @@ class BoundingSphere;
/** General purpose axis-aligned bounding box class for enclosing objects/vertices.
Used to bounding the leaf objects in the scene,
i.e. osg::GeoSet's to assist in view frustum culling etc.
i.e. osg::Drawable's to assist in view frustum culling etc.
*/
class SG_EXPORT BoundingBox
{

View File

@@ -33,7 +33,7 @@ class Node;
#define USE_SEPERATE_COMPILE_AND_EXECUTE
/** Pure virtual base class for drawable Geometry. Contains no drawing primitives
directly, these are provided by subclasses such as GeoSet. State attributes
directly, these are provided by subclasses such as osg::Geometry. State attributes
for a Drawable are maintained in StateSet which the Drawable maintains
a referenced counted pointer to. Both Drawable's and StateSet's can
be shared for optimal memory usage and graphics performance.
@@ -41,7 +41,7 @@ class Node;
Subclasses should provide an instance of getStats(Statistics *st) if the subclass
contains drawing primitives. This member function should add the primitives it
draws into the Statistics class; for example add the number of quads, triangles etc
created. For an example see GeoSet.cpp:
created. For an example see Geometry.cpp:
getStats(osgUtil::Statistics *stat).
Failure to implement this routine will only result in the stats displayed for
your drawable being wrong.
@@ -261,6 +261,26 @@ class SG_EXPORT Drawable : public Object
virtual AttributeBitMask applyAttributeOperation(AttributeFunctor&) { return 0; }
class PrimitiveFunctor
{
public:
virtual void setVertexArray(unsigned int count,Vec3* vertices) = 0;
virtual void drawArrays(GLenum mode,GLint first,GLsizei count) = 0;
virtual void drawElements(GLenum mode,GLsizei count,unsigned char* indices) = 0;
virtual void drawElements(GLenum mode,GLsizei count,unsigned short* indices) = 0;
virtual void drawElements(GLenum mode,GLsizei count,unsigned int* indices) = 0;
virtual void begin(GLenum mode) = 0;
virtual void vertex(const Vec3& vert) = 0;
virtual void vertex(float x,float y,float z) = 0;
virtual void end() = 0;
};
/** apply the internal geometry as basic primitives to a PrimitiveFunctor.*/
virtual void applyPrimitiveOperation(PrimitiveFunctor&) {}
protected:
@@ -354,7 +374,329 @@ inline void Drawable::draw(State& state)
else
drawImmediateMode(state);
}
}
};
template<class T>
class TriangleFunctor : public Drawable::PrimitiveFunctor, public T
{
public:
TriangleFunctor()
{
_vertexArraySize=0;
_vertexArrayPtr=0;
_modeCache=0;
}
virtual ~TriangleFunctor() {}
virtual void setVertexArray(unsigned int count,Vec3* vertices)
{
_vertexArraySize = count;
_vertexArrayPtr = vertices;
}
virtual void drawArrays(GLenum mode,GLint first,GLsizei count)
{
if (_vertexArrayPtr==0 && count==0) return;
switch(mode)
{
case(GL_TRIANGLES):
{
Vec3* vlast = &_vertexArrayPtr[first+count];
for(Vec3* vptr=&_vertexArrayPtr[first];vptr<vlast;vptr+=3)
operator()(*(vptr),*(vptr+1),*(vptr+2));
break;
}
case(GL_TRIANGLE_STRIP):
{
Vec3* vptr = &_vertexArrayPtr[first];
for(GLsizei i=2;i<count;++i,++vptr)
{
if ((i%2)) operator()(*(vptr),*(vptr+2),*(vptr+1));
else operator()(*(vptr),*(vptr+1),*(vptr+2));
}
break;
}
case(GL_QUADS):
{
Vec3* vptr = &_vertexArrayPtr[first];
for(GLsizei i=3;i<count;i+=4,vptr+=4)
{
operator()(*(vptr),*(vptr+1),*(vptr+2));
operator()(*(vptr),*(vptr+2),*(vptr+3));
}
break;
}
case(GL_QUAD_STRIP):
{
Vec3* vptr = &_vertexArrayPtr[first];
for(GLsizei i=3;i<count;i+=2,vptr+=2)
{
operator()(*(vptr),*(vptr+1),*(vptr+2));
operator()(*(vptr),*(vptr+2),*(vptr+3));
}
break;
}
case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
case(GL_TRIANGLE_FAN):
{
Vec3* vfirst = &_vertexArrayPtr[first];
Vec3* vptr = vfirst+1;
for(GLsizei i=2;i<count;++i,++vptr)
{
operator()(*(vfirst),*(vptr),*(vptr+1));
}
break;
}
case(GL_POINTS):
case(GL_LINES):
case(GL_LINE_STRIP):
case(GL_LINE_LOOP):
default:
// can't be converted into to triangles.
break;
}
}
virtual void drawElements(GLenum mode,GLsizei count,unsigned char* indices)
{
if (indices==0 || count==0) return;
typedef unsigned char* IndexPointer;
switch(mode)
{
case(GL_TRIANGLES):
{
IndexPointer ilast = &indices[count];
for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
operator()(_vertexArrayPtr[*iptr],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
break;
}
case(GL_TRIANGLE_STRIP):
{
IndexPointer iptr = indices;
for(GLsizei i=2;i<count;++i,++iptr)
{
if ((i%2)) operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+1)]);
else operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
}
break;
}
case(GL_QUADS):
{
IndexPointer iptr = indices;
for(GLsizei i=3;i<count;i+=4,iptr+=4)
{
operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)]);
}
break;
}
case(GL_QUAD_STRIP):
{
IndexPointer iptr = indices;
for(GLsizei i=3;i<count;i+=2,iptr+=2)
{
operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)]);
}
break;
}
case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
case(GL_TRIANGLE_FAN):
{
IndexPointer iptr = indices;
Vec3& vfirst = _vertexArrayPtr[*iptr];
++iptr;
for(GLsizei i=2;i<count;++i,++iptr)
{
operator()(vfirst,_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)]);
}
break;
}
case(GL_POINTS):
case(GL_LINES):
case(GL_LINE_STRIP):
case(GL_LINE_LOOP):
default:
// can't be converted into to triangles.
break;
}
}
virtual void drawElements(GLenum mode,GLsizei count,unsigned short* indices)
{
if (indices==0 || count==0) return;
typedef unsigned short* IndexPointer;
switch(mode)
{
case(GL_TRIANGLES):
{
IndexPointer ilast = &indices[count];
for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
{
operator()(_vertexArrayPtr[*iptr],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
}
break;
}
case(GL_TRIANGLE_STRIP):
{
IndexPointer iptr = indices;
for(GLsizei i=2;i<count;++i,++iptr)
{
if ((i%2)) operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+1)]);
else operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
}
break;
}
case(GL_QUADS):
{
IndexPointer iptr = indices;
for(GLsizei i=3;i<count;i+=4,iptr+=4)
{
operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)]);
}
break;
}
case(GL_QUAD_STRIP):
{
IndexPointer iptr = indices;
for(GLsizei i=3;i<count;i+=2,iptr+=2)
{
operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)]);
}
break;
}
case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
case(GL_TRIANGLE_FAN):
{
IndexPointer iptr = indices;
Vec3& vfirst = _vertexArrayPtr[*iptr];
++iptr;
for(GLsizei i=2;i<count;++i,++iptr)
{
operator()(vfirst,_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)]);
}
break;
}
case(GL_POINTS):
case(GL_LINES):
case(GL_LINE_STRIP):
case(GL_LINE_LOOP):
default:
// can't be converted into to triangles.
break;
}
}
virtual void drawElements(GLenum mode,GLsizei count,unsigned int* indices)
{
if (indices==0 || count==0) return;
typedef unsigned int* IndexPointer;
switch(mode)
{
case(GL_TRIANGLES):
{
IndexPointer ilast = &indices[count];
for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
operator()(_vertexArrayPtr[*iptr],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
break;
}
case(GL_TRIANGLE_STRIP):
{
IndexPointer iptr = indices;
for(GLsizei i=2;i<count;++i,++iptr)
{
if ((i%2)) operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+1)]);
else operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
}
break;
}
case(GL_QUADS):
{
IndexPointer iptr = indices;
for(GLsizei i=3;i<count;i+=4,iptr+=4)
{
operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)]);
}
break;
}
case(GL_QUAD_STRIP):
{
IndexPointer iptr = indices;
for(GLsizei i=3;i<count;i+=2,iptr+=2)
{
operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)]);
}
break;
}
case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
case(GL_TRIANGLE_FAN):
{
IndexPointer iptr = indices;
Vec3& vfirst = _vertexArrayPtr[*iptr];
++iptr;
for(GLsizei i=2;i<count;++i,++iptr)
{
operator()(vfirst,_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)]);
}
break;
}
case(GL_POINTS):
case(GL_LINES):
case(GL_LINE_STRIP):
case(GL_LINE_LOOP):
default:
// can't be converted into to triangles.
break;
}
}
/** begin(..),vertex(..) & end() are convinience methods for adapting
* non vertex array primitives to vertex array based primitives.
* this is done to simplify the implementation of primtive functor
* subclasses - users only need override drawArray and drawElements.*/
inline void begin(GLenum mode)
{
_modeCache = mode;
_vertexCache.clear();
}
inline void vertex(const Vec3& vert) { _vertexCache.push_back(vert); }
inline void vertex(float x,float y,float z) { _vertexCache.push_back(osg::Vec3(x,y,z)); }
inline void end()
{
if (!_vertexCache.empty())
{
setVertexArray(_vertexCache.size(),&_vertexCache.front());
drawArrays(_modeCache,0,_vertexCache.size());
}
}
protected:
unsigned int _vertexArraySize;
Vec3* _vertexArrayPtr;
GLenum _modeCache;
std::vector<Vec3> _vertexCache;
};
}

View File

@@ -337,6 +337,8 @@ class SG_EXPORT GeoSet : public Drawable
/** return the attributes successully applied in applyAttributeUpdate.*/
virtual AttributeBitMask applyAttributeOperation(AttributeFunctor& auf);
/** apply the internal geometry as basic primitives to a PrimitiveFunctor.*/
virtual void applyPrimitiveOperation(PrimitiveFunctor& functor);
/** convinience function for converting GeoSet's to equivilant Geometry nodes.*/
Geometry* convertToGeometry();

View File

@@ -76,6 +76,10 @@ class TemplateArray : public AttributeArray, public std::vector<T>
AttributeArray(ta,copyop),
std::vector<T>(ta) {}
TemplateArray(unsigned int no) :
AttributeArray(ARRAYTYPE,DataSize,DataType),
std::vector<T>(no) {}
TemplateArray(unsigned int no,T* ptr) :
AttributeArray(ARRAYTYPE,DataSize,DataType),
std::vector<T>(ptr,ptr+no) {}
@@ -131,10 +135,14 @@ class Primitive : public Object
POLYGON = GL_POLYGON
};
Primitive(PrimitiveType primType=PrimitivePrimitiveType):_primitiveType(primType) {}
Primitive(PrimitiveType primType=PrimitivePrimitiveType,GLenum mode=0):
_primitiveType(primType),
_mode(mode) {}
Primitive(const Primitive& prim,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Object(prim,copyop) {}
Object(prim,copyop),
_primitiveType(prim._primitiveType),
_mode(prim._mode) {}
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Primitive*>(obj)!=NULL; }
virtual const char* libraryName() const { return "osg"; }
@@ -142,9 +150,17 @@ class Primitive : public Object
PrimitiveType primitiveType() const { return _primitiveType; }
void setMode(GLenum mode) { _mode = mode; }
GLenum getMode() const { return _mode; }
virtual void draw() const = 0;
virtual void applyPrimitiveOperation(Drawable::PrimitiveFunctor&) {}
protected:
PrimitiveType _primitiveType;
GLenum _mode;
};
class DrawArrays : public Primitive
@@ -152,18 +168,16 @@ class DrawArrays : public Primitive
public:
DrawArrays():
Primitive(DrawArraysPrimitiveType)
Primitive(DrawArraysPrimitiveType,0)
{}
DrawArrays(GLenum mode, GLint first, GLsizei count):
Primitive(DrawArraysPrimitiveType),
_mode(mode),
Primitive(DrawArraysPrimitiveType,mode),
_first(first),
_count(count) {}
DrawArrays(const DrawArrays& da,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Primitive(da,copyop),
_mode(da._mode),
_first(da._first),
_count(da._count) {}
@@ -174,30 +188,29 @@ class DrawArrays : public Primitive
virtual const char* className() const { return "DrawArrays"; }
void set(GLenum mode, GLint first, GLsizei count)
void set(GLenum mode,GLint first, GLsizei count)
{
_mode = mode;
_first = first;
_count = count;
}
void setMode(GLenum mode) { _mode = mode; }
GLenum getMode() const { return _mode; }
void setFirst(GLint first) { _first = first; }
GLint getFirst() const { return _first; }
void setCount(GLsizei count) { _count = count; }
GLsizei getCount() const { return _count; }
virtual void draw() const
{
glDrawArrays(_mode,_first,_count);
}
GLenum _mode;
virtual void applyPrimitiveOperation(Drawable::PrimitiveFunctor& functor)
{
functor.drawArrays(_mode,_first,_count);
}
GLint _first;
GLsizei _count;
};
@@ -208,42 +221,44 @@ class DrawElements : public Primitive, public std::vector<T>
public:
DrawElements(GLenum mode=0):
Primitive(PRIMTYPE),
_mode(mode),
Primitive(PRIMTYPE,mode),
_dataType(DataType) {}
DrawElements(const DrawElements& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Primitive(array,copyop),
std::vector<T>(array),
_mode(array._mode),
_dataType(array._dataType) {}
DrawElements(GLenum mode,unsigned int no,T* ptr) :
Primitive(PRIMTYPE),
Primitive(PRIMTYPE,mode),
std::vector<T>(ptr,ptr+no),
_mode(mode),
_dataType(DataType) {}
DrawElements(GLenum mode,unsigned int no) :
Primitive(PRIMTYPE,mode),
std::vector<T>(no),
_dataType(DataType) {}
DrawElements(GLenum mode, T* first,T* last) :
Primitive(PRIMTYPE),
Primitive(PRIMTYPE,mode),
std::vector<T>(first,last),
_mode(mode),
_dataType(DataType) {}
virtual Object* cloneType() const { return osgNew DrawElements(); }
virtual Object* clone(const CopyOp& copyop) const { return osgNew DrawElements(*this,copyop); }
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const DrawElements*>(obj)!=NULL; }
virtual const char* libraryName() const { return "osg"; }
void setMode(GLenum mode) { _mode = mode; }
GLenum getMode() const { return _mode; }
virtual void draw() const
{
glDrawElements(_mode,size(),_dataType,&front());
}
GLenum _mode;
virtual void applyPrimitiveOperation(Drawable::PrimitiveFunctor& functor)
{
if (!empty()) functor.drawElements(_mode,size(),&front());
}
GLenum _dataType;
};
@@ -255,8 +270,6 @@ typedef DrawElements<unsigned int,UIntDrawElementsPrimitiveType,GL_UNSIGNED_INT>
/* ******************************************************************************************************************* */
/** Experiemntal replacement for GeoSet.
*/
class SG_EXPORT Geometry : public Drawable
{
public:
@@ -280,15 +293,15 @@ class SG_EXPORT Geometry : public Drawable
BIND_PER_VERTEX,
};
void setVertexArray(Vec3Array* array) { _vertexArray = array; }
void setVertexArray(Vec3Array* array) { _vertexArray = array; dirtyDisplayList(); }
Vec3Array* getVertexArray() { return _vertexArray.get(); }
const Vec3Array* getVertexArray() const { return _vertexArray.get(); }
void setNormalBinding(AttributeBinding ab) { _normalBinding = ab; }
void setNormalBinding(AttributeBinding ab) { _normalBinding = ab; dirtyDisplayList(); }
AttributeBinding getNormalBinding() const { return _normalBinding; }
void setNormalArray(Vec3Array* array) { _normalArray = array; if (!_normalArray.valid()) _normalBinding=BIND_OFF; }
void setNormalArray(Vec3Array* array) { _normalArray = array; if (!_normalArray.valid()) _normalBinding=BIND_OFF; dirtyDisplayList(); }
Vec3Array* getNormalArray() { return _normalArray.get(); }
const Vec3Array* getNormalArray() const { return _normalArray.get(); }
@@ -296,7 +309,7 @@ class SG_EXPORT Geometry : public Drawable
void setColorBinding(AttributeBinding ab) { _colorBinding = ab; }
AttributeBinding getColorBinding() const { return _colorBinding; }
void setColorArray(AttributeArray* array) { _colorArray = array; if (!_colorArray.valid()) _colorBinding=BIND_OFF; }
void setColorArray(AttributeArray* array) { _colorArray = array; if (!_colorArray.valid()) _colorBinding=BIND_OFF; dirtyDisplayList(); }
AttributeArray* getColorArray() { return _colorArray.get(); }
const AttributeArray* getColorArray() const { return _colorArray.get(); }
@@ -315,11 +328,11 @@ class SG_EXPORT Geometry : public Drawable
typedef std::vector< ref_ptr<Primitive> > PrimitiveList;
void setPrimitiveList(const PrimitiveList& primitives) { _primitives = primitives; }
void setPrimitiveList(const PrimitiveList& primitives) { _primitives = primitives; dirtyDisplayList(); }
PrimitiveList& getPrimitiveList() { return _primitives; }
const PrimitiveList& getPrimitiveList() const { return _primitives; }
void addPrimitive(Primitive* primitive) { if (primitive) _primitives.push_back(primitive); }
void addPrimitive(Primitive* primitive) { if (primitive) _primitives.push_back(primitive); dirtyDisplayList(); }
@@ -340,6 +353,7 @@ class SG_EXPORT Geometry : public Drawable
/** return the attributes successully applied in applyAttributeUpdate.*/
virtual AttributeBitMask applyAttributeOperation(AttributeFunctor& auf);
virtual void applyPrimitiveOperation(PrimitiveFunctor&);
protected:

View File

@@ -14,7 +14,7 @@ namespace osg {
* Statistics base class. Used to extract primitive information from
* the renderBin(s). Add a case of getStats(osgUtil::Statistics *stat)
* for any new drawable (or drawable derived class) that you generate
* (eg see GeoSet.cpp). There are 20 types of drawable counted - actually only
* (eg see Geometry.cpp). There are 20 types of drawable counted - actually only
* 14 cases can occur in reality. these represent sets of GL_POINTS, GL_LINES
* GL_LINESTRIPS, LOOPS, TRIANGLES, TRI-fans, tristrips, quads, quadstrips etc
* The number of triangles rendered is inferred:

View File

@@ -8,7 +8,6 @@
#include <osg/NodeVisitor>
#include <osg/LineSegment>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/Matrix>
#include <osgUtil/Export>
@@ -51,7 +50,7 @@ class OSGUTIL_EXPORT Hit
osg::ref_ptr<osg::LineSegment> _localLineSegment;
osg::NodePath _nodePath;
osg::ref_ptr<osg::Geode> _geode;
osg::ref_ptr<osg::GeoSet> _geoset;
osg::ref_ptr<osg::Drawable> _drawable;
osg::ref_ptr<osg::Matrix> _matrix;
osg::ref_ptr<osg::Matrix> _inverse;
@@ -139,7 +138,7 @@ class OSGUTIL_EXPORT IntersectVisitor : public osg::NodeVisitor
};
bool intersect(osg::GeoSet& gset);
bool intersect(osg::Drawable& gset);
void pushMatrix(const osg::Matrix& matrix);
void popMatrix();

View File

@@ -7,7 +7,7 @@
#include <osg/NodeVisitor>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/Geometry>
#include <osgUtil/Export>
@@ -30,7 +30,7 @@ class OSGUTIL_EXPORT TriStripVisitor : public osg::NodeVisitor
* NvTriStrip. Converts all primitive types except points
* and lines, linestrips which it leaves unchanged.
*/
static void stripify(osg::GeoSet& gset);
static void stripify(osg::Geometry& drawable);
/// apply stripify method to all geode geosets.
virtual void apply(osg::Geode& geode);

View File

@@ -1,8 +1,5 @@
// simple animation demo written by Graeme Harkness.
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/Geometry>
#include <osg/Material>
#include <osg/Vec3>
#include <osg/Transform>
@@ -15,16 +12,10 @@
#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
// ----------------------------------------------------------------------
osg::Geode* createCube(); //Forward Declaration added by SMW
class MyTransformCallback : public osg::NodeCallback{
public:
@@ -60,22 +51,6 @@ class MyTransformCallback : public osg::NodeCallback{
_previousTraversalNumber = nv->getTraversalNumber();
// Some memory stress testing added by Steve to reveal crashes under Windows.
// // Start Added by SMW
// osg::Transform* Tnode = (osg::Transform *)node;
// int i;
// osg::Node *n;
// while (Tnode->getNumChildren() > 0)
// {
// n = Tnode->getChild(0);
// Tnode->removeChild(n);
// }
// for (i = 0;i < 500;i++)
// {
// Tnode->addChild( createCube() );
// }
// // End Added by SMW
}
}
}
@@ -96,76 +71,76 @@ class MyTransformCallback : public osg::NodeCallback{
};
osg::Geode* createCube()
osg::Geode* createGeometryCube()
{
osg::Geode* geode = new osg::Geode();
// -------------------------------------------
// Set up a new GeoSet which will be our cube
// Set up a new Geometry which will be our cube
// -------------------------------------------
osg::GeoSet* cube = new osg::GeoSet();
osg::Geometry* cube = new osg::Geometry();
// set up the primitives
cube->setPrimType( osg::GeoSet::POLYGON );
cube->setNumPrims( 6 ); // the six square faces
cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,0,4));
cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,4,4));
cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,8,4));
cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,12,4));
cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,16,4));
cube->addPrimitive(new osg::DrawArrays(osg::Primitive::POLYGON,20,4));
// set up the primitive indices
int* cubeLengthList = new int[6];
cubeLengthList[0] = 4; // each side of the cube has 4 vertices
cubeLengthList[1] = 4;
cubeLengthList[2] = 4;
cubeLengthList[3] = 4;
cubeLengthList[4] = 4;
cubeLengthList[5] = 4;
// set up coords.
osg::Vec3Array* coords = new osg::Vec3Array;
coords->resize(24);
(*coords)[0].set( -1.0000f, 1.0000f, -1.000f );
(*coords)[1].set( 1.0000f, 1.0000f, -1.0000f );
(*coords)[2].set( 1.0000f, -1.0000f, -1.0000f );
(*coords)[3].set( -1.0000f, -1.0000f, -1.000 );
cube->setPrimLengths( cubeLengthList );
(*coords)[4].set( 1.0000f, 1.0000f, -1.0000f );
(*coords)[5].set( 1.0000f, 1.0000f, 1.0000f );
(*coords)[6].set( 1.0000f, -1.0000f, 1.0000f );
(*coords)[7].set( 1.0000f, -1.0000f, -1.0000f );
(*coords)[8].set( 1.0000f, 1.0000f, 1.0000f );
(*coords)[9].set( -1.0000f, 1.0000f, 1.000f );
(*coords)[10].set( -1.0000f, -1.0000f, 1.000f );
(*coords)[11].set( 1.0000f, -1.0000f, 1.0000f );
(*coords)[12].set( -1.0000f, 1.0000f, 1.000 );
(*coords)[13].set( -1.0000f, 1.0000f, -1.000 );
(*coords)[14].set( -1.0000f, -1.0000f, -1.000 );
(*coords)[15].set( -1.0000f, -1.0000f, 1.000 );
(*coords)[16].set( -1.0000f, 1.0000f, 1.000 );
(*coords)[17].set( 1.0000f, 1.0000f, 1.0000f );
(*coords)[18].set( 1.0000f, 1.0000f, -1.0000f );
(*coords)[19].set( -1.0000f, 1.0000f, -1.000f );
(*coords)[20].set( -1.0000f, -1.0000f, 1.000f );
(*coords)[21].set( -1.0000f, -1.0000f, -1.000f );
(*coords)[22].set( 1.0000f, -1.0000f, -1.0000f );
(*coords)[23].set( 1.0000f, -1.0000f, 1.0000f );
// set up the coordinates.
osg::Vec3 *cubeCoords = new osg::Vec3[24];
cubeCoords[0].set( -1.0000f, 1.0000f, -1.000f );
cubeCoords[1].set( 1.0000f, 1.0000f, -1.0000f );
cubeCoords[2].set( 1.0000f, -1.0000f, -1.0000f );
cubeCoords[3].set( -1.0000f, -1.0000f, -1.000 );
cubeCoords[4].set( 1.0000f, 1.0000f, -1.0000f );
cubeCoords[5].set( 1.0000f, 1.0000f, 1.0000f );
cubeCoords[6].set( 1.0000f, -1.0000f, 1.0000f );
cubeCoords[7].set( 1.0000f, -1.0000f, -1.0000f );
cubeCoords[8].set( 1.0000f, 1.0000f, 1.0000f );
cubeCoords[9].set( -1.0000f, 1.0000f, 1.000f );
cubeCoords[10].set( -1.0000f, -1.0000f, 1.000f );
cubeCoords[11].set( 1.0000f, -1.0000f, 1.0000f );
cubeCoords[12].set( -1.0000f, 1.0000f, 1.000 );
cubeCoords[13].set( -1.0000f, 1.0000f, -1.000 );
cubeCoords[14].set( -1.0000f, -1.0000f, -1.000 );
cubeCoords[15].set( -1.0000f, -1.0000f, 1.000 );
cubeCoords[16].set( -1.0000f, 1.0000f, 1.000 );
cubeCoords[17].set( 1.0000f, 1.0000f, 1.0000f );
cubeCoords[18].set( 1.0000f, 1.0000f, -1.0000f );
cubeCoords[19].set( -1.0000f, 1.0000f, -1.000f );
cubeCoords[20].set( -1.0000f, -1.0000f, 1.000f );
cubeCoords[21].set( -1.0000f, -1.0000f, -1.000f );
cubeCoords[22].set( 1.0000f, -1.0000f, -1.0000f );
cubeCoords[23].set( 1.0000f, -1.0000f, 1.0000f );
cube->setCoords( cubeCoords );
cube->setVertexArray( coords );
// set up the normals.
osg::Vec3 *cubeNormals = new osg::Vec3[6];
cubeNormals[0].set(0.0f,0.0f,-1.0f);
cubeNormals[1].set(1.0f,0.0f,0.0f);
cubeNormals[2].set(0.0f,0.0f,1.0f);
cubeNormals[3].set(-1.0f,0.0f,0.0f);
cubeNormals[4].set(0.0f,1.0f,0.0f);
cubeNormals[5].set(0.0f,-1.0f,0.0f);
cube->setNormals( cubeNormals );
cube->setNormalBinding( osg::GeoSet::BIND_PERPRIM );
osg::Vec3Array* cubeNormals = new osg::Vec3Array;
cubeNormals->resize(6);
(*cubeNormals)[0].set(0.0f,0.0f,-1.0f);
(*cubeNormals)[1].set(1.0f,0.0f,0.0f);
(*cubeNormals)[2].set(0.0f,0.0f,1.0f);
(*cubeNormals)[3].set(-1.0f,0.0f,0.0f);
(*cubeNormals)[4].set(0.0f,1.0f,0.0f);
(*cubeNormals)[5].set(0.0f,-1.0f,0.0f);
cube->setNormalArray( cubeNormals );
cube->setNormalBinding( osg::Geometry::BIND_PER_PRIMITIVE );
// ---------------------------------------
// Set up a StateSet to make the cube red
@@ -201,7 +176,7 @@ int main( int argc, char **argv )
viewer.readCommandLine(commandLine);
osg::Transform* myTransform = new osg::Transform();
myTransform->addChild( createCube() );
myTransform->addChild( createGeometryCube() );
// move node in a circle at 90 degrees a sec.
myTransform->setAppCallback(new MyTransformCallback(myTransform,osg::inDegrees(90.0f)));

View File

@@ -1,5 +1,4 @@
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/Geometry>
#include <osg/Material>
#include <osg/Vec3>
@@ -52,22 +51,6 @@ class MyTransformCallback : public osg::NodeCallback{
_previousTraversalNumber = nv->getTraversalNumber();
// Some memory stress testing added by Steve to reveal crashes under Windows.
// // Start Added by SMW
// osg::Transform* Tnode = (osg::Transform *)node;
// int i;
// osg::Node *n;
// while (Tnode->getNumChildren() > 0)
// {
// n = Tnode->getChild(0);
// Tnode->removeChild(n);
// }
// for (i = 0;i < 500;i++)
// {
// Tnode->addChild( createCube() );
// }
// // End Added by SMW
}
}
}
@@ -88,93 +71,6 @@ class MyTransformCallback : public osg::NodeCallback{
};
osg::Geode* createCube()
{
osg::Geode* geode = new osg::Geode();
// -------------------------------------------
// Set up a new GeoSet which will be our cube
// -------------------------------------------
osg::GeoSet* cube = new osg::GeoSet();
// set up the primitives
cube->setPrimType( osg::GeoSet::POLYGON );
cube->setNumPrims( 6 ); // the six square faces
// set up the primitive indices
int* cubeLengthList = new int[6];
cubeLengthList[0] = 4; // each side of the cube has 4 vertices
cubeLengthList[1] = 4;
cubeLengthList[2] = 4;
cubeLengthList[3] = 4;
cubeLengthList[4] = 4;
cubeLengthList[5] = 4;
cube->setPrimLengths( cubeLengthList );
// set up the coordinates.
osg::Vec3 *cubeCoords = new osg::Vec3[24];
cubeCoords[0].set( -1.0000f, 1.0000f, -1.000f );
cubeCoords[1].set( 1.0000f, 1.0000f, -1.0000f );
cubeCoords[2].set( 1.0000f, -1.0000f, -1.0000f );
cubeCoords[3].set( -1.0000f, -1.0000f, -1.000 );
cubeCoords[4].set( 1.0000f, 1.0000f, -1.0000f );
cubeCoords[5].set( 1.0000f, 1.0000f, 1.0000f );
cubeCoords[6].set( 1.0000f, -1.0000f, 1.0000f );
cubeCoords[7].set( 1.0000f, -1.0000f, -1.0000f );
cubeCoords[8].set( 1.0000f, 1.0000f, 1.0000f );
cubeCoords[9].set( -1.0000f, 1.0000f, 1.000f );
cubeCoords[10].set( -1.0000f, -1.0000f, 1.000f );
cubeCoords[11].set( 1.0000f, -1.0000f, 1.0000f );
cubeCoords[12].set( -1.0000f, 1.0000f, 1.000 );
cubeCoords[13].set( -1.0000f, 1.0000f, -1.000 );
cubeCoords[14].set( -1.0000f, -1.0000f, -1.000 );
cubeCoords[15].set( -1.0000f, -1.0000f, 1.000 );
cubeCoords[16].set( -1.0000f, 1.0000f, 1.000 );
cubeCoords[17].set( 1.0000f, 1.0000f, 1.0000f );
cubeCoords[18].set( 1.0000f, 1.0000f, -1.0000f );
cubeCoords[19].set( -1.0000f, 1.0000f, -1.000f );
cubeCoords[20].set( -1.0000f, -1.0000f, 1.000f );
cubeCoords[21].set( -1.0000f, -1.0000f, -1.000f );
cubeCoords[22].set( 1.0000f, -1.0000f, -1.0000f );
cubeCoords[23].set( 1.0000f, -1.0000f, 1.0000f );
cube->setCoords( cubeCoords );
// set up the normals.
osg::Vec3 *cubeNormals = new osg::Vec3[6];
cubeNormals[0].set(0.0f,0.0f,-1.0f);
cubeNormals[1].set(1.0f,0.0f,0.0f);
cubeNormals[2].set(0.0f,0.0f,1.0f);
cubeNormals[3].set(-1.0f,0.0f,0.0f);
cubeNormals[4].set(0.0f,1.0f,0.0f);
cubeNormals[5].set(0.0f,-1.0f,0.0f);
cube->setNormals( cubeNormals );
cube->setNormalBinding( osg::GeoSet::BIND_PERPRIM );
// ---------------------------------------
// Set up a StateSet to make the cube red
// ---------------------------------------
osg::StateSet* cubeState = new osg::StateSet();
osg::Material* redMaterial = new osg::Material();
osg::Vec4 red( 1.0f, 0.0f, 0.0f, 1.0f );
redMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, red );
cubeState->setAttribute( redMaterial );
cube->setStateSet( cubeState );
geode->addDrawable( cube );
return geode;
}
osg::Geode* createGeometryCube()
{
osg::Geode* geode = new osg::Geode();
@@ -280,7 +176,6 @@ int main( int argc, char **argv )
viewer.readCommandLine(commandLine);
osg::Transform* myTransform = new osg::Transform();
// myTransform->addChild( createCube() );
myTransform->addChild( createGeometryCube() );
// move node in a circle at 90 degrees a sec.

View File

@@ -979,8 +979,55 @@ bool GeoSet::getStats(Statistics &stat)
return true;
}
void GeoSet::applyPrimitiveOperation(PrimitiveFunctor& functor)
{
// will easily convert into a Geometry.
if (!_coords || !_numcoords) return;
functor.setVertexArray(_numcoords,_coords);
if( _needprimlen )
{
// LINE_STRIP, LINE_LOOP, TRIANGLE_STRIP,
// TRIANGLE_FAN, QUAD_STRIP, POLYGONS
int index = 0;
if( _primLengths == (int *)0 )
{
return;
}
for( int i = 0; i < _numprims; i++ )
{
if( _cindex.valid() )
{
if (_cindex._is_ushort)
functor.drawElements( (GLenum)_oglprimtype, _primLengths[i],&_cindex._ptr._ushort[index] );
else
functor.drawElements( (GLenum)_oglprimtype, _primLengths[i],&_cindex._ptr._ushort[index] );
}
else
functor.drawArrays( (GLenum)_oglprimtype, index, _primLengths[i] );
index += _primLengths[i];
}
}
else // POINTS, LINES, TRIANGLES, QUADS
{
if( _cindex.valid())
{
if (_cindex._is_ushort)
functor.drawElements( (GLenum)_oglprimtype, _cindex._size, _cindex._ptr._ushort );
else
functor.drawElements( (GLenum)_oglprimtype, _cindex._size, _cindex._ptr._uint );
}
else
functor.drawArrays( (GLenum)_oglprimtype, 0, _numcoords );
}
}
Geometry* GeoSet::convertToGeometry()
{

View File

@@ -73,6 +73,8 @@ void Geometry::setTexCoordArray(unsigned int unit,AttributeArray* array)
_texCoordList.resize(unit+1,0);
_texCoordList[unit] = array;
dirtyDisplayList();
}
AttributeArray* Geometry::getTexCoordArray(unsigned int unit)
@@ -245,6 +247,22 @@ Drawable::AttributeBitMask Geometry::applyAttributeOperation(AttributeFunctor& )
return 0;
}
void Geometry::applyPrimitiveOperation(PrimitiveFunctor& functor)
{
if (!_vertexArray.valid() || _vertexArray->empty()) return;
functor.setVertexArray(_vertexArray->size(),&(_vertexArray->front()));
for(PrimitiveList::iterator itr=_primitives.begin();
itr!=_primitives.end();
++itr)
{
(*itr)->applyPrimitiveOperation(functor);
}
}
const bool Geometry::computeBound() const
{
_bbox.init();

View File

@@ -5,7 +5,7 @@
#include <osg/Notify>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/Geometry>
#include <osg/StateSet>
#include <osg/Texture>
@@ -491,35 +491,33 @@ Geode* osg::createGeodeForImage(osg::Image* image,const float s,const float t)
dstate->setAttributeAndModes(texture,osg::StateAttribute::ON);
// set up the geoset.
osg::GeoSet* gset = osgNew osg::GeoSet;
gset->setStateSet(dstate);
Geometry* geom = osgNew Geometry;
geom->setStateSet(dstate);
osg::Vec3* coords = osgNew Vec3[4];
coords[0].set(-x,0.0f,y);
coords[1].set(-x,0.0f,-y);
coords[2].set(x,0.0f,-y);
coords[3].set(x,0.0f,y);
gset->setCoords(coords);
Vec3Array* coords = osgNew Vec3Array(4);
(*coords)[0].set(-x,0.0f,y);
(*coords)[1].set(-x,0.0f,-y);
(*coords)[2].set(x,0.0f,-y);
(*coords)[3].set(x,0.0f,y);
geom->setVertexArray(coords);
osg::Vec2* tcoords = osgNew Vec2[4];
tcoords[0].set(0.0f,1.0f);
tcoords[1].set(0.0f,0.0f);
tcoords[2].set(1.0f,0.0f);
tcoords[3].set(1.0f,1.0f);
gset->setTextureCoords(tcoords);
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
Vec2Array* tcoords = osgNew Vec2Array(4);
(*tcoords)[0].set(0.0f,1.0f);
(*tcoords)[1].set(0.0f,0.0f);
(*tcoords)[2].set(1.0f,0.0f);
(*tcoords)[3].set(1.0f,1.0f);
geom->setTexCoordArray(0,tcoords);
osg::Vec4* colours = osgNew Vec4[1];
colours->set(1.0f,1.0f,1.0,1.0f);
gset->setColors(colours);
gset->setColorBinding(osg::GeoSet::BIND_OVERALL);
osg::Vec4Array* colours = osgNew osg::Vec4Array(1);
(*colours)[0].set(1.0f,1.0f,1.0,1.0f);
geom->setColorArray(colours);
geom->setColorBinding(Geometry::BIND_OVERALL);
gset->setNumPrims(1);
gset->setPrimType(osg::GeoSet::QUADS);
geom->addPrimitive(osgNew DrawArrays(Primitive::QUADS,0,4));
// set up the geode.
osg::Geode* geode = osgNew osg::Geode;
geode->addDrawable(gset);
geode->addDrawable(geom);
return geode;

View File

@@ -6,7 +6,7 @@
#include <math.h>
#include <float.h>
#include <osg/GeoSet>
#include <osg/Geometry>
#include <osg/ImpostorSprite>
#include <osg/Texture>
#include <osg/TexEnv>

View File

@@ -3,7 +3,6 @@
#include <osg/Group>
#include <osg/Geode>
#include <osg/GeoSet>
using namespace osg;
@@ -163,59 +162,7 @@ float computePolytopeVolume(const PointList& front, const PointList& back)
return volume;
}
Drawable* createOccluderDrawable(const PointList& front, const PointList& back)
{
// create a drawable for occluder.
osg::GeoSet* geoset = osgNew osg::GeoSet;
int totalNumber = front.size()+back.size();
osg::Vec3* coords = osgNew osg::Vec3[front.size()+back.size()];
osg::Vec3* cptr = coords;
for(PointList::const_iterator fitr=front.begin();
fitr!=front.end();
++fitr)
{
*cptr = fitr->second;
++cptr;
}
for(PointList::const_iterator bitr=back.begin();
bitr!=back.end();
++bitr)
{
*cptr = bitr->second;
++cptr;
}
geoset->setCoords(coords);
osg::Vec4* color = osgNew osg::Vec4[1];
color[0].set(1.0f,1.0f,1.0f,0.5f);
geoset->setColors(color);
geoset->setColorBinding(osg::GeoSet::BIND_OVERALL);
geoset->setPrimType(osg::GeoSet::POINTS);
geoset->setNumPrims(totalNumber);
//cout << "totalNumber = "<<totalNumber<<endl;
osg::Geode* geode = osgNew osg::Geode;
geode->addDrawable(geoset);
osg::StateSet* stateset = osgNew osg::StateSet;
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
geoset->setStateSet(stateset);
return geoset;
}
bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,CullStack& cullStack,bool createDrawables)
bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,CullStack& cullStack,bool /*createDrawables*/)
{
@@ -291,24 +238,6 @@ bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const Convex
_volume = computePolytopeVolume(points,farPoints)/volumeview;
if (createDrawables && !nodePath.empty())
{
osg::Group* group = dynamic_cast<osg::Group*>(nodePath.back());
if (group)
{
osg::Matrix invMV;
invMV.invert(MV);
transform(points,invMV);
transform(farPoints,invMV);
osg::Geode* geode = osgNew osg::Geode;
group->addChild(geode);
geode->addDrawable(createOccluderDrawable(points,farPoints));
}
}
for(ConvexPlanerOccluder::HoleList::const_iterator hitr=occluder.getHoleList().begin();
hitr!=occluder.getHoleList().end();
@@ -350,24 +279,6 @@ bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const Convex
// remove the hole's volume from the occluder volume.
_volume -= computePolytopeVolume(points,farPoints)/volumeview;
if (createDrawables && !nodePath.empty())
{
osg::Group* group = dynamic_cast<osg::Group*>(nodePath.back());
if (group)
{
osg::Matrix invMV;
invMV.invert(MV);
transform(points,invMV);
transform(farPoints,invMV);
osg::Geode* geode = osgNew osg::Geode;
group->addChild(geode);
geode->addDrawable(createOccluderDrawable(points,farPoints));
}
}
}
}

View File

@@ -1158,8 +1158,8 @@ void Viewer::keyboard(unsigned char key, int x, int y)
if (key=='r' && geode)
{
// remove geoset..
osg::GeoSet* gset = hitr->_geoset.get();
osg::notify(osg::NOTICE) << " geoset ("<<gset<<") "<<geode->removeDrawable(gset)<<")"<< std::endl;
osg::Drawable* drawable = hitr->_drawable.get();
osg::notify(osg::NOTICE) << " drawable ("<<drawable<<") "<<geode->removeDrawable(drawable)<<")"<< std::endl;
}
}

View File

@@ -629,7 +629,7 @@ bool Primitve_writeLocalData(const Primitive& prim,Output& fw)
case(UByteDrawElementsPrimitiveType):
{
const UByteDrawElements& cprim = static_cast<const UByteDrawElements&>(prim);
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<std::endl;
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.size()<<std::endl;
Array_writeLocalData(fw,cprim.begin(),cprim.end());
return true;
}
@@ -637,7 +637,7 @@ bool Primitve_writeLocalData(const Primitive& prim,Output& fw)
case(UShortDrawElementsPrimitiveType):
{
const UShortDrawElements& cprim = static_cast<const UShortDrawElements&>(prim);
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<std::endl;
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.size()<<std::endl;
Array_writeLocalData(fw,cprim.begin(),cprim.end());
return true;
}
@@ -645,7 +645,7 @@ bool Primitve_writeLocalData(const Primitive& prim,Output& fw)
case(UIntDrawElementsPrimitiveType):
{
const UIntDrawElements& cprim = static_cast<const UIntDrawElements&>(prim);
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<std::endl;
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.size()<<std::endl;
Array_writeLocalData(fw,cprim.begin(),cprim.end());
return true;
}

View File

@@ -27,7 +27,7 @@ Hit::Hit(const Hit& hit)
_localLineSegment = hit._localLineSegment;
_nodePath = hit._nodePath;
_geode = hit._geode;
_geoset = hit._geoset;
_drawable = hit._drawable;
_matrix = hit._matrix;
_inverse = hit._inverse;
@@ -58,7 +58,7 @@ Hit& Hit::operator = (const Hit& hit)
_localLineSegment = hit._localLineSegment;
_nodePath = hit._nodePath;
_geode = hit._geode;
_geoset = hit._geoset;
_drawable = hit._drawable;
_vecIndexList = hit._vecIndexList;
_primitiveIndex = hit._primitiveIndex;
@@ -180,7 +180,8 @@ void IntersectVisitor::addLineSegment(LineSegment* seg)
if (!seg->valid())
{
notify(WARN)<<"Warning: invalid line segment passed to IntersectVisitor::addLineSegment(..), segment ignored.."<< std::endl;
notify(WARN)<<"Warning: invalid line segment passed to IntersectVisitor::addLineSegment(..)"<<std::endl;
notify(WARN)<<" "<<seg->start()<<" "<<seg->end()<<" segment ignored.."<< std::endl;
return;
}
@@ -304,7 +305,16 @@ struct TriangleIntersect
typedef std::multimap<float,std::pair<int,osg::Vec3> > TriangleHitList;
TriangleHitList _thl;
TriangleIntersect()
{
}
TriangleIntersect(const LineSegment& seg,float ratio=FLT_MAX)
{
set(seg,ratio);
}
void set(const LineSegment& seg,float ratio=FLT_MAX)
{
_seg=new LineSegment(seg);
_hit=false;
@@ -315,7 +325,6 @@ struct TriangleIntersect
_d = _seg->end()-_seg->start();
_length = _d.length();
_d /= _length;
}
// bool intersect(const Vec3& v1,const Vec3& v2,const Vec3& v3,float& r)
@@ -408,6 +417,14 @@ struct TriangleIntersect
float r = d/_length;
if (!in.valid())
{
osg::notify(WARN)<<"Warning:: Picked up error in TriangleIntersect"<<std::endl;
osg::notify(WARN)<<" ("<<v1<<",\t"<<v2<<",\t"<<v3<<")"<<std::endl;
osg::notify(WARN)<<" ("<<r1<<",\t"<<r2<<",\t"<<r3<<")"<<std::endl;
return;
}
_thl.insert(std::pair<const float,std::pair<int,osg::Vec3> > (r,std::pair<int,osg::Vec3>(_index-1,normal)));
_hit = true;
@@ -415,13 +432,13 @@ struct TriangleIntersect
};
bool IntersectVisitor::intersect(GeoSet& gset)
bool IntersectVisitor::intersect(Drawable& drawable)
{
bool hitFlag = false;
IntersectState* cis = _intersectStateStack.back().get();
const BoundingBox& bb = gset.getBound();
const BoundingBox& bb = drawable.getBound();
for(IntersectState::LineSegmentList::iterator sitr=cis->_segList.begin();
sitr!=cis->_segList.end();
@@ -429,8 +446,10 @@ bool IntersectVisitor::intersect(GeoSet& gset)
{
if (sitr->second->intersect(bb))
{
TriangleIntersect ti(*sitr->second);
for_each_triangle(gset,ti);
TriangleFunctor<TriangleIntersect> ti;
ti.set(*sitr->second);
drawable.applyPrimitiveOperation(ti);
if (ti._hit)
{
@@ -442,7 +461,7 @@ bool IntersectVisitor::intersect(GeoSet& gset)
hit._nodePath = _nodePath;
hit._matrix = cis->_matrix;
hit._inverse = cis->_inverse;
hit._geoset = &gset;
hit._drawable = &drawable;
if (_nodePath.empty()) hit._geode = NULL;
else hit._geode = dynamic_cast<Geode*>(_nodePath.back());
@@ -470,49 +489,13 @@ bool IntersectVisitor::intersect(GeoSet& gset)
}
void IntersectVisitor::apply(Geode& geode)
{
if (!enterNode(geode)) return;
for(int i = 0; i < geode.getNumDrawables(); i++ )
{
osg::GeoSet* gset = dynamic_cast<osg::GeoSet*>(geode.getDrawable(i));
if (gset) intersect(*gset);
else
{
IntersectState* cis = _intersectStateStack.back().get();
// simply default to intersecting with bounding box.
for(IntersectState::LineSegmentList::iterator sitr=cis->_segList.begin();
sitr!=cis->_segList.end();
++sitr)
{
if (sitr->second->intersect(geode.getDrawable(i)->getBound()))
{
Hit hit;
hit._nodePath = _nodePath;
hit._matrix = cis->_matrix;
hit._inverse = cis->_inverse;
hit._geoset = NULL;
if (_nodePath.empty()) hit._geode = NULL;
else hit._geode = dynamic_cast<Geode*>(_nodePath.back());
hit._ratio = 0.0f;
hit._primitiveIndex = -1;
hit._originalLineSegment = sitr->first;
hit._localLineSegment = sitr->second;
hit._intersectPoint = geode.getDrawable(i)->getBound().center();
hit._intersectNormal.set(0.0,0.0,1.0);
_segHitList[sitr->first.get()].push_back(hit);
std::sort(_segHitList[sitr->first.get()].begin(),_segHitList[sitr->first.get()].end());
}
}
}
intersect(*geode.getDrawable(i));
}
leaveNode();

View File

@@ -64,9 +64,9 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
}
// // convert the old style GeoSet to Geometry
// ConvertGeoSetsToGeometryVisitor cgtg;
// node->accept(cgtg);
// convert the old style GeoSet to Geometry
// ConvertGeoSetsToGeometryVisitor cgtg;
// node->accept(cgtg);
if (options & SHARE_DUPLICATE_STATE)

View File

@@ -22,7 +22,7 @@ struct LessPtr
};
// triangle functor.
struct TriangleFunctor
struct SmoothTriangleFunctor
{
osg::Vec3 *_coordBase;
@@ -31,7 +31,7 @@ struct TriangleFunctor
typedef std::multiset<const osg::Vec3*,LessPtr> CoordinateSet;
CoordinateSet _coordSet;
TriangleFunctor(osg::Vec3 *cb,int noVertices, osg::Vec3 *nb) : _coordBase(cb),_normalBase(nb)
SmoothTriangleFunctor(osg::Vec3 *cb,int noVertices, osg::Vec3 *nb) : _coordBase(cb),_normalBase(nb)
{
osg::Vec3* vptr = cb;
for(int i=0;i<noVertices;++i)
@@ -116,7 +116,7 @@ void SmoothingVisitor::smooth(osg::GeoSet& gset)
norms[j].set(0.0f,0.0f,0.0f);
}
TriangleFunctor tf(coords,ncoords,norms);
SmoothTriangleFunctor tf(coords,ncoords,norms);
for_each_triangle( gset, tf );
for(j = 0; j < ncoords; j++ )

View File

@@ -1,16 +1,11 @@
#if defined(_MSC_VER)
#pragma warning( disable : 4786 )
#endif
#include <stdio.h>
#include <osg/GeoSet>
#include <osg/Geode>
#include <osg/Types>
#include <osg/Notify>
#include <osgUtil/TriStripVisitor>
#include <stdio.h>
#include "NvTriStripObjects.h"
using namespace osg;
@@ -23,7 +18,9 @@ struct TriangleAcumulatorFunctor
WordVec in_indices;
const Vec3* _vbase;
TriangleAcumulatorFunctor( const Vec3* vbase ) : _vbase(vbase) {}
TriangleAcumulatorFunctor() : _vbase(0) {}
void setCoords( const Vec3* vbase ) { _vbase = vbase; }
inline void operator() ( const Vec3 &v1, const Vec3 &v2, const Vec3 &v3 )
{
@@ -37,267 +34,172 @@ struct TriangleAcumulatorFunctor
}
};
void createStrips(
NvStripInfoVec& strips,
NvFaceInfoVec& leftoverFaces,
int& noPrims,
int **lens,
osg::ushort **osg_indices)
void TriStripVisitor::stripify(Geometry& geom)
{
int nStripCount = strips.size();
assert(nStripCount > 0);
noPrims = strips.size()+leftoverFaces.size();
*lens = osgNew int [noPrims];
unsigned int numSurfacePrimitives = 0;
unsigned int numNonSurfacePrimitives = 0;
int* lensPtr = *lens;
unsigned int i;
int noIndices = 0;
for (i = 0; i < strips.size(); i++)
Geometry::PrimitiveList& primitives = geom.getPrimitiveList();
Geometry::PrimitiveList::iterator itr;
for(itr=primitives.begin();
itr!=primitives.end();
++itr)
{
noIndices += strips[i]->m_faces.size()+2;
}
noIndices += leftoverFaces.size()*3;
*osg_indices = osgNew osg::ushort[noIndices];
osg::ushort *osg_indicesPtr = *osg_indices;
for (i = 0; i < strips.size(); i++)
{
NvStripInfo *strip = strips[i];
int nStripFaceCount = strip->m_faces.size();
*(lensPtr++) = nStripFaceCount+2;
NvFaceInfo tLastFace(0, 0, 0);
// Handle the first face in the strip
switch((*itr)->getMode())
{
NvFaceInfo tFirstFace(strip->m_faces[0]->m_v0, strip->m_faces[0]->m_v1, strip->m_faces[0]->m_v2);
case(Primitive::TRIANGLES):
case(Primitive::TRIANGLE_STRIP):
case(Primitive::TRIANGLE_FAN):
case(Primitive::QUADS):
case(Primitive::QUAD_STRIP):
case(Primitive::POLYGON):
++numSurfacePrimitives;
break;
default:
++numNonSurfacePrimitives;
break;
}
}
if (!numSurfacePrimitives) return;
TriangleFunctor<TriangleAcumulatorFunctor> taf;
// If there is a second face, reorder vertices such that the
// unique vertex is first
if (nStripFaceCount > 1)
Geometry::PrimitiveList new_primitives;
new_primitives.reserve(primitives.size());
for(itr=primitives.begin();
itr!=primitives.end();
++itr)
{
switch((*itr)->getMode())
{
case(Primitive::TRIANGLES):
case(Primitive::TRIANGLE_STRIP):
case(Primitive::TRIANGLE_FAN):
case(Primitive::QUADS):
case(Primitive::QUAD_STRIP):
case(Primitive::POLYGON):
(*itr)->applyPrimitiveOperation(taf);
break;
default:
new_primitives.push_back(*itr);
break;
}
}
if (!taf.in_indices.empty())
{
int in_numVertices = -1;
for(WordVec::iterator itr=taf.in_indices.begin();
itr!=taf.in_indices.end();
++itr)
{
if (*itr>in_numVertices) in_numVertices=*itr;
}
// the largest indice is in_numVertices, but indices start at 0
// so increment to give to the corrent number of verticies.
++in_numVertices;
int in_cacheSize = 16;
int in_minStripLength = 2;
NvStripInfoVec strips;
NvFaceInfoVec leftoverFaces;
NvStripifier stripifier;
stripifier.Stripify(taf.in_indices,
in_numVertices,
in_cacheSize,
in_minStripLength,
strips,
leftoverFaces);
unsigned int i;
for (i = 0; i < strips.size(); ++i)
{
NvStripInfo *strip = strips[i];
int nStripFaceCount = strip->m_faces.size();
osg::UShortDrawElements* elements = osgNew osg::UShortDrawElements(osg::Primitive::TRIANGLE_STRIP);
elements->reserve(nStripFaceCount+2);
new_primitives.push_back(elements);
NvFaceInfo tLastFace(0, 0, 0);
// Handle the first face in the strip
{
int nUnique = NvStripifier::GetUniqueVertexInB(strip->m_faces[1], &tFirstFace);
if (nUnique == tFirstFace.m_v1)
{
std::swap(tFirstFace.m_v0, tFirstFace.m_v1);
}
else if (nUnique == tFirstFace.m_v2)
{
std::swap(tFirstFace.m_v0, tFirstFace.m_v2);
}
NvFaceInfo tFirstFace(strip->m_faces[0]->m_v0, strip->m_faces[0]->m_v1, strip->m_faces[0]->m_v2);
// If there is a third face, reorder vertices such that the
// shared vertex is last
if (nStripFaceCount > 2)
// If there is a second face, reorder vertices such that the
// unique vertex is first
if (nStripFaceCount > 1)
{
int nShared = NvStripifier::GetSharedVertex(strip->m_faces[2], &tFirstFace);
if (nShared == tFirstFace.m_v1)
int nUnique = NvStripifier::GetUniqueVertexInB(strip->m_faces[1], &tFirstFace);
if (nUnique == tFirstFace.m_v1)
{
std::swap(tFirstFace.m_v1, tFirstFace.m_v2);
std::swap(tFirstFace.m_v0, tFirstFace.m_v1);
}
else if (nUnique == tFirstFace.m_v2)
{
std::swap(tFirstFace.m_v0, tFirstFace.m_v2);
}
// If there is a third face, reorder vertices such that the
// shared vertex is last
if (nStripFaceCount > 2)
{
int nShared = NvStripifier::GetSharedVertex(strip->m_faces[2], &tFirstFace);
if (nShared == tFirstFace.m_v1)
{
std::swap(tFirstFace.m_v1, tFirstFace.m_v2);
}
}
}
}
*(osg_indicesPtr++) = tFirstFace.m_v0;
*(osg_indicesPtr++) = tFirstFace.m_v1;
*(osg_indicesPtr++) = tFirstFace.m_v2;
// Update last face info
tLastFace = tFirstFace;
}
for (int j = 1; j < nStripFaceCount; j++)
{
int nUnique = NvStripifier::GetUniqueVertexInB(&tLastFace, strip->m_faces[j]);
if (nUnique != -1)
{
*(osg_indicesPtr++) = nUnique;
elements->push_back(tFirstFace.m_v0);
elements->push_back(tFirstFace.m_v1);
elements->push_back(tFirstFace.m_v2);
// Update last face info
tLastFace.m_v0 = tLastFace.m_v1;
tLastFace.m_v1 = tLastFace.m_v2;
tLastFace.m_v2 = nUnique;
tLastFace = tFirstFace;
}
for (int j = 1; j < nStripFaceCount; j++)
{
int nUnique = NvStripifier::GetUniqueVertexInB(&tLastFace, strip->m_faces[j]);
if (nUnique != -1)
{
elements->push_back(nUnique);
// Update last face info
tLastFace.m_v0 = tLastFace.m_v1;
tLastFace.m_v1 = tLastFace.m_v2;
tLastFace.m_v2 = nUnique;
}
}
}
}
for (i = 0; i < leftoverFaces.size(); ++i)
{
*(lensPtr++) = 3;
*(osg_indicesPtr++) = leftoverFaces[i]->m_v0;
*(osg_indicesPtr++) = leftoverFaces[i]->m_v1;
*(osg_indicesPtr++) = leftoverFaces[i]->m_v2;
}
}
void TriStripVisitor::stripify(GeoSet& gset)
{
GeoSet::PrimitiveType primTypeIn = gset.getPrimType();
GeoSet::PrimitiveType primTypeOut = gset.getPrimType();
// determine whether to do smoothing or not, and if
// the primitive type needs to be modified enable smoothed normals.
bool doStripify;
switch(primTypeIn)
{
case(GeoSet::QUADS):
case(GeoSet::QUAD_STRIP):
case(GeoSet::POLYGON):
case(GeoSet::TRIANGLES):
case(GeoSet::TRIANGLE_STRIP):
case(GeoSet::TRIANGLE_FAN):
primTypeOut = GeoSet::TRIANGLE_STRIP;
doStripify = true;
break;
case(GeoSet::FLAT_TRIANGLE_STRIP):
case(GeoSet::FLAT_TRIANGLE_FAN):
// comment out for time being since per vertex colors and normals need
// to take account of the osg::GeoSet::_flat_shaded_skip
// primTypeOut = GeoSet::FLAT_TRIANGLE_STRIP;
// doStripify = true;
// break;
default: // points and lines etc.
doStripify = false;
break;
}
if (doStripify)
{
TriangleAcumulatorFunctor tt(gset.getCoords());
for_each_triangle( gset, tt );
if (!tt.in_indices.empty())
if (leftoverFaces.size())
{
int in_numVertices = -1;
for(WordVec::iterator itr=tt.in_indices.begin();
itr!=tt.in_indices.end();
++itr)
osg::UShortDrawElements* triangles = osgNew osg::UShortDrawElements(osg::Primitive::TRIANGLES);
triangles->reserve(leftoverFaces.size()*3);
new_primitives.push_back(triangles);
for (i = 0; i < leftoverFaces.size(); ++i)
{
if (*itr>in_numVertices) in_numVertices=*itr;
triangles->push_back(leftoverFaces[i]->m_v0);
triangles->push_back(leftoverFaces[i]->m_v1);
triangles->push_back(leftoverFaces[i]->m_v2);
}
// the largest indice is in_numVertices, but indices start at 0
// so increment to give to the corrent number of verticies.
++in_numVertices;
int in_cacheSize = 16;
int in_minStripLength = 1;
NvStripInfoVec strips;
NvFaceInfoVec leftoverFaces;
NvStripifier stripifier;
stripifier.Stripify(tt.in_indices,
in_numVertices,
in_cacheSize,
in_minStripLength,
strips,
leftoverFaces);
int noPrims;
int *lens;
osg::ushort* osg_indices;
createStrips(strips,leftoverFaces,noPrims,&lens,&osg_indices);
if (primTypeIn!=primTypeOut)
gset.setPrimType( primTypeOut );
gset.setPrimLengths(lens);
gset.setNumPrims(noPrims);
gset.setCoords(gset.getCoords(),osg_indices);
if (gset.getTextureCoords())
{
switch(gset.getTextureBinding())
{
case(GeoSet::BIND_OVERALL):
// leave as before
break;
case(GeoSet::BIND_PERPRIM):
// switch off tex coords..
gset.setTextureBinding(GeoSet::BIND_OFF);
gset.setTextureCoords(NULL);
break;
case(GeoSet::BIND_PERVERTEX):
// set up the indexing.
gset.setTextureCoords(gset.getTextureCoords(),osg_indices);
break;
case(GeoSet::BIND_OFF):
case(GeoSet::BIND_DEFAULT):
// switch off tex coords..
gset.setTextureCoords(NULL);
break;
}
}
if (gset.getColors())
{
switch(gset.getColorBinding())
{
case(GeoSet::BIND_OVERALL):
// leave as before
break;
case(GeoSet::BIND_PERPRIM):
// switch off colors..
gset.setColorBinding(GeoSet::BIND_OFF);
gset.setColors(NULL);
break;
case(GeoSet::BIND_PERVERTEX):
// set up the indexing.
gset.setColors(gset.getColors(),osg_indices);
break;
case(GeoSet::BIND_OFF):
case(GeoSet::BIND_DEFAULT):
// switch off colors..
gset.setColors(NULL);
break;
}
}
if (gset.getNormals())
{
switch(gset.getNormalBinding())
{
case(GeoSet::BIND_OVERALL):
// leave as before
break;
case(GeoSet::BIND_PERPRIM):
// switch off normals..
gset.setNormalBinding(GeoSet::BIND_OFF);
gset.setNormals(NULL);
break;
case(GeoSet::BIND_PERVERTEX):
// set up the indexing.
gset.setNormals(gset.getNormals(),osg_indices);
break;
case(GeoSet::BIND_OFF):
case(GeoSet::BIND_DEFAULT):
// switch off normals..
gset.setNormals(NULL);
break;
}
}
gset.computeNumVerts();
gset.dirtyDisplayList();
gset.dirtyBound();
}
else
{
notify(INFO) << "No triangles to stripify"<< std::endl;
}
geom.setPrimitiveList(new_primitives);
}
}
@@ -306,7 +208,7 @@ void TriStripVisitor::apply(Geode& geode)
{
for(int i = 0; i < geode.getNumDrawables(); ++i )
{
osg::GeoSet* gset = dynamic_cast<osg::GeoSet*>(geode.getDrawable(i));
if (gset) stripify(*gset);
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
if (geom) stripify(*geom);
}
}