scene: Factor out a common primitive functor.
This kind of work is done two times for different flavours of bounding volume generation. Factor out and use this in BVHPageNodeOSG.cxx and BoundingVolumeBuildVisitor.hxx.
This commit is contained in:
parent
cafbf860be
commit
63aa16b97c
@ -31,7 +31,6 @@
|
||||
#include <osg/PagedLOD>
|
||||
#include <osg/ProxyNode>
|
||||
#include <osg/Transform>
|
||||
#include <osg/TriangleFunctor>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include <simgear/scene/material/mat.hxx>
|
||||
@ -43,303 +42,40 @@
|
||||
|
||||
#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)
|
||||
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)
|
||||
{
|
||||
_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)
|
||||
{
|
||||
_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)
|
||||
@ -351,9 +87,6 @@ public:
|
||||
return _geometryBuilder->getCurrentMaterial();
|
||||
}
|
||||
|
||||
std::vector<SGVec3f> _vertices;
|
||||
GLenum _modeCache;
|
||||
|
||||
SGSharedPtr<BVHStaticGeometryBuilder> _geometryBuilder;
|
||||
};
|
||||
|
||||
@ -368,10 +101,10 @@ public:
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -380,9 +113,9 @@ public:
|
||||
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)
|
||||
@ -390,11 +123,11 @@ public:
|
||||
// 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);
|
||||
@ -422,7 +155,7 @@ public:
|
||||
}
|
||||
|
||||
// pop the current active primitive list
|
||||
_primitiveFunctor.swap(previousPrimitives);
|
||||
_primitiveCollector.swap(previousPrimitives);
|
||||
}
|
||||
|
||||
virtual void apply(osg::Transform& transform)
|
||||
@ -435,11 +168,11 @@ public:
|
||||
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);
|
||||
@ -455,7 +188,7 @@ public:
|
||||
_nodeVector.swap(nodeVector);
|
||||
|
||||
// pop the current active primitive list
|
||||
_primitiveFunctor.swap(previousPrimitives);
|
||||
_primitiveCollector.swap(previousPrimitives);
|
||||
|
||||
if (!nodeVector.empty()) {
|
||||
SGSharedPtr<BVHTransform> bvhTransform = new BVHTransform;
|
||||
@ -479,7 +212,7 @@ public:
|
||||
void addBoundingVolumeTreeToNode()
|
||||
{
|
||||
// Build the flat tree.
|
||||
BVHNode* bvNode = _primitiveFunctor.buildTreeAndClear();
|
||||
BVHNode* bvNode = _primitiveCollector.buildTreeAndClear();
|
||||
|
||||
// Nothing in there?
|
||||
if (!bvNode)
|
||||
@ -553,7 +286,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
PFunctor _primitiveFunctor;
|
||||
_PrimitiveCollector _primitiveCollector;
|
||||
typedef std::vector<SGSharedPtr<BVHNode> > NodeVector;
|
||||
NodeVector _nodeVector;
|
||||
};
|
||||
|
@ -29,309 +29,47 @@
|
||||
|
||||
#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)
|
||||
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)
|
||||
{
|
||||
_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)
|
||||
{
|
||||
_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)
|
||||
@ -343,37 +81,9 @@ public:
|
||||
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)
|
||||
@ -386,16 +96,16 @@ public:
|
||||
|
||||
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)
|
||||
@ -408,11 +118,11 @@ public:
|
||||
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)
|
||||
@ -422,13 +132,13 @@ public:
|
||||
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)
|
||||
@ -455,11 +165,11 @@ public:
|
||||
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);
|
||||
@ -470,7 +180,7 @@ public:
|
||||
addBoundingVolumeTreeToNode(node);
|
||||
|
||||
// pop the current active primitive list
|
||||
_primitiveFunctor.swap(previousPrimitives);
|
||||
_primitiveCollector.swap(previousPrimitives);
|
||||
}
|
||||
|
||||
void traverseAndCollect(osg::Node& node)
|
||||
@ -495,7 +205,7 @@ public:
|
||||
void addBoundingVolumeTreeToNode(osg::Node& node)
|
||||
{
|
||||
// Build the flat tree.
|
||||
BVHNode* bvNode = _primitiveFunctor.buildTreeAndClear();
|
||||
BVHNode* bvNode = _primitiveCollector.buildTreeAndClear();
|
||||
|
||||
// Nothing in there?
|
||||
if (!bvNode)
|
||||
@ -518,7 +228,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
PFunctor _primitiveFunctor;
|
||||
_PrimitiveCollector _primitiveCollector;
|
||||
bool _dumpIntoLeafs;
|
||||
};
|
||||
|
||||
|
@ -7,6 +7,7 @@ set(HEADERS
|
||||
CheckSceneryVisitor.hxx
|
||||
ConditionNode.hxx
|
||||
ModelRegistry.hxx
|
||||
PrimitiveCollector.hxx
|
||||
SGClipGroup.hxx
|
||||
SGInteractionAnimation.hxx
|
||||
SGMaterialAnimation.hxx
|
||||
@ -29,6 +30,7 @@ set(SOURCES
|
||||
CheckSceneryVisitor.cxx
|
||||
ConditionNode.cxx
|
||||
ModelRegistry.cxx
|
||||
PrimitiveCollector.cxx
|
||||
SGClipGroup.cxx
|
||||
SGInteractionAnimation.cxx
|
||||
SGLightAnimation.cxx
|
||||
|
350
simgear/scene/model/PrimitiveCollector.cxx
Normal file
350
simgear/scene/model/PrimitiveCollector.cxx
Normal file
@ -0,0 +1,350 @@
|
||||
// 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);
|
||||
}
|
||||
|
||||
}
|
77
simgear/scene/model/PrimitiveCollector.hxx
Normal file
77
simgear/scene/model/PrimitiveCollector.hxx
Normal file
@ -0,0 +1,77 @@
|
||||
// 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
|
Loading…
Reference in New Issue
Block a user