tile_map.cpp 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030
  1. /**************************************************************************/
  2. /* tile_map.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  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. #include "tile_map.h"
  31. #include "collision_object_2d.h"
  32. #include "core/io/marshalls.h"
  33. #include "core/method_bind_ext.gen.inc"
  34. #include "core/os/os.h"
  35. #include "scene/2d/area_2d.h"
  36. #include "servers/navigation_2d_server.h"
  37. #include "servers/physics_2d_server.h"
  38. #include "servers/visual/visual_server_canvas_helper.h"
  39. void TileMap::Quadrant::clear_navpoly() {
  40. for (Map<PosKey, Quadrant::NavPoly>::Element *E = navpoly_ids.front(); E; E = E->next()) {
  41. RID region = E->get().region;
  42. Navigation2DServer::get_singleton()->region_set_map(region, RID());
  43. Navigation2DServer::get_singleton()->free(region);
  44. }
  45. navpoly_ids.clear();
  46. }
  47. int TileMap::_get_quadrant_size() const {
  48. if (y_sort_mode) {
  49. return 1;
  50. } else {
  51. return quadrant_size;
  52. }
  53. }
  54. void TileMap::_notification(int p_what) {
  55. switch (p_what) {
  56. case NOTIFICATION_ENTER_TREE: {
  57. Node2D *c = this;
  58. while (c) {
  59. navigation = Object::cast_to<Navigation2D>(c);
  60. if (navigation) {
  61. // only for <3.5 backward compatibility
  62. bake_navigation = true;
  63. break;
  64. }
  65. c = Object::cast_to<Node2D>(c->get_parent());
  66. }
  67. if (use_parent) {
  68. _clear_quadrants();
  69. collision_parent = Object::cast_to<CollisionObject2D>(get_parent());
  70. }
  71. pending_update = true;
  72. _recreate_quadrants();
  73. update_dirty_quadrants();
  74. RID space = get_world_2d()->get_space();
  75. _update_quadrant_transform();
  76. _update_quadrant_space(space);
  77. update_configuration_warning();
  78. } break;
  79. case NOTIFICATION_EXIT_TREE: {
  80. _update_quadrant_space(RID());
  81. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  82. Quadrant &q = E->get();
  83. if (bake_navigation) {
  84. q.clear_navpoly();
  85. }
  86. if (collision_parent) {
  87. collision_parent->remove_shape_owner(q.shape_owner_id);
  88. q.shape_owner_id = -1;
  89. }
  90. for (Map<PosKey, Quadrant::Occluder>::Element *F = q.occluder_instances.front(); F; F = F->next()) {
  91. if (F->get().id.is_valid()) {
  92. VS::get_singleton()->free(F->get().id);
  93. }
  94. }
  95. q.occluder_instances.clear();
  96. }
  97. collision_parent = nullptr;
  98. navigation = nullptr;
  99. } break;
  100. case NOTIFICATION_TRANSFORM_CHANGED: {
  101. //move stuff
  102. _update_quadrant_transform();
  103. } break;
  104. case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
  105. if (use_parent) {
  106. _recreate_quadrants();
  107. }
  108. } break;
  109. case NOTIFICATION_VISIBILITY_CHANGED: {
  110. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  111. for (Map<PosKey, Quadrant::Occluder>::Element *F = E->get().occluder_instances.front(); F; F = F->next()) {
  112. VS::get_singleton()->canvas_light_occluder_set_enabled(F->get().id, is_visible());
  113. }
  114. }
  115. } break;
  116. case NOTIFICATION_RESET_PHYSICS_INTERPOLATION: {
  117. if (is_visible_in_tree() && is_physics_interpolated_and_enabled()) {
  118. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  119. Quadrant &q = E->get();
  120. for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) {
  121. VisualServer::get_singleton()->canvas_item_reset_physics_interpolation(F->get());
  122. }
  123. }
  124. }
  125. } break;
  126. }
  127. }
  128. void TileMap::_update_quadrant_space(const RID &p_space) {
  129. if (!use_parent) {
  130. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  131. Quadrant &q = E->get();
  132. Physics2DServer::get_singleton()->body_set_space(q.body, p_space);
  133. }
  134. }
  135. }
  136. void TileMap::_update_quadrant_transform() {
  137. if (!is_inside_tree()) {
  138. return;
  139. }
  140. Transform2D global_transform = get_global_transform();
  141. Transform2D local_transform;
  142. if (collision_parent) {
  143. local_transform = get_transform();
  144. }
  145. Transform2D nav_rel;
  146. if (bake_navigation) {
  147. if (navigation) {
  148. nav_rel = get_relative_transform_to_parent(navigation);
  149. } else {
  150. nav_rel = get_global_transform();
  151. }
  152. }
  153. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  154. Quadrant &q = E->get();
  155. Transform2D xform;
  156. xform.set_origin(q.pos);
  157. if (!use_parent) {
  158. xform = global_transform * xform;
  159. Physics2DServer::get_singleton()->body_set_state(q.body, Physics2DServer::BODY_STATE_TRANSFORM, xform);
  160. }
  161. if (bake_navigation) {
  162. for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
  163. Navigation2DServer::get_singleton()->region_set_transform(F->get().region, nav_rel * F->get().xform);
  164. }
  165. }
  166. for (Map<PosKey, Quadrant::Occluder>::Element *F = q.occluder_instances.front(); F; F = F->next()) {
  167. VS::get_singleton()->canvas_light_occluder_set_transform(F->get().id, global_transform * F->get().xform);
  168. }
  169. }
  170. }
  171. void TileMap::set_tileset(const Ref<TileSet> &p_tileset) {
  172. if (tile_set.is_valid()) {
  173. tile_set->disconnect("changed", this, "_recreate_quadrants");
  174. tile_set->remove_change_receptor(this);
  175. }
  176. _clear_quadrants();
  177. tile_set = p_tileset;
  178. if (tile_set.is_valid()) {
  179. tile_set->connect("changed", this, "_recreate_quadrants");
  180. tile_set->add_change_receptor(this);
  181. } else {
  182. clear();
  183. }
  184. _recreate_quadrants();
  185. emit_signal("settings_changed");
  186. }
  187. Ref<TileSet> TileMap::get_tileset() const {
  188. return tile_set;
  189. }
  190. void TileMap::set_cell_size(Size2 p_size) {
  191. ERR_FAIL_COND(p_size.x < 1 || p_size.y < 1);
  192. _clear_quadrants();
  193. cell_size = p_size;
  194. _recreate_quadrants();
  195. emit_signal("settings_changed");
  196. }
  197. Size2 TileMap::get_cell_size() const {
  198. return cell_size;
  199. }
  200. void TileMap::set_quadrant_size(int p_size) {
  201. ERR_FAIL_COND_MSG(p_size < 1, "Quadrant size cannot be smaller than 1.");
  202. _clear_quadrants();
  203. quadrant_size = p_size;
  204. _recreate_quadrants();
  205. emit_signal("settings_changed");
  206. }
  207. int TileMap::get_quadrant_size() const {
  208. return quadrant_size;
  209. }
  210. void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const Vector2 &p_offset, const Size2 &p_sc) {
  211. Size2 s = p_sc;
  212. Vector2 offset = p_offset;
  213. if (compatibility_mode && !centered_textures) {
  214. if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) {
  215. offset.y += cell_size.y;
  216. } else if (tile_origin == TILE_ORIGIN_CENTER) {
  217. offset += cell_size / 2;
  218. }
  219. if (s.y > s.x) {
  220. if ((p_cell.flip_h && (p_cell.flip_v || p_cell.transpose)) || (p_cell.flip_v && !p_cell.transpose)) {
  221. offset.y += s.y - s.x;
  222. }
  223. } else if (s.y < s.x) {
  224. if ((p_cell.flip_v && (p_cell.flip_h || p_cell.transpose)) || (p_cell.flip_h && !p_cell.transpose)) {
  225. offset.x += s.x - s.y;
  226. }
  227. }
  228. }
  229. if (p_cell.transpose) {
  230. SWAP(xform.elements[0].x, xform.elements[0].y);
  231. SWAP(xform.elements[1].x, xform.elements[1].y);
  232. SWAP(offset.x, offset.y);
  233. SWAP(s.x, s.y);
  234. }
  235. if (p_cell.flip_h) {
  236. xform.elements[0].x = -xform.elements[0].x;
  237. xform.elements[1].x = -xform.elements[1].x;
  238. if (compatibility_mode && !centered_textures) {
  239. if (tile_origin == TILE_ORIGIN_TOP_LEFT || tile_origin == TILE_ORIGIN_BOTTOM_LEFT) {
  240. offset.x = s.x - offset.x;
  241. } else if (tile_origin == TILE_ORIGIN_CENTER) {
  242. offset.x = s.x - offset.x / 2;
  243. }
  244. } else {
  245. offset.x = s.x - offset.x;
  246. }
  247. }
  248. if (p_cell.flip_v) {
  249. xform.elements[0].y = -xform.elements[0].y;
  250. xform.elements[1].y = -xform.elements[1].y;
  251. if (compatibility_mode && !centered_textures) {
  252. if (tile_origin == TILE_ORIGIN_TOP_LEFT) {
  253. offset.y = s.y - offset.y;
  254. } else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) {
  255. offset.y += s.y;
  256. } else if (tile_origin == TILE_ORIGIN_CENTER) {
  257. offset.y += s.y;
  258. }
  259. } else {
  260. offset.y = s.y - offset.y;
  261. }
  262. }
  263. if (centered_textures) {
  264. offset += cell_size / 2 - s / 2;
  265. }
  266. xform.elements[2] += offset;
  267. }
  268. void TileMap::_add_shape(int &shape_idx, const Quadrant &p_q, const Ref<Shape2D> &p_shape, const TileSet::ShapeData &p_shape_data, const Transform2D &p_xform, const Vector2 &p_metadata) {
  269. Physics2DServer *ps = Physics2DServer::get_singleton();
  270. if (!use_parent) {
  271. ps->body_add_shape(p_q.body, p_shape->get_rid(), p_xform);
  272. ps->body_set_shape_metadata(p_q.body, shape_idx, p_metadata);
  273. ps->body_set_shape_as_one_way_collision(p_q.body, shape_idx, p_shape_data.one_way_collision, p_shape_data.one_way_collision_margin);
  274. } else if (collision_parent) {
  275. Transform2D xform = p_xform;
  276. xform.set_origin(xform.get_origin() + p_q.pos);
  277. collision_parent->shape_owner_add_shape(p_q.shape_owner_id, p_shape);
  278. int real_index = collision_parent->shape_owner_get_shape_index(p_q.shape_owner_id, shape_idx);
  279. RID rid = collision_parent->get_rid();
  280. if (Object::cast_to<Area2D>(collision_parent) != nullptr) {
  281. ps->area_set_shape_transform(rid, real_index, get_transform() * xform);
  282. } else {
  283. ps->body_set_shape_transform(rid, real_index, get_transform() * xform);
  284. ps->body_set_shape_metadata(rid, real_index, p_metadata);
  285. ps->body_set_shape_as_one_way_collision(rid, real_index, p_shape_data.one_way_collision, p_shape_data.one_way_collision_margin);
  286. }
  287. }
  288. shape_idx++;
  289. }
  290. void TileMap::update_dirty_quadrants() {
  291. if (!pending_update) {
  292. return;
  293. }
  294. if (!is_inside_tree() || !tile_set.is_valid()) {
  295. pending_update = false;
  296. return;
  297. }
  298. VisualServer *vs = VisualServer::get_singleton();
  299. Physics2DServer *ps = Physics2DServer::get_singleton();
  300. Vector2 tofs = get_cell_draw_offset();
  301. Transform2D nav_rel;
  302. if (bake_navigation) {
  303. if (navigation) {
  304. nav_rel = get_relative_transform_to_parent(navigation);
  305. } else {
  306. nav_rel = get_global_transform();
  307. }
  308. }
  309. Vector2 qofs;
  310. SceneTree *st = SceneTree::get_singleton();
  311. Color debug_collision_color;
  312. Color debug_navigation_color;
  313. bool debug_shapes = false;
  314. if (st) {
  315. if (Engine::get_singleton()->is_editor_hint()) {
  316. debug_shapes = show_collision;
  317. } else {
  318. debug_shapes = st->is_debugging_collisions_hint();
  319. }
  320. if (debug_shapes) {
  321. debug_collision_color = st->get_debug_collisions_color();
  322. }
  323. }
  324. bool debug_navigation = st && st->is_debugging_navigation_hint();
  325. if (debug_navigation) {
  326. debug_navigation_color = st->get_debug_navigation_color();
  327. }
  328. while (dirty_quadrant_list.first()) {
  329. Quadrant &q = *dirty_quadrant_list.first()->self();
  330. for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) {
  331. if (E->get().is_valid()) {
  332. vs->free(E->get());
  333. }
  334. }
  335. q.canvas_items.clear();
  336. if (!use_parent) {
  337. ps->body_clear_shapes(q.body);
  338. } else if (collision_parent) {
  339. collision_parent->shape_owner_clear_shapes(q.shape_owner_id);
  340. }
  341. int shape_idx = 0;
  342. if (bake_navigation) {
  343. q.clear_navpoly();
  344. }
  345. for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) {
  346. if (E->get().id.is_valid()) {
  347. VS::get_singleton()->free(E->get().id);
  348. }
  349. }
  350. q.occluder_instances.clear();
  351. Ref<ShaderMaterial> prev_material;
  352. int prev_z_index = 0;
  353. RID prev_canvas_item;
  354. RID prev_debug_canvas_item;
  355. bool multirect_started = false;
  356. for (int i = 0; i < q.cells.size(); i++) {
  357. Map<PosKey, Cell>::Element *E = tile_map.find(q.cells[i]);
  358. Cell &c = E->get();
  359. //moment of truth
  360. if (!tile_set->has_tile(c.id)) {
  361. continue;
  362. }
  363. Ref<Texture> tex = tile_set->tile_get_texture(c.id);
  364. Vector2 tile_ofs = tile_set->tile_get_texture_offset(c.id);
  365. Vector2 wofs = _map_to_world(E->key().x, E->key().y);
  366. Vector2 offset = wofs - q.pos + tofs;
  367. if (!tex.is_valid()) {
  368. continue;
  369. }
  370. Ref<ShaderMaterial> mat = tile_set->tile_get_material(c.id);
  371. int z_index = tile_set->tile_get_z_index(c.id);
  372. if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) {
  373. z_index += tile_set->autotile_get_z_index(c.id, Vector2(c.autotile_coord_x, c.autotile_coord_y));
  374. }
  375. RID canvas_item;
  376. RID debug_canvas_item;
  377. if (prev_canvas_item == RID() || prev_material != mat || prev_z_index != z_index) {
  378. canvas_item = RID_PRIME(vs->canvas_item_create());
  379. if (mat.is_valid()) {
  380. vs->canvas_item_set_material(canvas_item, mat->get_rid());
  381. }
  382. vs->canvas_item_set_parent(canvas_item, get_canvas_item());
  383. _update_item_material_state(canvas_item);
  384. Transform2D xform;
  385. xform.set_origin(q.pos);
  386. vs->canvas_item_set_transform(canvas_item, xform);
  387. vs->canvas_item_set_light_mask(canvas_item, get_light_mask());
  388. vs->canvas_item_set_z_index(canvas_item, z_index);
  389. q.canvas_items.push_back(canvas_item);
  390. if (debug_shapes) {
  391. debug_canvas_item = RID_PRIME(vs->canvas_item_create());
  392. vs->canvas_item_set_parent(debug_canvas_item, canvas_item);
  393. vs->canvas_item_set_z_as_relative_to_parent(debug_canvas_item, false);
  394. vs->canvas_item_set_z_index(debug_canvas_item, VS::CANVAS_ITEM_Z_MAX - 1);
  395. q.canvas_items.push_back(debug_canvas_item);
  396. prev_debug_canvas_item = debug_canvas_item;
  397. }
  398. prev_canvas_item = canvas_item;
  399. prev_material = mat;
  400. prev_z_index = z_index;
  401. } else {
  402. canvas_item = prev_canvas_item;
  403. if (debug_shapes) {
  404. debug_canvas_item = prev_debug_canvas_item;
  405. }
  406. }
  407. Rect2 r = tile_set->tile_get_region(c.id);
  408. if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) {
  409. int spacing = tile_set->autotile_get_spacing(c.id);
  410. r.size = tile_set->autotile_get_size(c.id);
  411. r.position += (r.size + Vector2(spacing, spacing)) * Vector2(c.autotile_coord_x, c.autotile_coord_y);
  412. }
  413. Size2 s;
  414. if (r == Rect2()) {
  415. s = tex->get_size();
  416. } else {
  417. s = r.size;
  418. }
  419. Rect2 rect;
  420. rect.position = offset.floor();
  421. rect.size = s;
  422. rect.size.x += fp_adjust;
  423. rect.size.y += fp_adjust;
  424. if (compatibility_mode && !centered_textures) {
  425. if (rect.size.y > rect.size.x) {
  426. if ((c.flip_h && (c.flip_v || c.transpose)) || (c.flip_v && !c.transpose)) {
  427. tile_ofs.y += rect.size.y - rect.size.x;
  428. }
  429. } else if (rect.size.y < rect.size.x) {
  430. if ((c.flip_v && (c.flip_h || c.transpose)) || (c.flip_h && !c.transpose)) {
  431. tile_ofs.x += rect.size.x - rect.size.y;
  432. }
  433. }
  434. }
  435. if (c.transpose) {
  436. SWAP(tile_ofs.x, tile_ofs.y);
  437. if (centered_textures) {
  438. rect.position.x += cell_size.x / 2 - rect.size.y / 2;
  439. rect.position.y += cell_size.y / 2 - rect.size.x / 2;
  440. }
  441. } else if (centered_textures) {
  442. rect.position += cell_size / 2 - rect.size / 2;
  443. }
  444. if (c.flip_h) {
  445. rect.size.x = -rect.size.x;
  446. tile_ofs.x = -tile_ofs.x;
  447. }
  448. if (c.flip_v) {
  449. rect.size.y = -rect.size.y;
  450. tile_ofs.y = -tile_ofs.y;
  451. }
  452. if (compatibility_mode && !centered_textures) {
  453. if (tile_origin == TILE_ORIGIN_TOP_LEFT) {
  454. rect.position += tile_ofs;
  455. } else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) {
  456. rect.position += tile_ofs;
  457. if (c.transpose) {
  458. if (c.flip_h) {
  459. rect.position.x -= cell_size.x;
  460. } else {
  461. rect.position.x += cell_size.x;
  462. }
  463. } else {
  464. if (c.flip_v) {
  465. rect.position.y -= cell_size.y;
  466. } else {
  467. rect.position.y += cell_size.y;
  468. }
  469. }
  470. } else if (tile_origin == TILE_ORIGIN_CENTER) {
  471. rect.position += tile_ofs;
  472. if (c.flip_h) {
  473. rect.position.x -= cell_size.x / 2;
  474. } else {
  475. rect.position.x += cell_size.x / 2;
  476. }
  477. if (c.flip_v) {
  478. rect.position.y -= cell_size.y / 2;
  479. } else {
  480. rect.position.y += cell_size.y / 2;
  481. }
  482. }
  483. } else {
  484. rect.position += tile_ofs;
  485. }
  486. Ref<Texture> normal_map = tile_set->tile_get_normal_map(c.id);
  487. Color modulate = tile_set->tile_get_modulate(c.id) * get_self_modulate();
  488. if (r == Rect2()) {
  489. tex->draw_rect(canvas_item, rect, false, modulate, c.transpose, normal_map);
  490. } else {
  491. Texture::RefineRectResult res = tex->refine_rect_region(rect, r);
  492. switch (res) {
  493. case Texture::REFINE_RECT_RESULT_DRAW: {
  494. if (!multirect_started) {
  495. multirect_started = true;
  496. VisualServerCanvasHelper::tilemap_begin();
  497. }
  498. VisualServerCanvasHelper::tilemap_add_rect(canvas_item, rect, tex->get_rid(), r, modulate, c.transpose, normal_map.is_valid() ? normal_map->get_rid() : RID(), clip_uv);
  499. } break;
  500. case Texture::REFINE_RECT_RESULT_FALLBACK: {
  501. if (multirect_started) {
  502. // If we are currently writing a multirect, we must flush
  503. // to ensure there are no issues due to overlap.
  504. VisualServerCanvasHelper::tilemap_end();
  505. multirect_started = false;
  506. }
  507. tex->draw_rect_region(canvas_item, rect, r, modulate, c.transpose, normal_map, clip_uv);
  508. } break;
  509. default: {
  510. } break;
  511. }
  512. }
  513. Vector<TileSet::ShapeData> shapes = tile_set->tile_get_shapes(c.id);
  514. for (int j = 0; j < shapes.size(); j++) {
  515. Ref<Shape2D> shape = shapes[j].shape;
  516. if (shape.is_valid()) {
  517. if (tile_set->tile_get_tile_mode(c.id) == TileSet::SINGLE_TILE || (shapes[j].autotile_coord.x == c.autotile_coord_x && shapes[j].autotile_coord.y == c.autotile_coord_y)) {
  518. Transform2D xform;
  519. xform.set_origin(offset.floor() + tile_ofs);
  520. Vector2 shape_ofs = shapes[j].shape_transform.get_origin();
  521. _fix_cell_transform(xform, c, shape_ofs, s);
  522. xform *= shapes[j].shape_transform.untranslated();
  523. if (debug_canvas_item.is_valid()) {
  524. vs->canvas_item_add_set_transform(debug_canvas_item, xform);
  525. shape->draw(debug_canvas_item, debug_collision_color);
  526. }
  527. if (shape->has_meta("decomposed")) {
  528. Array _shapes = shape->get_meta("decomposed");
  529. for (int k = 0; k < _shapes.size(); k++) {
  530. Ref<ConvexPolygonShape2D> convex = _shapes[k];
  531. if (convex.is_valid()) {
  532. _add_shape(shape_idx, q, convex, shapes[j], xform, Vector2(E->key().x, E->key().y));
  533. #ifdef DEBUG_ENABLED
  534. } else {
  535. print_error("The TileSet assigned to the TileMap " + get_name() + " has an invalid convex shape.");
  536. #endif
  537. }
  538. }
  539. } else {
  540. _add_shape(shape_idx, q, shape, shapes[j], xform, Vector2(E->key().x, E->key().y));
  541. }
  542. }
  543. }
  544. }
  545. if (debug_canvas_item.is_valid()) {
  546. vs->canvas_item_add_set_transform(debug_canvas_item, Transform2D());
  547. }
  548. if (bake_navigation) {
  549. Ref<NavigationPolygon> navpoly;
  550. Vector2 npoly_ofs;
  551. if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) {
  552. navpoly = tile_set->autotile_get_navigation_polygon(c.id, Vector2(c.autotile_coord_x, c.autotile_coord_y));
  553. npoly_ofs = Vector2();
  554. } else {
  555. navpoly = tile_set->tile_get_navigation_polygon(c.id);
  556. npoly_ofs = tile_set->tile_get_navigation_polygon_offset(c.id);
  557. }
  558. if (navpoly.is_valid()) {
  559. Transform2D xform;
  560. xform.set_origin(offset.floor() + q.pos + tile_ofs);
  561. _fix_cell_transform(xform, c, npoly_ofs, s);
  562. RID region = Navigation2DServer::get_singleton()->region_create();
  563. if (navigation) {
  564. Navigation2DServer::get_singleton()->region_set_map(region, navigation->get_rid());
  565. } else {
  566. Navigation2DServer::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
  567. }
  568. Navigation2DServer::get_singleton()->region_set_navigation_layers(region, navigation_layers);
  569. Navigation2DServer::get_singleton()->region_set_transform(region, nav_rel * xform);
  570. Navigation2DServer::get_singleton()->region_set_navpoly(region, navpoly);
  571. Quadrant::NavPoly np;
  572. np.region = region;
  573. np.xform = xform;
  574. q.navpoly_ids[E->key()] = np;
  575. if (debug_navigation) {
  576. RID debug_navigation_item = RID_PRIME(vs->canvas_item_create());
  577. vs->canvas_item_set_parent(debug_navigation_item, canvas_item);
  578. vs->canvas_item_set_z_as_relative_to_parent(debug_navigation_item, false);
  579. vs->canvas_item_set_z_index(debug_navigation_item, VS::CANVAS_ITEM_Z_MAX - 2); // Display one below collision debug
  580. if (debug_navigation_item.is_valid()) {
  581. PoolVector<Vector2> navigation_polygon_vertices = navpoly->get_vertices();
  582. int vsize = navigation_polygon_vertices.size();
  583. if (vsize > 2) {
  584. Vector<Color> colors;
  585. Vector<Vector2> vertices;
  586. vertices.resize(vsize);
  587. colors.resize(vsize);
  588. {
  589. PoolVector<Vector2>::Read vr = navigation_polygon_vertices.read();
  590. for (int j = 0; j < vsize; j++) {
  591. vertices.write[j] = vr[j];
  592. colors.write[j] = debug_navigation_color;
  593. }
  594. }
  595. Vector<int> indices;
  596. for (int j = 0; j < navpoly->get_polygon_count(); j++) {
  597. Vector<int> polygon = navpoly->get_polygon(j);
  598. for (int k = 2; k < polygon.size(); k++) {
  599. int kofs[3] = { 0, k - 1, k };
  600. for (int l = 0; l < 3; l++) {
  601. int idx = polygon[kofs[l]];
  602. ERR_FAIL_INDEX(idx, vsize);
  603. indices.push_back(idx);
  604. }
  605. }
  606. }
  607. Transform2D navxform;
  608. navxform.set_origin(offset.floor() + tile_ofs);
  609. _fix_cell_transform(navxform, c, npoly_ofs, s);
  610. vs->canvas_item_set_transform(debug_navigation_item, navxform);
  611. vs->canvas_item_add_triangle_array(debug_navigation_item, indices, vertices, colors);
  612. }
  613. }
  614. }
  615. }
  616. }
  617. Ref<OccluderPolygon2D> occluder;
  618. if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) {
  619. occluder = tile_set->autotile_get_light_occluder(c.id, Vector2(c.autotile_coord_x, c.autotile_coord_y));
  620. } else {
  621. occluder = tile_set->tile_get_light_occluder(c.id);
  622. }
  623. if (occluder.is_valid()) {
  624. Vector2 occluder_ofs = tile_set->tile_get_occluder_offset(c.id);
  625. Transform2D xform;
  626. xform.set_origin(offset.floor() + q.pos);
  627. _fix_cell_transform(xform, c, occluder_ofs, s);
  628. RID orid = RID_PRIME(VS::get_singleton()->canvas_light_occluder_create());
  629. VS::get_singleton()->canvas_light_occluder_set_transform(orid, get_global_transform() * xform);
  630. VS::get_singleton()->canvas_light_occluder_set_polygon(orid, occluder->get_rid());
  631. VS::get_singleton()->canvas_light_occluder_attach_to_canvas(orid, get_canvas());
  632. VS::get_singleton()->canvas_light_occluder_set_light_mask(orid, occluder_light_mask);
  633. VS::get_singleton()->canvas_light_occluder_set_enabled(orid, is_visible());
  634. Quadrant::Occluder oc;
  635. oc.xform = xform;
  636. oc.id = orid;
  637. q.occluder_instances[E->key()] = oc;
  638. }
  639. }
  640. if (multirect_started) {
  641. VisualServerCanvasHelper::tilemap_end();
  642. }
  643. // Reset physics interpolation for any recreated canvas items.
  644. if (is_physics_interpolated_and_enabled() && is_visible_in_tree()) {
  645. for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) {
  646. VisualServer::get_singleton()->canvas_item_reset_physics_interpolation(F->get());
  647. }
  648. }
  649. dirty_quadrant_list.remove(dirty_quadrant_list.first());
  650. quadrant_order_dirty = true;
  651. }
  652. pending_update = false;
  653. if (quadrant_order_dirty) {
  654. int index = -(int64_t)0x80000000; //always must be drawn below children
  655. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  656. Quadrant &q = E->get();
  657. for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) {
  658. VS::get_singleton()->canvas_item_set_draw_index(F->get(), index++);
  659. }
  660. }
  661. quadrant_order_dirty = false;
  662. }
  663. _recompute_rect_cache();
  664. }
  665. void TileMap::_recompute_rect_cache() {
  666. #ifdef DEBUG_ENABLED
  667. if (!rect_cache_dirty) {
  668. return;
  669. }
  670. Rect2 r_total;
  671. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  672. Rect2 r;
  673. r.position = _map_to_world(E->key().x * _get_quadrant_size(), E->key().y * _get_quadrant_size());
  674. r.expand_to(_map_to_world(E->key().x * _get_quadrant_size() + _get_quadrant_size(), E->key().y * _get_quadrant_size()));
  675. r.expand_to(_map_to_world(E->key().x * _get_quadrant_size() + _get_quadrant_size(), E->key().y * _get_quadrant_size() + _get_quadrant_size()));
  676. r.expand_to(_map_to_world(E->key().x * _get_quadrant_size(), E->key().y * _get_quadrant_size() + _get_quadrant_size()));
  677. if (E == quadrant_map.front()) {
  678. r_total = r;
  679. } else {
  680. r_total = r_total.merge(r);
  681. }
  682. }
  683. rect_cache = r_total;
  684. item_rect_changed();
  685. rect_cache_dirty = false;
  686. #endif
  687. }
  688. Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(const PosKey &p_qk) {
  689. Transform2D xform;
  690. //xform.set_origin(Point2(p_qk.x,p_qk.y)*cell_size*quadrant_size);
  691. Quadrant q;
  692. q.pos = _map_to_world(p_qk.x * _get_quadrant_size(), p_qk.y * _get_quadrant_size());
  693. q.pos += get_cell_draw_offset();
  694. if (tile_origin == TILE_ORIGIN_CENTER) {
  695. q.pos += cell_size / 2;
  696. } else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) {
  697. q.pos.y += cell_size.y;
  698. }
  699. xform.set_origin(q.pos);
  700. //q.canvas_item = VisualServer::get_singleton()->canvas_item_create();
  701. if (!use_parent) {
  702. q.body = RID_PRIME(Physics2DServer::get_singleton()->body_create());
  703. Physics2DServer::get_singleton()->body_set_mode(q.body, use_kinematic ? Physics2DServer::BODY_MODE_KINEMATIC : Physics2DServer::BODY_MODE_STATIC);
  704. Physics2DServer::get_singleton()->body_attach_object_instance_id(q.body, get_instance_id());
  705. Physics2DServer::get_singleton()->body_set_collision_layer(q.body, collision_layer);
  706. Physics2DServer::get_singleton()->body_set_collision_mask(q.body, collision_mask);
  707. Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_FRICTION, friction);
  708. Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_BOUNCE, bounce);
  709. if (is_inside_tree()) {
  710. xform = get_global_transform() * xform;
  711. RID space = get_world_2d()->get_space();
  712. Physics2DServer::get_singleton()->body_set_space(q.body, space);
  713. }
  714. Physics2DServer::get_singleton()->body_set_state(q.body, Physics2DServer::BODY_STATE_TRANSFORM, xform);
  715. } else if (collision_parent) {
  716. xform = get_transform() * xform;
  717. q.shape_owner_id = collision_parent->create_shape_owner(this);
  718. } else {
  719. q.shape_owner_id = -1;
  720. }
  721. rect_cache_dirty = true;
  722. quadrant_order_dirty = true;
  723. return quadrant_map.insert(p_qk, q);
  724. }
  725. void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) {
  726. Quadrant &q = Q->get();
  727. if (!use_parent) {
  728. if (q.body.is_valid()) {
  729. Physics2DServer::get_singleton()->free(q.body);
  730. q.body = RID();
  731. }
  732. } else if (collision_parent) {
  733. collision_parent->remove_shape_owner(q.shape_owner_id);
  734. }
  735. for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) {
  736. if (E->get().is_valid()) {
  737. VisualServer::get_singleton()->free(E->get());
  738. }
  739. }
  740. q.canvas_items.clear();
  741. if (q.dirty_list.in_list()) {
  742. dirty_quadrant_list.remove(&q.dirty_list);
  743. }
  744. if (bake_navigation) {
  745. q.clear_navpoly();
  746. }
  747. for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) {
  748. if (E->get().id.is_valid()) {
  749. VS::get_singleton()->free(E->get().id);
  750. }
  751. }
  752. q.occluder_instances.clear();
  753. quadrant_map.erase(Q);
  754. rect_cache_dirty = true;
  755. }
  756. void TileMap::_make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q, bool update) {
  757. Quadrant &q = Q->get();
  758. if (!q.dirty_list.in_list()) {
  759. dirty_quadrant_list.add(&q.dirty_list);
  760. }
  761. if (pending_update) {
  762. return;
  763. }
  764. pending_update = true;
  765. if (!is_inside_tree()) {
  766. return;
  767. }
  768. if (update) {
  769. call_deferred("update_dirty_quadrants");
  770. }
  771. }
  772. void TileMap::set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose, const Vector2 &p_autotile_coord) {
  773. set_cell(p_pos.x, p_pos.y, p_tile, p_flip_x, p_flip_y, p_transpose, p_autotile_coord);
  774. }
  775. void TileMap::_set_celld(const Vector2 &p_pos, const Dictionary &p_data) {
  776. Variant v_pos_x = p_pos.x, v_pos_y = p_pos.y, v_tile = p_data["id"], v_flip_h = p_data["flip_h"], v_flip_v = p_data["flip_y"], v_transpose = p_data["transpose"], v_autotile_coord = p_data["auto_coord"];
  777. const Variant *args[7] = { &v_pos_x, &v_pos_y, &v_tile, &v_flip_h, &v_flip_v, &v_transpose, &v_autotile_coord };
  778. Variant::CallError ce;
  779. call("set_cell", args, 7, ce);
  780. }
  781. void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose, const Vector2 &p_autotile_coord) {
  782. PosKey pk(p_x, p_y);
  783. Map<PosKey, Cell>::Element *E = tile_map.find(pk);
  784. if (!E && p_tile == INVALID_CELL) {
  785. return; //nothing to do
  786. }
  787. PosKey qk = pk.to_quadrant(_get_quadrant_size());
  788. if (p_tile == INVALID_CELL) {
  789. //erase existing
  790. tile_map.erase(pk);
  791. Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk);
  792. ERR_FAIL_COND(!Q);
  793. Quadrant &q = Q->get();
  794. q.cells.erase(pk);
  795. if (q.cells.size() == 0) {
  796. _erase_quadrant(Q);
  797. } else {
  798. _make_quadrant_dirty(Q);
  799. }
  800. used_size_cache_dirty = true;
  801. return;
  802. }
  803. Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk);
  804. if (!E) {
  805. E = tile_map.insert(pk, Cell());
  806. if (!Q) {
  807. Q = _create_quadrant(qk);
  808. }
  809. Quadrant &q = Q->get();
  810. q.cells.insert(pk);
  811. } else {
  812. ERR_FAIL_COND(!Q); // quadrant should exist...
  813. if (E->get().id == p_tile && E->get().flip_h == p_flip_x && E->get().flip_v == p_flip_y && E->get().transpose == p_transpose && E->get().autotile_coord_x == (uint16_t)p_autotile_coord.x && E->get().autotile_coord_y == (uint16_t)p_autotile_coord.y) {
  814. return; //nothing changed
  815. }
  816. }
  817. Cell &c = E->get();
  818. c.id = p_tile;
  819. c.flip_h = p_flip_x;
  820. c.flip_v = p_flip_y;
  821. c.transpose = p_transpose;
  822. c.autotile_coord_x = (uint16_t)p_autotile_coord.x;
  823. c.autotile_coord_y = (uint16_t)p_autotile_coord.y;
  824. _make_quadrant_dirty(Q);
  825. used_size_cache_dirty = true;
  826. }
  827. int TileMap::get_cellv(const Vector2 &p_pos) const {
  828. return get_cell(p_pos.x, p_pos.y);
  829. }
  830. void TileMap::make_bitmask_area_dirty(const Vector2 &p_pos) {
  831. for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) {
  832. for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) {
  833. PosKey p(x, y);
  834. if (dirty_bitmask.find(p) == nullptr) {
  835. dirty_bitmask.push_back(p);
  836. }
  837. }
  838. }
  839. }
  840. void TileMap::update_bitmask_area(const Vector2 &p_pos) {
  841. for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) {
  842. for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) {
  843. update_cell_bitmask(x, y);
  844. }
  845. }
  846. }
  847. void TileMap::update_bitmask_region(const Vector2 &p_start, const Vector2 &p_end) {
  848. if ((p_end.x < p_start.x || p_end.y < p_start.y) || (p_end.x == p_start.x && p_end.y == p_start.y)) {
  849. Array a = get_used_cells();
  850. for (int i = 0; i < a.size(); i++) {
  851. Vector2 vector = (Vector2)a[i];
  852. update_cell_bitmask(vector.x, vector.y);
  853. }
  854. return;
  855. }
  856. for (int x = p_start.x - 1; x <= p_end.x + 1; x++) {
  857. for (int y = p_start.y - 1; y <= p_end.y + 1; y++) {
  858. update_cell_bitmask(x, y);
  859. }
  860. }
  861. }
  862. void TileMap::update_cell_bitmask(int p_x, int p_y) {
  863. ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot update cell bitmask if Tileset is not open.");
  864. PosKey p(p_x, p_y);
  865. Map<PosKey, Cell>::Element *E = tile_map.find(p);
  866. if (E != nullptr) {
  867. int id = get_cell(p_x, p_y);
  868. if (!tile_set->has_tile(id)) {
  869. return;
  870. }
  871. if (tile_set->tile_get_tile_mode(id) == TileSet::AUTO_TILE) {
  872. uint16_t mask = 0;
  873. if (tile_set->autotile_get_bitmask_mode(id) == TileSet::BITMASK_2X2) {
  874. if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) {
  875. mask |= TileSet::BIND_TOPLEFT;
  876. }
  877. if (tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y))) {
  878. mask |= TileSet::BIND_TOPRIGHT;
  879. }
  880. if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) {
  881. mask |= TileSet::BIND_BOTTOMLEFT;
  882. }
  883. if (tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y))) {
  884. mask |= TileSet::BIND_BOTTOMRIGHT;
  885. }
  886. } else {
  887. if (tile_set->autotile_get_bitmask_mode(id) == TileSet::BITMASK_3X3_MINIMAL) {
  888. if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) {
  889. mask |= TileSet::BIND_TOPLEFT;
  890. }
  891. if (tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y))) {
  892. mask |= TileSet::BIND_TOPRIGHT;
  893. }
  894. if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) {
  895. mask |= TileSet::BIND_BOTTOMLEFT;
  896. }
  897. if (tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y + 1)) && tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y))) {
  898. mask |= TileSet::BIND_BOTTOMRIGHT;
  899. }
  900. } else {
  901. if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y - 1))) {
  902. mask |= TileSet::BIND_TOPLEFT;
  903. }
  904. if (tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y - 1))) {
  905. mask |= TileSet::BIND_TOPRIGHT;
  906. }
  907. if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y + 1))) {
  908. mask |= TileSet::BIND_BOTTOMLEFT;
  909. }
  910. if (tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y + 1))) {
  911. mask |= TileSet::BIND_BOTTOMRIGHT;
  912. }
  913. }
  914. if (tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1))) {
  915. mask |= TileSet::BIND_TOP;
  916. }
  917. if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) {
  918. mask |= TileSet::BIND_LEFT;
  919. }
  920. mask |= TileSet::BIND_CENTER;
  921. if (tile_set->is_tile_bound(id, get_cell(p_x + 1, p_y))) {
  922. mask |= TileSet::BIND_RIGHT;
  923. }
  924. if (tile_set->is_tile_bound(id, get_cell(p_x, p_y + 1))) {
  925. mask |= TileSet::BIND_BOTTOM;
  926. }
  927. }
  928. Vector2 coord = tile_set->autotile_get_subtile_for_bitmask(id, mask, this, Vector2(p_x, p_y));
  929. E->get().autotile_coord_x = (int)coord.x;
  930. E->get().autotile_coord_y = (int)coord.y;
  931. PosKey qk = p.to_quadrant(_get_quadrant_size());
  932. Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk);
  933. _make_quadrant_dirty(Q);
  934. } else if (tile_set->tile_get_tile_mode(id) == TileSet::SINGLE_TILE) {
  935. E->get().autotile_coord_x = 0;
  936. E->get().autotile_coord_y = 0;
  937. } else if (tile_set->tile_get_tile_mode(id) == TileSet::ATLAS_TILE) {
  938. if (tile_set->autotile_get_bitmask(id, Vector2(p_x, p_y)) == TileSet::BIND_CENTER) {
  939. Vector2 coord = tile_set->atlastile_get_subtile_by_priority(id, this, Vector2(p_x, p_y));
  940. E->get().autotile_coord_x = (int)coord.x;
  941. E->get().autotile_coord_y = (int)coord.y;
  942. }
  943. }
  944. }
  945. }
  946. void TileMap::update_dirty_bitmask() {
  947. while (dirty_bitmask.size() > 0) {
  948. update_cell_bitmask(dirty_bitmask[0].x, dirty_bitmask[0].y);
  949. dirty_bitmask.pop_front();
  950. }
  951. }
  952. void TileMap::fix_invalid_tiles() {
  953. ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot fix invalid tiles if Tileset is not open.");
  954. Map<PosKey, Cell> temp_tile_map = tile_map;
  955. for (Map<PosKey, Cell>::Element *E = temp_tile_map.front(); E; E = E->next()) {
  956. if (!tile_set->has_tile(get_cell(E->key().x, E->key().y))) {
  957. set_cell(E->key().x, E->key().y, INVALID_CELL);
  958. }
  959. }
  960. }
  961. int TileMap::get_cell(int p_x, int p_y) const {
  962. PosKey pk(p_x, p_y);
  963. const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
  964. if (!E) {
  965. return INVALID_CELL;
  966. }
  967. return E->get().id;
  968. }
  969. bool TileMap::is_cell_x_flipped(int p_x, int p_y) const {
  970. PosKey pk(p_x, p_y);
  971. const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
  972. if (!E) {
  973. return false;
  974. }
  975. return E->get().flip_h;
  976. }
  977. bool TileMap::is_cell_y_flipped(int p_x, int p_y) const {
  978. PosKey pk(p_x, p_y);
  979. const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
  980. if (!E) {
  981. return false;
  982. }
  983. return E->get().flip_v;
  984. }
  985. bool TileMap::is_cell_transposed(int p_x, int p_y) const {
  986. PosKey pk(p_x, p_y);
  987. const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
  988. if (!E) {
  989. return false;
  990. }
  991. return E->get().transpose;
  992. }
  993. void TileMap::set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord) {
  994. PosKey pk(p_x, p_y);
  995. const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
  996. if (!E) {
  997. return;
  998. }
  999. Cell c = E->get();
  1000. c.autotile_coord_x = p_coord.x;
  1001. c.autotile_coord_y = p_coord.y;
  1002. tile_map[pk] = c;
  1003. PosKey qk = pk.to_quadrant(_get_quadrant_size());
  1004. Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk);
  1005. if (!Q) {
  1006. return;
  1007. }
  1008. _make_quadrant_dirty(Q);
  1009. }
  1010. Vector2 TileMap::get_cell_autotile_coord(int p_x, int p_y) const {
  1011. PosKey pk(p_x, p_y);
  1012. const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
  1013. if (!E) {
  1014. return Vector2();
  1015. }
  1016. return Vector2(E->get().autotile_coord_x, E->get().autotile_coord_y);
  1017. }
  1018. void TileMap::_recreate_quadrants() {
  1019. _clear_quadrants();
  1020. for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
  1021. PosKey qk = PosKey(E->key().x, E->key().y).to_quadrant(_get_quadrant_size());
  1022. Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk);
  1023. if (!Q) {
  1024. Q = _create_quadrant(qk);
  1025. dirty_quadrant_list.add(&Q->get().dirty_list);
  1026. }
  1027. Q->get().cells.insert(E->key());
  1028. _make_quadrant_dirty(Q, false);
  1029. }
  1030. update_dirty_quadrants();
  1031. }
  1032. void TileMap::_clear_quadrants() {
  1033. while (quadrant_map.size()) {
  1034. _erase_quadrant(quadrant_map.front());
  1035. }
  1036. }
  1037. void TileMap::set_material(const Ref<Material> &p_material) {
  1038. CanvasItem::set_material(p_material);
  1039. _update_all_items_material_state();
  1040. }
  1041. void TileMap::set_use_parent_material(bool p_use_parent_material) {
  1042. CanvasItem::set_use_parent_material(p_use_parent_material);
  1043. _update_all_items_material_state();
  1044. }
  1045. void TileMap::_update_all_items_material_state() {
  1046. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  1047. Quadrant &q = E->get();
  1048. for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) {
  1049. _update_item_material_state(F->get());
  1050. }
  1051. }
  1052. }
  1053. void TileMap::_update_item_material_state(const RID &p_canvas_item) {
  1054. VS::get_singleton()->canvas_item_set_use_parent_material(p_canvas_item, get_use_parent_material() || get_material().is_valid());
  1055. }
  1056. void TileMap::clear() {
  1057. _clear_quadrants();
  1058. tile_map.clear();
  1059. used_size_cache_dirty = true;
  1060. }
  1061. void TileMap::_set_tile_data(const PoolVector<int> &p_data) {
  1062. ERR_FAIL_COND(format > FORMAT_2);
  1063. int c = p_data.size();
  1064. PoolVector<int>::Read r = p_data.read();
  1065. int offset = (format == FORMAT_2) ? 3 : 2;
  1066. ERR_FAIL_COND_MSG(c % offset != 0, "Corrupted tile data.");
  1067. clear();
  1068. for (int i = 0; i < c; i += offset) {
  1069. const uint8_t *ptr = (const uint8_t *)&r[i];
  1070. uint8_t local[12];
  1071. const int buffer_size = (format == FORMAT_2) ? 12 : 8;
  1072. for (int j = 0; j < buffer_size; j++) {
  1073. local[j] = ptr[j];
  1074. }
  1075. #ifdef BIG_ENDIAN_ENABLED
  1076. SWAP(local[0], local[3]);
  1077. SWAP(local[1], local[2]);
  1078. SWAP(local[4], local[7]);
  1079. SWAP(local[5], local[6]);
  1080. //TODO: ask someone to check this...
  1081. if (FORMAT == FORMAT_2) {
  1082. SWAP(local[8], local[11]);
  1083. SWAP(local[9], local[10]);
  1084. }
  1085. #endif
  1086. uint16_t x = decode_uint16(&local[0]);
  1087. uint16_t y = decode_uint16(&local[2]);
  1088. uint32_t v = decode_uint32(&local[4]);
  1089. bool flip_h = v & (1 << 29);
  1090. bool flip_v = v & (1 << 30);
  1091. bool transpose = v & (1 << 31);
  1092. v &= (1 << 29) - 1;
  1093. int16_t coord_x = 0;
  1094. int16_t coord_y = 0;
  1095. if (format == FORMAT_2) {
  1096. coord_x = decode_uint16(&local[8]);
  1097. coord_y = decode_uint16(&local[10]);
  1098. }
  1099. set_cell(x, y, v, flip_h, flip_v, transpose, Vector2(coord_x, coord_y));
  1100. }
  1101. }
  1102. PoolVector<int> TileMap::_get_tile_data() const {
  1103. PoolVector<int> data;
  1104. data.resize(tile_map.size() * 3);
  1105. PoolVector<int>::Write w = data.write();
  1106. // Save in highest format
  1107. int idx = 0;
  1108. for (const Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
  1109. uint8_t *ptr = (uint8_t *)&w[idx];
  1110. encode_uint16(E->key().x, &ptr[0]);
  1111. encode_uint16(E->key().y, &ptr[2]);
  1112. uint32_t val = E->get().id;
  1113. if (E->get().flip_h) {
  1114. val |= (1 << 29);
  1115. }
  1116. if (E->get().flip_v) {
  1117. val |= (1 << 30);
  1118. }
  1119. if (E->get().transpose) {
  1120. val |= (1 << 31);
  1121. }
  1122. encode_uint32(val, &ptr[4]);
  1123. encode_uint16(E->get().autotile_coord_x, &ptr[8]);
  1124. encode_uint16(E->get().autotile_coord_y, &ptr[10]);
  1125. idx += 3;
  1126. }
  1127. w.release();
  1128. return data;
  1129. }
  1130. #ifdef TOOLS_ENABLED
  1131. Rect2 TileMap::_edit_get_rect() const {
  1132. if (pending_update) {
  1133. const_cast<TileMap *>(this)->update_dirty_quadrants();
  1134. } else {
  1135. const_cast<TileMap *>(this)->_recompute_rect_cache();
  1136. }
  1137. return rect_cache;
  1138. }
  1139. #endif
  1140. void TileMap::set_collision_layer(uint32_t p_layer) {
  1141. collision_layer = p_layer;
  1142. if (!use_parent) {
  1143. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  1144. Quadrant &q = E->get();
  1145. Physics2DServer::get_singleton()->body_set_collision_layer(q.body, collision_layer);
  1146. }
  1147. }
  1148. }
  1149. void TileMap::set_collision_mask(uint32_t p_mask) {
  1150. collision_mask = p_mask;
  1151. if (!use_parent) {
  1152. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  1153. Quadrant &q = E->get();
  1154. Physics2DServer::get_singleton()->body_set_collision_mask(q.body, collision_mask);
  1155. }
  1156. }
  1157. }
  1158. void TileMap::set_collision_layer_bit(int p_bit, bool p_value) {
  1159. ERR_FAIL_INDEX_MSG(p_bit, 32, "Collision layer bit must be between 0 and 31 inclusive.");
  1160. uint32_t layer = get_collision_layer();
  1161. if (p_value) {
  1162. layer |= 1 << p_bit;
  1163. } else {
  1164. layer &= ~(1 << p_bit);
  1165. }
  1166. set_collision_layer(layer);
  1167. }
  1168. void TileMap::set_collision_mask_bit(int p_bit, bool p_value) {
  1169. ERR_FAIL_INDEX_MSG(p_bit, 32, "Collision mask bit must be between 0 and 31 inclusive.");
  1170. uint32_t mask = get_collision_mask();
  1171. if (p_value) {
  1172. mask |= 1 << p_bit;
  1173. } else {
  1174. mask &= ~(1 << p_bit);
  1175. }
  1176. set_collision_mask(mask);
  1177. }
  1178. bool TileMap::get_collision_use_kinematic() const {
  1179. return use_kinematic;
  1180. }
  1181. void TileMap::set_collision_use_kinematic(bool p_use_kinematic) {
  1182. _clear_quadrants();
  1183. use_kinematic = p_use_kinematic;
  1184. _recreate_quadrants();
  1185. }
  1186. bool TileMap::get_collision_use_parent() const {
  1187. return use_parent;
  1188. }
  1189. void TileMap::set_collision_use_parent(bool p_use_parent) {
  1190. if (use_parent == p_use_parent) {
  1191. return;
  1192. }
  1193. _clear_quadrants();
  1194. use_parent = p_use_parent;
  1195. set_notify_local_transform(use_parent);
  1196. if (use_parent && is_inside_tree()) {
  1197. collision_parent = Object::cast_to<CollisionObject2D>(get_parent());
  1198. } else {
  1199. collision_parent = nullptr;
  1200. }
  1201. _recreate_quadrants();
  1202. _change_notify();
  1203. update_configuration_warning();
  1204. }
  1205. void TileMap::set_collision_friction(float p_friction) {
  1206. friction = p_friction;
  1207. if (!use_parent) {
  1208. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  1209. Quadrant &q = E->get();
  1210. Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_FRICTION, p_friction);
  1211. }
  1212. }
  1213. }
  1214. float TileMap::get_collision_friction() const {
  1215. return friction;
  1216. }
  1217. void TileMap::set_collision_bounce(float p_bounce) {
  1218. bounce = p_bounce;
  1219. if (!use_parent) {
  1220. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  1221. Quadrant &q = E->get();
  1222. Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_BOUNCE, p_bounce);
  1223. }
  1224. }
  1225. }
  1226. float TileMap::get_collision_bounce() const {
  1227. return bounce;
  1228. }
  1229. void TileMap::set_bake_navigation(bool p_bake_navigation) {
  1230. bake_navigation = p_bake_navigation;
  1231. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  1232. _make_quadrant_dirty(E);
  1233. }
  1234. }
  1235. bool TileMap::is_baking_navigation() {
  1236. return bake_navigation;
  1237. }
  1238. void TileMap::set_navigation_layers(uint32_t p_navigation_layers) {
  1239. navigation_layers = p_navigation_layers;
  1240. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  1241. _make_quadrant_dirty(E);
  1242. }
  1243. }
  1244. uint32_t TileMap::get_navigation_layers() {
  1245. return navigation_layers;
  1246. }
  1247. uint32_t TileMap::get_collision_layer() const {
  1248. return collision_layer;
  1249. }
  1250. uint32_t TileMap::get_collision_mask() const {
  1251. return collision_mask;
  1252. }
  1253. bool TileMap::get_collision_layer_bit(int p_bit) const {
  1254. ERR_FAIL_INDEX_V_MSG(p_bit, 32, false, "Collision layer bit must be between 0 and 31 inclusive.");
  1255. return get_collision_layer() & (1 << p_bit);
  1256. }
  1257. bool TileMap::get_collision_mask_bit(int p_bit) const {
  1258. ERR_FAIL_INDEX_V_MSG(p_bit, 32, false, "Collision mask bit must be between 0 and 31 inclusive.");
  1259. return get_collision_mask() & (1 << p_bit);
  1260. }
  1261. void TileMap::set_mode(Mode p_mode) {
  1262. _clear_quadrants();
  1263. mode = p_mode;
  1264. _recreate_quadrants();
  1265. emit_signal("settings_changed");
  1266. }
  1267. TileMap::Mode TileMap::get_mode() const {
  1268. return mode;
  1269. }
  1270. void TileMap::set_half_offset(HalfOffset p_half_offset) {
  1271. _clear_quadrants();
  1272. half_offset = p_half_offset;
  1273. _recreate_quadrants();
  1274. emit_signal("settings_changed");
  1275. }
  1276. void TileMap::set_tile_origin(TileOrigin p_tile_origin) {
  1277. _clear_quadrants();
  1278. tile_origin = p_tile_origin;
  1279. _recreate_quadrants();
  1280. emit_signal("settings_changed");
  1281. }
  1282. TileMap::TileOrigin TileMap::get_tile_origin() const {
  1283. return tile_origin;
  1284. }
  1285. Vector2 TileMap::get_cell_draw_offset() const {
  1286. switch (mode) {
  1287. case MODE_SQUARE: {
  1288. return Vector2();
  1289. } break;
  1290. case MODE_ISOMETRIC: {
  1291. return Vector2(-cell_size.x * 0.5, 0);
  1292. } break;
  1293. case MODE_CUSTOM: {
  1294. Vector2 min;
  1295. min.x = MIN(custom_transform[0].x, min.x);
  1296. min.y = MIN(custom_transform[0].y, min.y);
  1297. min.x = MIN(custom_transform[1].x, min.x);
  1298. min.y = MIN(custom_transform[1].y, min.y);
  1299. return min;
  1300. } break;
  1301. }
  1302. return Vector2();
  1303. }
  1304. TileMap::HalfOffset TileMap::get_half_offset() const {
  1305. return half_offset;
  1306. }
  1307. Transform2D TileMap::get_cell_transform() const {
  1308. switch (mode) {
  1309. case MODE_SQUARE: {
  1310. Transform2D m;
  1311. m[0] *= cell_size.x;
  1312. m[1] *= cell_size.y;
  1313. return m;
  1314. } break;
  1315. case MODE_ISOMETRIC: {
  1316. //isometric only makes sense when y is positive in both x and y vectors, otherwise
  1317. //the drawing of tiles will overlap
  1318. Transform2D m;
  1319. m[0] = Vector2(cell_size.x * 0.5, cell_size.y * 0.5);
  1320. m[1] = Vector2(-cell_size.x * 0.5, cell_size.y * 0.5);
  1321. return m;
  1322. } break;
  1323. case MODE_CUSTOM: {
  1324. return custom_transform;
  1325. } break;
  1326. }
  1327. return Transform2D();
  1328. }
  1329. void TileMap::set_custom_transform(const Transform2D &p_xform) {
  1330. _clear_quadrants();
  1331. custom_transform = p_xform;
  1332. _recreate_quadrants();
  1333. emit_signal("settings_changed");
  1334. }
  1335. Transform2D TileMap::get_custom_transform() const {
  1336. return custom_transform;
  1337. }
  1338. Vector2 TileMap::_map_to_world(int p_x, int p_y, bool p_ignore_ofs) const {
  1339. Vector2 ret = get_cell_transform().xform(Vector2(p_x, p_y));
  1340. if (!p_ignore_ofs) {
  1341. switch (half_offset) {
  1342. case HALF_OFFSET_X:
  1343. case HALF_OFFSET_NEGATIVE_X: {
  1344. if (ABS(p_y) & 1) {
  1345. ret += get_cell_transform()[0] * (half_offset == HALF_OFFSET_X ? 0.5 : -0.5);
  1346. }
  1347. } break;
  1348. case HALF_OFFSET_Y:
  1349. case HALF_OFFSET_NEGATIVE_Y: {
  1350. if (ABS(p_x) & 1) {
  1351. ret += get_cell_transform()[1] * (half_offset == HALF_OFFSET_Y ? 0.5 : -0.5);
  1352. }
  1353. } break;
  1354. case HALF_OFFSET_DISABLED: {
  1355. // Nothing to do.
  1356. }
  1357. }
  1358. }
  1359. return ret;
  1360. }
  1361. bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
  1362. if (p_name == "format") {
  1363. if (p_value.get_type() == Variant::INT) {
  1364. format = (DataFormat)(p_value.operator int64_t()); // Set format used for loading
  1365. return true;
  1366. }
  1367. } else if (p_name == "tile_data") {
  1368. if (p_value.is_array()) {
  1369. _set_tile_data(p_value);
  1370. return true;
  1371. }
  1372. return false;
  1373. }
  1374. return false;
  1375. }
  1376. bool TileMap::_get(const StringName &p_name, Variant &r_ret) const {
  1377. if (p_name == "format") {
  1378. r_ret = FORMAT_2; // When saving, always save highest format
  1379. return true;
  1380. } else if (p_name == "tile_data") {
  1381. r_ret = _get_tile_data();
  1382. return true;
  1383. }
  1384. return false;
  1385. }
  1386. void TileMap::_get_property_list(List<PropertyInfo> *p_list) const {
  1387. PropertyInfo p(Variant::INT, "format", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL);
  1388. p_list->push_back(p);
  1389. p = PropertyInfo(Variant::OBJECT, "tile_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL);
  1390. p_list->push_back(p);
  1391. }
  1392. void TileMap::_validate_property(PropertyInfo &property) const {
  1393. if (use_parent && property.name != "collision_use_parent" && property.name.begins_with("collision_")) {
  1394. property.usage = PROPERTY_USAGE_NOEDITOR;
  1395. }
  1396. }
  1397. Vector2 TileMap::map_to_world(const Vector2 &p_pos, bool p_ignore_ofs) const {
  1398. return _map_to_world(p_pos.x, p_pos.y, p_ignore_ofs);
  1399. }
  1400. Vector2 TileMap::world_to_map(const Vector2 &p_pos) const {
  1401. Vector2 ret = get_cell_transform().affine_inverse().xform(p_pos);
  1402. // Account for precision errors on the border (GH-23250).
  1403. // 0.00005 is 5*CMP_EPSILON, results would start being unpredictable if
  1404. // cell size is > 15,000, but we can hardly have more precision anyway with
  1405. // floating point.
  1406. ret += Vector2(0.00005, 0.00005);
  1407. switch (half_offset) {
  1408. case HALF_OFFSET_X: {
  1409. if (int(floor(ret.y)) & 1) {
  1410. ret.x -= 0.5;
  1411. }
  1412. } break;
  1413. case HALF_OFFSET_NEGATIVE_X: {
  1414. if (int(floor(ret.y)) & 1) {
  1415. ret.x += 0.5;
  1416. }
  1417. } break;
  1418. case HALF_OFFSET_Y: {
  1419. if (int(floor(ret.x)) & 1) {
  1420. ret.y -= 0.5;
  1421. }
  1422. } break;
  1423. case HALF_OFFSET_NEGATIVE_Y: {
  1424. if (int(floor(ret.x)) & 1) {
  1425. ret.y += 0.5;
  1426. }
  1427. } break;
  1428. case HALF_OFFSET_DISABLED: {
  1429. // Nothing to do.
  1430. }
  1431. }
  1432. return ret.floor();
  1433. }
  1434. void TileMap::set_y_sort_mode(bool p_enable) {
  1435. _clear_quadrants();
  1436. y_sort_mode = p_enable;
  1437. VS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), y_sort_mode);
  1438. _recreate_quadrants();
  1439. emit_signal("settings_changed");
  1440. }
  1441. bool TileMap::is_y_sort_mode_enabled() const {
  1442. return y_sort_mode;
  1443. }
  1444. void TileMap::set_compatibility_mode(bool p_enable) {
  1445. _clear_quadrants();
  1446. compatibility_mode = p_enable;
  1447. _recreate_quadrants();
  1448. emit_signal("settings_changed");
  1449. }
  1450. bool TileMap::is_compatibility_mode_enabled() const {
  1451. return compatibility_mode;
  1452. }
  1453. void TileMap::set_centered_textures(bool p_enable) {
  1454. _clear_quadrants();
  1455. centered_textures = p_enable;
  1456. _recreate_quadrants();
  1457. emit_signal("settings_changed");
  1458. }
  1459. bool TileMap::is_centered_textures_enabled() const {
  1460. return centered_textures;
  1461. }
  1462. Array TileMap::get_used_cells() const {
  1463. Array a;
  1464. a.resize(tile_map.size());
  1465. int i = 0;
  1466. for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
  1467. Vector2 p(E->key().x, E->key().y);
  1468. a[i++] = p;
  1469. }
  1470. return a;
  1471. }
  1472. Array TileMap::get_used_cells_by_id(int p_id) const {
  1473. Array a;
  1474. for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
  1475. if (E->value().id == p_id) {
  1476. Vector2 p(E->key().x, E->key().y);
  1477. a.push_back(p);
  1478. }
  1479. }
  1480. return a;
  1481. }
  1482. Rect2 TileMap::get_used_rect() { // Not const because of cache
  1483. if (used_size_cache_dirty) {
  1484. if (tile_map.size() > 0) {
  1485. used_size_cache = Rect2(tile_map.front()->key().x, tile_map.front()->key().y, 0, 0);
  1486. for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
  1487. used_size_cache.expand_to(Vector2(E->key().x, E->key().y));
  1488. }
  1489. used_size_cache.size += Vector2(1, 1);
  1490. } else {
  1491. used_size_cache = Rect2();
  1492. }
  1493. used_size_cache_dirty = false;
  1494. }
  1495. return used_size_cache;
  1496. }
  1497. void TileMap::set_occluder_light_mask(int p_mask) {
  1498. occluder_light_mask = p_mask;
  1499. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  1500. for (Map<PosKey, Quadrant::Occluder>::Element *F = E->get().occluder_instances.front(); F; F = F->next()) {
  1501. VisualServer::get_singleton()->canvas_light_occluder_set_light_mask(F->get().id, occluder_light_mask);
  1502. }
  1503. }
  1504. }
  1505. int TileMap::get_occluder_light_mask() const {
  1506. return occluder_light_mask;
  1507. }
  1508. void TileMap::set_light_mask(int p_light_mask) {
  1509. CanvasItem::set_light_mask(p_light_mask);
  1510. for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  1511. for (List<RID>::Element *F = E->get().canvas_items.front(); F; F = F->next()) {
  1512. VisualServer::get_singleton()->canvas_item_set_light_mask(F->get(), get_light_mask());
  1513. }
  1514. }
  1515. }
  1516. void TileMap::set_clip_uv(bool p_enable) {
  1517. if (clip_uv == p_enable) {
  1518. return;
  1519. }
  1520. _clear_quadrants();
  1521. clip_uv = p_enable;
  1522. _recreate_quadrants();
  1523. }
  1524. bool TileMap::get_clip_uv() const {
  1525. return clip_uv;
  1526. }
  1527. String TileMap::get_configuration_warning() const {
  1528. String warning = Node2D::get_configuration_warning();
  1529. if (use_parent && !collision_parent) {
  1530. if (!warning.empty()) {
  1531. warning += "\n\n";
  1532. }
  1533. return TTR("TileMap with Use Parent on needs a parent CollisionObject2D to give shapes to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape.");
  1534. }
  1535. return warning;
  1536. }
  1537. void TileMap::set_show_collision(bool p_value) {
  1538. show_collision = p_value;
  1539. _recreate_quadrants();
  1540. }
  1541. bool TileMap::is_show_collision_enabled() const {
  1542. return show_collision;
  1543. }
  1544. void TileMap::_bind_methods() {
  1545. ClassDB::bind_method(D_METHOD("set_tileset", "tileset"), &TileMap::set_tileset);
  1546. ClassDB::bind_method(D_METHOD("get_tileset"), &TileMap::get_tileset);
  1547. ClassDB::bind_method(D_METHOD("set_mode", "mode"), &TileMap::set_mode);
  1548. ClassDB::bind_method(D_METHOD("get_mode"), &TileMap::get_mode);
  1549. ClassDB::bind_method(D_METHOD("set_half_offset", "half_offset"), &TileMap::set_half_offset);
  1550. ClassDB::bind_method(D_METHOD("get_half_offset"), &TileMap::get_half_offset);
  1551. ClassDB::bind_method(D_METHOD("set_custom_transform", "custom_transform"), &TileMap::set_custom_transform);
  1552. ClassDB::bind_method(D_METHOD("get_custom_transform"), &TileMap::get_custom_transform);
  1553. ClassDB::bind_method(D_METHOD("set_cell_size", "size"), &TileMap::set_cell_size);
  1554. ClassDB::bind_method(D_METHOD("get_cell_size"), &TileMap::get_cell_size);
  1555. ClassDB::bind_method(D_METHOD("_set_old_cell_size", "size"), &TileMap::_set_old_cell_size);
  1556. ClassDB::bind_method(D_METHOD("_get_old_cell_size"), &TileMap::_get_old_cell_size);
  1557. ClassDB::bind_method(D_METHOD("set_quadrant_size", "size"), &TileMap::set_quadrant_size);
  1558. ClassDB::bind_method(D_METHOD("get_quadrant_size"), &TileMap::get_quadrant_size);
  1559. ClassDB::bind_method(D_METHOD("set_tile_origin", "origin"), &TileMap::set_tile_origin);
  1560. ClassDB::bind_method(D_METHOD("get_tile_origin"), &TileMap::get_tile_origin);
  1561. ClassDB::bind_method(D_METHOD("set_clip_uv", "enable"), &TileMap::set_clip_uv);
  1562. ClassDB::bind_method(D_METHOD("get_clip_uv"), &TileMap::get_clip_uv);
  1563. ClassDB::bind_method(D_METHOD("set_y_sort_mode", "enable"), &TileMap::set_y_sort_mode);
  1564. ClassDB::bind_method(D_METHOD("is_y_sort_mode_enabled"), &TileMap::is_y_sort_mode_enabled);
  1565. ClassDB::bind_method(D_METHOD("set_compatibility_mode", "enable"), &TileMap::set_compatibility_mode);
  1566. ClassDB::bind_method(D_METHOD("is_compatibility_mode_enabled"), &TileMap::is_compatibility_mode_enabled);
  1567. ClassDB::bind_method(D_METHOD("set_show_collision", "enable"), &TileMap::set_show_collision);
  1568. ClassDB::bind_method(D_METHOD("is_show_collision_enabled"), &TileMap::is_show_collision_enabled);
  1569. ClassDB::bind_method(D_METHOD("set_centered_textures", "enable"), &TileMap::set_centered_textures);
  1570. ClassDB::bind_method(D_METHOD("is_centered_textures_enabled"), &TileMap::is_centered_textures_enabled);
  1571. ClassDB::bind_method(D_METHOD("set_collision_use_kinematic", "use_kinematic"), &TileMap::set_collision_use_kinematic);
  1572. ClassDB::bind_method(D_METHOD("get_collision_use_kinematic"), &TileMap::get_collision_use_kinematic);
  1573. ClassDB::bind_method(D_METHOD("set_collision_use_parent", "use_parent"), &TileMap::set_collision_use_parent);
  1574. ClassDB::bind_method(D_METHOD("get_collision_use_parent"), &TileMap::get_collision_use_parent);
  1575. ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &TileMap::set_collision_layer);
  1576. ClassDB::bind_method(D_METHOD("get_collision_layer"), &TileMap::get_collision_layer);
  1577. ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &TileMap::set_collision_mask);
  1578. ClassDB::bind_method(D_METHOD("get_collision_mask"), &TileMap::get_collision_mask);
  1579. ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &TileMap::set_collision_layer_bit);
  1580. ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &TileMap::get_collision_layer_bit);
  1581. ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &TileMap::set_collision_mask_bit);
  1582. ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &TileMap::get_collision_mask_bit);
  1583. ClassDB::bind_method(D_METHOD("set_collision_friction", "value"), &TileMap::set_collision_friction);
  1584. ClassDB::bind_method(D_METHOD("get_collision_friction"), &TileMap::get_collision_friction);
  1585. ClassDB::bind_method(D_METHOD("set_collision_bounce", "value"), &TileMap::set_collision_bounce);
  1586. ClassDB::bind_method(D_METHOD("get_collision_bounce"), &TileMap::get_collision_bounce);
  1587. ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &TileMap::set_bake_navigation);
  1588. ClassDB::bind_method(D_METHOD("is_baking_navigation"), &TileMap::is_baking_navigation);
  1589. ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &TileMap::set_navigation_layers);
  1590. ClassDB::bind_method(D_METHOD("get_navigation_layers"), &TileMap::get_navigation_layers);
  1591. ClassDB::bind_method(D_METHOD("set_occluder_light_mask", "mask"), &TileMap::set_occluder_light_mask);
  1592. ClassDB::bind_method(D_METHOD("get_occluder_light_mask"), &TileMap::get_occluder_light_mask);
  1593. ClassDB::bind_method(D_METHOD("set_cell", "x", "y", "tile", "flip_x", "flip_y", "transpose", "autotile_coord"), &TileMap::set_cell, DEFVAL(false), DEFVAL(false), DEFVAL(false), DEFVAL(Vector2()));
  1594. ClassDB::bind_method(D_METHOD("set_cellv", "position", "tile", "flip_x", "flip_y", "transpose", "autotile_coord"), &TileMap::set_cellv, DEFVAL(false), DEFVAL(false), DEFVAL(false), DEFVAL(Vector2()));
  1595. ClassDB::bind_method(D_METHOD("_set_celld", "position", "data"), &TileMap::_set_celld);
  1596. ClassDB::bind_method(D_METHOD("get_cell", "x", "y"), &TileMap::get_cell);
  1597. ClassDB::bind_method(D_METHOD("get_cellv", "position"), &TileMap::get_cellv);
  1598. ClassDB::bind_method(D_METHOD("is_cell_x_flipped", "x", "y"), &TileMap::is_cell_x_flipped);
  1599. ClassDB::bind_method(D_METHOD("is_cell_y_flipped", "x", "y"), &TileMap::is_cell_y_flipped);
  1600. ClassDB::bind_method(D_METHOD("is_cell_transposed", "x", "y"), &TileMap::is_cell_transposed);
  1601. ClassDB::bind_method(D_METHOD("get_cell_autotile_coord", "x", "y"), &TileMap::get_cell_autotile_coord);
  1602. ClassDB::bind_method(D_METHOD("fix_invalid_tiles"), &TileMap::fix_invalid_tiles);
  1603. ClassDB::bind_method(D_METHOD("clear"), &TileMap::clear);
  1604. ClassDB::bind_method(D_METHOD("get_used_cells"), &TileMap::get_used_cells);
  1605. ClassDB::bind_method(D_METHOD("get_used_cells_by_id", "id"), &TileMap::get_used_cells_by_id);
  1606. ClassDB::bind_method(D_METHOD("get_used_rect"), &TileMap::get_used_rect);
  1607. ClassDB::bind_method(D_METHOD("map_to_world", "map_position", "ignore_half_ofs"), &TileMap::map_to_world, DEFVAL(false));
  1608. ClassDB::bind_method(D_METHOD("world_to_map", "world_position"), &TileMap::world_to_map);
  1609. ClassDB::bind_method(D_METHOD("_clear_quadrants"), &TileMap::_clear_quadrants);
  1610. ClassDB::bind_method(D_METHOD("_recreate_quadrants"), &TileMap::_recreate_quadrants);
  1611. ClassDB::bind_method(D_METHOD("update_dirty_quadrants"), &TileMap::update_dirty_quadrants);
  1612. ClassDB::bind_method(D_METHOD("update_bitmask_area", "position"), &TileMap::update_bitmask_area);
  1613. ClassDB::bind_method(D_METHOD("update_bitmask_region", "start", "end"), &TileMap::update_bitmask_region, DEFVAL(Vector2()), DEFVAL(Vector2()));
  1614. ClassDB::bind_method(D_METHOD("_set_tile_data"), &TileMap::_set_tile_data);
  1615. ClassDB::bind_method(D_METHOD("_get_tile_data"), &TileMap::_get_tile_data);
  1616. ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Square,Isometric,Custom"), "set_mode", "get_mode");
  1617. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tile_set", PROPERTY_HINT_RESOURCE_TYPE, "TileSet"), "set_tileset", "get_tileset");
  1618. ADD_GROUP("Cell", "cell_");
  1619. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "cell_size", PROPERTY_HINT_RANGE, "1,8192,1"), "set_cell_size", "get_cell_size");
  1620. ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_quadrant_size", PROPERTY_HINT_RANGE, "1,128,1"), "set_quadrant_size", "get_quadrant_size");
  1621. ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "cell_custom_transform"), "set_custom_transform", "get_custom_transform");
  1622. ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_half_offset", PROPERTY_HINT_ENUM, "Offset X,Offset Y,Disabled,Offset Negative X,Offset Negative Y"), "set_half_offset", "get_half_offset");
  1623. ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_tile_origin", PROPERTY_HINT_ENUM, "Top Left,Center,Bottom Left"), "set_tile_origin", "get_tile_origin");
  1624. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_y_sort"), "set_y_sort_mode", "is_y_sort_mode_enabled");
  1625. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_collision"), "set_show_collision", "is_show_collision_enabled");
  1626. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "compatibility_mode"), "set_compatibility_mode", "is_compatibility_mode_enabled");
  1627. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered_textures"), "set_centered_textures", "is_centered_textures_enabled");
  1628. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_clip_uv"), "set_clip_uv", "get_clip_uv");
  1629. ADD_GROUP("Collision", "collision_");
  1630. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_parent", PROPERTY_HINT_NONE, ""), "set_collision_use_parent", "get_collision_use_parent");
  1631. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_kinematic", PROPERTY_HINT_NONE, ""), "set_collision_use_kinematic", "get_collision_use_kinematic");
  1632. ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision_friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_friction", "get_collision_friction");
  1633. ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision_bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_bounce", "get_collision_bounce");
  1634. ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer");
  1635. ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask");
  1636. ADD_GROUP("Navigation", "");
  1637. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_navigation"), "set_bake_navigation", "is_baking_navigation");
  1638. ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
  1639. ADD_GROUP("Occluder", "occluder_");
  1640. ADD_PROPERTY(PropertyInfo(Variant::INT, "occluder_light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask");
  1641. ADD_PROPERTY_DEFAULT("format", FORMAT_1);
  1642. ADD_SIGNAL(MethodInfo("settings_changed"));
  1643. BIND_CONSTANT(INVALID_CELL);
  1644. BIND_ENUM_CONSTANT(MODE_SQUARE);
  1645. BIND_ENUM_CONSTANT(MODE_ISOMETRIC);
  1646. BIND_ENUM_CONSTANT(MODE_CUSTOM);
  1647. BIND_ENUM_CONSTANT(HALF_OFFSET_X);
  1648. BIND_ENUM_CONSTANT(HALF_OFFSET_Y);
  1649. BIND_ENUM_CONSTANT(HALF_OFFSET_DISABLED);
  1650. BIND_ENUM_CONSTANT(HALF_OFFSET_NEGATIVE_X);
  1651. BIND_ENUM_CONSTANT(HALF_OFFSET_NEGATIVE_Y);
  1652. BIND_ENUM_CONSTANT(TILE_ORIGIN_TOP_LEFT);
  1653. BIND_ENUM_CONSTANT(TILE_ORIGIN_CENTER);
  1654. BIND_ENUM_CONSTANT(TILE_ORIGIN_BOTTOM_LEFT);
  1655. }
  1656. void TileMap::_changed_callback(Object *p_changed, const char *p_prop) {
  1657. if (tile_set.is_valid() && tile_set.ptr() == p_changed) {
  1658. emit_signal("settings_changed");
  1659. }
  1660. }
  1661. TileMap::TileMap() {
  1662. rect_cache_dirty = true;
  1663. used_size_cache_dirty = true;
  1664. pending_update = false;
  1665. quadrant_order_dirty = false;
  1666. quadrant_size = 16;
  1667. cell_size = Size2(64, 64);
  1668. custom_transform = Transform2D(64, 0, 0, 64, 0, 0);
  1669. collision_layer = 1;
  1670. collision_mask = 1;
  1671. friction = 1;
  1672. bounce = 0;
  1673. mode = MODE_SQUARE;
  1674. half_offset = HALF_OFFSET_DISABLED;
  1675. use_parent = false;
  1676. collision_parent = nullptr;
  1677. use_kinematic = false;
  1678. navigation = nullptr;
  1679. y_sort_mode = false;
  1680. compatibility_mode = false;
  1681. centered_textures = false;
  1682. occluder_light_mask = 1;
  1683. clip_uv = false;
  1684. format = FORMAT_1; // Assume lowest possible format if none is present
  1685. fp_adjust = 0.00001;
  1686. tile_origin = TILE_ORIGIN_TOP_LEFT;
  1687. set_notify_transform(true);
  1688. set_notify_local_transform(false);
  1689. }
  1690. TileMap::~TileMap() {
  1691. if (tile_set.is_valid()) {
  1692. tile_set->remove_change_receptor(this);
  1693. }
  1694. clear();
  1695. }