1 /*************************************************************************/ 2 /* tile_map.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ 10 /* */ 11 /* Permission is hereby granted, free of charge, to any person obtaining */ 12 /* a copy of this software and associated documentation files (the */ 13 /* "Software"), to deal in the Software without restriction, including */ 14 /* without limitation the rights to use, copy, modify, merge, publish, */ 15 /* distribute, sublicense, and/or sell copies of the Software, and to */ 16 /* permit persons to whom the Software is furnished to do so, subject to */ 17 /* the following conditions: */ 18 /* */ 19 /* The above copyright notice and this permission notice shall be */ 20 /* included in all copies or substantial portions of the Software. */ 21 /* */ 22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 29 /*************************************************************************/ 30 #ifndef TILE_MAP_H 31 #define TILE_MAP_H 32 33 #include "scene/2d/navigation2d.h" 34 #include "scene/2d/node_2d.h" 35 #include "scene/resources/tile_set.h" 36 #include "self_list.h" 37 #include "vset.h" 38 39 class TileMap : public Node2D { 40 41 OBJ_TYPE(TileMap, Node2D); 42 43 public: 44 enum Mode { 45 MODE_SQUARE, 46 MODE_ISOMETRIC, 47 MODE_CUSTOM 48 }; 49 50 enum HalfOffset { 51 HALF_OFFSET_X, 52 HALF_OFFSET_Y, 53 HALF_OFFSET_DISABLED, 54 }; 55 56 enum TileOrigin { 57 TILE_ORIGIN_TOP_LEFT, 58 TILE_ORIGIN_CENTER, 59 TILE_ORIGIN_BOTTOM_LEFT 60 }; 61 62 private: 63 Ref<TileSet> tile_set; 64 Size2i cell_size; 65 int quadrant_size; 66 bool center_x, center_y; 67 Mode mode; 68 Matrix32 custom_transform; 69 HalfOffset half_offset; 70 bool use_kinematic; 71 Navigation2D *navigation; 72 73 union PosKey { 74 75 struct { 76 int16_t x; 77 int16_t y; 78 }; 79 uint32_t key; 80 81 //using a more precise comparison so the regions can be sorted later 82 bool operator<(const PosKey &p_k) const { return (y == p_k.y) ? x < p_k.x : y < p_k.y; } 83 PosKey(int16_t p_x,int16_t p_y)84 PosKey(int16_t p_x, int16_t p_y) { 85 x = p_x; 86 y = p_y; 87 } PosKey()88 PosKey() { 89 x = 0; 90 y = 0; 91 } 92 }; 93 94 union Cell { 95 96 struct { 97 int32_t id : 24; 98 bool flip_h : 1; 99 bool flip_v : 1; 100 bool transpose : 1; 101 }; 102 103 uint32_t _u32t; Cell()104 Cell() { _u32t = 0; } 105 }; 106 107 Map<PosKey, Cell> tile_map; 108 struct Quadrant { 109 110 Vector2 pos; 111 List<RID> canvas_items; 112 Vector<RID> bodies; 113 114 SelfList<Quadrant> dirty_list; 115 116 struct NavPoly { 117 int id; 118 Matrix32 xform; 119 }; 120 121 struct Occluder { 122 RID id; 123 Matrix32 xform; 124 }; 125 126 Map<PosKey, NavPoly> navpoly_ids; 127 Map<PosKey, Occluder> occluder_instances; 128 129 VSet<PosKey> cells; 130 131 void operator=(const Quadrant &q) { 132 pos = q.pos; 133 canvas_items = q.canvas_items; 134 bodies = q.bodies; 135 cells = q.cells; 136 navpoly_ids = q.navpoly_ids; 137 occluder_instances = q.occluder_instances; 138 } QuadrantQuadrant139 Quadrant(const Quadrant &q) : 140 dirty_list(this) { 141 pos = q.pos; 142 canvas_items = q.canvas_items; 143 bodies = q.bodies; 144 cells = q.cells; 145 occluder_instances = q.occluder_instances; 146 navpoly_ids = q.navpoly_ids; 147 } QuadrantQuadrant148 Quadrant() : 149 dirty_list(this) {} 150 }; 151 152 Map<PosKey, Quadrant> quadrant_map; 153 154 SelfList<Quadrant>::List dirty_quadrant_list; 155 156 bool pending_update; 157 158 Rect2 rect_cache; 159 bool rect_cache_dirty; 160 Rect2 used_size_cache; 161 bool used_size_cache_dirty; 162 bool quadrant_order_dirty; 163 bool y_sort_mode; 164 float fp_adjust; 165 float friction; 166 float bounce; 167 uint32_t collision_layer; 168 uint32_t collision_mask; 169 170 TileOrigin tile_origin; 171 172 int occluder_light_mask; 173 174 void _fix_cell_transform(Matrix32 &xform, const Cell &p_cell, const Vector2 &p_offset, const Size2 &p_sc); 175 176 Map<PosKey, Quadrant>::Element *_create_quadrant(const PosKey &p_qk); 177 void _erase_quadrant(Map<PosKey, Quadrant>::Element *Q); 178 void _make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q); 179 void _recreate_quadrants(); 180 void _clear_quadrants(); 181 void _update_dirty_quadrants(); 182 void _update_quadrant_space(const RID &p_space); 183 void _update_quadrant_transform(); 184 void _recompute_rect_cache(); 185 186 void _update_all_items_material_state(); 187 _FORCE_INLINE_ void _update_item_material_state(const RID &p_canvas_item); 188 189 _FORCE_INLINE_ int _get_quadrant_size() const; 190 191 void _set_tile_data(const DVector<int> &p_data); 192 DVector<int> _get_tile_data() const; 193 _set_old_cell_size(int p_size)194 void _set_old_cell_size(int p_size) { set_cell_size(Size2(p_size, p_size)); } _get_old_cell_size()195 int _get_old_cell_size() const { return cell_size.x; } 196 197 _FORCE_INLINE_ Vector2 _map_to_world(int p_x, int p_y, bool p_ignore_ofs = false) const; 198 199 protected: 200 void _notification(int p_what); 201 static void _bind_methods(); 202 203 public: 204 enum { 205 INVALID_CELL = -1 206 }; 207 208 void set_tileset(const Ref<TileSet> &p_tileset); 209 Ref<TileSet> get_tileset() const; 210 211 void set_cell_size(Size2 p_size); 212 Size2 get_cell_size() const; 213 214 void set_quadrant_size(int p_size); 215 int get_quadrant_size() const; 216 217 void set_center_x(bool p_enable); 218 bool get_center_x() const; 219 void set_center_y(bool p_enable); 220 bool get_center_y() const; 221 222 void set_cell(int p_x, int p_y, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false); 223 int get_cell(int p_x, int p_y) const; 224 bool is_cell_x_flipped(int p_x, int p_y) const; 225 bool is_cell_y_flipped(int p_x, int p_y) const; 226 bool is_cell_transposed(int p_x, int p_y) const; 227 228 void set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false); 229 int get_cellv(const Vector2 &p_pos) const; 230 231 Rect2 get_item_rect() const; 232 233 void set_collision_layer(uint32_t p_layer); 234 uint32_t get_collision_layer() const; 235 236 void set_collision_mask(uint32_t p_mask); 237 uint32_t get_collision_mask() const; 238 239 void set_collision_layer_bit(int p_bit, bool p_value); 240 bool get_collision_layer_bit(int p_bit) const; 241 242 void set_collision_mask_bit(int p_bit, bool p_value); 243 bool get_collision_mask_bit(int p_bit) const; 244 245 void set_collision_use_kinematic(bool p_use_kinematic); 246 bool get_collision_use_kinematic() const; 247 248 void set_collision_friction(float p_friction); 249 float get_collision_friction() const; 250 251 void set_collision_bounce(float p_bounce); 252 float get_collision_bounce() const; 253 254 void set_mode(Mode p_mode); 255 Mode get_mode() const; 256 257 void set_half_offset(HalfOffset p_half_offset); 258 HalfOffset get_half_offset() const; 259 260 void set_tile_origin(TileOrigin p_tile_origin); 261 TileOrigin get_tile_origin() const; 262 263 void set_custom_transform(const Matrix32 &p_xform); 264 Matrix32 get_custom_transform() const; 265 266 Matrix32 get_cell_transform() const; 267 Vector2 get_cell_draw_offset() const; 268 269 Vector2 map_to_world(const Vector2 &p_pos, bool p_ignore_ofs = false) const; 270 Vector2 world_to_map(const Vector2 &p_pos) const; 271 272 void set_y_sort_mode(bool p_enable); 273 bool is_y_sort_mode_enabled() const; 274 275 Array get_used_cells() const; 276 Array get_used_cells_by_id(int p_id) const; 277 Rect2 get_used_rect(); // Not const because of cache 278 279 void set_occluder_light_mask(int p_mask); 280 int get_occluder_light_mask() const; 281 282 virtual void set_light_mask(int p_light_mask); 283 284 virtual void set_material(const Ref<CanvasItemMaterial> &p_material); 285 286 virtual void set_use_parent_material(bool p_use_parent_material); 287 288 void clear(); 289 290 TileMap(); 291 ~TileMap(); 292 }; 293 294 VARIANT_ENUM_CAST(TileMap::Mode); 295 VARIANT_ENUM_CAST(TileMap::HalfOffset); 296 VARIANT_ENUM_CAST(TileMap::TileOrigin); 297 298 #endif // TILE_MAP_H 299