28 #include "shadowAtlas.h" 31 NotifyCategoryDef(shadowatlas,
"");
53 nassertv(size > 1 && tile_size >= 1);
54 nassertv(tile_size < size && size % tile_size == 0);
56 _tile_size = tile_size;
73 void ShadowAtlas::init_tiles() {
74 _num_tiles = _size / _tile_size;
75 _flags =
new bool[_num_tiles * _num_tiles];
76 memset(_flags, 0x0,
sizeof(
bool) * _num_tiles * _num_tiles);
92 void ShadowAtlas::reserve_region(
size_t x,
size_t y,
size_t w,
size_t h) {
95 nassertv(x >= 0 && y >= 0 && x + w <= _num_tiles && y + h <= _num_tiles);
97 _num_used_tiles += w * h;
100 for (
size_t cx = 0; cx < w; ++cx) {
101 for (
size_t cy = 0; cy < h; ++cy) {
102 set_tile(cx + x, cy + y,
true);
133 if (tile_width < 1 || tile_height < 1) {
134 shadowatlas_cat.error() <<
"Called find_and_reserve_region with null-region!" << std::endl;
135 return LVecBase4i(-1);
139 if (tile_width > _num_tiles || tile_height > _num_tiles) {
140 shadowatlas_cat.error() <<
"Requested region exceeds shadow atlas size!" << std::endl;
141 return LVecBase4i(-1);
145 for (
size_t x = 0; x <= _num_tiles - tile_width; ++x) {
146 for (
size_t y = 0; y <= _num_tiles - tile_height; ++y) {
147 if (region_is_free(x, y, tile_width, tile_height)) {
149 reserve_region(x, y, tile_width, tile_height);
150 return LVecBase4i(x, y, tile_width, tile_height);
157 shadowatlas_cat.error() <<
"Failed to find a free region of size " << tile_width
158 <<
" x " << tile_height <<
"!" << std::endl;
159 return LVecBase4i(-1);
175 nassertv(region.get_x() >= 0 && region.get_y() >= 0);
176 nassertv(region.get_x() + region.get_z() <= (int)_num_tiles && region.get_y() + region.get_w() <= (int)_num_tiles);
178 _num_used_tiles -= region.get_z() * region.get_w();
180 for (
int x = 0; x < region.get_z(); ++x) {
181 for (
int y = 0; y < region.get_w(); ++y) {
183 set_tile(region.get_x() + x, region.get_y() + y,
false);
~ShadowAtlas()
Destructs the shadow atlas.
ShadowAtlas(size_t size, size_t tile_size=32)
Constructs a new shadow atlas.
void free_region(const LVecBase4i ®ion)
Frees a given region.
LVecBase4i find_and_reserve_region(size_t tile_width, size_t tile_height)
Finds space for a map of the given size in the atlas.