From Sukender, "1. More handled cases in MergeGeometryVisitor

- Algorithm doesn't try to merge double and single precision arrays together
- Algorithm doesn't try to merge incompatible geometries (ex: one with "vertices + texoords", and another with only vertices)

2. Better TextureAtlasBuilder
Algorithm is still sub-optimal, but it now tries to fill more blanks, using "unused space in the current line".
(Don't know if I already submitted it, but I guess not)
One day, someone should try to find a good solution to this NP-problem... For instance : http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.140.200&rep=rep1&type=pdf
"
This commit is contained in:
Robert Osfield
2010-11-05 17:04:08 +00:00
parent 2f51919979
commit 147fdd0430
2 changed files with 423 additions and 147 deletions

View File

@@ -663,13 +663,13 @@ class OSGUTIL_EXPORT Optimizer
void reset();
void setMaximumAtlasSize(unsigned int width, unsigned int height);
void setMaximumAtlasSize(int width, int height);
unsigned int getMaximumAtlasWidth() const { return _maximumAtlasWidth; }
unsigned int getMaximumAtlasHeight() const { return _maximumAtlasHeight; }
int getMaximumAtlasWidth() const { return _maximumAtlasWidth; }
int getMaximumAtlasHeight() const { return _maximumAtlasHeight; }
void setMargin(unsigned int margin);
unsigned int getMargin() const { return _margin; }
void setMargin(int margin);
int getMargin() const { return _margin; }
void addSource(const osg::Image* image);
void addSource(const osg::Texture2D* texture);
@@ -677,9 +677,8 @@ class OSGUTIL_EXPORT Optimizer
unsigned int getNumSources() const { return _sourceList.size(); }
const osg::Image* getSourceImage(unsigned int i) { return _sourceList[i]->_image.get(); }
const osg::Texture2D* getSourceTexture(unsigned int i) { return _sourceList[i]->_texture.get(); }
void buildAtlas();
osg::Image* getImageAtlas(unsigned int i);
osg::Texture2D* getTextureAtlas(unsigned int i);
osg::Matrix getTextureMatrix(unsigned int i);
@@ -694,14 +693,14 @@ class OSGUTIL_EXPORT Optimizer
protected:
unsigned int _maximumAtlasWidth;
unsigned int _maximumAtlasHeight;
unsigned int _margin;
int _maximumAtlasWidth;
int _maximumAtlasHeight;
int _margin;
// forward declare
class Atlas;
class Source : public osg::Referenced
{
public:
@@ -714,14 +713,14 @@ class OSGUTIL_EXPORT Optimizer
Source(const osg::Texture2D* texture):
_x(0),_y(0),_atlas(0),_texture(texture) { if (texture) _image = texture->getImage(); }
unsigned int _x;
unsigned int _y;
int _x;
int _y;
Atlas* _atlas;
osg::ref_ptr<const osg::Image> _image;
osg::ref_ptr<const osg::Texture2D> _texture;
bool suitableForAtlas(unsigned int maximumAtlasWidth, unsigned int maximumAtlasHeight, unsigned int margin);
bool suitableForAtlas(int maximumAtlasWidth, int maximumAtlasHeight, int margin);
osg::Matrix computeTextureMatrix() const;
@@ -729,42 +728,51 @@ class OSGUTIL_EXPORT Optimizer
virtual ~Source() {}
};
typedef std::vector< osg::ref_ptr<Source> > SourceList;
class Atlas : public osg::Referenced
{
public:
Atlas(unsigned int width, unsigned height, unsigned margin):
Atlas(int width, int height, int margin):
_maximumAtlasWidth(width),
_maximumAtlasHeight(height),
_margin(margin),
_x(0),
_y(0),
_width(0),
_height(0){}
_height(0),
_indexFirstOfRow(0){}
unsigned int _maximumAtlasWidth;
unsigned int _maximumAtlasHeight;
unsigned int _margin;
int _maximumAtlasWidth;
int _maximumAtlasHeight;
int _margin;
osg::ref_ptr<osg::Texture2D> _texture;
osg::ref_ptr<osg::Image> _image;
SourceList _sourceList;
unsigned int _x;
unsigned int _y;
unsigned int _width;
unsigned int _height;
bool doesSourceFit(Source* source);
int _x;
int _y;
int _width;
int _height;
unsigned int _indexFirstOfRow; ///< Contain the index of the first element of the last row.
enum FitsIn
{
NO,
YES,
IN_NEXT_ROW
};
//Return YES if it fits in the current row,
//NO if it can't fit in any row.
//IN_NEXT_ROW if it can't fin the the current row, but can fit in next row or atlas.
FitsIn doesSourceFit(Source* source);
bool addSource(Source* source);
void clampToNearestPowerOfTwoSize();
void copySources();
protected:
virtual ~Atlas() {}
};
@@ -774,7 +782,16 @@ class OSGUTIL_EXPORT Optimizer
Source* getSource(const osg::Texture2D* texture);
SourceList _sourceList;
AtlasList _atlasList;
AtlasList _atlasList;
private:
struct CompareSrc
{
bool operator()(osg::ref_ptr<Source> src1, osg::ref_ptr<Source> src2) const
{
return src1->_image->t() > src2->_image->t();
}
};
void completeRow(unsigned int indexAtlas);
};