From David Callu, various classes in support of VirtualPlanetBuilder
This commit is contained in:
139
include/osgUtil/ConvertVec
Normal file
139
include/osgUtil/ConvertVec
Normal file
@@ -0,0 +1,139 @@
|
||||
/* -*-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_CONVERTVEC
|
||||
#define OSGUTIL_CONVERTVEC 1
|
||||
|
||||
namespace osgUtil {
|
||||
|
||||
template <typename InType, typename OutType,
|
||||
unsigned int InSize = InType::num_components,
|
||||
unsigned int OutSize = OutType::num_components>
|
||||
struct ConvertVec
|
||||
{
|
||||
static void convert(InType & in, OutType & out)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
struct ConvertVec<InType, OutType, 2, 2>
|
||||
{
|
||||
static void convert(InType & in, OutType & out)
|
||||
{
|
||||
out.set(static_cast<typename OutType::value_type>(in.x()),
|
||||
static_cast<typename OutType::value_type>(in.y()));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
struct ConvertVec<InType, OutType, 2, 3>
|
||||
{
|
||||
static void convert(InType & in, OutType & out)
|
||||
{
|
||||
out.set(static_cast<typename OutType::value_type>(in.x()),
|
||||
static_cast<typename OutType::value_type>(in.y()),
|
||||
static_cast<typename OutType::value_type>(0.0));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
struct ConvertVec<InType, OutType, 2, 4>
|
||||
{
|
||||
static void convert(InType & in, OutType & out)
|
||||
{
|
||||
out.set(static_cast<typename OutType::value_type>(in.x()),
|
||||
static_cast<typename OutType::value_type>(in.y()),
|
||||
static_cast<typename OutType::value_type>(0.0),
|
||||
static_cast<typename OutType::value_type>(1.0));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
struct ConvertVec<InType, OutType, 3, 2>
|
||||
{
|
||||
static void convert(InType & in, OutType & out)
|
||||
{
|
||||
out.set(static_cast<typename OutType::value_type>(in.x()),
|
||||
static_cast<typename OutType::value_type>(in.y()));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
struct ConvertVec<InType, OutType, 3, 3>
|
||||
{
|
||||
static void convert(InType & in, OutType & out)
|
||||
{
|
||||
out.set(static_cast<typename OutType::value_type>(in.x()),
|
||||
static_cast<typename OutType::value_type>(in.y()),
|
||||
static_cast<typename OutType::value_type>(in.z()));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
struct ConvertVec<InType, OutType, 3, 4>
|
||||
{
|
||||
static void convert(InType & in, OutType & out)
|
||||
{
|
||||
out.set(static_cast<typename OutType::value_type>(in.x()),
|
||||
static_cast<typename OutType::value_type>(in.y()),
|
||||
static_cast<typename OutType::value_type>(in.z()),
|
||||
static_cast<typename OutType::value_type>(1.0));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
struct ConvertVec<InType, OutType, 4, 2>
|
||||
{
|
||||
static void convert(InType & in, OutType & out)
|
||||
{
|
||||
out.set(static_cast<typename OutType::value_type>(in.x()/in.w()),
|
||||
static_cast<typename OutType::value_type>(in.y()/in.w()));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
struct ConvertVec<InType, OutType, 4, 3>
|
||||
{
|
||||
static void convert(InType & in, OutType & out)
|
||||
{
|
||||
out.set(static_cast<typename OutType::value_type>(in.x()/in.w()),
|
||||
static_cast<typename OutType::value_type>(in.y()/in.w()),
|
||||
static_cast<typename OutType::value_type>(in.z()/in.w()));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
struct ConvertVec<InType, OutType, 4, 4>
|
||||
{
|
||||
static void convert(InType & in, OutType & out)
|
||||
{
|
||||
out.set(static_cast<typename OutType::value_type>(in.x()),
|
||||
static_cast<typename OutType::value_type>(in.y()),
|
||||
static_cast<typename OutType::value_type>(in.z()),
|
||||
static_cast<typename OutType::value_type>(in.w()));
|
||||
}
|
||||
};
|
||||
|
||||
} // end of osg namespace
|
||||
|
||||
#endif // ** OSG_CONVERTVEC ** //
|
||||
210
include/osgUtil/EdgeCollector
Normal file
210
include/osgUtil/EdgeCollector
Normal file
@@ -0,0 +1,210 @@
|
||||
/* -*-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_EDGECOLLECTOR
|
||||
#define OSGUTIL_EDGECOLLECTOR 1
|
||||
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <osg/Array>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
namespace osgUtil {
|
||||
|
||||
struct dereference_less
|
||||
{
|
||||
template<class T, class U>
|
||||
inline bool operator() (const T& lhs,const U& rhs) const
|
||||
{
|
||||
return *lhs < *rhs;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
bool dereference_check_less(const T& lhs,const T& rhs)
|
||||
{
|
||||
if (lhs==rhs) return false;
|
||||
if (!lhs) return true;
|
||||
if (!rhs) return false;
|
||||
return *lhs < *rhs;
|
||||
}
|
||||
|
||||
struct dereference_clear
|
||||
{
|
||||
template<class T>
|
||||
inline void operator() (const T& t)
|
||||
{
|
||||
T& non_const_t = const_cast<T&>(t);
|
||||
non_const_t->clear();
|
||||
}
|
||||
};
|
||||
|
||||
class EdgeCollector
|
||||
{
|
||||
public:
|
||||
|
||||
struct Triangle;
|
||||
struct Edge;
|
||||
struct Edgeloop;
|
||||
struct Point;
|
||||
|
||||
|
||||
|
||||
typedef std::list<osg::ref_ptr<osg::UIntArray> > IndexArrayList;
|
||||
|
||||
~EdgeCollector();
|
||||
|
||||
void setGeometry(osg::Geometry* geometry);
|
||||
osg::Geometry* getGeometry() { return _geometry; }
|
||||
|
||||
unsigned int getNumOfTriangles() { return _triangleSet.size(); }
|
||||
|
||||
typedef std::set<osg::ref_ptr<Edge>,dereference_less > EdgeSet;
|
||||
typedef std::vector<osg::ref_ptr<Edge> > EdgeList;
|
||||
typedef std::list< osg::ref_ptr<Edgeloop> > EdgeloopList;
|
||||
typedef std::set< osg::ref_ptr<Point>,dereference_less > PointSet;
|
||||
typedef std::vector< osg::ref_ptr<Point> > PointList;
|
||||
typedef std::list< osg::ref_ptr<Triangle> > TriangleList;
|
||||
typedef std::set< osg::ref_ptr<Triangle> > TriangleSet;
|
||||
typedef std::map< osg::ref_ptr<Triangle>, unsigned int, dereference_less > TriangleMap;
|
||||
|
||||
struct Point : public osg::Referenced
|
||||
{
|
||||
Point(): _protected(false), _index(0) {}
|
||||
|
||||
bool _protected;
|
||||
|
||||
unsigned int _index;
|
||||
|
||||
osg::Vec3 _vertex;
|
||||
TriangleSet _triangles;
|
||||
|
||||
void clear() { _triangles.clear(); }
|
||||
|
||||
bool operator < ( const Point& rhs) const { return _vertex < rhs._vertex; }
|
||||
|
||||
bool isBoundaryPoint() const;
|
||||
};
|
||||
|
||||
struct Edge : public osg::Referenced
|
||||
{
|
||||
void clear();
|
||||
|
||||
osg::ref_ptr<Point> _p1;
|
||||
osg::ref_ptr<Point> _p2;
|
||||
|
||||
osg::ref_ptr<Point> _op1;
|
||||
osg::ref_ptr<Point> _op2;
|
||||
|
||||
TriangleSet _triangles;
|
||||
|
||||
|
||||
bool operator < ( const Edge& rhs) const;
|
||||
|
||||
bool operator == ( const Edge& rhs) const;
|
||||
|
||||
bool operator != ( const Edge& rhs) const;
|
||||
|
||||
void setOrderedPoints(Point* p1, Point* p2);
|
||||
|
||||
void addTriangle(Triangle* triangle) { _triangles.insert(triangle); }
|
||||
|
||||
bool isBoundaryEdge() const { return _triangles.size()<=1; }
|
||||
|
||||
bool isAdjacentToBoundary() const { return isBoundaryEdge() || _p1->isBoundaryPoint() || _p2->isBoundaryPoint(); }
|
||||
|
||||
bool endConnected(const Edge& rhs) const { return (_op2 == rhs._op1); }
|
||||
|
||||
bool beginConnected(const Edge& rhs) const { return (_op1 == rhs._op2); }
|
||||
};
|
||||
|
||||
struct Triangle : public osg::Referenced
|
||||
{
|
||||
Triangle() {}
|
||||
|
||||
void clear();
|
||||
|
||||
inline bool operator < (const Triangle& rhs) const;
|
||||
|
||||
|
||||
void setOrderedPoints(Point* p1, Point* p2, Point* p3);
|
||||
|
||||
float distance(const osg::Vec3& vertex) const { return _plane.distance(vertex); }
|
||||
|
||||
bool isBoundaryTriangle() const
|
||||
{ return (_e1->isBoundaryEdge() || _e2->isBoundaryEdge() || _e3->isBoundaryEdge()); }
|
||||
|
||||
|
||||
osg::ref_ptr<Point> _p1;
|
||||
osg::ref_ptr<Point> _p2;
|
||||
osg::ref_ptr<Point> _p3;
|
||||
|
||||
osg::ref_ptr<Point> _op1;
|
||||
osg::ref_ptr<Point> _op2;
|
||||
osg::ref_ptr<Point> _op3;
|
||||
|
||||
osg::ref_ptr<Edge> _e1;
|
||||
osg::ref_ptr<Edge> _e2;
|
||||
osg::ref_ptr<Edge> _e3;
|
||||
|
||||
osg::Plane _plane;
|
||||
};
|
||||
|
||||
class Edgeloop : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
typedef std::vector<osg::ref_ptr<Edge> > EdgeList;
|
||||
|
||||
bool isClosed() { return (_edgeList.back()->endConnected(*_edgeList.front().get())); }
|
||||
|
||||
osg::UIntArray * toIndexArray() const;
|
||||
|
||||
EdgeList _edgeList;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Triangle* addTriangle(unsigned int p1, unsigned int p2, unsigned int p3);
|
||||
Triangle* addTriangle(Point* p1, Point* p2, Point* p3);
|
||||
|
||||
Edge* addEdge(Triangle* triangle, Point* p1, Point* p2);
|
||||
|
||||
Point* addPoint(Triangle* triangle, unsigned int p1) { return addPoint(triangle,_originalPointList[p1].get()); }
|
||||
Point* addPoint(Triangle* triangle, Point* point);
|
||||
|
||||
void getBoundaryEdgeList(EdgeList & el);
|
||||
bool extractBoundaryEdgeloop(EdgeList & el, Edgeloop & edgeloop);
|
||||
bool extractBoundaryEdgeloopList(EdgeList & el, EdgeloopList & edgeloopList);
|
||||
|
||||
void getEdgeloopIndexList(IndexArrayList & ial);
|
||||
|
||||
//protected:
|
||||
|
||||
osg::Geometry* _geometry;
|
||||
|
||||
EdgeSet _edgeSet;
|
||||
TriangleSet _triangleSet;
|
||||
PointSet _pointSet;
|
||||
PointList _originalPointList;
|
||||
|
||||
};
|
||||
|
||||
} // end of osgUtil namespace
|
||||
|
||||
#endif // ** OSGUTIL_EDGECOLLECTOR ** //
|
||||
103
include/osgUtil/OperationArrayFunctor
Normal file
103
include/osgUtil/OperationArrayFunctor
Normal file
@@ -0,0 +1,103 @@
|
||||
#ifndef OSGUTIL_OPERATIONARRAYFUNCTOR
|
||||
#define OSGUTIL_OPERATIONARRAYFUNCTOR 1
|
||||
|
||||
|
||||
#include <osg/Array>
|
||||
#include <osgUtil/ConvertVec>
|
||||
|
||||
// ** template ArrayVisitor to handle all method in one template.
|
||||
// ** Only use when process done on each array could be templated
|
||||
|
||||
namespace osgUtil {
|
||||
|
||||
template <class T>
|
||||
class OperationArrayFunctor : public osg::ArrayVisitor, public T
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void apply(osg::Array&) {}
|
||||
// virtual void apply(osg::ByteArray& array) { T::process<osg::ByteArray>(array); }
|
||||
// virtual void apply(osg::ShortArray& array) { T::process(array); }
|
||||
// virtual void apply(osg::IntArray& array) { T::process<osg::IntArray>(array); }
|
||||
// virtual void apply(osg::UByteArray& array) { T::process<osg::UByteArray>(array); }
|
||||
// virtual void apply(osg::UShortArray& array) { T::process<osg::UShortArray>(array); }
|
||||
// virtual void apply(osg::UIntArray& array) { T::process<osg::UIntArray>(array); }
|
||||
// virtual void apply(osg::FloatArray& array) { T::process<osg::FloatArray>(array); }
|
||||
// virtual void apply(osg::DoubleArray& array) { T::process<osg::DoubleArray>(array); }
|
||||
|
||||
virtual void apply(osg::Vec2Array & array) { T::process(array); }
|
||||
virtual void apply(osg::Vec3Array& array) { T::process(array); }
|
||||
virtual void apply(osg::Vec4Array& array) { T::process(array); }
|
||||
|
||||
virtual void apply(osg::Vec4ubArray& array) { T::process(array); }
|
||||
|
||||
virtual void apply(osg::Vec2bArray& array) { T::process(array); }
|
||||
virtual void apply(osg::Vec3bArray& array) { T::process(array); }
|
||||
virtual void apply(osg::Vec4bArray& array) { T::process(array); }
|
||||
|
||||
virtual void apply(osg::Vec2sArray& array) { T::process(array); }
|
||||
virtual void apply(osg::Vec3sArray& array) { T::process(array); }
|
||||
virtual void apply(osg::Vec4sArray& array) { T::process(array); }
|
||||
|
||||
virtual void apply(osg::Vec2dArray& array) { T::process(array); }
|
||||
virtual void apply(osg::Vec3dArray& array) { T::process(array); }
|
||||
virtual void apply(osg::Vec4dArray& array) { T::process(array); }
|
||||
};
|
||||
|
||||
struct AddRangeOperator
|
||||
{
|
||||
template <typename ArrayType>
|
||||
void process(ArrayType & array)
|
||||
{
|
||||
typedef typename ArrayType::ElementDataType ElementDataType;
|
||||
|
||||
ElementDataType convertedVector;
|
||||
osgUtil::ConvertVec<osg::Vec3, ElementDataType>::convert(_vector, convertedVector);
|
||||
|
||||
typename ArrayType::iterator it = array.begin();
|
||||
std::advance(it, _begin);
|
||||
|
||||
typename ArrayType::iterator end = it;
|
||||
std::advance(end, _count);
|
||||
|
||||
for (; it < end; ++it)
|
||||
(*it) += convertedVector;
|
||||
}
|
||||
|
||||
unsigned int _begin;
|
||||
unsigned int _count;
|
||||
|
||||
osg::Vec3 _vector;
|
||||
};
|
||||
typedef OperationArrayFunctor<AddRangeOperator> AddRangeFunctor;
|
||||
|
||||
struct MultiplyRangeOperator
|
||||
{
|
||||
template <typename ArrayType>
|
||||
void process(ArrayType & array)
|
||||
{
|
||||
typedef typename ArrayType::ElementDataType ElementDataType;
|
||||
|
||||
ElementDataType convertedVector;
|
||||
osgUtil::ConvertVec<osg::Vec3, ElementDataType>::convert(_vector, convertedVector);
|
||||
|
||||
typename ArrayType::iterator it = array.begin();
|
||||
std::advance(it, _begin);
|
||||
|
||||
typename ArrayType::iterator end = it;
|
||||
std::advance(end, _count);
|
||||
|
||||
for (; it < end; ++it)
|
||||
(*it) *= convertedVector;
|
||||
}
|
||||
|
||||
unsigned int _begin;
|
||||
unsigned int _count;
|
||||
|
||||
osg::Vec3 _vector;
|
||||
};
|
||||
typedef OperationArrayFunctor<MultiplyRangeOperator> MultiplyRangeFunctor;
|
||||
|
||||
} // end osgUtil namespace
|
||||
|
||||
#endif // ** OPERATIONARRAYFUNCTOR ** //
|
||||
77
include/osgUtil/ReversePrimitiveFunctor
Normal file
77
include/osgUtil/ReversePrimitiveFunctor
Normal file
@@ -0,0 +1,77 @@
|
||||
/* -*-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_REVERSEPRIMITIVEFUNCTOR
|
||||
#define OSGUTIL_REVERSEPRIMITIVEFUNCTOR 1
|
||||
|
||||
#include <osg/PrimitiveSet>
|
||||
#include <osg/Notify>
|
||||
|
||||
namespace osgUtil {
|
||||
|
||||
|
||||
class ReversePrimitiveFunctor : public osg::PrimitiveIndexFunctor
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~ReversePrimitiveFunctor() {}
|
||||
|
||||
osg::PrimitiveSet * getReversedPrimitiveSet() { return _reversedPrimitiveSet.get(); }
|
||||
|
||||
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; }
|
||||
|
||||
|
||||
osg::ref_ptr<osg::PrimitiveSet> _reversedPrimitiveSet;
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // end osgUtil namespace
|
||||
|
||||
#endif // ** OSGUTIL_REVERSEFACEVISITOR ** //
|
||||
@@ -9,17 +9,20 @@ ENDIF(DYNAMIC_OPENSCENEGRAPH)
|
||||
SET(LIB_NAME osgUtil)
|
||||
SET(HEADER_PATH ${OpenSceneGraph_SOURCE_DIR}/include/${LIB_NAME})
|
||||
SET(LIB_PUBLIC_HEADERS
|
||||
${HEADER_PATH}/ConvertVec
|
||||
${HEADER_PATH}/CubeMapGenerator
|
||||
${HEADER_PATH}/CullVisitor
|
||||
${HEADER_PATH}/DelaunayTriangulator
|
||||
${HEADER_PATH}/DisplayRequirementsVisitor
|
||||
${HEADER_PATH}/EdgeCollector
|
||||
${HEADER_PATH}/Export
|
||||
${HEADER_PATH}/GLObjectsVisitor
|
||||
${HEADER_PATH}/HalfWayMapGenerator
|
||||
${HEADER_PATH}/HighlightMapGenerator
|
||||
${HEADER_PATH}/IntersectVisitor
|
||||
${HEADER_PATH}/IntersectionVisitor
|
||||
${HEADER_PATH}/IntersectVisitor
|
||||
${HEADER_PATH}/LineSegmentIntersector
|
||||
${HEADER_PATH}/OperationArrayFunctor
|
||||
${HEADER_PATH}/Optimizer
|
||||
${HEADER_PATH}/PlaneIntersector
|
||||
${HEADER_PATH}/PolytopeIntersector
|
||||
@@ -28,6 +31,7 @@ SET(LIB_PUBLIC_HEADERS
|
||||
${HEADER_PATH}/RenderBin
|
||||
${HEADER_PATH}/RenderLeaf
|
||||
${HEADER_PATH}/RenderStage
|
||||
${HEADER_PATH}/ReversePrimitiveFunctor
|
||||
${HEADER_PATH}/SceneView
|
||||
${HEADER_PATH}/Simplifier
|
||||
${HEADER_PATH}/SmoothingVisitor
|
||||
@@ -49,11 +53,12 @@ ADD_LIBRARY(${LIB_NAME}
|
||||
CullVisitor.cpp
|
||||
DelaunayTriangulator.cpp
|
||||
DisplayRequirementsVisitor.cpp
|
||||
EdgeCollector.cpp
|
||||
GLObjectsVisitor.cpp
|
||||
HalfWayMapGenerator.cpp
|
||||
HighlightMapGenerator.cpp
|
||||
IntersectVisitor.cpp
|
||||
IntersectionVisitor.cpp
|
||||
IntersectVisitor.cpp
|
||||
LineSegmentIntersector.cpp
|
||||
Optimizer.cpp
|
||||
PlaneIntersector.cpp
|
||||
@@ -62,6 +67,7 @@ ADD_LIBRARY(${LIB_NAME}
|
||||
RenderBin.cpp
|
||||
RenderLeaf.cpp
|
||||
RenderStage.cpp
|
||||
ReversePrimitiveFunctor.cpp
|
||||
SceneView.cpp
|
||||
Simplifier.cpp
|
||||
SmoothingVisitor.cpp
|
||||
@@ -71,11 +77,11 @@ ADD_LIBRARY(${LIB_NAME}
|
||||
Tessellator.cpp
|
||||
TransformAttributeFunctor.cpp
|
||||
TransformCallback.cpp
|
||||
TriStripVisitor.cpp
|
||||
TriStrip_graph_array.h
|
||||
TriStrip_heap_array.h
|
||||
TriStrip_tri_stripper.cpp
|
||||
TriStrip_tri_stripper.h
|
||||
TriStripVisitor.cpp
|
||||
UpdateVisitor.cpp
|
||||
Version.cpp
|
||||
)
|
||||
|
||||
457
src/osgUtil/EdgeCollector.cpp
Normal file
457
src/osgUtil/EdgeCollector.cpp
Normal file
@@ -0,0 +1,457 @@
|
||||
/* -*-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.
|
||||
*/
|
||||
|
||||
#include <osgUtil/EdgeCollector>
|
||||
|
||||
#include <osg/TriangleIndexFunctor>
|
||||
|
||||
namespace osgUtil
|
||||
{
|
||||
|
||||
bool EdgeCollector::Point::isBoundaryPoint() const
|
||||
{
|
||||
if (_protected) return true;
|
||||
|
||||
for(TriangleSet::const_iterator itr=_triangles.begin();
|
||||
itr!=_triangles.end();
|
||||
++itr)
|
||||
{
|
||||
const Triangle* triangle = itr->get();
|
||||
if ((triangle->_e1->_p1==this || triangle->_e1->_p2==this) && triangle->_e1->isBoundaryEdge()) return true;
|
||||
if ((triangle->_e2->_p1==this || triangle->_e2->_p2==this) && triangle->_e2->isBoundaryEdge()) return true;
|
||||
if ((triangle->_e3->_p1==this || triangle->_e3->_p2==this) && triangle->_e3->isBoundaryEdge()) return true;
|
||||
|
||||
//if ((*itr)->isBoundaryTriangle()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EdgeCollector::Edge::clear()
|
||||
{
|
||||
_p1 = 0;
|
||||
_p2 = 0;
|
||||
_op1 = 0;
|
||||
_op2 = 0;
|
||||
_triangles.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool EdgeCollector::Edge::operator < ( const Edge& rhs) const
|
||||
{
|
||||
if (dereference_check_less(_p1,rhs._p1)) return true;
|
||||
if (dereference_check_less(rhs._p1,_p1)) return false;
|
||||
|
||||
return dereference_check_less(_p2,rhs._p2);
|
||||
}
|
||||
|
||||
bool EdgeCollector::Edge::operator == ( const Edge& rhs) const
|
||||
{
|
||||
if (&rhs==this) return true;
|
||||
if (*this<rhs) return false;
|
||||
if (rhs<*this) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EdgeCollector::Edge::operator != ( const Edge& rhs) const
|
||||
{
|
||||
if (&rhs==this) return false;
|
||||
if (*this<rhs) return true;
|
||||
if (rhs<*this) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void EdgeCollector::Edge::setOrderedPoints(Point* p1, Point* p2)
|
||||
{
|
||||
if (dereference_check_less(p1, p2))
|
||||
{
|
||||
_p1 = _op1 = p1;
|
||||
_p2 = _op2 = p2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_p1 = _op2 = p2;
|
||||
_p2 = _op1 = p1;
|
||||
}
|
||||
}
|
||||
|
||||
void EdgeCollector::Triangle::clear()
|
||||
{
|
||||
_p1 = 0;
|
||||
_p2 = 0;
|
||||
_p3 = 0;
|
||||
|
||||
_op1 = 0;
|
||||
_op2 = 0;
|
||||
_op3 = 0;
|
||||
|
||||
_e1 = 0;
|
||||
_e2 = 0;
|
||||
_e3 = 0;
|
||||
}
|
||||
|
||||
bool EdgeCollector::Triangle::operator < (const Triangle& rhs) const
|
||||
{
|
||||
if (dereference_check_less(_p1,rhs._p1)) return true;
|
||||
if (dereference_check_less(rhs._p1,_p1)) return false;
|
||||
|
||||
|
||||
const Point* lhs_lower = dereference_check_less(_p2,_p3) ? _p2.get() : _p3.get();
|
||||
const Point* rhs_lower = dereference_check_less(rhs._p2,rhs._p3) ? rhs._p2.get() : rhs._p3.get();
|
||||
|
||||
if (dereference_check_less(lhs_lower,rhs_lower)) return true;
|
||||
if (dereference_check_less(rhs_lower,lhs_lower)) return false;
|
||||
|
||||
const Point* lhs_upper = dereference_check_less(_p2,_p3) ? _p3.get() : _p2.get();
|
||||
const Point* rhs_upper = dereference_check_less(rhs._p2,rhs._p3) ? rhs._p3.get() : rhs._p2.get();
|
||||
|
||||
return dereference_check_less(lhs_upper,rhs_upper);
|
||||
}
|
||||
|
||||
|
||||
void EdgeCollector::Triangle::setOrderedPoints(Point* p1, Point* p2, Point* p3)
|
||||
{
|
||||
Point* points[3];
|
||||
|
||||
_op1 = points[0] = p1;
|
||||
_op2 = points[1] = p2;
|
||||
_op3 = points[2] = p3;
|
||||
|
||||
// find the lowest value point in the list.
|
||||
unsigned int lowest = 0;
|
||||
if (dereference_check_less(points[1],points[lowest])) lowest = 1;
|
||||
if (dereference_check_less(points[2],points[lowest])) lowest = 2;
|
||||
|
||||
_p1 = points[lowest];
|
||||
_p2 = points[(lowest+1)%3];
|
||||
_p3 = points[(lowest+2)%3];
|
||||
|
||||
_plane.set(_op1->_vertex,_op2->_vertex,_op3->_vertex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
osg::UIntArray * EdgeCollector::Edgeloop::toIndexArray() const
|
||||
{
|
||||
osg::UIntArray * indexArray = new osg::UIntArray;
|
||||
|
||||
EdgeList::const_iterator it = _edgeList.begin(), end = _edgeList.end();
|
||||
|
||||
for (;it != end; ++it)
|
||||
indexArray->push_back((*it)->_op1->_index);
|
||||
|
||||
return indexArray;
|
||||
}
|
||||
|
||||
EdgeCollector::Triangle* EdgeCollector::addTriangle(unsigned int p1, unsigned int p2, unsigned int p3)
|
||||
{
|
||||
//osg::notify(osg::NOTICE)<<"addTriangle("<<p1<<","<<p2<<","<<p3<<")"<<std::endl;
|
||||
|
||||
// detect if triangle is degenerate.
|
||||
if (p1==p2 || p2==p3 || p1==p3) return 0;
|
||||
if ((_originalPointList[p1]->_vertex == _originalPointList[p2]->_vertex) ||
|
||||
(_originalPointList[p2]->_vertex == _originalPointList[p3]->_vertex) ||
|
||||
(_originalPointList[p3]->_vertex == _originalPointList[p1]->_vertex)) return 0;
|
||||
|
||||
Triangle* triangle = new Triangle;
|
||||
|
||||
triangle->setOrderedPoints(addPoint(triangle, p1), addPoint(triangle, p2), addPoint(triangle, p3));
|
||||
|
||||
triangle->_e1 = addEdge(triangle, triangle->_op1.get(), triangle->_op2.get());
|
||||
triangle->_e2 = addEdge(triangle, triangle->_op2.get(), triangle->_op3.get());
|
||||
triangle->_e3 = addEdge(triangle, triangle->_op3.get(), triangle->_op1.get());
|
||||
|
||||
_triangleSet.insert(triangle);
|
||||
|
||||
return triangle;
|
||||
}
|
||||
|
||||
EdgeCollector::Triangle* EdgeCollector::addTriangle(Point* p1, Point* p2, Point* p3)
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<" addTriangle("<<p1<<","<<p2<<","<<p3<<")"<<std::endl;
|
||||
|
||||
// detect if triangle is degenerate.
|
||||
if (p1==p2 || p2==p3 || p1==p3) return 0;
|
||||
if ((p1->_vertex == p2->_vertex) ||
|
||||
(p2->_vertex == p3->_vertex) ||
|
||||
(p3->_vertex == p1->_vertex)) return 0;
|
||||
|
||||
Triangle* triangle = new Triangle;
|
||||
|
||||
triangle->setOrderedPoints(addPoint(triangle, p1), addPoint(triangle, p2), addPoint(triangle, p3));
|
||||
|
||||
triangle->_e1 = addEdge(triangle, triangle->_op1.get(), triangle->_op2.get());
|
||||
triangle->_e2 = addEdge(triangle, triangle->_op2.get(), triangle->_op3.get());
|
||||
triangle->_e3 = addEdge(triangle, triangle->_op3.get(), triangle->_op1.get());
|
||||
|
||||
_triangleSet.insert(triangle);
|
||||
|
||||
return triangle;
|
||||
}
|
||||
|
||||
|
||||
EdgeCollector::Edge* EdgeCollector::addEdge(Triangle* triangle, Point* p1, Point* p2)
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<" addEdge("<<p1<<","<<p2<<")"<<std::endl;
|
||||
osg::ref_ptr<Edge> edge = new Edge;
|
||||
edge->setOrderedPoints(p1,p2);
|
||||
|
||||
EdgeSet::iterator itr = _edgeSet.find(edge);
|
||||
if (itr==_edgeSet.end())
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<" addEdge("<<edge.get()<<") edge->_p1="<<edge->_p1.get()<<" _p2="<<edge->_p2.get()<<std::endl;
|
||||
_edgeSet.insert(edge);
|
||||
}
|
||||
else
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<" reuseEdge("<<edge.get()<<") edge->_p1="<<edge->_p1.get()<<" _p2="<<edge->_p2.get()<<std::endl;
|
||||
edge = *itr;
|
||||
}
|
||||
|
||||
edge->addTriangle(triangle);
|
||||
|
||||
return edge.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EdgeCollector::Point* EdgeCollector::addPoint(Triangle* triangle, Point* point)
|
||||
{
|
||||
|
||||
PointSet::iterator itr = _pointSet.find(point);
|
||||
if (itr==_pointSet.end())
|
||||
{
|
||||
//osg::notify(osg::NOTICE)<<" addPoint("<<point.get()<<")"<<std::endl;
|
||||
_pointSet.insert(point);
|
||||
}
|
||||
else
|
||||
{
|
||||
point = const_cast<Point*>(itr->get());
|
||||
//osg::notify(osg::NOTICE)<<" reusePoint("<<point.get()<<")"<<std::endl;
|
||||
}
|
||||
|
||||
point->_triangles.insert(triangle);
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
void EdgeCollector::getBoundaryEdgeList(EdgeList & el)
|
||||
{
|
||||
for (EdgeSet::iterator it = _edgeSet.begin(), end = _edgeSet.end(); it != end; ++it)
|
||||
{
|
||||
if ((*it)->isBoundaryEdge()) el.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
bool EdgeCollector::extractBoundaryEdgeloop(EdgeList & el, Edgeloop & edgeloop)
|
||||
{
|
||||
if (el.empty()) return false;
|
||||
|
||||
|
||||
osg::ref_ptr<Edge> current = el.back();
|
||||
el.pop_back();
|
||||
|
||||
// ** init the Edgeloop
|
||||
edgeloop._edgeList.push_back(current.get());
|
||||
|
||||
|
||||
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
bool found = false;
|
||||
EdgeList::iterator it = el.begin(), end = el.end();
|
||||
while (it != end && !found)
|
||||
{
|
||||
if (current->endConnected(*(it->get())))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
osg::notify(osg::WARN) << "extractBoundaryEdgeloop : unable to close edge loop" << std::endl;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
edgeloop._edgeList.push_back(it->get());
|
||||
current = it->get();
|
||||
el.erase(it);
|
||||
|
||||
if (edgeloop.isClosed()) done = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EdgeCollector::extractBoundaryEdgeloopList(EdgeList & el, EdgeloopList & edgeloopList)
|
||||
{
|
||||
while (!el.empty())
|
||||
{
|
||||
osg::ref_ptr<Edgeloop> edgeloop(new Edgeloop);
|
||||
|
||||
if (extractBoundaryEdgeloop(el, *edgeloop))
|
||||
edgeloopList.push_back(edgeloop);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct CollectTriangleOperator
|
||||
{
|
||||
|
||||
CollectTriangleOperator():_ec(0) {}
|
||||
|
||||
void setEdgeCollector(EdgeCollector* ec) { _ec = ec; }
|
||||
|
||||
EdgeCollector* _ec;
|
||||
|
||||
// for use in the triangle functor.
|
||||
inline void operator()(unsigned int p1, unsigned int p2, unsigned int p3)
|
||||
{
|
||||
_ec->addTriangle(p1,p2,p3);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef osg::TriangleIndexFunctor<CollectTriangleOperator> CollectTriangleIndexFunctor;
|
||||
|
||||
class CopyVertexArrayToPointsVisitor : public osg::ArrayVisitor
|
||||
{
|
||||
public:
|
||||
CopyVertexArrayToPointsVisitor(EdgeCollector::PointList& pointList):
|
||||
_pointList(pointList) {}
|
||||
|
||||
virtual void apply(osg::Vec2Array& 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;
|
||||
|
||||
osg::Vec2& value = array[i];
|
||||
osg::Vec3& vertex = _pointList[i]->_vertex;
|
||||
vertex.set(value.x(),value.y(),0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void apply(osg::Vec3Array& 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::Vec4Array& 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;
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
EdgeCollector::PointList& _pointList;
|
||||
};
|
||||
|
||||
EdgeCollector::~EdgeCollector()
|
||||
{
|
||||
std::for_each(_edgeSet.begin(),_edgeSet.end(),dereference_clear());
|
||||
|
||||
std::for_each(_triangleSet.begin(),_triangleSet.end(),dereference_clear());
|
||||
std::for_each(_pointSet.begin(),_pointSet.end(),dereference_clear());
|
||||
std::for_each(_originalPointList.begin(),_originalPointList.end(),dereference_clear());
|
||||
}
|
||||
|
||||
|
||||
void EdgeCollector::setGeometry(osg::Geometry* geometry)
|
||||
{
|
||||
_geometry = geometry;
|
||||
|
||||
// check to see if vertex attributes indices exists, if so expand them to remove them
|
||||
if (_geometry->suitableForOptimization())
|
||||
{
|
||||
// removing coord indices
|
||||
osg::notify(osg::INFO)<<"EdgeCollector::setGeometry(..): Removing attribute indices"<<std::endl;
|
||||
_geometry->copyToAndOptimize(*_geometry);
|
||||
}
|
||||
|
||||
unsigned int numVertices = geometry->getVertexArray()->getNumElements();
|
||||
|
||||
_originalPointList.resize(numVertices);
|
||||
|
||||
// copy vertices across to local point list
|
||||
CopyVertexArrayToPointsVisitor copyVertexArrayToPoints(_originalPointList);
|
||||
_geometry->getVertexArray()->accept(copyVertexArrayToPoints);
|
||||
|
||||
CollectTriangleIndexFunctor collectTriangles;
|
||||
collectTriangles.setEdgeCollector(this);
|
||||
|
||||
_geometry->accept(collectTriangles);
|
||||
}
|
||||
|
||||
// ** search BoundaryEdgeloop in the geometry, extrude this loop
|
||||
// ** and create primitiveSet to link original loop and extruded loop
|
||||
void EdgeCollector::getEdgeloopIndexList(IndexArrayList & ial)
|
||||
{
|
||||
// ** collect Boundary Edge
|
||||
EdgeList edgeList;
|
||||
getBoundaryEdgeList(edgeList);
|
||||
|
||||
// ** collect Edgeloop
|
||||
EdgeloopList edgeloopList;
|
||||
if (extractBoundaryEdgeloopList(edgeList, edgeloopList) == false)
|
||||
{
|
||||
osg::notify(osg::WARN) << "EdgeCollector: fail to collect Edgeloop.\n\n\n" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// ** get IndexArray of each Edgeloop
|
||||
EdgeloopList::iterator elIt, elEnd = edgeloopList.end();
|
||||
for (elIt = edgeloopList.begin(); elIt != elEnd; ++elIt)
|
||||
{
|
||||
ial.push_back((*elIt)->toIndexArray());
|
||||
}
|
||||
}
|
||||
|
||||
} // end of osgUtil namespace
|
||||
112
src/osgUtil/ReversePrimitiveFunctor.cpp
Normal file
112
src/osgUtil/ReversePrimitiveFunctor.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
/* -*-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.
|
||||
*/
|
||||
|
||||
#include <osgUtil/ReversePrimitiveFunctor>
|
||||
|
||||
|
||||
template <typename Type>
|
||||
osg::PrimitiveSet * drawElementsTemplate(GLenum mode,GLsizei count, const typename Type::value_type* indices)
|
||||
{
|
||||
if (indices==0 || count==0) return NULL;
|
||||
|
||||
Type * dePtr = new Type(mode);
|
||||
Type & de = *dePtr;
|
||||
de.reserve(count);
|
||||
|
||||
typedef const typename Type::value_type* IndexPointer;
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case(GL_TRIANGLES):
|
||||
{
|
||||
IndexPointer ilast = &indices[count];
|
||||
|
||||
for (IndexPointer iptr=indices; iptr<ilast; iptr+=3)
|
||||
{
|
||||
de.push_back(*(iptr));
|
||||
de.push_back(*(iptr+2));
|
||||
de.push_back(*(iptr+1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (GL_QUADS):
|
||||
{
|
||||
|
||||
IndexPointer ilast = &indices[count - 3];
|
||||
for (IndexPointer iptr = indices; iptr<ilast; iptr+=4)
|
||||
{
|
||||
de.push_back(*(iptr));
|
||||
de.push_back(*(iptr+3));
|
||||
de.push_back(*(iptr+2));
|
||||
de.push_back(*(iptr+1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (GL_TRIANGLE_STRIP):
|
||||
case (GL_QUAD_STRIP):
|
||||
{
|
||||
IndexPointer ilast = &indices[count];
|
||||
for (IndexPointer iptr = indices; iptr<ilast; iptr+=2)
|
||||
{
|
||||
de.push_back(*(iptr+1));
|
||||
de.push_back(*(iptr));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (GL_TRIANGLE_FAN):
|
||||
{
|
||||
de.push_back(*indices);
|
||||
|
||||
IndexPointer iptr = indices + 1;
|
||||
IndexPointer ilast = &indices[count];
|
||||
de.resize(count);
|
||||
std::reverse_copy(iptr, ilast, de.begin() + 1);
|
||||
|
||||
break;
|
||||
}
|
||||
case (GL_POLYGON):
|
||||
case (GL_POINTS):
|
||||
case (GL_LINES):
|
||||
case (GL_LINE_STRIP):
|
||||
case (GL_LINE_LOOP):
|
||||
{
|
||||
IndexPointer iptr = indices;
|
||||
IndexPointer ilast = &indices[count];
|
||||
de.resize(count);
|
||||
std::reverse_copy(iptr, ilast, de.begin());
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return &de;
|
||||
}
|
||||
|
||||
namespace osgUtil {
|
||||
|
||||
void ReversePrimitiveFunctor::drawElements(GLenum mode,GLsizei count,const GLubyte* indices)
|
||||
{
|
||||
_reversedPrimitiveSet = drawElementsTemplate<osg::DrawElementsUByte>(mode, count, indices);
|
||||
}
|
||||
void ReversePrimitiveFunctor::drawElements(GLenum mode,GLsizei count,const GLushort* indices)
|
||||
{
|
||||
_reversedPrimitiveSet = drawElementsTemplate<osg::DrawElementsUShort>(mode, count, indices);
|
||||
}
|
||||
void ReversePrimitiveFunctor::drawElements(GLenum mode,GLsizei count,const GLuint* indices)
|
||||
{
|
||||
_reversedPrimitiveSet = drawElementsTemplate<osg::DrawElementsUInt>(mode, count, indices);
|
||||
}
|
||||
|
||||
} // end osgUtil namespace
|
||||
Reference in New Issue
Block a user