Files
OpenSceneGraph/src/osgPlugins/flt/GeoSetBuilder.h

300 lines
9.9 KiB
C++

#ifndef __FLT_GEOSETBUILDER_H
#define __FLT_GEOSETBUILDER_H
// Added DynGeoSet::setDetailTextureAttrData that is used to store texture
// Attributes
// Julian Ortiz, June 18th 2003.
// ---
// Added support for multiple layers of texture coordinates. Changed the
// detail texture support to only store the M & N scalar values instead of
// the whole AttrData structure.
// Jason Daly, Sept 25, 2004
#include <osg/ref_ptr>
#include <osg/Vec2>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/Material>
#include <osg/StateSet>
#include <map>
#include <vector>
namespace flt {
class Record;
class TmpGeoSet;
////////////////////////////////////////////////////////////////////
//
// DynGeoSet
//
////////////////////////////////////////////////////////////////////
#if 1
# define COMPARE_DynGeoSet_Parameter(parameter) \
if (parameter<rhs.parameter) return -1; \
if (rhs.parameter<parameter) return 1;
#else
# define COMPARE_DynGeoSet_Parameter(parameter) \
if (parameter != rhs.parameter) return -1;
#endif
/** DynGeoSet - Dynamic GeoSet.
*/
class DynGeoSet : public osg::Referenced
{
public:
DynGeoSet();
int compare(const DynGeoSet& rhs) const
{
COMPARE_DynGeoSet_Parameter(_color_binding)
COMPARE_DynGeoSet_Parameter(_normal_binding)
for (unsigned int i = 0; i < _texture_bindings.size(); i++)
{
if (getTextureBinding(i)<rhs.getTextureBinding(i))
return -1;
if (getTextureBinding(i)>rhs.getTextureBinding(i))
return 1;
}
if (_color_binding == osg::Geometry::BIND_OVERALL)
{
if ((_colorList.size() >= 1) && (rhs._colorList.size() >= 1))
{
if (_colorList[0]<rhs._colorList[0]) return -1;
if (rhs._colorList[0]<_colorList[0]) return 1;
}
}
int result=getStateSet()->compare(*rhs.getStateSet(), true);
if (result!=0) return result;
COMPARE_DynGeoSet_Parameter(_primtype);
return 0;
}
int compatible(const DynGeoSet& rhs) const
{
COMPARE_DynGeoSet_Parameter(_color_binding)
for (unsigned int i = 0; i < _texture_bindings.size(); i++)
{
if (getTextureBinding(i)<rhs.getTextureBinding(i))
return -1;
if (getTextureBinding(i)>rhs.getTextureBinding(i))
return 1;
}
int result=getStateSet()->compare(*rhs.getStateSet(), true);
if (result!=0) return result;
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]<rhs._colorList[0]) return -1;
if (rhs._colorList[0]<_colorList[0]) return 1;
}
}
return 0;
}
bool operator < (const DynGeoSet& rhs) const { return compare(rhs)<0; }
bool operator == (const DynGeoSet& rhs) const { return compare(rhs)==0; }
bool operator != (const DynGeoSet& rhs) const { return compare(rhs)!=0; }
void setStateSet(osg::StateSet* stateset) {
_stateset = stateset;
_geom->setStateSet( stateset );
}
osg::StateSet* getStateSet() { return _stateset.get(); }
const osg::StateSet* getStateSet() const { return _stateset.get(); }
void setColorBinding(osg::Geometry::AttributeBinding bind) { _color_binding = bind; }
void setNormalBinding(osg::Geometry::AttributeBinding bind) { _normal_binding = bind; }
void setTextureBinding(osg::Geometry::AttributeBinding bind)
{
setTextureBinding(0, bind);
}
void setTextureBinding(unsigned int index,
osg::Geometry::AttributeBinding bind)
{
if (_texture_bindings.size() <= index)
_texture_bindings.resize(index+1);
_texture_bindings[index] = bind;
}
osg::Geometry::AttributeBinding getColorBinding() const { return _color_binding; }
osg::Geometry::AttributeBinding getNormalBinding() const { return _normal_binding; }
osg::Geometry::AttributeBinding getTextureBinding() const { return getTextureBinding(0); }
osg::Geometry::AttributeBinding getTextureBinding(unsigned int index) const
{
if (_texture_bindings.size() > index)
return _texture_bindings[index];
else
return osg::Geometry::BIND_OFF;
}
void setPrimType(osg::PrimitiveSet::Mode type) { _primtype=type; }
osg::PrimitiveSet::Mode getPrimType() const { return _primtype; }
inline void addPrimLen(int len) { _primLenList.push_back(len); }
inline void addCoord(const osg::Vec3& coord) { _coordList.push_back(coord); }
inline void addNormal(const osg::Vec3& normal) { _normalList.push_back(normal); }
inline void addColor(const osg::Vec4& color) { _colorList.push_back(color); }
inline void addTCoord(const osg::Vec2& tcoord) { addTCoord(0, tcoord); }
inline void addTCoord(unsigned int index, const osg::Vec2& tcoord)
{
if (_tcoordLists.size() <= index)
_tcoordLists.resize(index+1);
_tcoordLists[index].push_back(tcoord);
}
typedef std::vector<osg::Vec3> CoordList;
typedef std::vector<osg::Vec3> NormalList;
typedef std::vector<osg::Vec4> ColorList;
typedef std::vector<osg::Vec2> TcoordList;
typedef std::vector<TcoordList> TcoordLists;
typedef std::vector<osg::Geometry::AttributeBinding> TextureBindings;
const CoordList& getCoordList() { return _coordList; }
const NormalList& getNormalList() { return _normalList; }
const ColorList& getColorList() { return _colorList; }
const TcoordList& getTcoordList() { return getTcoordList(0); }
const TcoordList& getTcoordList(unsigned int index)
{
if (_tcoordLists.size() <= index)
_tcoordLists.resize(index+1);
return _tcoordLists[index];
}
void append(DynGeoSet* source);
void setBinding();
void addToGeometry(osg::Geometry* geom);
inline int primLenListSize() const { return _primLenList.size(); }
inline int coordListSize() const { return _coordList.size(); }
inline int normalListSize() const { return _normalList.size(); }
inline int colorListSize() const { return _colorList.size(); }
inline int tcoordListSize() const { return tcoordListSize(0); }
inline int tcoordListSize(unsigned int index) const
{
if (_tcoordLists.size() <= index)
return _tcoordLists[index].size() ;
else
return 0;
}
inline void enableDetailTexture() { _detailTextureEnabled=true; }
inline void disableDetailTexture() { _detailTextureEnabled=false; }
inline void setDetailTexCoords(int32 m, int32 n)
{
// If somebody knows what the other TX_DETAIL parameters do,
// please add them. I looked through the OF specs as well as
// the SGIS_detail_texture extension, and I didn't find any
// clear explanation. The only reason this is here at all is
// because of Julian Ortiz' previous work.
_detailTexCoord_m = m;
_detailTexCoord_n = n;
}
osg::Geometry* getGeometry() {
CERR << "_geom.get(): " << _geom.get()
<< "; referenceCount: " << _geom.get()->referenceCount()<<"\n";
return _geom.get();
};
private:
typedef std::vector<int> PrimLenList;
osg::ref_ptr<osg::Geometry> _geom;
osg::ref_ptr<osg::StateSet> _stateset;
osg::PrimitiveSet::Mode _primtype;
PrimLenList _primLenList;
CoordList _coordList;
osg::Geometry::AttributeBinding _normal_binding;
NormalList _normalList;
osg::Geometry::AttributeBinding _color_binding;
ColorList _colorList;
TextureBindings _texture_bindings;
TcoordLists _tcoordLists;
int32 _detailTexCoord_m;
int32 _detailTexCoord_n;
bool _detailTextureEnabled;
};
////////////////////////////////////////////////////////////////////
//
// GeoSetBuilder
//
////////////////////////////////////////////////////////////////////
/** GeoSetBuilder - Contains a list of TmpGeoSets to be converted to osg::Geode.
*
*/
class GeoSetBuilder
{
public:
GeoSetBuilder(osg::Geode* geode = NULL);
virtual ~GeoSetBuilder() {}
bool addPrimitive( bool dontMerge = false);
osg::Geode* createOsgGeoSets(osg::Geode* geode = NULL);
inline DynGeoSet* getDynGeoSet() { return _dynGeoSet.get(); }
inline const DynGeoSet* getDynGeoSet() const { return _dynGeoSet.get(); }
inline bool empty() { return _dynGeoSetList.empty(); } ;
protected:
void initPrimData();
DynGeoSet* findMatchingGeoSet();
osg::PrimitiveSet::Mode findPrimType(const int nVertices);
private:
osg::ref_ptr<osg::Geode> _geode;
osg::ref_ptr<DynGeoSet> _dynGeoSet;
typedef std::vector<osg::ref_ptr<DynGeoSet> > DynGeoSetList;
DynGeoSetList _dynGeoSetList;
};
}; // end of namespace flt
#endif