From 80baa19ff339dbd52c1ad128760981e5aecd96d1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 21 May 2003 14:34:12 +0000 Subject: [PATCH] Added GeoSet to osgconv. --- examples/osgconv/GeoSet.cpp | 1178 ++++++++++++++++++++++++++++++++ examples/osgconv/GeoSet.h | 414 +++++++++++ examples/osgconv/IO_GeoSet.cpp | 1097 +++++++++++++++++++++++++++++ 3 files changed, 2689 insertions(+) create mode 100644 examples/osgconv/GeoSet.cpp create mode 100644 examples/osgconv/GeoSet.h create mode 100644 examples/osgconv/IO_GeoSet.cpp diff --git a/examples/osgconv/GeoSet.cpp b/examples/osgconv/GeoSet.cpp new file mode 100644 index 000000000..c6b7f1c60 --- /dev/null +++ b/examples/osgconv/GeoSet.cpp @@ -0,0 +1,1178 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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. +*/ +#if defined(_MSC_VER) + #pragma warning( disable : 4786 ) +#endif + +#include +#include + +#include "GeoSet.h" + +#include + +#include +#include + +#include + +using namespace osg; + +GeoSet::GeoSet() +{ + // we will use the a default delete functor which + // assumes that users have allocated arrays with new only + // and that now sharing of attributes exists between GeoSet's. + _adf = new AttributeDeleteFunctor; + + _coords = (Vec3 *)0; + + _normals = (Vec3 *)0; + + _colors = (Vec4 *)0; + + _tcoords = (Vec2 *)0; + + _iarray = (float *)0L; + _iaformat = IA_OFF; + _ogliaformat = 0; + + + _numprims = 0; + _primtype = NO_TYPE; + _oglprimtype = 0xFFFF; + _needprimlen = 0; + _primLengths = (int *)0; + + _numcoords = 0; + _numnormals = 0; + _numcolors = 0; + _numtcoords = 0; + + _normal_binding = BIND_OFF; + _color_binding = BIND_OFF; + _texture_binding = BIND_OFF; + + _fast_path = 1; + + _primlength = 0; + _flat_shaded_skip = 0; + +} + + +GeoSet::GeoSet(const GeoSet& geoset,const CopyOp& copyop): + Drawable(geoset,copyop) +{ + // ensure that the num of vertices etc have been set up before we copy. + geoset.computeNumVerts(); + + _adf = geoset._adf; + + _numprims = geoset._numprims; + _primtype = geoset._primtype; + _needprimlen = geoset._needprimlen; + _oglprimtype = geoset._oglprimtype; + _primlength = geoset._primlength; + _flat_shaded_skip = geoset._flat_shaded_skip; + if (geoset._primLengths) + { + _primLengths = new int [_numprims]; + memcpy(_primLengths,geoset._primLengths,_numprims*sizeof(int)); + } + else + { + _primLengths = 0L; + } + + _numcoords = geoset._numcoords; + _cindex = geoset._cindex; + if (geoset._coords) + { + _coords = new Vec3 [_numcoords]; + memcpy(_coords,geoset._coords,_numcoords*sizeof(Vec3)); + } + else + { + _coords = 0L; + } + + _normal_binding = geoset._normal_binding; + _numnormals = geoset._numnormals; + _nindex = geoset._nindex; + if (geoset._normals) + { + _normals = new Vec3 [_numnormals]; + memcpy(_normals,geoset._normals,_numnormals*sizeof(Vec3)); + } + else + { + _normals = 0L; + } + + _color_binding = geoset._color_binding; + _numcolors = geoset._numcolors; + _colindex = geoset._colindex; + if (geoset._colors) + { + _colors = new Vec4 [_numcolors]; + memcpy(_colors,geoset._colors,_numcolors*sizeof(Vec4)); + } + else + { + _colors = 0L; + } + + _texture_binding = geoset._texture_binding; + _numtcoords = geoset._numtcoords; + _tindex = geoset._tindex; + if (geoset._tcoords) + { + _tcoords = new Vec2 [_numtcoords]; + memcpy(_tcoords,geoset._tcoords,_numtcoords*sizeof(Vec2)); + } + else + { + _tcoords = 0L; + } + + _iaindex = geoset._iaindex; + _iaformat = geoset._iaformat; + _ogliaformat = geoset._ogliaformat; + _fast_path = geoset._fast_path; + if (geoset._iarray) + { + _iarray = 0L; + osg::notify(osg::WARN)<<"Warning :: GeoSet copy constructor error, copying of interleaved arrays unsupported."<getPrimLengths(); + delete [] gset->getCoords(); + delete [] gset->getNormals(); + delete [] gset->getColors(); + delete [] gset->getTextureCoords(); + // can't delete a void* right now... interleaved arrays needs to be reimplemented with a proper pointer.. + // delete [] gset->getInterleavedArray(); + + + // coord indicies may be shared so we have to go through the long winded + // step of creating unique pointer sets which we then delete. This + // ensures that arrays aren't delete twice. Robert. + std::set ushortList; + std::set uintList; + + INDEX_ARRAY_DELETE(gset->getCoordIndices()) + INDEX_ARRAY_DELETE(gset->getNormalIndices()); + INDEX_ARRAY_DELETE(gset->getColorIndices()); + INDEX_ARRAY_DELETE(gset->getTextureIndices()) + INDEX_ARRAY_DELETE(gset->getInterleavedIndices()); + + for(std::set::iterator sitr=ushortList.begin(); + sitr!=ushortList.end(); + ++sitr) + { + delete [] *sitr; + } + + for(std::set::iterator iitr=uintList.begin(); + iitr!=uintList.end(); + ++iitr) + { + delete [] *iitr; + } +} + +#undef INDEX_ARRAY_DELETE + +GeoSet::~GeoSet() +{ + // if attached call the adf do delete the memory. + if (_adf.valid()) (*_adf)(this); +} + + +void GeoSet::setColorBinding( BindingType binding ) +{ + if( binding != BIND_DEFAULT && + binding != BIND_OFF && + binding != BIND_OVERALL && + binding != BIND_PERPRIM && + binding != BIND_PERVERTEX ) + _color_binding = BIND_OFF; + else + _color_binding = binding; + + if( _color_binding == BIND_DEFAULT ) + _color_binding = BIND_PERVERTEX; +} + + +void GeoSet::setNormalBinding( BindingType binding ) +{ + if( binding != BIND_DEFAULT && + binding != BIND_OFF && + binding != BIND_OVERALL && + binding != BIND_PERPRIM && + binding != BIND_PERVERTEX ) + _normal_binding = BIND_OFF; + else + _normal_binding = binding; + + if( _normal_binding == BIND_DEFAULT ) + _normal_binding = BIND_PERVERTEX; + +} + + +void GeoSet::setTextureBinding( BindingType binding ) +{ + if( binding != BIND_DEFAULT && + binding != BIND_OFF && + binding != BIND_PERVERTEX ) + _texture_binding = BIND_OFF; + else + _texture_binding = binding; + + if( _texture_binding == BIND_DEFAULT ) + _texture_binding = BIND_PERVERTEX; + +} + +void GeoSet::computeNumVerts() const +{ + int i; + int numverts=0; + + int flat_shaded_offset=0; + if (_primtype == FLAT_LINE_STRIP) flat_shaded_offset=_numprims; + else if (_primtype == FLAT_TRIANGLE_STRIP) flat_shaded_offset=2*_numprims; + else if (_primtype == FLAT_TRIANGLE_FAN) flat_shaded_offset=2*_numprims; + + switch( _primtype ) + { + case POINTS : + _primlength = 1; + numverts = _numprims * _primlength; + break; + + case LINES : + _primlength = 2; + numverts = _numprims * _primlength; + break; + + case TRIANGLES : + _primlength = 3; + numverts = _numprims * _primlength; + break; + + case QUADS : + _primlength = 4; + numverts = _numprims * _primlength; + break; + + case QUAD_STRIP : + case FLAT_TRIANGLE_FAN : + case TRIANGLE_FAN : + case LINE_LOOP : + case LINE_STRIP : + case FLAT_LINE_STRIP : + case TRIANGLE_STRIP : + case FLAT_TRIANGLE_STRIP : + case POLYGON : + _primlength = 0; + numverts = 0; + for( i = 0; i < _numprims; i++ ) + numverts += _primLengths[i]; + break; + default: + notify(WARN) << "Not supported primitive "<<(int)_primtype<= 3 ? fptr[2] : 0.0f; + Vec3 vv(x,y,z); + center += vv; + _bbox.expandBy(vv); + + fptr += stride; + } + } + + center /= (float)_numcoords; + + _bbox_computed=true; + + return true; +} + +bool GeoSet::check() const +{ + if( _coords == (Vec3 *)0 ) return false; + + if( _cindex.valid() || + _nindex.valid() || + _colindex.valid() || + _tindex.valid() ) + { + + if( (_coords && _cindex.null()) || + (_normals && _nindex.null()) || + (_colors && _colindex.null()) || + (_tcoords && _tindex.null()) ) + { + + notify(WARN) << "GeoSet::check() : " + "Cannot mix indexed and non-indexed attributes.\n"; + return false; + } + } + return true; +} + + +void GeoSet::setPrimType( PrimitiveType type ) +{ + switch( type ) + { + case NO_TYPE: break; + + case POINTS: _oglprimtype = GL_POINTS; _needprimlen = 0; break; + case LINES: _oglprimtype = GL_LINES; _needprimlen = 0; break; + case FLAT_LINE_STRIP: _oglprimtype = GL_LINE_STRIP; _needprimlen=1; break; + case LINE_STRIP: _oglprimtype = GL_LINE_STRIP; _needprimlen=1; break; + case LINE_LOOP: _oglprimtype = GL_LINE_LOOP; _needprimlen=1; break; + case TRIANGLES: _oglprimtype = GL_TRIANGLES; _needprimlen=0; break; + case FLAT_TRIANGLE_STRIP: _oglprimtype = GL_TRIANGLE_STRIP; _needprimlen=1; break; + case TRIANGLE_STRIP: _oglprimtype = GL_TRIANGLE_STRIP; _needprimlen=1; break; + case TRIANGLE_FAN: _oglprimtype = GL_TRIANGLE_FAN; _needprimlen=1; break; + case FLAT_TRIANGLE_FAN: _oglprimtype = GL_TRIANGLE_FAN; _needprimlen=1; break; + case QUADS: _oglprimtype = GL_QUADS; _needprimlen=0; break; + case QUAD_STRIP: _oglprimtype = GL_QUAD_STRIP; _needprimlen=1; break; + case POLYGON : _oglprimtype = GL_POLYGON; _needprimlen=1; break; + } + + _primtype = type; + + if( _primtype == FLAT_LINE_STRIP ) _flat_shaded_skip = 1; + else if( _primtype == FLAT_TRIANGLE_STRIP ) _flat_shaded_skip = 2; + else if( _primtype == FLAT_TRIANGLE_FAN ) _flat_shaded_skip = 2; + else _flat_shaded_skip = 0; +} + + +void GeoSet::setCoords( Vec3 *cp ) +{ + _coords = cp; + _cindex.setToNull(); + dirtyBound(); +} + + +void GeoSet::setCoords( Vec3 *cp, GLushort *ci ) +{ + _coords = cp; + // note the size of cindex defaults 0, but will be recalculated + // automatically by computeNumVerts(). + _cindex.set(0,ci); + dirtyBound(); +} + + +void GeoSet::setCoords( Vec3 *cp, GLuint *ci ) +{ + _coords = cp; + // note the size of cindex defaults 0, but will be recalculated + // automatically by computeNumVerts(). + _cindex.set(0,ci); + dirtyBound(); +} + +void GeoSet::setCoords( Vec3 *cp, IndexPointer& ip ) +{ + _coords = cp; + _cindex = ip; + dirtyBound(); +} + +void GeoSet::setNormals( Vec3 *np ) +{ + _normals = np; + _nindex.setToNull(); + if( _normal_binding == BIND_OFF ) + setNormalBinding( BIND_DEFAULT ); +} + + +void GeoSet::setNormals( Vec3 *np, GLushort *ni ) +{ + _normals = np; + // note the size of nindex defaults 0, but will be recalculated + // automatically by computeNumVerts(). + _nindex.set(0,ni); + if( _normal_binding == BIND_OFF ) + setNormalBinding( BIND_DEFAULT ); +} + +void GeoSet::setNormals( Vec3 *np, GLuint *ni ) +{ + _normals = np; + // note the size of nindex defaults 0, but will be recalculated + // automatically by computeNumVerts(). + _nindex.set(0,ni); + if( _normal_binding == BIND_OFF ) + setNormalBinding( BIND_DEFAULT ); +} + +void GeoSet::setNormals( Vec3 *cp, IndexPointer& ip ) +{ + _normals = cp; + _nindex = ip; + _bbox_computed = false; + if( _normal_binding == BIND_OFF ) + setNormalBinding( BIND_DEFAULT ); +} + + +void GeoSet::setColors( Vec4 *lp ) +{ + _colors = lp; + _colindex.setToNull(); + if( _color_binding == BIND_OFF ) + setColorBinding( BIND_DEFAULT ); +} + + +void GeoSet::setColors( Vec4 *lp, GLushort *coli ) +{ + _colors = lp; + // note the size of colindex defaults 0, but will be recalculated + // automatically by computeNumVerts(). + _colindex.set(0,coli); + if( _color_binding == BIND_OFF ) + setColorBinding( BIND_DEFAULT ); +} + +void GeoSet::setColors( Vec4 *lp, GLuint *coli ) +{ + _colors = lp; + // note the size of colindex defaults 0, but will be recalculated + // automatically by computeNumVerts(). + _colindex.set(0,coli); + if( _color_binding == BIND_OFF ) + setColorBinding( BIND_DEFAULT ); +} + +void GeoSet::setColors( Vec4 *cp, IndexPointer& ip ) +{ + _colors = cp; + _colindex = ip; + _bbox_computed = false; + if( _color_binding == BIND_OFF ) + setColorBinding( BIND_DEFAULT ); +} + + +void GeoSet::setTextureCoords( Vec2 *tc ) +{ + _tcoords = tc; + _tindex.setToNull(); + if( _texture_binding == BIND_OFF ) + setTextureBinding( BIND_DEFAULT ); +} + + +void GeoSet::setTextureCoords( Vec2 *tc, GLushort *ti ) +{ + _tcoords = tc; + // note the size of tindex defaults 0, but will be recalculated + // automatically by computeNumVerts(). + _tindex.set(0,ti); + if( _texture_binding == BIND_OFF ) + setTextureBinding( BIND_DEFAULT ); + +} + +void GeoSet::setTextureCoords( Vec2 *tc, GLuint *ti ) +{ + _tcoords = tc; + // note the size of tindex defaults 0, but will be recalculated + // automatically by computeNumVerts(). + _tindex.set(0,ti); + if( _texture_binding == BIND_OFF ) + setTextureBinding( BIND_DEFAULT ); + +} + +void GeoSet::setTextureCoords( Vec2 *cp, IndexPointer& ip ) +{ + _tcoords = cp; + _tindex = ip; + _bbox_computed = false; + if( _texture_binding == BIND_OFF ) + setTextureBinding( BIND_DEFAULT ); +} + +void GeoSet::setInterleavedArray( InterleaveArrayType format, float *pointer ) +{ + _iaformat = format; + + _ogliaformat = + (_iaformat == IA_OFF ) ? 0 : + (_iaformat == IA_V2F ) ? GL_V2F: + (_iaformat == IA_V3F ) ? GL_V3F: + (_iaformat == IA_C4UB_V2F) ? GL_C4UB_V2F: + (_iaformat == IA_C4UB_V3F) ? GL_C4UB_V3F: + (_iaformat == IA_C3F_V3F) ? GL_C3F_V3F: + (_iaformat == IA_N3F_V3F) ? GL_N3F_V3F: + (_iaformat == IA_C4F_N3F_V3F) ? GL_C4F_N3F_V3F: + (_iaformat == IA_T2F_V3F) ? GL_T2F_V3F: + (_iaformat == IA_T4F_V4F) ? GL_T4F_V4F: + (_iaformat == IA_T2F_C4UB_V3F) ? GL_T2F_C4UB_V3F: + (_iaformat == IA_T2F_C3F_V3F) ? GL_T2F_C3F_V3F: + (_iaformat == IA_T2F_N3F_V3F) ? GL_T2F_N3F_V3F: + (_iaformat == IA_T2F_C4F_N3F_V3F) ? GL_T2F_C4F_N3F_V3F: + (_iaformat == IA_T4F_C4F_N3F_V4F) ? GL_T4F_C4F_N3F_V4F: 0; + + _iarray = pointer; + _iaindex.setToNull(); +} + + +void GeoSet::setInterleavedArray( InterleaveArrayType format, float *ia, GLushort *iai ) +{ + _iaformat = format; + + _ogliaformat = + (_iaformat == IA_OFF ) ? 0 : + (_iaformat == IA_V2F ) ? GL_V2F: + (_iaformat == IA_V3F ) ? GL_V3F: + (_iaformat == IA_C4UB_V2F) ? GL_C4UB_V2F: + (_iaformat == IA_C4UB_V3F) ? GL_C4UB_V3F: + (_iaformat == IA_C3F_V3F) ? GL_C3F_V3F: + (_iaformat == IA_N3F_V3F) ? GL_N3F_V3F: + (_iaformat == IA_C4F_N3F_V3F) ? GL_C4F_N3F_V3F: + (_iaformat == IA_T2F_V3F) ? GL_T2F_V3F: + (_iaformat == IA_T4F_V4F) ? GL_T4F_V4F: + (_iaformat == IA_T2F_C4UB_V3F) ? GL_T2F_C4UB_V3F: + (_iaformat == IA_T2F_C3F_V3F) ? GL_T2F_C3F_V3F: + (_iaformat == IA_T2F_N3F_V3F) ? GL_T2F_N3F_V3F: + (_iaformat == IA_T2F_C4F_N3F_V3F) ? GL_T2F_C4F_N3F_V3F: + (_iaformat == IA_T4F_C4F_N3F_V4F) ? GL_T4F_C4F_N3F_V4F: 0; + + _iarray = ia; + // note the size of _iaindex defaults 0, but will be recalculated + // automatically by computeNumVerts(). + _iaindex.set(0,iai); +} + +void GeoSet::setInterleavedArray( InterleaveArrayType format, float *ia, GLuint *iai ) +{ + _iaformat = format; + + _ogliaformat = + (_iaformat == IA_OFF ) ? 0 : + (_iaformat == IA_V2F ) ? GL_V2F: + (_iaformat == IA_V3F ) ? GL_V3F: + (_iaformat == IA_C4UB_V2F) ? GL_C4UB_V2F: + (_iaformat == IA_C4UB_V3F) ? GL_C4UB_V3F: + (_iaformat == IA_C3F_V3F) ? GL_C3F_V3F: + (_iaformat == IA_N3F_V3F) ? GL_N3F_V3F: + (_iaformat == IA_C4F_N3F_V3F) ? GL_C4F_N3F_V3F: + (_iaformat == IA_T2F_V3F) ? GL_T2F_V3F: + (_iaformat == IA_T4F_V4F) ? GL_T4F_V4F: + (_iaformat == IA_T2F_C4UB_V3F) ? GL_T2F_C4UB_V3F: + (_iaformat == IA_T2F_C3F_V3F) ? GL_T2F_C3F_V3F: + (_iaformat == IA_T2F_N3F_V3F) ? GL_T2F_N3F_V3F: + (_iaformat == IA_T2F_C4F_N3F_V3F) ? GL_T2F_C4F_N3F_V3F: + (_iaformat == IA_T4F_C4F_N3F_V4F) ? GL_T4F_C4F_N3F_V4F: 0; + + _iarray = ia; + // note the size of _iaindex defaults 0, but will be recalculated + // automatically by computeNumVerts(). + _iaindex.set(0,iai); +} + +void GeoSet::setInterleavedArray( InterleaveArrayType format, float *ia, IndexPointer& iai ) +{ + _iaformat = format; + + _ogliaformat = + (_iaformat == IA_OFF ) ? 0 : + (_iaformat == IA_V2F ) ? GL_V2F: + (_iaformat == IA_V3F ) ? GL_V3F: + (_iaformat == IA_C4UB_V2F) ? GL_C4UB_V2F: + (_iaformat == IA_C4UB_V3F) ? GL_C4UB_V3F: + (_iaformat == IA_C3F_V3F) ? GL_C3F_V3F: + (_iaformat == IA_N3F_V3F) ? GL_N3F_V3F: + (_iaformat == IA_C4F_N3F_V3F) ? GL_C4F_N3F_V3F: + (_iaformat == IA_T2F_V3F) ? GL_T2F_V3F: + (_iaformat == IA_T4F_V4F) ? GL_T4F_V4F: + (_iaformat == IA_T2F_C4UB_V3F) ? GL_T2F_C4UB_V3F: + (_iaformat == IA_T2F_C3F_V3F) ? GL_T2F_C3F_V3F: + (_iaformat == IA_T2F_N3F_V3F) ? GL_T2F_N3F_V3F: + (_iaformat == IA_T2F_C4F_N3F_V3F) ? GL_T2F_C4F_N3F_V3F: + (_iaformat == IA_T4F_C4F_N3F_V4F) ? GL_T4F_C4F_N3F_V4F: 0; + + _iarray = ia; + // note the size of _iaindex defaults 0, but will be recalculated + // automatically by computeNumVerts(). + _iaindex = iai; +} + +void GeoSet::accept(AttributeFunctor& auf) +{ + if (_numcoords == 0) computeNumVerts(); + + if (_coords && _numcoords) + { + auf.apply(VERTICES,_numcoords,_coords); + } + + if (_normals && _numnormals) + { + auf.apply(NORMALS,_numnormals,_normals); + } + + if (_colors && _numcolors) + { + auf.apply(COLORS,_numcolors,_colors); + } + + if (_tcoords && _numtcoords) + { + auf.apply(TEXTURE_COORDS_0,_numtcoords,_tcoords); + } +} + +void GeoSet::accept(ConstAttributeFunctor& auf) const +{ + if (_numcoords == 0) computeNumVerts(); + + if (_coords && _numcoords) + { + auf.apply(VERTICES,_numcoords,_coords); + } + + if (_normals && _numnormals) + { + auf.apply(NORMALS,_numnormals,_normals); + } + + if (_colors && _numcolors) + { + auf.apply(COLORS,_numcolors,_colors); + } + + if (_tcoords && _numtcoords) + { + auf.apply(TEXTURE_COORDS_0,_numtcoords,_tcoords); + } +} + +void GeoSet::accept(PrimitiveFunctor& functor) const +{ + // will easily convert into a Geometry. + + if (!_coords || !_numcoords) return; + + functor.setVertexArray(_numcoords,_coords); + + if( _needprimlen ) + { + // LINE_STRIP, LINE_LOOP, TRIANGLE_STRIP, + // TRIANGLE_FAN, QUAD_STRIP, POLYGONS + int index = 0; + if( _primLengths == (int *)0 ) + { + return; + } + + for( int i = 0; i < _numprims; i++ ) + { + if( _cindex.valid() ) + { + + if (_cindex._is_ushort) + functor.drawElements( (GLenum)_oglprimtype, _primLengths[i],&_cindex._ptr._ushort[index] ); + else + functor.drawElements( (GLenum)_oglprimtype, _primLengths[i],&_cindex._ptr._uint[index] ); + } + else + functor.drawArrays( (GLenum)_oglprimtype, index, _primLengths[i] ); + + index += _primLengths[i]; + } + } + else // POINTS, LINES, TRIANGLES, QUADS + { + if( _cindex.valid()) + { + if (_cindex._is_ushort) + functor.drawElements( (GLenum)_oglprimtype, _cindex._size, _cindex._ptr._ushort ); + else + functor.drawElements( (GLenum)_oglprimtype, _cindex._size, _cindex._ptr._uint ); + } + else + functor.drawArrays( (GLenum)_oglprimtype, 0, _numcoords ); + } + +} + +Geometry* GeoSet::convertToGeometry() +{ + computeNumVerts(); + + ref_ptr geom = new Geometry; + geom->setStateSet(getStateSet()); + + if (_flat_shaded_skip) + { + // will need to add flat shading to primitive. + + StateSet* stateset = geom->getOrCreateStateSet(); + ShadeModel* shademodel = dynamic_cast(stateset->getAttribute(StateAttribute::SHADEMODEL)); + if (!shademodel) + { + shademodel = new osg::ShadeModel; + stateset->setAttribute(shademodel); + } + shademodel->setMode( ShadeModel::FLAT ); + } + + switch(_normal_binding) + { + case(BIND_OFF): + geom->setNormalBinding(Geometry::BIND_OFF); + break; + case(BIND_OVERALL): + geom->setNormalBinding(Geometry::BIND_OVERALL); + break; + case(BIND_PERPRIM): + geom->setNormalBinding(Geometry::BIND_PER_PRIMITIVE); + break; + case(BIND_PERVERTEX): + geom->setNormalBinding(Geometry::BIND_PER_VERTEX); + break; + default: + geom->setNormalBinding(Geometry::BIND_OFF); + break; + } + + switch(_color_binding) + { + case(BIND_OFF): + geom->setColorBinding(Geometry::BIND_OFF); + break; + case(BIND_OVERALL): + geom->setColorBinding(Geometry::BIND_OVERALL); + break; + case(BIND_PERPRIM): + geom->setColorBinding(Geometry::BIND_PER_PRIMITIVE); + break; + case(BIND_PERVERTEX): + geom->setColorBinding(Geometry::BIND_PER_VERTEX); + break; + default: + geom->setColorBinding(Geometry::BIND_OFF); + break; + } + + if (_coords) + { + geom->setVertexArray(new Vec3Array(_numcoords,_coords)); + if (_cindex.valid()) + { + if (_cindex._is_ushort) geom->setVertexIndices(new UShortArray(_cindex._size,_cindex._ptr._ushort)); + else /* _nindex._is_uint*/ geom->setVertexIndices(new UIntArray(_cindex._size,_cindex._ptr._uint)); + } + } + + if (_normals) + { + if (_flat_shaded_skip && _needprimlen && _normal_binding==BIND_PERVERTEX) + { + if (_nindex.valid()) + { + geom->setNormalArray(new Vec3Array(_numnormals,_normals)); + if (_nindex._is_ushort) + { + UShortArray* indices = new UShortArray; + int index=0; + for(int primNo = 0; primNo<_numprims; ++primNo) + { + for (int i=0;i<_primLengths[primNo];++i) + { + indices->push_back(_nindex._ptr._ushort[index]); + if (i>=_flat_shaded_skip) ++index; + } + } + geom->setNormalIndices(indices); + } + else + { + UIntArray* indices = new UIntArray; + int index=0; + for(int primNo = 0; primNo<_numprims; ++primNo) + { + for (int i=0;i<_primLengths[primNo];++i) + { + indices->push_back(_nindex._ptr._uint[index]); + if (i>=_flat_shaded_skip) ++index; + } + } + geom->setNormalIndices(indices); + } + } + else + { + Vec3Array* normals = new Vec3Array; + int index=0; + for(int primNo = 0; primNo<_numprims; ++primNo) + { + for (int i=0;i<_primLengths[primNo];++i) + { + normals->push_back(_normals[index]); + if (i>=_flat_shaded_skip) ++index; + } + } + geom->setNormalArray(normals); + } + } + else + { + // usual path. + geom->setNormalArray(new Vec3Array(_numnormals,_normals)); + if (_nindex.valid()) + { + if (_nindex==_cindex) geom->setNormalIndices(geom->getVertexIndices()); + else if (_nindex._is_ushort) geom->setNormalIndices(new UShortArray(_nindex._size,_nindex._ptr._ushort)); + else /* _nindex._is_uint*/ geom->setNormalIndices(new UIntArray(_nindex._size,_nindex._ptr._uint)); + } + } + } + + if (_colors) + { + if (_flat_shaded_skip && _needprimlen && _color_binding==BIND_PERVERTEX) + { + if (_colindex.valid()) + { + geom->setColorArray(new Vec4Array(_numcolors,_colors)); + if (_colindex==_nindex && _normal_binding==BIND_PERVERTEX) + { + geom->setColorIndices(geom->getNormalIndices()); + } + else if (_colindex._is_ushort) + { + UShortArray* indices = new UShortArray; + int index=0; + for(int primNo = 0; primNo<_numprims; ++primNo) + { + for (int i=0;i<_primLengths[primNo];++i) + { + indices->push_back(_colindex._ptr._ushort[index]); + if (i>=_flat_shaded_skip) ++index; + } + } + geom->setColorIndices(indices); + } + else + { + UIntArray* indices = new UIntArray; + int index=0; + for(int primNo = 0; primNo<_numprims; ++primNo) + { + for (int i=0;i<_primLengths[primNo];++i) + { + indices->push_back(_colindex._ptr._uint[index]); + if (i>=_flat_shaded_skip) ++index; + } + } + geom->setColorIndices(indices); + } + } + else + { + Vec4Array* colors = new Vec4Array; + int index=0; + for(int primNo = 0; primNo<_numprims; ++primNo) + { + for (int i=0;i<_primLengths[primNo];++i) + { + colors->push_back(_colors[index]); + if (i>=_flat_shaded_skip) ++index; + } + } + geom->setColorArray(colors); + } + + } + else + { + // usual path. + geom->setColorArray(new Vec4Array(_numcolors,_colors)); + if (_colindex.valid()) + { + if (_colindex==_cindex) geom->setColorIndices(geom->getVertexIndices()); + else if (_colindex==_nindex) geom->setColorIndices(geom->getNormalIndices()); + else if (_colindex._is_ushort) geom->setColorIndices(new UShortArray(_colindex._size,_colindex._ptr._ushort)); + else /* _colindex._is_uint*/ geom->setColorIndices(new UIntArray(_colindex._size,_colindex._ptr._uint)); + } + } + } + + if (_tcoords) + { + geom->setTexCoordArray(0,new Vec2Array(_numtcoords,_tcoords)); + if (_tindex.valid()) + { + if (_tindex==_cindex) geom->setTexCoordIndices(0,geom->getVertexIndices()); + else if (_tindex==_nindex) geom->setTexCoordIndices(0,geom->getNormalIndices()); + else if (_tindex==_colindex) geom->setTexCoordIndices(0,geom->getColorIndices()); + else if (_tindex._is_ushort) geom->setTexCoordIndices(0,new UShortArray(_tindex._size,_tindex._ptr._ushort)); + else /* _tindex._is_uint*/ geom->setTexCoordIndices(0,new UIntArray(_tindex._size,_tindex._ptr._uint)); + } + } + + + if (_needprimlen) + { + DrawArrayLengths* primitives = new DrawArrayLengths((GLenum)_oglprimtype); + primitives->insert(primitives->end(), _primLengths, _primLengths+_numprims ); + geom->addPrimitiveSet(primitives); + } + else + { + geom->addPrimitiveSet(new DrawArrays((GLenum)_oglprimtype,0, _numcoords)); + } + + return geom.take(); + + +} diff --git a/examples/osgconv/GeoSet.h b/examples/osgconv/GeoSet.h new file mode 100644 index 000000000..0be563ed2 --- /dev/null +++ b/examples/osgconv/GeoSet.h @@ -0,0 +1,414 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 OSG_GEOSET +#define OSG_GEOSET 1 + +#include +#include +#include +#include + +namespace osg { + + +// forward declare so that we don't need to include the header. +class Geometry; + +/** Note, osg::GeoSet is now deprecated, please use osg::Geometry instead. + osg::GeoSet will be kept through to the beta release for + backwards compatability only. + + Encapsulates OpenGL drawing primitives, geometry and + optional binding of normal, color and texture coordinates. Used + for representing the visible objects in the scene. State attributes + for a GeoSet are maintained in StateSet which the GeoSet maintains + a referenced counted pointer to. Both GeoSet's and StateSet's can + be shared for optimal memory usage and graphics performance. +*/ +class SG_EXPORT GeoSet : public Drawable +{ + public: + + + + enum PrimitiveType { + NO_TYPE, + POINTS, + LINES, + LINE_STRIP, + FLAT_LINE_STRIP, + LINE_LOOP, + TRIANGLES, + TRIANGLE_STRIP, + FLAT_TRIANGLE_STRIP, + TRIANGLE_FAN, + FLAT_TRIANGLE_FAN, + QUADS, + QUAD_STRIP, + POLYGON + }; + + enum BindingType { + BIND_OFF, + BIND_OVERALL, + BIND_PERPRIM, + BIND_PERVERTEX, + BIND_DEFAULT + }; + + enum InterleaveArrayType { + IA_OFF, + IA_V2F, + IA_V3F, + IA_C4UB_V2F, + IA_C4UB_V3F, + IA_C3F_V3F, + IA_N3F_V3F, + IA_C4F_N3F_V3F, + IA_T2F_V3F, + IA_T4F_V4F, + IA_T2F_C4UB_V3F, + IA_T2F_C3F_V3F, + IA_T2F_N3F_V3F, + IA_T2F_C4F_N3F_V3F, + IA_T4F_C4F_N3F_V4F + }; + + + struct SG_EXPORT IndexPointer + { + + mutable unsigned int _size; + bool _is_ushort; + union _TPtr + { + GLushort* _ushort; + GLuint* _uint; + } _ptr; + + IndexPointer() { _size=0;_is_ushort=true;_ptr._ushort = (GLushort*)0; } + + inline bool operator == (const IndexPointer& ip) const + { + return _size == ip._size && + _is_ushort == ip._is_ushort && + _ptr._ushort == ip._ptr._ushort; + } + + inline bool valid() const + { + return _ptr._ushort != (GLushort*)0; + } + + inline bool null() const + { + return _ptr._ushort == (GLushort*)0; + } + + inline void setToNull() + { + _size = 0; + _is_ushort = true; + _ptr._ushort = (GLushort*)0; + } + + inline void set(unsigned int size,GLushort* data) + { + _size = size; + _is_ushort = true; + _ptr._ushort = data; + } + + + void set(unsigned int size,GLuint* data) + { + _size = size; + _is_ushort = false; + _ptr._uint = data; + } + + inline unsigned int maxIndex() const + { + unsigned int max = 0; + if (_is_ushort) + { + for(unsigned int ai = 0; ai < _size; ai++ ) + if( _ptr._ushort[ai] > max ) max = _ptr._ushort[ai]; + } + else + { + for(unsigned int ai = 0; ai < _size; ai++ ) + if( _ptr._uint[ai] > max ) max = _ptr._uint[ai]; + } + return max; + } + + inline GLint operator [] (const GLuint pos) const + { + if (_is_ushort) return _ptr._ushort[pos]; + else return _ptr._uint[pos]; + } + + }; + + GeoSet(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + GeoSet(const GeoSet& geoset,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + virtual Object* cloneType() const { return new GeoSet(); } + + virtual Object* clone(const CopyOp& copyop) const { return new GeoSet(*this,copyop); } + + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } + + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return "GeoSet"; } + + + // data access methods. + inline void setNumPrims( int n ) { _numprims = n; _numcoords=0;} + inline int getNumPrims() const { return _numprims; } + + void setPrimType( PrimitiveType type ); + inline PrimitiveType getPrimType() const { return _primtype; } + + inline void setPrimLengths( int *lens ) { _primLengths = lens; } + inline int *getPrimLengths() { return _primLengths; } + inline int *getPrimLengths() const { return _primLengths; } + + void computeNumVerts() const; + + /** get the number of coords required by the defined primitives. */ + inline int getNumCoords() const + { if( _numcoords == 0 ) computeNumVerts(); return _numcoords; } + /** get a pointer to Vec3 coord array. */ + inline Vec3* getCoords() { return _coords; } + /** get a const pointer to Vec3 coord array. */ + inline const Vec3* getCoords() const { return _coords; } + /** get the number of indices required by the defined primitives. */ + inline int getNumCoordIndices() const { return _cindex._size; } + /** get the coord index array. */ + inline IndexPointer& getCoordIndices() { return _cindex; } + /** get the const coord index array. */ + inline const IndexPointer& getCoordIndices() const { return _cindex; } + /** set the coords (i.e the geometry) of the geoset.*/ + void setCoords( Vec3 *cp ); + /** set the coords (i.e the geometry) and ushort indices of the geoset. + To reduce memory footprint and bandwidth for small datasets it is + recommended the ushort indices are used instead of unit indices.*/ + void setCoords( Vec3 *cp, GLushort *ci ); + /** set the coords (i.e the geometry) and unsigned int indices of the geoset. + Unless your data set exceeds 65536 indices prefer ushort indices + over unsigned int indices, only use this unit indices version if necessary.*/ + void setCoords( Vec3 *cp, GLuint *ci ); + /** set the coords (i.e the geometry) and indices of the geoset.*/ + void setCoords( Vec3 *cp, IndexPointer& ip ); + + /** get the number of normals required by the defined primitives and normals binding.*/ + inline int getNumNormals() const { return _numnormals; } + /** get a pointer to Vec3 normal array. */ + inline Vec3* getNormals() { return _normals; } + /** get a const pointer to Vec3 normal array. */ + inline const Vec3* getNormals() const { return _normals; } + /** get the number of normal indices required by the defined primitives and normals binding.*/ + inline int getNumNormalIndices() const { return _nindex._size; } + /** get the normal index array. */ + inline IndexPointer& getNormalIndices() { return _nindex; } + /** get the const normal index array. */ + inline const IndexPointer& getNormalIndices() const { return _nindex; } + /** set the normals of the geoset.*/ + void setNormals( Vec3 *np ); + /** set the normals and normal indices of the geoset.*/ + void setNormals( Vec3 *np, GLushort *ni ); + /** set the normals and normal indices of the geoset.*/ + void setNormals( Vec3 *np, GLuint *ni ); + /** set the normals and normal indices of the geoset.*/ + void setNormals( Vec3 *np, IndexPointer& ip ); + /** set the normals binding to the vertices/primitives/overall.*/ + void setNormalBinding( BindingType binding ); + inline BindingType getNormalBinding() const { return _normal_binding; } + + /** get the number of colors required by the defined primitives and color binding.*/ + inline int getNumColors() const { return _numcolors; } + /** get a pointer to Vec4 color array. */ + inline Vec4* getColors() { return _colors; } + /** get a pointer to Vec4 color array. */ + inline const Vec4* getColors() const { return _colors; } + /** get the number of colors indices required by the defined primitives and color binding.*/ + inline int getNumColorIndices() const { return _colindex._size; } + /** get the color index array. */ + inline IndexPointer& getColorIndices() { return _colindex; } + /** get the const color index array. */ + inline const IndexPointer& getColorIndices() const { return _colindex; } + /** set the colors of the geoset.*/ + void setColors( Vec4 *cp ); + /** set the colors and color indices of the geoset.*/ + void setColors( Vec4 *cp, GLushort *li ); + /** set the colors and color indices of the geoset.*/ + void setColors( Vec4 *cp, GLuint *li ); + /** set the colors and color indices of the geoset.*/ + void setColors( Vec4 *cp, IndexPointer& ip ); + /** set the color binding to the vertices/primitives/overall.*/ + void setColorBinding( BindingType binding ); + inline BindingType getColorBinding() const { return _color_binding; } + + /** get the number of texture coords required by the defined primitives and textures binding.*/ + inline int getNumTextureCoords() const { return _numtcoords; } + /** get a pointer to Vec4 color array. */ + inline Vec2* getTextureCoords() { return _tcoords; } + /** get a pointer to Vec4 color array. */ + inline const Vec2* getTextureCoords() const { return _tcoords; } + /** get the number of texture coord indices required by the defined primitives and texture binding.*/ + inline int getNumTextureIndices() const { return _tindex._size; } + /** get the texture index array. */ + inline IndexPointer& getTextureIndices() { return _tindex; } + /** get the texture index array. */ + inline const IndexPointer& getTextureIndices() const { return _tindex; } + /** set the texture coords of the geoset.*/ + void setTextureCoords( Vec2 *tc ); + /** set the texture coords and texture coord indices of the geoset.*/ + void setTextureCoords( Vec2 *tc, GLushort *ti ); + /** set the texture coords and texture coord indices of the geoset.*/ + void setTextureCoords( Vec2 *tc, GLuint *ti ); + /** set the texture coords and texture indices of the geoset.*/ + void setTextureCoords( Vec2 *tc, IndexPointer& ip ); + /** set the texture coord binding to the vertices/primitives/overall.*/ + void setTextureBinding( BindingType binding ); + inline BindingType getTextureBinding() const { return _texture_binding; } + + /** get the number of texture coords required by the defined primitives and textures binding.*/ + inline int getNumInterleavedCoords() const { return _numcoords; } + /** get a pointer to interleaved float array. */ + inline void* getInterleavedArray() { return _iarray; } + /** get a const pointer to interleaved float array. */ + inline const void* getInterleavedArray() const { return _iarray; } + /** get the number of texture coord indices required by the defined primitives and texture binding.*/ + inline int getNumInterleavedIndices() const { return _iaindex._size; } + /** get the texture index array. */ + inline IndexPointer& getInterleavedIndices() { return _iaindex; } + /** get the interleaved index array. */ + inline const IndexPointer& getInterleavedIndices() const { return _iaindex; } + /** get the interleaved array storage format. */ + inline InterleaveArrayType getInterleavedFormat() const { return _iaformat; } + + /** set the interleaved arrays of the geoset.*/ + void setInterleavedArray( InterleaveArrayType format, float *ia ); + void setInterleavedArray( InterleaveArrayType format, float *ia, GLushort *iai ); + void setInterleavedArray( InterleaveArrayType format, float *ia, GLuint *iai ); + void setInterleavedArray( InterleaveArrayType format, float *ia, IndexPointer& iai ); + + /** draw geoset directly ignoring an OpenGL display list which could be attached. + * This is the internal draw method which does the drawing itself, + * and is the method to override when deriving from GeoSet for user-drawn objects. + */ + virtual void drawImplementation(State&) const {} + + bool check() const; + + + /** function object which is used to handling the clean up of attribute arrays + * associated with GeoSet's. A default is provided which assumes that all + * momory attached to the GeoSet is owned by this GeoSet and can be deleted + * using delete []. If this is not the cause derive your own AttributeDeleteFunctor + * a specify your own memory deletion operation.*/ + struct SG_EXPORT AttributeDeleteFunctor : public osg::Referenced + { + // see GeoSet.cpp for implemention. + virtual void operator() (GeoSet* gset); + }; + + /** set an alternative AttributeDeleteFunction to handle attribute arrays attached to this Geoset.*/ + void setAttributeDeleteFunctor(AttributeDeleteFunctor* adf) { _adf = adf; } + + /** get the current AttributeDeleteFunction to handle attribute arrays attached to this Geoset.*/ + AttributeDeleteFunctor* getAttributeDeleteFunctor() { return _adf.get(); } + + /** get the current AttributeDeleteFunction to handle attribute arrays attached to this Geoset.*/ + const AttributeDeleteFunctor* getAttributeDeleteFunctor() const { return _adf.get(); } + + /** return true, osg::GeoSet does support accept(AttributeFunctor&).*/ + virtual bool supports(AttributeFunctor&) const { return true; } + + /** accept an AttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ + virtual void accept(AttributeFunctor& af); + + /** return true, osg::GeoSet does support accept(ConstAttributeFunctor&).*/ + virtual bool supports(ConstAttributeFunctor&) const { return true; } + + /** accept an ConstAttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ + virtual void accept(ConstAttributeFunctor& af) const; + + /** return true, osg::GeoSet does support accept(PrimitiveFunctor&) .*/ + virtual bool supports(PrimitiveFunctor&) const { return true; } + + /** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/ + virtual void accept(PrimitiveFunctor& pf) const; + + /** convinience function for converting GeoSet's to equivilant Geometry nodes.*/ + Geometry* convertToGeometry(); + + protected: + + GeoSet& operator = (const GeoSet&) { return *this;} + + virtual ~GeoSet(); + + virtual bool computeBound() const; + + ref_ptr _adf; + + int _numprims; + PrimitiveType _primtype; + int _needprimlen; + unsigned int _oglprimtype; + int *_primLengths; + mutable unsigned char _primlength; + unsigned char _flat_shaded_skip; + + mutable int _numcoords; + Vec3 *_coords; + mutable IndexPointer _cindex; + + BindingType _normal_binding; + mutable int _numnormals; + Vec3 *_normals; + IndexPointer _nindex; + + BindingType _color_binding; + mutable int _numcolors; + Vec4 *_colors; + IndexPointer _colindex; + + BindingType _texture_binding; + mutable int _numtcoords; + Vec2 *_tcoords; + IndexPointer _tindex; + + void *_iarray; + IndexPointer _iaindex; + InterleaveArrayType _iaformat; + unsigned int _ogliaformat; + + + int _fast_path; + +}; + + + +} + +#endif diff --git a/examples/osgconv/IO_GeoSet.cpp b/examples/osgconv/IO_GeoSet.cpp new file mode 100644 index 000000000..29b15924e --- /dev/null +++ b/examples/osgconv/IO_GeoSet.cpp @@ -0,0 +1,1097 @@ +#if defined(_MSC_VER) + #pragma warning( disable : 4786 ) +#endif + +#include "GeoSet.h" +#include "osg/Notify" + +#include "osgDB/Registry" +#include "osgDB/Input" +#include "osgDB/ParameterOutput" + +using namespace osg; +using namespace osgDB; + +// forward declare functions to use later. +bool GeoSet_readLocalData(Object& obj, Input& fr); +bool GeoSet_writeLocalData(const Object& obj, Output& fw); + +bool GeoSet_readIndexData(Input& fr, const char* IndexName, GeoSet::IndexPointer& ip, bool& useCIndex); +bool GeoSet_writeIndexData(Output& fw, const char* IndexName,const GeoSet::IndexPointer& ip); +bool GeoSet_matchBindingTypeStr(const char* str,GeoSet::BindingType& mode); +const char* GeoSet_getBindingTypeStr(GeoSet::BindingType mode); +const char* GeoSet_getInterleavedRowComposition(GeoSet::InterleaveArrayType at); +int GeoSet_getInterleavedRowLength(GeoSet::InterleaveArrayType at); + +// register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_GeoSetFuncProxy +( + new osg::GeoSet, + "GeoSet", + "Object Drawable GeoSet", + &GeoSet_readLocalData, + &GeoSet_writeLocalData, + DotOsgWrapper::READ_AND_WRITE +); + +// register the old style 'Geoset' keyword read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_GeosetFuncProxy +( + new osg::GeoSet, + "Geoset", + "Object Drawable Geoset", + &GeoSet_readLocalData, + NULL, + DotOsgWrapper::READ_ONLY +); + +bool GeoSet_readLocalData(Object& obj, Input& fr) +{ + bool iteratorAdvanced = false; + + GeoSet& geoset = static_cast(obj); + + Vec3* coordList = NULL; + bool coordIndexUseCIndex = false; + GeoSet::IndexPointer coordIndex; + Vec3* normalList = NULL; + bool normIndexUseCIndex = false; + GeoSet::IndexPointer normIndex; + Vec4* colorList = NULL; + bool colIndexUseCIndex = false; + GeoSet::IndexPointer colIndex; + Vec2* textureList = NULL; + bool tIndexUseCIndex = false; + GeoSet::IndexPointer tIndex; + float* interleavedArray = NULL; + bool iaIndexUseCIndex = false; + GeoSet::IndexPointer iaIndex; + + GeoSet::BindingType bind=GeoSet::BIND_OFF; + GeoSet::BindingType normal_bind=GeoSet::BIND_OFF; + GeoSet::BindingType color_bind=GeoSet::BIND_OFF; + GeoSet::BindingType texture_bind=GeoSet::BIND_OFF; + GeoSet::InterleaveArrayType iaType = GeoSet::IA_OFF; + + int start_indent = fr[0].getNoNestedBrackets(); + while (!fr.eof() && fr[0].getNoNestedBrackets()>=start_indent) + { + + bool fieldAdvanced = false; + + bool readPrimitiveLengths = false; + if (fr.matchSequence("tstrips %i {")) + { + readPrimitiveLengths = true; + geoset.setPrimType(GeoSet::TRIANGLE_STRIP); + } + else if (fr.matchSequence("flat_tstrips %i {")) + { + readPrimitiveLengths = true; + geoset.setPrimType(GeoSet::FLAT_TRIANGLE_STRIP); + } + else if (fr.matchSequence("polys %i {")) + { + readPrimitiveLengths = true; + geoset.setPrimType(GeoSet::POLYGON); + } + else if (fr.matchSequence("quadstrip %i {")) + { + readPrimitiveLengths = true; + geoset.setPrimType(GeoSet::QUAD_STRIP); + } + else if (fr.matchSequence("lineloops %i {")) + { + readPrimitiveLengths = true; + geoset.setPrimType(GeoSet::LINE_LOOP); + } + else if (fr.matchSequence("linestrip %i {")) + { + readPrimitiveLengths = true; + geoset.setPrimType(GeoSet::LINE_STRIP); + } + else if (fr.matchSequence("flat_linestrip %i {")) + { + readPrimitiveLengths = true; + geoset.setPrimType(GeoSet::FLAT_LINE_STRIP); + } + else if (fr.matchSequence("tfans %i {")) + { + readPrimitiveLengths = true; + geoset.setPrimType(GeoSet::TRIANGLE_FAN); + } + else if (fr.matchSequence("flat_tfans %i {")) + { + readPrimitiveLengths = true; + geoset.setPrimType(GeoSet::FLAT_TRIANGLE_FAN); + } + + if (readPrimitiveLengths) + { + + int entry = fr[1].getNoNestedBrackets(); + fr += 3; + + int capacity; + if (!fr[1].getInt(capacity)) capacity=100; + int size = 0; + int* list = new int [capacity]; + memset(list,0,capacity*sizeof(int)); + while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) + { + int primLength; + + if (fr[0].getInt(primLength)) + { + + if (size>=capacity) + { + int oldCapacity = capacity; + while(capacity<=size) capacity *= 2; + int* oldList = list; + list = new int[capacity]; + memset(list,0,capacity*sizeof(int)); + for(int i=0;ientry) + { + float x,y,z; + if (fr[0].getFloat(x) && fr[1].getFloat(y) && fr[2].getFloat(z)) + { + fr += 3; + + if (size>=capacity) + { + int oldCapacity = capacity; + while(capacity<=size) capacity *= 2; + Vec3* oldList = coordList; + coordList = new Vec3[capacity]; + for(int i=0;ientry) + { + float x,y,z; + if (fr[0].getFloat(x) && fr[1].getFloat(y) && fr[2].getFloat(z)) + { + fr += 3; + + if (size>=capacity) + { + int oldCapacity = capacity; + while(capacity<=size) capacity *= 2; + Vec3* oldList = normalList; + normalList = new Vec3[capacity]; + for(int i=0;ientry) + { + float r,g,b,a; + if (fr[0].getFloat(r) && fr[1].getFloat(g) && fr[2].getFloat(b) && fr[3].getFloat(a)) + { + + fr += 4; + + if (size>=capacity) + { + int oldCapacity = capacity; + while(capacity<=size) capacity *= 2; + Vec4* oldList = colorList; + colorList = new Vec4[capacity]; + for(int i=0;ientry) + { + float r,s; + if (fr[0].getFloat(r) && fr[1].getFloat(s)) + { + fr += 2; + if (size>=capacity) + { + int oldCapacity = capacity; + while(capacity<=size) capacity *= 2; + Vec2* oldList = textureList; + textureList = new Vec2[capacity]; + for(int i=0;ientry) ++fr; + } + else + { + // now read the data rows between the {}. + const char* rowComp = GeoSet_getInterleavedRowComposition(iaType); + int rowLength = GeoSet_getInterleavedRowLength(iaType); + + int size = 0; + unsigned char* dataList = new unsigned char[capacity*rowLength]; + + unsigned char* rowData = new unsigned char [rowLength]; + + float floatData; + int intData; + while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) + { + + unsigned char* itrRowData = rowData; + const char* itrRowComp = rowComp; + int rn = 0; + while (*itrRowComp!=0 && !fr.eof() && fr[0].getNoNestedBrackets()>entry) + { + if (*itrRowComp=='f') + { + if (!fr[rn].getFloat(floatData)) break; + *(float*)itrRowData = floatData; + itrRowData += 4; + } + else + { + if (!fr[rn].getInt(intData)) break; + *itrRowData = (unsigned char)intData; + itrRowData += 1; + } + ++itrRowComp; + ++rn; + } + if (*itrRowComp==0) + { + fr += rn; + if (size>=capacity) + { + int oldCapacity = capacity; + while(capacity<=size) capacity *= 2; + unsigned char* oldList = dataList; + dataList = new unsigned char[capacity*rowLength]; + memcpy(dataList,oldList,oldCapacity*rowLength); + delete [] oldList; + } + memcpy(dataList+size*rowLength,rowData,rowLength); + ++size; + + } + else + { + if (!fr.eof() && fr[0].getNoNestedBrackets()>entry) ++fr; + } + } + + delete [] rowData; + + interleavedArray = (float*)dataList; + } + + fieldAdvanced = true; + ++fr; + + } + + if (GeoSet_readIndexData(fr, "InterleavedArrayIndex" ,iaIndex, iaIndexUseCIndex)) + { + fieldAdvanced = true; + } + + if (!fieldAdvanced) + { + if (fr[0].getNoNestedBrackets()>start_indent) fr.advanceToEndOfBlock(start_indent+1); + else ++fr; + } + iteratorAdvanced = true; + + } + + // set up the coord lists. + if (coordList) + { + geoset.setCoords(coordList,coordIndex); + } + + // set up the normal lists. + if (normalList) + { + geoset.setNormalBinding(normal_bind); + if (normIndexUseCIndex) geoset.setNormals(normalList,coordIndex); + else geoset.setNormals(normalList,normIndex); + + } else geoset.setNormalBinding(GeoSet::BIND_OFF); + + // set up the color lists. + if (colorList) + { + geoset.setColorBinding(color_bind); + if (colIndexUseCIndex) geoset.setColors(colorList,coordIndex); + else geoset.setColors(colorList,colIndex); + + } else geoset.setColorBinding(GeoSet::BIND_OFF); + + if (textureList) + { + geoset.setTextureBinding(texture_bind); + if (tIndexUseCIndex) geoset.setTextureCoords(textureList,coordIndex); + else geoset.setTextureCoords(textureList,tIndex); + + } else geoset.setTextureBinding(GeoSet::BIND_OFF); + + if (interleavedArray) + { + if (iaIndexUseCIndex) geoset.setInterleavedArray(iaType,interleavedArray,coordIndex); + else geoset.setInterleavedArray(iaType,interleavedArray,iaIndex); + + }; + + return iteratorAdvanced; +} + + +bool GeoSet_writeLocalData(const Object& obj, Output& fw) +{ + int i; + + const GeoSet& geoset = static_cast(obj); + + // write out primitives. + bool writeOutPrimitiveLengths = false; + switch(geoset.getPrimType()) + { + case (GeoSet::TRIANGLE_STRIP): + fw.indent()<<"tstrips "<< geoset.getNumPrims() << std::endl; + writeOutPrimitiveLengths = true; + break; + case (GeoSet::FLAT_TRIANGLE_STRIP): + fw.indent()<<"flat_tstrips "<< geoset.getNumPrims() << std::endl; + writeOutPrimitiveLengths = true; + break; + case (GeoSet::POLYGON): + fw.indent()<<"polys "<< geoset.getNumPrims() << std::endl; + writeOutPrimitiveLengths = true; + break; + case (GeoSet::QUAD_STRIP): + fw.indent()<<"quadstrip "<< geoset.getNumPrims() << std::endl; + writeOutPrimitiveLengths = true; + break; + case (GeoSet::LINE_LOOP): + fw.indent()<<"lineloops "<< geoset.getNumPrims() << std::endl; + writeOutPrimitiveLengths = true; + break; + case (GeoSet::LINE_STRIP): + fw.indent()<<"linestrip "<< geoset.getNumPrims() << std::endl; + writeOutPrimitiveLengths = true; + break; + case (GeoSet::FLAT_LINE_STRIP): + fw.indent()<<"flat_linestrip "<< geoset.getNumPrims() << std::endl; + writeOutPrimitiveLengths = true; + break; + case (GeoSet::TRIANGLE_FAN): + fw.indent()<<"tfans "<< geoset.getNumPrims() << std::endl; + writeOutPrimitiveLengths = true; + case (GeoSet::FLAT_TRIANGLE_FAN): + fw.indent()<<"flat_tfans "<< geoset.getNumPrims() << std::endl; + writeOutPrimitiveLengths = true; + break; + case (GeoSet::LINES): + fw.indent()<<"lines "<< geoset.getNumPrims() << std::endl; + writeOutPrimitiveLengths = false; + break; + case (GeoSet::TRIANGLES): + fw.indent()<<"triangles "<< geoset.getNumPrims() << std::endl; + writeOutPrimitiveLengths = false; + break; + case (GeoSet::QUADS): + fw.indent()<<"quads "<< geoset.getNumPrims() << std::endl; + writeOutPrimitiveLengths = false; + break; + case (GeoSet::POINTS) : + fw.indent()<<"points "<< geoset.getNumPrims() << std::endl; + break; + default: + notify(WARN) << "GeoSet::writeLocalData() - unhandled primitive type = "<<(int)geoset.getPrimType()<< std::endl; + } + if (writeOutPrimitiveLengths) + { + writeArray(fw,geoset.getPrimLengths(),geoset.getPrimLengths()+geoset.getNumPrims()); + } + + GeoSet& non_const_geoset = const_cast(geoset); + non_const_geoset.computeNumVerts(); + + if (geoset.getCoords()) + { + // write out _coords. + fw.indent() << "Coords " << geoset.getNumCoords()<< std::endl; + fw.indent() << "{"<< std::endl; + fw.moveIn(); + const Vec3* coords = geoset.getCoords(); + for(i=0;ientry) + { + int index; + if (fr[0].getInt(index)) + { + + if (size>=capacity) + { + int oldCapacity = capacity; + while(capacity<=size) capacity *= 2; + GLushort* oldList = coordIndexList; + coordIndexList = new GLushort[capacity]; + for(int i=0;ientry) + { + int index; + if (fr[0].getInt(index)) + { + + if (size>=capacity) + { + int oldCapacity = capacity; + while(capacity<=size) capacity *= 2; + GLuint* oldList = coordIndexList; + coordIndexList = new GLuint[capacity]; + for(int i=0;i