qt/TextureSheetMaker/TextureSheet.cpp
2013-06-22 18:18:33 +00:00

141 lines
4.9 KiB
C++

#include "TextureSheet.h"
bool pixmapSortFunc(const std::pair<QString, boost::shared_ptr<QPixmap>>& pixmap1, const std::pair<QString, boost::shared_ptr<QPixmap>>& pixmap2)
{
return pixmap1.second->width() * pixmap1.second->height() > pixmap2.second->width() * pixmap2.second->height();
}
bool resultTexturePositionsSortFunc(const std::pair<QString, TexCoordRect>& result1, const std::pair<QString, TexCoordRect>& result2)
{
return result1.first < result2.first;
}
void TextureSheet::Calculate(int width, int height)
{
spaceAreaArr.clear();
resultTexturePositions.clear();
std::sort(pixmapArray.begin(), pixmapArray.end(), &pixmapSortFunc);
resultPixmap = boost::shared_ptr<QPixmap>(new QPixmap(width, height));
QColor transparentColor(0,0,0,0);
resultPixmap->fill(transparentColor);
spaceAreaArr.push_back(SpaceArea(0,0,width,height));
QPainter p;
p.begin(&(*resultPixmap));
for (std::vector<std::pair<QString, boost::shared_ptr<QPixmap>>>::iterator pixmapItr = pixmapArray.begin(); pixmapItr != pixmapArray.end(); pixmapItr++)
{
boost::shared_ptr<QPixmap> selectedPixmap = pixmapItr->second;
int foundIndex = -1;
for (size_t i = 0; i < spaceAreaArr.size(); i++)
{
if (spaceAreaArr[i].Width >= selectedPixmap->width()
&& spaceAreaArr[i].Height >= selectedPixmap->height()
&& (foundIndex == -1 ||
spaceAreaArr[i].Width*spaceAreaArr[i].Height < spaceAreaArr[foundIndex].Width*spaceAreaArr[foundIndex].Height))
{
foundIndex = i;
}
}
if (foundIndex != -1)
{
//split space
SpaceArea rightSpaceArea(spaceAreaArr[foundIndex].posX + selectedPixmap->width(),
spaceAreaArr[foundIndex].posY,
spaceAreaArr[foundIndex].Width - selectedPixmap->width(),
selectedPixmap->height());
SpaceArea topSpaceArea(spaceAreaArr[foundIndex].posX,
spaceAreaArr[foundIndex].posY + selectedPixmap->height(),
spaceAreaArr[foundIndex].Width,
spaceAreaArr[foundIndex].Height - selectedPixmap->height());
p.drawPixmap(spaceAreaArr[foundIndex].posX, spaceAreaArr[foundIndex].posY, *selectedPixmap);
TexCoordRect texCoordRect(spaceAreaArr[foundIndex].posX / static_cast<float>(width),
spaceAreaArr[foundIndex].posY / static_cast<float>(height),
(spaceAreaArr[foundIndex].posX + selectedPixmap->width()) / static_cast<float>(width),
(spaceAreaArr[foundIndex].posY + selectedPixmap->height()) / static_cast<float>(height));
texCoordRect.texCoordFromY = 1.f - texCoordRect.texCoordFromY;
texCoordRect.texCoordToY = 1.f - texCoordRect.texCoordToY;
float temp = texCoordRect.texCoordFromY;
texCoordRect.texCoordFromY = texCoordRect.texCoordToY;
texCoordRect.texCoordToY = temp;
resultTexturePositions.push_back(std::pair<QString, TexCoordRect>(pixmapItr->first, texCoordRect));
spaceAreaArr.erase(spaceAreaArr.begin() + foundIndex);
spaceAreaArr.push_back(rightSpaceArea);
spaceAreaArr.push_back(topSpaceArea);
}
else
{
throw std::runtime_error("Not enough space");
}
}
}
QString TextureSheet::GetCalculatedXml()
{
QString result;
result = "<TextureSheet>\n\t<TextureElements>\n";
std::sort(imageNamesArray.begin(), imageNamesArray.end());
std::sort(resultTexturePositions.begin(), resultTexturePositions.end(), &resultTexturePositionsSortFunc);
for (size_t i = 0; i < imageNamesArray.size(); i++)
{
result += QString("\t\t<Texture><Name>%1</Name><TexCoordFrom x='%2' y='%3'/><TexCoordTo x='%4' y='%5'/></Texture>\n")
.arg(imageNamesArray[i])
.arg(QString::number(resultTexturePositions[i].second.texCoordFromX))
.arg(QString::number(resultTexturePositions[i].second.texCoordFromY))
.arg(QString::number(resultTexturePositions[i].second.texCoordToX))
.arg(QString::number(resultTexturePositions[i].second.texCoordToY));
}
result += "\t</TextureElements>\n</TextureSheet>";
return result;
}
void TextureSheet::Clear()
{
spaceAreaArr.clear();
resultTexturePositions.clear();
pixmapArray.clear();
imageNamesArray.clear();
resultPixmap = boost::shared_ptr<QPixmap>(new QPixmap(4,4));
QColor transparentColor(0,0,0,0);
resultPixmap->fill(transparentColor);
}