From David Callu, further work in support of shapefile support in VirtualPlanetBuilder

This commit is contained in:
Robert Osfield 2007-12-26 21:39:29 +00:00
parent 9d29cc53dc
commit 2aca19a4e6
10 changed files with 308 additions and 58 deletions

View File

@ -0,0 +1,38 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* 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
* OpenSceneGraph Public License for more details.
*/
#ifndef OSGUTIL_DRAWELEMENTTYPESIMPLIFIER
#define OSGUTIL_DRAWELEMENTTYPESIMPLIFIER
#include <osg/Geometry>
#include <osg/NodeVisitor>
namespace osgUtil
{
class DrawElementTypeSimplifier
{
public:
void simplify(osg::Geometry & geometry) const;
};
class DrawElementTypeSimplifierVisitor : public osg::NodeVisitor
{
public:
void apply(osg::Geode& node);
};
}
#endif // ** OSGUTIL_DRAWELEMENTTYPESIMPLIFIER ** //

View File

@ -25,6 +25,9 @@
#include <osg/Geometry>
#include <osg/ref_ptr>
#include <osgUtil/Export>
namespace osgUtil {
struct dereference_less
@ -55,7 +58,8 @@ namespace osgUtil {
}
};
class EdgeCollector
class OSGUTIL_EXPORT EdgeCollector
{
public:
@ -92,7 +96,7 @@ public:
unsigned int _index;
osg::Vec3 _vertex;
osg::Vec3d _vertex;
TriangleSet _triangles;
void clear() { _triangles.clear(); }

View File

@ -65,7 +65,7 @@ struct AddRangeOperator
typedef typename ArrayType::ElementDataType ElementDataType;
ElementDataType convertedVector;
osgUtil::ConvertVec<osg::Vec3, ElementDataType>::convert(_vector, convertedVector);
osgUtil::ConvertVec<osg::Vec3d, ElementDataType>::convert(_vector, convertedVector);
typename ArrayType::iterator it = array.begin();
std::advance(it, _begin);
@ -80,7 +80,7 @@ struct AddRangeOperator
unsigned int _begin;
unsigned int _count;
osg::Vec3 _vector;
osg::Vec3d _vector;
};
typedef OperationArrayFunctor<AddRangeOperator> AddRangeFunctor;
@ -92,7 +92,7 @@ struct MultiplyRangeOperator
typedef typename ArrayType::ElementDataType ElementDataType;
ElementDataType convertedVector;
osgUtil::ConvertVec<osg::Vec3, ElementDataType>::convert(_vector, convertedVector);
osgUtil::ConvertVec<osg::Vec3d, ElementDataType>::convert(_vector, convertedVector);
typename ArrayType::iterator it = array.begin();
std::advance(it, _begin);
@ -107,7 +107,7 @@ struct MultiplyRangeOperator
unsigned int _begin;
unsigned int _count;
osg::Vec3 _vector;
osg::Vec3d _vector;
};
typedef OperationArrayFunctor<MultiplyRangeOperator> MultiplyRangeFunctor;

View File

@ -22,54 +22,36 @@ namespace osgUtil {
class ReversePrimitiveFunctor : public osg::PrimitiveIndexFunctor
{
public:
virtual ~ReversePrimitiveFunctor() {}
osg::PrimitiveSet * getReversedPrimitiveSet() { return _reversedPrimitiveSet.get(); }
public:
virtual void setVertexArray(unsigned int /*count*/,const osg::Vec2* /*vertices*/)
{ osg::notify(osg::WARN) << "ReversePrimitiveFunctor : not implemented " << std::endl; }
virtual void setVertexArray(unsigned int /*count*/,const osg::Vec3* /*vertices*/)
{ osg::notify(osg::WARN) << "ReversePrimitiveFunctor : not implemented " << std::endl; }
virtual void setVertexArray(unsigned int /*count*/,const osg::Vec4* /*vertices*/)
{ osg::notify(osg::WARN) << "ReversePrimitiveFunctor : not implemented " << std::endl; }
virtual void setVertexArray(unsigned int /*count*/,const osg::Vec2d* /*vertices*/)
{ osg::notify(osg::WARN) << "ReversePrimitiveFunctor : not implemented " << std::endl; }
virtual void setVertexArray(unsigned int /*count*/,const osg::Vec3d* /*vertices*/)
{ osg::notify(osg::WARN) << "ReversePrimitiveFunctor : not implemented " << std::endl; }
virtual void setVertexArray(unsigned int /*count*/,const osg::Vec4d* /*vertices*/)
{ osg::notify(osg::WARN) << "ReversePrimitiveFunctor : not implemented " << std::endl; }
virtual void drawArrays(GLenum /*mode*/,GLint /*first*/,GLsizei /*count*/)
{ osg::notify(osg::WARN) << "ReversePrimitiveFunctor : not implemented " << std::endl; }
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);
/// Mimics the OpenGL \c glBegin() function.
virtual void begin(GLenum /*mode*/)
{ osg::notify(osg::WARN) << "ReversePrimitiveFunctor : not implemented " << std::endl; }
virtual void vertex(unsigned int /*pos*/)
{ osg::notify(osg::WARN) << "ReversePrimitiveFunctor : not implemented " << std::endl; }
virtual void end()
{ osg::notify(osg::WARN) << "ReversePrimitiveFunctor : not implemented " << std::endl; }
virtual ~ReversePrimitiveFunctor() {}
osg::PrimitiveSet * getReversedPrimitiveSet() { return _reversedPrimitiveSet.get(); }
virtual void setVertexArray(unsigned int , const osg::Vec2* ) {}
virtual void setVertexArray(unsigned int , const osg::Vec3* ) {}
virtual void setVertexArray(unsigned int , const osg::Vec4* ) {}
virtual void setVertexArray(unsigned int , const osg::Vec2d* ) {}
virtual void setVertexArray(unsigned int , const osg::Vec3d* ) {}
virtual void setVertexArray(unsigned int , const osg::Vec4d* ) {}
osg::ref_ptr<osg::PrimitiveSet> _reversedPrimitiveSet;
virtual void drawArrays(GLenum mode,GLint first,GLsizei count);
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);
/// Mimics the OpenGL \c glBegin() function.
virtual void begin(GLenum mode);
virtual void vertex(unsigned int /*pos*/);
virtual void end();
osg::ref_ptr<osg::PrimitiveSet> _reversedPrimitiveSet;
private:
bool _running;
};
} // end osgUtil namespace

View File

@ -14,6 +14,7 @@ SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/CullVisitor
${HEADER_PATH}/DelaunayTriangulator
${HEADER_PATH}/DisplayRequirementsVisitor
${HEADER_PATH}/DrawElementTypeSimplifier
${HEADER_PATH}/EdgeCollector
${HEADER_PATH}/Export
${HEADER_PATH}/GLObjectsVisitor
@ -53,6 +54,7 @@ ADD_LIBRARY(${LIB_NAME}
CullVisitor.cpp
DelaunayTriangulator.cpp
DisplayRequirementsVisitor.cpp
DrawElementTypeSimplifier.cpp
EdgeCollector.cpp
GLObjectsVisitor.cpp
HalfWayMapGenerator.cpp

View File

@ -0,0 +1,83 @@
#include <osgUtil/DrawElementTypeSimplifier>
#include <osg/Geode>
template <typename InType, typename OutType>
OutType * copy(InType& array)
{
unsigned int size = array.size();
OutType * newArray = new OutType(array.getMode(), size);
OutType & na = *newArray;
for (unsigned int i = 0; i < size; ++i) na[i] = array[i];
return newArray;
}
template <typename InType>
unsigned int getMax(InType& array)
{
unsigned int max = 0;
unsigned int size = array.size();
for (unsigned int i = 0; i < size; ++i)
{
if (array[i] > max) max = array[i];
}
return (max);
}
namespace osgUtil
{
void DrawElementTypeSimplifier::simplify(osg::Geometry & geometry) const
{
osg::Geometry::PrimitiveSetList & psl = geometry.getPrimitiveSetList();
osg::Geometry::PrimitiveSetList::iterator it, end = psl.end();
unsigned int max = 0;
for (it = psl.begin(); it!=end; ++it)
{
switch ((*it)->getType())
{
case osg::PrimitiveSet::DrawElementsUShortPrimitiveType:
{
osg::DrawElementsUShort & de = *static_cast<osg::DrawElementsUShort*>(it->get());
max = getMax<osg::DrawElementsUShort>(de);
if (max < 255) *it = copy<osg::DrawElementsUShort, osg::DrawElementsUByte>(de);
break;
}
case osg::PrimitiveSet::DrawElementsUIntPrimitiveType:
{
osg::DrawElementsUInt & de = *static_cast<osg::DrawElementsUInt*>(it->get());
max = getMax<osg::DrawElementsUInt>(de);
if (max < 256) *it = copy<osg::DrawElementsUInt, osg::DrawElementsUByte>(de);
else if (max < 65536) *it = copy<osg::DrawElementsUInt, osg::DrawElementsUShort>(de);
break;
}
default: break;
}
}
}
void DrawElementTypeSimplifierVisitor::apply(osg::Geode& node)
{
DrawElementTypeSimplifier dets;
unsigned int numDrawables = node.getNumDrawables();
for (unsigned int i = 0; i != numDrawables; ++i)
{
osg::Geometry * geom = dynamic_cast<osg::Geometry*>(node.getDrawable(i));
if (geom) dets.simplify(*geom);
}
osg::NodeVisitor::apply((osg::Node&)node);
}
}

View File

@ -12,6 +12,7 @@
*/
#include <osgUtil/EdgeCollector>
#include <osgUtil/ConvertVec>
#include <osg/TriangleIndexFunctor>
@ -357,9 +358,7 @@ class CopyVertexArrayToPointsVisitor : public osg::ArrayVisitor
_pointList[i] = new EdgeCollector::Point;
_pointList[i]->_index = i;
osg::Vec2& value = array[i];
osg::Vec3& vertex = _pointList[i]->_vertex;
vertex.set(value.x(),value.y(),0.0f);
osgUtil::ConvertVec<osg::Vec2, osg::Vec3d>::convert(array[i], _pointList[i]->_vertex);
}
}
@ -385,9 +384,46 @@ class CopyVertexArrayToPointsVisitor : public osg::ArrayVisitor
_pointList[i] = new EdgeCollector::Point;
_pointList[i]->_index = i;
osg::Vec4& value = array[i];
osg::Vec3& vertex = _pointList[i]->_vertex;
vertex.set(value.x()/value.w(),value.y()/value.w(),value.z()/value.w());
osgUtil::ConvertVec<osg::Vec4, osg::Vec3d>::convert(array[i], _pointList[i]->_vertex);
}
}
virtual void apply(osg::Vec2dArray& array)
{
if (_pointList.size()!=array.size()) return;
for(unsigned int i=0;i<_pointList.size();++i)
{
_pointList[i] = new EdgeCollector::Point;
_pointList[i]->_index = i;
osgUtil::ConvertVec<osg::Vec2d, osg::Vec3d>::convert(array[i], _pointList[i]->_vertex);
}
}
virtual void apply(osg::Vec3dArray& array)
{
if (_pointList.size()!=array.size()) return;
for(unsigned int i=0;i<_pointList.size();++i)
{
_pointList[i] = new EdgeCollector::Point;
_pointList[i]->_index = i;
_pointList[i]->_vertex = array[i];
}
}
virtual void apply(osg::Vec4dArray& array)
{
if (_pointList.size()!=array.size()) return;
for(unsigned int i=0;i<_pointList.size();++i)
{
_pointList[i] = new EdgeCollector::Point;
_pointList[i]->_index = i;
osgUtil::ConvertVec<osg::Vec4d, osg::Vec3d>::convert(array[i], _pointList[i]->_vertex);
}
}

View File

@ -97,6 +97,76 @@ osg::PrimitiveSet * drawElementsTemplate(GLenum mode,GLsizei count, const typena
namespace osgUtil {
void ReversePrimitiveFunctor::drawArrays(GLenum mode, GLint first, GLsizei count)
{
if (count==0) return ;
osg::DrawElementsUInt * dePtr = new osg::DrawElementsUInt(mode);
osg::DrawElementsUInt & de = *dePtr;
de.reserve(count);
GLint end = first + count;
switch (mode)
{
case (GL_TRIANGLES):
{
for (GLint i=first; i<end; i+=3)
{
de.push_back(i);
de.push_back(i+2);
de.push_back(i+1);
}
break;
}
case (GL_QUADS):
{
for (GLint i=first; i<end; i+=4)
{
de.push_back(i);
de.push_back(i+3);
de.push_back(i+2);
de.push_back(i+1);
}
break;
}
case (GL_TRIANGLE_STRIP):
case (GL_QUAD_STRIP):
{
for (GLint i=first; i<end; i+=2)
{
de.push_back(i+1);
de.push_back(i);
}
break;
}
case (GL_TRIANGLE_FAN):
{
de.push_back(first);
for (GLint i=end-1; i>first; i--)
de.push_back(i);
break;
}
case (GL_POLYGON):
case (GL_POINTS):
case (GL_LINES):
case (GL_LINE_STRIP):
case (GL_LINE_LOOP):
{
for (GLint i=end-1; i>=first; i--)
de.push_back(i);
break;
}
default:
break;
}
_reversedPrimitiveSet = &de;
}
void ReversePrimitiveFunctor::drawElements(GLenum mode,GLsizei count,const GLubyte* indices)
{
_reversedPrimitiveSet = drawElementsTemplate<osg::DrawElementsUByte>(mode, count, indices);
@ -110,4 +180,39 @@ void ReversePrimitiveFunctor::drawElements(GLenum mode,GLsizei count,const GLuin
_reversedPrimitiveSet = drawElementsTemplate<osg::DrawElementsUInt>(mode, count, indices);
}
void ReversePrimitiveFunctor::begin(GLenum mode)
{
if (_running)
osg::notify(osg::WARN) << "ReversePrimitiveFunctor : call \"begin\" without call \"end\"." << std::endl;
else
{
_running = true;
_reversedPrimitiveSet = new osg::DrawElementsUInt(mode);
}
}
void ReversePrimitiveFunctor::vertex(unsigned int pos)
{
if (_running == false)
osg::notify(osg::WARN) << "ReversePrimitiveFunctor : call \"vertex(" << pos << ")\" without call \"begin\"." << std::endl;
else
{
static_cast<osg::DrawElementsUInt*>(_reversedPrimitiveSet.get())->push_back(pos);
}
}
void ReversePrimitiveFunctor::end()
{
if (_running == false)
osg::notify(osg::WARN) << "ReversePrimitiveFunctor : call \"end\" without call \"begin\"." << std::endl;
else
{
_running = false;
osg::ref_ptr<osg::DrawElementsUInt> tmpDe(static_cast<osg::DrawElementsUInt*>(_reversedPrimitiveSet.get()));
_reversedPrimitiveSet = drawElementsTemplate<osg::DrawElementsUInt>(tmpDe->getMode(), tmpDe->size(), &(tmpDe->front()));
}
}
} // end osgUtil namespace

View File

@ -217,7 +217,7 @@ BEGIN_OBJECT_REFLECTOR(osgUtil::EdgeCollector::Point)
"");
I_PublicMemberProperty(bool, _protected);
I_PublicMemberProperty(unsigned int, _index);
I_PublicMemberProperty(osg::Vec3, _vertex);
I_PublicMemberProperty(osg::Vec3d, _vertex);
I_PublicMemberProperty(osgUtil::EdgeCollector::TriangleSet, _triangles);
END_REFLECTOR

View File

@ -68,7 +68,7 @@ BEGIN_ABSTRACT_OBJECT_REFLECTOR(osgUtil::ReversePrimitiveFunctor)
__void__setVertexArray__unsigned__C5_osg_Vec4d_P1,
"",
"");
I_Method3(void, drawArrays, IN, GLenum, x, IN, GLint, x, IN, GLsizei, x,
I_Method3(void, drawArrays, IN, GLenum, mode, IN, GLint, first, IN, GLsizei, count,
Properties::VIRTUAL,
__void__drawArrays__GLenum__GLint__GLsizei,
"",
@ -88,7 +88,7 @@ BEGIN_ABSTRACT_OBJECT_REFLECTOR(osgUtil::ReversePrimitiveFunctor)
__void__drawElements__GLenum__GLsizei__C5_GLuint_P1,
"",
"");
I_Method1(void, begin, IN, GLenum, x,
I_Method1(void, begin, IN, GLenum, mode,
Properties::VIRTUAL,
__void__begin__GLenum,
"Mimics the OpenGL glBegin() function. ",