Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
94
libs/geometry/packer.hpp
Normal file
94
libs/geometry/packer.hpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#pragma once
|
||||
|
||||
#include "geometry/rect2d.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace m2
|
||||
{
|
||||
template <typename pair_t>
|
||||
struct first_less
|
||||
{
|
||||
bool operator()(pair_t const & first, pair_t const & second) { return first.first < second.first; }
|
||||
};
|
||||
|
||||
/// The simplest row-by-row packer.
|
||||
/// When there is no free room all the packing
|
||||
/// rect is cleared and the process is started again.
|
||||
class Packer
|
||||
{
|
||||
public:
|
||||
using overflowFn = std::function<void()>;
|
||||
|
||||
using overflowFns = std::priority_queue<std::pair<size_t, overflowFn>, std::vector<std::pair<size_t, overflowFn>>,
|
||||
first_less<std::pair<size_t, overflowFn>>>;
|
||||
|
||||
using handle_t = uint32_t;
|
||||
using find_result_t = std::pair<bool, m2::RectU>;
|
||||
|
||||
Packer();
|
||||
|
||||
/// create a packer on a rectangular area of (0, 0, width, height) dimensions
|
||||
Packer(unsigned width, unsigned height, uint32_t maxHandle = 0xFFFF - 1);
|
||||
|
||||
/// reset the state of the packer
|
||||
void reset();
|
||||
|
||||
/// add overflow handler.
|
||||
/// @param priority handlers with higher priority value are called first.
|
||||
void addOverflowFn(overflowFn fn, int priority);
|
||||
|
||||
/// pack the rect with dimensions width X height on a free area.
|
||||
/// when there is no free area - find it somehow(depending on a packer implementation,
|
||||
/// the simplest one will just clear the whole rect and start the packing process again).
|
||||
handle_t pack(unsigned width, unsigned height);
|
||||
|
||||
/// return free handle
|
||||
handle_t freeHandle();
|
||||
|
||||
/// Does we have room to pack another rectangle?
|
||||
bool hasRoom(unsigned width, unsigned height) const;
|
||||
|
||||
/// Does we have room to pack a sequence of rectangles?
|
||||
bool hasRoom(m2::PointU const * sizes, size_t cnt) const;
|
||||
|
||||
/// is the handle present on the texture.
|
||||
bool isPacked(handle_t handle);
|
||||
|
||||
/// find the packed area by the handle.
|
||||
find_result_t find(handle_t handle) const;
|
||||
|
||||
/// remove the handle from the list of active handles.
|
||||
void remove(handle_t handle);
|
||||
|
||||
/// get an invalid handle
|
||||
uint32_t invalidHandle() const;
|
||||
|
||||
private:
|
||||
using rects_t = std::map<handle_t, m2::RectU>;
|
||||
|
||||
void callOverflowFns();
|
||||
|
||||
unsigned m_currentX;
|
||||
unsigned m_currentY;
|
||||
unsigned m_yStep;
|
||||
|
||||
unsigned m_width;
|
||||
unsigned m_height;
|
||||
|
||||
overflowFns m_overflowFns;
|
||||
|
||||
handle_t m_currentHandle;
|
||||
|
||||
rects_t m_rects;
|
||||
|
||||
uint32_t m_maxHandle;
|
||||
uint32_t m_invalidHandle;
|
||||
};
|
||||
} // namespace m2
|
||||
Loading…
Add table
Add a link
Reference in a new issue