diff --git a/doc/install.html b/doc/install.html
index 6cd19f6c1..813a923c3 100644
--- a/doc/install.html
+++ b/doc/install.html
@@ -274,66 +274,73 @@ To get full details of make options, type:
-Compiling under MacOS X (instructions written
-by Phil Atkin)
-For anyone who's ever used a Unix box for development it really is so simple
-it's insane.
-You need to have installed the Developer tools from the CD that comes
+Compiling under MacOS X
+For anyone who's ever used a Unix box for development, well, the mac
+is a Unix box. It's very simple to get OpenSceneGraph building
+and running under Mac OS X. The main requirement is that you need to have
+installed the Developer tools from the CD that comes
for free with OS X. This gives you compilers, headers, frameworks - stuff
-like GLUT and Carbon for developers.
-
Everything is done command-line, so you need to get to the underlying
-OS rather than the Aqua gloss. The Mac comes with an app in Applications/Utilities
+like GLUT and Carbon for developers. Get those here:
+
+
+
+Everything is done command-line, so you need to get to a shell before
+proceeding. The Mac comes with an app in Applications/Utilities
called Terminal - open up any Finder window (e.g double-click on your hard
disk icon), click on the Applications icon at the top right of the window,
-then click on the Utilities folder to get access to all the grubby apps
-which give away the real OS roots underneath the shiny paint work. Anyone
-developing will need Terminal so much they should put it in their Dock.
-You do that by grabbing the icon of the app in the Utilities folder and
-dragging it to the bottom of your screen, at which point the other app
-icons in the Dock slide away to leave a gap which when you release the
-mouse button leaves Terminal permanently available, just a mouse click
-away on your desktop. When you start Terminal it brings you up a csh running
-under Darwin (which is the BSD-with-knobs-on that underlies OS X), and
-does a cd to ~ (otherwise /Users/username of whoever you are logged in
-as, as far as the Finder in OS X is concerned you are in the Users/username
-folder of the harddisk the machine booted from).
-
Then you are in Unix land, and it's all very familiar.
-
You will need a .cshrc file with $OSGHOME (as above), and this is a
-filename that the Mac won't let you see from the Finder or in fact generate
-from an app, so I used vi to create that. Then I just went
-
cd $OSGHOME
-
% make clean
-
% make macosx
+then click on the Utilities folder to get access to the Terminal.
+When you start Terminal it brings you up a csh running from your ~/ directory.
+Now, go to your OpenSceneGraph directory, and simply type:
+
+
+make -j2
+
-
And it sounds too good to be true but it is that simple. It's worth
-doing some editing on the Makefiles in the Plugins and Demos directories
-so that it only tries to build a subset, otherwise the developer will have
-to dig out the support projects like jpeg etc. I have only built up to
-now sgv, hangglide, osgcube, osgreflect, osgviews and in the Plugins have
-built osg rgb 3ds and a couple others - will check and get back to you.
-
Tricky bit :
-
Installing the libdl.a is more trouble, as you have to enable the root
-account on the machine, which by default is switched off as the machines
-ship for security reasons. Rather than typing in and risking error through
-paraphrase, here is a link to a site which tells you how to do this -
-
http://www.macos.utah.edu/Documentation/macosx/security/enablerootuser.html
-Or alternately,
-http://www.thinkmacintosh.com/osxfaq.html
+And some time later you'll be rewarded with a lovely set of binaries and
+libraries. The Mac OSX build currently only builds a subset of the total
+functionality in OpenSceneGraph, but a large subset at that. Some of
+the remaining projects are known to build as well, but have external
+dependencies on libraries such as libtiff, libjpg, libpng, etc. and
+so are not included in the default build. However, if you examine
+the file OpenSceneGraph/Make/makedefs you will find which extra
+projects build for the mac, provided you have the external libraries
+required. Details
+on how to install these external libraries are outside the scope of
+this document, but for starting points, see one of:
+
+ Running the examples
+Once you've got OpenSceneGraph built, you're ready to run your examples.
+As with other builds on other platforms, OpenSceneGraph requires
+you to set a few environment variables which describe your installation. These
+environment variables should be full-path, not relative, and a list
+of these for a csh-derived environment follow:
+
+
+
+setenv OSGHOME `pwd`/OpenSceneGraph
+setenv OSGFILEPATH `pwd`/OpenSceneGraph-Data
+setenv OSG_LD_LIBRARY_PATH ${OSGHOME}/lib
+setenv DYLD_LIBRARY_PATH ${OSG_LD_LIBRARY_PATH}
+
+
+
+ Notes
+
+
+- Input Focus: Many OSG examples have keyboard commands, however, when launching
+apps from the Mac Terminal, the focus seems to remain in the Terminal. Option-Clicking on
+the graphics window focuses it as the recipient of events, and allows these keyboard commands
+to then function properly.
+
- Known Bugs:
+
- Installation: No package based version of an OS X installer yet exists.
+
-
One you have a root account enabled, you have to su root you cd
-to the directory which the Fink installer generates, and it puts libdl.a
-and the associated .h files in sensible system places so the compiler just
-finds them.
-
There is one oddball problem - if you rely on Path to find the resulting
-executables, a weird Core Graphics error occurs - so even though I set
-up my path to include $(OSGHOME)/bin, and when I cd to $OSGHOME and type
-for example hangglide, the application starts fine (so it is in the path),
-but at the point it tries to use GLUT to open a window it falls over with
-a CGS error (which is I think Core Graphics System). If you explicitly
-go bin/hangglide it works fine. Weird, it may be an OS X 10.04 issue which
-is gone in 10.1 or it may be a weirdy in the Mac GLUT implementation, but
-forewarned is forearmed.
-
Compiling under Cygwin
To compile, from the OSG root directory, type: make Note, make should automatically
diff --git a/include/osg/Array b/include/osg/Array
index d90f69776..160305682 100644
--- a/include/osg/Array
+++ b/include/osg/Array
@@ -58,9 +58,10 @@ class SG_EXPORT Array : public Object
Type getType() const { return _arrayType; }
- GLint dataSize() const { return _dataSize; }
- GLenum dataType() const { return _dataType; }
- virtual const GLvoid* dataPointer() const = 0;
+ GLint getDataSize() const { return _dataSize; }
+ GLenum getDataType() const { return _dataType; }
+ virtual const GLvoid* getDataPointer() const = 0;
+ virtual unsigned int getNumElements() const = 0;
protected:
@@ -101,7 +102,8 @@ class TemplateArray : public Array, public std::vector
virtual Object* clone(const CopyOp& copyop) const { return osgNew TemplateArray(*this,copyop); }
virtual void accept(ArrayVisitor& av) { av.apply(*this); }
- virtual const GLvoid* dataPointer() const { if (!empty()) return &front(); else return 0; }
+ virtual const GLvoid* getDataPointer() const { if (!empty()) return &front(); else return 0; }
+ virtual unsigned int getNumElements() const { return size(); }
protected:
diff --git a/include/osg/Geode b/include/osg/Geode
index dead4e21d..728f6ea85 100644
--- a/include/osg/Geode
+++ b/include/osg/Geode
@@ -54,13 +54,13 @@ class SG_EXPORT Geode : public Node
/** return the number of geoset's.*/
- inline const int getNumDrawables() const { return _drawables.size(); }
+ inline const unsigned int getNumDrawables() const { return _drawables.size(); }
/** return geoset at position i.*/
- inline Drawable* getDrawable( const int i ) { return _drawables[i].get(); }
+ inline Drawable* getDrawable( const unsigned int i ) { return _drawables[i].get(); }
/** return geoset at position i.*/
- inline const Drawable* getDrawable( const int i ) const { return _drawables[i].get(); }
+ inline const Drawable* getDrawable( const unsigned int i ) const { return _drawables[i].get(); }
/** return true if geoset is contained within Geode.*/
inline const bool containsDrawable(const Drawable* gset) const
diff --git a/include/osg/Geometry b/include/osg/Geometry
index 45cad8ca6..c8d4fbd81 100644
--- a/include/osg/Geometry
+++ b/include/osg/Geometry
@@ -80,6 +80,10 @@ class SG_EXPORT Geometry : public Drawable
void addPrimitive(Primitive* primitive) { if (primitive) _primitives.push_back(primitive); dirtyDisplayList(); }
+ bool verifyBindings() const;
+
+ void computeCorrectBindingsAndArraySizes();
+
/** draw Geometry directly ignoring an OpenGL display list which could be attached.
* This is the internal draw method which does the drawing itself,
diff --git a/include/osg/Primitive b/include/osg/Primitive
index ea52e475b..949b172f5 100644
--- a/include/osg/Primitive
+++ b/include/osg/Primitive
@@ -124,6 +124,8 @@ class Primitive : public Object
virtual void draw() const = 0;
virtual void applyPrimitiveOperation(Drawable::PrimitiveFunctor&) {}
+
+ virtual void offsetIndices(int offset) = 0;
protected:
@@ -174,6 +176,8 @@ class SG_EXPORT DrawArrays : public Primitive
virtual void applyPrimitiveOperation(Drawable::PrimitiveFunctor& functor);
+ virtual void offsetIndices(int offset) { _first += offset; }
+
protected:
GLint _first;
@@ -223,6 +227,8 @@ class SG_EXPORT DrawArrayLengths : public Primitive, public VectorSizei
virtual void applyPrimitiveOperation(Drawable::PrimitiveFunctor& functor);
+ virtual void offsetIndices(int offset) { _first += offset; }
+
protected:
GLint _first;
@@ -261,6 +267,8 @@ class SG_EXPORT DrawElementsUByte : public Primitive, public VectorUByte
virtual void draw() const ;
virtual void applyPrimitiveOperation(Drawable::PrimitiveFunctor& functor);
+
+ virtual void offsetIndices(int offset);
};
@@ -297,6 +305,8 @@ class SG_EXPORT DrawElementsUShort : public Primitive, public VectorUShort
virtual void draw() const;
virtual void applyPrimitiveOperation(Drawable::PrimitiveFunctor& functor);
+
+ virtual void offsetIndices(int offset);
};
class SG_EXPORT DrawElementsUInt : public Primitive, public VectorUInt
@@ -333,6 +343,7 @@ class SG_EXPORT DrawElementsUInt : public Primitive, public VectorUInt
virtual void applyPrimitiveOperation(Drawable::PrimitiveFunctor& functor);
+ virtual void offsetIndices(int offset);
};
// backwards compatibility with first incarnation of DrawElements nameing convention.
diff --git a/include/osgUtil/AppVisitor b/include/osgUtil/AppVisitor
index 070f07dc8..88afec889 100644
--- a/include/osgUtil/AppVisitor
+++ b/include/osgUtil/AppVisitor
@@ -73,7 +73,7 @@ class OSGUTIL_EXPORT AppVisitor : public osg::NodeVisitor
else if (node.getNumChildrenRequiringAppTraversal()>0) traverse(node);
// call the app callbacks on the drawables.
- for(int i=0;igetAppCallback();
if (callback) callback->app(this,node.getDrawable(i));
diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer
index 5e37f5e44..8c342321b 100644
--- a/include/osgUtil/Optimizer
+++ b/include/osgUtil/Optimizer
@@ -7,6 +7,7 @@
#include
#include
+#include
#include
@@ -315,7 +316,22 @@ class OSGUTIL_EXPORT Optimizer
StateSetMap _statesets;
};
+
+
+ class OSGUTIL_EXPORT MergeGeometryVisitor : public osg::NodeVisitor
+ {
+ public:
+ /// default to traversing all children.
+ MergeGeometryVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {}
+
+ virtual void apply(osg::Geode& geode) { mergeGeode(geode); }
+ virtual void apply(osg::Billboard& billboard) { /* don't do anything*/ }
+
+ static bool mergeGeode(osg::Geode& geode);
+ static bool mergeGeometry(osg::Geometry& lhs,osg::Geometry& rhs);
+
+ };
};
}
diff --git a/src/Demos/osgcallback/osgcallback.cpp b/src/Demos/osgcallback/osgcallback.cpp
index 5ffaee7bb..5016bc66d 100644
--- a/src/Demos/osgcallback/osgcallback.cpp
+++ b/src/Demos/osgcallback/osgcallback.cpp
@@ -170,7 +170,7 @@ class InsertCallbacksVisitor : public osg::NodeVisitor
//If you wish to control the culling of drawables
//then use a drawable cullback...
- for(int i=0;isetAppCallback(new DrawableAppCallback());
geode.getDrawable(i)->setCullCallback(new DrawableCullCallback());
diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp
index ad4d1025e..e5b446864 100644
--- a/src/osg/Geometry.cpp
+++ b/src/osg/Geometry.cpp
@@ -1,4 +1,5 @@
#include
+#include
using namespace osg;
@@ -40,12 +41,18 @@ Array* Geometry::getTexCoordArray(unsigned int unit)
else return 0;
}
+const Array* Geometry::getTexCoordArray(unsigned int unit) const
+{
+ if (unit<_texCoordList.size()) return _texCoordList[unit].get();
+ else return 0;
+}
+
void Geometry::drawImmediateMode(State& state)
{
if (!_vertexArray.valid()) return;
// set up the vertex arrays.
- state.setVertexPointer(3,GL_FLOAT,0,_vertexArray->dataPointer());
+ state.setVertexPointer(3,GL_FLOAT,0,_vertexArray->getDataPointer());
// set up texture coordinates.
unsigned int i;
@@ -53,7 +60,7 @@ void Geometry::drawImmediateMode(State& state)
{
Array* array = _texCoordList[i].get();
if (array)
- state.setTexCoordPointer(i,array->dataSize(),array->dataType(),0,array->dataPointer());
+ state.setTexCoordPointer(i,array->getDataSize(),array->getDataType(),0,array->getDataPointer());
else
state.disableTexCoordPointer(i);
}
@@ -96,19 +103,19 @@ void Geometry::drawImmediateMode(State& state)
{
case(Array::UByte4ArrayType):
{
- colorPointer = reinterpret_cast(_colorArray->dataPointer());
+ colorPointer = reinterpret_cast(_colorArray->getDataPointer());
colorStride = 4;
break;
}
case(Array::Vec3ArrayType):
{
- colorPointer = reinterpret_cast(_colorArray->dataPointer());
+ colorPointer = reinterpret_cast(_colorArray->getDataPointer());
colorStride = 12;
break;
}
case(Array::Vec4ArrayType):
{
- colorPointer = reinterpret_cast(_colorArray->dataPointer());
+ colorPointer = reinterpret_cast(_colorArray->getDataPointer());
colorStride = 16;
break;
}
@@ -146,7 +153,7 @@ void Geometry::drawImmediateMode(State& state)
state.disableColorPointer();
break;
case(BIND_PER_VERTEX):
- if (colorPointer) state.setColorPointer(_colorArray->dataSize(),_colorArray->dataType(),0,colorPointer);
+ if (colorPointer) state.setColorPointer(_colorArray->getDataSize(),_colorArray->getDataType(),0,colorPointer);
else state.disableColorPointer();
}
@@ -255,3 +262,148 @@ const bool Geometry::computeBound() const
return _bbox.valid();
}
+bool Geometry::verifyBindings() const
+{
+ switch(_normalBinding)
+ {
+ case(BIND_OFF):
+ if (_normalArray.valid() && _normalArray->getNumElements()>0) return false;
+ break;
+ case(BIND_OVERALL):
+ if (!_normalArray.valid()) return false;
+ if (_normalArray->getNumElements()!=1) return false;
+ break;
+ case(BIND_PER_PRIMITIVE):
+ if (!_normalArray.valid()) return false;
+ if (_normalArray->getNumElements()!=_primitives.size()) return false;
+ break;
+ case(BIND_PER_VERTEX):
+ if (_vertexArray.valid())
+ {
+ if (!_normalArray.valid()) return false;
+ if (_normalArray->getNumElements()!=_vertexArray->getNumElements()) return false;
+ }
+ else if (_normalArray.valid() && _normalArray->getNumElements()>0) return false;
+ break;
+ }
+
+ switch(_colorBinding)
+ {
+ case(BIND_OFF):
+ if (_colorArray.valid() && _colorArray->getNumElements()>0) return false;
+ break;
+ case(BIND_OVERALL):
+ if (!_colorArray.valid()) return false;
+ if (_colorArray->getNumElements()!=1) return false;
+ break;
+ case(BIND_PER_PRIMITIVE):
+ if (!_colorArray.valid()) return false;
+ if (_colorArray->getNumElements()!=_primitives.size()) return false;
+ break;
+ case(BIND_PER_VERTEX):
+ if (_vertexArray.valid())
+ {
+ if (!_colorArray.valid()) return false;
+ if (_colorArray->getNumElements()!=_vertexArray->getNumElements()) return false;
+ }
+ else if (_colorArray.valid() && _colorArray->getNumElements()>0) return false;
+ break;
+ }
+
+ for(TexCoordArrayList::const_iterator itr=_texCoordList.begin();
+ itr!=_texCoordList.end();
+ ++itr)
+ {
+ const Array* array = itr->get();
+ if (_vertexArray.valid())
+ {
+ if (array && array->getNumElements()!=_vertexArray->getNumElements()) return false;
+ }
+ else if (array && array->getNumElements()>0) return false;
+ }
+
+ return true;
+}
+
+void Geometry::computeCorrectBindingsAndArraySizes()
+{
+ if (verifyBindings()) return;
+
+ if (!_vertexArray.valid() || _vertexArray->empty())
+ {
+ // no vertex array so switch everything off.
+
+ _vertexArray = 0;
+
+ _colorArray = 0;
+ _colorBinding = BIND_OFF;
+
+ _normalArray = 0;
+ _normalBinding = BIND_OFF;
+
+ _texCoordList.clear();
+
+ notify(INFO)<<"Info: remove redundent attribute arrays from empty osg::Geometry"<getNumElements()==0)
+ {
+ _normalArray = 0;
+ _normalBinding = BIND_OFF;
+ }
+ else if (_normalArray->getNumElements()>1)
+ {
+ // trim the array down to 1 element long.
+ _normalArray->erase(_normalArray->begin()+1,_normalArray->end());
+ }
+ break;
+ case(BIND_PER_PRIMITIVE):
+ if (!_normalArray.valid())
+ {
+ _normalBinding = BIND_OFF;
+ }
+ else if (_normalArray->getNumElements()<_primitives.size())
+ {
+ _normalArray = 0;
+ _normalBinding = BIND_OFF;
+ }
+ else if (_normalArray->getNumElements()>_primitives.size())
+ {
+ // trim the array down to size of the number of primitives.
+ _normalArray->erase(_normalArray->begin()+_primitives.size(),_normalArray->end());
+ }
+ break;
+ case(BIND_PER_VERTEX):
+ if (!_normalArray.valid())
+ {
+ _normalBinding = BIND_OFF;
+ }
+ else if (_normalArray->getNumElements()<_vertexArray->getNumElements())
+ {
+ _normalArray = 0;
+ _normalBinding = BIND_OFF;
+ }
+ else if (_normalArray->getNumElements()>_vertexArray->getNumElements())
+ {
+ // trim the array down to size of the number of primitives.
+ _normalArray->erase(_normalArray->begin()+_vertexArray->getNumElements(),_normalArray->end());
+ }
+ break;
+ }
+
+ // TODO colours and tex coords.
+
+}
diff --git a/src/osg/Primitive.cpp b/src/osg/Primitive.cpp
index fb5f99dca..2ae37fca6 100644
--- a/src/osg/Primitive.cpp
+++ b/src/osg/Primitive.cpp
@@ -48,6 +48,16 @@ void DrawElementsUByte::applyPrimitiveOperation(Drawable::PrimitiveFunctor& func
if (!empty()) functor.drawElements(_mode,size(),&front());
}
+void DrawElementsUByte::offsetIndices(int offset)
+{
+ for(iterator itr=begin();
+ itr!=end();
+ ++itr)
+ {
+ *itr += offset;
+ }
+}
+
void DrawElementsUShort::draw() const
{
@@ -59,6 +69,15 @@ void DrawElementsUShort::applyPrimitiveOperation(Drawable::PrimitiveFunctor& fun
if (!empty()) functor.drawElements(_mode,size(),&front());
}
+void DrawElementsUShort::offsetIndices(int offset)
+{
+ for(iterator itr=begin();
+ itr!=end();
+ ++itr)
+ {
+ *itr += offset;
+ }
+}
void DrawElementsUInt::draw() const
@@ -70,3 +89,13 @@ void DrawElementsUInt::applyPrimitiveOperation(Drawable::PrimitiveFunctor& funct
{
if (!empty()) functor.drawElements(_mode,size(),&front());
}
+
+void DrawElementsUInt::offsetIndices(int offset)
+{
+ for(iterator itr=begin();
+ itr!=end();
+ ++itr)
+ {
+ *itr += offset;
+ }
+}
diff --git a/src/osgPlugins/flt/GeoSetBuilder.cpp b/src/osgPlugins/flt/GeoSetBuilder.cpp
index 03e94533b..12181dd35 100644
--- a/src/osgPlugins/flt/GeoSetBuilder.cpp
+++ b/src/osgPlugins/flt/GeoSetBuilder.cpp
@@ -49,39 +49,39 @@ void DynGeoSet::append(DynGeoSet* source)
{
APPEND_DynGeoSet_List(_primLenList)
APPEND_DynGeoSet_List(_coordList)
- APPEND_DynGeoSet_List(_normalList)
- APPEND_DynGeoSet_List(_colorList)
- APPEND_DynGeoSet_List(_tcoordList)
+ if (_normal_binding==osg::Geometry::BIND_PER_VERTEX || _normal_binding==osg::Geometry::BIND_PER_PRIMITIVE) APPEND_DynGeoSet_List(_normalList)
+ if (_color_binding==osg::Geometry::BIND_PER_VERTEX || _color_binding==osg::Geometry::BIND_PER_PRIMITIVE) APPEND_DynGeoSet_List(_colorList)
+ if (_texture_binding==osg::Geometry::BIND_PER_VERTEX || _texture_binding==osg::Geometry::BIND_PER_PRIMITIVE) APPEND_DynGeoSet_List(_tcoordList)
}
#define VERIFY_DynGeoSet_Binding(binding,list) \
switch (binding) \
{ \
- case osg::GeoSet::BIND_PERVERTEX: \
+ case osg::Geometry::BIND_PER_VERTEX: \
if (list.size() < _coordList.size()) { \
- binding = osg::GeoSet::BIND_OFF; \
+ binding = osg::Geometry::BIND_OFF; \
list.clear(); } \
break; \
- case osg::GeoSet::BIND_PERPRIM: \
+ case osg::Geometry::BIND_PER_PRIMITIVE: \
if (list.size() < _primLenList.size()) { \
- binding = osg::GeoSet::BIND_OFF; \
+ binding = osg::Geometry::BIND_OFF; \
list.clear(); } \
break; \
- case osg::GeoSet::BIND_OVERALL: \
+ case osg::Geometry::BIND_OVERALL: \
if (list.size() < 1) { \
- binding = osg::GeoSet::BIND_OFF; \
+ binding = osg::Geometry::BIND_OFF; \
list.clear(); } \
break; \
default: \
break; \
}
-DynGeoSet::DynGeoSet():osg::GeoSet()
+const osg::Primitive::Mode NO_PRIMITIVE_TYPE = (osg::Primitive::Mode)0xffff;
+
+DynGeoSet::DynGeoSet()
{
- // disable the attribute delete functor since the vectors contained in DynGeoSet
- // will delete the memory for us.
- _adf = NULL;
+ _primtype=NO_PRIMITIVE_TYPE;
}
void DynGeoSet::setBinding()
@@ -98,38 +98,13 @@ void DynGeoSet::setBinding()
osg::StateSet* stateset = getStateSet();
if (stateset)
{
- if (_normal_binding == osg::GeoSet::BIND_OFF)
+ if (_normal_binding == osg::Geometry::BIND_OFF)
stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
}
}
-bool DynGeoSet::setLists()
-{
- if ((_primLenList.size() > 0) && (_coordList.size() > 0))
- {
- setPrimLengths(&_primLenList.front());
- setCoords(&_coordList.front());
-
- if ((_normalList.size() > 0)
- && (getNormalBinding() != osg::GeoSet::BIND_OFF))
- setNormals(&_normalList.front());
-
- if ((_colorList.size() > 0)
- && (getColorBinding() != osg::GeoSet::BIND_OFF))
- setColors(&_colorList.front());
-
- if ((_tcoordList.size() > 0)
- && (getTextureBinding() != osg::GeoSet::BIND_OFF))
- setTextureCoords(&_tcoordList.front());
-
- return true;
- }
-
- return false;
-}
-
void DynGeoSet::addToGeometry(osg::Geometry* geom)
{
int indexBase = 0;
@@ -153,7 +128,7 @@ void DynGeoSet::addToGeometry(osg::Geometry* geom)
osg::Vec3Array* normals = geom->getNormalArray();
if (normals)
{
- if (_normal_binding==osg::GeoSet::BIND_PERVERTEX || _normal_binding==osg::GeoSet::BIND_PERPRIM)
+ if (_normal_binding==osg::Geometry::BIND_PER_VERTEX || _normal_binding==osg::Geometry::BIND_PER_PRIMITIVE)
normals->insert(normals->end(),_normalList.begin(),_normalList.end());
}
else
@@ -163,9 +138,9 @@ void DynGeoSet::addToGeometry(osg::Geometry* geom)
switch(_normal_binding)
{
- case(osg::GeoSet::BIND_OVERALL):geom->setNormalBinding(osg::Geometry::BIND_OVERALL);break;
- case(osg::GeoSet::BIND_PERVERTEX):geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);break;
- case(osg::GeoSet::BIND_PERPRIM):geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);break;
+ case(osg::Geometry::BIND_OVERALL):geom->setNormalBinding(osg::Geometry::BIND_OVERALL);break;
+ case(osg::Geometry::BIND_PER_VERTEX):geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);break;
+ case(osg::Geometry::BIND_PER_PRIMITIVE):geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);break;
default:geom->setNormalBinding(osg::Geometry::BIND_OFF); break;
}
}
@@ -190,7 +165,7 @@ void DynGeoSet::addToGeometry(osg::Geometry* geom)
osg::Vec4Array* colors = dynamic_cast(geom->getColorArray());
if (colors)
{
- if (_color_binding==osg::GeoSet::BIND_PERVERTEX || _color_binding==osg::GeoSet::BIND_PERPRIM)
+ if (_color_binding==osg::Geometry::BIND_PER_VERTEX || _color_binding==osg::Geometry::BIND_PER_PRIMITIVE)
colors->insert(colors->end(),_colorList.begin(),_colorList.end());
}
else
@@ -200,29 +175,17 @@ void DynGeoSet::addToGeometry(osg::Geometry* geom)
switch(_color_binding)
{
- case(osg::GeoSet::BIND_OVERALL):geom->setColorBinding(osg::Geometry::BIND_OVERALL);break;
- case(osg::GeoSet::BIND_PERVERTEX):geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);break;
- case(osg::GeoSet::BIND_PERPRIM):geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE);break;
+ case(osg::Geometry::BIND_OVERALL):geom->setColorBinding(osg::Geometry::BIND_OVERALL);break;
+ case(osg::Geometry::BIND_PER_VERTEX):geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);break;
+ case(osg::Geometry::BIND_PER_PRIMITIVE):geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE);break;
default:geom->setColorBinding(osg::Geometry::BIND_OFF); break;
}
}
- }
-
- osg::Primitive::Mode mode = osg::Primitive::POLYGON;
- switch(_primtype)
- {
- case(osg::GeoSet::POINTS):mode = osg::Primitive::POINTS; break;
- case(osg::GeoSet::LINES):mode = osg::Primitive::LINES; break;
- case(osg::GeoSet::TRIANGLES):mode = osg::Primitive::TRIANGLES; break;
- case(osg::GeoSet::QUADS):mode = osg::Primitive::QUADS; break;
- case(osg::GeoSet::POLYGON):mode = osg::Primitive::POLYGON; break;
- default: mode = osg::Primitive::POLYGON;
- }
+ }
-
- if (mode!=osg::Primitive::POLYGON)
+ if (_primtype!=osg::Primitive::POLYGON)
{
- geom->addPrimitive(new osg::DrawArrays(mode,indexBase,_coordList.size()));
+ geom->addPrimitive(new osg::DrawArrays(_primtype,indexBase,_coordList.size()));
}
else
{
@@ -230,7 +193,7 @@ void DynGeoSet::addToGeometry(osg::Geometry* geom)
itr!=_primLenList.end();
++itr)
{
- geom->addPrimitive(new osg::DrawArrays(mode,indexBase,*itr));
+ geom->addPrimitive(new osg::DrawArrays(_primtype,indexBase,*itr));
indexBase += *itr;
}
}
@@ -314,30 +277,12 @@ osg::Geode* GeoSetBuilder::createOsgGeoSets(osg::Geode* geode)
}
osgUtil::Tesselator tesselator;
- for(int i=0;igetNumDrawables();++i)
+ for(unsigned int i=0;igetNumDrawables();++i)
{
osg::Geometry* geom = dynamic_cast(geode->getDrawable(i));
if (geom) tesselator.retesselatePolygons(*geom);
}
-//Old GeoSet code.
-// for(itr=_dynGeoSetList.begin();
-// itr!=_dynGeoSetList.end();
-// ++itr)
-// {
-// DynGeoSet* dgset = itr->get();
-// if (dgset)
-// {
-// int prims = dgset->primLenListSize();
-// if (prims > 0)
-// {
-// dgset->setLists();
-// dgset->setNumPrims(prims);
-// geode->addDrawable(dgset);
-// }
-// }
-// }
-
return geode;
}
@@ -346,11 +291,13 @@ bool GeoSetBuilder::addPrimitive(bool dontMerge)
{
DynGeoSet* dgset = getDynGeoSet(); // This is the new geoset we want to add
- if (dgset->getPrimType() == osg::GeoSet::NO_TYPE)
+ if (dgset->getPrimType()==NO_PRIMITIVE_TYPE)
+ {
dgset->setPrimType(findPrimType(dgset->coordListSize()));
+ }
// Still no primitive type?
- if (dgset->getPrimType() == osg::GeoSet::NO_TYPE)
+ if (dgset->getPrimType()==NO_PRIMITIVE_TYPE)
return false;
dgset->setBinding();
@@ -389,18 +336,19 @@ DynGeoSet* GeoSetBuilder::findMatchingGeoSet()
}
-osg::GeoSet::PrimitiveType GeoSetBuilder::findPrimType(const int nVertices)
+osg::Primitive::Mode GeoSetBuilder::findPrimType(const int nVertices)
{
switch (nVertices)
{
- case 1: return osg::GeoSet::POINTS;
- case 2: return osg::GeoSet::LINES;
- case 3: return osg::GeoSet::TRIANGLES;
- case 4: return osg::GeoSet::QUADS;
+ case 1: return osg::Primitive::POINTS;
+ case 2: return osg::Primitive::LINES;
+ case 3: return osg::Primitive::TRIANGLES;
+ case 4: return osg::Primitive::QUADS;
}
- if (nVertices >= 5) return osg::GeoSet::POLYGON;
- return osg::GeoSet::NO_TYPE;
+ if (nVertices>=5) return osg::Primitive::POLYGON;
+
+ return NO_PRIMITIVE_TYPE;
}
diff --git a/src/osgPlugins/flt/GeoSetBuilder.h b/src/osgPlugins/flt/GeoSetBuilder.h
index 4307e1b3b..0d490c4ff 100644
--- a/src/osgPlugins/flt/GeoSetBuilder.h
+++ b/src/osgPlugins/flt/GeoSetBuilder.h
@@ -5,7 +5,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -27,7 +26,7 @@ class TmpGeoSet;
// DynGeoSet
//
////////////////////////////////////////////////////////////////////
-#if 0
+#if 1
# define COMPARE_DynGeoSet_Parameter(parameter) \
if (parameter= 1) && (rhs._colorList.size() >= 1)
- && (_colorList[0] != rhs._colorList[0]))
- return -1;
-
+ if (_color_binding == osg::Geometry::BIND_OVERALL)
+ {
+ if ((_colorList.size() >= 1) && (rhs._colorList.size() >= 1))
+ {
+ if (_colorList[0]compare(*rhs.getStateSet(), true);
if (result!=0) return result;
@@ -66,18 +67,26 @@ class DynGeoSet : public osg::GeoSet
int compatible(const DynGeoSet& rhs) const
{
+
COMPARE_DynGeoSet_Parameter(_color_binding)
- COMPARE_DynGeoSet_Parameter(_normal_binding)
COMPARE_DynGeoSet_Parameter(_texture_binding)
-
int result=getStateSet()->compare(*rhs.getStateSet(), true);
if (result!=0) return result;
- if ((_color_binding == osg::GeoSet::BIND_OVERALL)
- && (_colorList.size() >= 1) && (rhs._colorList.size() >= 1)
- && (_colorList[0] != rhs._colorList[0]))
- return -1;
+ COMPARE_DynGeoSet_Parameter(_normal_binding)
+
+ return 0;
+
+
+ if (_color_binding == osg::Geometry::BIND_OVERALL)
+ {
+ if ((_colorList.size() >= 1) && (rhs._colorList.size() >= 1))
+ {
+ if (_colorList[0] ColorList;
typedef std::vector TcoordList;
- PrimLenList _primLenList;
- CoordList _coordList;
- NormalList _normalList;
- ColorList _colorList;
- TcoordList _tcoordList;
+
+ osg::ref_ptr _stateset;
+
+
+ osg::Primitive::Mode _primtype;
+ PrimLenList _primLenList;
+
+ CoordList _coordList;
+
+ osg::Geometry::AttributeBinding _normal_binding;
+ NormalList _normalList;
+
+ osg::Geometry::AttributeBinding _color_binding;
+ ColorList _colorList;
+
+ osg::Geometry::AttributeBinding _texture_binding;
+ TcoordList _tcoordList;
};
@@ -149,7 +184,7 @@ class GeoSetBuilder
void initPrimData();
DynGeoSet* findMatchingGeoSet();
- osg::GeoSet::PrimitiveType findPrimType(const int nVertices);
+ osg::Primitive::Mode findPrimType(const int nVertices);
private:
diff --git a/src/osgPlugins/flt/flt2osg.cpp b/src/osgPlugins/flt/flt2osg.cpp
index 48ed8bf9c..110532d97 100644
--- a/src/osgPlugins/flt/flt2osg.cpp
+++ b/src/osgPlugins/flt/flt2osg.cpp
@@ -7,7 +7,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -672,16 +671,27 @@ osg::Group* ConvertFromFLT::visitSwitch(osg::Group& osgParent, SwitchRecord* rec
visitAncillary(osgParent, *group, rec)->addChild( group );
visitPrimaryNode(*group, (PrimNodeRecord*)rec);
- for(int nChild=0; nChildgetNumChildren(); nChild++)
+ for(unsigned int nChild=0; nChild<(unsigned int)rec->getNumChildren(); nChild++)
{
- int nMaskBit = nChild % 32;
- int nMaskWord = pSSwitch->nCurrentMask * pSSwitch->nWordsInMask + nChild / 32;
+ unsigned int nMaskBit = nChild % 32;
+ unsigned int nMaskWord = pSSwitch->nCurrentMask * pSSwitch->nWordsInMask + nChild / 32;
if (!(pSSwitch->aMask[nMaskWord] & (uint32(1) << nMaskBit)))
{
- osg::Node* node = group->getChild(nChild);
- if (node)
- node->setNodeMask(0);
+ if (nChildgetNumChildren())
+ {
+ osg::Node* node = group->getChild(nChild);
+ if (node)
+ node->setNodeMask(0);
+ }
+ else
+ {
+ osg::notify(osg::WARN)<<"Warning::OpenFlight loader has come across an incorrectly handled switch."<getNumChildren()<<") "<getNumChildren()<<")"<setPrimType(osg::GeoSet::LINE_STRIP);
+ dgset->setPrimType(osg::Primitive::LINE_STRIP);
break;
case FaceRecord::WIREFRAME_CLOSED:
- dgset->setPrimType(osg::GeoSet::LINE_LOOP);
+ dgset->setPrimType(osg::Primitive::LINE_LOOP);
break;
}
@@ -776,39 +786,39 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec)
case FaceRecord::FACE_COLOR:
// Use face color, not illuminated
osgStateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
- dgset->setColorBinding( osg::GeoSet::BIND_OVERALL /*BIND_PERPRIM*/ );
+ dgset->setColorBinding( osg::Geometry::BIND_OVERALL /*BIND_PERPRIM*/ );
break;
case FaceRecord::VERTEX_COLOR:
// Use vertex colors, not illuminated
osgStateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
- dgset->setColorBinding( osg::GeoSet::BIND_PERVERTEX );
+ dgset->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
break;
case FaceRecord::FACE_COLOR_LIGHTING:
// Use face color and vertex normal
osgStateSet->setMode( GL_LIGHTING, osg::StateAttribute::ON );
- dgset->setColorBinding( osg::GeoSet::BIND_OVERALL );
- dgset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
+ dgset->setColorBinding( osg::Geometry::BIND_OVERALL );
+ dgset->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
break;
case FaceRecord::VERTEX_COLOR_LIGHTING:
// Use vertex color and vertex normal
osgStateSet->setMode( GL_LIGHTING, osg::StateAttribute::ON );
- dgset->setColorBinding( osg::GeoSet::BIND_PERVERTEX );
- dgset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
+ dgset->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
+ dgset->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
break;
default :
osgStateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
- dgset->setColorBinding( osg::GeoSet::BIND_OVERALL );
+ dgset->setColorBinding( osg::Geometry::BIND_OVERALL );
break;
}
}
else // Version 11, 12 & 13
{
osgStateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
- dgset->setColorBinding( osg::GeoSet::BIND_OVERALL /*BIND_PERPRIM*/ );
+ dgset->setColorBinding( osg::Geometry::BIND_OVERALL /*BIND_PERPRIM*/ );
}
@@ -857,8 +867,8 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec)
_faceColor[3] = 1.0f - ((float)pSFace->wTransparency / 65535.0f);
if (pSFace->wTransparency > 0) bBlend = true;
- if ((dgset->getColorBinding() == osg::GeoSet::BIND_OVERALL)
- || (dgset->getColorBinding() == osg::GeoSet::BIND_PERPRIM))
+ if ((dgset->getColorBinding() == osg::Geometry::BIND_OVERALL)
+ || (dgset->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE))
dgset->addColor(_faceColor);
//
@@ -974,7 +984,7 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec)
}
#endif
- dgset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
+ dgset->setTextureBinding(osg::Geometry::BIND_PER_VERTEX);
}
}
}
@@ -1050,7 +1060,7 @@ int ConvertFromFLT::addVertices(GeoSetBuilder* pBuilder, PrimNodeRecord* primRec
if (vertices > 0)
{
- if (dgset->getPrimType() == osg::GeoSet::POINTS)
+ if (dgset->getPrimType() == osg::Primitive::POINTS)
{
for (i=0; i < vertices; i++)
dgset->addPrimLen(1);
@@ -1095,7 +1105,7 @@ int ConvertFromFLT::addVertex(DynGeoSet* dgset, Record* rec)
osg::Vec3 coord(pVert->Coord.x(), pVert->Coord.y(), pVert->Coord.z());
coord *= (float)_unitScale;
dgset->addCoord(coord);
- if (dgset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if (dgset->getColorBinding() == osg::Geometry::BIND_PER_VERTEX)
ADD_VERTEX_COLOR(dgset, pVert, rec->getFltFile()->getColorPool())
}
@@ -1107,9 +1117,9 @@ int ConvertFromFLT::addVertex(DynGeoSet* dgset, Record* rec)
osg::Vec3 coord(pVert->Coord.x(), pVert->Coord.y(), pVert->Coord.z());
coord *= (float)_unitScale;
dgset->addCoord(coord);
- if (dgset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if (dgset->getNormalBinding() == osg::Geometry::BIND_PER_VERTEX)
ADD_NORMAL(dgset, pVert)
- if (dgset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if (dgset->getColorBinding() == osg::Geometry::BIND_PER_VERTEX)
ADD_VERTEX_COLOR(dgset, pVert, rec->getFltFile()->getColorPool())
}
break;
@@ -1120,11 +1130,11 @@ int ConvertFromFLT::addVertex(DynGeoSet* dgset, Record* rec)
osg::Vec3 coord(pVert->Coord.x(), pVert->Coord.y(), pVert->Coord.z());
coord *= (float)_unitScale;
dgset->addCoord(coord);
- if (dgset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if (dgset->getNormalBinding() == osg::Geometry::BIND_PER_VERTEX)
ADD_NORMAL(dgset, pVert)
- if (dgset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if (dgset->getTextureBinding() == osg::Geometry::BIND_PER_VERTEX)
ADD_TCOORD(dgset, pVert)
- if (dgset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if (dgset->getColorBinding() == osg::Geometry::BIND_PER_VERTEX)
ADD_VERTEX_COLOR(dgset, pVert, rec->getFltFile()->getColorPool())
}
break;
@@ -1135,9 +1145,9 @@ int ConvertFromFLT::addVertex(DynGeoSet* dgset, Record* rec)
osg::Vec3 coord(pVert->Coord.x(), pVert->Coord.y(), pVert->Coord.z());
coord *= (float)_unitScale;
dgset->addCoord(coord);
- if (dgset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if (dgset->getTextureBinding() == osg::Geometry::BIND_PER_VERTEX)
ADD_TCOORD(dgset, pVert)
- if (dgset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if (dgset->getColorBinding() == osg::Geometry::BIND_PER_VERTEX)
ADD_VERTEX_COLOR(dgset, pVert, rec->getFltFile()->getColorPool())
}
break;
@@ -1148,7 +1158,7 @@ int ConvertFromFLT::addVertex(DynGeoSet* dgset, Record* rec)
osg::Vec3 coord(pVert->v[0], pVert->v[1], pVert->v[2]);
coord *= (float)_unitScale;
dgset->addCoord(coord);
- if ((dgset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if ((dgset->getTextureBinding() == osg::Geometry::BIND_PER_VERTEX)
&& (rec->getSize() >= sizeof(SOldVertex)))
ADD_OLD_TCOORD(dgset, pVert)
}
@@ -1160,9 +1170,9 @@ int ConvertFromFLT::addVertex(DynGeoSet* dgset, Record* rec)
osg::Vec3 coord(pVert->v[0], pVert->v[1], pVert->v[2]);
coord *= (float)_unitScale;
dgset->addCoord(coord);
- if (dgset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if (dgset->getColorBinding() == osg::Geometry::BIND_PER_VERTEX)
ADD_OLD_COLOR(dgset, pVert, rec->getFltFile()->getColorPool())
- if ((dgset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if ((dgset->getTextureBinding() == osg::Geometry::BIND_PER_VERTEX)
&& (rec->getSize() >= sizeof(SOldVertexColor)))
ADD_OLD_TCOORD(dgset, pVert)
}
@@ -1174,15 +1184,15 @@ int ConvertFromFLT::addVertex(DynGeoSet* dgset, Record* rec)
osg::Vec3 coord(pVert->v[0], pVert->v[1], pVert->v[2]);
coord *= (float)_unitScale;
dgset->addCoord(coord);
- if (dgset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if (dgset->getNormalBinding() == osg::Geometry::BIND_PER_VERTEX)
{
osg::Vec3 normal(pVert->n[0], pVert->n[1], pVert->n[2]);
normal /= (float)(1L<<30);
dgset->addNormal(normal);
}
- if (dgset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if (dgset->getColorBinding() == osg::Geometry::BIND_PER_VERTEX)
ADD_OLD_COLOR(dgset, pVert, rec->getFltFile()->getColorPool())
- if ((dgset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX)
+ if ((dgset->getTextureBinding() == osg::Geometry::BIND_PER_VERTEX)
&& (rec->getSize() >= sizeof(SOldVertexColorNormal)))
ADD_OLD_TCOORD(dgset, pVert)
}
@@ -1249,10 +1259,10 @@ void ConvertFromFLT::visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord*
osg::StateSet* stateSet = dgset->getStateSet();
SLightPoint *pSLightPoint = (SLightPoint*)rec->getData();
- dgset->setPrimType(osg::GeoSet::POINTS);
+ dgset->setPrimType(osg::Primitive::POINTS);
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateSet->setMode(GL_POINT_SMOOTH, osg::StateAttribute::ON);
- dgset->setColorBinding(osg::GeoSet::BIND_PERVERTEX);
+ dgset->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
osg::Point* point = new osg::Point;
if (point)
diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp
index e21e69e93..054dc095b 100644
--- a/src/osgUtil/CullVisitor.cpp
+++ b/src/osgUtil/CullVisitor.cpp
@@ -250,7 +250,7 @@ void CullVisitor::apply(Geode& node)
if (node_state) pushStateSet(node_state);
Matrix& matrix = getModelViewMatrix();
- for(int i=0;igetBound();
@@ -316,7 +316,7 @@ void CullVisitor::apply(Billboard& node)
const Vec3& eye_local = getEyeLocal();
const Matrix& modelview = getModelViewMatrix();
- for(int i=0;iaccept(osv);
osv.optimize();
+
+ MergeGeometryVisitor mgv;
+ node->accept(mgv);
#endif
}
-
@@ -138,7 +140,7 @@ class TransformFunctor : public osg::Drawable::AttributeFunctor
void Optimizer::ConvertGeoSetsToGeometryVisitor::apply(osg::Geode& geode)
{
- for(int i=0;i(geode.getDrawable(i));
if (geoset)
@@ -204,7 +206,7 @@ void Optimizer::StateVisitor::apply(osg::Geode& geode)
{
osg::StateSet* ss = geode.getStateSet();
if (ss && ss->getDataVariance()==osg::Object::STATIC) addStateSet(ss,&geode);
- for(int i=0;isetAxis(axis);
- for(int i=0;igetNumDrawables();++i)
+ for(unsigned int i=0;igetNumDrawables();++i)
{
billboard->setPos(i,billboard->getPos(i)*matrix);
billboard->getDrawable(i)->applyAttributeOperation(tf);
@@ -650,7 +652,7 @@ void Optimizer::RemoveLowestStaticTransformsVisitor::apply(osg::Geode& geode)
osg::Matrix matrix;
if (!_matrixStack.empty()) matrix = _matrixStack.back();
- for(int i=0;isetAxis(axis);
- for(int i=0;igetNumDrawables();++i)
+ for(unsigned int i=0;igetNumDrawables();++i)
{
billboard->setPos(i,billboard->getPos(i)*matrix);
billboard->getDrawable(i)->applyAttributeOperation(tf);
@@ -1162,3 +1164,166 @@ void Optimizer::CombineLODsVisitor::combineLODs()
_groupList.clear();
}
+////////////////////////////////////////////////////////////////////////////
+// code to merge geometry object which share, state, and attribute bindings.
+////////////////////////////////////////////////////////////////////////////
+
+struct LessGeometry
+{
+ bool operator() (const osg::Geometry* lhs,const osg::Geometry* rhs)
+ {
+ if (lhs->getStateSet()getStateSet()) return true;
+ if (rhs->getStateSet()getStateSet()) return false;
+
+ if (lhs->getColorBinding()getColorBinding()) return true;
+ if (rhs->getColorBinding()getColorBinding()) return false;
+
+ if (lhs->getNormalBinding()getNormalBinding()) return true;
+ if (rhs->getNormalBinding()getNormalBinding()) return false;
+
+ if (lhs->getNumTexCoordArrays()getNumTexCoordArrays()) return true;
+ if (rhs->getNumTexCoordArrays()getNumTexCoordArrays()) return false;
+
+ // therefore lhs->getNumTexCoordArrays()==rhs->getNumTexCoordArrays()
+
+ for(unsigned int i=0;igetNumTexCoordArrays();++i)
+ {
+ if (rhs->getTexCoordArray(i))
+ {
+ if (!lhs->getTexCoordArray(i)) return true;
+ }
+ else if (lhs->getTexCoordArray(i)) return false;
+ }
+
+ if (lhs->getNormalBinding()==osg::Geometry::BIND_OVERALL)
+ {
+ // assumes that the bindings and arrays are set up correctly, this
+ // should be the case after running computeCorrectBindingsAndArraySizes();
+ const osg::Vec3& lhs_normal = (*(lhs->getNormalArray()))[0];
+ const osg::Vec3& rhs_normal = (*(rhs->getNormalArray()))[0];
+ if (lhs_normalgetColorBinding()==osg::Geometry::BIND_OVERALL)
+ {
+ if (lhs->getColorArray()->getType()getColorArray()->getType()) return true;
+ if (rhs->getColorArray()->getType()getColorArray()->getType()) return false;
+ }
+
+ return false;
+
+ }
+};
+
+bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode)
+{
+ if (geode.getNumDrawables()<2) return false;
+
+ typedef std::vector DuplicateList;
+ typedef std::map GeometryDuplicateMap;
+
+ GeometryDuplicateMap geometryDuplicateMap;
+
+ for(unsigned int i=0;i(geode.getDrawable(i));
+ if (geom)
+ {
+ geom->computeCorrectBindingsAndArraySizes();
+
+ geometryDuplicateMap[geom].push_back(geom);
+ }
+ }
+
+ for(GeometryDuplicateMap::iterator itr=geometryDuplicateMap.begin();
+ itr!=geometryDuplicateMap.end();
+ ++itr)
+ {
+ if (itr->second.size()>1)
+ {
+ osg::Geometry* lhs = itr->second[0];
+ for(DuplicateList::iterator dupItr=itr->second.begin()+1;
+ dupItr!=itr->second.end();
+ ++dupItr)
+ {
+ osg::Geometry* rhs = *dupItr;
+ if (mergeGeometry(*lhs,*rhs))
+ {
+ geode.removeDrawable(rhs);
+
+ static int co = 0;
+ osg::notify(osg::INFO)<<"merged and removed Geometry "<<++co<size();
+ lhs.getVertexArray()->insert(lhs.getVertexArray()->end(),rhs.getVertexArray()->begin(),rhs.getVertexArray()->end());
+ }
+ else if (rhs.getVertexArray())
+ {
+ lhs.setVertexArray(rhs.getVertexArray());
+ }
+
+ if (lhs.getNormalArray() && rhs.getNormalArray() && lhs.getNormalBinding()!=osg::Geometry::BIND_OVERALL)
+ {
+ lhs.getNormalArray()->insert(lhs.getNormalArray()->end(),rhs.getNormalArray()->begin(),rhs.getNormalArray()->end());
+ }
+ else if (rhs.getNormalArray())
+ {
+ lhs.setNormalArray(rhs.getNormalArray());
+ }
+
+ if (lhs.getColorArray() && rhs.getColorArray() && lhs.getColorBinding()!=osg::Geometry::BIND_OVERALL)
+ {
+ // we need to add the handling of the other array types...
+ osg::Vec4Array* col_lhs = dynamic_cast(lhs.getColorArray());
+ osg::Vec4Array* col_rhs = dynamic_cast(rhs.getColorArray());
+
+ if (col_lhs && col_rhs)
+ {
+ col_lhs->insert(col_lhs->end(),col_rhs->begin(),col_rhs->end());
+ }
+ }
+ else if (rhs.getColorArray())
+ {
+ lhs.setColorArray(rhs.getColorArray());
+ }
+
+ for(unsigned int unit=0;unit(lhs.getTexCoordArray(unit));
+ osg::Vec2Array* tex_rhs = dynamic_cast(rhs.getTexCoordArray(unit));
+
+ if (tex_lhs && tex_rhs)
+ {
+ tex_lhs->insert(tex_lhs->end(),tex_rhs->begin(),tex_rhs->end());
+ }
+ }
+
+ // shift the indices of the incomming primitives to account for the pre exisiting geometry.
+ for(osg::Geometry::PrimitiveList::iterator primItr=rhs.getPrimitiveList().begin();
+ primItr!=rhs.getPrimitiveList().end();
+ ++primItr)
+ {
+ osg::Primitive* primitive = primItr->get();
+ primitive->offsetIndices(base);
+ }
+
+ lhs.getPrimitiveList().insert(lhs.getPrimitiveList().end(),rhs.getPrimitiveList().begin(),rhs.getPrimitiveList().end());
+
+
+ return true;
+}