From bdd04bef604f2fa03d5cbe2940d9ba8ae32e84d7 Mon Sep 17 00:00:00 2001 From: Don BURNS Date: Sun, 13 Mar 2005 01:47:46 +0000 Subject: [PATCH] Added applications directory. Copied (not moved) osgarchive osgconv osgdem osgversion osgviewer into applications directory. Leaving them in the examples directory as well, for now. Made examples optional via the make COMPILE_EXAMPLES=yes option Added static lib and static plugin build support. --- Make/dependencies | 3 + Make/distrules | 13 +- Make/makedefs | 18 +- Make/makedirdefs | 17 +- Make/makerules | 76 +- applications/osgarchive/GNUmakefile | 18 + applications/osgarchive/GNUmakefile.inst | 13 + applications/osgarchive/osgarchive.cpp | 184 +++ applications/osgconv/GNUmakefile | 22 + applications/osgconv/GNUmakefile.inst | 21 + applications/osgconv/GeoSet.cpp | 1178 +++++++++++++++++ applications/osgconv/GeoSet.h | 414 ++++++ applications/osgconv/IO_GeoSet.cpp | 1097 +++++++++++++++ applications/osgconv/OrientationConverter.cpp | 69 + applications/osgconv/OrientationConverter.h | 30 + applications/osgconv/osgconv.cpp | 622 +++++++++ applications/osgdem/GNUmakefile | 18 + applications/osgdem/GNUmakefile.inst | 14 + applications/osgdem/osgdem.cpp | 591 +++++++++ applications/osgversion/GNUmakefile | 17 + applications/osgversion/GNUmakefile.inst | 14 + applications/osgversion/osgversion.cpp | 9 + applications/osgviewer/GNUmakefile | 18 + applications/osgviewer/GNUmakefile.inst | 13 + applications/osgviewer/osgviewer.cpp | 122 ++ 25 files changed, 4573 insertions(+), 38 deletions(-) create mode 100644 applications/osgarchive/GNUmakefile create mode 100644 applications/osgarchive/GNUmakefile.inst create mode 100644 applications/osgarchive/osgarchive.cpp create mode 100644 applications/osgconv/GNUmakefile create mode 100644 applications/osgconv/GNUmakefile.inst create mode 100644 applications/osgconv/GeoSet.cpp create mode 100644 applications/osgconv/GeoSet.h create mode 100644 applications/osgconv/IO_GeoSet.cpp create mode 100644 applications/osgconv/OrientationConverter.cpp create mode 100644 applications/osgconv/OrientationConverter.h create mode 100644 applications/osgconv/osgconv.cpp create mode 100644 applications/osgdem/GNUmakefile create mode 100644 applications/osgdem/GNUmakefile.inst create mode 100644 applications/osgdem/osgdem.cpp create mode 100755 applications/osgversion/GNUmakefile create mode 100644 applications/osgversion/GNUmakefile.inst create mode 100644 applications/osgversion/osgversion.cpp create mode 100644 applications/osgviewer/GNUmakefile create mode 100644 applications/osgviewer/GNUmakefile.inst create mode 100644 applications/osgviewer/osgviewer.cpp 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)<