#include "Runtime/Particle/CUVElement.hpp" /* Documentation at: https://wiki.axiodl.com/w/Particle_Script#UV_Elements */ namespace metaforce { CUVEAnimTexture::CUVEAnimTexture(TToken&& tex, std::unique_ptr&& tileW, std::unique_ptr&& tileH, std::unique_ptr&& strideW, std::unique_ptr&& strideH, std::unique_ptr&& cycleFrames, bool loop) : x4_tex(std::move(tex)), x24_loop(loop), x28_cycleFrames(std::move(cycleFrames)) { tileW->GetValue(0, x10_tileW); tileH->GetValue(0, x14_tileH); strideW->GetValue(0, x18_strideW); strideH->GetValue(0, x1c_strideH); const int width = int(x4_tex.GetObj()->GetWidth()); const int height = int(x4_tex.GetObj()->GetHeight()); const float widthF = float(width); const float heightF = float(height); const int xTiles = std::max(1, width / x18_strideW); const int yTiles = std::max(1, height / x1c_strideH); x20_tiles = xTiles * yTiles; x2c_uvElems.reserve(x20_tiles); for (int y = yTiles - 1; y >= 0; --y) { for (int x = 0; x < xTiles; ++x) { const int px = x18_strideW * x; const int px2 = px + x10_tileW; const int py = x1c_strideH * y; const int py2 = py + x14_tileH; x2c_uvElems.push_back({ float(px) / widthF, float(py) / heightF, float(px2) / widthF, float(py2) / heightF, }); } } } void CUVEAnimTexture::GetValueUV(int frame, SUVElementSet& valOut) const { int cv = 1; x28_cycleFrames->GetValue(frame, cv); float cvf = float(cv) / float(x20_tiles); cvf = float(frame) / cvf; int tile = int(cvf); if (x24_loop) { // HACK // Check bad values for cvf tile = !(std::isnan(cvf) || std::isinf(cvf)) && int(cvf) >= 0 ? int(cvf) : 0; if (tile >= x20_tiles) { tile = tile % x20_tiles; } } else { if (cvf >= float(x20_tiles)) { tile = x20_tiles - 1; } } valOut = x2c_uvElems[tile]; } } // namespace metaforce