Added support to osgUtil::Tesselator to insert extra vertices and other
attributes into an osg::Geometry node. Uses the new osg::ArrayVisitor. Converted the osg plugin Geometry support to use the new UByte4 class.
This commit is contained in:
@@ -70,7 +70,7 @@ class OSGUTIL_EXPORT Tesselator
|
|||||||
|
|
||||||
void begin(GLenum mode);
|
void begin(GLenum mode);
|
||||||
void vertex(osg::Vec3* vertex);
|
void vertex(osg::Vec3* vertex);
|
||||||
void combine(osg::Vec3* vertex);
|
void combine(osg::Vec3* vertex,void* vertex_data[4],GLfloat weight[4]);
|
||||||
void end();
|
void end();
|
||||||
void error(GLenum errorCode);
|
void error(GLenum errorCode);
|
||||||
|
|
||||||
@@ -90,11 +90,63 @@ class OSGUTIL_EXPORT Tesselator
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct NewVertex
|
||||||
|
{
|
||||||
|
|
||||||
|
NewVertex():
|
||||||
|
_f1(0),
|
||||||
|
_v1(0),
|
||||||
|
_f2(0),
|
||||||
|
_v2(0),
|
||||||
|
_f3(0),
|
||||||
|
_v3(0),
|
||||||
|
_f4(0),
|
||||||
|
_v4(0) {}
|
||||||
|
|
||||||
|
NewVertex(const NewVertex& nv):
|
||||||
|
_f1(nv._f1),
|
||||||
|
_v1(nv._v1),
|
||||||
|
_f2(nv._f2),
|
||||||
|
_v2(nv._v2),
|
||||||
|
_f3(nv._f3),
|
||||||
|
_v3(nv._v3),
|
||||||
|
_f4(nv._f4),
|
||||||
|
_v4(nv._v4) {}
|
||||||
|
|
||||||
|
NewVertex(float f1,osg::Vec3* v1,
|
||||||
|
float f2,osg::Vec3* v2,
|
||||||
|
float f3,osg::Vec3* v3,
|
||||||
|
float f4,osg::Vec3* v4):
|
||||||
|
_f1(f1),
|
||||||
|
_v1(v1),
|
||||||
|
_f2(f2),
|
||||||
|
_v2(v2),
|
||||||
|
_f3(f3),
|
||||||
|
_v3(v3),
|
||||||
|
_f4(f4),
|
||||||
|
_v4(v4) {}
|
||||||
|
|
||||||
|
float _f1;
|
||||||
|
osg::Vec3* _v1;
|
||||||
|
|
||||||
|
float _f2;
|
||||||
|
osg::Vec3* _v2;
|
||||||
|
|
||||||
|
float _f3;
|
||||||
|
osg::Vec3* _v3;
|
||||||
|
|
||||||
|
float _f4;
|
||||||
|
osg::Vec3* _v4;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<osg::Vec3*,NewVertex> NewVertexList;
|
||||||
typedef std::vector<Vec3d*> Vec3dList;
|
typedef std::vector<Vec3d*> Vec3dList;
|
||||||
|
|
||||||
GLUtesselator* _tobj;
|
GLUtesselator* _tobj;
|
||||||
PrimList _primList;
|
PrimList _primList;
|
||||||
Vec3dList _coordData;
|
Vec3dList _coordData;
|
||||||
|
NewVertexList _newVertexList;
|
||||||
GLenum _errorCode;
|
GLenum _errorCode;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -296,11 +296,14 @@ Array* Array_readLocalData(Input& fr)
|
|||||||
array->reserve(capacity);
|
array->reserve(capacity);
|
||||||
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||||
{
|
{
|
||||||
unsigned int uint_value;
|
unsigned int r,g,b,a;
|
||||||
if (fr[0].getUInt(uint_value))
|
if (fr[0].getUInt(r) &&
|
||||||
|
fr[1].getUInt(g) &&
|
||||||
|
fr[2].getUInt(b) &&
|
||||||
|
fr[3].getUInt(a))
|
||||||
{
|
{
|
||||||
++fr;
|
++fr;
|
||||||
array->push_back(uint_value);
|
array->push_back(osg::UByte4(r,g,b,a));
|
||||||
}
|
}
|
||||||
else ++fr;
|
else ++fr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,9 +93,51 @@ void Tesselator::reset()
|
|||||||
}
|
}
|
||||||
_primList.clear();
|
_primList.clear();
|
||||||
_coordData.clear();
|
_coordData.clear();
|
||||||
|
_newVertexList.clear();
|
||||||
_errorCode = 0;
|
_errorCode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InsertNewVertices : public osg::ArrayVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
float _f1,_f2,_f3,_f4;
|
||||||
|
unsigned int _i1,_i2,_i3,_i4;
|
||||||
|
|
||||||
|
InsertNewVertices(float f1,unsigned int i1,
|
||||||
|
float f2,unsigned int i2,
|
||||||
|
float f3,unsigned int i3,
|
||||||
|
float f4,unsigned int i4):
|
||||||
|
_f1(f1),_f2(f2),_f3(f3),_f4(f4),
|
||||||
|
_i1(i1),_i2(i2),_i3(i3),_i4(i4){}
|
||||||
|
|
||||||
|
template <class A,class Type>
|
||||||
|
void apply_imp(A& array)
|
||||||
|
{
|
||||||
|
Type val;
|
||||||
|
if (_f1) val += static_cast<Type>(array[_i1] * _f1);
|
||||||
|
if (_f2) val += static_cast<Type>(array[_i2] * _f2);
|
||||||
|
if (_f3) val += static_cast<Type>(array[_i3] * _f3);
|
||||||
|
if (_f4) val += static_cast<Type>(array[_i4] * _f4);
|
||||||
|
|
||||||
|
array.push_back(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void apply(osg::ByteArray& ba) { apply_imp<ByteArray,ByteArray::value_type>(ba); }
|
||||||
|
virtual void apply(osg::ShortArray& ba) { apply_imp<ShortArray,ShortArray::value_type>(ba); }
|
||||||
|
virtual void apply(osg::IntArray& ba) { apply_imp<IntArray,IntArray::value_type>(ba); }
|
||||||
|
virtual void apply(osg::UByteArray& ba) { apply_imp<UByteArray,UByteArray::value_type>(ba); }
|
||||||
|
virtual void apply(osg::UShortArray& ba) { apply_imp<UShortArray,UShortArray::value_type>(ba); }
|
||||||
|
virtual void apply(osg::UIntArray& ba) { apply_imp<UIntArray,UIntArray::value_type>(ba); }
|
||||||
|
virtual void apply(osg::UByte4Array& ba) { apply_imp<UByte4Array,UByte4Array::value_type>(ba); }
|
||||||
|
virtual void apply(osg::FloatArray& ba) { apply_imp<FloatArray,FloatArray::value_type>(ba); }
|
||||||
|
virtual void apply(osg::Vec2Array& ba) { apply_imp<Vec2Array,Vec2Array::value_type>(ba); }
|
||||||
|
virtual void apply(osg::Vec3Array& ba) { apply_imp<Vec3Array,Vec3Array::value_type>(ba); }
|
||||||
|
virtual void apply(osg::Vec4Array& ba) { apply_imp<Vec4Array,Vec4Array::value_type>(ba); }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void Tesselator::retesselatePolygons(osg::Geometry& geom)
|
void Tesselator::retesselatePolygons(osg::Geometry& geom)
|
||||||
{
|
{
|
||||||
Vec3Array* vertices = geom.getVertexArray();
|
Vec3Array* vertices = geom.getVertexArray();
|
||||||
@@ -163,8 +205,86 @@ void Tesselator::retesselatePolygons(osg::Geometry& geom)
|
|||||||
endContour();
|
endContour();
|
||||||
endTesselation();
|
endTesselation();
|
||||||
|
|
||||||
Vec3* vbase = &(vertices->front());
|
typedef std::map<osg::Vec3*,unsigned int> VertexPtrToIndexMap;
|
||||||
Vec3* vtop = &(vertices->back());
|
VertexPtrToIndexMap vertexPtrToIndexMap;
|
||||||
|
|
||||||
|
// populate the VertexPtrToIndexMap.
|
||||||
|
for(unsigned int vi=0;vi<vertices->size();++vi)
|
||||||
|
{
|
||||||
|
vertexPtrToIndexMap[&((*vertices)[vi])] = vi;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_newVertexList.empty())
|
||||||
|
{
|
||||||
|
|
||||||
|
osg::Vec3Array* normals = NULL;
|
||||||
|
if (geom.getNormalBinding()==osg::Geometry::BIND_PER_VERTEX)
|
||||||
|
{
|
||||||
|
normals = geom.getNormalArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef std::vector<osg::Array*> ArrayList;
|
||||||
|
ArrayList arrays;
|
||||||
|
|
||||||
|
if (geom.getColorBinding()==osg::Geometry::BIND_PER_VERTEX)
|
||||||
|
{
|
||||||
|
arrays.push_back(geom.getColorArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Geometry::TexCoordArrayList& tcal = geom.getTexCoordArrayList();
|
||||||
|
for(osg::Geometry::TexCoordArrayList::iterator tcalItr=tcal.begin();
|
||||||
|
tcalItr!=tcal.end();
|
||||||
|
++tcalItr)
|
||||||
|
{
|
||||||
|
if (tcalItr->valid())
|
||||||
|
{
|
||||||
|
arrays.push_back(tcalItr->get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now add any new vertices that are required.
|
||||||
|
for(NewVertexList::iterator itr=_newVertexList.begin();
|
||||||
|
itr!=_newVertexList.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
osg::Vec3* vertex = itr->first;
|
||||||
|
NewVertex& newVertex = itr->second;
|
||||||
|
|
||||||
|
// assign vertex.
|
||||||
|
vertexPtrToIndexMap[vertex]=vertices->size();
|
||||||
|
vertices->push_back(*vertex);
|
||||||
|
|
||||||
|
// assign normals
|
||||||
|
if (normals)
|
||||||
|
{
|
||||||
|
osg::Vec3 norm(0.0f,0.0f,0.0f);
|
||||||
|
if (newVertex._v1) norm += (*normals)[vertexPtrToIndexMap[newVertex._v1]] * newVertex._f1;
|
||||||
|
if (newVertex._v2) norm += (*normals)[vertexPtrToIndexMap[newVertex._v2]] * newVertex._f2;
|
||||||
|
if (newVertex._v3) norm += (*normals)[vertexPtrToIndexMap[newVertex._v3]] * newVertex._f3;
|
||||||
|
if (newVertex._v4) norm += (*normals)[vertexPtrToIndexMap[newVertex._v4]] * newVertex._f4;
|
||||||
|
norm.normalize();
|
||||||
|
normals->push_back(norm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arrays.empty())
|
||||||
|
{
|
||||||
|
InsertNewVertices inv(newVertex._f1,vertexPtrToIndexMap[newVertex._v1],
|
||||||
|
newVertex._f2,vertexPtrToIndexMap[newVertex._v2],
|
||||||
|
newVertex._f3,vertexPtrToIndexMap[newVertex._v3],
|
||||||
|
newVertex._f4,vertexPtrToIndexMap[newVertex._v4]);
|
||||||
|
|
||||||
|
// assign the rest of the attributes.
|
||||||
|
for(ArrayList::iterator aItr=arrays.begin();
|
||||||
|
aItr!=arrays.end();
|
||||||
|
++aItr)
|
||||||
|
{
|
||||||
|
(*aItr)->accept(inv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for(PrimList::iterator primItr=_primList.begin();
|
for(PrimList::iterator primItr=_primList.begin();
|
||||||
primItr!=_primList.end();
|
primItr!=_primList.end();
|
||||||
@@ -177,17 +297,7 @@ void Tesselator::retesselatePolygons(osg::Geometry& geom)
|
|||||||
vitr!=prim->_vertices.end();
|
vitr!=prim->_vertices.end();
|
||||||
++vitr)
|
++vitr)
|
||||||
{
|
{
|
||||||
if (*vitr<vbase || *vitr>vtop)
|
elements->push_back(vertexPtrToIndexMap[*vitr]);
|
||||||
{
|
|
||||||
// new vertex.
|
|
||||||
std::cout<<"Ooohhh we're getting funky, extra vertices need to be inserted"<<std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// old vertex.
|
|
||||||
unsigned int i=*vitr-vbase;
|
|
||||||
elements->push_back(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primItr==_primList.begin())
|
if (primItr==_primList.begin())
|
||||||
@@ -218,16 +328,16 @@ void Tesselator::vertex(osg::Vec3* vertex)
|
|||||||
{
|
{
|
||||||
Prim* prim = _primList.back().get();
|
Prim* prim = _primList.back().get();
|
||||||
prim->_vertices.push_back(vertex);
|
prim->_vertices.push_back(vertex);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tesselator::combine(osg::Vec3* vertex)
|
void Tesselator::combine(osg::Vec3* vertex,void* vertex_data[4],GLfloat weight[4])
|
||||||
{
|
{
|
||||||
if (!_primList.empty())
|
_newVertexList[vertex]=NewVertex(weight[0],(Vec3*)vertex_data[0],
|
||||||
{
|
weight[1],(Vec3*)vertex_data[1],
|
||||||
Prim* prim = _primList.back().get();
|
weight[2],(Vec3*)vertex_data[2],
|
||||||
prim->_vertices.push_back(vertex);
|
weight[3],(Vec3*)vertex_data[3]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tesselator::end()
|
void Tesselator::end()
|
||||||
@@ -255,14 +365,14 @@ void CALLBACK Tesselator::vertexCallback(GLvoid *data, void* userData)
|
|||||||
((Tesselator*)userData)->vertex((Vec3*)data);
|
((Tesselator*)userData)->vertex((Vec3*)data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CALLBACK Tesselator::combineCallback(GLdouble coords[3], void* /*vertex_data*/[4],
|
void CALLBACK Tesselator::combineCallback(GLdouble coords[3], void* vertex_data[4],
|
||||||
GLfloat /*weight*/[4], void** outData,
|
GLfloat weight[4], void** outData,
|
||||||
void* userData)
|
void* /*userData*/)
|
||||||
{
|
{
|
||||||
Vec3* newData = new osg::Vec3(coords[0],coords[2],coords[3]);
|
Vec3* newData = new osg::Vec3(coords[0],coords[1],coords[2]);
|
||||||
*outData = newData;
|
*outData = newData;
|
||||||
//((Tesselator*)userData)->combine(newData);
|
//((Tesselator*)userData)->combine(newData);
|
||||||
s_currentTesselator->combine(newData);
|
s_currentTesselator->combine(newData,vertex_data,weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CALLBACK Tesselator::errorCallback(GLenum errorCode, void* userData)
|
void CALLBACK Tesselator::errorCallback(GLenum errorCode, void* userData)
|
||||||
|
|||||||
Reference in New Issue
Block a user