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