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:
Robert Osfield
2002-07-15 22:23:57 +00:00
parent e280b50d31
commit 8a14aa29cd
3 changed files with 193 additions and 28 deletions

View File

@@ -70,7 +70,7 @@ class OSGUTIL_EXPORT Tesselator
void begin(GLenum mode);
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 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;
GLUtesselator* _tobj;
PrimList _primList;
Vec3dList _coordData;
NewVertexList _newVertexList;
GLenum _errorCode;
};

View File

@@ -296,11 +296,14 @@ Array* Array_readLocalData(Input& fr)
array->reserve(capacity);
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
{
unsigned int uint_value;
if (fr[0].getUInt(uint_value))
unsigned int r,g,b,a;
if (fr[0].getUInt(r) &&
fr[1].getUInt(g) &&
fr[2].getUInt(b) &&
fr[3].getUInt(a))
{
++fr;
array->push_back(uint_value);
array->push_back(osg::UByte4(r,g,b,a));
}
else ++fr;
}

View File

@@ -93,9 +93,51 @@ void Tesselator::reset()
}
_primList.clear();
_coordData.clear();
_newVertexList.clear();
_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)
{
Vec3Array* vertices = geom.getVertexArray();
@@ -163,8 +205,86 @@ void Tesselator::retesselatePolygons(osg::Geometry& geom)
endContour();
endTesselation();
Vec3* vbase = &(vertices->front());
Vec3* vtop = &(vertices->back());
typedef std::map<osg::Vec3*,unsigned int> VertexPtrToIndexMap;
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();
primItr!=_primList.end();
@@ -177,17 +297,7 @@ void Tesselator::retesselatePolygons(osg::Geometry& geom)
vitr!=prim->_vertices.end();
++vitr)
{
if (*vitr<vbase || *vitr>vtop)
{
// 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);
}
elements->push_back(vertexPtrToIndexMap[*vitr]);
}
if (primItr==_primList.begin())
@@ -218,16 +328,16 @@ void Tesselator::vertex(osg::Vec3* vertex)
{
Prim* prim = _primList.back().get();
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())
{
Prim* prim = _primList.back().get();
prim->_vertices.push_back(vertex);
}
_newVertexList[vertex]=NewVertex(weight[0],(Vec3*)vertex_data[0],
weight[1],(Vec3*)vertex_data[1],
weight[2],(Vec3*)vertex_data[2],
weight[3],(Vec3*)vertex_data[3]);
}
void Tesselator::end()
@@ -255,14 +365,14 @@ void CALLBACK Tesselator::vertexCallback(GLvoid *data, void* userData)
((Tesselator*)userData)->vertex((Vec3*)data);
}
void CALLBACK Tesselator::combineCallback(GLdouble coords[3], void* /*vertex_data*/[4],
GLfloat /*weight*/[4], void** outData,
void* userData)
void CALLBACK Tesselator::combineCallback(GLdouble coords[3], void* vertex_data[4],
GLfloat weight[4], void** outData,
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;
//((Tesselator*)userData)->combine(newData);
s_currentTesselator->combine(newData);
s_currentTesselator->combine(newData,vertex_data,weight);
}
void CALLBACK Tesselator::errorCallback(GLenum errorCode, void* userData)