1 module stb.rectpack; 2 3 import 4 std.typecons, 5 std.algorithm, 6 7 stb, 8 stb.rectpack.binding; 9 10 11 struct TexturePacker 12 { 13 this(stbrp_rect[] rects) 14 { 15 _rects = rects; 16 _nodes = new stbrp_node[TEX_MAX]; 17 } 18 19 auto process() 20 { 21 auto w = binarySearch(0, TEX_MAX, a => canPack(a, a) ? -1 : 1); 22 auto h = binarySearch(0, w, a => canPack(w, a) ? -1 : 1); 23 24 // call once more because binarySearch can do some extra failing tries 25 canPack(w, h); 26 27 return tuple!(`w`, `h`)(w, h); 28 29 } 30 31 private: 32 enum TEX_MAX = 16384; 33 34 bool canPack(int w, int h) 35 { 36 stbrp_init_target(&_context, w, h, _nodes.ptr, cast(uint)_nodes.length); 37 return !!stbrp_pack_rects(&_context, _rects.ptr, cast(uint)_rects.length); 38 } 39 40 stbrp_rect[] _rects; 41 stbrp_node[] _nodes; 42 stbrp_context _context; 43 } 44 45 unittest 46 { 47 stbrp_rect[3] arr; 48 49 arr[0] = stbrp_rect(0, 10, 20); // id, w, h 50 arr[1] = stbrp_rect(1, 20, 20); 51 arr[2] = stbrp_rect(2, 40, 20); 52 53 auto res = TexturePacker(arr).process; 54 55 assert(res.w == 40 && res.h == 40); 56 assert(arr[].all!(a => a.was_packed)); 57 }