diff --git a/Make/dependencies b/Make/dependencies index f4ca300e3..949d41e65 100644 --- a/Make/dependencies +++ b/Make/dependencies @@ -41,3 +41,6 @@ INVENTOR_INSTALLED ?= no PERFORMER_INSTALLED ?= no DEMETER_INSTALLED ?= no + +COMPILE_EXAMPLES ?= no + diff --git a/Make/distrules b/Make/distrules index f02f36e40..0f597b378 100644 --- a/Make/distrules +++ b/Make/distrules @@ -1,17 +1,6 @@ distribution : - @$(MAKEDIST) \ - $(OS)\ - $(TOPDIR)\ - $(INST_LIBS)\ - $(INST_PLUGINS)\ - $(INST_INCLUDE)\ - $(INST_EXAMPLES)\ - $(INST_SRC)\ - $(INST_EXAMPLE_SRC)\ - $(INST_DOC)\ - $(INST_DATA) + @sh $(MAKEDIST) OpenSceneGraph Make/rpm.header Make/rpm.files - cleandist: @$(MAKECLEANDIST) diff --git a/Make/makedefs b/Make/makedefs index 370239cde..970bcfaff 100644 --- a/Make/makedefs +++ b/Make/makedefs @@ -134,6 +134,8 @@ endif RECURSIVE_TARGETS = \ opt\ debug\ + static\ + staticdebug\ clean\ cleandepend\ cleandependopt\ @@ -150,13 +152,18 @@ RECURSIVE_TARGETS = \ docs\ depend\ +STATICLIB = $(LIB:.$(LIB_EXT)=.a) +STATICPLUGIN = $(PLUGIN:.$(PLUGIN_EXT)=.a) + #### SUN OS Specific definitions ifeq ($(OS),SunOS) - #### if useing g++ on a sun + #### if using g++ on a sun ifeq ($(COMPILER),gnu) C++ = g++ DEPARG = -M + INC += + DEF += -W -Wall -fPIC -fpermissive OPTF = -O2 DBGF = -g -DOSG_COMPILE_UNIT_TESTS SHARED = -shared -fPIC @@ -230,10 +237,10 @@ ifeq ($(OS),IRIX) C++ = CC DEPARG = -M INC += -I${TOPDIR}/include -I/usr/freeware/include - LDFLAGS += -L/usr/local/lib + LDFLAGS += -L/usr/local/lib DEF += -LANG:std -OPT:Olimit=0 \ - -DEBUG:woff=1681 -DEBUG:woff=1682 -DEBUG:woff=3303\ - -MDupdate $(MAKEDEPEND) + -DEBUG:woff=1681 -DEBUG:woff=1682 -DEBUG:woff=3303\ + -MDupdate $(MAKEDEPEND) OPTF = -O2 DBGF = -g -DOSG_COMPILE_UNIT_TESTS SHARED = -shared @@ -322,7 +329,6 @@ ifeq ($(OS),Linux) C++ = $(CXX) endif - DEPARG = -M INC += @@ -346,7 +352,7 @@ ifeq ($(OS),Linux) ifeq ("$(COMPILE_OSG_OP_OT_WITH_SONAMES)","YES") LDFLAGS += -Wl,-soname -Wl,$@.0 endif - + LDFLAGS += `getconf LFS_LDFLAGS` DEF += `getconf LFS_CFLAGS` diff --git a/Make/makedirdefs b/Make/makedirdefs index 3c4730de4..acf9a164d 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -1,7 +1,13 @@ ################################################################ # Directories traversed from the top level -TOP_LEVEL_DIRS = src +TOP_LEVEL_DIRS = \ + src\ + applications + +ifeq ($(COMPILE_EXAMPLES),yes) +TOP_LEVEL_DIRS += examples +endif ################################################################ @@ -26,7 +32,6 @@ endif SRC_DIRS += \ osgPlugins\ osgWrappers\ - ../examples WRAPPER_DIRS = \ osg\ @@ -149,6 +154,14 @@ endif ################################################################ # Directories traversed in the TOPDIR/examples directory +APPLICATION_DIRS = \ + osgarchive\ + osgconv\ + osgdem\ + osgversion\ + osgviewer\ + + EXAMPLE_DIRS = \ osganimate\ osgarchive\ diff --git a/Make/makerules b/Make/makerules index 5a81fb175..cb1b25066 100644 --- a/Make/makerules +++ b/Make/makerules @@ -1,16 +1,26 @@ default: opt -opt: $(EXEC:=.opt)\ +opt: \ + $(EXEC:=.opt)\ $(LIB:=.opt)\ $(WRAPPER:=.opt)\ $(PLUGIN:=.opt)\ -debug: $(EXEC:=.dbg)\ +debug: \ + $(EXEC:=.dbg)\ $(LIB:=.dbg)\ $(WRAPPER:=.dbg)\ $(PLUGIN:=.dbg)\ +static:\ + $(LIB:.$(LIB_EXT)=.static)\ + $(PLUGIN:.$(PLUGIN_EXT)=.static)\ + +staticdebug:\ + $(LIB:.$(LIB_EXT)=.staticdbg)\ + $(PLUGIN:.$(LIB_EXT)=.staticdbg)\ + cleandepend: cleandependopt cleandependdbg cleandependopt: @@ -73,18 +83,26 @@ $(LIB): $(OBJS) $(WRAPPER) $(PLUGIN): $(OBJS) $(C++) $(LDFLAGS) -bundle $(OBJS) $(LIBS) -o $@ +$(PLUGIN): $(OBJS) + $(C++) $(LDFLAGS) -bundle $(OBJS) $(LIBS) -o $@ + else -ifeq ($(OS),HP-UX) + ifeq ($(OS),HP-UX) # we need to explicitly tell the linker the library name - else it will # include paths like ../../../libosg.sl into executables $(LIB) $(PLUGIN) ${WRAPPER} : $(OBJS) $(C++) $(LDFLAGS) $(SHARED) $(OBJS) $(LIBS) -Wl,+h -Wl,$@ -o $@ -else + + else + $(LIB) $(PLUGIN) ${WRAPPER} : $(OBJS) $(C++) $(LDFLAGS) $(SHARED) $(OBJS) $(LIBS) -o $@ -endif # not HP-UX +$(STATICLIB) $(STATICPLUGIN): $(OBJS) + ar rv $@ $? + + endif # not HP-UX endif # not Darwin $(EXEC:=.dbg) : @@ -103,6 +121,14 @@ $(LIB:=.dbg) : MAKEDEPEND=Makedepend $(LIB) @$(MAKE) LNSRC=$(DEBUGDIR)/$(LIB) LNDEST=$(LIBINST)/$(LIB) __link +$(LIB:.$(LIB_EXT)=.staticdbg) : + @[ -d $(DEBUGDIR) ] || mkdir $(DEBUGDIR) + @cd $(DEBUGDIR);\ + $(MAKE) -f ../GNUmakefile "DOF=$(DBGF)" TOPDIR=../${TOPDIR} \ + THISDIR=../$(THISDIR)\ + MAKEDEPEND=Makedepend $(STATICLIB) + @$(MAKE) LNSRC=$(DEBUGDIR)/$(STATICLIB) LNDEST=$(LIBINST)/$(OS)$(ARCH)/$(STATICLIB) __link + $(WRAPPER:=.dbg) : @[ -d $(DEBUGDIR) ] || mkdir $(DEBUGDIR) @cd $(DEBUGDIR); \ @@ -119,6 +145,14 @@ $(PLUGIN:=.dbg) : MAKEDEPEND=Makedepend $(PLUGIN) @$(MAKE) LNSRC=$(DEBUGDIR)/$(PLUGIN) LNDEST=$(PLUGININST)/$(PLUGIN) __link +$(PLUGIN:.$(PLUGIN_EXT)=.staticdbg) : + @[ -d $(DEBUGDIR) ] || mkdir -p $(DEBUGDIR) + @cd $(DEBUGDIR); \ + $(MAKE) -f ../GNUmakefile "DOF=$(DBGF)" TOPDIR=../${TOPDIR} \ + THISDIR=../$(THISDIR)\ + MAKEDEPEND=Makedepend STATICPLUGIN=$(PLUGIN:.$(PLUGIN_EXT)=.a) $(STATICPLUGIN) + @$(MAKE) LNSRC=$(DEBUGDIR)/$(STATICPLUGIN) LNDEST=$(PLUGININST)/$(STATICPLUGIN) __link + $(EXEC:=.opt) : @[ -d $(OPTDIR) ] || mkdir $(OPTDIR) @cd $(OPTDIR); \ @@ -136,6 +170,15 @@ $(LIB:=.opt) : MAKEDEPEND=Makedepend $(LIB) @$(MAKE) LNSRC=$(OPTDIR)/$(LIB) LNDEST=$(LIBINST)/$(LIB) __link +$(LIB:.$(LIB_EXT)=.static) : + [ -d $(OPTDIR) ] || mkdir $(OPTDIR) + cd $(OPTDIR);\ + $(MAKE) -f ../GNUmakefile DOF=$(OPTF) TOPDIR=../${TOPDIR} \ + THISDIR=../$(THISDIR)\ + MAKEDEPEND=Makedepend $(STATICLIB) + @$(MAKE) LNSRC=$(OPTDIR)/$(STATICLIB) LNDEST=$(LIBINST)/$(OS)$(ARCH)/$(STATICLIB) __link + + $(WRAPPER:=.opt) : @[ -d $(OPTDIR) ] || mkdir -p $(OPTDIR) @cd $(OPTDIR); \ @@ -152,6 +195,16 @@ $(PLUGIN:=.opt) : MAKEDEPEND=Makedepend $(PLUGIN) @$(MAKE) LNSRC=$(OPTDIR)/$(PLUGIN) LNDEST=$(PLUGININST)/$(PLUGIN) __link +$(PLUGIN:.$(PLUGIN_EXT)=.static) : + @[ -d $(OPTDIR) ] || mkdir -p $(OPTDIR) + @cd $(OPTDIR); \ + $(MAKE) -f ../GNUmakefile DOF=$(OPTF) TOPDIR=../${TOPDIR} \ + THISDIR=../$(THISDIR)\ + MAKEDEPEND=Makedepend STATICPLUGIN=$(PLUGIN:.$(PLUGIN_EXT)=.a) $(STATICPLUGIN) + @$(MAKE) LNSRC=$(OPTDIR)/$(STATICPLUGIN) LNDEST=$(PLUGININST)/$(STATICPLUGIN) __link + + + ## Revamped method for making Makedepend files ## Under this method, Makedepend simply includes ## all dependency files which are built for each @@ -179,18 +232,6 @@ else endif -ifeq (0,1) ##### OLD WAY : Keep until we've proven that this doesn't trip up - ##### on other OS's. - Makedepend : $(CXXFILES) $(CFILES) - ifeq ($(OS),IRIX) - touch $@ - else - $(C++) $(INC) $(DEPARG) $^ > $(MAKEDEPEND) - endif - -endif - - .SUFFIXES: .cpp .o .cpp.o: $(C++) $(CXXFLAGS) -c $< @@ -198,7 +239,6 @@ endif depend : $(MAKEDEPEND) __link : - @echo Calling dolink.sh wit LNSRC = $(LNSRC) and LNDEST = $(LNDEST) @sh $(TOPDIR)/Make/dolink.sh $(TOPDIR) $(LNSRC) $(LNDEST) "$(LINK)" __instfiles : diff --git a/applications/osgarchive/GNUmakefile b/applications/osgarchive/GNUmakefile new file mode 100644 index 000000000..fdeb1bb21 --- /dev/null +++ b/applications/osgarchive/GNUmakefile @@ -0,0 +1,18 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgarchive.cpp\ + +LIBS += -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgarchive + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules + diff --git a/applications/osgarchive/GNUmakefile.inst b/applications/osgarchive/GNUmakefile.inst new file mode 100644 index 000000000..7ea6387c3 --- /dev/null +++ b/applications/osgarchive/GNUmakefile.inst @@ -0,0 +1,13 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgarchive.cpp\ + +LIBS += -losgDB losgUtil -losg $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgarchive + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules diff --git a/applications/osgarchive/osgarchive.cpp b/applications/osgarchive/osgarchive.cpp new file mode 100644 index 000000000..ab4d6ef73 --- /dev/null +++ b/applications/osgarchive/osgarchive.cpp @@ -0,0 +1,184 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This application is open source and may be redistributed and/or modified + * freely and without restriction, both in commericial and non commericial applications, + * as long as this copyright notice is maintained. + * + * This application 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. +*/ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + + +int main( int argc, char **argv ) +{ + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + // set up the usage document, in case we need to print out how to use this program. + arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName()); + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + arguments.getApplicationUsage()->write(std::cout); + return 1; + } + + std::string archiveFilename; + while (arguments.read("-a",archiveFilename) || arguments.read("--archive",archiveFilename)) + { + } + + bool insert = false; + while (arguments.read("-i") || arguments.read("--insert")) + { + insert = true; + } + + bool extract = false; + while (arguments.read("-e") || arguments.read("--extract")) + { + extract = true; + } + + bool list = false; + while (arguments.read("-l") || arguments.read("--list")) + { + list = true; + } + + typedef std::vector FileNameList; + FileNameList files; + for(int pos=1;pos archive; + + if (insert) + { + archive = osgDB::openArchive(archiveFilename, osgDB::Archive::WRITE); + + if (archive.valid()) + { + for (FileNameList::iterator itr=files.begin(); + itr!=files.end(); + ++itr) + { + std::cout<<"reading "<<*itr< obj = osgDB::readObjectFile(*itr); + if (obj.valid()) + { + std::cout<<" write to archive "<<*itr<writeObject(*obj, *itr); + } + } + } + } + else + { + archive = osgDB::openArchive(archiveFilename, osgDB::Archive::READ); + + if (extract && archive.valid()) + { + for (FileNameList::iterator itr=files.begin(); + itr!=files.end(); + ++itr) + { + osg::Timer_t start = osg::Timer::instance()->tick(); + osgDB::ReaderWriter::ReadResult result = archive->readObject(*itr); + osg::ref_ptr obj = result.getObject(); + std::cout<<"readObejct time = "<delta_m(start,osg::Timer::instance()->tick())<getFileNames(fileNames)) + { + for(osgDB::Archive::FileNameList::const_iterator itr=fileNames.begin(); + itr!=fileNames.end(); + ++itr) + { + std::cout<<" "<<*itr<getMasterFileName()< +#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/applications/osgconv/GeoSet.h b/applications/osgconv/GeoSet.h new file mode 100644 index 000000000..aabda2243 --- /dev/null +++ b/applications/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 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 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 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/applications/osgconv/IO_GeoSet.cpp b/applications/osgconv/IO_GeoSet.cpp new file mode 100644 index 000000000..29b15924e --- /dev/null +++ b/applications/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 + +#include +#include + +#include "OrientationConverter.h" + +using namespace osg; + +OrientationConverter::OrientationConverter( void ) +{ + R.makeIdentity(); + T.makeIdentity(); + _trans_set = false; + S.makeIdentity(); +} + +void OrientationConverter::setRotation( const Vec3 &from, const Vec3 &to ) +{ + R = Matrix::rotate( from, to ); +} + +void OrientationConverter::setRotation( float degrees, const Vec3 &axis ) +{ + R = Matrix::rotate( osg::DegreesToRadians(degrees), axis ); +} + +void OrientationConverter::setTranslation( const Vec3 &trans ) +{ + T = Matrix::translate(trans); + _trans_set = true; +} + +void OrientationConverter::setScale( const Vec3 &scale ) +{ + S = Matrix::scale(scale); +} + + +Node* OrientationConverter::convert( Node *node ) +{ + // Order of operations here is : + // 1. Translate to world origin (0,0,0) + // 2. Rotate to new orientation + // 3. Scale in new orientation coordinates + // 4. If an absolute translation was specified then + // - translate to absolute translation in world coordinates + // else + // - translate back to model's original origin. + BoundingSphere bs = node->getBound(); + Matrix C = Matrix::translate( -bs.center() ); + if( _trans_set == false ) + T = Matrix::translate( bs.center() ); + + osg::Group* root = new osg::Group; + osg::MatrixTransform* transform = new osg::MatrixTransform; + + transform->setDataVariance(osg::Object::STATIC); + transform->setMatrix( C * R * S * T ); + + root->addChild(transform); + transform->addChild(node); + + osgUtil::Optimizer::FlattenStaticTransformsVisitor fstv; + root->accept(fstv); + fstv.removeTransforms(root); + + return root->getChild(0); +} diff --git a/applications/osgconv/OrientationConverter.h b/applications/osgconv/OrientationConverter.h new file mode 100644 index 000000000..1f9923541 --- /dev/null +++ b/applications/osgconv/OrientationConverter.h @@ -0,0 +1,30 @@ +#ifndef _ORIENTATION_CONVERTER_H +#define _ORIENTATION_CONVERTER_H + +#include +#include +#include +#include + +class OrientationConverter { + public : + OrientationConverter(void); + void setRotation( const osg::Vec3 &from, + const osg::Vec3 &to ); + void setRotation( float degrees, const osg::Vec3 &axis ); + void setTranslation( const osg::Vec3 &trans); + void setScale( const osg::Vec3 &trans); + + /** return the root of the updated subgraph as the subgraph + * the node passed in my flatten during optimization.*/ + osg::Node* convert( osg::Node* node ); + + private : + OrientationConverter( const OrientationConverter& ) {} + OrientationConverter& operator = (const OrientationConverter& ) { return *this; } + + osg::Matrix R, T, S; + bool _trans_set; + +}; +#endif diff --git a/applications/osgconv/osgconv.cpp b/applications/osgconv/osgconv.cpp new file mode 100644 index 000000000..0cdd2b793 --- /dev/null +++ b/applications/osgconv/osgconv.cpp @@ -0,0 +1,622 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include "OrientationConverter.h" +#include "GeoSet.h" + +typedef std::vector FileNameList; + + +//////////////////////////////////////////////////////////////////////////// +// Convert GeoSet To Geometry Visitor. +//////////////////////////////////////////////////////////////////////////// + +/** ConvertGeoSetsToGeometryVisitor all the old GeoSet Drawables to the new Geometry Drawables.*/ +class ConvertGeoSetsToGeometryVisitor : public osg::NodeVisitor +{ +public: + + ConvertGeoSetsToGeometryVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + + virtual void apply(osg::Geode& geode) + { + for(unsigned int i=0;i(geode.getDrawable(i)); + if (geoset) + { + osg::Geometry* geom = geoset->convertToGeometry(); + if (geom) + { + osg::notify(osg::NOTICE)<<"Successfully converted GeoSet to Geometry"<setWindowRectangle(0,0,1,1); + rs->useBorder(false); + rs->useConfigEventThread(false); + rs->realize(); + std::cout<<"Realized window"< rs; +}; + +class CompressTexturesVisitor : public osg::NodeVisitor +{ +public: + + CompressTexturesVisitor(osg::Texture::InternalFormatMode internalFormatMode): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _internalFormatMode(internalFormatMode) {} + + virtual void apply(osg::Node& node) + { + if (node.getStateSet()) apply(*node.getStateSet()); + traverse(node); + } + + virtual void apply(osg::Geode& node) + { + if (node.getStateSet()) apply(*node.getStateSet()); + + for(unsigned int i=0;igetStateSet()) apply(*drawable->getStateSet()); + } + + traverse(node); + } + + virtual void apply(osg::StateSet& stateset) + { + // search for the existance of any texture object attributes + for(unsigned int i=0;i(stateset.getTextureAttribute(i,osg::StateAttribute::TEXTURE)); + if (texture) + { + _textureSet.insert(texture); + } + } + } + + void compress() + { + GraphicsContext context; + + osg::ref_ptr state = new osg::State; + + for(TextureSet::iterator itr=_textureSet.begin(); + itr!=_textureSet.end(); + ++itr) + { + osg::Texture* texture = const_cast(itr->get()); + + osg::Texture2D* texture2D = dynamic_cast(texture); + osg::Texture3D* texture3D = dynamic_cast(texture); + + osg::Image* image = texture2D ? texture2D->getImage() : texture3D ? texture3D->getImage() : 0; + if (image && + (image->getPixelFormat()==GL_RGB || image->getPixelFormat()==GL_RGBA) && + (image->s()>=32 && image->t()>=32)) + { + texture->setInternalFormatMode(_internalFormatMode); + + // get OpenGL driver to create texture from image. + texture->apply(*state); + + image->readImageFromCurrentTexture(0,true); + + texture->setInternalFormatMode(osg::Texture::USE_IMAGE_DATA_FORMAT); + } + } + } + + typedef std::set< osg::ref_ptr > TextureSet; + TextureSet _textureSet; + osg::Texture::InternalFormatMode _internalFormatMode; + +}; + + +class FixTransparencyVisitor : public osg::NodeVisitor +{ +public: + + enum FixTransparencyMode + { + NO_TRANSPARANCY_FIXING, + MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE, + MAKE_ALL_STATESET_OPAQUE, + }; + + FixTransparencyVisitor(FixTransparencyMode mode=MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _numTransparent(0), + _numOpaque(0), + _numTransparentMadeOpaque(0), + _mode(mode) + { + std::cout<<"Running FixTransparencyVisitor..."<getStateSet()) isTransparent(*drawable->getStateSet()); + } + + traverse(node); + } + + virtual bool isTransparent(osg::StateSet& stateset) + { + bool hasTranslucentTexture = false; + bool hasBlendFunc = dynamic_cast(stateset.getAttribute(osg::StateAttribute::BLENDFUNC))!=0; + bool hasTransparentRenderingHint = stateset.getRenderingHint()==osg::StateSet::TRANSPARENT_BIN; + bool hasDepthSortBin = (stateset.getRenderBinMode()==osg::StateSet::USE_RENDERBIN_DETAILS)?(stateset.getBinName()=="DepthSortedBin"):false; + bool hasTexture = false; + + + // search for the existance of any texture object attributes + for(unsigned int i=0;i(stateset.getTextureAttribute(i,osg::StateAttribute::TEXTURE)); + if (texture) + { + hasTexture = true; + for (unsigned int im=0;imgetNumImages();++im) + { + osg::Image* image = texture->getImage(im); + if (image->isImageTranslucent()) hasTranslucentTexture = true; + } + } + } + + if (hasTranslucentTexture || hasBlendFunc || hasTransparentRenderingHint || hasDepthSortBin) + { + ++_numTransparent; + + bool makeNonTransparent = false; + + switch(_mode) + { + case(MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE): + if (hasTexture && !hasTranslucentTexture) + { + makeNonTransparent = true; + } + break; + case(MAKE_ALL_STATESET_OPAQUE): + makeNonTransparent = true; + break; + default: + makeNonTransparent = false; + break; + } + + if (makeNonTransparent) + { + stateset.removeAttribute(osg::StateAttribute::BLENDFUNC); + stateset.removeMode(GL_BLEND); + stateset.setRenderingHint(osg::StateSet::DEFAULT_BIN); + ++_numTransparentMadeOpaque; + } + + + return true; + } + else + { + ++_numOpaque; + return false; + } + } + + unsigned int _numTransparent; + unsigned int _numOpaque; + unsigned int _numTransparentMadeOpaque; + FixTransparencyMode _mode; +}; + +class PruneStateSetVisitor : public osg::NodeVisitor +{ +public: + + PruneStateSetVisitor(): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _numStateSetRemoved(0) + { + std::cout<<"Running PruneStateSet..."<getStateSet()) + { + drawable->setStateSet(0); + ++_numStateSetRemoved; + } + } + + traverse(node); + } + + unsigned int _numStateSetRemoved; +}; + + + +static void usage( const char *prog, const char *msg ) +{ + if (msg) + { + osg::notify(osg::NOTICE)<< std::endl; + osg::notify(osg::NOTICE) << msg << std::endl; + } + osg::notify(osg::NOTICE)<< std::endl; + osg::notify(osg::NOTICE)<<"usage:"<< std::endl; + osg::notify(osg::NOTICE)<<" " << prog << " [options] infile1 [infile2 ...] outfile"<< std::endl; + osg::notify(osg::NOTICE)<< std::endl; + osg::notify(osg::NOTICE)<<"options:"<< std::endl; + osg::notify(osg::NOTICE)<<" -O option - ReaderWriter option"<< std::endl; + osg::notify(osg::NOTICE)<< std::endl; + osg::notify(osg::NOTICE)<<" --compressed - Enable the usage of compressed textures,"<< std::endl; + osg::notify(osg::NOTICE)<<" defaults to OpenGL ARB compressed textures."<< std::endl; + osg::notify(osg::NOTICE)<<" --compressed-arb - Enable the usage of OpenGL ARB compressed textures"<< std::endl; + osg::notify(osg::NOTICE)<<" --compressed-dxt1 - Enable the usage of S3TC DXT1 compressed textures"<< std::endl; + osg::notify(osg::NOTICE)<<" --compressed-dxt3 - Enable the usage of S3TC DXT3 compressed textures"<< std::endl; + osg::notify(osg::NOTICE)<<" --compressed-dxt5 - Enable the usage of S3TC DXT5 compressed textures"<< std::endl; + osg::notify(osg::NOTICE)<< std::endl; + osg::notify(osg::NOTICE)<<" --fix-transparency - fix stateset which are curerntly declared as transprent,"<< std::endl; + osg::notify(osg::NOTICE)<<" but should be opaque. Defaults to using the "<< std::endl; + osg::notify(osg::NOTICE)<<" fixTranspancyMode MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE."<< std::endl; + osg::notify(osg::NOTICE)<<" --fix-transparency-mode - fix stateset which are curerntly declared as"<< std::endl; + osg::notify(osg::NOTICE)<<" transprent but should be opaque. The mode_string determines"<< std::endl; + osg::notify(osg::NOTICE)<<" algorithm is used to fix the transparency, options are: "<< std::endl; + osg::notify(osg::NOTICE)<<" MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE,"<setApplicationName(arguments.getApplicationName()); + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + usage( arguments.getApplicationName().c_str(), 0 ); + //arguments.getApplicationUsage()->write(std::cout); + return 1; + } + + + if (arguments.argc()<=1) + { + arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); + return 1; + } + + FileNameList fileNames; + OrientationConverter oc; + bool do_convert = false; + + std::string str; + while (arguments.read("-O",str)) + { + osgDB::ReaderWriter::Options* options = new osgDB::ReaderWriter::Options; + options->setOptionString(str); + osgDB::Registry::instance()->setOptions(options); + } + + std::string ext; + while (arguments.read("-e",ext)) + { + std::string libName = osgDB::Registry::instance()->createLibraryNameForExtension(ext); + osgDB::Registry::instance()->loadLibrary(libName); + } + + std::string libName; + while (arguments.read("-l",libName)) + { + osgDB::Registry::instance()->loadLibrary(libName); + } + + while (arguments.read("-o",str)) + { + osg::Vec3 from, to; + if( sscanf( str.c_str(), "%f,%f,%f-%f,%f,%f", + &from[0], &from[1], &from[2], + &to[0], &to[1], &to[2] ) + != 6 ) + { + float degrees; + osg::Vec3 axis; + // Try deg-axis format + if( sscanf( str.c_str(), "%f-%f,%f,%f", + °rees, &axis[0], &axis[1], &axis[2] ) != 4 ) + { + usage( argv[0], "Orientation argument format incorrect." ); + return 1; + } + else + { + oc.setRotation( degrees, axis ); + do_convert = true; + } + } + else + { + oc.setRotation( from, to ); + do_convert = true; + } + } + + while (arguments.read("-s",str)) + { + osg::Vec3 scale(0,0,0); + if( sscanf( str.c_str(), "%f,%f,%f", + &scale[0], &scale[1], &scale[2] ) != 3 ) + { + usage( argv[0], "Scale argument format incorrect." ); + return 1; + } + oc.setScale( scale ); + do_convert = true; + } + + while (arguments.read("-t",str)) + { + osg::Vec3 trans(0,0,0); + if( sscanf( str.c_str(), "%f,%f,%f", + &trans[0], &trans[1], &trans[2] ) != 3 ) + { + usage( argv[0], "Translation argument format incorrect." ); + return 1; + } + oc.setTranslation( trans ); + do_convert = true; + } + + + FixTransparencyVisitor::FixTransparencyMode fixTransparencyMode = FixTransparencyVisitor::NO_TRANSPARANCY_FIXING; + std::string fixString; + while(arguments.read("--fix-transparency")) fixTransparencyMode = FixTransparencyVisitor::MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE; + while(arguments.read("--fix-transparency-mode",fixString)) + { + if (fixString=="MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE") fixTransparencyMode = FixTransparencyVisitor::MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE; + if (fixString=="MAKE_ALL_STATESET_OPAQUE") fixTransparencyMode = FixTransparencyVisitor::MAKE_ALL_STATESET_OPAQUE; + }; + + bool pruneStateSet = false; + while(arguments.read("--prune-StateSet")) pruneStateSet = true; + + osg::Texture::InternalFormatMode internalFormatMode = osg::Texture::USE_IMAGE_DATA_FORMAT; + while(arguments.read("--compressed") || arguments.read("--compressed-arb")) { internalFormatMode = osg::Texture::USE_ARB_COMPRESSION; } + + while(arguments.read("--compressed-dxt1")) { internalFormatMode = osg::Texture::USE_S3TC_DXT1_COMPRESSION; } + while(arguments.read("--compressed-dxt3")) { internalFormatMode = osg::Texture::USE_S3TC_DXT3_COMPRESSION; } + while(arguments.read("--compressed-dxt5")) { internalFormatMode = osg::Texture::USE_S3TC_DXT5_COMPRESSION; } + + // any option left unread are converted into errors to write out later. + arguments.reportRemainingOptionsAsUnrecognized(); + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + return 1; + } + + for(int pos=1;pos1) + { + fileNameOut = fileNames.back(); + fileNames.pop_back(); + } + + osg::ref_ptr root = osgDB::readNodeFiles(fileNames); + + if (pruneStateSet) + { + PruneStateSetVisitor pssv; + root->accept(pssv); + } + + if (fixTransparencyMode != FixTransparencyVisitor::NO_TRANSPARANCY_FIXING) + { + FixTransparencyVisitor atv(fixTransparencyMode); + root->accept(atv); + } + + if ( root.valid() ) + { + // convert the old style GeoSet to Geometry + ConvertGeoSetsToGeometryVisitor cgtg; + if( root.valid() ) root->accept(cgtg); + + // optimize the scene graph, remove rendundent nodes and state etc. + osgUtil::Optimizer optimizer; + optimizer.optimize(root.get()); + + if( do_convert ) + root = oc.convert( root.get() ); + + if (internalFormatMode != osg::Texture::USE_IMAGE_DATA_FORMAT) + { + std::string ext = osgDB::getFileExtension(fileNameOut); + if (ext=="ive") + { + CompressTexturesVisitor ctv(internalFormatMode); + root->accept(ctv); + ctv.compress(); + } + else + { + std::cout<<"Warning: compressing texture only supported when outputing to .ive"< +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include + +class GraphicsContext { + public: + GraphicsContext() + { + rs = new Producer::RenderSurface; + rs->setWindowRectangle(0,0,1,1); + rs->useBorder(false); + rs->useConfigEventThread(false); + rs->realize(); + std::cout<<"Realized window"< rs; +}; + +osg::Matrixd computeGeoTransForRange(double xMin, double xMax, double yMin, double yMax) +{ + osg::Matrixd matrix; + matrix(0,0) = xMax-xMin; + matrix(3,0) = xMin; + + matrix(1,1) = yMax-yMin; + matrix(3,1) = yMin; + + return matrix; +} + + +void ellipsodeTransformTest(double latitude, double longitude, double height) +{ + osg::ref_ptr transform = new osg::EllipsoidModel; + + double X,Y,Z; + double newLat, newLong, newHeight; + + transform->convertLatLongHeightToXYZ(latitude,longitude,height, + X,Y,Z); + + transform->convertXYZToLatLongHeight(X,Y,Z, + newLat,newLong,newHeight); + + std::cout<<"lat = "< dataset) { + + if(filename.empty()) return; + + if(osgDB::fileType(filename) == osgDB::REGULAR_FILE) { + + osgTerrain::DataSet::Source* source = new osgTerrain::DataSet::Source(type, filename); + if (source) + { + if (!currentCS.empty()) + { + std::cout<<"source->setCoordySystem "<setCoordinateSystemPolicy(osgTerrain::DataSet::Source::PREFER_CONFIG_SETTINGS); + source->setCoordinateSystem(currentCS); + } + + if (geoTransformSet) + { + std::cout<<"source->setGeoTransform "<setGeoTransformPolicy(geoTransformScale ? + osgTerrain::DataSet::Source::PREFER_CONFIG_SETTINGS_BUT_SCALE_BY_FILE_RESOLUTION : + osgTerrain::DataSet::Source::PREFER_CONFIG_SETTINGS); + source->setGeoTransform(geoTransform); + } + if (minmaxLevelSet) + { + source->setMinMaxLevel(min_level, max_level); + } + + dataset->addSource(source); + } + } else if (osgDB::fileType(filename) == osgDB::DIRECTORY) { + + osgDB::DirectoryContents dirContents= osgDB::getDirectoryContents(filename); + + // loop through directory contents and call processFile + std::vector::iterator i; + std::string fullfilename; + for(i = dirContents.begin(); i != dirContents.end(); ++i) { + if((*i != ".") && (*i != "..")) { + fullfilename = filename + '/' + *i; + processFile(fullfilename, type, currentCS, + geoTransform, geoTransformSet, geoTransformScale, + minmaxLevelSet, min_level, max_level, + dataset); + } + } + } +} + + +int main( int argc, char **argv ) +{ + + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + // set up the usage document, in case we need to print out how to use this program. + arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName()); + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("-d ","Specify the digital elevation map input file to process"); + arguments.getApplicationUsage()->addCommandLineOption("-t ","Specify the texture map input file to process"); + arguments.getApplicationUsage()->addCommandLineOption("-m ","Specify the 3D database model input file to process"); + arguments.getApplicationUsage()->addCommandLineOption("-a ","Specify the archive to place the generated database"); + arguments.getApplicationUsage()->addCommandLineOption("-o ","Specify the output master file to generate"); + arguments.getApplicationUsage()->addCommandLineOption("-l ","Specify the number of PagedLOD levels to generate"); + arguments.getApplicationUsage()->addCommandLineOption("-e ","Extents of the model to generate"); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + arguments.getApplicationUsage()->addCommandLineOption("--cs ","Set the coordinates system of source imagery, DEM or destination database. The string may be any of the usual GDAL/OGR forms, complete WKT, PROJ.4, EPS"); + arguments.getApplicationUsage()->addCommandLineOption("--wkt ","Set the coordinates system of source imagery, DEM or destination database in WellKownText form."); + arguments.getApplicationUsage()->addCommandLineOption("--wkt-file ","Set the coordinates system of source imagery, DEM or destination database by as file containing WellKownText definition."); + arguments.getApplicationUsage()->addCommandLineOption("--skirt-ratio ","Set the ratio of skirt height to tile size"); + arguments.getApplicationUsage()->addCommandLineOption("--HEIGHT_FIELD","Create a height field database"); + arguments.getApplicationUsage()->addCommandLineOption("--POLYGONAL","Create a height field database"); + arguments.getApplicationUsage()->addCommandLineOption("--LOD","Create a LOD'd database"); + arguments.getApplicationUsage()->addCommandLineOption("--PagedLOD","Create a PagedLOD'd database"); + arguments.getApplicationUsage()->addCommandLineOption("-v","Set the vertical multiplier"); + arguments.getApplicationUsage()->addCommandLineOption("--compressed","Use OpenGL compression on destination imagery"); + arguments.getApplicationUsage()->addCommandLineOption("--RGB-16","Use 16bit RGB destination imagery"); + arguments.getApplicationUsage()->addCommandLineOption("--RGB-24","Use 24bit RGB destination imagery"); + arguments.getApplicationUsage()->addCommandLineOption("--max-visible-distance-of-top-level","Set the maximum visible distance that the top most tile can be viewed at"); + arguments.getApplicationUsage()->addCommandLineOption("--radius-to-max-visible-distance-ratio","Set the maximum visible distance ratio for all tiles apart from the top most tile. The maximum visuble distance is computed from the ratio * tile radius."); + arguments.getApplicationUsage()->addCommandLineOption("--no-mip-mapping","Disable mip mapping of textures"); + arguments.getApplicationUsage()->addCommandLineOption("--mip-mapping-hardware","Use mip mapped textures, and generate the mipmaps in hardware when available."); + arguments.getApplicationUsage()->addCommandLineOption("--mip-mapping-imagery","Use mip mapped textures, and generate the mipmaps in imagery."); + arguments.getApplicationUsage()->addCommandLineOption("--max-anisotropy","Max anisotropy level to use when texturing, defaults to 1.0."); + arguments.getApplicationUsage()->addCommandLineOption("--bluemarble-east",""); + arguments.getApplicationUsage()->addCommandLineOption("--bluemarble-west",""); + arguments.getApplicationUsage()->addCommandLineOption("--whole-globe",""); + arguments.getApplicationUsage()->addCommandLineOption("--geocentric",""); + arguments.getApplicationUsage()->addCommandLineOption("--range",""); + arguments.getApplicationUsage()->addCommandLineOption("--xx",""); + arguments.getApplicationUsage()->addCommandLineOption("--xt",""); + arguments.getApplicationUsage()->addCommandLineOption("--yy",""); + arguments.getApplicationUsage()->addCommandLineOption("--yt",""); + arguments.getApplicationUsage()->addCommandLineOption("--zz",""); + arguments.getApplicationUsage()->addCommandLineOption("--zt",""); + arguments.getApplicationUsage()->addCommandLineOption("--tile-image-size","Set the tile maximum image size"); + arguments.getApplicationUsage()->addCommandLineOption("--tile-terrain-size","Set the tile maximum terrain size"); + arguments.getApplicationUsage()->addCommandLineOption("--comment","Added a comment/description string to the top most node in the dataset"); + + // create DataSet. + osg::ref_ptr dataset = new osgTerrain::DataSet; + + + float x,y,w,h; + while (arguments.read("-e",x,y,w,h)) + { + dataset->setDestinationExtents(osg::BoundingBox(x,y,0.0f,x+w,y+h,0.0f)); + } + + while (arguments.read("--HEIGHT_FIELD")) + { + dataset->setGeometryType(osgTerrain::DataSet::HEIGHT_FIELD); + } + + while (arguments.read("--POLYGONAL")) + { + dataset->setGeometryType(osgTerrain::DataSet::POLYGONAL); + } + + while (arguments.read("--LOD")) + { + dataset->setDatabaseType(osgTerrain::DataSet::LOD_DATABASE); + } + + while (arguments.read("--PagedLOD")) + { + dataset->setDatabaseType(osgTerrain::DataSet::PagedLOD_DATABASE); + } + + while (arguments.read("--compressed")) { dataset->setTextureType(osgTerrain::DataSet::COMPRESSED_TEXTURE); } + while (arguments.read("--RGB_16") || arguments.read("--RGB-16") ) { dataset->setTextureType(osgTerrain::DataSet::RGB_16_BIT); } + while (arguments.read("--RGB_24") || arguments.read("--RGB-24") ) { dataset->setTextureType(osgTerrain::DataSet::RGB_24_BIT); } + + while (arguments.read("--no_mip_mapping") || arguments.read("--no-mip-mapping")) { dataset->setMipMappingMode(osgTerrain::DataSet::NO_MIP_MAPPING); } + while (arguments.read("--mip_mapping_hardware") || arguments.read("--mip-mapping-hardware")) { dataset->setMipMappingMode(osgTerrain::DataSet::MIP_MAPPING_HARDWARE); } + while (arguments.read("--mip_mapping_imagery") || arguments.read("--mip-mapping-imagery")) { dataset->setMipMappingMode(osgTerrain::DataSet::MIP_MAPPING_IMAGERY); } + + float maxAnisotropy; + while (arguments.read("--max_anisotropy",maxAnisotropy) || arguments.read("--max-anisotropy",maxAnisotropy)) + { + dataset->setMaxAnisotropy(maxAnisotropy); + } + + unsigned int image_size; + while (arguments.read("--tile-image-size",image_size)) { dataset->setMaximumTileImageSize(image_size); } + + unsigned int terrain_size; + while (arguments.read("--tile-terrain-size",terrain_size)) { dataset->setMaximumTileTerrainSize(terrain_size); } + + std::string comment; + while (arguments.read("--comment",comment)) { dataset->setCommentString(comment); } + + std::string archiveName; + while (arguments.read("-a",archiveName)) { dataset->setArchiveName(archiveName); } + + dataset->setDestinationTileBaseName("output"); + dataset->setDestinationTileExtension(".ive"); + + + unsigned int numLevels = 10; + while (arguments.read("-l",numLevels)) {} + + float verticalScale; + while (arguments.read("-v",verticalScale)) + { + dataset->setVerticalScale(verticalScale); + } + + float skirtRatio; + while (arguments.read("--skirt-ratio",skirtRatio)) + { + dataset->setSkirtRatio(skirtRatio); + } + + float maxVisibleDistanceOfTopLevel; + while (arguments.read("--max_visible_distance_of_top_level",maxVisibleDistanceOfTopLevel) || + arguments.read("--max-visible-distance-of-top-level",maxVisibleDistanceOfTopLevel) ) + { + dataset->setMaximumVisibleDistanceOfTopLevel(maxVisibleDistanceOfTopLevel); + } + + float radiusToMaxVisibleDistanceRatio; + while (arguments.read("--radius_to_max_visible_distance_ratio",radiusToMaxVisibleDistanceRatio) || + arguments.read("--radius-to-max-visible-distance-ratio",radiusToMaxVisibleDistanceRatio)) + { + dataset->setRadiusToMaxVisibleDistanceRatio(radiusToMaxVisibleDistanceRatio); + } + + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); + return 1; + } + + unsigned int maximumPossibleLevel = 30; + + + // read the input data + + std::string filename; + std::string currentCS; + osg::Matrixd geoTransform; + bool geoTransformSet = false; + bool geoTransformScale = false; + double xMin, xMax, yMin, yMax; + bool minmaxLevelSet = false; + unsigned int min_level=0, max_level=maximumPossibleLevel; + + int pos = 1; + while(pos> line; + currentCS += line; + } + std::cout<<"--wkt-file "<setConvertFromGeographicToGeocentric(true); + std::cout<<"--geocentric "<setConvertFromGeographicToGeocentric(true); + std::cout<<"--bluemarble-west"<setConvertFromGeographicToGeocentric(true); + std::cout<<"--bluemarble-west "<setConvertFromGeographicToGeocentric(true); + std::cout<<"--whole-globe "<setDestinationTileBaseName(base); + dataset->setDestinationTileExtension(extension); + + if (!currentCS.empty()) dataset->setDestinationCoordinateSystem(currentCS); + + minmaxLevelSet = false; + min_level=0; max_level=maximumPossibleLevel; + + currentCS = ""; + geoTransformSet = false; + geoTransformScale = false; + geoTransform.makeIdentity(); + + } + else + { + // if no argument read advance to next argument. + ++pos; + } + } + + // any option left unread are converted into errors to write out later. + arguments.reportRemainingOptionsAsUnrecognized(); + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + return 1; + } + + // generate the database + { + GraphicsContext context; + + dataset->loadSources(); + + dataset->createDestination((unsigned int)numLevels); + + dataset->writeDestination(); + } + + return 0; +} + diff --git a/applications/osgversion/GNUmakefile b/applications/osgversion/GNUmakefile new file mode 100755 index 000000000..d1c2a056c --- /dev/null +++ b/applications/osgversion/GNUmakefile @@ -0,0 +1,17 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgversion.cpp\ + +LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgversion + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules diff --git a/applications/osgversion/GNUmakefile.inst b/applications/osgversion/GNUmakefile.inst new file mode 100644 index 000000000..482d9d332 --- /dev/null +++ b/applications/osgversion/GNUmakefile.inst @@ -0,0 +1,14 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgversion.cpp\ + +LIBS += -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgversion + +INC += $(PRODUCER_INCLUDE_DIR) $(X_INC) +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/applications/osgversion/osgversion.cpp b/applications/osgversion/osgversion.cpp new file mode 100644 index 000000000..43b7d4477 --- /dev/null +++ b/applications/osgversion/osgversion.cpp @@ -0,0 +1,9 @@ +#include +#include + + +int main( int, char **) +{ + printf( "%s\n", osgGetVersion() ); + return 0; +} diff --git a/applications/osgviewer/GNUmakefile b/applications/osgviewer/GNUmakefile new file mode 100644 index 000000000..e6ae462f3 --- /dev/null +++ b/applications/osgviewer/GNUmakefile @@ -0,0 +1,18 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgviewer.cpp\ + +LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgviewer + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules + diff --git a/applications/osgviewer/GNUmakefile.inst b/applications/osgviewer/GNUmakefile.inst new file mode 100644 index 000000000..11834bc69 --- /dev/null +++ b/applications/osgviewer/GNUmakefile.inst @@ -0,0 +1,13 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgviewer.cpp\ + +LIBS += -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgviewer + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules diff --git a/applications/osgviewer/osgviewer.cpp b/applications/osgviewer/osgviewer.cpp new file mode 100644 index 000000000..6b3cfc4a4 --- /dev/null +++ b/applications/osgviewer/osgviewer.cpp @@ -0,0 +1,122 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This application is open source and may be redistributed and/or modified + * freely and without restriction, both in commericial and non commericial applications, + * as long as this copyright notice is maintained. + * + * This application 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. +*/ + +#include +#include +#include +#include + +int main( int argc, char **argv ) +{ + + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + // set up the usage document, in case we need to print out how to use this program. + arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName()); + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("--image ","Load an image and render it on a quad"); + arguments.getApplicationUsage()->addCommandLineOption("--dem ","Load an image/DEM and render it on a HeightField"); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display command line paramters"); + arguments.getApplicationUsage()->addCommandLineOption("--help-env","Display environmental variables available"); + arguments.getApplicationUsage()->addCommandLineOption("--help-keys","Display keyboard & mouse bindings available"); + arguments.getApplicationUsage()->addCommandLineOption("--help-all","Display all command line, env vars and keyboard & mouse bindigs."); + + + // construct the viewer. + osgProducer::Viewer viewer(arguments); + + // set up the value with sensible default event handlers. + viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); + + // get details on keyboard and mouse bindings used by the viewer. + viewer.getUsage(*arguments.getApplicationUsage()); + + // if user request help write it out to cout. + bool helpAll = arguments.read("--help-all"); + unsigned int helpType = ((helpAll || arguments.read("-h") || arguments.read("--help"))? osg::ApplicationUsage::COMMAND_LINE_OPTION : 0 ) | + ((helpAll || arguments.read("--help-env"))? osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE : 0 ) | + ((helpAll || arguments.read("--help-keys"))? osg::ApplicationUsage::KEYBOARD_MOUSE_BINDING : 0 ); + if (helpType) + { + arguments.getApplicationUsage()->write(std::cout, helpType); + return 1; + } + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + return 1; + } + + if (arguments.argc()<=1) + { + arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); + return 1; + } + + osg::Timer_t start_tick = osg::Timer::instance()->tick(); + + // read the scene from the list of file specified commandline args. + osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); + + // if no model has been successfully loaded report failure. + if (!loadedModel) + { + std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl; + return 1; + } + + // any option left unread are converted into errors to write out later. + arguments.reportRemainingOptionsAsUnrecognized(); + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + } + + osg::Timer_t end_tick = osg::Timer::instance()->tick(); + + std::cout << "Time to load = "<delta_s(start_tick,end_tick)<