/* * Copyright 2011-2013 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause */ #ifndef RECTPACK_H_HEADER_GUARD #define RECTPACK_H_HEADER_GUARD #include struct Pack2D { uint16_t m_x; uint16_t m_y; uint16_t m_width; uint16_t m_height; }; struct PackCube { Pack2D m_rect; uint8_t m_side; }; template class RectPackCubeT; template class RectPack2DT { public: RectPack2DT(uint16_t _width, uint16_t _height) { reset(_width, _height); } void reset(uint16_t _width, uint16_t _height) { m_bw = _width/64; m_bh = _height/numBlocks; memset(m_mem, 0xff, sizeof(m_mem) ); } bool find(uint16_t _width, uint16_t _height, Pack2D& _pack) { uint16_t width = bx::uint16_min(64, (_width + m_bw - 1) / m_bw); uint16_t height = bx::uint16_min(numBlocks, (_height + m_bh - 1) / m_bh); uint16_t numx = 64-width; uint16_t numy = numBlocks-height; const uint64_t scan = width == 64 ? UINT64_MAX : (UINT64_C(1)<; RectPack2DT() { } uint64_t m_mem[numBlocks]; uint16_t m_bw; uint16_t m_bh; }; template class RectPackCubeT { public: RectPackCubeT(uint16_t _side) { reset(_side); } void reset(uint16_t _side) { for (uint32_t ii = 0; ii < 6; ++ii) { m_mru[ii] = ii; m_ra[ii].reset(_side, _side); } } bool find(uint16_t _width, uint16_t _height, PackCube& _pack) { bool found = false; for (uint32_t ii = 0; ii < 6; ++ii) { uint8_t side = m_mru[ii]; found = m_ra[side].find(_width, _height, _pack.m_rect); if (found) { _pack.m_side = side; m_mru[ii] = m_mru[0]; m_mru[0] = side; return true; } } return false; } void clear(const PackCube& _pack) { uint8_t side = _pack.m_side; uint32_t ii = 0; for (; ii < 6 && m_mru[ii] != side; ++ii) {}; m_mru[ii] = m_mru[0]; m_mru[0] = side; m_ra[side].clear(_pack.m_rect); } private: RectPackCubeT(); RectPack2DT m_ra[6]; uint8_t m_mru[6]; }; #endif // RECTPACK_H_HEADER_GUARD