141 lines
4.9 KiB
C++
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);
|
||
|
}
|