#include <osg/PagedLOD>
#include <osg/ProxyNode>
#include <osg/Transform>
-#include <osg/TriangleFunctor>
#include <osgDB/ReadFile>
#include <simgear/scene/material/mat.hxx>
#include <simgear/bvh/BVHStaticGeometryBuilder.hxx>
+#include "PrimitiveCollector.hxx"
+
namespace simgear {
class BVHPageNodeOSG::_NodeVisitor : public osg::NodeVisitor {
public:
- class PFunctor : public osg::PrimitiveFunctor {
+ class _PrimitiveCollector : public PrimitiveCollector {
public:
- PFunctor() :
- _modeCache(0)
- {
- _geometryBuilder = new BVHStaticGeometryBuilder;
- }
- virtual ~PFunctor()
+ _PrimitiveCollector() :
+ _geometryBuilder(new BVHStaticGeometryBuilder)
+ { }
+ virtual ~_PrimitiveCollector()
{ }
- virtual void setVertexArray(unsigned int count, const osg::Vec2* vertices)
- {
- _vertices.resize(count);
- for (unsigned i = 0; i < count; ++i)
- _vertices[i] = SGVec3f(vertices[i][0], vertices[i][1], 0);
- }
-
- virtual void setVertexArray(unsigned int count, const osg::Vec3* vertices)
- {
- _vertices.resize(count);
- for (unsigned i = 0; i < count; ++i)
- _vertices[i] = SGVec3f(vertices[i][0], vertices[i][1], vertices[i][2]);
- }
-
- virtual void setVertexArray(unsigned int count, const osg::Vec4* vertices)
- {
- _vertices.resize(count);
- for (unsigned i = 0; i < count; ++i)
- _vertices[i] = SGVec3f(vertices[i][0]/vertices[i][3],
- vertices[i][1]/vertices[i][3],
- vertices[i][2]/vertices[i][3]);
- }
-
- virtual void setVertexArray(unsigned int count, const osg::Vec2d* vertices)
- {
- _vertices.resize(count);
- for (unsigned i = 0; i < count; ++i)
- _vertices[i] = SGVec3f(vertices[i][0], vertices[i][1], 0);
- }
-
- virtual void setVertexArray(unsigned int count, const osg::Vec3d* vertices)
- {
- _vertices.resize(count);
- for (unsigned i = 0; i < count; ++i)
- _vertices[i] = SGVec3f(vertices[i][0], vertices[i][1], vertices[i][2]);
- }
-
- virtual void setVertexArray(unsigned int count, const osg::Vec4d* vertices)
- {
- _vertices.resize(count);
- for (unsigned i = 0; i < count; ++i)
- _vertices[i] = SGVec3f(vertices[i][0]/vertices[i][3],
- vertices[i][1]/vertices[i][3],
- vertices[i][2]/vertices[i][3]);
- }
-
- virtual void drawArrays(GLenum mode, GLint first, GLsizei count)
- {
- if (_vertices.empty() || count <= 0)
- return;
-
- GLsizei end = first + count;
- switch(mode) {
- case (GL_TRIANGLES):
- for (GLsizei i = first; i < end - 2; i += 3) {
- addTriangle(i, i + 1, i + 2);
- }
- break;
-
- case (GL_TRIANGLE_STRIP):
- for (GLsizei i = first; i < end - 2; ++i) {
- addTriangle(i, i + 1, i + 2);
- }
- break;
-
- case (GL_QUADS):
- for (GLsizei i = first; i < end - 3; i += 4) {
- addQuad(i, i + 1, i + 2, i + 3);
- }
- break;
-
- case (GL_QUAD_STRIP):
- for (GLsizei i = first; i < end - 3; i += 2) {
- addQuad(i, i + 1, i + 2, i + 3);
- }
- break;
-
- case (GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
- case (GL_TRIANGLE_FAN):
- for (GLsizei i = first; i < end - 2; ++i) {
- addTriangle(first, i + 1, i + 2);
- }
- break;
-
- case (GL_POINTS):
- for (GLsizei i = first; i < end; ++i) {
- addPoint(i);
- }
- break;
-
- case (GL_LINES):
- for (GLsizei i = first; i < end - 1; i += 2) {
- addLine(i, i + 1);
- }
- break;
-
- case (GL_LINE_STRIP):
- for (GLsizei i = first; i < end - 1; ++i) {
- addLine(i, i + 1);
- }
- break;
-
- case (GL_LINE_LOOP):
- for (GLsizei i = first; i < end - 1; ++i) {
- addLine(i, i + 1);
- }
- addLine(end - 1, first);
- break;
-
- default:
- break;
- }
- }
-
- virtual void drawElements(GLenum mode, GLsizei count, const GLubyte* indices)
- {
- drawElementsTemplate(mode, count, indices);
- }
-
- virtual void drawElements(GLenum mode, GLsizei count, const GLushort* indices)
- {
- drawElementsTemplate(mode, count, indices);
- }
-
- virtual void drawElements(GLenum mode, GLsizei count, const GLuint* indices)
- {
- drawElementsTemplate(mode, count, indices);
- }
-
- virtual void begin(GLenum mode)
- {
- _modeCache = mode;
- _vertices.resize(0);
- }
-
- virtual void vertex(const osg::Vec2& v)
- {
- _vertices.push_back(SGVec3f(v[0], v[1], 0));
- }
- virtual void vertex(const osg::Vec3& v)
- {
- _vertices.push_back(SGVec3f(v[0], v[1], v[2]));
- }
- virtual void vertex(const osg::Vec4& v)
- {
- _vertices.push_back(SGVec3f(v[0]/v[3], v[1]/v[3], v[2]/v[3]));
- }
- virtual void vertex(float x, float y)
- {
- _vertices.push_back(SGVec3f(x, y, 0));
- }
- virtual void vertex(float x, float y, float z)
- {
- _vertices.push_back(SGVec3f(x, y, z));
- }
- virtual void vertex(float x, float y, float z, float w)
- {
- _vertices.push_back(SGVec3f(x/w, y/w, z/w));
- }
- virtual void end()
- {
- if (_vertices.empty())
- return;
-
- drawArrays(_modeCache, 0, _vertices.size());
- }
-
- template<typename index_type>
- void drawElementsTemplate(GLenum mode, GLsizei count,
- const index_type* indices)
- {
- if (_vertices.empty() || indices == 0 || count <= 0)
- return;
-
- switch(mode) {
- case (GL_TRIANGLES):
- for (GLsizei i = 0; i < count - 2; i += 3) {
- addTriangle(indices[i], indices[i + 1], indices[i + 2]);
- }
- break;
-
- case (GL_TRIANGLE_STRIP):
- for (GLsizei i = 0; i < count - 2; ++i) {
- addTriangle(indices[i], indices[i + 1], indices[i + 2]);
- }
- break;
-
- case (GL_QUADS):
- for (GLsizei i = 0; i < count - 3; i += 4) {
- addQuad(indices[i], indices[i + 1], indices[i + 2], indices[i + 3]);
- }
- break;
-
- case (GL_QUAD_STRIP):
- for (GLsizei i = 0; i < count - 3; i += 2) {
- addQuad(indices[i], indices[i + 1], indices[i + 2], indices[i + 3]);
- }
- break;
-
- case (GL_POLYGON):
- case (GL_TRIANGLE_FAN):
- for (GLsizei i = 0; i < count - 2; ++i) {
- addTriangle(indices[0], indices[i + 1], indices[i + 2]);
- }
- break;
-
- case (GL_POINTS):
- for(GLsizei i = 0; i < count; ++i) {
- addPoint(indices[i]);
- }
- break;
-
- case (GL_LINES):
- for (GLsizei i = 0; i < count - 1; i += 2) {
- addLine(indices[i], indices[i + 1]);
- }
- break;
-
- case (GL_LINE_STRIP):
- for (GLsizei i = 0; i < count - 1; ++i) {
- addLine(indices[i], indices[i + 1]);
- }
- break;
-
- case (GL_LINE_LOOP):
- for (GLsizei i = 0; i < count - 1; ++i) {
- addLine(indices[i], indices[i + 1]);
- }
- addLine(indices[count - 1], indices[0]);
- break;
-
- default:
- break;
- }
- }
-
- void addPoint(unsigned i1)
- {
- addPoint(_vertices[i1]);
- }
- void addLine(unsigned i1, unsigned i2)
- {
- addLine(_vertices[i1], _vertices[i2]);
- }
- void addTriangle(unsigned i1, unsigned i2, unsigned i3)
- {
- addTriangle(_vertices[i1], _vertices[i2], _vertices[i3]);
- }
- void addQuad(unsigned i1, unsigned i2, unsigned i3, unsigned i4)
- {
- addQuad(_vertices[i1], _vertices[i2], _vertices[i3], _vertices[i4]);
- }
-
- void addPoint(const SGVec3f& v1)
- {
- }
- void addLine(const SGVec3f& v1, const SGVec3f& v2)
- {
- }
- void addTriangle(const SGVec3f& v1, const SGVec3f& v2, const SGVec3f& v3)
- {
- _geometryBuilder->addTriangle(v1, v2, v3);
- }
- void addQuad(const SGVec3f& v1, const SGVec3f& v2,
- const SGVec3f& v3, const SGVec3f& v4)
+ virtual void addPoint(const osg::Vec3d& v1)
+ { }
+ virtual void addLine(const osg::Vec3d& v1, const osg::Vec3d& v2)
+ { }
+ virtual void addTriangle(const osg::Vec3d& v1, const osg::Vec3d& v2, const osg::Vec3d& v3)
{
- _geometryBuilder->addTriangle(v1, v2, v3);
- _geometryBuilder->addTriangle(v1, v3, v4);
+ _geometryBuilder->addTriangle(toVec3f(toSG(v1)), toVec3f(toSG(v2)), toVec3f(toSG(v3)));
}
BVHNode* buildTreeAndClear()
{
BVHNode* bvNode = _geometryBuilder->buildTree();
_geometryBuilder = new BVHStaticGeometryBuilder;
- _vertices.clear();
return bvNode;
}
- void swap(PFunctor& primitiveFunctor)
+ void swap(_PrimitiveCollector& primitiveCollector)
{
- _vertices.swap(primitiveFunctor._vertices);
- std::swap(_modeCache, primitiveFunctor._modeCache);
- std::swap(_geometryBuilder, primitiveFunctor._geometryBuilder);
+ PrimitiveCollector::swap(primitiveCollector);
+ std::swap(_geometryBuilder, primitiveCollector._geometryBuilder);
}
void setCurrentMaterial(const BVHMaterial* material)
return _geometryBuilder->getCurrentMaterial();
}
- std::vector<SGVec3f> _vertices;
- GLenum _modeCache;
-
SGSharedPtr<BVHStaticGeometryBuilder> _geometryBuilder;
};
const BVHMaterial* pushMaterial(osg::Geode* geode)
{
- const BVHMaterial* oldMaterial = _primitiveFunctor.getCurrentMaterial();
+ const BVHMaterial* oldMaterial = _primitiveCollector.getCurrentMaterial();
const BVHMaterial* material = SGMaterialLib::findMaterial(geode);
if (material)
- _primitiveFunctor.setCurrentMaterial(material);
+ _primitiveCollector.setCurrentMaterial(material);
return oldMaterial;
}
const BVHMaterial* oldMaterial = pushMaterial(&geode);
for(unsigned i = 0; i < geode.getNumDrawables(); ++i)
- geode.getDrawable(i)->accept(_primitiveFunctor);
+ geode.getDrawable(i)->accept(_primitiveCollector);
- _primitiveFunctor.setCurrentMaterial(oldMaterial);
+ _primitiveCollector.setCurrentMaterial(oldMaterial);
}
virtual void apply(osg::Group& group)
// FIXME optimize this to collapse more leafs
// push the current active primitive list
- PFunctor previousPrimitives;
- _primitiveFunctor.swap(previousPrimitives);
+ _PrimitiveCollector previousPrimitives;
+ _primitiveCollector.swap(previousPrimitives);
const BVHMaterial* mat = previousPrimitives.getCurrentMaterial();
- _primitiveFunctor.setCurrentMaterial(mat);
+ _primitiveCollector.setCurrentMaterial(mat);
NodeVector nodeVector;
_nodeVector.swap(nodeVector);
}
// pop the current active primitive list
- _primitiveFunctor.swap(previousPrimitives);
+ _primitiveCollector.swap(previousPrimitives);
}
virtual void apply(osg::Transform& transform)
return;
// push the current active primitive list
- PFunctor previousPrimitives;
- _primitiveFunctor.swap(previousPrimitives);
+ _PrimitiveCollector previousPrimitives;
+ _primitiveCollector.swap(previousPrimitives);
const BVHMaterial* mat = previousPrimitives.getCurrentMaterial();
- _primitiveFunctor.setCurrentMaterial(mat);
+ _primitiveCollector.setCurrentMaterial(mat);
NodeVector nodeVector;
_nodeVector.swap(nodeVector);
_nodeVector.swap(nodeVector);
// pop the current active primitive list
- _primitiveFunctor.swap(previousPrimitives);
+ _primitiveCollector.swap(previousPrimitives);
if (!nodeVector.empty()) {
SGSharedPtr<BVHTransform> bvhTransform = new BVHTransform;
void addBoundingVolumeTreeToNode()
{
// Build the flat tree.
- BVHNode* bvNode = _primitiveFunctor.buildTreeAndClear();
+ BVHNode* bvNode = _primitiveCollector.buildTreeAndClear();
// Nothing in there?
if (!bvNode)
}
private:
- PFunctor _primitiveFunctor;
+ _PrimitiveCollector _primitiveCollector;
typedef std::vector<SGSharedPtr<BVHNode> > NodeVector;
NodeVector _nodeVector;
};
#include <simgear/scene/material/mat.hxx>
#include <simgear/scene/material/matlib.hxx>
+#include <simgear/scene/util/OsgMath.hxx>
#include <simgear/scene/util/SGNodeMasks.hxx>
#include <simgear/scene/util/SGSceneUserData.hxx>
#include <simgear/math/SGGeometry.hxx>
#include <simgear/bvh/BVHStaticGeometryBuilder.hxx>
+#include "PrimitiveCollector.hxx"
+
namespace simgear {
class BoundingVolumeBuildVisitor : public osg::NodeVisitor {
public:
- class PFunctor : public osg::PrimitiveFunctor {
+ class _PrimitiveCollector : public PrimitiveCollector {
public:
- PFunctor() :
- _modeCache(0)
- {
- _geometryBuilder = new BVHStaticGeometryBuilder;
- }
- virtual ~PFunctor()
+ _PrimitiveCollector() :
+ _geometryBuilder(new BVHStaticGeometryBuilder)
+ { }
+ virtual ~_PrimitiveCollector()
{ }
- virtual void setVertexArray(unsigned int count, const osg::Vec2* vertices)
- {
- _vertices.resize(count);
- for (unsigned i = 0; i < count; ++i)
- _vertices[i] = SGVec3f(vertices[i][0], vertices[i][1], 0);
- }
-
- virtual void setVertexArray(unsigned int count, const osg::Vec3* vertices)
- {
- _vertices.resize(count);
- for (unsigned i = 0; i < count; ++i)
- _vertices[i] = SGVec3f(vertices[i][0], vertices[i][1], vertices[i][2]);
- }
-
- virtual void setVertexArray(unsigned int count, const osg::Vec4* vertices)
- {
- _vertices.resize(count);
- for (unsigned i = 0; i < count; ++i)
- _vertices[i] = SGVec3f(vertices[i][0]/vertices[i][3],
- vertices[i][1]/vertices[i][3],
- vertices[i][2]/vertices[i][3]);
- }
-
- virtual void setVertexArray(unsigned int count, const osg::Vec2d* vertices)
- {
- _vertices.resize(count);
- for (unsigned i = 0; i < count; ++i)
- _vertices[i] = SGVec3f(vertices[i][0], vertices[i][1], 0);
- }
-
- virtual void setVertexArray(unsigned int count, const osg::Vec3d* vertices)
- {
- _vertices.resize(count);
- for (unsigned i = 0; i < count; ++i)
- _vertices[i] = SGVec3f(vertices[i][0], vertices[i][1], vertices[i][2]);
- }
-
- virtual void setVertexArray(unsigned int count, const osg::Vec4d* vertices)
- {
- _vertices.resize(count);
- for (unsigned i = 0; i < count; ++i)
- _vertices[i] = SGVec3f(vertices[i][0]/vertices[i][3],
- vertices[i][1]/vertices[i][3],
- vertices[i][2]/vertices[i][3]);
- }
-
- virtual void drawArrays(GLenum mode, GLint first, GLsizei count)
- {
- if (_vertices.empty() || count <= 0)
- return;
-
- GLsizei end = first + count;
- switch(mode) {
- case (GL_TRIANGLES):
- for (GLsizei i = first; i < end - 2; i += 3) {
- addTriangle(i, i + 1, i + 2);
- }
- break;
-
- case (GL_TRIANGLE_STRIP):
- for (GLsizei i = first; i < end - 2; ++i) {
- addTriangle(i, i + 1, i + 2);
- }
- break;
-
- case (GL_QUADS):
- for (GLsizei i = first; i < end - 3; i += 4) {
- addQuad(i, i + 1, i + 2, i + 3);
- }
- break;
-
- case (GL_QUAD_STRIP):
- for (GLsizei i = first; i < end - 3; i += 2) {
- addQuad(i, i + 1, i + 2, i + 3);
- }
- break;
-
- case (GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
- case (GL_TRIANGLE_FAN):
- for (GLsizei i = first; i < end - 2; ++i) {
- addTriangle(first, i + 1, i + 2);
- }
- break;
-
- case (GL_POINTS):
- for (GLsizei i = first; i < end; ++i) {
- addPoint(i);
- }
- break;
-
- case (GL_LINES):
- for (GLsizei i = first; i < end - 1; i += 2) {
- addLine(i, i + 1);
- }
- break;
-
- case (GL_LINE_STRIP):
- for (GLsizei i = first; i < end - 1; ++i) {
- addLine(i, i + 1);
- }
- break;
-
- case (GL_LINE_LOOP):
- for (GLsizei i = first; i < end - 1; ++i) {
- addLine(i, i + 1);
- }
- addLine(end - 1, first);
- break;
-
- default:
- break;
- }
- }
-
- virtual void drawElements(GLenum mode, GLsizei count, const GLubyte* indices)
- {
- drawElementsTemplate(mode, count, indices);
- }
-
- virtual void drawElements(GLenum mode, GLsizei count, const GLushort* indices)
- {
- drawElementsTemplate(mode, count, indices);
- }
-
- virtual void drawElements(GLenum mode, GLsizei count, const GLuint* indices)
- {
- drawElementsTemplate(mode, count, indices);
- }
-
- virtual void begin(GLenum mode)
- {
- _modeCache = mode;
- _vertices.resize(0);
- }
-
- virtual void vertex(const osg::Vec2& v)
- {
- _vertices.push_back(SGVec3f(v[0], v[1], 0));
- }
- virtual void vertex(const osg::Vec3& v)
- {
- _vertices.push_back(SGVec3f(v[0], v[1], v[2]));
- }
- virtual void vertex(const osg::Vec4& v)
- {
- _vertices.push_back(SGVec3f(v[0]/v[3], v[1]/v[3], v[2]/v[3]));
- }
- virtual void vertex(float x, float y)
- {
- _vertices.push_back(SGVec3f(x, y, 0));
- }
- virtual void vertex(float x, float y, float z)
- {
- _vertices.push_back(SGVec3f(x, y, z));
- }
- virtual void vertex(float x, float y, float z, float w)
- {
- _vertices.push_back(SGVec3f(x/w, y/w, z/w));
- }
- virtual void end()
- {
- if (_vertices.empty())
- return;
-
- drawArrays(_modeCache, 0, _vertices.size());
- }
-
- template<typename index_type>
- void drawElementsTemplate(GLenum mode, GLsizei count,
- const index_type* indices)
- {
- if (_vertices.empty() || indices == 0 || count <= 0)
- return;
-
- switch(mode) {
- case (GL_TRIANGLES):
- for (GLsizei i = 0; i < count - 2; i += 3) {
- addTriangle(indices[i], indices[i + 1], indices[i + 2]);
- }
- break;
-
- case (GL_TRIANGLE_STRIP):
- for (GLsizei i = 0; i < count - 2; ++i) {
- addTriangle(indices[i], indices[i + 1], indices[i + 2]);
- }
- break;
-
- case (GL_QUADS):
- for (GLsizei i = 0; i < count - 3; i += 4) {
- addQuad(indices[i], indices[i + 1], indices[i + 2], indices[i + 3]);
- }
- break;
-
- case (GL_QUAD_STRIP):
- for (GLsizei i = 0; i < count - 3; i += 2) {
- addQuad(indices[i], indices[i + 1], indices[i + 2], indices[i + 3]);
- }
- break;
-
- case (GL_POLYGON):
- case (GL_TRIANGLE_FAN):
- for (GLsizei i = 0; i < count - 2; ++i) {
- addTriangle(indices[0], indices[i + 1], indices[i + 2]);
- }
- break;
-
- case (GL_POINTS):
- for(GLsizei i = 0; i < count; ++i) {
- addPoint(indices[i]);
- }
- break;
-
- case (GL_LINES):
- for (GLsizei i = 0; i < count - 1; i += 2) {
- addLine(indices[i], indices[i + 1]);
- }
- break;
-
- case (GL_LINE_STRIP):
- for (GLsizei i = 0; i < count - 1; ++i) {
- addLine(indices[i], indices[i + 1]);
- }
- break;
-
- case (GL_LINE_LOOP):
- for (GLsizei i = 0; i < count - 1; ++i) {
- addLine(indices[i], indices[i + 1]);
- }
- addLine(indices[count - 1], indices[0]);
- break;
-
- default:
- break;
- }
- }
-
- void addPoint(unsigned i1)
- {
- addPoint(_vertices[i1]);
- }
- void addLine(unsigned i1, unsigned i2)
- {
- addLine(_vertices[i1], _vertices[i2]);
- }
- void addTriangle(unsigned i1, unsigned i2, unsigned i3)
- {
- addTriangle(_vertices[i1], _vertices[i2], _vertices[i3]);
- }
- void addQuad(unsigned i1, unsigned i2, unsigned i3, unsigned i4)
- {
- addQuad(_vertices[i1], _vertices[i2], _vertices[i3], _vertices[i4]);
- }
-
- void addPoint(const SGVec3f& v1)
- {
- }
- void addLine(const SGVec3f& v1, const SGVec3f& v2)
- {
- }
- void addTriangle(const SGVec3f& v1, const SGVec3f& v2, const SGVec3f& v3)
- {
- _geometryBuilder->addTriangle(v1, v2, v3);
- }
- void addQuad(const SGVec3f& v1, const SGVec3f& v2,
- const SGVec3f& v3, const SGVec3f& v4)
+ virtual void addPoint(const osg::Vec3d& v1)
+ { }
+ virtual void addLine(const osg::Vec3d& v1, const osg::Vec3d& v2)
+ { }
+ virtual void addTriangle(const osg::Vec3d& v1, const osg::Vec3d& v2, const osg::Vec3d& v3)
{
- _geometryBuilder->addTriangle(v1, v2, v3);
- _geometryBuilder->addTriangle(v1, v3, v4);
+ _geometryBuilder->addTriangle(toVec3f(toSG(v1)), toVec3f(toSG(v2)), toVec3f(toSG(v3)));
}
BVHNode* buildTreeAndClear()
{
BVHNode* bvNode = _geometryBuilder->buildTree();
_geometryBuilder = new BVHStaticGeometryBuilder;
- _vertices.clear();
return bvNode;
}
- void swap(PFunctor& primitiveFunctor)
+ void swap(_PrimitiveCollector& primitiveCollector)
{
- _vertices.swap(primitiveFunctor._vertices);
- std::swap(_modeCache, primitiveFunctor._modeCache);
- std::swap(_geometryBuilder, primitiveFunctor._geometryBuilder);
+ PrimitiveCollector::swap(primitiveCollector);
+ std::swap(_geometryBuilder, primitiveCollector._geometryBuilder);
}
void setCurrentMaterial(const BVHMaterial* material)
return _geometryBuilder->getCurrentMaterial();
}
- std::vector<SGVec3f> _vertices;
- GLenum _modeCache;
-
SGSharedPtr<BVHStaticGeometryBuilder> _geometryBuilder;
};
-
- // class PrimitiveIndexFunctor
- // {
- // public:
-
- // virtual ~PrimitiveIndexFunctor() {}
-
- // virtual void setVertexArray(unsigned int count,const Vec2* vertices) = 0;
- // virtual void setVertexArray(unsigned int count,const Vec3* vertices) = 0;
- // virtual void setVertexArray(unsigned int count,const Vec4* vertices) = 0;
-
- // virtual void setVertexArray(unsigned int count,const Vec2d* vertices) = 0;
- // virtual void setVertexArray(unsigned int count,const Vec3d* vertices) = 0;
- // virtual void setVertexArray(unsigned int count,const Vec4d* vertices) = 0;
-
- // virtual void drawArrays(GLenum mode,GLint first,GLsizei count) = 0;
- // virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices) = 0;
- // virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices) = 0;
- // virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) = 0;
-
- // virtual void begin(GLenum mode) = 0;
- // virtual void vertex(unsigned int pos) = 0;
- // virtual void end() = 0;
- // };
-
BoundingVolumeBuildVisitor(bool dumpIntoLeafs) :
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN),
_dumpIntoLeafs(dumpIntoLeafs)
const BVHMaterial* pushMaterial(osg::Geode* geode)
{
- const BVHMaterial* oldMaterial = _primitiveFunctor.getCurrentMaterial();
+ const BVHMaterial* oldMaterial = _primitiveCollector.getCurrentMaterial();
const BVHMaterial* material = SGMaterialLib::findMaterial(geode);
if (material)
- _primitiveFunctor.setCurrentMaterial(material);
+ _primitiveCollector.setCurrentMaterial(material);
return oldMaterial;
}
void fillWith(osg::Drawable* drawable)
{
- drawable->accept(_primitiveFunctor);
+ drawable->accept(_primitiveCollector);
}
virtual void apply(osg::Geode& geode)
bool flushHere = getNodePath().size() <= 1 || _dumpIntoLeafs;
if (flushHere) {
// push the current active primitive list
- PFunctor previousPrimitives;
- _primitiveFunctor.swap(previousPrimitives);
+ _PrimitiveCollector previousPrimitives;
+ _primitiveCollector.swap(previousPrimitives);
const BVHMaterial* mat = previousPrimitives.getCurrentMaterial();
- _primitiveFunctor.setCurrentMaterial(mat);
+ _primitiveCollector.setCurrentMaterial(mat);
// walk the children
for(unsigned i = 0; i < geode.getNumDrawables(); ++i)
addBoundingVolumeTreeToNode(geode);
// pop the current active primitive list
- _primitiveFunctor.swap(previousPrimitives);
+ _primitiveCollector.swap(previousPrimitives);
} else {
for(unsigned i = 0; i < geode.getNumDrawables(); ++i)
fillWith(geode.getDrawable(i));
}
- _primitiveFunctor.setCurrentMaterial(oldMaterial);
+ _primitiveCollector.setCurrentMaterial(oldMaterial);
}
virtual void apply(osg::Group& group)
return;
// push the current active primitive list
- PFunctor previousPrimitives;
- _primitiveFunctor.swap(previousPrimitives);
+ _PrimitiveCollector previousPrimitives;
+ _primitiveCollector.swap(previousPrimitives);
const BVHMaterial* mat = previousPrimitives.getCurrentMaterial();
- _primitiveFunctor.setCurrentMaterial(mat);
+ _primitiveCollector.setCurrentMaterial(mat);
// walk the children
traverse(node);
addBoundingVolumeTreeToNode(node);
// pop the current active primitive list
- _primitiveFunctor.swap(previousPrimitives);
+ _primitiveCollector.swap(previousPrimitives);
}
void traverseAndCollect(osg::Node& node)
void addBoundingVolumeTreeToNode(osg::Node& node)
{
// Build the flat tree.
- BVHNode* bvNode = _primitiveFunctor.buildTreeAndClear();
+ BVHNode* bvNode = _primitiveCollector.buildTreeAndClear();
// Nothing in there?
if (!bvNode)
}
private:
- PFunctor _primitiveFunctor;
+ _PrimitiveCollector _primitiveCollector;
bool _dumpIntoLeafs;
};
CheckSceneryVisitor.hxx
ConditionNode.hxx
ModelRegistry.hxx
+ PrimitiveCollector.hxx
SGClipGroup.hxx
SGInteractionAnimation.hxx
SGMaterialAnimation.hxx
CheckSceneryVisitor.cxx
ConditionNode.cxx
ModelRegistry.cxx
+ PrimitiveCollector.cxx
SGClipGroup.cxx
SGInteractionAnimation.cxx
SGLightAnimation.cxx
--- /dev/null
+// Copyright (C) 2008 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+# include <simgear_config.h>
+#endif
+
+#include "PrimitiveCollector.hxx"
+
+#include <simgear/scene/util/OsgMath.hxx>
+
+namespace simgear {
+
+PrimitiveCollector::PrimitiveCollector() :
+ _mode(0)
+{
+}
+
+PrimitiveCollector::~PrimitiveCollector()
+{
+}
+
+void
+PrimitiveCollector::swap(PrimitiveCollector& primitiveFunctor)
+{
+ _vertices.swap(primitiveFunctor._vertices);
+ std::swap(_mode, primitiveFunctor._mode);
+}
+
+void
+PrimitiveCollector::setVertexArray(unsigned int count, const osg::Vec2* vertices)
+{
+ _vertices.resize(0);
+ _vertices.reserve(count);
+ for (unsigned i = 0; i < count; ++i)
+ addVertex(osg::Vec3d(vertices[i][0], vertices[i][1], 0));
+}
+
+void
+PrimitiveCollector::setVertexArray(unsigned int count, const osg::Vec3* vertices)
+{
+ _vertices.resize(0);
+ _vertices.reserve(count);
+ for (unsigned i = 0; i < count; ++i)
+ addVertex(osg::Vec3d(vertices[i][0], vertices[i][1], vertices[i][2]));
+}
+
+void
+PrimitiveCollector::setVertexArray(unsigned int count, const osg::Vec4* vertices)
+{
+ _vertices.resize(0);
+ _vertices.reserve(count);
+ for (unsigned i = 0; i < count; ++i)
+ addVertex(osg::Vec4d(vertices[i][0], vertices[i][1], vertices[i][2], vertices[i][3]));
+}
+
+void
+PrimitiveCollector::setVertexArray(unsigned int count, const osg::Vec2d* vertices)
+{
+ _vertices.resize(0);
+ _vertices.reserve(count);
+ for (unsigned i = 0; i < count; ++i)
+ addVertex(osg::Vec3d(vertices[i][0], vertices[i][1], 0));
+}
+
+void
+PrimitiveCollector::setVertexArray(unsigned int count, const osg::Vec3d* vertices)
+{
+ _vertices.resize(0);
+ _vertices.reserve(count);
+ for (unsigned i = 0; i < count; ++i)
+ addVertex(osg::Vec3d(vertices[i][0], vertices[i][1], vertices[i][2]));
+}
+
+void
+PrimitiveCollector::setVertexArray(unsigned int count, const osg::Vec4d* vertices)
+{
+ _vertices.resize(0);
+ _vertices.reserve(count);
+ for (unsigned i = 0; i < count; ++i)
+ addVertex(osg::Vec4d(vertices[i][0], vertices[i][1], vertices[i][2], vertices[i][3]));
+}
+
+void
+PrimitiveCollector::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ if (_vertices.empty() || count <= 0)
+ return;
+
+ GLsizei end = first + count;
+ switch(mode) {
+ case (GL_TRIANGLES):
+ for (GLsizei i = first; i < end - 2; i += 3) {
+ addTriangle(i, i + 1, i + 2);
+ }
+ break;
+
+ case (GL_TRIANGLE_STRIP):
+ for (GLsizei i = first; i < end - 2; ++i) {
+ addTriangle(i, i + 1, i + 2);
+ }
+ break;
+
+ case (GL_QUADS):
+ for (GLsizei i = first; i < end - 3; i += 4) {
+ addQuad(i, i + 1, i + 2, i + 3);
+ }
+ break;
+
+ case (GL_QUAD_STRIP):
+ for (GLsizei i = first; i < end - 3; i += 2) {
+ addQuad(i, i + 1, i + 2, i + 3);
+ }
+ break;
+
+ case (GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
+ case (GL_TRIANGLE_FAN):
+ for (GLsizei i = first; i < end - 2; ++i) {
+ addTriangle(first, i + 1, i + 2);
+ }
+ break;
+
+ case (GL_POINTS):
+ for (GLsizei i = first; i < end; ++i) {
+ addPoint(i);
+ }
+ break;
+
+ case (GL_LINES):
+ for (GLsizei i = first; i < end - 1; i += 2) {
+ addLine(i, i + 1);
+ }
+ break;
+
+ case (GL_LINE_STRIP):
+ for (GLsizei i = first; i < end - 1; ++i) {
+ addLine(i, i + 1);
+ }
+ break;
+
+ case (GL_LINE_LOOP):
+ for (GLsizei i = first; i < end - 1; ++i) {
+ addLine(i, i + 1);
+ }
+ addLine(end - 1, first);
+ break;
+
+ default:
+ break;
+ }
+}
+
+template<typename index_type>
+void
+PrimitiveCollector::drawElementsTemplate(GLenum mode, GLsizei count, const index_type* indices)
+{
+ if (_vertices.empty() || indices == 0 || count <= 0)
+ return;
+
+ switch(mode) {
+ case (GL_TRIANGLES):
+ for (GLsizei i = 0; i < count - 2; i += 3) {
+ addTriangle(indices[i], indices[i + 1], indices[i + 2]);
+ }
+ break;
+
+ case (GL_TRIANGLE_STRIP):
+ for (GLsizei i = 0; i < count - 2; ++i) {
+ addTriangle(indices[i], indices[i + 1], indices[i + 2]);
+ }
+ break;
+
+ case (GL_QUADS):
+ for (GLsizei i = 0; i < count - 3; i += 4) {
+ addQuad(indices[i], indices[i + 1], indices[i + 2], indices[i + 3]);
+ }
+ break;
+
+ case (GL_QUAD_STRIP):
+ for (GLsizei i = 0; i < count - 3; i += 2) {
+ addQuad(indices[i], indices[i + 1], indices[i + 2], indices[i + 3]);
+ }
+ break;
+
+ case (GL_POLYGON):
+ case (GL_TRIANGLE_FAN):
+ for (GLsizei i = 0; i < count - 2; ++i) {
+ addTriangle(indices[0], indices[i + 1], indices[i + 2]);
+ }
+ break;
+
+ case (GL_POINTS):
+ for(GLsizei i = 0; i < count; ++i) {
+ addPoint(indices[i]);
+ }
+ break;
+
+ case (GL_LINES):
+ for (GLsizei i = 0; i < count - 1; i += 2) {
+ addLine(indices[i], indices[i + 1]);
+ }
+ break;
+
+ case (GL_LINE_STRIP):
+ for (GLsizei i = 0; i < count - 1; ++i) {
+ addLine(indices[i], indices[i + 1]);
+ }
+ break;
+
+ case (GL_LINE_LOOP):
+ for (GLsizei i = 0; i < count - 1; ++i) {
+ addLine(indices[i], indices[i + 1]);
+ }
+ addLine(indices[count - 1], indices[0]);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void
+PrimitiveCollector::drawElements(GLenum mode, GLsizei count, const GLubyte* indices)
+{
+ drawElementsTemplate(mode, count, indices);
+}
+
+void PrimitiveCollector::drawElements(GLenum mode, GLsizei count, const GLushort* indices)
+{
+ drawElementsTemplate(mode, count, indices);
+}
+
+void
+PrimitiveCollector::drawElements(GLenum mode, GLsizei count, const GLuint* indices)
+{
+ drawElementsTemplate(mode, count, indices);
+}
+
+void
+PrimitiveCollector::begin(GLenum mode)
+{
+ _mode = mode;
+ _vertices.resize(0);
+}
+
+void
+PrimitiveCollector::vertex(const osg::Vec2& v)
+{
+ addVertex(osg::Vec3d(v[0], v[1], 0));
+}
+
+void
+PrimitiveCollector::vertex(const osg::Vec3& v)
+{
+ addVertex(osg::Vec3d(v[0], v[1], v[2]));
+}
+
+void
+PrimitiveCollector::vertex(const osg::Vec4& v)
+{
+ addVertex(osg::Vec4d(v[0], v[1], v[2], v[3]));
+}
+
+void
+PrimitiveCollector::vertex(float x, float y)
+{
+ addVertex(osg::Vec3d(x, y, 0));
+}
+
+void
+PrimitiveCollector::vertex(float x, float y, float z)
+{
+ addVertex(osg::Vec3d(x, y, z));
+}
+
+void
+PrimitiveCollector::vertex(float x, float y, float z, float w)
+{
+ addVertex(osg::Vec4d(x, y, z, w));
+}
+
+void
+PrimitiveCollector::end()
+{
+ if (_vertices.empty())
+ return;
+
+ drawArrays(_mode, 0, _vertices.size());
+}
+
+void
+PrimitiveCollector::addVertex(const osg::Vec3d& v)
+{
+ _vertices.push_back(v);
+}
+
+void
+PrimitiveCollector::addVertex(const osg::Vec4d& v)
+{
+ _vertices.push_back(osg::Vec3d(v[0]/v[3], v[1]/v[3], v[2]/v[3]));
+}
+
+void
+PrimitiveCollector::addPoint(unsigned i1)
+{
+ if (_vertices.size() <= i1)
+ return;
+ addPoint(_vertices[i1]);
+}
+
+void
+PrimitiveCollector::addLine(unsigned i1, unsigned i2)
+{
+ size_t size = _vertices.size();
+ if (size <= i1 || size <= i2)
+ return;
+ addLine(_vertices[i1], _vertices[i2]);
+}
+
+void
+PrimitiveCollector::addTriangle(unsigned i1, unsigned i2, unsigned i3)
+{
+ size_t size = _vertices.size();
+ if (size <= i1 || size <= i2 || size <= i3)
+ return;
+ addTriangle(_vertices[i1], _vertices[i2], _vertices[i3]);
+}
+
+void
+PrimitiveCollector::addQuad(unsigned i1, unsigned i2, unsigned i3, unsigned i4)
+{
+ addTriangle(i1, i2, i3);
+ addTriangle(i1, i3, i4);
+}
+
+}
--- /dev/null
+// Copyright (C) 2008 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef SIMGEAR_PRIMITIVE_COLLECTOR_HXX
+#define SIMGEAR_PRIMITIVE_COLLECTOR_HXX
+
+#include <osg/Matrix>
+#include <osg/PrimitiveSet>
+
+namespace simgear {
+
+class PrimitiveCollector : public osg::PrimitiveFunctor {
+public:
+ PrimitiveCollector();
+ virtual ~PrimitiveCollector();
+
+ void swap(PrimitiveCollector& primitiveFunctor);
+
+ virtual void setVertexArray(unsigned int count, const osg::Vec2* vertices);
+ virtual void setVertexArray(unsigned int count, const osg::Vec3* vertices);
+ virtual void setVertexArray(unsigned int count, const osg::Vec4* vertices);
+ virtual void setVertexArray(unsigned int count, const osg::Vec2d* vertices);
+ virtual void setVertexArray(unsigned int count, const osg::Vec3d* vertices);
+ virtual void setVertexArray(unsigned int count, const osg::Vec4d* vertices);
+
+ virtual void drawArrays(GLenum mode, GLint first, GLsizei count);
+
+ template<typename index_type>
+ void drawElementsTemplate(GLenum mode, GLsizei count, const index_type* indices);
+ virtual void drawElements(GLenum mode, GLsizei count, const GLubyte* indices);
+ virtual void drawElements(GLenum mode, GLsizei count, const GLushort* indices);
+ virtual void drawElements(GLenum mode, GLsizei count, const GLuint* indices);
+
+ virtual void begin(GLenum mode);
+ virtual void vertex(const osg::Vec2& v);
+ virtual void vertex(const osg::Vec3& v);
+ virtual void vertex(const osg::Vec4& v);
+ virtual void vertex(float x, float y);
+ virtual void vertex(float x, float y, float z);
+ virtual void vertex(float x, float y, float z, float w);
+ virtual void end();
+
+ void addVertex(const osg::Vec3d& v);
+ void addVertex(const osg::Vec4d& v);
+
+ void addPoint(unsigned i1);
+ void addLine(unsigned i1, unsigned i2);
+ void addTriangle(unsigned i1, unsigned i2, unsigned i3);
+ void addQuad(unsigned i1, unsigned i2, unsigned i3, unsigned i4);
+
+ /// The callback functions that are called on an apropriate primitive
+ virtual void addPoint(const osg::Vec3d& v1) = 0;
+ virtual void addLine(const osg::Vec3d& v1, const osg::Vec3d& v2) = 0;
+ virtual void addTriangle(const osg::Vec3d& v1, const osg::Vec3d& v2, const osg::Vec3d& v3) = 0;
+
+private:
+ std::vector<osg::Vec3d> _vertices;
+ GLenum _mode;
+};
+
+}
+
+#endif