Ported pfb, txp and obj loaders across to use osg::Geometry.
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
#include <osg/Transform>
|
||||
#include <osg/Geode>
|
||||
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/StateSet>
|
||||
#include <osg/Material>
|
||||
#include <osg/Texture>
|
||||
@@ -203,205 +203,87 @@ osg::Drawable* ReaderWriterOBJ::makeDrawable(GLMmodel* obj,
|
||||
unsigned int ntris = grp->numtriangles;
|
||||
unsigned int i = 0;
|
||||
|
||||
// geoset
|
||||
osg::GeoSet* gset = new osg::GeoSet;
|
||||
// geometry
|
||||
osg::Geometry* geom = new osg::Geometry;
|
||||
|
||||
// primitives are only triangles
|
||||
gset->setPrimType(osg::GeoSet::TRIANGLES);
|
||||
gset->setNumPrims(ntris);
|
||||
int* primLen = new int[ntris];
|
||||
gset->setPrimLengths(primLen);
|
||||
|
||||
geom->addPrimitive(new osg::DrawArrays(osg::Primitive::TRIANGLES,0,ntris*3));
|
||||
|
||||
// the following code for mapping the coords, normals and texcoords
|
||||
// is complicated greatly by the need to create seperate out the
|
||||
// sets of coords etc for each drawable.
|
||||
|
||||
typedef std::vector<int> IndexVec;
|
||||
|
||||
// fill an vector full of 0's, one for each vertex.
|
||||
IndexVec vcount(obj->numvertices+1,0);
|
||||
IndexVec ncount(obj->numnormals+1,0);
|
||||
IndexVec tcount(obj->numtexcoords+1,0);
|
||||
|
||||
bool needNormals = obj->normals && obj->normals>0;
|
||||
bool needTexcoords = obj->texcoords && obj->numtexcoords>0 && grp->hastexcoords;
|
||||
|
||||
|
||||
osg::Vec3Array* coordArray = new osg::Vec3Array(3*ntris);
|
||||
|
||||
osg::Vec3Array::iterator coords = coordArray->begin();
|
||||
geom->setVertexArray(coordArray);
|
||||
|
||||
osg::Vec3Array::iterator normals = 0;
|
||||
if (needNormals)
|
||||
{
|
||||
osg::Vec3Array* normalArray = new osg::Vec3Array(3*ntris);
|
||||
geom->setNormalArray(normalArray);
|
||||
geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||
normals = normalArray->begin();
|
||||
}
|
||||
|
||||
osg::Vec2Array::iterator texcoords = 0;
|
||||
if (needTexcoords)
|
||||
{
|
||||
osg::Vec2Array* texCoordArray = new osg::Vec2Array(3*ntris);
|
||||
geom->setTexCoordArray(0,texCoordArray);
|
||||
|
||||
texcoords = texCoordArray->begin();
|
||||
}
|
||||
|
||||
// first count the number of vertices used in this group.
|
||||
for (i = 0; i < ntris; i++)
|
||||
{
|
||||
GLMtriangle* tri = &(tris[grp->triangles[i]]);
|
||||
|
||||
// increment the count once for each traingle corner.
|
||||
++vcount[tri->vindices[0]];
|
||||
++vcount[tri->vindices[1]];
|
||||
++vcount[tri->vindices[2]];
|
||||
|
||||
if (needNormals)
|
||||
for(int corner=0;corner<3;++corner)
|
||||
{
|
||||
++ncount[tri->nindices[0]];
|
||||
++ncount[tri->nindices[1]];
|
||||
++ncount[tri->nindices[2]];
|
||||
}
|
||||
|
||||
if (needTexcoords)
|
||||
{
|
||||
++tcount[tri->tindices[0]];
|
||||
++tcount[tri->tindices[1]];
|
||||
++tcount[tri->tindices[2]];
|
||||
}
|
||||
}
|
||||
int ci = tri->vindices[corner]*3;
|
||||
|
||||
|
||||
IndexVec::iterator itr;
|
||||
int numCoords = 0;
|
||||
for(itr=vcount.begin();
|
||||
itr!=vcount.end();
|
||||
++itr)
|
||||
{
|
||||
if ((*itr)>0) ++numCoords;
|
||||
}
|
||||
|
||||
if (numCoords==0) return NULL;
|
||||
|
||||
int numNormals = 0;
|
||||
for(itr=ncount.begin();
|
||||
itr!=ncount.end();
|
||||
++itr)
|
||||
{
|
||||
if ((*itr)>0) ++numNormals;
|
||||
}
|
||||
|
||||
int numTexcoords = 0;
|
||||
for(itr=tcount.begin();
|
||||
itr!=tcount.end();
|
||||
++itr)
|
||||
{
|
||||
if ((*itr)>0) ++numTexcoords;
|
||||
}
|
||||
|
||||
|
||||
// allocate drawables vertices.
|
||||
osg::Vec3* coords = new osg::Vec3[numCoords];
|
||||
|
||||
// allocate drawables normals.
|
||||
osg::Vec3* normals = NULL;
|
||||
if (numNormals>0) normals = new osg::Vec3[numNormals];
|
||||
|
||||
// allocate drawables textcoords.
|
||||
osg::Vec2* texcoords = NULL;
|
||||
if (numTexcoords>0) texcoords = new osg::Vec2[numTexcoords];
|
||||
|
||||
|
||||
// fill an vector full of 0's, one for each vertex.
|
||||
IndexVec vmapping(obj->numvertices+1,-1);
|
||||
IndexVec nmapping(obj->numnormals+1,-1);
|
||||
IndexVec tmapping(obj->numtexcoords+1,-1);
|
||||
|
||||
int coordCount = 0;
|
||||
for (i = 0; i < vcount.size(); i++)
|
||||
{
|
||||
|
||||
if (vcount[i]>0)
|
||||
{
|
||||
|
||||
// note obj_x -> osg_x,
|
||||
// obj_y -> -osg_z,
|
||||
// obj_z -> osg_y,
|
||||
coords[coordCount].set(obj->vertices[i*3+0],
|
||||
-obj->vertices[i*3+2],
|
||||
obj->vertices[i*3+1]);
|
||||
coords->set(obj->vertices[ci],-obj->vertices[ci+2],obj->vertices[ci+1]);
|
||||
++coords;
|
||||
|
||||
vmapping[i]=coordCount;
|
||||
++coordCount;
|
||||
if (needNormals)
|
||||
{
|
||||
int ni = tri->nindices[corner]*3;
|
||||
|
||||
// note obj_x -> osg_x,
|
||||
// obj_y -> osg_z,
|
||||
// obj_z -> osg_y,
|
||||
// to rotate the about x axis to have model z upwards.
|
||||
normals->set(obj->normals[ni],-obj->normals[ni+2],obj->normals[ni+1]);
|
||||
++normals;
|
||||
}
|
||||
|
||||
if (needTexcoords)
|
||||
{
|
||||
int ti = tri->tindices[corner]*2;
|
||||
texcoords->set(obj->texcoords[ti+0], obj->texcoords[ti+1]);
|
||||
++texcoords;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int normCount = 0;
|
||||
for (i = 0; i < ncount.size(); i++)
|
||||
{
|
||||
|
||||
if (ncount[i]>0)
|
||||
{
|
||||
// note obj_x -> osg_x,
|
||||
// obj_y -> osg_z,
|
||||
// obj_z -> osg_y,
|
||||
// to rotate the about x axis to have model z upwards.
|
||||
normals[normCount].set(obj->normals[i*3+0],
|
||||
-obj->normals[i*3+2],
|
||||
obj->normals[i*3+1]);
|
||||
nmapping[i]=normCount;
|
||||
++normCount;
|
||||
}
|
||||
}
|
||||
|
||||
int texCount = 0;
|
||||
for (i = 0; i < tcount.size(); i++)
|
||||
{
|
||||
if (tcount[i]>0)
|
||||
{
|
||||
texcoords[texCount].set(obj->texcoords[i*2+0], obj->texcoords[i*2+1]);
|
||||
tmapping[i]=texCount;
|
||||
++texCount;
|
||||
}
|
||||
}
|
||||
|
||||
// index arrays
|
||||
unsigned int* cindex = NULL;
|
||||
cindex = new unsigned int[ntris * 3];
|
||||
|
||||
unsigned int* nindex = NULL;
|
||||
if (normals)
|
||||
nindex = new unsigned int[ntris * 3];
|
||||
|
||||
unsigned int* tindex = NULL;
|
||||
if (texcoords)
|
||||
tindex = new unsigned int[ntris * 3];
|
||||
|
||||
// setup arrays
|
||||
for (i = 0; i < ntris; i++) {
|
||||
primLen[i] = 3;
|
||||
GLMtriangle* tri = &(tris[grp->triangles[i]]);
|
||||
|
||||
cindex[i*3+0] = vmapping[tri->vindices[0]];
|
||||
cindex[i*3+1] = vmapping[tri->vindices[1]];
|
||||
cindex[i*3+2] = vmapping[tri->vindices[2]];
|
||||
|
||||
if (nindex) {
|
||||
nindex[i*3+0] = nmapping[tri->nindices[0]];
|
||||
nindex[i*3+1] = nmapping[tri->nindices[1]];
|
||||
nindex[i*3+2] = nmapping[tri->nindices[2]];
|
||||
}
|
||||
|
||||
if (tindex) {
|
||||
tindex[i*3+0] = tmapping[tri->tindices[0]];
|
||||
tindex[i*3+1] = tmapping[tri->tindices[1]];
|
||||
tindex[i*3+2] = tmapping[tri->tindices[2]];
|
||||
}
|
||||
}
|
||||
|
||||
if (coords && cindex)
|
||||
gset->setCoords(coords, cindex);
|
||||
|
||||
if (normals && nindex) {
|
||||
gset->setNormals(normals, nindex);
|
||||
gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
|
||||
}
|
||||
|
||||
if (texcoords && tindex) {
|
||||
gset->setTextureCoords(texcoords, tindex);
|
||||
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
|
||||
}
|
||||
|
||||
// state and material (if any)
|
||||
if (mtl) {
|
||||
|
||||
gset->setStateSet(mtl[grp->material]);
|
||||
geom->setStateSet(mtl[grp->material]);
|
||||
}
|
||||
else
|
||||
osg::notify(osg::INFO) << "Group " << grp->name << " has no material" << std::endl;
|
||||
|
||||
return gset;
|
||||
return geom;
|
||||
}
|
||||
|
||||
|
||||
@@ -463,23 +463,20 @@ int ConvertFromPerformer::getNumVerts(pfGeoSet *gset)
|
||||
}
|
||||
|
||||
|
||||
osg::GeoSet* ConvertFromPerformer::visitGeoSet(osg::Geode* osgGeode,pfGeoSet* geoset)
|
||||
osg::Drawable* ConvertFromPerformer::visitGeoSet(osg::Geode* osgGeode,pfGeoSet* geoset)
|
||||
{
|
||||
if (geoset==NULL) return NULL;
|
||||
|
||||
osg::GeoSet* osgGeoSet = dynamic_cast<osg::GeoSet*>(getOsgObject(geoset));
|
||||
if (osgGeoSet)
|
||||
osg::Drawable* osgDrawable = dynamic_cast<osg::Drawable*>(getOsgObject(geoset));
|
||||
if (osgDrawable)
|
||||
{
|
||||
if (osgGeode) osgGeode->addDrawable(osgGeoSet);
|
||||
return osgGeoSet;
|
||||
if (osgGeode) osgGeode->addDrawable(osgDrawable);
|
||||
return osgDrawable;
|
||||
}
|
||||
|
||||
osgGeoSet = new osg::GeoSet;
|
||||
if (osgGeode) osgGeode->addDrawable(osgGeoSet);
|
||||
|
||||
regisiterPfObjectForOsgObject(geoset,osgGeoSet);
|
||||
|
||||
visitGeoState(osgGeoSet,geoset->getGState());
|
||||
// we'll make it easy to convert by using the Performer style osg::GeoSet,
|
||||
// and then convert back to a osg::Geometry afterwards.
|
||||
osg::ref_ptr<osg::GeoSet> osgGeoSet = new osg::GeoSet;
|
||||
|
||||
int i;
|
||||
|
||||
@@ -702,11 +699,23 @@ osg::GeoSet* ConvertFromPerformer::visitGeoSet(osg::Geode* osgGeode,pfGeoSet* ge
|
||||
|
||||
}
|
||||
|
||||
return osgGeoSet;
|
||||
visitGeoState(osgGeoSet,geoset->getGState());
|
||||
|
||||
|
||||
// convert to osg::Geometry, as osg::GeoSet is now deprecated.
|
||||
osgDrawable = osgGeoSet->convertToGeometry();
|
||||
if (osgDrawable)
|
||||
{
|
||||
osgGeode->addDrawable(osgDrawable);
|
||||
regisiterPfObjectForOsgObject(geoset,osgDrawable);
|
||||
}
|
||||
|
||||
|
||||
return osgDrawable;
|
||||
}
|
||||
|
||||
|
||||
osg::StateSet* ConvertFromPerformer::visitGeoState(osg::GeoSet* osgGeoSet,pfGeoState* geostate)
|
||||
osg::StateSet* ConvertFromPerformer::visitGeoState(osg:Drawable* osgDrawable,pfGeoState* geostate)
|
||||
{
|
||||
if (geostate==NULL) return NULL;
|
||||
|
||||
@@ -718,7 +727,7 @@ osg::StateSet* ConvertFromPerformer::visitGeoState(osg::GeoSet* osgGeoSet,pfGeoS
|
||||
}
|
||||
|
||||
osgStateSet = new osg::StateSet;
|
||||
if (osgGeoSet) osgGeoSet->setStateSet(osgStateSet);
|
||||
if (osgDrawable) osgDrawable->setStateSet(osgStateSet);
|
||||
|
||||
regisiterPfObjectForOsgObject(geostate,osgStateSet);
|
||||
|
||||
|
||||
@@ -45,8 +45,8 @@ class ConvertFromPerformer {
|
||||
osg::Node* visitBillboard(osg::Group* osgParent,pfBillboard* billboard);
|
||||
|
||||
int getNumVerts(pfGeoSet *gset);
|
||||
osg::GeoSet* visitGeoSet(osg::Geode* osgParent,pfGeoSet* geoset);
|
||||
osg::StateSet* visitGeoState(osg::GeoSet* osgGeoSet,pfGeoState* geostate);
|
||||
osg::Drawable* visitGeoSet(osg::Geode* osgParent,pfGeoSet* geoset);
|
||||
osg::StateSet* visitGeoState(osg::Drawable* osgGeoSet,pfGeoState* geostate);
|
||||
osg::Material* visitMaterial(osg::StateSet* osgStateSet,pfMaterial* front_mat,pfMaterial* back_mat);
|
||||
osg::Texture* visitTexture(osg::StateSet* osgStateSet,pfTexture* tex);
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "osg/Notify"
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/Texture>
|
||||
|
||||
#include "osg/GL"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "osg/Notify"
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/Texture>
|
||||
|
||||
#include "osg/GL"
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
|
||||
#include "TrPageParser.h"
|
||||
|
||||
#include <osg/GeoSet>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory> // for auto_ptr
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <osg/Billboard>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Transform>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/CullFace>
|
||||
#include <osg/Light>
|
||||
#include <osg/Transparency>
|
||||
@@ -216,30 +216,30 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
geom.GetMaterial(0,matId, local);
|
||||
geom.GetNumNormal(numNorm);
|
||||
|
||||
Vec3* vertices = new Vec3[numVert];
|
||||
Vec3Array* vertices = new Vec3Array(numVert);
|
||||
// Get vertices
|
||||
geom.GetVertices(vertices);
|
||||
geom.GetVertices(&(vertices->front()));
|
||||
|
||||
// Turn the trpgGeometry into something Performer can understand
|
||||
GeoSet *gset = 0L;
|
||||
Geometry *geometry = 0L;
|
||||
|
||||
// Get texture coordinates
|
||||
Vec2* tex_coords = 0L;
|
||||
Vec2Array* tex_coords = 0L;
|
||||
trpgTexData td;
|
||||
if (geom.GetTexCoordSet(0,&td))
|
||||
{
|
||||
tex_coords = new Vec2[numVert];
|
||||
tex_coords = new Vec2Array(numVert);
|
||||
for (int i=0 ;i < numVert; i++)
|
||||
{
|
||||
tex_coords[i][0] = td.floatData[2*i+0];
|
||||
tex_coords[i][1] = td.floatData[2*i+1];
|
||||
(*tex_coords)[i].set(td.floatData[2*i+0],td.floatData[2*i+1]);
|
||||
}
|
||||
}
|
||||
|
||||
Vec3* normals = 0L;
|
||||
Vec3Array* normals = 0L;
|
||||
if (numNorm == numVert)
|
||||
{
|
||||
normals = new Vec3[numVert];
|
||||
geom.GetNormals(normals);
|
||||
normals = new Vec3Array(numVert);
|
||||
geom.GetNormals(&(normals->front()));
|
||||
}
|
||||
|
||||
Geode *geode = new Geode();
|
||||
@@ -248,8 +248,8 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
{
|
||||
case trpgGeometry::Triangles:
|
||||
{
|
||||
gset = new GeoSet;
|
||||
gset->setPrimType(GeoSet::TRIANGLES);
|
||||
geometry = new Geometry;
|
||||
geometry->addPrimitive(new DrawArrays(Primitive::TRIANGLES,0,numPrims*3));
|
||||
}
|
||||
break;
|
||||
case trpgGeometry::TriStrips:
|
||||
@@ -258,10 +258,15 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
int* primitives = new int[numPrims];
|
||||
geom.GetPrimLengths(primitives);
|
||||
|
||||
// Define GeoSet
|
||||
gset = new GeoSet;
|
||||
gset->setPrimType(GeoSet::TRIANGLE_STRIP);
|
||||
gset->setPrimLengths(primitives);
|
||||
// Define Geomtry
|
||||
geometry = new Geometry;
|
||||
int first=0;
|
||||
for(int i=0;i<numPrims;++i)
|
||||
{
|
||||
geometry->addPrimitive(new DrawArrays(Primitive::TRIANGLE_STRIP,first,primitives[i]));
|
||||
first += primitives[i];
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
case trpgGeometry::TriFans:
|
||||
@@ -269,10 +274,21 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
// Need primitive lengths too
|
||||
int* primitives = new int[numPrims];
|
||||
geom.GetPrimLengths(primitives);
|
||||
|
||||
// Need to flip the fans
|
||||
|
||||
|
||||
// create the trifan primitives.
|
||||
geometry = new Geometry;
|
||||
int first=0;
|
||||
int i;
|
||||
for(i=0;i<numPrims;++i)
|
||||
{
|
||||
geometry->addPrimitive(new DrawArrays(Primitive::TRIANGLE_FAN,first,primitives[i]));
|
||||
first += primitives[i];
|
||||
}
|
||||
|
||||
// Need to flip the fans coords.
|
||||
int ind = 0;
|
||||
for (int i=0;i<numPrims;i++)
|
||||
for (i=0;i<numPrims;++i)
|
||||
{
|
||||
int start=ind+1;
|
||||
int end=primitives[i]+ind-1;
|
||||
@@ -281,20 +297,16 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
// Swap vertices, texture coords & normals
|
||||
for (int j=0; j < numSwap; j++ )
|
||||
{
|
||||
std::swap(vertices[start], vertices[end]);
|
||||
std::swap((*vertices)[start], (*vertices)[end]);
|
||||
if( tex_coords )
|
||||
std::swap(tex_coords[start], tex_coords[end]);
|
||||
std::swap((*tex_coords)[start], (*tex_coords)[end]);
|
||||
if(normals)
|
||||
std::swap(normals[start], normals[end]);
|
||||
std::swap((*normals)[start], (*normals)[end]);
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
ind += primitives[i];
|
||||
}
|
||||
// Define GeoSet
|
||||
gset = new GeoSet;
|
||||
gset->setPrimType(GeoSet::TRIANGLE_FAN);
|
||||
gset->setPrimLengths(primitives);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -305,12 +317,14 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
|
||||
// Add it to the current parent group
|
||||
Group *top = parse->GetCurrTop();
|
||||
if (gset)
|
||||
if (geometry)
|
||||
{
|
||||
gset->setCoords(vertices);
|
||||
gset->setNumPrims(numPrims);
|
||||
geometry->setVertexArray(vertices);
|
||||
if (normals)
|
||||
gset->setNormals(normals);
|
||||
{
|
||||
geometry->setNormalArray(normals);
|
||||
geometry->setNormalBinding(Geometry::BIND_PER_VERTEX);
|
||||
}
|
||||
// Note: Should check number of materials first
|
||||
// Note: Should be combining multiple geosets
|
||||
ref_ptr<StateSet> sset = 0L;
|
||||
@@ -321,12 +335,11 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
|
||||
if (tex_coords)
|
||||
{
|
||||
gset->setTextureCoords(tex_coords);
|
||||
gset->setTextureBinding(GeoSet::BIND_PERVERTEX);
|
||||
geometry->setTexCoordArray( 0, tex_coords);
|
||||
}
|
||||
|
||||
gset->setStateSet(sset.get());
|
||||
geode->addDrawable(gset);
|
||||
geometry->setStateSet(sset.get());
|
||||
geode->addDrawable(geometry);
|
||||
top->addChild(geode);
|
||||
}
|
||||
return (void *) 1;
|
||||
|
||||
Reference in New Issue
Block a user