#include "TextureSheet.h" bool pixmapSortFunc(const std::pair>& pixmap1, const std::pair>& pixmap2) { return pixmap1.second->width() * pixmap1.second->height() > pixmap2.second->width() * pixmap2.second->height(); } bool resultTexturePositionsSortFunc(const std::pair& result1, const std::pair& 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(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>>::iterator pixmapItr = pixmapArray.begin(); pixmapItr != pixmapArray.end(); pixmapItr++) { boost::shared_ptr 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(width), spaceAreaArr[foundIndex].posY / static_cast(height), (spaceAreaArr[foundIndex].posX + selectedPixmap->width()) / static_cast(width), (spaceAreaArr[foundIndex].posY + selectedPixmap->height()) / static_cast(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(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 = "\n\t\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%1\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\n"; return result; } void TextureSheet::Clear() { spaceAreaArr.clear(); resultTexturePositions.clear(); pixmapArray.clear(); imageNamesArray.clear(); resultPixmap = boost::shared_ptr(new QPixmap(4,4)); QColor transparentColor(0,0,0,0); resultPixmap->fill(transparentColor); }