From 9d182e93a3d75396405733109f9f086969c4b19b Mon Sep 17 00:00:00 2001 From: Carl Olsson Date: Fri, 13 Feb 2015 20:49:21 +1000 Subject: [PATCH 1/6] Added body mode property to TileMap to select between static and kinematic physics bodies. Kinematic allow use of TileMaps for moving platforms for example. Updated 2D Platformer demo to use kinematic TileMaps for moving platforms, in doing so discovered that the tileset was messed up and not converting properly, so fixed that too. And in order to fix the tileset I need to activate snapping for collision polygon vertices. --- demos/2d/platformer/moving_platform.png | Bin 2143 -> 0 bytes demos/2d/platformer/moving_platform.xml | 119 ++++++----- demos/2d/platformer/stage.xml | 40 ++-- demos/2d/platformer/tiles_demo.png | Bin 11736 -> 10066 bytes demos/2d/platformer/tileset.xml | 185 ++++++++++++------ demos/2d/platformer/tileset_edit.xml | 142 +++++++++----- scene/2d/tile_map.cpp | 51 +++-- scene/2d/tile_map.h | 11 +- .../collision_polygon_editor_plugin.cpp | 14 +- 9 files changed, 339 insertions(+), 223 deletions(-) delete mode 100644 demos/2d/platformer/moving_platform.png diff --git a/demos/2d/platformer/moving_platform.png b/demos/2d/platformer/moving_platform.png deleted file mode 100644 index f01c6ea37fc5535d28d704004a6c36deb0587890..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2143 zcmV-l2%z_gP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iye- z1PU`=_Loio00-YmL_t(|+U=dqZxvM-#-G7TDaC4AkhGQrB1jNPNlXaQbb(b96XSxI zxYCvG`~!?87&pd^J9oM;x-u~?)Sxlck2D~`4XA{m7)WUND)c7A(iVYnaqn9?Z|B@| z&diyQOP}ASxijbMJ!g8J=bX7SH$uh4aa>5b+ddzU0pRafC!(dtpZMhYM7lp;{~>6- zcW!(|+m3e)7x6_j-iYop8TLlun zQ&-&?W-pLVAga0nL+|Vc01Ry2005XdH|>=T{kzS|M%>^JP`kQ0eq}Tl-A$7v&J>00B`QSHolYyXG2NQ+rb4ej zD&x@nJb4tk#Hi=dKz4cnJigQo0{Dg9Lg)ZI*!l5u z0DwyuF2w+_acpzj8P!DSbfL-(b-b*2^Ty>{f7Sg{R=>;V%ai8-09OzE9&rzV5VEoz zz~FnkQk9>OdlBsfuD$yQ_W%eX)zDR!hWM`e3F$=TuiJG^2S5lNKz*<|fzZ41S!d?5 z^ZCYQ%NMGgQ1Mnh4rN_$b%PFo5ITVR&^X)t?t8!IjIDQ9P5I@#khLDuXKBCb`wWZi z+p-~7e1hrjiO#Rv2kGZlJFNZLO6TjSB){$Z9kz739eKye)E~Nj*Ku{NM~^!l03oC@ zYV$0Bo*@@!W>IR#q0a7T{i$=;@962|8sm6fDlp{wYdv$_f0vC z#Ed!CI{wj)DFDFu7q?qVlgvN(VRPmkL{h0lxv+RVT?wJ`NqLR^>Gd=W=@yj`(`}Ve z$6-=_jZL97ws`L<`*dnOrgHTfTE{Ca?}ubR;aK{3+WOHp4yN%kjkhV@<=0VqJ$gLf zJT(FUm~?!@6&(N}WaaGvyz$~b0Km7Sjl>>+W_E5NQ~4YFdYsZ7es&H3@bsZ%`pehn z+BymwyGN4BWm0z2`QuYFsfuKCFd7|~Yd=W*%bi90cKF6`>IWUa4LweJ{7vI*!W6%a z-k$E%4*t{ z4uB9kfa-X-Z*3{cR+R#WRwQ4g_KiREZh6&v6`kV1=l}>I+yjtZf8X8HqITg;<<@1b zxzghA)bTgn&7uP!gwO%_I)SRci5GgUTo=V-{9)s-tMbzU5JKwb0Oa|9d5&6U(5z1b z%F}3BaeW%CsI_ulrDOcn#Q*PqcT%rwIsifl9e{A<`i46R0;uF4VJOi3YyJat#<&j^^nHa+nW(u3KnSUi0~p=3zLI*iGMBxJ zP6e-)vc{hdfDl3l;ELS$FKQRnv?iD1p_IV)elr!Yoc=3o{7u(29RMMO4xlQf6HIS) z4W*1(6)Uvzx!#2^rK`#r6s`D0k3aVS2qAO;zQkz$RLbPJ>DXs4An*NlQ3U&LD66zE3CSjbGOOa$VB_5JKnxe4W6y!QMY01V?+!!& zFn#?-TV>nOw>B|jOZu#9W>;l2<;%Oa*YQX{Tvq*HN@we@yvl6rpV0AV82{AkO4nm* z=h~h%iR+pUfDl3lAe=aVHSu}-@L*!b{A+IBYi+6(-!#KJC}8T^QPOE8vE4;*br7z~ zr~AVcmrd!WJ=41?Y1TEpt)EQiUE}v1f0H9{9hVXQIxr!G4j?0s4G%^DaQecv)ETzT zTDMRI)SpFBOisn7{I=hlx9x4%+UpuuR$|o-(^}bvDP6p{cQF^cD0bFybxp4wgpOaX z+qy#sKnNW`{n5W7ENij63TDfnLrGJW$k!p5$}L*a1N4vAo`k7ieB%#2uC5NU=wG>} z10aOldk!G$%;`FVU$N}k7S%pih17_mgi`XN;?L@g9O4V=V2U39(2k1^fDlp|{{xVg V;v;u%4f_B9002ovPDHLkV1g7OG=~5H diff --git a/demos/2d/platformer/moving_platform.xml b/demos/2d/platformer/moving_platform.xml index 4d54d6d11c8e..f39b11782c23 100644 --- a/demos/2d/platformer/moving_platform.xml +++ b/demos/2d/platformer/moving_platform.xml @@ -1,77 +1,56 @@ - - - - - 0 - -88, 24, -88, -24, 88, -24, 88, 24 - - + + + "names" - + "moving_platform" "Node2D" + "_import_path" "visibility/visible" "visibility/opacity" "visibility/self_opacity" - "visibility/on_top" "transform/pos" "transform/rot" "transform/scale" + "z/z" + "z/relative" "script/script" "__meta__" "motion" "cycle" "platform" - "RigidBody2D" - "shape_count" - "shapes/0/shape" - "shapes/0/transform" - "shapes/0/trigger" + "TileMap" "mode" - "mass" - "friction" - "bounce" - "custom_integrator" - "continuous_cd" - "contacts_reported" - "contact_monitor" - "active" - "can_sleep" - "velocity/linear" - "velocity/angular" - "Sprite" - "texture" - "centered" - "offset" - "flip_h" - "flip_v" - "vframes" - "hframes" - "frame" - "modulate" - "region" - "region_rect" - "CollisionPolygon2D" - "build_mode" - "polygon" + "tile_set" + "cell/size" + "cell/quadrant_size" + "cell/custom_transform" + "cell/half_offset" + "collision/body_mode" + "collision/friction" + "collision/bounce" + "collision/layers" + "tile_data" "version" 1 "conn_count" 0 "node_count" - 4 + 2 "variants" + "" True 1 0, 0 0 1, 1 - + 0 + "__editor_plugin_states__" @@ -92,16 +71,22 @@ "pixel_snap" False "zoom" - 1.360373 + 1.850616 + "use_snap" + True "ofs" - -210.652, -172.81 + -406.735, -157.32 + "snap" + 32 "3D" + "deflight_rot_y" + 0.628319 "zfar" 500 "fov" - 400 + 179 "viewports" @@ -111,10 +96,12 @@ 0 "y_rot" 0 - "use_orthogonal" - False + "listener" + True "use_environment" False + "use_orthogonal" + False "pos" 0, 0, 0 @@ -125,10 +112,12 @@ 0 "y_rot" 0 - "use_orthogonal" + "listener" False "use_environment" False + "use_orthogonal" + False "pos" 0, 0, 0 @@ -139,10 +128,12 @@ 0 "y_rot" 0 - "use_orthogonal" + "listener" False "use_environment" False + "use_orthogonal" + False "pos" 0, 0, 0 @@ -153,10 +144,12 @@ 0 "y_rot" 0 - "use_orthogonal" + "listener" False "use_environment" False + "use_orthogonal" + False "pos" 0, 0, 0 @@ -165,12 +158,18 @@ 1 "default_light" True + "ambient_light_color" + 0.15, 0.15, 0.15, 1 "show_grid" True "show_origin" True "znear" 0.1 + "default_srgb" + False + "deflight_rot_x" + 0.942478 "__editor_run_settings__" @@ -183,19 +182,17 @@ "__editor_plugin_screen__" "2D" + -96, -32 + + 64, 64 + 16 + 1, 0, 0, 1, 0, 0 + 2 1 - - 1, -0, 0, 1, 0, 0 - False - 3 - 0 - - 1, 1, 1, 1 - 0, 0, 0, 0 - -88, -24, 88, -24, 88, 24, -88, 24 + 0, 536870927, 1, 536870926, 2, 15 "nodes" - -1, -1, 1, 0, -1, 11, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11, 2, 12, 1, 0, 0, 0, 14, 13, -1, 23, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 15, 7, 16, 8, 17, 9, 18, 10, 19, 11, 20, 1, 21, 1, 22, 3, 23, 10, 24, 10, 25, 12, 26, 10, 27, 0, 28, 0, 29, 2, 30, 3, 0, 1, 0, 31, 31, -1, 18, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 32, 13, 33, 0, 34, 2, 35, 10, 36, 10, 37, 7, 38, 7, 39, 12, 40, 14, 41, 10, 42, 15, 0, 1, 0, 43, 43, -1, 9, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 44, 12, 45, 16, 0 + -1, -1, 1, 0, -1, 13, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 1, 11, 7, 12, 8, 13, 3, 14, 2, 0, 0, 0, 16, 15, -1, 20, 2, 0, 3, 1, 4, 2, 5, 2, 6, 9, 7, 4, 8, 5, 9, 6, 10, 1, 17, 6, 18, 10, 19, 11, 20, 12, 21, 13, 22, 14, 23, 15, 24, 2, 25, 4, 26, 15, 27, 16, 0 "conns" diff --git a/demos/2d/platformer/stage.xml b/demos/2d/platformer/stage.xml index e2943d8fcf65..35517f747db0 100644 --- a/demos/2d/platformer/stage.xml +++ b/demos/2d/platformer/stage.xml @@ -1,17 +1,17 @@ - - + + + - - + "names" - + "stage" "Node" "_import_path" @@ -21,16 +21,18 @@ "visibility/visible" "visibility/opacity" "visibility/self_opacity" - "visibility/behind_parent" "transform/pos" "transform/rot" "transform/scale" + "z/z" + "z/relative" "mode" "tile_set" "cell/size" "cell/quadrant_size" "cell/custom_transform" "cell/half_offset" + "collision/body_mode" "collision/friction" "collision/bounce" "collision/layers" @@ -167,11 +169,11 @@ "pixel_snap" False "zoom" - 0.54036 + 0.814506 "use_snap" False "ofs" - -177.089, 415.221 + -121.031, 464.121 "snap" 10 @@ -276,22 +278,21 @@ 0 "__editor_plugin_screen__" - "Script" + "2D" True 1 - False 0, 0 0 1, 1 0 64, 64 - 16 + 8 1, 0, 0, 1, 0, 0 2 1 - 0, 2, 70, 536870914, 71, 10, 72, 10, 73, 10, 74, 10, 75, 10, 76, 10, 77, 10, 78, 10, 65536, 2, 65606, 536870914, 65607, 10, 65608, 10, 65609, 10, 65610, 10, 65611, 10, 65612, 10, 65613, 10, 65614, 10, 131072, 2, 131142, 536870914, 131143, 10, 131144, 10, 131145, 10, 131146, 10, 131147, 10, 131148, 10, 131149, 10, 131150, 10, 196608, 2, 196626, 9, 196678, 536870914, 196679, 10, 196680, 10, 196681, 10, 196682, 10, 196683, 10, 196684, 10, 196685, 10, 196686, 10, 262144, 2, 262162, 8, 262214, 536870914, 262215, 10, 262216, 10, 262217, 10, 262218, 10, 262219, 10, 262220, 10, 262221, 10, 262222, 10, 327680, 2, 327697, 536870921, 327698, 7, 327733, 9, 327750, 536870914, 327751, 10, 327752, 10, 327753, 10, 327754, 10, 327755, 10, 327756, 10, 327757, 10, 327758, 10, 393216, 2, 393233, 536870920, 393234, 7, 393257, 9, 393269, 7, 393286, 536870914, 393287, 10, 393288, 10, 393289, 10, 393290, 10, 393291, 10, 393292, 10, 393293, 10, 393294, 10, 458752, 2, 458769, 7, 458770, 8, 458790, 9, 458793, 8, 458805, 8, 458822, 536870914, 458823, 10, 458824, 10, 458825, 10, 458826, 10, 458827, 10, 458828, 10, 458829, 10, 458830, 10, 524288, 4, 524289, 1, 524304, 536870913, 524305, 536870918, 524306, 6, 524307, 5, 524308, 1, 524326, 8, 524329, 7, 524341, 7, 524358, 536870914, 524359, 10, 524360, 10, 524361, 10, 524362, 10, 524363, 10, 524364, 10, 524365, 10, 524366, 10, 589824, 10, 589825, 13, 589840, 536870914, 589841, 10, 589842, 10, 589843, 10, 589844, 2, 589862, 7, 589865, 7, 589876, 536870913, 589877, 6, 589878, 1, 589894, 536870914, 589895, 10, 589896, 10, 589897, 10, 589898, 10, 589899, 10, 589900, 10, 589901, 10, 589902, 10, 655360, 2, 655376, 536870914, 655377, 10, 655378, 10, 655379, 10, 655380, 2, 655398, 7, 655401, 8, 655412, 536870925, 655413, 11, 655414, 13, 655430, 536870914, 655431, 10, 655432, 10, 655433, 10, 655434, 10, 655435, 10, 655436, 10, 655437, 10, 655438, 10, 720896, 2, 720912, 536870914, 720913, 10, 720914, 10, 720915, 10, 720916, 2, 720934, 8, 720937, 7, 720958, 536870913, 720959, 5, 720960, 536870917, 720961, 5, 720962, 5, 720963, 536870917, 720964, 5, 720965, 0, 720966, 536870916, 720967, 10, 720968, 10, 720969, 10, 720970, 10, 720971, 10, 720972, 10, 720973, 10, 720974, 10, 786432, 2, 786437, 9, 786448, 536870914, 786449, 10, 786450, 10, 786451, 10, 786452, 2, 786464, 536870913, 786465, 1, 786470, 7, 786473, 7, 786474, 536870924, 786475, 1, 786494, 536870914, 786495, 10, 786496, 10, 786497, 10, 786498, 10, 786499, 10, 786500, 10, 786501, 10, 786502, 10, 786503, 10, 786504, 10, 786505, 10, 786506, 10, 786507, 10, 786508, 10, 786509, 10, 851968, 2, 851973, 7, 851984, 536870914, 851985, 10, 851986, 10, 851987, 10, 851988, 2, 851996, 536870913, 851997, 1, 852000, 536870914, 852001, 3, 852006, 7, 852009, 536870913, 852011, 2, 852030, 536870914, 852031, 10, 852032, 10, 852033, 10, 852034, 10, 852035, 10, 852036, 10, 852037, 10, 852038, 10, 852039, 10, 852040, 10, 852041, 10, 852042, 10, 852043, 10, 852044, 10, 852045, 10, 917504, 2, 917506, 9, 917509, 7, 917512, 536870921, 917520, 536870925, 917521, 11, 917522, 11, 917523, 11, 917524, 13, 917532, 536870925, 917533, 13, 917536, 536870914, 917537, 4, 917538, 1, 917540, 536870913, 917541, 0, 917542, 1, 917545, 536870914, 917546, 10, 917547, 4, 917548, 1, 917566, 536870914, 917567, 10, 917568, 10, 917569, 10, 917570, 10, 917571, 10, 917572, 10, 917573, 10, 917574, 10, 917575, 10, 917576, 10, 917577, 10, 917578, 10, 917579, 10, 917580, 10, 917581, 10, 983040, 2, 983042, 7, 983045, 7, 983048, 536870920, 983050, 536870913, 983051, 1, 983064, 536870913, 983065, 1, 983072, 536870914, 983073, 10, 983074, 4, 983075, 0, 983076, 536870916, 983077, 10, 983078, 4, 983079, 536870912, 983080, 536870912, 983081, 536870916, 983082, 10, 983083, 10, 983084, 2, 983095, 9, 983102, 536870914, 983103, 10, 983104, 10, 983105, 10, 983106, 10, 983107, 10, 983108, 10, 983109, 10, 983110, 10, 983111, 10, 983112, 10, 983113, 10, 983114, 10, 983115, 10, 983116, 10, 983117, 10, 1048576, 2, 1048578, 8, 1048581, 8, 1048584, 536870919, 1048586, 536870925, 1048587, 13, 1048600, 536870925, 1048601, 13, 1048604, 9, 1048608, 536870925, 1048609, 536870923, 1048610, 536870923, 1048611, 536870923, 1048612, 10, 1048613, 10, 1048614, 10, 1048615, 10, 1048616, 10, 1048617, 10, 1048618, 10, 1048619, 10, 1048620, 4, 1048621, 1, 1048630, 536870921, 1048631, 8, 1048638, 536870914, 1048639, 10, 1048640, 10, 1048641, 10, 1048642, 10, 1048643, 10, 1048644, 10, 1048645, 10, 1048646, 10, 1048647, 10, 1048648, 10, 1048649, 10, 1048650, 10, 1048651, 10, 1048652, 10, 1048653, 10, 1114112, 4, 1114113, 0, 1114114, 6, 1114115, 0, 1114116, 0, 1114117, 6, 1114118, 1, 1114120, 536870920, 1114128, 536870913, 1114129, 5, 1114130, 536870917, 1114131, 5, 1114132, 0, 1114133, 1, 1114140, 7, 1114141, 536870921, 1114148, 536870914, 1114149, 10, 1114150, 10, 1114151, 10, 1114152, 10, 1114153, 10, 1114154, 10, 1114155, 10, 1114156, 10, 1114157, 2, 1114166, 536870920, 1114167, 8, 1114174, 536870914, 1114175, 10, 1114176, 10, 1114177, 10, 1114178, 10, 1114179, 10, 1114180, 10, 1114181, 10, 1114182, 10, 1114183, 10, 1114184, 10, 1114185, 10, 1114186, 10, 1114187, 10, 1114188, 10, 1179648, 10, 1179649, 10, 1179650, 10, 1179651, 10, 1179652, 10, 1179653, 10, 1179654, 2, 1179656, 536870919, 1179663, 536870915, 1179665, 10, 1179666, 10, 1179667, 10, 1179668, 10, 1179669, 4, 1179670, 12, 1179675, 9, 1179676, 8, 1179677, 8, 1179684, 536870914, 1179685, 10, 1179686, 10, 1179687, 10, 1179688, 10, 1179689, 10, 1179690, 10, 1179691, 10, 1179692, 10, 1179693, 4, 1179694, 1, 1179701, 9, 1179702, 536870919, 1179703, 7, 1179710, 536870914, 1179711, 10, 1179712, 10, 1179713, 10, 1179714, 10, 1179715, 10, 1179716, 10, 1179717, 10, 1179718, 10, 1179719, 10, 1179720, 10, 1179721, 10, 1179722, 10, 1245184, 10, 1245185, 10, 1245186, 10, 1245187, 10, 1245188, 10, 1245189, 10, 1245190, 2, 1245192, 536870919, 1245199, 536870913, 1245200, 536870916, 1245201, 10, 1245202, 10, 1245203, 10, 1245204, 10, 1245205, 10, 1245207, 1, 1245211, 7, 1245212, 7, 1245213, 536870920, 1245220, 536870914, 1245221, 10, 1245222, 10, 1245223, 10, 1245224, 10, 1245225, 10, 1245226, 10, 1245227, 10, 1245228, 10, 1245229, 10, 1245230, 2, 1245237, 8, 1245238, 536870919, 1245239, 8, 1245240, 536870921, 1245246, 536870914, 1245247, 10, 1245248, 10, 1245249, 10, 1245250, 10, 1245251, 10, 1245252, 10, 1245253, 10, 1245254, 10, 1245255, 10, 1245256, 10, 1245257, 10, 1245258, 10, 1310720, 10, 1310721, 10, 1310722, 10, 1310723, 10, 1310724, 10, 1310725, 10, 1310726, 2, 1310728, 536870920, 1310730, 536870913, 1310731, 1, 1310734, 536870913, 1310735, 536870916, 1310736, 10, 1310737, 10, 1310738, 10, 1310739, 10, 1310740, 10, 1310741, 10, 1310742, 10, 1310743, 4, 1310744, 1, 1310747, 8, 1310748, 7, 1310749, 536870919, 1310756, 536870914, 1310757, 10, 1310758, 10, 1310759, 10, 1310760, 10, 1310761, 10, 1310762, 10, 1310763, 10, 1310764, 10, 1310765, 10, 1310766, 4, 1310767, 5, 1310768, 12, 1310773, 7, 1310774, 536870919, 1310775, 7, 1310776, 536870919, 1310782, 536870914, 1310783, 10, 1310784, 10, 1310785, 10, 1310786, 10, 1310787, 10, 1310788, 10, 1310789, 10, 1310790, 10, 1310791, 10, 1310792, 10, 1310793, 10, 1376256, 10, 1376257, 10, 1376258, 10, 1376259, 10, 1376260, 10, 1376261, 10, 1376262, 4, 1376263, 0, 1376264, 536870918, 1376265, 0, 1376266, 536870916, 1376267, 4, 1376268, 0, 1376269, 0, 1376270, 536870916, 1376271, 10, 1376272, 10, 1376273, 10, 1376274, 10, 1376275, 10, 1376276, 10, 1376277, 10, 1376278, 10, 1376279, 10, 1376280, 4, 1376281, 12, 1376283, 8, 1376284, 8, 1376285, 536870920, 1376287, 536870924, 1376288, 0, 1376289, 5, 1376290, 536870917, 1376291, 0, 1376292, 536870916, 1376293, 10, 1376294, 10, 1376295, 10, 1376296, 10, 1376297, 10, 1376298, 10, 1376299, 10, 1376300, 10, 1376301, 10, 1376302, 10, 1376303, 10, 1376305, 12, 1376309, 7, 1376310, 536870920, 1376311, 7, 1376312, 536870920, 1376318, 536870914, 1376319, 10, 1376320, 10, 1376321, 10, 1376322, 10, 1376323, 10, 1376324, 10, 1376325, 10, 1376326, 10, 1376327, 10, 1376328, 10, 1441792, 10, 1441793, 10, 1441794, 10, 1441795, 10, 1441796, 10, 1441797, 10, 1441798, 10, 1441799, 10, 1441800, 10, 1441801, 10, 1441802, 10, 1441803, 10, 1441804, 10, 1441805, 10, 1441806, 10, 1441807, 10, 1441808, 10, 1441809, 10, 1441810, 10, 1441811, 10, 1441812, 10, 1441813, 10, 1441814, 10, 1441815, 10, 1441816, 10, 1441818, 0, 1441819, 6, 1441820, 6, 1441821, 536870918, 1441822, 5, 1441824, 10, 1441825, 10, 1441826, 10, 1441827, 10, 1441828, 10, 1441829, 10, 1441830, 10, 1441831, 10, 1441832, 10, 1441833, 10, 1441834, 10, 1441835, 10, 1441836, 10, 1441837, 10, 1441838, 10, 1441839, 10, 1441840, 10, 1441842, 0, 1441843, 0, 1441844, 0, 1441845, 6, 1441846, 536870918, 1441847, 6, 1441848, 536870918, 1441849, 0, 1441850, 5, 1441851, 536870917, 1441852, 5, 1441853, 0, 1441854, 536870916, 1441855, 10, 1441856, 10, 1441857, 10, 1441858, 10, 1441859, 10, 1441860, 10, 1441861, 10, 1441862, 10, 1441863, 10, 1507328, 10, 1507329, 10, 1507330, 10, 1507331, 10, 1507332, 10, 1507333, 10, 1507334, 10, 1507335, 10, 1507336, 10, 1507337, 10, 1507338, 10, 1507339, 10, 1507340, 10, 1507341, 10, 1507342, 10, 1507343, 10, 1507344, 10, 1507345, 10, 1507346, 10, 1507347, 10, 1507348, 10, 1507349, 10, 1507350, 10, 1507351, 10, 1507352, 10, 1507353, 10, 1507354, 10, 1507355, 10, 1507356, 10, 1507357, 10, 1507358, 10, 1507359, 10, 1507360, 10, 1507361, 10, 1507362, 10, 1507363, 10, 1507364, 10, 1507365, 10, 1507366, 10, 1507367, 10, 1507368, 10, 1507369, 10, 1507370, 10, 1507371, 10, 1507372, 10, 1507373, 10, 1507374, 10, 1507375, 10, 1507376, 10, 1507377, 10, 1507378, 10, 1507379, 10, 1507380, 10, 1507381, 10, 1507382, 10, 1507383, 10, 1507384, 10, 1507385, 10, 1507386, 10, 1507387, 10, 1507388, 10, 1507389, 10, 1507390, 10, 1507391, 10, 1507392, 10, 1507393, 10, 1507394, 10, 1507395, 10, 1507396, 10, 1507397, 10, 1507398, 10, 1507399, 10, 1572864, 10, 1572865, 10, 1572866, 10, 1572867, 10, 1572868, 10, 1572869, 10, 1572870, 10, 1572871, 10, 1572872, 10, 1572873, 10, 1572874, 10, 1572875, 10, 1572876, 10, 1572877, 10, 1572878, 10, 1572879, 10, 1572880, 10, 1572881, 10, 1572882, 10, 1572883, 10, 1572884, 10, 1572885, 10, 1572886, 10, 1572887, 10, 1572888, 10, 1572889, 10, 1572890, 10, 1572891, 10, 1572892, 10, 1572893, 10, 1572894, 10, 1572895, 10, 1572896, 10, 1572897, 10, 1572898, 10, 1572899, 10, 1572900, 10, 1572901, 10, 1572902, 10, 1572903, 10, 1572904, 10, 1572905, 10, 1572906, 10, 1572907, 10, 1572908, 10, 1572909, 10, 1572910, 10, 1572911, 10, 1572912, 10, 1572913, 10, 1572914, 10, 1572915, 10, 1572916, 10, 1572917, 10, 1572918, 10, 1572919, 10, 1572920, 10, 1572921, 10, 1572922, 10, 1572923, 10, 1572924, 10, 1572925, 10, 1572926, 10, 1572927, 10, 1572928, 10, 1572929, 10, 1572930, 10, 1572931, 10, 1572932, 10, 1572933, 10, 1572934, 10, 1572935, 10, 1638400, 10, 1638401, 10, 1638402, 10, 1638403, 10, 1638404, 10, 1638405, 10, 1638406, 10, 1638407, 10, 1638408, 10, 1638409, 10, 1638410, 10, 1638411, 10, 1638412, 10, 1638413, 10, 1638414, 10, 1638415, 10, 1638416, 10, 1638417, 10, 1638418, 10, 1638419, 10, 1638420, 10, 1638421, 10, 1638422, 10, 1638423, 10, 1638424, 10, 1638425, 10, 1638426, 10, 1638427, 10, 1638428, 10, 1638429, 10, 1638430, 10, 1638431, 10, 1638432, 10, 1638433, 10, 1638434, 10, 1638435, 10, 1638436, 10, 1638437, 10, 1638438, 10, 1638439, 10, 1638440, 10, 1638441, 10, 1638442, 10, 1638443, 10, 1638444, 10, 1638445, 10, 1638446, 10, 1638447, 10, 1638448, 10, 1638449, 10, 1638450, 10, 1638451, 10, 1638452, 10, 1638453, 10, 1638454, 10, 1638455, 10, 1638456, 10, 1638457, 10, 1638458, 10, 1638459, 10, 1638460, 10, 1638461, 10, 1638462, 10, 1638463, 10, 1638464, 10, 1638465, 10, 1638466, 10, 1638467, 10, 1638468, 10, 1638469, 10, 1638470, 10, 1638471, 10, 1703952, 10, 1703953, 10, 1703954, 10, 1703955, 10, 1703956, 10, 1703957, 10, 1703958, 10, 1703959, 10, 1703960, 10, 1703961, 10, 1703962, 10, 1703963, 10, 1703964, 10, 1703965, 10, 1703966, 10, 1703967, 10, 1703968, 10, 1703969, 10, 1703970, 10, 1703971, 10, 1703972, 10, 1703973, 10, 1703974, 10, 1703975, 10, 1703976, 10, 1703977, 10, 1703978, 10, 1703979, 10, 1703980, 10, 1703981, 10, 1703982, 10, 1703983, 10, 1703984, 10, 1703985, 10, 1703986, 10, 1703987, 10, 1703988, 10, 1703989, 10, 1703990, 10, 1703991, 10, 1703992, 10, 1703993, 10, 1703994, 10, 1703995, 10, 1703996, 10, 1703997, 10, 1703998, 10, 1703999, 10, 1704000, 10, 1704001, 10, 1704002, 10, 1704003, 10, 1704004, 10, 1704005, 10, 1704006, 10, 1704007, 10, 1769488, 10, 1769489, 10, 1769490, 10, 1769491, 10, 1769492, 10, 1769493, 10, 1769494, 10, 1769495, 10, 1769496, 10, 1769497, 10, 1769498, 10, 1769499, 10, 1769500, 10, 1769501, 10, 1769502, 10, 1769503, 10, 1769504, 10, 1769505, 10, 1769506, 10, 1769507, 10, 1769508, 10, 1769509, 10, 1769510, 10, 1769511, 10, 1769512, 10, 1769513, 10, 1769514, 10, 1769515, 10, 1769516, 10, 1769517, 10, 1769518, 10, 1769519, 10, 1769520, 10, 1769521, 10, 1769522, 10, 1769523, 10, 1769524, 10, 1769525, 10, 1769526, 10, 1769527, 10, 1769528, 10, 1769529, 10, 1769530, 10, 1769531, 10, 1769532, 10, 1769533, 10, 1769534, 10, 1769535, 10, 1769536, 10, 1769537, 10, 1769538, 10, 1769539, 10, 1769540, 10, 1769541, 10 + 0, 2, 70, 536870914, 71, 10, 72, 10, 73, 10, 74, 10, 75, 10, 76, 10, 77, 10, 78, 10, 65536, 2, 65606, 536870914, 65607, 10, 65608, 10, 65609, 10, 65610, 10, 65611, 10, 65612, 10, 65613, 10, 65614, 10, 131072, 2, 131142, 536870914, 131143, 10, 131144, 10, 131145, 10, 131146, 10, 131147, 10, 131148, 10, 131149, 10, 131150, 10, 196608, 2, 196626, 9, 196678, 536870914, 196679, 10, 196680, 10, 196681, 10, 196682, 10, 196683, 10, 196684, 10, 196685, 10, 196686, 10, 262144, 2, 262162, 8, 262214, 536870914, 262215, 10, 262216, 10, 262217, 10, 262218, 10, 262219, 10, 262220, 10, 262221, 10, 262222, 10, 327680, 2, 327697, 536870921, 327698, 7, 327733, 9, 327750, 536870914, 327751, 10, 327752, 10, 327753, 10, 327754, 10, 327755, 10, 327756, 10, 327757, 10, 327758, 10, 393216, 2, 393233, 536870920, 393234, 7, 393257, 9, 393269, 7, 393286, 536870914, 393287, 10, 393288, 10, 393289, 10, 393290, 10, 393291, 10, 393292, 10, 393293, 10, 393294, 10, 458752, 2, 458769, 7, 458770, 8, 458790, 9, 458793, 8, 458805, 8, 458822, 536870914, 458823, 10, 458824, 10, 458825, 10, 458826, 10, 458827, 10, 458828, 10, 458829, 10, 458830, 10, 524288, 4, 524289, 1, 524304, 536870913, 524305, 536870918, 524306, 6, 524307, 5, 524308, 1, 524326, 8, 524329, 7, 524341, 7, 524358, 536870914, 524359, 10, 524360, 10, 524361, 10, 524362, 10, 524363, 10, 524364, 10, 524365, 10, 524366, 10, 589824, 10, 589825, 13, 589840, 536870914, 589841, 10, 589842, 10, 589843, 10, 589844, 2, 589862, 7, 589865, 7, 589876, 536870913, 589877, 6, 589878, 1, 589894, 536870914, 589895, 10, 589896, 10, 589897, 10, 589898, 10, 589899, 10, 589900, 10, 589901, 10, 589902, 10, 655360, 2, 655376, 536870914, 655377, 10, 655378, 10, 655379, 10, 655380, 2, 655398, 7, 655401, 8, 655412, 536870925, 655413, 11, 655414, 13, 655430, 536870914, 655431, 10, 655432, 10, 655433, 10, 655434, 10, 655435, 10, 655436, 10, 655437, 10, 655438, 10, 720896, 2, 720912, 536870914, 720913, 10, 720914, 10, 720915, 10, 720916, 2, 720934, 8, 720937, 7, 720958, 536870913, 720959, 5, 720960, 536870917, 720961, 5, 720962, 5, 720963, 536870917, 720964, 5, 720965, 0, 720966, 536870916, 720967, 10, 720968, 10, 720969, 10, 720970, 10, 720971, 10, 720972, 10, 720973, 10, 720974, 10, 786432, 2, 786437, 9, 786448, 536870914, 786449, 10, 786450, 10, 786451, 10, 786452, 2, 786464, 536870913, 786465, 1, 786470, 7, 786473, 7, 786474, 536870924, 786475, 1, 786494, 536870914, 786495, 10, 786496, 10, 786497, 10, 786498, 10, 786499, 10, 786500, 10, 786501, 10, 786502, 10, 786503, 10, 786504, 10, 786505, 10, 786506, 10, 786507, 10, 786508, 10, 786509, 10, 851968, 2, 851973, 7, 851984, 536870914, 851985, 10, 851986, 10, 851987, 10, 851988, 2, 851996, 536870913, 851997, 1, 852000, 536870914, 852001, 3, 852006, 7, 852009, 536870913, 852011, 2, 852030, 536870914, 852031, 10, 852032, 10, 852033, 10, 852034, 10, 852035, 10, 852036, 10, 852037, 10, 852038, 10, 852039, 10, 852040, 10, 852041, 10, 852042, 10, 852043, 10, 852044, 10, 852045, 10, 917504, 2, 917506, 9, 917509, 7, 917512, 536870921, 917520, 536870925, 917521, 11, 917522, 11, 917523, 11, 917524, 13, 917532, 536870925, 917533, 13, 917536, 536870914, 917537, 4, 917538, 1, 917540, 536870913, 917541, 0, 917542, 1, 917545, 536870914, 917546, 10, 917547, 4, 917548, 1, 917566, 536870914, 917567, 10, 917568, 10, 917569, 10, 917570, 10, 917571, 10, 917572, 10, 917573, 10, 917574, 10, 917575, 10, 917576, 10, 917577, 10, 917578, 10, 917579, 10, 917580, 10, 917581, 10, 983040, 2, 983042, 7, 983045, 7, 983048, 536870920, 983050, 536870913, 983051, 1, 983064, 536870913, 983065, 1, 983072, 536870914, 983073, 10, 983074, 4, 983075, 0, 983076, 536870916, 983077, 10, 983078, 4, 983079, 536870912, 983080, 536870912, 983081, 536870916, 983082, 10, 983083, 10, 983084, 2, 983095, 9, 983102, 536870914, 983103, 10, 983104, 10, 983105, 10, 983106, 10, 983107, 10, 983108, 10, 983109, 10, 983110, 10, 983111, 10, 983112, 10, 983113, 10, 983114, 10, 983115, 10, 983116, 10, 983117, 10, 1048576, 2, 1048578, 8, 1048581, 8, 1048584, 536870919, 1048586, 536870925, 1048587, 13, 1048600, 536870925, 1048601, 13, 1048604, 9, 1048608, 536870925, 1048609, 536870923, 1048610, 536870923, 1048611, 536870923, 1048612, 10, 1048613, 10, 1048614, 10, 1048615, 10, 1048616, 10, 1048617, 10, 1048618, 10, 1048619, 10, 1048620, 4, 1048621, 1, 1048630, 536870921, 1048631, 8, 1048638, 536870914, 1048639, 10, 1048640, 10, 1048641, 10, 1048642, 10, 1048643, 10, 1048644, 10, 1048645, 10, 1048646, 10, 1048647, 10, 1048648, 10, 1048649, 10, 1048650, 10, 1048651, 10, 1048652, 10, 1048653, 10, 1114112, 4, 1114113, 0, 1114114, 6, 1114115, 0, 1114116, 0, 1114117, 6, 1114118, 1, 1114120, 536870920, 1114128, 536870913, 1114129, 5, 1114130, 536870917, 1114131, 5, 1114132, 0, 1114133, 1, 1114140, 7, 1114141, 536870921, 1114148, 536870914, 1114149, 10, 1114150, 10, 1114151, 10, 1114152, 10, 1114153, 10, 1114154, 10, 1114155, 10, 1114156, 10, 1114157, 2, 1114166, 536870920, 1114167, 8, 1114174, 536870914, 1114175, 10, 1114176, 10, 1114177, 10, 1114178, 10, 1114179, 10, 1114180, 10, 1114181, 10, 1114182, 10, 1114183, 10, 1114184, 10, 1114185, 10, 1114186, 10, 1114187, 10, 1114188, 10, 1179648, 10, 1179649, 10, 1179650, 10, 1179651, 10, 1179652, 10, 1179653, 10, 1179654, 2, 1179656, 536870919, 1179663, 536870915, 1179665, 10, 1179666, 10, 1179667, 10, 1179668, 10, 1179669, 4, 1179670, 12, 1179675, 9, 1179676, 8, 1179677, 8, 1179684, 536870914, 1179685, 10, 1179686, 10, 1179687, 10, 1179688, 10, 1179689, 10, 1179690, 10, 1179691, 10, 1179692, 10, 1179693, 4, 1179694, 1, 1179701, 9, 1179702, 536870919, 1179703, 7, 1179710, 536870914, 1179711, 10, 1179712, 10, 1179713, 10, 1179714, 10, 1179715, 10, 1179716, 10, 1179717, 10, 1179718, 10, 1179719, 10, 1179720, 10, 1179721, 10, 1179722, 10, 1245184, 10, 1245185, 10, 1245186, 10, 1245187, 10, 1245188, 10, 1245189, 10, 1245190, 2, 1245192, 536870919, 1245199, 536870913, 1245200, 536870916, 1245201, 10, 1245202, 10, 1245203, 10, 1245204, 10, 1245205, 10, 1245207, 1, 1245211, 7, 1245212, 7, 1245213, 536870920, 1245220, 536870914, 1245221, 10, 1245222, 10, 1245223, 10, 1245224, 10, 1245225, 10, 1245226, 10, 1245227, 10, 1245228, 10, 1245229, 10, 1245230, 2, 1245237, 8, 1245238, 536870919, 1245239, 8, 1245240, 536870921, 1245246, 536870914, 1245247, 10, 1245248, 10, 1245249, 10, 1245250, 10, 1245251, 10, 1245252, 10, 1245253, 10, 1245254, 10, 1245255, 10, 1245256, 10, 1245257, 10, 1245258, 10, 1310720, 10, 1310721, 10, 1310722, 10, 1310723, 10, 1310724, 10, 1310725, 10, 1310726, 2, 1310728, 536870920, 1310730, 536870913, 1310731, 1, 1310734, 536870913, 1310735, 536870916, 1310736, 10, 1310737, 10, 1310738, 10, 1310739, 10, 1310740, 10, 1310741, 10, 1310742, 10, 1310743, 4, 1310744, 1, 1310747, 8, 1310748, 7, 1310749, 536870919, 1310756, 536870914, 1310757, 10, 1310758, 10, 1310759, 10, 1310760, 10, 1310761, 10, 1310762, 10, 1310763, 10, 1310764, 10, 1310765, 10, 1310766, 4, 1310767, 5, 1310768, 12, 1310773, 7, 1310774, 536870919, 1310775, 7, 1310776, 536870919, 1310782, 536870914, 1310783, 10, 1310784, 10, 1310785, 10, 1310786, 10, 1310787, 10, 1310788, 10, 1310789, 10, 1310790, 10, 1310791, 10, 1310792, 10, 1310793, 10, 1376256, 10, 1376257, 10, 1376258, 10, 1376259, 10, 1376260, 10, 1376261, 10, 1376262, 4, 1376263, 0, 1376264, 0, 1376265, 0, 1376266, 536870916, 1376267, 4, 1376268, 0, 1376269, 0, 1376270, 536870916, 1376271, 10, 1376272, 10, 1376273, 10, 1376274, 10, 1376275, 10, 1376276, 10, 1376277, 10, 1376278, 10, 1376279, 10, 1376280, 4, 1376281, 12, 1376283, 8, 1376284, 8, 1376285, 536870920, 1376287, 536870924, 1376288, 0, 1376289, 5, 1376290, 536870917, 1376291, 0, 1376292, 536870916, 1376293, 10, 1376294, 10, 1376295, 10, 1376296, 10, 1376297, 10, 1376298, 10, 1376299, 10, 1376300, 10, 1376301, 10, 1376302, 10, 1376303, 10, 1376305, 12, 1376309, 7, 1376310, 536870920, 1376311, 7, 1376312, 536870920, 1376318, 536870914, 1376319, 10, 1376320, 10, 1376321, 10, 1376322, 10, 1376323, 10, 1376324, 10, 1376325, 10, 1376326, 10, 1376327, 10, 1376328, 10, 1441792, 10, 1441793, 10, 1441794, 10, 1441795, 10, 1441796, 10, 1441797, 10, 1441798, 10, 1441799, 10, 1441800, 10, 1441801, 10, 1441802, 10, 1441803, 10, 1441804, 10, 1441805, 10, 1441806, 10, 1441807, 10, 1441808, 10, 1441809, 10, 1441810, 10, 1441811, 10, 1441812, 10, 1441813, 10, 1441814, 10, 1441815, 10, 1441816, 10, 1441818, 0, 1441819, 6, 1441820, 6, 1441821, 536870918, 1441822, 5, 1441824, 10, 1441825, 10, 1441826, 10, 1441827, 10, 1441828, 10, 1441829, 10, 1441830, 10, 1441831, 10, 1441832, 10, 1441833, 10, 1441834, 10, 1441835, 10, 1441836, 10, 1441837, 10, 1441838, 10, 1441839, 10, 1441840, 10, 1441842, 0, 1441843, 0, 1441844, 0, 1441845, 6, 1441846, 536870918, 1441847, 6, 1441848, 536870918, 1441849, 0, 1441850, 5, 1441851, 536870917, 1441852, 5, 1441853, 0, 1441854, 536870916, 1441855, 10, 1441856, 10, 1441857, 10, 1441858, 10, 1441859, 10, 1441860, 10, 1441861, 10, 1441862, 10, 1441863, 10, 1507328, 10, 1507329, 10, 1507330, 10, 1507331, 10, 1507332, 10, 1507333, 10, 1507334, 10, 1507335, 10, 1507336, 10, 1507337, 10, 1507338, 10, 1507339, 10, 1507340, 10, 1507341, 10, 1507342, 10, 1507343, 10, 1507344, 10, 1507345, 10, 1507346, 10, 1507347, 10, 1507348, 10, 1507349, 10, 1507350, 10, 1507351, 10, 1507352, 10, 1507353, 10, 1507354, 10, 1507355, 10, 1507356, 10, 1507357, 10, 1507358, 10, 1507359, 10, 1507360, 10, 1507361, 10, 1507362, 10, 1507363, 10, 1507364, 10, 1507365, 10, 1507366, 10, 1507367, 10, 1507368, 10, 1507369, 10, 1507370, 10, 1507371, 10, 1507372, 10, 1507373, 10, 1507374, 10, 1507375, 10, 1507376, 10, 1507377, 10, 1507378, 10, 1507379, 10, 1507380, 10, 1507381, 10, 1507382, 10, 1507383, 10, 1507384, 10, 1507385, 10, 1507386, 10, 1507387, 10, 1507388, 10, 1507389, 10, 1507390, 10, 1507391, 10, 1507392, 10, 1507393, 10, 1507394, 10, 1507395, 10, 1507396, 10, 1507397, 10, 1507398, 10, 1507399, 10, 1572864, 10, 1572865, 10, 1572866, 10, 1572867, 10, 1572868, 10, 1572869, 10, 1572870, 10, 1572871, 10, 1572872, 10, 1572873, 10, 1572874, 10, 1572875, 10, 1572876, 10, 1572877, 10, 1572878, 10, 1572879, 10, 1572880, 10, 1572881, 10, 1572882, 10, 1572883, 10, 1572884, 10, 1572885, 10, 1572886, 10, 1572887, 10, 1572888, 10, 1572889, 10, 1572890, 10, 1572891, 10, 1572892, 10, 1572893, 10, 1572894, 10, 1572895, 10, 1572896, 10, 1572897, 10, 1572898, 10, 1572899, 10, 1572900, 10, 1572901, 10, 1572902, 10, 1572903, 10, 1572904, 10, 1572905, 10, 1572906, 10, 1572907, 10, 1572908, 10, 1572909, 10, 1572910, 10, 1572911, 10, 1572912, 10, 1572913, 10, 1572914, 10, 1572915, 10, 1572916, 10, 1572917, 10, 1572918, 10, 1572919, 10, 1572920, 10, 1572921, 10, 1572922, 10, 1572923, 10, 1572924, 10, 1572925, 10, 1572926, 10, 1572927, 10, 1572928, 10, 1572929, 10, 1572930, 10, 1572931, 10, 1572932, 10, 1572933, 10, 1572934, 10, 1572935, 10, 1638400, 10, 1638401, 10, 1638402, 10, 1638403, 10, 1638404, 10, 1638405, 10, 1638406, 10, 1638407, 10, 1638408, 10, 1638409, 10, 1638410, 10, 1638411, 10, 1638412, 10, 1638413, 10, 1638414, 10, 1638415, 10, 1638416, 10, 1638417, 10, 1638418, 10, 1638419, 10, 1638420, 10, 1638421, 10, 1638422, 10, 1638423, 10, 1638424, 10, 1638425, 10, 1638426, 10, 1638427, 10, 1638428, 10, 1638429, 10, 1638430, 10, 1638431, 10, 1638432, 10, 1638433, 10, 1638434, 10, 1638435, 10, 1638436, 10, 1638437, 10, 1638438, 10, 1638439, 10, 1638440, 10, 1638441, 10, 1638442, 10, 1638443, 10, 1638444, 10, 1638445, 10, 1638446, 10, 1638447, 10, 1638448, 10, 1638449, 10, 1638450, 10, 1638451, 10, 1638452, 10, 1638453, 10, 1638454, 10, 1638455, 10, 1638456, 10, 1638457, 10, 1638458, 10, 1638459, 10, 1638460, 10, 1638461, 10, 1638462, 10, 1638463, 10, 1638464, 10, 1638465, 10, 1638466, 10, 1638467, 10, 1638468, 10, 1638469, 10, 1638470, 10, 1638471, 10, 1703952, 10, 1703953, 10, 1703954, 10, 1703955, 10, 1703956, 10, 1703957, 10, 1703958, 10, 1703959, 10, 1703960, 10, 1703961, 10, 1703962, 10, 1703963, 10, 1703964, 10, 1703965, 10, 1703966, 10, 1703967, 10, 1703968, 10, 1703969, 10, 1703970, 10, 1703971, 10, 1703972, 10, 1703973, 10, 1703974, 10, 1703975, 10, 1703976, 10, 1703977, 10, 1703978, 10, 1703979, 10, 1703980, 10, 1703981, 10, 1703982, 10, 1703983, 10, 1703984, 10, 1703985, 10, 1703986, 10, 1703987, 10, 1703988, 10, 1703989, 10, 1703990, 10, 1703991, 10, 1703992, 10, 1703993, 10, 1703994, 10, 1703995, 10, 1703996, 10, 1703997, 10, 1703998, 10, 1703999, 10, 1704000, 10, 1704001, 10, 1704002, 10, 1704003, 10, 1704004, 10, 1704005, 10, 1704006, 10, 1704007, 10, 1769488, 10, 1769489, 10, 1769490, 10, 1769491, 10, 1769492, 10, 1769493, 10, 1769494, 10, 1769495, 10, 1769496, 10, 1769497, 10, 1769498, 10, 1769499, 10, 1769500, 10, 1769501, 10, 1769502, 10, 1769503, 10, 1769504, 10, 1769505, 10, 1769506, 10, 1769507, 10, 1769508, 10, 1769509, 10, 1769510, 10, 1769511, 10, 1769512, 10, 1769513, 10, 1769514, 10, 1769515, 10, 1769516, 10, 1769517, 10, 1769518, 10, 1769519, 10, 1769520, 10, 1769521, 10, 1769522, 10, 1769523, 10, 1769524, 10, 1769525, 10, 1769526, 10, 1769527, 10, 1769528, 10, 1769529, 10, 1769530, 10, 1769531, 10, 1769532, 10, 1769533, 10, 1769534, 10, 1769535, 10, 1769536, 10, 1769537, 10, 1769538, 10, 1769539, 10, 1769540, 10, 1769541, 10 "_edit_lock_" True @@ -482,6 +483,12 @@ "3D" + "deflight_rot_y" + 0.628319 + "zfar" + 500 + "fov" + 45 "viewports" @@ -549,12 +556,6 @@ 0, 0, 0 - "zfar" - 500 - "deflight_rot_y" - 0.628319 - "fov" - 45 "default_light" True "viewport_mode" @@ -805,6 +806,7 @@ "2D" + False 2 834.664, 1309.6 @@ -998,7 +1000,7 @@ -1 "nodes" - -1, -1, 1, 0, -1, 2, 2, 0, 3, 1, 0, 0, 0, 5, 4, -1, 19, 2, 0, 6, 2, 7, 3, 8, 3, 9, 4, 10, 5, 11, 6, 12, 7, 13, 8, 14, 9, 15, 10, 16, 11, 17, 12, 18, 13, 19, 3, 20, 6, 21, 14, 22, 15, 3, 16, 0, 0, 0, 1, 23, -1, 2, 2, 0, 3, 17, 0, 2, 0, 25, 24, 18, 3, 2, 0, 10, 19, 3, 20, 0, 2, 0, 25, 26, 18, 3, 2, 0, 10, 21, 3, 20, 0, 2, 0, 25, 27, 18, 3, 2, 0, 10, 22, 3, 20, 0, 2, 0, 25, 28, 18, 3, 2, 0, 10, 23, 3, 20, 0, 2, 0, 25, 29, 18, 3, 2, 0, 10, 24, 3, 20, 0, 2, 0, 25, 30, 18, 3, 2, 0, 10, 25, 3, 20, 0, 2, 0, 25, 31, 18, 3, 2, 0, 10, 26, 3, 20, 0, 2, 0, 25, 32, 18, 3, 2, 0, 10, 27, 3, 20, 0, 2, 0, 25, 33, 18, 3, 2, 0, 10, 28, 3, 20, 0, 2, 0, 25, 34, 18, 3, 2, 0, 10, 29, 3, 20, 0, 2, 0, 25, 35, 18, 3, 2, 0, 10, 30, 3, 20, 0, 2, 0, 25, 36, 18, 3, 2, 0, 10, 31, 3, 20, 0, 2, 0, 25, 37, 18, 3, 2, 0, 10, 32, 3, 20, 0, 2, 0, 25, 38, 18, 3, 2, 0, 10, 33, 3, 20, 0, 2, 0, 25, 39, 18, 3, 2, 0, 10, 34, 3, 20, 0, 2, 0, 25, 40, 18, 3, 2, 0, 10, 35, 3, 20, 0, 2, 0, 25, 41, 18, 3, 2, 0, 10, 36, 3, 20, 0, 2, 0, 25, 42, 18, 3, 2, 0, 10, 37, 3, 20, 0, 2, 0, 25, 43, 18, 3, 2, 0, 10, 38, 3, 20, 0, 2, 0, 25, 44, 18, 3, 2, 0, 10, 39, 3, 20, 0, 2, 0, 25, 45, 18, 3, 2, 0, 10, 40, 3, 20, 0, 2, 0, 25, 46, 18, 3, 2, 0, 10, 41, 3, 20, 0, 2, 0, 25, 47, 18, 3, 2, 0, 10, 42, 3, 20, 0, 2, 0, 25, 48, 18, 3, 2, 0, 10, 43, 3, 20, 0, 2, 0, 25, 49, 18, 3, 2, 0, 10, 44, 3, 20, 0, 2, 0, 25, 50, 18, 3, 2, 0, 10, 45, 3, 20, 0, 2, 0, 25, 51, 18, 3, 2, 0, 10, 46, 3, 20, 0, 2, 0, 25, 52, 18, 3, 2, 0, 10, 47, 3, 20, 0, 2, 0, 25, 53, 18, 3, 2, 0, 10, 48, 3, 20, 0, 2, 0, 25, 54, 18, 3, 2, 0, 10, 49, 3, 20, 0, 2, 0, 25, 55, 18, 3, 2, 0, 10, 50, 3, 20, 0, 2, 0, 25, 56, 18, 3, 2, 0, 10, 51, 3, 20, 0, 2, 0, 25, 57, 18, 3, 2, 0, 10, 52, 3, 20, 0, 2, 0, 25, 58, 18, 3, 2, 0, 10, 53, 3, 20, 0, 2, 0, 25, 59, 18, 3, 2, 0, 10, 54, 3, 20, 0, 2, 0, 25, 60, 18, 3, 2, 0, 10, 55, 3, 20, 0, 2, 0, 25, 61, 18, 3, 2, 0, 10, 56, 3, 20, 0, 2, 0, 25, 62, 18, 3, 2, 0, 10, 57, 3, 20, 0, 2, 0, 25, 63, 18, 3, 2, 0, 10, 58, 3, 20, 0, 2, 0, 25, 64, 18, 3, 2, 0, 10, 59, 3, 20, 0, 2, 0, 25, 65, 18, 3, 2, 0, 10, 60, 3, 20, 0, 2, 0, 25, 66, 18, 3, 2, 0, 10, 61, 3, 20, 0, 0, 0, 68, 67, 62, 3, 2, 0, 10, 63, 3, 64, 0, 0, 0, 1, 69, -1, 1, 2, 0, 0, 46, 0, 71, 70, 65, 5, 2, 0, 10, 66, 3, 67, 72, 68, 73, 69, 0, 46, 0, 71, 74, 65, 5, 2, 0, 10, 70, 3, 67, 72, 71, 73, 72, 0, 46, 0, 71, 75, 65, 5, 2, 0, 10, 73, 3, 67, 72, 74, 73, 72, 0, 46, 0, 71, 76, 75, 3, 2, 0, 10, 76, 3, 77, 0, 0, 0, 78, 77, -1, 7, 2, 0, 79, 78, 80, 4, 81, 2, 82, 79, 83, 2, 84, 4, 0, 0, 0, 1, 85, -1, 1, 2, 0, 0, 52, 0, 68, 86, 80, 3, 2, 0, 10, 81, 3, 82, 0, 52, 0, 68, 87, 80, 3, 2, 0, 10, 83, 3, 82, 0, 52, 0, 68, 88, 80, 3, 2, 0, 10, 84, 3, 82, 0, 52, 0, 68, 89, 80, 3, 2, 0, 10, 85, 3, 82, 0, 52, 0, 68, 90, 80, 3, 2, 0, 10, 86, 3, 82, 0, 52, 0, 68, 91, 80, 3, 2, 0, 10, 87, 3, 82, 0, 52, 0, 68, 92, 80, 3, 2, 0, 10, 88, 3, 82, 0, 52, 0, 68, 93, 80, 3, 2, 0, 10, 89, 3, 82, 0, 52, 0, 68, 94, 80, 3, 2, 0, 10, 90, 3, 82, 0, 52, 0, 68, 95, 80, 3, 2, 0, 10, 91, 3, 82, 0, 52, 0, 68, 96, 80, 3, 2, 0, 10, 92, 3, 82, 0, 0, 0, 98, 97, 93, 2, 2, 0, 3, 94, 0, 0, 0, 99, 99, -1, 30, 2, 0, 6, 2, 7, 3, 8, 3, 9, 4, 100, 95, 101, 96, 102, 97, 103, 98, 104, 0, 105, 0, 106, 0, 107, 0, 108, 2, 109, 2, 110, 13, 111, 3, 112, 6, 113, 99, 114, 3, 115, 100, 116, 6, 117, 4, 118, 4, 119, 101, 120, 8, 121, 8, 122, 2, 123, 4, 124, 102, 0 + -1, -1, 1, 0, -1, 2, 2, 0, 3, 1, 0, 0, 0, 5, 4, -1, 21, 2, 0, 6, 2, 7, 3, 8, 3, 9, 4, 10, 5, 11, 6, 12, 7, 13, 2, 14, 7, 15, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 7, 21, 3, 22, 5, 23, 13, 24, 14, 3, 15, 0, 0, 0, 1, 25, -1, 2, 2, 0, 3, 16, 0, 2, 0, 27, 26, 17, 3, 2, 0, 9, 18, 3, 19, 0, 2, 0, 27, 28, 17, 3, 2, 0, 9, 20, 3, 19, 0, 2, 0, 27, 29, 17, 3, 2, 0, 9, 21, 3, 19, 0, 2, 0, 27, 30, 17, 3, 2, 0, 9, 22, 3, 19, 0, 2, 0, 27, 31, 17, 3, 2, 0, 9, 23, 3, 19, 0, 2, 0, 27, 32, 17, 3, 2, 0, 9, 24, 3, 19, 0, 2, 0, 27, 33, 17, 3, 2, 0, 9, 25, 3, 19, 0, 2, 0, 27, 34, 17, 3, 2, 0, 9, 26, 3, 19, 0, 2, 0, 27, 35, 17, 3, 2, 0, 9, 27, 3, 19, 0, 2, 0, 27, 36, 17, 3, 2, 0, 9, 28, 3, 19, 0, 2, 0, 27, 37, 17, 3, 2, 0, 9, 29, 3, 19, 0, 2, 0, 27, 38, 17, 3, 2, 0, 9, 30, 3, 19, 0, 2, 0, 27, 39, 17, 3, 2, 0, 9, 31, 3, 19, 0, 2, 0, 27, 40, 17, 3, 2, 0, 9, 32, 3, 19, 0, 2, 0, 27, 41, 17, 3, 2, 0, 9, 33, 3, 19, 0, 2, 0, 27, 42, 17, 3, 2, 0, 9, 34, 3, 19, 0, 2, 0, 27, 43, 17, 3, 2, 0, 9, 35, 3, 19, 0, 2, 0, 27, 44, 17, 3, 2, 0, 9, 36, 3, 19, 0, 2, 0, 27, 45, 17, 3, 2, 0, 9, 37, 3, 19, 0, 2, 0, 27, 46, 17, 3, 2, 0, 9, 38, 3, 19, 0, 2, 0, 27, 47, 17, 3, 2, 0, 9, 39, 3, 19, 0, 2, 0, 27, 48, 17, 3, 2, 0, 9, 40, 3, 19, 0, 2, 0, 27, 49, 17, 3, 2, 0, 9, 41, 3, 19, 0, 2, 0, 27, 50, 17, 3, 2, 0, 9, 42, 3, 19, 0, 2, 0, 27, 51, 17, 3, 2, 0, 9, 43, 3, 19, 0, 2, 0, 27, 52, 17, 3, 2, 0, 9, 44, 3, 19, 0, 2, 0, 27, 53, 17, 3, 2, 0, 9, 45, 3, 19, 0, 2, 0, 27, 54, 17, 3, 2, 0, 9, 46, 3, 19, 0, 2, 0, 27, 55, 17, 3, 2, 0, 9, 47, 3, 19, 0, 2, 0, 27, 56, 17, 3, 2, 0, 9, 48, 3, 19, 0, 2, 0, 27, 57, 17, 3, 2, 0, 9, 49, 3, 19, 0, 2, 0, 27, 58, 17, 3, 2, 0, 9, 50, 3, 19, 0, 2, 0, 27, 59, 17, 3, 2, 0, 9, 51, 3, 19, 0, 2, 0, 27, 60, 17, 3, 2, 0, 9, 52, 3, 19, 0, 2, 0, 27, 61, 17, 3, 2, 0, 9, 53, 3, 19, 0, 2, 0, 27, 62, 17, 3, 2, 0, 9, 54, 3, 19, 0, 2, 0, 27, 63, 17, 3, 2, 0, 9, 55, 3, 19, 0, 2, 0, 27, 64, 17, 3, 2, 0, 9, 56, 3, 19, 0, 2, 0, 27, 65, 17, 3, 2, 0, 9, 57, 3, 19, 0, 2, 0, 27, 66, 17, 3, 2, 0, 9, 58, 3, 19, 0, 2, 0, 27, 67, 17, 3, 2, 0, 9, 59, 3, 19, 0, 2, 0, 27, 68, 17, 3, 2, 0, 9, 60, 3, 19, 0, 0, 0, 70, 69, 61, 3, 2, 0, 9, 62, 3, 63, 0, 0, 0, 1, 71, -1, 1, 2, 0, 0, 46, 0, 73, 72, 64, 5, 2, 0, 9, 65, 3, 66, 74, 67, 75, 68, 0, 46, 0, 73, 76, 64, 5, 2, 0, 9, 69, 3, 66, 74, 70, 75, 71, 0, 46, 0, 73, 77, 64, 5, 2, 0, 9, 72, 3, 66, 74, 73, 75, 71, 0, 46, 0, 73, 78, 74, 3, 2, 0, 9, 75, 3, 76, 0, 0, 0, 80, 79, -1, 7, 2, 0, 81, 77, 82, 78, 83, 2, 84, 79, 85, 2, 86, 78, 0, 0, 0, 1, 87, -1, 1, 2, 0, 0, 52, 0, 70, 88, 80, 3, 2, 0, 9, 81, 3, 82, 0, 52, 0, 70, 89, 80, 3, 2, 0, 9, 83, 3, 82, 0, 52, 0, 70, 90, 80, 3, 2, 0, 9, 84, 3, 82, 0, 52, 0, 70, 91, 80, 3, 2, 0, 9, 85, 3, 82, 0, 52, 0, 70, 92, 80, 3, 2, 0, 9, 86, 3, 82, 0, 52, 0, 70, 93, 80, 3, 2, 0, 9, 87, 3, 82, 0, 52, 0, 70, 94, 80, 3, 2, 0, 9, 88, 3, 82, 0, 52, 0, 70, 95, 80, 3, 2, 0, 9, 89, 3, 82, 0, 52, 0, 70, 96, 80, 3, 2, 0, 9, 90, 3, 82, 0, 52, 0, 70, 97, 80, 3, 2, 0, 9, 91, 3, 82, 0, 52, 0, 70, 98, 80, 3, 2, 0, 9, 92, 3, 82, 0, 0, 0, 100, 99, 93, 2, 2, 0, 3, 94, 0, 0, 0, 101, 101, -1, 29, 2, 0, 6, 2, 7, 3, 8, 3, 102, 95, 103, 96, 104, 97, 105, 98, 106, 0, 107, 0, 108, 0, 109, 0, 110, 2, 111, 2, 112, 12, 113, 3, 114, 5, 115, 99, 116, 3, 117, 100, 118, 5, 119, 78, 120, 78, 121, 101, 122, 7, 123, 7, 124, 2, 125, 78, 126, 102, 0 "conns" diff --git a/demos/2d/platformer/tiles_demo.png b/demos/2d/platformer/tiles_demo.png index a7a5000906e746f5dea30f6439ab316b5e77163e..bc738e6d387d09cbe98f456228bb126d07f03650 100644 GIT binary patch literal 10066 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 diff --git a/demos/2d/platformer/tileset.xml b/demos/2d/platformer/tileset.xml index 2e4ecc8c0464..d8f9a651ee88 100644 --- a/demos/2d/platformer/tileset.xml +++ b/demos/2d/platformer/tileset.xml @@ -1,134 +1,191 @@ - + - - "" - 0 - 0, 8, 64, 8, 64, 64, 0, 64 - - - "" 0 - 0, 64, 0, 8, 56, 8, 56, 64 - + -32, -24, 32, -24, 32, 32, -32, 32 + - "" 0 - 0, 64, 0, 0, 56, 0, 56, 64 - + -32, 32, -32, -24, 24, -24, 24, 32 + - "" 0 - 0, 64, 0, 0, 56, 0, 56, 64 - + -32, 32, -32, -32, 24, -32, 24, 32 + - "" 0 - 0, 64, 0, 0, 56, 0, 64, 8, 64, 64 - + -64, 32, -64, -32, -8, -32, -8, 32 + - "" 0 - 0, 64, 0, 8, 64, 8, 64, 64 - + -32, 32, -32, -32, 24, -32, 32, -24, 32, 32 + - "" 0 - 0, 64, 0, 8, 64, 8, 64, 64 - + -32, 32, -32, -24, 32, -24, 32, 32 + - "" 0 - 0, 0, 64, 0, 64, 64, 0, 64 - + -32, 32, -32, -24, 32, -24, 32, 32 + - "" 0 - 0, 8, 64, 72, 64, 128, 0, 128 - + -32, -32, 32, -32, 32, 32, -32, 32 + - "" 0 - 0, 64, 0, 0, 56, 0, 56, 64 - + -32, -56, 32, 8, 32, 64, -32, 64 + + + + 0 + -32, 32, -32, -32, 24, -32, 24, 32 + + + + 0 + -32, -24, 32, -24, 32, 24, -32, 24 + + + + 0 + -32, -24, 24, -24, 24, 24, -32, 24 + - "" "floor" - 0, 0 + 0, 0 + 32, 32 0, 0, 64, 64 - + + + "edge" - 0, 0 + 0, 0 + 32, 32 64, 0, 64, 64 - + + + "wall" - 0, 0 + 0, 0 + 32, 32 64, 64, 64, 64 - + + + "wall_deco" - 0, 0 + 0, 0 + 64, 32 320, 128, 128, 64 - + + + "corner" - 0, 0 + 0, 0 + 32, 32 64, 128, 64, 64 - + + + "flowers" - 0, 0 + 0, 0 + 32, 32 192, 192, 64, 64 - + + + "tree_base" - 0, 0 + 0, 0 + 32, 32 256, 192, 64, 64 - + + + "tree_mid" - 0, 0 + 0, 0 + 0, 0 256, 128, 64, 64 - "tree_mid 2" + + + "tree_mid 2" - 0, 0 + 0, 0 + 0, 0 256, 64, 64, 64 - "tree_top" + + + "tree_top" - 0, 0 + 0, 0 + 0, 0 256, 0, 64, 64 - "solid" + + + "solid" - 0, 0 + 0, 0 + 0, 0 0, 64, 64, 64 - "ceiling" + + + "ceiling" - 0, 0 + 0, 0 + 32, 32 384, 64, 64, 64 - + + + "ramp" - 0, 0 + 0, 0 + 32, 64 128, 128, 64, 128 - + + + "ceiling2wall" - 0, 0 + 0, 0 + 32, 32 448, 64, 64, 64 - - + + + + "platform_floor" + + 0, 0 + 32, 32 + 128, 0, 64, 64 + + + + "platform_edge" + + 0, 0 + 32, 32 + 192, 0, 64, 64 + + + + \ No newline at end of file diff --git a/demos/2d/platformer/tileset_edit.xml b/demos/2d/platformer/tileset_edit.xml index 2473656a6a07..db289433abae 100644 --- a/demos/2d/platformer/tileset_edit.xml +++ b/demos/2d/platformer/tileset_edit.xml @@ -1,71 +1,83 @@ - + 0 - 0, 8, 64, 8, 64, 64, 0, 64 + -32, -24, 32, -24, 32, 32, -32, 32 0 - 0, 64, 0, 8, 56, 8, 56, 64 + -32, 32, -32, -24, 24, -24, 24, 32 0 - 0, 64, 0, 0, 56, 0, 56, 64 + -32, 32, -32, -32, 24, -32, 24, 32 0 - 0, 64, 0, 0, 56, 0, 56, 64 + -64, 32, -64, -32, -8, -32, -8, 32 0 - 0, 64, 0, 0, 56, 0, 64, 8, 64, 64 + -32, 32, -32, -32, 24, -32, 32, -24, 32, 32 0 - 0, 8, 64, 72, 64, 128, 0, 128 + -32, 32, -32, -24, 32, -24, 32, 32 0 - 0, 64, 0, 8, 64, 8, 64, 64 + -32, 32, -32, -24, 32, -24, 32, 32 0 - 0, 64, 0, 8, 64, 8, 64, 64 + -32, -32, 32, -32, 32, 32, -32, 32 0 - 0, 0, 64, 0, 64, 64, 0, 64 + -32, -56, 32, 8, 32, 64, -32, 64 0 - 0, 64, 0, 0, 56, 0, 56, 64 + -32, 32, -32, -32, 24, -32, 24, 32 + + + + 0 + -32, -24, 32, -24, 32, 24, -32, 24 + + + + 0 + -32, -24, 24, -24, 24, 24, -32, 24 "names" - + "Node" + "_import_path" "__meta__" "floor" "Sprite" "visibility/visible" "visibility/opacity" "visibility/self_opacity" - "visibility/behind_parent" "transform/pos" "transform/rot" "transform/scale" + "z/z" + "z/relative" "texture" "centered" "offset" @@ -83,6 +95,7 @@ "shapes/0/shape" "shapes/0/transform" "shapes/0/trigger" + "layers" "constant_linear_velocity" "constant_angular_velocity" "friction" @@ -90,11 +103,11 @@ "CollisionPolygon2D" "build_mode" "polygon" + "trigger" "edge" "wall" "wall_deco" "corner" - "ramp" "flowers" "tree_base" "tree_mid" @@ -102,13 +115,10 @@ "tree_top" "solid" "ceiling" + "ramp" "ceiling2wall" "help" "Label" - "margin/left" - "margin/top" - "margin/right" - "margin/bottom" "focus_neighbour/left" "focus_neighbour/top" "focus_neighbour/right" @@ -130,29 +140,38 @@ "autowrap" "uppercase" "percent_visible" + "platform_floor" + "platform_edge" "version" 1 "conn_count" 0 "node_count" - 36 + 42 "variants" - + + "" "__editor_plugin_states__" "2D" "pixel_snap" - False + True "zoom" - 1.670182 + 1.670183 + "use_snap" + True "ofs" - -58.9115, 60.1605 + -446.534, -87.6905 + "snap" + 8 "3D" + "deflight_rot_y" + 0.628319 "zfar" 500 "fov" @@ -166,10 +185,12 @@ 0 "y_rot" 0 - "use_orthogonal" - False + "listener" + True "use_environment" False + "use_orthogonal" + False "pos" 0, 0, 0 @@ -180,10 +201,12 @@ 0 "y_rot" 0 - "use_orthogonal" + "listener" False "use_environment" False + "use_orthogonal" + False "pos" 0, 0, 0 @@ -194,10 +217,12 @@ 0 "y_rot" 0 - "use_orthogonal" + "listener" False "use_environment" False + "use_orthogonal" + False "pos" 0, 0, 0 @@ -208,10 +233,12 @@ 0 "y_rot" 0 - "use_orthogonal" + "listener" False "use_environment" False + "use_orthogonal" + False "pos" 0, 0, 0 @@ -220,12 +247,18 @@ 1 "default_light" True + "ambient_light_color" + 0.15, 0.15, 0.15, 1 "show_grid" True "show_origin" True "znear" 0.1 + "default_srgb" + False + "deflight_rot_x" + 0.942478 "__editor_run_settings__" @@ -239,45 +272,42 @@ "2D" True - - + 1 0, 0 - + 0 1, 1 + 0 + False 1 - 1, 1, 1, 1 0, 0, 64, 64 1, -0, 0, 1, 0, 0 - 64, 8, 64, 64, 0, 64, 0, 8 + 32, -24, 32, 32, -32, 32, -32, -24 64, 0 64, 0, 64, 64 - 0, 8, 56, 8, 56, 64, 0, 64 + -32, -24, 24, -24, 24, 32, -32, 32 64, 64 64, 64, 64, 64 - 0, 0, 56, 0, 56, 64, 0, 64 - 64, 128 + -32, -32, 24, -32, 24, 32, -32, 32 + 96, 128 320, 128, 128, 64 + -64, -32, -8, -32, -8, 32, -64, 32 64, 192 64, 128, 64, 64 - 0, 0, 56, 0, 64, 8, 64, 64, 0, 64 - 256, 192 - 128, 128, 64, 128 - - 0, 8, 64, 72, 64, 128, 0, 128 + -32, -32, 24, -32, 32, -24, 32, 32, -32, 32 128, 192 192, 192, 64, 64 - - 0, 64, 64, 64, 64, 8, 0, 8 + + -32, 32, 32, 32, 32, -24, -32, -24 192, 192 256, 192, 64, 64 - + 192, 128 256, 128, 64, 64 192, 64 @@ -288,23 +318,29 @@ 0, 64, 64, 64 0, 128 384, 64, 64, 64 + + 32, -32, 32, 32, -32, 32, -32, -32 + 256, 224 + 128, 128, 64, 128 - 64, 0, 64, 64, 0, 64, 0, 0 + -32, -56, 32, 8, 32, 64, -32, 64 0, 192 448, 64, 64, 64 - - - - - 2 - - "This scene serves as a tool for editing the tileset. Nodes (sprites) and their respective collisions are edited here. To create a tileset from this, a "TileSet" resoucre must be created. Use the helper in: Scene -< Convert To -< TileSet This will save a tileset. Saving over it will merge your changes. Finally, the saved tileset resource (tileset.xml in this case), can be opened to be used into a TileMap node for editing a tile map. " + "This scene serves as a tool for editing the tileset. Nodes (sprites) and their respective collisions are edited here. To create a tileset from this, a "TileSet" resoucre must be created. Use the helper in: Scene -< Convert To -< TileSet This will save a tileset. Saving over it will merge your changes. Finally, the saved tileset resource (tileset.xml in this case), can be opened to be used into a TileMap node for editing a tile map. " -1 + 0, 256 + 128, 0, 64, 64 + + 32, -24, 32, 24, -32, 24, -32, -24 + 64, 256 + 192, 0, 64, 64 + + 24, -24, 24, 24, -32, 24, -32, -24 "nodes" - -1, -1, 0, 0, -1, 1, 1, 0, 0, 0, 0, 3, 2, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 11, 0, 1, 0, 23, 22, -1, 15, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 24, 8, 25, 12, 26, 13, 27, 3, 28, 4, 29, 5, 30, 2, 31, 5, 0, 2, 0, 32, 32, -1, 9, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 33, 9, 34, 14, 0, 0, 0, 3, 35, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 15, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 16, 0, 4, 0, 23, 22, -1, 15, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 24, 8, 25, 17, 26, 13, 27, 3, 28, 4, 29, 5, 30, 2, 31, 5, 0, 5, 0, 32, 32, -1, 9, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 33, 9, 34, 18, 0, 0, 0, 3, 36, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 19, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 20, 0, 7, 0, 23, 22, -1, 15, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 24, 8, 25, 21, 26, 13, 27, 3, 28, 4, 29, 5, 30, 2, 31, 5, 0, 8, 0, 32, 32, -1, 9, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 33, 9, 34, 22, 0, 0, 0, 3, 37, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 23, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 24, 0, 10, 0, 23, 22, -1, 15, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 24, 8, 25, 25, 26, 13, 27, 3, 28, 4, 29, 5, 30, 2, 31, 5, 0, 11, 0, 32, 32, -1, 9, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 33, 9, 34, 22, 0, 0, 0, 3, 38, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 26, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 27, 0, 13, 0, 23, 22, -1, 15, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 24, 8, 25, 28, 26, 13, 27, 3, 28, 4, 29, 5, 30, 2, 31, 5, 0, 14, 0, 32, 32, -1, 9, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 33, 9, 34, 29, 0, 0, 0, 3, 39, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 30, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 31, 0, 16, 0, 23, 22, -1, 15, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 24, 8, 25, 32, 26, 13, 27, 3, 28, 4, 29, 5, 30, 2, 31, 5, 0, 17, 0, 32, 32, -1, 9, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 33, 9, 34, 33, 0, 0, 0, 3, 40, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 34, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 35, 0, 19, 0, 23, 22, -1, 15, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 24, 8, 25, 36, 26, 13, 27, 3, 28, 4, 29, 5, 30, 2, 31, 5, 0, 20, 0, 32, 32, -1, 9, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 33, 9, 34, 37, 0, 0, 0, 3, 41, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 38, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 39, 0, 22, 0, 23, 22, -1, 15, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 24, 8, 25, 40, 26, 13, 27, 3, 28, 4, 29, 5, 30, 2, 31, 5, 0, 23, 0, 32, 32, -1, 9, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 33, 9, 34, 37, 0, 0, 0, 3, 42, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 41, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 42, 0, 0, 0, 3, 43, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 43, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 44, 0, 0, 0, 3, 44, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 45, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 46, 0, 0, 0, 3, 45, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 47, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 48, 0, 0, 0, 3, 46, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 49, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 50, 0, 29, 0, 23, 22, -1, 15, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 24, 8, 25, 51, 26, 13, 27, 3, 28, 4, 29, 5, 30, 2, 31, 5, 0, 30, 0, 32, 32, -1, 9, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 33, 9, 34, 52, 0, 0, 0, 3, 47, -1, 18, 4, 1, 5, 2, 6, 2, 7, 3, 8, 53, 9, 5, 10, 6, 11, 7, 12, 3, 13, 4, 14, 3, 15, 3, 16, 8, 17, 8, 18, 9, 19, 10, 20, 1, 21, 54, 0, 32, 0, 23, 22, -1, 15, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 24, 8, 25, 55, 26, 13, 27, 3, 28, 4, 29, 5, 30, 2, 31, 5, 0, 33, 0, 32, 32, -1, 9, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 33, 9, 34, 22, 0, 0, 0, 49, 48, -1, 29, 4, 1, 5, 2, 6, 2, 7, 3, 50, 56, 51, 57, 52, 58, 53, 59, 54, 60, 55, 60, 56, 60, 57, 60, 58, 1, 59, 1, 60, 61, 61, 2, 62, 5, 63, 62, 64, 2, 65, 62, 66, 5, 67, 3, 68, 3, 69, 63, 70, 9, 71, 9, 72, 3, 73, 3, 74, 64, 0 + -1, -1, 0, 0, -1, 2, 1, 0, 2, 1, 0, 0, 0, 4, 3, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 12, 0, 1, 0, 25, 24, -1, 18, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 26, 10, 27, 13, 28, 14, 29, 9, 30, 10, 31, 4, 32, 5, 33, 3, 34, 5, 0, 2, 0, 35, 35, -1, 12, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 36, 7, 37, 15, 38, 9, 0, 0, 0, 4, 39, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 16, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 17, 0, 4, 0, 25, 24, -1, 18, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 26, 10, 27, 18, 28, 14, 29, 9, 30, 10, 31, 4, 32, 5, 33, 3, 34, 5, 0, 5, 0, 35, 35, -1, 12, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 36, 7, 37, 19, 38, 9, 0, 0, 0, 4, 40, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 20, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 21, 0, 7, 0, 25, 24, -1, 18, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 26, 10, 27, 22, 28, 14, 29, 9, 30, 10, 31, 4, 32, 5, 33, 3, 34, 5, 0, 8, 0, 35, 35, -1, 12, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 36, 7, 37, 23, 38, 9, 0, 0, 0, 4, 41, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 24, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 25, 0, 10, 0, 25, 24, -1, 18, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 26, 10, 27, 26, 28, 14, 29, 9, 30, 10, 31, 4, 32, 5, 33, 3, 34, 5, 0, 11, 0, 35, 35, -1, 12, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 36, 7, 37, 27, 38, 9, 0, 0, 0, 4, 42, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 28, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 29, 0, 13, 0, 25, 24, -1, 18, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 26, 10, 27, 30, 28, 14, 29, 9, 30, 10, 31, 4, 32, 5, 33, 3, 34, 5, 0, 14, 0, 35, 35, -1, 12, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 36, 7, 37, 31, 38, 9, 0, 0, 0, 4, 43, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 32, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 33, 0, 16, 0, 25, 24, -1, 18, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 26, 10, 27, 34, 28, 14, 29, 9, 30, 10, 31, 4, 32, 5, 33, 3, 34, 5, 0, 17, 0, 35, 35, -1, 12, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 36, 7, 37, 35, 38, 9, 0, 0, 0, 4, 44, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 36, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 37, 0, 19, 0, 25, 24, -1, 18, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 26, 10, 27, 38, 28, 14, 29, 9, 30, 10, 31, 4, 32, 5, 33, 3, 34, 5, 0, 20, 0, 35, 35, -1, 12, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 36, 7, 37, 35, 38, 9, 0, 0, 0, 4, 45, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 39, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 40, 0, 0, 0, 4, 46, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 41, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 42, 0, 0, 0, 4, 47, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 43, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 44, 0, 0, 0, 4, 48, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 45, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 46, 0, 0, 0, 4, 49, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 47, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 48, 0, 26, 0, 25, 24, -1, 18, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 26, 10, 27, 49, 28, 14, 29, 9, 30, 10, 31, 4, 32, 5, 33, 3, 34, 5, 0, 27, 0, 35, 35, -1, 12, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 36, 7, 37, 50, 38, 9, 0, 0, 0, 4, 50, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 51, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 52, 0, 29, 0, 25, 24, -1, 18, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 26, 10, 27, 53, 28, 14, 29, 9, 30, 10, 31, 4, 32, 5, 33, 3, 34, 5, 0, 30, 0, 35, 35, -1, 12, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 36, 7, 37, 54, 38, 9, 0, 0, 0, 4, 51, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 55, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 56, 0, 32, 0, 25, 24, -1, 18, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 26, 10, 27, 57, 28, 14, 29, 9, 30, 10, 31, 4, 32, 5, 33, 3, 34, 5, 0, 33, 0, 35, 35, -1, 12, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 36, 7, 37, 23, 38, 9, 0, 0, 0, 53, 52, -1, 25, 1, 0, 5, 2, 6, 3, 7, 3, 54, 0, 55, 0, 56, 0, 57, 0, 58, 2, 59, 2, 60, 58, 61, 3, 62, 5, 63, 3, 64, 3, 65, 3, 66, 5, 67, 9, 68, 9, 69, 59, 70, 7, 71, 7, 72, 9, 73, 9, 74, 60, 0, 0, 0, 4, 75, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 61, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 62, 0, 36, 0, 25, 24, -1, 18, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 26, 10, 27, 63, 28, 14, 29, 9, 30, 10, 31, 4, 32, 5, 33, 3, 34, 5, 0, 37, 0, 35, 35, -1, 12, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 36, 7, 37, 64, 38, 9, 0, 0, 0, 4, 76, -1, 20, 1, 0, 5, 2, 6, 3, 7, 3, 8, 65, 9, 5, 10, 6, 11, 7, 12, 2, 13, 8, 14, 2, 15, 4, 16, 9, 17, 9, 18, 10, 19, 10, 20, 7, 21, 11, 22, 2, 23, 66, 0, 39, 0, 25, 24, -1, 18, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 26, 10, 27, 67, 28, 14, 29, 9, 30, 10, 31, 4, 32, 5, 33, 3, 34, 5, 0, 40, 0, 35, 35, -1, 12, 1, 0, 5, 2, 6, 3, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12, 2, 36, 7, 37, 68, 38, 9, 0 "conns" diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 9fcf34cee631..06c97027f09a 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -28,7 +28,7 @@ /*************************************************************************/ #include "tile_map.h" #include "io/marshalls.h" -#include "servers/physics_2d_server.h" + void TileMap::_notification(int p_what) { switch(p_what) { @@ -62,7 +62,7 @@ void TileMap::_update_quadrant_space(const RID& p_space) { for (Map::Element *E=quadrant_map.front();E;E=E->next()) { Quadrant &q=E->get(); - Physics2DServer::get_singleton()->body_set_space(q.static_body,p_space); + Physics2DServer::get_singleton()->body_set_space(q.body,p_space); } } @@ -79,7 +79,7 @@ void TileMap::_update_quadrant_transform() { Matrix32 xform; xform.set_origin( q.pos ); xform = global_transform * xform; - Physics2DServer::get_singleton()->body_set_state(q.static_body,Physics2DServer::BODY_STATE_TRANSFORM,xform); + Physics2DServer::get_singleton()->body_set_state(q.body,Physics2DServer::BODY_STATE_TRANSFORM,xform); } } @@ -178,7 +178,7 @@ void TileMap::_update_dirty_quadrants() { Quadrant &q = *dirty_quadrant_list.first()->self(); vs->canvas_item_clear(q.canvas_item); - ps->body_clear_shapes(q.static_body); + ps->body_clear_shapes(q.body); int shape_idx=0; for(int i=0;ibody_add_shape(q.static_body,shape->get_rid(),xform); - ps->body_set_shape_metadata(q.static_body,shape_idx++,Vector2(E->key().x,E->key().y)); + ps->body_add_shape(q.body,shape->get_rid(),xform); + ps->body_set_shape_metadata(q.body,shape_idx++,Vector2(E->key().x,E->key().y)); } } @@ -339,19 +339,19 @@ Map::Element *TileMap::_create_quadrant(const q.canvas_item = VisualServer::get_singleton()->canvas_item_create(); VisualServer::get_singleton()->canvas_item_set_parent( q.canvas_item, get_canvas_item() ); VisualServer::get_singleton()->canvas_item_set_transform( q.canvas_item, xform ); - q.static_body=Physics2DServer::get_singleton()->body_create(Physics2DServer::BODY_MODE_STATIC); - Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.static_body,get_instance_ID()); - Physics2DServer::get_singleton()->body_set_layer_mask(q.static_body,collision_layer); - Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_FRICTION,friction); - Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_BOUNCE,bounce); + q.body=Physics2DServer::get_singleton()->body_create(body_mode); + Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.body,get_instance_ID()); + Physics2DServer::get_singleton()->body_set_layer_mask(q.body,collision_layer); + Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_FRICTION,friction); + Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_BOUNCE,bounce); if (is_inside_tree()) { xform = get_global_transform() * xform; RID space = get_world_2d()->get_space(); - Physics2DServer::get_singleton()->body_set_space(q.static_body,space); + Physics2DServer::get_singleton()->body_set_space(q.body,space); } - Physics2DServer::get_singleton()->body_set_state(q.static_body,Physics2DServer::BODY_STATE_TRANSFORM,xform); + Physics2DServer::get_singleton()->body_set_state(q.body,Physics2DServer::BODY_STATE_TRANSFORM,xform); rect_cache_dirty=true; quadrant_order_dirty=true; @@ -361,7 +361,7 @@ Map::Element *TileMap::_create_quadrant(const void TileMap::_erase_quadrant(Map::Element *Q) { Quadrant &q=Q->get(); - Physics2DServer::get_singleton()->free(q.static_body); + Physics2DServer::get_singleton()->free(q.body); VisualServer::get_singleton()->free(q.canvas_item); if (q.dirty_list.in_list()) dirty_quadrant_list.remove(&q.dirty_list); @@ -586,17 +586,29 @@ void TileMap::set_collision_layer_mask(uint32_t p_layer) { for (Map::Element *E=quadrant_map.front();E;E=E->next()) { Quadrant &q=E->get(); - Physics2DServer::get_singleton()->body_set_layer_mask(q.static_body,collision_layer); + Physics2DServer::get_singleton()->body_set_layer_mask(q.body,collision_layer); } } +Physics2DServer::BodyMode TileMap::get_collision_body_mode() const{ + + return body_mode; +} + +void TileMap::set_collision_body_mode(Physics2DServer::BodyMode p_body_mode) { + + _clear_quadrants(); + body_mode=p_body_mode; + _recreate_quadrants(); +} + void TileMap::set_collision_friction(float p_friction) { friction=p_friction; for (Map::Element *E=quadrant_map.front();E;E=E->next()) { Quadrant &q=E->get(); - Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_FRICTION,p_friction); + Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_FRICTION,p_friction); } } @@ -612,7 +624,7 @@ void TileMap::set_collision_bounce(float p_bounce){ for (Map::Element *E=quadrant_map.front();E;E=E->next()) { Quadrant &q=E->get(); - Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_BOUNCE,p_bounce); + Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_BOUNCE,p_bounce); } } @@ -807,6 +819,9 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_collision_layer_mask","mask"),&TileMap::set_collision_layer_mask); ObjectTypeDB::bind_method(_MD("get_collision_layer_mask"),&TileMap::get_collision_layer_mask); + ObjectTypeDB::bind_method(_MD("set_collision_body_mode","body_mode"),&TileMap::set_collision_body_mode); + ObjectTypeDB::bind_method(_MD("get_collision_body_mode"),&TileMap::get_collision_body_mode); + ObjectTypeDB::bind_method(_MD("set_collision_friction","value"),&TileMap::set_collision_friction); ObjectTypeDB::bind_method(_MD("get_collision_friction"),&TileMap::get_collision_friction); @@ -837,6 +852,7 @@ void TileMap::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size")); ADD_PROPERTY( PropertyInfo(Variant::MATRIX32,"cell/custom_transform"),_SCS("set_custom_transform"),_SCS("get_custom_transform")); ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/half_offset",PROPERTY_HINT_ENUM,"Offset X,Offset Y,Disabled"),_SCS("set_half_offset"),_SCS("get_half_offset")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/body_mode",PROPERTY_HINT_ENUM,"Static,Kinematic"),_SCS("set_collision_body_mode"),_SCS("get_collision_body_mode")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_bounce"),_SCS("get_collision_bounce")); ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask")); @@ -870,6 +886,7 @@ TileMap::TileMap() { bounce=0; mode=MODE_SQUARE; half_offset=HALF_OFFSET_DISABLED; + body_mode=Physics2DServer::BODY_MODE_STATIC; fp_adjust=0.01; fp_adjust=0.01; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 4e9e2e7e9797..52e8eae306c2 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -33,6 +33,7 @@ #include "scene/resources/tile_set.h" #include "self_list.h" #include "vset.h" +#include "servers/physics_2d_server.h" class TileMap : public Node2D { @@ -60,6 +61,7 @@ private: Mode mode; Matrix32 custom_transform; HalfOffset half_offset; + Physics2DServer::BodyMode body_mode; union PosKey { @@ -97,14 +99,14 @@ private: Vector2 pos; RID canvas_item; - RID static_body; + RID body; SelfList dirty_list; VSet cells; - void operator=(const Quadrant& q) { pos=q.pos; canvas_item=q.canvas_item; static_body=q.static_body; cells=q.cells; } - Quadrant(const Quadrant& q) : dirty_list(this) { pos=q.pos; canvas_item=q.canvas_item; static_body=q.static_body; cells=q.cells;} + void operator=(const Quadrant& q) { pos=q.pos; canvas_item=q.canvas_item; body=q.body; cells=q.cells; } + Quadrant(const Quadrant& q) : dirty_list(this) { pos=q.pos; canvas_item=q.canvas_item; body=q.body; cells=q.cells;} Quadrant() : dirty_list(this) {} }; @@ -177,6 +179,9 @@ public: void set_collision_layer_mask(uint32_t p_layer); uint32_t get_collision_layer_mask() const; + void set_collision_body_mode(Physics2DServer::BodyMode p_body_mode); + Physics2DServer::BodyMode get_collision_body_mode() const; + void set_collision_friction(float p_friction); float get_collision_friction() const; diff --git a/tools/editor/plugins/collision_polygon_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_editor_plugin.cpp index b92acb60f95e..a6f2085a191c 100644 --- a/tools/editor/plugins/collision_polygon_editor_plugin.cpp +++ b/tools/editor/plugins/collision_polygon_editor_plugin.cpp @@ -31,6 +31,8 @@ #include "os/file_access.h" #include "tools/editor/editor_settings.h" #include "scene/3d/camera.h" +#include "canvas_item_editor_plugin.h" + void CollisionPolygonEditor::_notification(int p_what) { switch(p_what) { @@ -71,14 +73,14 @@ void CollisionPolygonEditor::_node_removed(Node *p_node) { Vector2 CollisionPolygonEditor::snap_point(const Vector2& p_point) const { return p_point; - /* - if (canvas_item_editor->is_snap_active()) { + + if (CanvasItemEditor::get_singleton()->is_snap_active()) { - return p_point.snapped(Vector2(1,1)*canvas_item_editor->get_snap()); + return p_point.snapped(Vector2(1,1)*CanvasItemEditor::get_singleton()->get_snap()); } else { return p_point; - } ??? */ + } } void CollisionPolygonEditor::_menu_option(int p_option) { @@ -148,7 +150,7 @@ bool CollisionPolygonEditor::forward_spatial_input_event(Camera* p_camera,const Vector2 cpoint(spoint.x,spoint.y); - //cpoint=snap_point(cpoint); snap? + cpoint=snap_point(cpoint); Vector poly = node->get_polygon(); @@ -362,7 +364,7 @@ bool CollisionPolygonEditor::forward_spatial_input_event(Camera* p_camera,const Vector2 cpoint(spoint.x,spoint.y); - //cpoint=snap_point(cpoint); + cpoint=snap_point(cpoint); edited_point_pos = cpoint; _polygon_draw(); From 8bb1e19d7355ac92ec5cfe39fbb6db73d6c0fffe Mon Sep 17 00:00:00 2001 From: Carl Olsson Date: Sat, 14 Feb 2015 06:43:50 +1000 Subject: [PATCH 2/6] Replace body_mode property with use_kinematic flag. Revert 2D Platformer demo's moving platforms to sprite plus body. --- demos/2d/platformer/moving_platform.png | Bin 0 -> 2143 bytes demos/2d/platformer/moving_platform.xml | 119 ++++++++++++------------ scene/2d/tile_map.cpp | 21 +++-- scene/2d/tile_map.h | 7 +- 4 files changed, 75 insertions(+), 72 deletions(-) create mode 100644 demos/2d/platformer/moving_platform.png diff --git a/demos/2d/platformer/moving_platform.png b/demos/2d/platformer/moving_platform.png new file mode 100644 index 0000000000000000000000000000000000000000..f01c6ea37fc5535d28d704004a6c36deb0587890 GIT binary patch literal 2143 zcmV-l2%z_gP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iye- z1PU`=_Loio00-YmL_t(|+U=dqZxvM-#-G7TDaC4AkhGQrB1jNPNlXaQbb(b96XSxI zxYCvG`~!?87&pd^J9oM;x-u~?)Sxlck2D~`4XA{m7)WUND)c7A(iVYnaqn9?Z|B@| z&diyQOP}ASxijbMJ!g8J=bX7SH$uh4aa>5b+ddzU0pRafC!(dtpZMhYM7lp;{~>6- zcW!(|+m3e)7x6_j-iYop8TLlun zQ&-&?W-pLVAga0nL+|Vc01Ry2005XdH|>=T{kzS|M%>^JP`kQ0eq}Tl-A$7v&J>00B`QSHolYyXG2NQ+rb4ej zD&x@nJb4tk#Hi=dKz4cnJigQo0{Dg9Lg)ZI*!l5u z0DwyuF2w+_acpzj8P!DSbfL-(b-b*2^Ty>{f7Sg{R=>;V%ai8-09OzE9&rzV5VEoz zz~FnkQk9>OdlBsfuD$yQ_W%eX)zDR!hWM`e3F$=TuiJG^2S5lNKz*<|fzZ41S!d?5 z^ZCYQ%NMGgQ1Mnh4rN_$b%PFo5ITVR&^X)t?t8!IjIDQ9P5I@#khLDuXKBCb`wWZi z+p-~7e1hrjiO#Rv2kGZlJFNZLO6TjSB){$Z9kz739eKye)E~Nj*Ku{NM~^!l03oC@ zYV$0Bo*@@!W>IR#q0a7T{i$=;@962|8sm6fDlp{wYdv$_f0vC z#Ed!CI{wj)DFDFu7q?qVlgvN(VRPmkL{h0lxv+RVT?wJ`NqLR^>Gd=W=@yj`(`}Ve z$6-=_jZL97ws`L<`*dnOrgHTfTE{Ca?}ubR;aK{3+WOHp4yN%kjkhV@<=0VqJ$gLf zJT(FUm~?!@6&(N}WaaGvyz$~b0Km7Sjl>>+W_E5NQ~4YFdYsZ7es&H3@bsZ%`pehn z+BymwyGN4BWm0z2`QuYFsfuKCFd7|~Yd=W*%bi90cKF6`>IWUa4LweJ{7vI*!W6%a z-k$E%4*t{ z4uB9kfa-X-Z*3{cR+R#WRwQ4g_KiREZh6&v6`kV1=l}>I+yjtZf8X8HqITg;<<@1b zxzghA)bTgn&7uP!gwO%_I)SRci5GgUTo=V-{9)s-tMbzU5JKwb0Oa|9d5&6U(5z1b z%F}3BaeW%CsI_ulrDOcn#Q*PqcT%rwIsifl9e{A<`i46R0;uF4VJOi3YyJat#<&j^^nHa+nW(u3KnSUi0~p=3zLI*iGMBxJ zP6e-)vc{hdfDl3l;ELS$FKQRnv?iD1p_IV)elr!Yoc=3o{7u(29RMMO4xlQf6HIS) z4W*1(6)Uvzx!#2^rK`#r6s`D0k3aVS2qAO;zQkz$RLbPJ>DXs4An*NlQ3U&LD66zE3CSjbGOOa$VB_5JKnxe4W6y!QMY01V?+!!& zFn#?-TV>nOw>B|jOZu#9W>;l2<;%Oa*YQX{Tvq*HN@we@yvl6rpV0AV82{AkO4nm* z=h~h%iR+pUfDl3lAe=aVHSu}-@L*!b{A+IBYi+6(-!#KJC}8T^QPOE8vE4;*br7z~ zr~AVcmrd!WJ=41?Y1TEpt)EQiUE}v1f0H9{9hVXQIxr!G4j?0s4G%^DaQecv)ETzT zTDMRI)SpFBOisn7{I=hlx9x4%+UpuuR$|o-(^}bvDP6p{cQF^cD0bFybxp4wgpOaX z+qy#sKnNW`{n5W7ENij63TDfnLrGJW$k!p5$}L*a1N4vAo`k7ieB%#2uC5NU=wG>} z10aOldk!G$%;`FVU$N}k7S%pih17_mgi`XN;?L@g9O4V=V2U39(2k1^fDlp|{{xVg V;v;u%4f_B9002ovPDHLkV1g7OG=~5H literal 0 HcmV?d00001 diff --git a/demos/2d/platformer/moving_platform.xml b/demos/2d/platformer/moving_platform.xml index f39b11782c23..4d54d6d11c8e 100644 --- a/demos/2d/platformer/moving_platform.xml +++ b/demos/2d/platformer/moving_platform.xml @@ -1,56 +1,77 @@ - - - + + + + + 0 + -88, 24, -88, -24, 88, -24, 88, 24 + + "names" - + "moving_platform" "Node2D" - "_import_path" "visibility/visible" "visibility/opacity" "visibility/self_opacity" + "visibility/on_top" "transform/pos" "transform/rot" "transform/scale" - "z/z" - "z/relative" "script/script" "__meta__" "motion" "cycle" "platform" - "TileMap" + "RigidBody2D" + "shape_count" + "shapes/0/shape" + "shapes/0/transform" + "shapes/0/trigger" "mode" - "tile_set" - "cell/size" - "cell/quadrant_size" - "cell/custom_transform" - "cell/half_offset" - "collision/body_mode" - "collision/friction" - "collision/bounce" - "collision/layers" - "tile_data" + "mass" + "friction" + "bounce" + "custom_integrator" + "continuous_cd" + "contacts_reported" + "contact_monitor" + "active" + "can_sleep" + "velocity/linear" + "velocity/angular" + "Sprite" + "texture" + "centered" + "offset" + "flip_h" + "flip_v" + "vframes" + "hframes" + "frame" + "modulate" + "region" + "region_rect" + "CollisionPolygon2D" + "build_mode" + "polygon" "version" 1 "conn_count" 0 "node_count" - 2 + 4 "variants" - "" True 1 0, 0 0 1, 1 - 0 - + "__editor_plugin_states__" @@ -71,22 +92,16 @@ "pixel_snap" False "zoom" - 1.850616 - "use_snap" - True + 1.360373 "ofs" - -406.735, -157.32 - "snap" - 32 + -210.652, -172.81 "3D" - "deflight_rot_y" - 0.628319 "zfar" 500 "fov" - 179 + 400 "viewports" @@ -96,12 +111,10 @@ 0 "y_rot" 0 - "listener" - True - "use_environment" - False "use_orthogonal" False + "use_environment" + False "pos" 0, 0, 0 @@ -112,12 +125,10 @@ 0 "y_rot" 0 - "listener" + "use_orthogonal" False "use_environment" False - "use_orthogonal" - False "pos" 0, 0, 0 @@ -128,12 +139,10 @@ 0 "y_rot" 0 - "listener" + "use_orthogonal" False "use_environment" False - "use_orthogonal" - False "pos" 0, 0, 0 @@ -144,12 +153,10 @@ 0 "y_rot" 0 - "listener" + "use_orthogonal" False "use_environment" False - "use_orthogonal" - False "pos" 0, 0, 0 @@ -158,18 +165,12 @@ 1 "default_light" True - "ambient_light_color" - 0.15, 0.15, 0.15, 1 "show_grid" True "show_origin" True "znear" 0.1 - "default_srgb" - False - "deflight_rot_x" - 0.942478 "__editor_run_settings__" @@ -182,17 +183,19 @@ "__editor_plugin_screen__" "2D" - -96, -32 - - 64, 64 - 16 - 1, 0, 0, 1, 0, 0 - 2 1 - 0, 536870927, 1, 536870926, 2, 15 + + 1, -0, 0, 1, 0, 0 + False + 3 + 0 + + 1, 1, 1, 1 + 0, 0, 0, 0 + -88, -24, 88, -24, 88, 24, -88, 24 "nodes" - -1, -1, 1, 0, -1, 13, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 1, 11, 7, 12, 8, 13, 3, 14, 2, 0, 0, 0, 16, 15, -1, 20, 2, 0, 3, 1, 4, 2, 5, 2, 6, 9, 7, 4, 8, 5, 9, 6, 10, 1, 17, 6, 18, 10, 19, 11, 20, 12, 21, 13, 22, 14, 23, 15, 24, 2, 25, 4, 26, 15, 27, 16, 0 + -1, -1, 1, 0, -1, 11, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11, 2, 12, 1, 0, 0, 0, 14, 13, -1, 23, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 15, 7, 16, 8, 17, 9, 18, 10, 19, 11, 20, 1, 21, 1, 22, 3, 23, 10, 24, 10, 25, 12, 26, 10, 27, 0, 28, 0, 29, 2, 30, 3, 0, 1, 0, 31, 31, -1, 18, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 32, 13, 33, 0, 34, 2, 35, 10, 36, 10, 37, 7, 38, 7, 39, 12, 40, 14, 41, 10, 42, 15, 0, 1, 0, 43, 43, -1, 9, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 44, 12, 45, 16, 0 "conns" diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 06c97027f09a..52f4d274972b 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -28,6 +28,7 @@ /*************************************************************************/ #include "tile_map.h" #include "io/marshalls.h" +#include "servers/physics_2d_server.h" void TileMap::_notification(int p_what) { @@ -339,7 +340,7 @@ Map::Element *TileMap::_create_quadrant(const q.canvas_item = VisualServer::get_singleton()->canvas_item_create(); VisualServer::get_singleton()->canvas_item_set_parent( q.canvas_item, get_canvas_item() ); VisualServer::get_singleton()->canvas_item_set_transform( q.canvas_item, xform ); - q.body=Physics2DServer::get_singleton()->body_create(body_mode); + q.body=Physics2DServer::get_singleton()->body_create(use_kinematic?Physics2DServer::BODY_MODE_KINEMATIC:Physics2DServer::BODY_MODE_STATIC); Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.body,get_instance_ID()); Physics2DServer::get_singleton()->body_set_layer_mask(q.body,collision_layer); Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_FRICTION,friction); @@ -590,15 +591,15 @@ void TileMap::set_collision_layer_mask(uint32_t p_layer) { } } -Physics2DServer::BodyMode TileMap::get_collision_body_mode() const{ +bool TileMap::get_collision_use_kinematic() const{ - return body_mode; + return use_kinematic; } -void TileMap::set_collision_body_mode(Physics2DServer::BodyMode p_body_mode) { +void TileMap::set_collision_use_kinematic(bool p_use_kinematic) { _clear_quadrants(); - body_mode=p_body_mode; + use_kinematic=p_use_kinematic; _recreate_quadrants(); } @@ -816,12 +817,12 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_center_y","enable"),&TileMap::set_center_y); ObjectTypeDB::bind_method(_MD("get_center_y"),&TileMap::get_center_y); + ObjectTypeDB::bind_method(_MD("set_collision_use_kinematic","use_kinematic"),&TileMap::set_collision_use_kinematic); + ObjectTypeDB::bind_method(_MD("get_collision_use_kinematic"),&TileMap::get_collision_use_kinematic); + ObjectTypeDB::bind_method(_MD("set_collision_layer_mask","mask"),&TileMap::set_collision_layer_mask); ObjectTypeDB::bind_method(_MD("get_collision_layer_mask"),&TileMap::get_collision_layer_mask); - ObjectTypeDB::bind_method(_MD("set_collision_body_mode","body_mode"),&TileMap::set_collision_body_mode); - ObjectTypeDB::bind_method(_MD("get_collision_body_mode"),&TileMap::get_collision_body_mode); - ObjectTypeDB::bind_method(_MD("set_collision_friction","value"),&TileMap::set_collision_friction); ObjectTypeDB::bind_method(_MD("get_collision_friction"),&TileMap::get_collision_friction); @@ -852,7 +853,7 @@ void TileMap::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size")); ADD_PROPERTY( PropertyInfo(Variant::MATRIX32,"cell/custom_transform"),_SCS("set_custom_transform"),_SCS("get_custom_transform")); ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/half_offset",PROPERTY_HINT_ENUM,"Offset X,Offset Y,Disabled"),_SCS("set_half_offset"),_SCS("get_half_offset")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/body_mode",PROPERTY_HINT_ENUM,"Static,Kinematic"),_SCS("set_collision_body_mode"),_SCS("get_collision_body_mode")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collision/use_kinematic",PROPERTY_HINT_NONE,""),_SCS("set_collision_use_kinematic"),_SCS("get_collision_use_kinematic")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_bounce"),_SCS("get_collision_bounce")); ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask")); @@ -886,7 +887,7 @@ TileMap::TileMap() { bounce=0; mode=MODE_SQUARE; half_offset=HALF_OFFSET_DISABLED; - body_mode=Physics2DServer::BODY_MODE_STATIC; + use_kinematic=false; fp_adjust=0.01; fp_adjust=0.01; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 52e8eae306c2..c8708e1bed0e 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -33,7 +33,6 @@ #include "scene/resources/tile_set.h" #include "self_list.h" #include "vset.h" -#include "servers/physics_2d_server.h" class TileMap : public Node2D { @@ -61,7 +60,7 @@ private: Mode mode; Matrix32 custom_transform; HalfOffset half_offset; - Physics2DServer::BodyMode body_mode; + bool use_kinematic; union PosKey { @@ -179,8 +178,8 @@ public: void set_collision_layer_mask(uint32_t p_layer); uint32_t get_collision_layer_mask() const; - void set_collision_body_mode(Physics2DServer::BodyMode p_body_mode); - Physics2DServer::BodyMode get_collision_body_mode() const; + void set_collision_use_kinematic(bool p_use_kinematic); + bool get_collision_use_kinematic() const; void set_collision_friction(float p_friction); float get_collision_friction() const; From c5f509f238576dba39ffcce74ab2066f24e67b58 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sat, 14 Feb 2015 12:09:52 -0300 Subject: [PATCH 3/6] New Navigation & Pathfinding support for 2D -Added Navigation & NavigationPolygon nodes -Added corresponding visual editor -New pathfinding algorithm is modern and fast! -Similar API to 3D Pathfinding (more coherent) --- core/bind/core_bind.cpp | 7 + core/bind/core_bind.h | 2 + core/dvector.h | 17 + core/math/geometry.h | 14 + core/math/triangulator.cpp | 1543 +++++++++++++++++ core/math/triangulator.h | 309 ++++ demos/2d/navpoly/agent.png | Bin 0 -> 2508 bytes demos/2d/navpoly/engine.cfg | 4 + demos/2d/navpoly/navigation.gd | 63 + demos/2d/navpoly/navigation.scn | Bin 0 -> 3471 bytes demos/2d/navpoly/path.png | Bin 0 -> 309506 bytes scene/2d/navigation2d.cpp | 623 +++++++ scene/2d/navigation2d.h | 137 ++ scene/2d/navigation_polygon.cpp | 450 +++++ scene/2d/navigation_polygon.h | 84 + scene/2d/node_2d.cpp | 14 + scene/2d/node_2d.h | 3 + scene/gui/dialogs.cpp | 4 +- scene/gui/popup.cpp | 4 + scene/register_scene_types.cpp | 5 + tools/editor/editor_node.cpp | 9 + tools/editor/editor_node.h | 4 + tools/editor/icons/icon_navigation_2d.png | Bin 0 -> 541 bytes .../icon_navigation_polygon_instance.png | Bin 0 -> 391 bytes .../navigation_polygon_editor_plugin.cpp | 547 ++++++ .../navigation_polygon_editor_plugin.h | 91 + 26 files changed, 3932 insertions(+), 2 deletions(-) create mode 100644 core/math/triangulator.cpp create mode 100644 core/math/triangulator.h create mode 100644 demos/2d/navpoly/agent.png create mode 100644 demos/2d/navpoly/engine.cfg create mode 100644 demos/2d/navpoly/navigation.gd create mode 100644 demos/2d/navpoly/navigation.scn create mode 100644 demos/2d/navpoly/path.png create mode 100644 scene/2d/navigation2d.cpp create mode 100644 scene/2d/navigation2d.h create mode 100644 scene/2d/navigation_polygon.cpp create mode 100644 scene/2d/navigation_polygon.h create mode 100644 tools/editor/icons/icon_navigation_2d.png create mode 100644 tools/editor/icons/icon_navigation_polygon_instance.png create mode 100644 tools/editor/plugins/navigation_polygon_editor_plugin.cpp create mode 100644 tools/editor/plugins/navigation_polygon_editor_plugin.h diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 0c5d21b4f61a..a03fd7fe4ab6 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -838,6 +838,12 @@ Variant _Geometry::segment_intersects_triangle( const Vector3& p_from, const Vec return Variant(); } + +bool _Geometry::point_is_inside_triangle(const Vector2& s, const Vector2& a, const Vector2& b, const Vector2& c) const { + + return Geometry::is_point_in_triangle(s,a,b,c); +} + DVector _Geometry::segment_intersects_sphere( const Vector3& p_from, const Vector3& p_to, const Vector3& p_sphere_pos,real_t p_sphere_radius) { DVector r; @@ -938,6 +944,7 @@ void _Geometry::_bind_methods() { ObjectTypeDB::bind_method(_MD("segment_intersects_sphere","from","to","spos","sradius"),&_Geometry::segment_intersects_sphere); ObjectTypeDB::bind_method(_MD("segment_intersects_cylinder","from","to","height","radius"),&_Geometry::segment_intersects_cylinder); ObjectTypeDB::bind_method(_MD("segment_intersects_convex","from","to","planes"),&_Geometry::segment_intersects_convex); + ObjectTypeDB::bind_method(_MD("point_is_inside_triangle","point","a","b","c"),&_Geometry::point_is_inside_triangle); ObjectTypeDB::bind_method(_MD("triangulate_polygon","polygon"),&_Geometry::triangulate_polygon); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 12a4ae86ebf7..f5043ba71fa4 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -248,6 +248,8 @@ public: Vector3 get_closest_point_to_segment(const Vector3& p_point, const Vector3& p_a,const Vector3& p_b); Variant ray_intersects_triangle( const Vector3& p_from, const Vector3& p_dir, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2); Variant segment_intersects_triangle( const Vector3& p_from, const Vector3& p_to, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2); + bool point_is_inside_triangle(const Vector2& s, const Vector2& a, const Vector2& b, const Vector2& c) const; + DVector segment_intersects_sphere( const Vector3& p_from, const Vector3& p_to, const Vector3& p_sphere_pos,real_t p_sphere_radius); DVector segment_intersects_cylinder( const Vector3& p_from, const Vector3& p_to, float p_height,float p_radius); DVector segment_intersects_convex(const Vector3& p_from, const Vector3& p_to,const Vector& p_planes); diff --git a/core/dvector.h b/core/dvector.h index 72661882cd51..29be4178443d 100644 --- a/core/dvector.h +++ b/core/dvector.h @@ -262,6 +262,23 @@ public: w[bs+i]=r[i]; } + + Error insert(int p_pos,const T& p_val) { + + int s=size(); + ERR_FAIL_INDEX_V(p_pos,s+1,ERR_INVALID_PARAMETER); + resize(s+1); + { + Write w = write(); + for (int i=s;i>p_pos;i--) + w[i]=w[i-1]; + w[p_pos]=p_val; + } + + return OK; + } + + bool is_locked() const { return mem.is_locked(); } inline const T operator[](int p_index) const; diff --git a/core/math/geometry.h b/core/math/geometry.h index 81530e30c003..7e0cc01a2284 100644 --- a/core/math/geometry.h +++ b/core/math/geometry.h @@ -511,6 +511,20 @@ public: else return p_segment[0]+n*d; // inside } + + static bool is_point_in_triangle(const Vector2& s, const Vector2& a, const Vector2& b, const Vector2& c) + { + int as_x = s.x-a.x; + int as_y = s.y-a.y; + + bool s_ab = (b.x-a.x)*as_y-(b.y-a.y)*as_x > 0; + + if((c.x-a.x)*as_y-(c.y-a.y)*as_x > 0 == s_ab) return false; + + if((c.x-b.x)*(s.y-b.y)-(c.y-b.y)*(s.x-b.x) > 0 != s_ab) return false; + + return true; + } static Vector2 get_closest_point_to_segment_uncapped_2d(const Vector2& p_point, const Vector2 *p_segment) { Vector2 p=p_point-p_segment[0]; diff --git a/core/math/triangulator.cpp b/core/math/triangulator.cpp new file mode 100644 index 000000000000..6be1cdb3304c --- /dev/null +++ b/core/math/triangulator.cpp @@ -0,0 +1,1543 @@ +//Copyright (C) 2011 by Ivan Fratric +// +//Permission is hereby granted, free of charge, to any person obtaining a copy +//of this software and associated documentation files (the "Software"), to deal +//in the Software without restriction, including without limitation the rights +//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +//copies of the Software, and to permit persons to whom the Software is +//furnished to do so, subject to the following conditions: +// +//The above copyright notice and this permission notice shall be included in +//all copies or substantial portions of the Software. +// +//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +//THE SOFTWARE. + + +#include +#include +#include +#include +#include "triangulator.h" +using namespace std; + +#define TRIANGULATOR_VERTEXTYPE_REGULAR 0 +#define TRIANGULATOR_VERTEXTYPE_START 1 +#define TRIANGULATOR_VERTEXTYPE_END 2 +#define TRIANGULATOR_VERTEXTYPE_SPLIT 3 +#define TRIANGULATOR_VERTEXTYPE_MERGE 4 + +TriangulatorPoly::TriangulatorPoly() { + hole = false; + numpoints = 0; + points = NULL; +} + +TriangulatorPoly::~TriangulatorPoly() { + if(points) delete [] points; +} + +void TriangulatorPoly::Clear() { + if(points) delete [] points; + hole = false; + numpoints = 0; + points = NULL; +} + +void TriangulatorPoly::Init(long numpoints) { + Clear(); + this->numpoints = numpoints; + points = new Vector2[numpoints]; +} + +void TriangulatorPoly::Triangle(Vector2 &p1, Vector2 &p2, Vector2 &p3) { + Init(3); + points[0] = p1; + points[1] = p2; + points[2] = p3; +} + +TriangulatorPoly::TriangulatorPoly(const TriangulatorPoly &src) { + hole = src.hole; + numpoints = src.numpoints; + points = new Vector2[numpoints]; + memcpy(points, src.points, numpoints*sizeof(Vector2)); +} + +TriangulatorPoly& TriangulatorPoly::operator=(const TriangulatorPoly &src) { + Clear(); + hole = src.hole; + numpoints = src.numpoints; + points = new Vector2[numpoints]; + memcpy(points, src.points, numpoints*sizeof(Vector2)); + return *this; +} + +int TriangulatorPoly::GetOrientation() { + long i1,i2; + real_t area = 0; + for(i1=0; i10) return TRIANGULATOR_CCW; + if(area<0) return TRIANGULATOR_CW; + return 0; +} + +void TriangulatorPoly::SetOrientation(int orientation) { + int polyorientation = GetOrientation(); + if(polyorientation&&(polyorientation!=orientation)) { + Invert(); + } +} + +void TriangulatorPoly::Invert() { + long i; + Vector2 *invpoints; + + invpoints = new Vector2[numpoints]; + for(i=0;i0) return 0; + if(dot21*dot22>0) return 0; + + return 1; +} + +//removes holes from inpolys by merging them with non-holes +int TriangulatorPartition::RemoveHoles(list *inpolys, list *outpolys) { + list polys; + list::iterator holeiter,polyiter,iter,iter2; + long i,i2,holepointindex,polypointindex; + Vector2 holepoint,polypoint,bestpolypoint; + Vector2 linep1,linep2; + Vector2 v1,v2; + TriangulatorPoly newpoly; + bool hasholes; + bool pointvisible; + bool pointfound; + + //check for trivial case (no holes) + hasholes = false; + for(iter = inpolys->begin(); iter!=inpolys->end(); iter++) { + if(iter->IsHole()) { + hasholes = true; + break; + } + } + if(!hasholes) { + for(iter = inpolys->begin(); iter!=inpolys->end(); iter++) { + outpolys->push_back(*iter); + } + return 1; + } + + polys = *inpolys; + + while(1) { + //find the hole point with the largest x + hasholes = false; + for(iter = polys.begin(); iter!=polys.end(); iter++) { + if(!iter->IsHole()) continue; + + if(!hasholes) { + hasholes = true; + holeiter = iter; + holepointindex = 0; + } + + for(i=0; i < iter->GetNumPoints(); i++) { + if(iter->GetPoint(i).x > holeiter->GetPoint(holepointindex).x) { + holeiter = iter; + holepointindex = i; + } + } + } + if(!hasholes) break; + holepoint = holeiter->GetPoint(holepointindex); + + pointfound = false; + for(iter = polys.begin(); iter!=polys.end(); iter++) { + if(iter->IsHole()) continue; + for(i=0; i < iter->GetNumPoints(); i++) { + if(iter->GetPoint(i).x <= holepoint.x) continue; + if(!InCone(iter->GetPoint((i+iter->GetNumPoints()-1)%(iter->GetNumPoints())), + iter->GetPoint(i), + iter->GetPoint((i+1)%(iter->GetNumPoints())), + holepoint)) + continue; + polypoint = iter->GetPoint(i); + if(pointfound) { + v1 = Normalize(polypoint-holepoint); + v2 = Normalize(bestpolypoint-holepoint); + if(v2.x > v1.x) continue; + } + pointvisible = true; + for(iter2 = polys.begin(); iter2!=polys.end(); iter2++) { + if(iter2->IsHole()) continue; + for(i2=0; i2 < iter2->GetNumPoints(); i2++) { + linep1 = iter2->GetPoint(i2); + linep2 = iter2->GetPoint((i2+1)%(iter2->GetNumPoints())); + if(Intersects(holepoint,polypoint,linep1,linep2)) { + pointvisible = false; + break; + } + } + if(!pointvisible) break; + } + if(pointvisible) { + pointfound = true; + bestpolypoint = polypoint; + polyiter = iter; + polypointindex = i; + } + } + } + + if(!pointfound) return 0; + + newpoly.Init(holeiter->GetNumPoints() + polyiter->GetNumPoints() + 2); + i2 = 0; + for(i=0;i<=polypointindex;i++) { + newpoly[i2] = polyiter->GetPoint(i); + i2++; + } + for(i=0;i<=holeiter->GetNumPoints();i++) { + newpoly[i2] = holeiter->GetPoint((i+holepointindex)%holeiter->GetNumPoints()); + i2++; + } + for(i=polypointindex;iGetNumPoints();i++) { + newpoly[i2] = polyiter->GetPoint(i); + i2++; + } + + polys.erase(holeiter); + polys.erase(polyiter); + polys.push_back(newpoly); + } + + for(iter = polys.begin(); iter!=polys.end(); iter++) { + outpolys->push_back(*iter); + } + + return 1; +} + +bool TriangulatorPartition::IsConvex(Vector2& p1, Vector2& p2, Vector2& p3) { + real_t tmp; + tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y); + if(tmp>0) return 1; + else return 0; +} + +bool TriangulatorPartition::IsReflex(Vector2& p1, Vector2& p2, Vector2& p3) { + real_t tmp; + tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y); + if(tmp<0) return 1; + else return 0; +} + +bool TriangulatorPartition::IsInside(Vector2& p1, Vector2& p2, Vector2& p3, Vector2 &p) { + if(IsConvex(p1,p,p2)) return false; + if(IsConvex(p2,p,p3)) return false; + if(IsConvex(p3,p,p1)) return false; + return true; +} + +bool TriangulatorPartition::InCone(Vector2 &p1, Vector2 &p2, Vector2 &p3, Vector2 &p) { + bool convex; + + convex = IsConvex(p1,p2,p3); + + if(convex) { + if(!IsConvex(p1,p2,p)) return false; + if(!IsConvex(p2,p3,p)) return false; + return true; + } else { + if(IsConvex(p1,p2,p)) return true; + if(IsConvex(p2,p3,p)) return true; + return false; + } +} + +bool TriangulatorPartition::InCone(PartitionVertex *v, Vector2 &p) { + Vector2 p1,p2,p3; + + p1 = v->previous->p; + p2 = v->p; + p3 = v->next->p; + + return InCone(p1,p2,p3,p); +} + +void TriangulatorPartition::UpdateVertexReflexity(PartitionVertex *v) { + PartitionVertex *v1,*v3; + v1 = v->previous; + v3 = v->next; + v->isConvex = !IsReflex(v1->p,v->p,v3->p); +} + +void TriangulatorPartition::UpdateVertex(PartitionVertex *v, PartitionVertex *vertices, long numvertices) { + long i; + PartitionVertex *v1,*v3; + Vector2 vec1,vec3; + + v1 = v->previous; + v3 = v->next; + + v->isConvex = IsConvex(v1->p,v->p,v3->p); + + vec1 = Normalize(v1->p - v->p); + vec3 = Normalize(v3->p - v->p); + v->angle = vec1.x*vec3.x + vec1.y*vec3.y; + + if(v->isConvex) { + v->isEar = true; + for(i=0;ip.x)&&(vertices[i].p.y==v->p.y)) continue; + if((vertices[i].p.x==v1->p.x)&&(vertices[i].p.y==v1->p.y)) continue; + if((vertices[i].p.x==v3->p.x)&&(vertices[i].p.y==v3->p.y)) continue; + if(IsInside(v1->p,v->p,v3->p,vertices[i].p)) { + v->isEar = false; + break; + } + } + } else { + v->isEar = false; + } +} + +//triangulation by ear removal +int TriangulatorPartition::Triangulate_EC(TriangulatorPoly *poly, list *triangles) { + long numvertices; + PartitionVertex *vertices; + PartitionVertex *ear; + TriangulatorPoly triangle; + long i,j; + bool earfound; + + if(poly->GetNumPoints() < 3) return 0; + if(poly->GetNumPoints() == 3) { + triangles->push_back(*poly); + return 1; + } + + numvertices = poly->GetNumPoints(); + + vertices = new PartitionVertex[numvertices]; + for(i=0;iGetPoint(i); + if(i==(numvertices-1)) vertices[i].next=&(vertices[0]); + else vertices[i].next=&(vertices[i+1]); + if(i==0) vertices[i].previous = &(vertices[numvertices-1]); + else vertices[i].previous = &(vertices[i-1]); + } + for(i=0;i ear->angle) { + ear = &(vertices[j]); + } + } + } + if(!earfound) { + delete [] vertices; + return 0; + } + + triangle.Triangle(ear->previous->p,ear->p,ear->next->p); + triangles->push_back(triangle); + + ear->isActive = false; + ear->previous->next = ear->next; + ear->next->previous = ear->previous; + + if(i==numvertices-4) break; + + UpdateVertex(ear->previous,vertices,numvertices); + UpdateVertex(ear->next,vertices,numvertices); + } + for(i=0;ip,vertices[i].p,vertices[i].next->p); + triangles->push_back(triangle); + break; + } + } + + delete [] vertices; + + return 1; +} + +int TriangulatorPartition::Triangulate_EC(list *inpolys, list *triangles) { + list outpolys; + list::iterator iter; + + if(!RemoveHoles(inpolys,&outpolys)) return 0; + for(iter=outpolys.begin();iter!=outpolys.end();iter++) { + if(!Triangulate_EC(&(*iter),triangles)) return 0; + } + return 1; +} + +int TriangulatorPartition::ConvexPartition_HM(TriangulatorPoly *poly, list *parts) { + list triangles; + list::iterator iter1,iter2; + TriangulatorPoly *poly1,*poly2; + TriangulatorPoly newpoly; + Vector2 d1,d2,p1,p2,p3; + long i11,i12,i21,i22,i13,i23,j,k; + bool isdiagonal; + long numreflex; + + //check if the poly is already convex + numreflex = 0; + for(i11=0;i11GetNumPoints();i11++) { + if(i11==0) i12 = poly->GetNumPoints()-1; + else i12=i11-1; + if(i11==(poly->GetNumPoints()-1)) i13=0; + else i13=i11+1; + if(IsReflex(poly->GetPoint(i12),poly->GetPoint(i11),poly->GetPoint(i13))) { + numreflex = 1; + break; + } + } + if(numreflex == 0) { + parts->push_back(*poly); + return 1; + } + + if(!Triangulate_EC(poly,&triangles)) return 0; + + for(iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) { + poly1 = &(*iter1); + for(i11=0;i11GetNumPoints();i11++) { + d1 = poly1->GetPoint(i11); + i12 = (i11+1)%(poly1->GetNumPoints()); + d2 = poly1->GetPoint(i12); + + isdiagonal = false; + for(iter2 = iter1; iter2 != triangles.end(); iter2++) { + if(iter1 == iter2) continue; + poly2 = &(*iter2); + + for(i21=0;i21GetNumPoints();i21++) { + if((d2.x != poly2->GetPoint(i21).x)||(d2.y != poly2->GetPoint(i21).y)) continue; + i22 = (i21+1)%(poly2->GetNumPoints()); + if((d1.x != poly2->GetPoint(i22).x)||(d1.y != poly2->GetPoint(i22).y)) continue; + isdiagonal = true; + break; + } + if(isdiagonal) break; + } + + if(!isdiagonal) continue; + + p2 = poly1->GetPoint(i11); + if(i11 == 0) i13 = poly1->GetNumPoints()-1; + else i13 = i11-1; + p1 = poly1->GetPoint(i13); + if(i22 == (poly2->GetNumPoints()-1)) i23 = 0; + else i23 = i22+1; + p3 = poly2->GetPoint(i23); + + if(!IsConvex(p1,p2,p3)) continue; + + p2 = poly1->GetPoint(i12); + if(i12 == (poly1->GetNumPoints()-1)) i13 = 0; + else i13 = i12+1; + p3 = poly1->GetPoint(i13); + if(i21 == 0) i23 = poly2->GetNumPoints()-1; + else i23 = i21-1; + p1 = poly2->GetPoint(i23); + + if(!IsConvex(p1,p2,p3)) continue; + + newpoly.Init(poly1->GetNumPoints()+poly2->GetNumPoints()-2); + k = 0; + for(j=i12;j!=i11;j=(j+1)%(poly1->GetNumPoints())) { + newpoly[k] = poly1->GetPoint(j); + k++; + } + for(j=i22;j!=i21;j=(j+1)%(poly2->GetNumPoints())) { + newpoly[k] = poly2->GetPoint(j); + k++; + } + + triangles.erase(iter2); + *iter1 = newpoly; + poly1 = &(*iter1); + i11 = -1; + + continue; + } + } + + for(iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) { + parts->push_back(*iter1); + } + + return 1; +} + +int TriangulatorPartition::ConvexPartition_HM(list *inpolys, list *parts) { + list outpolys; + list::iterator iter; + + if(!RemoveHoles(inpolys,&outpolys)) return 0; + for(iter=outpolys.begin();iter!=outpolys.end();iter++) { + if(!ConvexPartition_HM(&(*iter),parts)) return 0; + } + return 1; +} + +//minimum-weight polygon triangulation by dynamic programming +//O(n^3) time complexity +//O(n^2) space complexity +int TriangulatorPartition::Triangulate_OPT(TriangulatorPoly *poly, list *triangles) { + long i,j,k,gap,n; + DPState **dpstates; + Vector2 p1,p2,p3,p4; + long bestvertex; + real_t weight,minweight,d1,d2; + Diagonal diagonal,newdiagonal; + list diagonals; + TriangulatorPoly triangle; + int ret = 1; + + n = poly->GetNumPoints(); + dpstates = new DPState *[n]; + for(i=1;iGetPoint(i); + for(j=i+1;jGetPoint(j); + + //visibility check + if(i==0) p3 = poly->GetPoint(n-1); + else p3 = poly->GetPoint(i-1); + if(i==(n-1)) p4 = poly->GetPoint(0); + else p4 = poly->GetPoint(i+1); + if(!InCone(p3,p1,p4,p2)) { + dpstates[j][i].visible = false; + continue; + } + + if(j==0) p3 = poly->GetPoint(n-1); + else p3 = poly->GetPoint(j-1); + if(j==(n-1)) p4 = poly->GetPoint(0); + else p4 = poly->GetPoint(j+1); + if(!InCone(p3,p2,p4,p1)) { + dpstates[j][i].visible = false; + continue; + } + + for(k=0;kGetPoint(k); + if(k==(n-1)) p4 = poly->GetPoint(0); + else p4 = poly->GetPoint(k+1); + if(Intersects(p1,p2,p3,p4)) { + dpstates[j][i].visible = false; + break; + } + } + } + } + } + dpstates[n-1][0].visible = true; + dpstates[n-1][0].weight = 0; + dpstates[n-1][0].bestvertex = -1; + + for(gap = 2; gapGetPoint(i),poly->GetPoint(k)); + if(j<=(k+1)) d2=0; + else d2 = Distance(poly->GetPoint(k),poly->GetPoint(j)); + + weight = dpstates[k][i].weight + dpstates[j][k].weight + d1 + d2; + + if((bestvertex == -1)||(weightGetPoint(diagonal.index1),poly->GetPoint(bestvertex),poly->GetPoint(diagonal.index2)); + triangles->push_back(triangle); + if(bestvertex > (diagonal.index1+1)) { + newdiagonal.index1 = diagonal.index1; + newdiagonal.index2 = bestvertex; + diagonals.push_back(newdiagonal); + } + if(diagonal.index2 > (bestvertex+1)) { + newdiagonal.index1 = bestvertex; + newdiagonal.index2 = diagonal.index2; + diagonals.push_back(newdiagonal); + } + } + + for(i=1;i *pairs; + long w2; + + w2 = dpstates[a][b].weight; + if(w>w2) return; + + pairs = &(dpstates[a][b].pairs); + newdiagonal.index1 = i; + newdiagonal.index2 = j; + + if(wclear(); + pairs->push_front(newdiagonal); + dpstates[a][b].weight = w; + } else { + if((!pairs->empty())&&(i <= pairs->begin()->index1)) return; + while((!pairs->empty())&&(pairs->begin()->index2 >= j)) pairs->pop_front(); + pairs->push_front(newdiagonal); + } +} + +void TriangulatorPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) { + list *pairs; + list::iterator iter,lastiter; + long top; + long w; + + if(!dpstates[i][j].visible) return; + top = j; + w = dpstates[i][j].weight; + if(k-j > 1) { + if (!dpstates[j][k].visible) return; + w += dpstates[j][k].weight + 1; + } + if(j-i > 1) { + pairs = &(dpstates[i][j].pairs); + iter = pairs->end(); + lastiter = pairs->end(); + while(iter!=pairs->begin()) { + iter--; + if(!IsReflex(vertices[iter->index2].p,vertices[j].p,vertices[k].p)) lastiter = iter; + else break; + } + if(lastiter == pairs->end()) w++; + else { + if(IsReflex(vertices[k].p,vertices[i].p,vertices[lastiter->index1].p)) w++; + else top = lastiter->index1; + } + } + UpdateState(i,k,w,top,j,dpstates); +} + +void TriangulatorPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) { + list *pairs; + list::iterator iter,lastiter; + long top; + long w; + + if(!dpstates[j][k].visible) return; + top = j; + w = dpstates[j][k].weight; + + if (j-i > 1) { + if (!dpstates[i][j].visible) return; + w += dpstates[i][j].weight + 1; + } + if (k-j > 1) { + pairs = &(dpstates[j][k].pairs); + + iter = pairs->begin(); + if((!pairs->empty())&&(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->index1].p))) { + lastiter = iter; + while(iter!=pairs->end()) { + if(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->index1].p)) { + lastiter = iter; + iter++; + } + else break; + } + if(IsReflex(vertices[lastiter->index2].p,vertices[k].p,vertices[i].p)) w++; + else top = lastiter->index2; + } else w++; + } + UpdateState(i,k,w,j,top,dpstates); +} + +int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, list *parts) { + Vector2 p1,p2,p3,p4; + PartitionVertex *vertices; + DPState2 **dpstates; + long i,j,k,n,gap; + list diagonals,diagonals2; + Diagonal diagonal,newdiagonal; + list *pairs,*pairs2; + list::iterator iter,iter2; + int ret; + TriangulatorPoly newpoly; + list indices; + list::iterator iiter; + bool ijreal,jkreal; + + n = poly->GetNumPoints(); + vertices = new PartitionVertex[n]; + + dpstates = new DPState2 *[n]; + for(i=0;iGetPoint(i); + vertices[i].isActive = true; + if(i==0) vertices[i].previous = &(vertices[n-1]); + else vertices[i].previous = &(vertices[i-1]); + if(i==(poly->GetNumPoints()-1)) vertices[i].next = &(vertices[0]); + else vertices[i].next = &(vertices[i+1]); + } + for(i=1;iGetPoint(i); + for(j=i+1;jGetPoint(j); + + //visibility check + if(!InCone(&vertices[i],p2)) { + dpstates[i][j].visible = false; + continue; + } + if(!InCone(&vertices[j],p1)) { + dpstates[i][j].visible = false; + continue; + } + + for(k=0;kGetPoint(k); + if(k==(n-1)) p4 = poly->GetPoint(0); + else p4 = poly->GetPoint(k+1); + if(Intersects(p1,p2,p3,p4)) { + dpstates[i][j].visible = false; + break; + } + } + } + } + } + for(i=0;i<(n-2);i++) { + j = i+2; + if(dpstates[i][j].visible) { + dpstates[i][j].weight = 0; + newdiagonal.index1 = i+1; + newdiagonal.index2 = i+1; + dpstates[i][j].pairs.push_back(newdiagonal); + } + } + + dpstates[0][n-1].visible = true; + vertices[0].isConvex = false; //by convention + + for(gap=3; gapempty()) { + ret = 0; + break; + } + if(!vertices[diagonal.index1].isConvex) { + iter = pairs->end(); + iter--; + j = iter->index2; + newdiagonal.index1 = j; + newdiagonal.index2 = diagonal.index2; + diagonals.push_front(newdiagonal); + if((j - diagonal.index1)>1) { + if(iter->index1 != iter->index2) { + pairs2 = &(dpstates[diagonal.index1][j].pairs); + while(1) { + if(pairs2->empty()) { + ret = 0; + break; + } + iter2 = pairs2->end(); + iter2--; + if(iter->index1 != iter2->index1) pairs2->pop_back(); + else break; + } + if(ret == 0) break; + } + newdiagonal.index1 = diagonal.index1; + newdiagonal.index2 = j; + diagonals.push_front(newdiagonal); + } + } else { + iter = pairs->begin(); + j = iter->index1; + newdiagonal.index1 = diagonal.index1; + newdiagonal.index2 = j; + diagonals.push_front(newdiagonal); + if((diagonal.index2 - j) > 1) { + if(iter->index1 != iter->index2) { + pairs2 = &(dpstates[j][diagonal.index2].pairs); + while(1) { + if(pairs2->empty()) { + ret = 0; + break; + } + iter2 = pairs2->begin(); + if(iter->index2 != iter2->index2) pairs2->pop_front(); + else break; + } + if(ret == 0) break; + } + newdiagonal.index1 = j; + newdiagonal.index2 = diagonal.index2; + diagonals.push_front(newdiagonal); + } + } + } + + if(ret == 0) { + for(i=0;iend(); + iter--; + j = iter->index2; + if(iter->index1 != iter->index2) ijreal = false; + } else { + iter = pairs->begin(); + j = iter->index1; + if(iter->index1 != iter->index2) jkreal = false; + } + + newdiagonal.index1 = diagonal.index1; + newdiagonal.index2 = j; + if(ijreal) { + diagonals.push_back(newdiagonal); + } else { + diagonals2.push_back(newdiagonal); + } + + newdiagonal.index1 = j; + newdiagonal.index2 = diagonal.index2; + if(jkreal) { + diagonals.push_back(newdiagonal); + } else { + diagonals2.push_back(newdiagonal); + } + + indices.push_back(j); + } + + indices.sort(); + newpoly.Init((long)indices.size()); + k=0; + for(iiter = indices.begin();iiter!=indices.end();iiter++) { + newpoly[k] = vertices[*iiter].p; + k++; + } + parts->push_back(newpoly); + } + + for(i=0;i *inpolys, list *monotonePolys) { + list::iterator iter; + MonotoneVertex *vertices; + long i,numvertices,vindex,vindex2,newnumvertices,maxnumvertices; + long polystartindex, polyendindex; + TriangulatorPoly *poly; + MonotoneVertex *v,*v2,*vprev,*vnext; + ScanLineEdge newedge; + bool error = false; + + numvertices = 0; + for(iter = inpolys->begin(); iter != inpolys->end(); iter++) { + numvertices += iter->GetNumPoints(); + } + + maxnumvertices = numvertices*3; + vertices = new MonotoneVertex[maxnumvertices]; + newnumvertices = numvertices; + + polystartindex = 0; + for(iter = inpolys->begin(); iter != inpolys->end(); iter++) { + poly = &(*iter); + polyendindex = polystartindex + poly->GetNumPoints()-1; + for(i=0;iGetNumPoints();i++) { + vertices[i+polystartindex].p = poly->GetPoint(i); + if(i==0) vertices[i+polystartindex].previous = polyendindex; + else vertices[i+polystartindex].previous = i+polystartindex-1; + if(i==(poly->GetNumPoints()-1)) vertices[i+polystartindex].next = polystartindex; + else vertices[i+polystartindex].next = i+polystartindex+1; + } + polystartindex = polyendindex+1; + } + + //construct the priority queue + long *priority = new long [numvertices]; + for(i=0;iprevious]); + vnext = &(vertices[v->next]); + + if(Below(vprev->p,v->p)&&Below(vnext->p,v->p)) { + if(IsConvex(vnext->p,vprev->p,v->p)) { + vertextypes[i] = TRIANGULATOR_VERTEXTYPE_START; + } else { + vertextypes[i] = TRIANGULATOR_VERTEXTYPE_SPLIT; + } + } else if(Below(v->p,vprev->p)&&Below(v->p,vnext->p)) { + if(IsConvex(vnext->p,vprev->p,v->p)) + { + vertextypes[i] = TRIANGULATOR_VERTEXTYPE_END; + } else { + vertextypes[i] = TRIANGULATOR_VERTEXTYPE_MERGE; + } + } else { + vertextypes[i] = TRIANGULATOR_VERTEXTYPE_REGULAR; + } + } + + //helpers + long *helpers = new long[maxnumvertices]; + + //binary search tree that holds edges intersecting the scanline + //note that while set doesn't actually have to be implemented as a tree + //complexity requirements for operations are the same as for the balanced binary search tree + set edgeTree; + //store iterators to the edge tree elements + //this makes deleting existing edges much faster + set::iterator *edgeTreeIterators,edgeIter; + edgeTreeIterators = new set::iterator[maxnumvertices]; + pair::iterator,bool> edgeTreeRet; + for(i = 0; ip; + newedge.p2 = vertices[v->next].p; + newedge.index = vindex; + edgeTreeRet = edgeTree.insert(newedge); + edgeTreeIterators[vindex] = edgeTreeRet.first; + helpers[vindex] = vindex; + break; + + case TRIANGULATOR_VERTEXTYPE_END: + //if helper(ei-1) is a merge vertex + if(vertextypes[helpers[v->previous]]==TRIANGULATOR_VERTEXTYPE_MERGE) { + //Insert the diagonal connecting vi to helper(ei-1) in D. + AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + } + //Delete ei-1 from T + edgeTree.erase(edgeTreeIterators[v->previous]); + break; + + case TRIANGULATOR_VERTEXTYPE_SPLIT: + //Search in T to find the edge e j directly left of vi. + newedge.p1 = v->p; + newedge.p2 = v->p; + edgeIter = edgeTree.lower_bound(newedge); + if(edgeIter == edgeTree.begin()) { + error = true; + break; + } + edgeIter--; + //Insert the diagonal connecting vi to helper(ej) in D. + AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->index], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + vindex2 = newnumvertices-2; + v2 = &(vertices[vindex2]); + //helper(e j)�vi + helpers[edgeIter->index] = vindex; + //Insert ei in T and set helper(ei) to vi. + newedge.p1 = v2->p; + newedge.p2 = vertices[v2->next].p; + newedge.index = vindex2; + edgeTreeRet = edgeTree.insert(newedge); + edgeTreeIterators[vindex2] = edgeTreeRet.first; + helpers[vindex2] = vindex2; + break; + + case TRIANGULATOR_VERTEXTYPE_MERGE: + //if helper(ei-1) is a merge vertex + if(vertextypes[helpers[v->previous]]==TRIANGULATOR_VERTEXTYPE_MERGE) { + //Insert the diagonal connecting vi to helper(ei-1) in D. + AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + vindex2 = newnumvertices-2; + v2 = &(vertices[vindex2]); + } + //Delete ei-1 from T. + edgeTree.erase(edgeTreeIterators[v->previous]); + //Search in T to find the edge e j directly left of vi. + newedge.p1 = v->p; + newedge.p2 = v->p; + edgeIter = edgeTree.lower_bound(newedge); + if(edgeIter == edgeTree.begin()) { + error = true; + break; + } + edgeIter--; + //if helper(ej) is a merge vertex + if(vertextypes[helpers[edgeIter->index]]==TRIANGULATOR_VERTEXTYPE_MERGE) { + //Insert the diagonal connecting vi to helper(e j) in D. + AddDiagonal(vertices,&newnumvertices,vindex2,helpers[edgeIter->index], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + } + //helper(e j)�vi + helpers[edgeIter->index] = vindex2; + break; + + case TRIANGULATOR_VERTEXTYPE_REGULAR: + //if the interior of P lies to the right of vi + if(Below(v->p,vertices[v->previous].p)) { + //if helper(ei-1) is a merge vertex + if(vertextypes[helpers[v->previous]]==TRIANGULATOR_VERTEXTYPE_MERGE) { + //Insert the diagonal connecting vi to helper(ei-1) in D. + AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + vindex2 = newnumvertices-2; + v2 = &(vertices[vindex2]); + } + //Delete ei-1 from T. + edgeTree.erase(edgeTreeIterators[v->previous]); + //Insert ei in T and set helper(ei) to vi. + newedge.p1 = v2->p; + newedge.p2 = vertices[v2->next].p; + newedge.index = vindex2; + edgeTreeRet = edgeTree.insert(newedge); + edgeTreeIterators[vindex2] = edgeTreeRet.first; + helpers[vindex2] = vindex; + } else { + //Search in T to find the edge ej directly left of vi. + newedge.p1 = v->p; + newedge.p2 = v->p; + edgeIter = edgeTree.lower_bound(newedge); + if(edgeIter == edgeTree.begin()) { + error = true; + break; + } + edgeIter--; + //if helper(ej) is a merge vertex + if(vertextypes[helpers[edgeIter->index]]==TRIANGULATOR_VERTEXTYPE_MERGE) { + //Insert the diagonal connecting vi to helper(e j) in D. + AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->index], + vertextypes, edgeTreeIterators, &edgeTree, helpers); + } + //helper(e j)�vi + helpers[edgeIter->index] = vindex; + } + break; + } + + if(error) break; + } + + char *used = new char[newnumvertices]; + memset(used,0,newnumvertices*sizeof(char)); + + if(!error) { + //return result + long size; + TriangulatorPoly mpoly; + for(i=0;inext]); + size = 1; + while(vnext!=v) { + vnext = &(vertices[vnext->next]); + size++; + } + mpoly.Init(size); + v = &(vertices[i]); + mpoly[0] = v->p; + vnext = &(vertices[v->next]); + size = 1; + used[i] = 1; + used[v->next] = 1; + while(vnext!=v) { + mpoly[size] = vnext->p; + used[vnext->next] = 1; + vnext = &(vertices[vnext->next]); + size++; + } + monotonePolys->push_back(mpoly); + } + } + + //cleanup + delete [] vertices; + delete [] priority; + delete [] vertextypes; + delete [] edgeTreeIterators; + delete [] helpers; + delete [] used; + + if(error) { + return 0; + } else { + return 1; + } +} + +//adds a diagonal to the doubly-connected list of vertices +void TriangulatorPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2, + char *vertextypes, set::iterator *edgeTreeIterators, + set *edgeTree, long *helpers) +{ + long newindex1,newindex2; + + newindex1 = *numvertices; + (*numvertices)++; + newindex2 = *numvertices; + (*numvertices)++; + + vertices[newindex1].p = vertices[index1].p; + vertices[newindex2].p = vertices[index2].p; + + vertices[newindex2].next = vertices[index2].next; + vertices[newindex1].next = vertices[index1].next; + + vertices[vertices[index2].next].previous = newindex2; + vertices[vertices[index1].next].previous = newindex1; + + vertices[index1].next = newindex2; + vertices[newindex2].previous = index1; + + vertices[index2].next = newindex1; + vertices[newindex1].previous = index2; + + //update all relevant structures + vertextypes[newindex1] = vertextypes[index1]; + edgeTreeIterators[newindex1] = edgeTreeIterators[index1]; + helpers[newindex1] = helpers[index1]; + if(edgeTreeIterators[newindex1] != edgeTree->end()) + edgeTreeIterators[newindex1]->index = newindex1; + vertextypes[newindex2] = vertextypes[index2]; + edgeTreeIterators[newindex2] = edgeTreeIterators[index2]; + helpers[newindex2] = helpers[index2]; + if(edgeTreeIterators[newindex2] != edgeTree->end()) + edgeTreeIterators[newindex2]->index = newindex2; +} + +bool TriangulatorPartition::Below(Vector2 &p1, Vector2 &p2) { + if(p1.y < p2.y) return true; + else if(p1.y == p2.y) { + if(p1.x < p2.x) return true; + } + return false; +} + +//sorts in the falling order of y values, if y is equal, x is used instead +bool TriangulatorPartition::VertexSorter::operator() (long index1, long index2) { + if(vertices[index1].p.y > vertices[index2].p.y) return true; + else if(vertices[index1].p.y == vertices[index2].p.y) { + if(vertices[index1].p.x > vertices[index2].p.x) return true; + } + return false; +} + +bool TriangulatorPartition::ScanLineEdge::IsConvex(const Vector2& p1, const Vector2& p2, const Vector2& p3) const { + real_t tmp; + tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y); + if(tmp>0) return 1; + else return 0; +} + +bool TriangulatorPartition::ScanLineEdge::operator < (const ScanLineEdge & other) const { + if(other.p1.y == other.p2.y) { + if(p1.y == p2.y) { + if(p1.y < other.p1.y) return true; + else return false; + } + if(IsConvex(p1,p2,other.p1)) return true; + else return false; + } else if(p1.y == p2.y) { + if(IsConvex(other.p1,other.p2,p1)) return false; + else return true; + } else if(p1.y < other.p1.y) { + if(IsConvex(other.p1,other.p2,p1)) return false; + else return true; + } else { + if(IsConvex(p1,p2,other.p1)) return true; + else return false; + } +} + +//triangulates monotone polygon +//O(n) time, O(n) space complexity +int TriangulatorPartition::TriangulateMonotone(TriangulatorPoly *inPoly, list *triangles) { + long i,i2,j,topindex,bottomindex,leftindex,rightindex,vindex; + Vector2 *points; + long numpoints; + TriangulatorPoly triangle; + + numpoints = inPoly->GetNumPoints(); + points = inPoly->GetPoints(); + + //trivial calses + if(numpoints < 3) return 0; + if(numpoints == 3) { + triangles->push_back(*inPoly); + } + + topindex = 0; bottomindex=0; + for(i=1;i=numpoints) i2 = 0; + if(!Below(points[i2],points[i])) return 0; + i = i2; + } + i = bottomindex; + while(i!=topindex) { + i2 = i+1; if(i2>=numpoints) i2 = 0; + if(!Below(points[i],points[i2])) return 0; + i = i2; + } + + char *vertextypes = new char[numpoints]; + long *priority = new long[numpoints]; + + //merge left and right vertex chains + priority[0] = topindex; + vertextypes[topindex] = 0; + leftindex = topindex+1; if(leftindex>=numpoints) leftindex = 0; + rightindex = topindex-1; if(rightindex<0) rightindex = numpoints-1; + for(i=1;i<(numpoints-1);i++) { + if(leftindex==bottomindex) { + priority[i] = rightindex; + rightindex--; if(rightindex<0) rightindex = numpoints-1; + vertextypes[priority[i]] = -1; + } else if(rightindex==bottomindex) { + priority[i] = leftindex; + leftindex++; if(leftindex>=numpoints) leftindex = 0; + vertextypes[priority[i]] = 1; + } else { + if(Below(points[leftindex],points[rightindex])) { + priority[i] = rightindex; + rightindex--; if(rightindex<0) rightindex = numpoints-1; + vertextypes[priority[i]] = -1; + } else { + priority[i] = leftindex; + leftindex++; if(leftindex>=numpoints) leftindex = 0; + vertextypes[priority[i]] = 1; + } + } + } + priority[i] = bottomindex; + vertextypes[bottomindex] = 0; + + long *stack = new long[numpoints]; + long stackptr = 0; + + stack[0] = priority[0]; + stack[1] = priority[1]; + stackptr = 2; + + //for each vertex from top to bottom trim as many triangles as possible + for(i=2;i<(numpoints-1);i++) { + vindex = priority[i]; + if(vertextypes[vindex]!=vertextypes[stack[stackptr-1]]) { + for(j=0;j<(stackptr-1);j++) { + if(vertextypes[vindex]==1) { + triangle.Triangle(points[stack[j+1]],points[stack[j]],points[vindex]); + } else { + triangle.Triangle(points[stack[j]],points[stack[j+1]],points[vindex]); + } + triangles->push_back(triangle); + } + stack[0] = priority[i-1]; + stack[1] = priority[i]; + stackptr = 2; + } else { + stackptr--; + while(stackptr>0) { + if(vertextypes[vindex]==1) { + if(IsConvex(points[vindex],points[stack[stackptr-1]],points[stack[stackptr]])) { + triangle.Triangle(points[vindex],points[stack[stackptr-1]],points[stack[stackptr]]); + triangles->push_back(triangle); + stackptr--; + } else { + break; + } + } else { + if(IsConvex(points[vindex],points[stack[stackptr]],points[stack[stackptr-1]])) { + triangle.Triangle(points[vindex],points[stack[stackptr]],points[stack[stackptr-1]]); + triangles->push_back(triangle); + stackptr--; + } else { + break; + } + } + } + stackptr++; + stack[stackptr] = vindex; + stackptr++; + } + } + vindex = priority[i]; + for(j=0;j<(stackptr-1);j++) { + if(vertextypes[stack[j+1]]==1) { + triangle.Triangle(points[stack[j]],points[stack[j+1]],points[vindex]); + } else { + triangle.Triangle(points[stack[j+1]],points[stack[j]],points[vindex]); + } + triangles->push_back(triangle); + } + + delete [] priority; + delete [] vertextypes; + delete [] stack; + + return 1; +} + +int TriangulatorPartition::Triangulate_MONO(list *inpolys, list *triangles) { + list monotone; + list::iterator iter; + + if(!MonotonePartition(inpolys,&monotone)) return 0; + for(iter = monotone.begin(); iter!=monotone.end();iter++) { + if(!TriangulateMonotone(&(*iter),triangles)) return 0; + } + return 1; +} + +int TriangulatorPartition::Triangulate_MONO(TriangulatorPoly *poly, list *triangles) { + list polys; + polys.push_back(*poly); + + return Triangulate_MONO(&polys, triangles); +} diff --git a/core/math/triangulator.h b/core/math/triangulator.h new file mode 100644 index 000000000000..c34c445892f2 --- /dev/null +++ b/core/math/triangulator.h @@ -0,0 +1,309 @@ +//Copyright (C) 2011 by Ivan Fratric +// +//Permission is hereby granted, free of charge, to any person obtaining a copy +//of this software and associated documentation files (the "Software"), to deal +//in the Software without restriction, including without limitation the rights +//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +//copies of the Software, and to permit persons to whom the Software is +//furnished to do so, subject to the following conditions: +// +//The above copyright notice and this permission notice shall be included in +//all copies or substantial portions of the Software. +// +//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +//THE SOFTWARE. + +#ifndef TRIANGULATOR_H +#define TRIANGULATOR_H + +#include "math_2d.h" +#include +#include + +//2D point structure + + +#define TRIANGULATOR_CCW 1 +#define TRIANGULATOR_CW -1 +//Polygon implemented as an array of points with a 'hole' flag +class TriangulatorPoly { +protected: + + + + Vector2 *points; + long numpoints; + bool hole; + +public: + + //constructors/destructors + TriangulatorPoly(); + ~TriangulatorPoly(); + + TriangulatorPoly(const TriangulatorPoly &src); + TriangulatorPoly& operator=(const TriangulatorPoly &src); + + //getters and setters + long GetNumPoints() { + return numpoints; + } + + bool IsHole() { + return hole; + } + + void SetHole(bool hole) { + this->hole = hole; + } + + Vector2 &GetPoint(long i) { + return points[i]; + } + + Vector2 *GetPoints() { + return points; + } + + Vector2& operator[] (int i) { + return points[i]; + } + + //clears the polygon points + void Clear(); + + //inits the polygon with numpoints vertices + void Init(long numpoints); + + //creates a triangle with points p1,p2,p3 + void Triangle(Vector2 &p1, Vector2 &p2, Vector2 &p3); + + //inverts the orfer of vertices + void Invert(); + + //returns the orientation of the polygon + //possible values: + // Triangulator_CCW : polygon vertices are in counter-clockwise order + // Triangulator_CW : polygon vertices are in clockwise order + // 0 : the polygon has no (measurable) area + int GetOrientation(); + + //sets the polygon orientation + //orientation can be + // Triangulator_CCW : sets vertices in counter-clockwise order + // Triangulator_CW : sets vertices in clockwise order + void SetOrientation(int orientation); +}; + +class TriangulatorPartition { +protected: + struct PartitionVertex { + bool isActive; + bool isConvex; + bool isEar; + + Vector2 p; + real_t angle; + PartitionVertex *previous; + PartitionVertex *next; + }; + + struct MonotoneVertex { + Vector2 p; + long previous; + long next; + }; + + class VertexSorter{ + MonotoneVertex *vertices; + public: + VertexSorter(MonotoneVertex *v) : vertices(v) {} + bool operator() (long index1, long index2); + }; + + struct Diagonal { + long index1; + long index2; + }; + + //dynamic programming state for minimum-weight triangulation + struct DPState { + bool visible; + real_t weight; + long bestvertex; + }; + + //dynamic programming state for convex partitioning + struct DPState2 { + bool visible; + long weight; + std::list pairs; + }; + + //edge that intersects the scanline + struct ScanLineEdge { + mutable long index; + Vector2 p1; + Vector2 p2; + + //determines if the edge is to the left of another edge + bool operator< (const ScanLineEdge & other) const; + + bool IsConvex(const Vector2& p1, const Vector2& p2, const Vector2& p3) const; + }; + + //standard helper functions + bool IsConvex(Vector2& p1, Vector2& p2, Vector2& p3); + bool IsReflex(Vector2& p1, Vector2& p2, Vector2& p3); + bool IsInside(Vector2& p1, Vector2& p2, Vector2& p3, Vector2 &p); + + bool InCone(Vector2 &p1, Vector2 &p2, Vector2 &p3, Vector2 &p); + bool InCone(PartitionVertex *v, Vector2 &p); + + int Intersects(Vector2 &p11, Vector2 &p12, Vector2 &p21, Vector2 &p22); + + Vector2 Normalize(const Vector2 &p); + real_t Distance(const Vector2 &p1, const Vector2 &p2); + + //helper functions for Triangulate_EC + void UpdateVertexReflexity(PartitionVertex *v); + void UpdateVertex(PartitionVertex *v,PartitionVertex *vertices, long numvertices); + + //helper functions for ConvexPartition_OPT + void UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates); + void TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates); + void TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates); + + //helper functions for MonotonePartition + bool Below(Vector2 &p1, Vector2 &p2); + void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2, + char *vertextypes, std::set::iterator *edgeTreeIterators, + std::set *edgeTree, long *helpers); + + //triangulates a monotone polygon, used in Triangulate_MONO + int TriangulateMonotone(TriangulatorPoly *inPoly, std::list *triangles); + +public: + + //simple heuristic procedure for removing holes from a list of polygons + //works by creating a diagonal from the rightmost hole vertex to some visible vertex + //time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices + //space complexity: O(n) + //params: + // inpolys : a list of polygons that can contain holes + // vertices of all non-hole polys have to be in counter-clockwise order + // vertices of all hole polys have to be in clockwise order + // outpolys : a list of polygons without holes + //returns 1 on success, 0 on failure + int RemoveHoles(std::list *inpolys, std::list *outpolys); + + //triangulates a polygon by ear clipping + //time complexity O(n^2), n is the number of vertices + //space complexity: O(n) + //params: + // poly : an input polygon to be triangulated + // vertices have to be in counter-clockwise order + // triangles : a list of triangles (result) + //returns 1 on success, 0 on failure + int Triangulate_EC(TriangulatorPoly *poly, std::list *triangles); + + //triangulates a list of polygons that may contain holes by ear clipping algorithm + //first calls RemoveHoles to get rid of the holes, and then Triangulate_EC for each resulting polygon + //time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices + //space complexity: O(n) + //params: + // inpolys : a list of polygons to be triangulated (can contain holes) + // vertices of all non-hole polys have to be in counter-clockwise order + // vertices of all hole polys have to be in clockwise order + // triangles : a list of triangles (result) + //returns 1 on success, 0 on failure + int Triangulate_EC(std::list *inpolys, std::list *triangles); + + //creates an optimal polygon triangulation in terms of minimal edge length + //time complexity: O(n^3), n is the number of vertices + //space complexity: O(n^2) + //params: + // poly : an input polygon to be triangulated + // vertices have to be in counter-clockwise order + // triangles : a list of triangles (result) + //returns 1 on success, 0 on failure + int Triangulate_OPT(TriangulatorPoly *poly, std::list *triangles); + + //triangulates a polygons by firstly partitioning it into monotone polygons + //time complexity: O(n*log(n)), n is the number of vertices + //space complexity: O(n) + //params: + // poly : an input polygon to be triangulated + // vertices have to be in counter-clockwise order + // triangles : a list of triangles (result) + //returns 1 on success, 0 on failure + int Triangulate_MONO(TriangulatorPoly *poly, std::list *triangles); + + //triangulates a list of polygons by firstly partitioning them into monotone polygons + //time complexity: O(n*log(n)), n is the number of vertices + //space complexity: O(n) + //params: + // inpolys : a list of polygons to be triangulated (can contain holes) + // vertices of all non-hole polys have to be in counter-clockwise order + // vertices of all hole polys have to be in clockwise order + // triangles : a list of triangles (result) + //returns 1 on success, 0 on failure + int Triangulate_MONO(std::list *inpolys, std::list *triangles); + + //creates a monotone partition of a list of polygons that can contain holes + //time complexity: O(n*log(n)), n is the number of vertices + //space complexity: O(n) + //params: + // inpolys : a list of polygons to be triangulated (can contain holes) + // vertices of all non-hole polys have to be in counter-clockwise order + // vertices of all hole polys have to be in clockwise order + // monotonePolys : a list of monotone polygons (result) + //returns 1 on success, 0 on failure + int MonotonePartition(std::list *inpolys, std::list *monotonePolys); + + //partitions a polygon into convex polygons by using Hertel-Mehlhorn algorithm + //the algorithm gives at most four times the number of parts as the optimal algorithm + //however, in practice it works much better than that and often gives optimal partition + //uses triangulation obtained by ear clipping as intermediate result + //time complexity O(n^2), n is the number of vertices + //space complexity: O(n) + //params: + // poly : an input polygon to be partitioned + // vertices have to be in counter-clockwise order + // parts : resulting list of convex polygons + //returns 1 on success, 0 on failure + int ConvexPartition_HM(TriangulatorPoly *poly, std::list *parts); + + //partitions a list of polygons into convex parts by using Hertel-Mehlhorn algorithm + //the algorithm gives at most four times the number of parts as the optimal algorithm + //however, in practice it works much better than that and often gives optimal partition + //uses triangulation obtained by ear clipping as intermediate result + //time complexity O(n^2), n is the number of vertices + //space complexity: O(n) + //params: + // inpolys : an input list of polygons to be partitioned + // vertices of all non-hole polys have to be in counter-clockwise order + // vertices of all hole polys have to be in clockwise order + // parts : resulting list of convex polygons + //returns 1 on success, 0 on failure + int ConvexPartition_HM(std::list *inpolys, std::list *parts); + + //optimal convex partitioning (in terms of number of resulting convex polygons) + //using the Keil-Snoeyink algorithm + //M. Keil, J. Snoeyink, "On the time bound for convex decomposition of simple polygons", 1998 + //time complexity O(n^3), n is the number of vertices + //space complexity: O(n^3) + // poly : an input polygon to be partitioned + // vertices have to be in counter-clockwise order + // parts : resulting list of convex polygons + //returns 1 on success, 0 on failure + int ConvexPartition_OPT(TriangulatorPoly *poly, std::list *parts); +}; + + +#endif diff --git a/demos/2d/navpoly/agent.png b/demos/2d/navpoly/agent.png new file mode 100644 index 0000000000000000000000000000000000000000..23e396c4787450c93f25ebd4b2f52f20ac911695 GIT binary patch literal 2508 zcmV;-2{ZPIP)WFU8GbZ8()Nlj2>E@cM*00}TjL_t(|+U=ZMY#dh| z#=kQ&yK6g6-L$0%wv(1nK^2sXV`5{6I7LWnm&szhI)Ehx|ks>H6qLRG7ZOR12M z5~QF$6sdjVokG<{wVcFBb7>kSAknBv4M{~?tEugsb3PvS;<=nNb7ppD?IKSUMSDE4 z=ltgTfB(zu8dy8ljx2}hp$A>P3K`uDxu0y>XT}FNApPAoN_=#pYr8Z+ zfd)!sjby)4zN}VnedQCan9;pY^pa{mywNnJFmQVCyzsezn1c{UXJ>x>i%+0p_?_s! zmZ8uPKG26${an`93AKqz{(N}!rwj^iFYed5_?R~4ACeN#fpB^A8Wu2;gDQ-6a<0HR%E__dg+4r|YqOQ{tVguV7&F zm;V}!b=ULo#_ZqWdLCR5hZe8k+wvM7kpICTKgKz?52}u-n?63vTaXa=03NEstzR5N zfzkk6sdS@U>C*VjGN}H+@yguwnU_~gG1IS2ab)~(6G`)872&wG4f+uHi?<2eIFB2m zj6ak<1HWl+gf9dRF8u>9F3jSUh1c=I!YO=R{yTKevMUPA&;Qq0<20^7DgS3Hs+f`S z$wMH&7A)c#o-p_BzaWHw0C3Ie!WFR&FO&x1Mb4EJc-_4N-;i@S>Gt8McMoRVJKzL+ ztH9A!S%==+ZjTsnG^F744~#9%U7tCgXJ20HRlj6p z624p6jSqzf2Y@g@2{)o9pJ{&CSwZuqwn|k>VQ}z1FjTOajaC4duR}@8T9UG9v?eIE zYp6cCB49?xC+{?s>7+#8hPyIlAJP0yW++NZ+;i`?M5Q!WTbS6i1V&Nb3@43nMd}C_ zpSyn;)#{Q}N@j{ul$014ybsb}N(i4I6k^x#kN(_IFe77!57#e6=tl>&dtWM5uybfX zT(?wfBuO;?)L+{`A&I;09z@^mpK5*&v-t*KD*s!ZHD4j#164xr5)P7WUl_&vAKZWt zB6Q)7>*DgIS-6g4^sVlm^|*WEX7sM#04fy$V20B1UTI`}Vk;^CsfQB1_qt3K-h|`2 z@s2yt2a$wQGJ~fqo3a2F&Yd~Z-4Vr*@`^PS#wNG1j#x@RQluppZ)xEJqk$LbF?+@i zKL*lC4fo_*p_B2{o3 z+Jda1lnH>*Q*MQ*_~D@R?Sj9tGvT>CPg8dGKDmTAL`)#^td7MPV< z$vzehVHTs+PW3eH1p(BaW_?un*db}0P_(DSOMgV*QM=BJkI=k!LCKbqX{?J9J;l%u z>AZ?9&V9X%a%oeY0!vScDj=zNV+xd_6q5izJ8LyIgjt}NL&a1xY0o7fL_vzNA15UB zJ~=%lZMK^NrS|g*R18ut(mXm~j_}bMt+l71rFTALYzZP8&26;#!Y7wfG`FU(%9qyR zlLrd*Hf`vA(xF0A9=ClSlMp6M>S{AWp;eY*Jxd7ys{Wr`GOZD9w_=!*l98wPiM#`X z(dyNh0aXo(SP&350ZIVE^w@;jTB&_msg%uA%q@VG{F5tMDTG)A;S=lyAVIkLr;sdG zF=tNx?vM35Lp!5IHld5{1V$#VS-&Wc1ALC4s%=9tW6GGEW@?gl8r&2C;#p|MI$ z?0p2P^;a%Hhh#~Yrt>N#7ns=-zp3i0ikwi8rXEd7Cd;U)!zbAV(2IJKE}UJre55ci z0N^^MAGf1U0pnu=+SMrz0EdKE|Js59-PWfOW6icI}snFBShLfQXAWG%lt$Fv=w$EMf-2LdJluHu;dvet&)B~_r zN_e!9S1D}=vkd5w?@77%C)oN#7ASU}BFg37doP?l_I4}#X!|d{=vlY%`3q-{3CAft zBLv>JnX%}h&=N|>oy6t0UJ~nX+j6zleH8wyn05?3{2+j;l+_8+-yWSaS{ZG+Qc&`` zAB5wadh_hDOYOMsj{fqlox_i=t1jJo2f)Ymoq4WT`Re&IN6%yJSUc8^wPWpAJN^eW WJOO3L7}D+l00001): + + var to_walk = delta*SPEED + while(to_walk>0 and path.size()>=2): + var pfrom = path[path.size()-1] + var pto = path[path.size()-2] + var d = pfrom.distance_to(pto) + if (d<=to_walk): + path.remove(path.size()-1) + to_walk-=d + else: + path[path.size()-1] = pfrom.linear_interpolate(pto,to_walk/d) + to_walk=0 + + var atpos = path[path.size()-1] + get_node("agent").set_pos(atpos) + + if (path.size()<2): + path=[] + set_process(false) + + else: + set_process(false) + + + +func _update_path(): + + var p = get_simple_path(begin,end,true) + path=Array(p) # Vector2array to complex to use, convert to regular array + path.invert() + + set_process(true) + + +func _input(ev): + if (ev.type==InputEvent.MOUSE_BUTTON and ev.pressed and ev.button_index==1): + begin=get_node("agent").get_pos() + #mouse to local navigatio cooards + end=ev.pos - get_pos() + _update_path() + +func _ready(): + # Initialization here + set_process_input(true) + pass + + diff --git a/demos/2d/navpoly/navigation.scn b/demos/2d/navpoly/navigation.scn new file mode 100644 index 0000000000000000000000000000000000000000..c116d10ae2b6b11007dad10ffa94a012fa412614 GIT binary patch literal 3471 zcmYjU4R{pgwLUwu$t2m34GCd^CF~>tf=S4VDME;lZ}v=*hQDA!iJFTulikU(ve^l{ zn}i>Gvk+T~pum#~Dk`Z+P(zCftzM~Rg-ia>T7Qa)^txzG(6kgvE0)|!&&K=Qr~5p+ z^L=N|&-;DfIp2A=whj^EpLBpDkz!XVT0aC?;lvSF0z3!=V>j7Py z5StGmh)Yxj(!`{+pdK<>gKpg!(3*8f7AFdAdNAyB>mfBYvBmIj@*06iYJ$-k_WJ_j zRJJfNc+gAFAZ%0%8dHkAh!@~Qia`ec5;ek$*{MJjn{EDL& z6Tg_v%i6Kyn%DaH_Fuck_D+=VxmE5exiDL1A7)J2d<=j4hflHWZ@1Xl8?CYWx_K8;WHz>XLjM|a* zboo{6aes`9E`nTi>I>14b%la{h0lHY5N_Od4*#St#5>>r1xmJ*(+^*A{pkFU(E8w1 zt=@6ypM{uR?38y*|1qXL)rake@4}BSzJp&qJP#lH=rTfYt~d1){R*b!*I@E*{(v`g zYi#c=oC(2O>6R z<#H*Oz})6MQlBaEvJGaF=X^5CVNM$S^?jYDDOkoz5Ddoi%$&~ByE9G(L!-cDz2Cp5t=eWa+kAaT{ir)^lrUy<^f1EF^y&ScMB*cFc_0(26#5J!#)V znl`qKyO++NWN;ttR0GNEY*`$E`9DZ!?YK^f>xTJ$nknNm2fYo&HKJ}-6+bk#1(6j- zZPH2h3HzKP*w`&*R7*&>9S()u&}<*JuEa-EUV;4td$BN6((@`@HWu7;`L@pTprf>o42pY#kQH`pyjtXZk;p>MPgx+53<89q8+gDt(6}Z{_g;9B3HWIS}gW?dy^{DtGoB z7-(Qh(}JE+*l;KT4vr3%F#|gW#|FCw4-JkDS)^m|c!7P0AIgMl zFB}-`WzOo8gXad04~2$0S%-A&vZ>6}gWq3v85*8HG*CjZ#)e9Ua1aN}@o7!}B<*rj={_?lIn*>E^*29{jsNbql$&ygl67+?2 z?>-10Jzv!`caJ%&2X&8{mtZtCh4iqRVs7<9insngVTVDc9B%)RtCVgmv8(NmWzS z8ot@^w2DuIuF70c_ZE%n!;uuT64c#cb#YDvT8iG(Uc6-b;n5Egs{^617H~&?&glUy zrx`q|w^>m?WLxK6h7eOK?vrjxSEP%A+Xw^{x6vvVn0SalbQ&KpJbH|qR`C#SR=cgCw5f6bYc`DbiF+=3qZ6pKH6USd$vH^y7gIh-=oWO z_$yqR>jb-#?XLV^tD@*0U)TsLE&f)oFQDXPaA7@^b3Vq;iE;I8GV5XGQa0~y4F+>A zs&x#aw%x^%VfG}m#jNp??aIqy_p>y{OP=Hw-$vc9gaTTN+A2`tK>SutkN<2ojAk&? z;Qh*}t+YC#EuBQ`k(i(G((jlrFTco8WRmmWzsrSBr>&O<~hnIqs4SXA3tF2A`+3#yZ7KW-vfhPWo9O%*tR z@2LiBq)gM><9Qc?8KRBNVm_jc7B-)q7CgT3^U>Am@x5ehiaC*BZ)97#vm(VT3pT}) zvX~5hQRazq1~map-NleD3X+(j2ikl=BhdUE3k2q2Bg`Q_leo?xrm6XfC$ghlixJW$ z$9Ra{8>Llu$Nm|O4MnAkke2hsnQXH{nWVcPK7Ep9=XIL3R)1J=|D^HBXf{j|%XqE1 z(U<#fBs+mJ!*2vt8~@}JQtuxvcZ_ww7nXB=-IyJ!v`si3=W;+JB z%>n(;m;Bpry|tM7)&z)|p5Q}4Z=-q#;h2uK;;+<~@p+T7(OtkU^v3rX3mo=oeBVbqgZJ(<;0)2<=)_&1Z;qaoM* z%py%>Rm4PAvpUES1-2V9y9Mek`-zQMS)7ju^xj6l`z4(@U2|A3g#f#lTJae>NsBp1 zLA+#ekX#;Q@gVk??IZy@1=GdltctW*CovYvd(!_7Qen&zlBh?AB+Dg>Q?e7)s3Q1r iGVuwskdu&RD^*PwQF|cJ z%+BTg5&#f&GBa{9GbMAkaKH%dGetey z@$pguTW_!6DAURE;Kb{l|2TOVfpPfz+tyL{bMHj^hTp@Fb?{lUv^)8 z`I?+`pZC_=$Ic<3_I2+Mb+2bncY$~7{+&;w;E7BA^P1!_{1Lwf7u zcW3Prw?I#q8{x2xruFWXiHDeVgn)DZNu5_d5K`nsTz}CvYu7mj%mq4YABHIEB@nP2 ztKTGa+KyuA24$opbW#u}pxeUL{;;Rhfz*=<03mnXotwZ|`eu=jv^CQ1(zC-cFs5`A*ip1qVC-Mj>y~72IWD`4)1BtKeTg3@~9Ni5VhahlMl1`+BVD`Dy*l5Z4d? zccbdZ&LZnCPzEZl><8u*A{}9*B)(+!o%}x_O}{(+DZBW;dEEpwqd@xgd>#+u=Bw}Q zZSPx2fw~boO=}kj9)NE{o$DRG3;WxSZGf#0_+)LopSr;3J?mhh7}Df*a`+9B|Kbpr4R30Hjo z7qe$u=+lv)<$b_%hm3cI2p__-bNLpL{l@(zjVu5r;2dh(L<{P7Qi5#@HUGfcNf*0A z#>@R6iH9%r$vF+*S82bezj}f_m}kTaRW*;FNQ|PEpJL$4an0P%=CZwA;$j8j`P~2V zPKJJ4_U&p{_)L>TJ2)7)?YLH5kZ`dR@~x^Pe&K=;u+i`w)b$Ey;EM`K=itU$*>m=Z z9bQB0wdh*Qc`^ZbvtPquyfq{AlnmRgdi9ci^9a~YzX9C$Z@2^gzsv9c=J}Ee;+YVs8zgC0i(% z@#1a~Dt>1l7>z_V^ahx-|DpGhL-h#51{BPN#-Ho^3+|Erl-N>`2K|GBS7OQVJ~D6#>h#98n$}GS?2cBy#E!>~>=wxL`4|l_ z-$xh73LxWRH$Q;>1Kx&S+feBMY-UFpaw&un9BX|UwD;r9Dlh)N#yVZnOoPJe> z?Msq(v%q{ZWThcwL-E9Vrd5IPu9Yk6wB_8Do9g&trHTKaq#IP*bia5)X9b-9+wDep zCH?Aw2p{g^cGlp3jY&nF3M``up#Tb!CXk2?tEY2v{DeX50Tm|#G@H}*s^J*RMCas!GC~qUGY&a2 z!%FewlkoaEy_L%c9H(c>ydc?!rxr1!qzb2-z1VN&qV@)>p*Jb3=Yj&rHK(cHCnSv6 z&>^`4lN{vVcI$bhg3f_Jp$svFU`Z zx&eBpeFxH;K!7(c6oobb%ihDxOtTjFzn6-@K5QjWnhQAKudoHDWL@~L%EyQnAytYJ6 z;o${kJBv5FN5Q`5qJY#WCxqwD*r4$SLjR1uKl0!6tA^C>k)WiVvzQTjo9IoIrtx*6qVS$7C+;nV->3ne##S+?ztaDVasgt?vfv@e07^voBBH|q<15ElzY@q84 z*~#hZuEpjXgT75C4aG#hygth5i6eQmQZv4>C9-l5h%ONeQGz8D7HLZQgY;0)S~)?t zrda9GS9nBno@H2+so-90?eK2?Fa4vdV*$$fbMrh}1Yp*@=0;;`pcTc(#;kd@zB&p) z6%-=~-Idk@ziyX3s9+R(OYcL&08 zW7h~3`FetaQ5y{g+#GO8Ph0wax7*N~Pc*+jt6WEgqL46b>LLtBj~EBHSu^3WMB5du zo`kYOP*FnhlEvVmEau_0V6^XWLO$Ax2Mo|sP$ESp$SA_9szpMFSF9|2>t&|OoQ`pE z7Au&p≠iy~RL&qv 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 qXbs8J&<6ql!`-5CH|m<)z?+c42~rU8)2 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

H)507$$^>G>c(X=W#qB4AF) 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⩔EIBU?5>6w;=p?LHT7} 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

  • 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≀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

    gn-bn3C548WFnBP3k1iNfT#~gqFEBZ8Otz|RZ0 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 S{cZ%jUh=Xkkk8Vlq5ltUdGsOx literal 0 HcmV?d00001 diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation2d.cpp new file mode 100644 index 000000000000..5e93dac61d87 --- /dev/null +++ b/scene/2d/navigation2d.cpp @@ -0,0 +1,623 @@ +#include "navigation2d.h" + +void Navigation2D::_navpoly_link(int p_id) { + + ERR_FAIL_COND(!navpoly_map.has(p_id)); + NavMesh &nm=navpoly_map[p_id]; + ERR_FAIL_COND(nm.linked); + + print_line("LINK"); + + DVector vertices=nm.navpoly->get_vertices(); + int len = vertices.size(); + if (len==0) + return; + + DVector::Read r=vertices.read(); + + for(int i=0;iget_polygon_count();i++) { + + //build + + List::Element *P=nm.polygons.push_back(Polygon()); + Polygon &p=P->get(); + p.owner=&nm; + + Vector poly = nm.navpoly->get_polygon(i); + int plen=poly.size(); + const int *indices=poly.ptr(); + bool valid=true; + p.edges.resize(plen); + + Vector2 center; + + for(int j=0;j=len) { + valid=false; + break; + } + + Polygon::Edge e; + Vector2 ep=nm.xform.xform(r[idx]); + center+=ep; + e.point=_get_point(ep); + p.edges[j]=e; + } + + if (!valid) { + nm.polygons.pop_back(); + ERR_CONTINUE(!valid); + continue; + } + + p.center=center/plen; + + //connect + + for(int j=0;j::Element *C=connections.find(ek); + if (!C) { + + Connection c; + c.A=&p; + c.A_edge=j; + c.B=NULL; + c.B_edge=-1; + connections[ek]=c; + } else { + + if (C->get().B!=NULL) { + print_line(String()+_get_vertex(ek.a)+" -> "+_get_vertex(ek.b)); + } + ERR_CONTINUE(C->get().B!=NULL); //wut + + C->get().B=&p; + C->get().B_edge=j; + C->get().A->edges[C->get().A_edge].C=&p; + C->get().A->edges[C->get().A_edge].C_edge=j;; + p.edges[j].C=C->get().A; + p.edges[j].C_edge=C->get().A_edge; + //connection successful. + } + } + } + + nm.linked=true; + +} + + +void Navigation2D::_navpoly_unlink(int p_id) { + + ERR_FAIL_COND(!navpoly_map.has(p_id)); + NavMesh &nm=navpoly_map[p_id]; + ERR_FAIL_COND(!nm.linked); + + print_line("UNLINK"); + + for (List::Element *E=nm.polygons.front();E;E=E->next()) { + + + Polygon &p=E->get(); + + int ec = p.edges.size(); + Polygon::Edge *edges=p.edges.ptr(); + + for(int i=0;i::Element *C=connections.find(ek); + ERR_CONTINUE(!C); + if (C->get().B) { + //disconnect + + C->get().B->edges[C->get().B_edge].C=NULL; + C->get().B->edges[C->get().B_edge].C_edge=-1; + C->get().A->edges[C->get().A_edge].C=NULL; + C->get().A->edges[C->get().A_edge].C_edge=-1; + + if (C->get().A==&E->get()) { + + C->get().A=C->get().B; + C->get().A_edge=C->get().B_edge; + } + C->get().B=NULL; + C->get().B_edge=-1; + + } else { + connections.erase(C); + //erase + } + } + } + + nm.polygons.clear(); + + nm.linked=false; + + +} + + +int Navigation2D::navpoly_create(const Ref& p_mesh, const Matrix32& p_xform, Object *p_owner) { + + int id = last_id++; + NavMesh nm; + nm.linked=false; + nm.navpoly=p_mesh; + nm.xform=p_xform; + nm.owner=p_owner; + navpoly_map[id]=nm; + + _navpoly_link(id); + + return id; +} + +void Navigation2D::navpoly_set_transform(int p_id, const Matrix32& p_xform){ + + ERR_FAIL_COND(!navpoly_map.has(p_id)); + NavMesh &nm=navpoly_map[p_id]; + if (nm.xform==p_xform) + return; //bleh + _navpoly_unlink(p_id); + nm.xform=p_xform; + _navpoly_link(p_id); + + + +} +void Navigation2D::navpoly_remove(int p_id){ + + ERR_FAIL_COND(!navpoly_map.has(p_id)); + _navpoly_unlink(p_id); + navpoly_map.erase(p_id); + +} +#if 0 +void Navigation2D::_clip_path(Vector& path, Polygon *from_poly, const Vector2& p_to_point, Polygon* p_to_poly) { + + Vector2 from = path[path.size()-1]; + + if (from.distance_to(p_to_point)prev_edge; + Vector2 a = _get_vertex(from_poly->edges[pe].point); + Vector2 b = _get_vertex(from_poly->edges[(pe+1)%from_poly->edges.size()].point); + + from_poly=from_poly->edges[pe].C; + ERR_FAIL_COND(!from_poly); + + if (a.distance_to(b)>CMP_EPSILON) { + + Vector2 inters; + if (cut_plane.intersects_segment(a,b,&inters)) { + if (inters.distance_to(p_to_point)>CMP_EPSILON && inters.distance_to(path[path.size()-1])>CMP_EPSILON) { + path.push_back(inters); + } + } + } + } +} +#endif + +Vector Navigation2D::get_simple_path(const Vector2& p_start, const Vector2& p_end, bool p_optimize) { + + + Polygon *begin_poly=NULL; + Polygon *end_poly=NULL; + Vector2 begin_point; + Vector2 end_point; + float begin_d=1e20; + float end_d=1e20; + + //look for point inside triangle + + for (Map::Element*E=navpoly_map.front();E;E=E->next()) { + + if (!E->get().linked) + continue; + for(List::Element *F=E->get().polygons.front();F;F=F->next()) { + + + Polygon &p=F->get(); + if (begin_d || end_d) { + for(int i=2;i0) { + + if (Geometry::is_point_in_triangle(p_start,_get_vertex(p.edges[0].point),_get_vertex(p.edges[i-1].point),_get_vertex(p.edges[i].point))) { + + begin_poly=&p; + begin_point=p_start; + begin_d=0; + if (end_d==0) + break; + + } + } + + if (end_d>0) { + + if (Geometry::is_point_in_triangle(p_end,_get_vertex(p.edges[0].point),_get_vertex(p.edges[i-1].point),_get_vertex(p.edges[i].point))) { + + end_poly=&p; + end_point=p_end; + end_d=0; + if (begin_d==0) + break; + } + } + + } + } + + p.prev_edge=-1; + } + } + + //start or end not inside triangle.. look for closest segment :| + if (begin_d || end_d) { + for (Map::Element*E=navpoly_map.front();E;E=E->next()) { + + if (!E->get().linked) + continue; + for(List::Element *F=E->get().polygons.front();F;F=F->next()) { + + Polygon &p=F->get(); + int es = p.edges.size(); + for(int i=0;i0) { + Vector2 spoint=Geometry::get_closest_point_to_segment_2d(p_start,edge); + float d = spoint.distance_to(p_start); + if (d0) { + Vector2 spoint=Geometry::get_closest_point_to_segment_2d(p_end,edge); + float d = spoint.distance_to(p_end); + if (d(); //no path + } + + if (begin_poly==end_poly) { + + Vector path; + path.resize(2); + path[0]=begin_point; + path[1]=end_point; + //print_line("Direct Path"); + return path; + } + + + bool found_route=false; + + List open_list; + + for(int i=0;iedges.size();i++) { + + if (begin_poly->edges[i].C) { + + begin_poly->edges[i].C->prev_edge=begin_poly->edges[i].C_edge; + begin_poly->edges[i].C->distance=begin_poly->center.distance_to(begin_poly->edges[i].C->center); + open_list.push_back(begin_poly->edges[i].C); + + if (begin_poly->edges[i].C==end_poly) { + found_route=true; + } + } + } + + + while(!found_route) { + + if (open_list.size()==0) { + // print_line("NOU OPEN LIST"); + break; + } + //check open list + + List::Element *least_cost_poly=NULL; + float least_cost=1e30; + + //this could be faster (cache previous results) + for (List::Element *E=open_list.front();E;E=E->next()) { + + Polygon *p=E->get(); + + + float cost=p->distance; + cost+=p->center.distance_to(end_point); + + if (costget(); + //open the neighbours for search + + for(int i=0;iedges.size();i++) { + + + Polygon::Edge &e=p->edges[i]; + + if (!e.C) + continue; + + float distance = p->center.distance_to(e.C->center) + p->distance; + + if (e.C->prev_edge!=-1) { + //oh this was visited already, can we win the cost? + + if (e.C->distance>distance) { + + e.C->prev_edge=e.C_edge; + e.C->distance=distance; + } + } else { + //add to open neighbours + + e.C->prev_edge=e.C_edge; + e.C->distance=distance; + open_list.push_back(e.C); + + if (e.C==end_poly) { + //oh my reached end! stop algorithm + found_route=true; + break; + + } + + } + } + + if (found_route) + break; + + open_list.erase(least_cost_poly); + } + + if (found_route) { + + Vector path; + + if (p_optimize) { + //string pulling + + Polygon *apex_poly=end_poly; + Vector2 apex_point=end_point; + Vector2 portal_left=apex_point; + Vector2 portal_right=apex_point; + Polygon *left_poly=end_poly; + Polygon *right_poly=end_poly; + Polygon *p=end_poly; + path.push_back(end_point); + + while(p) { + + Vector2 left; + Vector2 right; + +//#define CLOCK_TANGENT(m_a,m_b,m_c) ( ((m_a)-(m_c)).cross((m_a)-(m_b)) ) +#define CLOCK_TANGENT(m_a,m_b,m_c) ((((m_a).x - (m_c).x) * ((m_b).y - (m_c).y) - ((m_b).x - (m_c).x) * ((m_a).y - (m_c).y))) + + if (p==begin_poly) { + left=begin_point; + right=begin_point; + } else { + int prev = p->prev_edge; + int prev_n = (p->prev_edge+1)%p->edges.size(); + left = _get_vertex(p->edges[prev].point); + right = _get_vertex(p->edges[prev_n].point); + + if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5) < 0){ + SWAP(left,right); + } + } + + bool skip=false; + + + if (CLOCK_TANGENT(apex_point,portal_left,left) >= 0){ + //process + if (portal_left==apex_point || CLOCK_TANGENT(apex_point,left,portal_right) > 0) { + left_poly=p; + portal_left=left; + } else { + + //_clip_path(path,apex_poly,portal_right,right_poly); + + apex_point=portal_right; + p=right_poly; + left_poly=p; + apex_poly=p; + portal_left=apex_point; + portal_right=apex_point; + path.push_back(apex_point); + skip=true; + } + } + + if (!skip && CLOCK_TANGENT(apex_point,portal_right,right) <= 0){ + //process + if (portal_right==apex_point || CLOCK_TANGENT(apex_point,right,portal_left) < 0) { + right_poly=p; + portal_right=right; + } else { + + //_clip_path(path,apex_poly,portal_left,left_poly); + + apex_point=portal_left; + p=left_poly; + right_poly=p; + apex_poly=p; + portal_right=apex_point; + portal_left=apex_point; + path.push_back(apex_point); + } + } + + if (p!=begin_poly) + p=p->edges[p->prev_edge].C; + else + p=NULL; + + } + + if (path[path.size()-1]!=begin_point) + path.push_back(begin_point); + + path.invert(); + + + + + } else { + //midpoints + Polygon *p=end_poly; + + path.push_back(end_point); + while(true) { + int prev = p->prev_edge; + int prev_n = (p->prev_edge+1)%p->edges.size(); + Vector2 point = (_get_vertex(p->edges[prev].point) + _get_vertex(p->edges[prev_n].point))*0.5; + path.push_back(point); + p = p->edges[prev].C; + if (p==begin_poly) + break; + } + + path.push_back(begin_point); + + + path.invert();; + } + + return path; + } + + + return Vector(); + +} + + +Vector2 Navigation2D::get_closest_point(const Vector2& p_point) { + + Vector2 closest_point=Vector2(); + float closest_point_d=1e20; + + for (Map::Element*E=navpoly_map.front();E;E=E->next()) { + + if (!E->get().linked) + continue; + for(List::Element *F=E->get().polygons.front();F;F=F->next()) { + + Polygon &p=F->get(); + for(int i=2;i::Element*E=navpoly_map.front();E;E=E->next()) { + + if (!E->get().linked) + continue; + for(List::Element *F=E->get().polygons.front();F;F=F->next()) { + + Polygon &p=F->get(); + int es = p.edges.size(); + for(int i=0;i b.key) { + SWAP(a,b); + } + } + }; + + + struct NavMesh; + + + struct Polygon { + + struct Edge { + Point point; + Polygon *C; //connection + int C_edge; + Edge() { C=NULL; C_edge=-1; } + }; + + Vector edges; + + Vector2 center; + + float distance; + int prev_edge; + + NavMesh *owner; + }; + + + struct Connection { + + Polygon *A; + int A_edge; + Polygon *B; + int B_edge; + Connection() { A=NULL; B=NULL; A_edge=-1; B_edge=-1;} + }; + + Map connections; + + + struct NavMesh { + + Object *owner; + Matrix32 xform; + bool linked; + Ref navpoly; + List polygons; + + }; + + + + _FORCE_INLINE_ Point _get_point(const Vector2& p_pos) const { + + int x = int(Math::floor(p_pos.x/cell_size)); + int y = int(Math::floor(p_pos.y/cell_size)); + + Point p; + p.key=0; + p.x=x; + p.y=y; + return p; + + } + + _FORCE_INLINE_ Vector2 _get_vertex(const Point& p_point) const { + + return Vector2(p_point.x,p_point.y)*cell_size; + } + + + + void _navpoly_link(int p_id); + void _navpoly_unlink(int p_id); + + float cell_size; + Map navpoly_map; + int last_id; +#if 0 + void _clip_path(Vector& path,Polygon *from_poly, const Vector2& p_to_point, Polygon* p_to_poly); +#endif +protected: + + static void _bind_methods(); + +public: + + //API should be as dynamic as possible + int navpoly_create(const Ref& p_mesh,const Matrix32& p_xform,Object* p_owner=NULL); + void navpoly_set_transform(int p_id, const Matrix32& p_xform); + void navpoly_remove(int p_id); + + Vector get_simple_path(const Vector2& p_start, const Vector2& p_end,bool p_optimize=true); + Vector2 get_closest_point(const Vector2& p_point); + + Navigation2D(); +}; + + +#endif // Navigation2D2D_H diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp new file mode 100644 index 000000000000..570a5b95b0dc --- /dev/null +++ b/scene/2d/navigation_polygon.cpp @@ -0,0 +1,450 @@ +#include "navigation_polygon.h" +#include "navigation2d.h" +#include "triangulator.h" +#include "core_string_names.h" + +void NavigationPolygon::set_vertices(const DVector& p_vertices) { + + vertices=p_vertices; +} + +DVector NavigationPolygon::get_vertices() const{ + + return vertices; +} + + +void NavigationPolygon::_set_polygons(const Array& p_array) { + + polygons.resize(p_array.size()); + for(int i=0;i& p_polygon){ + + Polygon polygon; + polygon.indices=p_polygon; + polygons.push_back(polygon); + +} + +void NavigationPolygon::add_outline_at_index(const DVector& p_outline,int p_index) { + + outlines.insert(p_index,p_outline); +} + +int NavigationPolygon::get_polygon_count() const{ + + return polygons.size(); +} +Vector NavigationPolygon::get_polygon(int p_idx){ + + ERR_FAIL_INDEX_V(p_idx,polygons.size(),Vector()); + return polygons[p_idx].indices; +} +void NavigationPolygon::clear_polygons(){ + + polygons.clear(); +} + +void NavigationPolygon::add_outline(const DVector& p_outline) { + + outlines.push_back(p_outline); +} + +int NavigationPolygon::get_outline_count() const{ + + return outlines.size(); +} + +void NavigationPolygon::set_outline(int p_idx,const DVector& p_outline) { + ERR_FAIL_INDEX(p_idx,outlines.size()); + outlines[p_idx]=p_outline; +} + +void NavigationPolygon::remove_outline(int p_idx) { + + ERR_FAIL_INDEX(p_idx,outlines.size()); + outlines.remove(p_idx); + +} + +DVector NavigationPolygon::get_outline(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx,outlines.size(),DVector()); + return outlines[p_idx]; +} + +void NavigationPolygon::clear_outlines(){ + + outlines.clear();; +} +void NavigationPolygon::make_polygons_from_outlines(){ + + std::list in_poly,out_poly; + + Vector2 outside_point(-1e10,-1e10); + + for(int i=0;i ol = outlines[i]; + int olsize = ol.size(); + if (olsize<3) + continue; + DVector::Read r=ol.read(); + for(int j=0;j ol = outlines[i]; + int olsize = ol.size(); + if (olsize<3) + continue; + DVector::Read r=ol.read(); + + int interscount=0; + //test if this is an outer outline + for(int k=0;k ol2 = outlines[k]; + int olsize2 = ol2.size(); + if (olsize2<3) + continue; + DVector::Read r2=ol2.read(); + + for(int l=0;l points; + for(std::list::iterator I = out_poly.begin();I!=out_poly.end();I++) { + + TriangulatorPoly& tp = *I; + + struct Polygon p; + + for(int i=0;i::Element *E=points.find(tp[i]); + if (!E) { + E=points.insert(tp[i],vertices.size()); + vertices.push_back(tp[i]); + } + p.indices.push_back(E->get()); + } + + polygons.push_back(p); + } + + emit_signal(CoreStringNames::get_singleton()->changed); +} + + +void NavigationPolygon::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_vertices","vertices"),&NavigationPolygon::set_vertices); + ObjectTypeDB::bind_method(_MD("get_vertices"),&NavigationPolygon::get_vertices); + + ObjectTypeDB::bind_method(_MD("add_polygon","polygon"),&NavigationPolygon::add_polygon); + ObjectTypeDB::bind_method(_MD("get_polygon_count"),&NavigationPolygon::get_polygon_count); + ObjectTypeDB::bind_method(_MD("get_polygon","idx"),&NavigationPolygon::get_polygon); + ObjectTypeDB::bind_method(_MD("clear_polygons"),&NavigationPolygon::clear_polygons); + + ObjectTypeDB::bind_method(_MD("add_outline","outline"),&NavigationPolygon::add_outline); + ObjectTypeDB::bind_method(_MD("add_outline_at_index","outline","index"),&NavigationPolygon::add_outline_at_index); + ObjectTypeDB::bind_method(_MD("get_outline_count"),&NavigationPolygon::get_outline_count); + ObjectTypeDB::bind_method(_MD("set_outline","idx","outline"),&NavigationPolygon::set_outline); + ObjectTypeDB::bind_method(_MD("get_outline","idx"),&NavigationPolygon::get_outline); + ObjectTypeDB::bind_method(_MD("remove_outline","idx"),&NavigationPolygon::remove_outline); + ObjectTypeDB::bind_method(_MD("clear_outlines"),&NavigationPolygon::clear_outlines); + ObjectTypeDB::bind_method(_MD("make_polygons_from_outlines"),&NavigationPolygon::make_polygons_from_outlines); + + ObjectTypeDB::bind_method(_MD("_set_polygons","polygons"),&NavigationPolygon::_set_polygons); + ObjectTypeDB::bind_method(_MD("_get_polygons"),&NavigationPolygon::_get_polygons); + + ObjectTypeDB::bind_method(_MD("_set_outlines","outlines"),&NavigationPolygon::_set_outlines); + ObjectTypeDB::bind_method(_MD("_get_outlines"),&NavigationPolygon::_get_outlines); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3_ARRAY,"vertices",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_vertices"),_SCS("get_vertices")); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY,"polygons",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_polygons"),_SCS("_get_polygons")); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY,"outlines",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_outlines"),_SCS("_get_outlines")); +} + +NavigationPolygon::NavigationPolygon() { + + +} + +void NavigationPolygonInstance::set_enabled(bool p_enabled) { + + if (enabled==p_enabled) + return; + enabled=p_enabled; + + if (!is_inside_tree()) + return; + + if (!enabled) { + + if (nav_id!=-1) { + navigation->navpoly_remove(nav_id); + nav_id=-1; + } + } else { + + if (navigation) { + + if (navpoly.is_valid()) { + + nav_id = navigation->navpoly_create(navpoly,get_relative_transform(navigation),this); + } + } + + } + + if (get_tree()->is_editor_hint()) + update(); + +// update_gizmo(); +} + +bool NavigationPolygonInstance::is_enabled() const { + + + return enabled; +} + + +///////////////////////////// + + +void NavigationPolygonInstance::_notification(int p_what) { + + + switch(p_what) { + case NOTIFICATION_ENTER_TREE: { + + Node2D *c=this; + while(c) { + + navigation=c->cast_to(); + if (navigation) { + + if (enabled && navpoly.is_valid()) { + + nav_id = navigation->navpoly_create(navpoly,get_relative_transform(navigation),this); + } + break; + } + + c=c->get_parent()->cast_to(); + } + + } break; + case NOTIFICATION_TRANSFORM_CHANGED: { + + if (navigation && nav_id!=-1) { + navigation->navpoly_set_transform(nav_id,get_relative_transform(navigation)); + } + + } break; + case NOTIFICATION_EXIT_TREE: { + + if (navigation) { + + if (nav_id!=-1) { + navigation->navpoly_remove(nav_id); + nav_id=-1; + } + } + navigation=NULL; + } break; + case NOTIFICATION_DRAW: { + + if (is_inside_tree() && get_tree()->is_editor_hint() && navpoly.is_valid()) { + + DVector verts=navpoly->get_vertices(); + int vsize = verts.size(); + if (vsize<3) + return; + + + Color color; + if (enabled) { + color=Color(0.1,0.8,1.0,0.4); + } else { + color=Color(1.0,0.8,0.1,0.4); + } + Vector colors; + Vector vertices; + vertices.resize(vsize); + colors.resize(vsize); + { + DVector::Read vr = verts.read(); + for(int i=0;i indices; + + + for(int i=0;iget_polygon_count();i++) { + Vector polygon = navpoly->get_polygon(i); + + for(int j=2;jcanvas_item_add_triangle_array(get_canvas_item(),indices,vertices,colors); + + } + } break; + + } +} + + +void NavigationPolygonInstance::set_navigation_polygon(const Ref& p_navpoly) { + + if (p_navpoly==navpoly) + return; + + if (navigation && nav_id!=-1) { + navigation->navpoly_remove(nav_id); + nav_id=-1; + } + if (navpoly.is_valid()) { + navpoly->disconnect(CoreStringNames::get_singleton()->changed,this,"_navpoly_changed"); + } + navpoly=p_navpoly; + + if (navpoly.is_valid()) { + navpoly->connect(CoreStringNames::get_singleton()->changed,this,"_navpoly_changed"); + } + + if (navigation && navpoly.is_valid() && enabled) { + nav_id = navigation->navpoly_create(navpoly,get_relative_transform(navigation),this); + } + //update_gizmo(); + _change_notify("navpoly"); + +} + +Ref NavigationPolygonInstance::get_navigation_polygon() const{ + + return navpoly; +} + +void NavigationPolygonInstance::_navpoly_changed() { + + if (is_inside_tree() && get_tree()->is_editor_hint()) + update(); +} + +void NavigationPolygonInstance::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_navigation_polygon","navpoly"),&NavigationPolygonInstance::set_navigation_polygon); + ObjectTypeDB::bind_method(_MD("get_navigation_polygon"),&NavigationPolygonInstance::get_navigation_polygon); + + ObjectTypeDB::bind_method(_MD("set_enabled","enabled"),&NavigationPolygonInstance::set_enabled); + ObjectTypeDB::bind_method(_MD("is_enabled"),&NavigationPolygonInstance::is_enabled); + + ObjectTypeDB::bind_method(_MD("_navpoly_changed"),&NavigationPolygonInstance::_navpoly_changed); + + ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"navpoly",PROPERTY_HINT_RESOURCE_TYPE,"NavigationPolygon"),_SCS("set_navigation_polygon"),_SCS("get_navigation_polygon")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled")); +} + +NavigationPolygonInstance::NavigationPolygonInstance() { + + navigation=NULL; + nav_id=-1; + enabled=true; + +} diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_polygon.h new file mode 100644 index 000000000000..01307a170bb2 --- /dev/null +++ b/scene/2d/navigation_polygon.h @@ -0,0 +1,84 @@ +#ifndef NAVIGATION_POLYGON_H +#define NAVIGATION_POLYGON_H + +#include "scene/2d/node_2d.h" + + +class NavigationPolygon : public Resource { + + OBJ_TYPE( NavigationPolygon, Resource ); + + DVector vertices; + struct Polygon { + Vector indices; + }; + Vector polygons; + Vector< DVector > outlines; + +protected: + + static void _bind_methods(); + + void _set_polygons(const Array& p_array); + Array _get_polygons() const; + + void _set_outlines(const Array& p_array); + Array _get_outlines() const; + +public: + + + + void set_vertices(const DVector& p_vertices); + DVector get_vertices() const; + + void add_polygon(const Vector& p_polygon); + int get_polygon_count() const; + + void add_outline(const DVector& p_outline); + void add_outline_at_index(const DVector& p_outline,int p_index); + void set_outline(int p_idx,const DVector& p_outline); + DVector get_outline(int p_idx) const; + void remove_outline(int p_idx); + int get_outline_count() const; + + void clear_outlines(); + void make_polygons_from_outlines(); + + Vector get_polygon(int p_idx); + void clear_polygons(); + + NavigationPolygon(); +}; + + +class Navigation2D; + +class NavigationPolygonInstance : public Node2D { + + OBJ_TYPE(NavigationPolygonInstance,Node2D); + + bool enabled; + int nav_id; + Navigation2D *navigation; + Ref navpoly; + + void _navpoly_changed(); + +protected: + + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_enabled(bool p_enabled); + bool is_enabled() const; + + void set_navigation_polygon(const Ref& p_navpoly); + Ref get_navigation_polygon() const; + + NavigationPolygonInstance(); +}; + + +#endif // NAVIGATIONPOLYGON_H diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 8b4196ee7f41..36b6b220b32c 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -317,6 +317,18 @@ int Node2D::get_z() const{ return z; } +Matrix32 Node2D::get_relative_transform(const Node *p_parent) const { + + if (p_parent==this) + return Matrix32(); + + Node2D *parent_2d = get_parent()->cast_to(); + ERR_FAIL_COND_V(!parent_2d,Matrix32()); + if (p_parent==parent_2d) + return get_transform(); + else + return parent_2d->get_relative_transform(p_parent) * get_transform(); +} void Node2D::_bind_methods() { @@ -351,6 +363,8 @@ void Node2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("edit_set_pivot"),&Node2D::edit_set_pivot); + ObjectTypeDB::bind_method(_MD("get_relative_transform"),&Node2D::get_relative_transform); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/pos"),_SCS("set_pos"),_SCS("get_pos")); ADD_PROPERTY(PropertyInfo(Variant::REAL,"transform/rot",PROPERTY_HINT_RANGE,"-1440,1440,0.1"),_SCS("_set_rotd"),_SCS("_get_rotd")); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/scale"),_SCS("set_scale"),_SCS("get_scale")); diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index 61b8c829d669..7b059008c26f 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -93,6 +93,9 @@ public: void set_z_as_relative(bool p_enabled); bool is_z_relative() const; + Matrix32 get_relative_transform(const Node *p_parent) const; + + Matrix32 get_transform() const; Node2D(); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index a82cfc7ea624..30e0241f2338 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -328,8 +328,8 @@ AcceptDialog::AcceptDialog() { label->set_anchor(MARGIN_RIGHT,ANCHOR_END); label->set_anchor(MARGIN_BOTTOM,ANCHOR_END); label->set_begin( Point2( margin, margin) ); - label->set_end( Point2( margin, button_margin) ); - label->set_autowrap(true); + label->set_end( Point2( margin, button_margin+10) ); + //label->set_autowrap(true); add_child(label); hbc = memnew( HBoxContainer ); diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index bccd05d4fe52..d58cb3da796c 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -94,6 +94,8 @@ void Popup::popup_centered_minsize(const Size2& p_minsize) { Control *c=get_child(i)->cast_to(); if (!c) continue; + if (c->is_hidden()) + continue; Size2 minsize = c->get_combined_minimum_size(); @@ -114,6 +116,8 @@ void Popup::popup_centered_minsize(const Size2& p_minsize) { } + print_line(String(c->get_type())+": "+minsize); + total_minsize.width = MAX( total_minsize.width, minsize.width ); total_minsize.height = MAX( total_minsize.height, minsize.height ); } diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 9d907391ecf9..9600469e8a67 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -102,6 +102,7 @@ #include "scene/2d/screen_button.h" #include "scene/2d/remote_transform_2d.h" #include "scene/2d/y_sort.h" +#include "scene/2d/navigation2d.h" #include "scene/2d/position_2d.h" #include "scene/2d/tile_map.h" @@ -575,6 +576,10 @@ void register_scene_types() { ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); + OS::get_singleton()->yield(); //may take time to init ObjectTypeDB::register_type(); diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 58c1cac12cc5..cc1a05f7d39f 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -89,6 +89,7 @@ #include "plugins/animation_player_editor_plugin.h" #include "plugins/baked_light_editor_plugin.h" #include "plugins/polygon_2d_editor_plugin.h" +#include "plugins/navigation_polygon_editor_plugin.h" // end #include "tools/editor/io_plugins/editor_texture_import_plugin.h" #include "tools/editor/io_plugins/editor_scene_import_plugin.h" @@ -3260,6 +3261,11 @@ Error EditorNode::export_platform(const String& p_platform, const String& p_path return OK; } +void EditorNode::show_warning(const String& p_text) { + + warning->set_text(p_text); + warning->popup_centered_minsize(); +} EditorNode::EditorNode() { @@ -3970,6 +3976,8 @@ EditorNode::EditorNode() { logo->set_pos(Point2(20,20)); logo->set_texture(gui_base->get_icon("Logo","EditorIcons") ); + warning = memnew( AcceptDialog ); + add_child(warning); @@ -4107,6 +4115,7 @@ EditorNode::EditorNode() { add_editor_plugin( memnew( PathEditorPlugin(this) ) ); add_editor_plugin( memnew( BakedLightEditorPlugin(this) ) ); add_editor_plugin( memnew( Polygon2DEditorPlugin(this) ) ); + add_editor_plugin( memnew( NavigationPolygonEditorPlugin(this) ) ); for(int i=0;i get_editor_theme() const { return theme; } + void show_warning(const String& p_text); + + Error export_platform(const String& p_platform, const String& p_path, bool p_debug,const String& p_password,bool p_quit_after=false); static void register_editor_types(); diff --git a/tools/editor/icons/icon_navigation_2d.png b/tools/editor/icons/icon_navigation_2d.png new file mode 100644 index 0000000000000000000000000000000000000000..8170ecf68c4bdb21d25e780c2191beec6b2f4b30 GIT binary patch literal 541 zcmV+&0^WFU8GbZ8()Nlj2>E@cM*00DtXL_t(I%YD;Nh>c+s z2Jqj#_p?#5)0kw#lHD{L-I17^A~I7pWMLMwVqrBKOQo?;c9d)=g-|pL3uC6FFhoYN z8X7fZ?C!#Fug!Dy^>v$5Z@qucd7kr}bKcsmnP1kiBUr{8box2eOZyrcmG{Yj6cxXE z6`+P4I9dUChWnM^eHiXt^pG1E!dZMn8zX395MMBdpSTdv7iEAyxQ!)DU>g>&f{)mV zD|i=@m(>h<*2Z>xz%)j27hCZc2XMI@Pz7k>H7?;W#<2(QaS@+z9w*BH<2V&fO?<~8 z9LG&;3iAeRK`Y%E!EAxAc!e1ZU@?Ki*o@tn#e+zh#GQ~Y7YTlwjFwWcf!yuIJa*wm zW?~MjxQ1?#3Hu#@`BZx?b?D$xGMdIQ9E|UpJ`?sM%q@J5=E2O!7@kIQBVGAFiFNEx zn%8k6=W}=*z)_qD!C1dGw(&4Ekyf2f@m5PjQ{}kcri15MWouz0u10eQ_ezqxh4t-8 fzH_(FTNnNT*BoCJN6ql)00000NkvXXu0mjftrXr4 literal 0 HcmV?d00001 diff --git a/tools/editor/icons/icon_navigation_polygon_instance.png b/tools/editor/icons/icon_navigation_polygon_instance.png new file mode 100644 index 0000000000000000000000000000000000000000..9f9c318906004aa41977731d1dc76973530b7981 GIT binary patch literal 391 zcmV;20eJq2P)M`j>p1Pu{TlOVU@gU<8NPyN++jW9v1qG-xx5*a0{n>2i1#p_0(Ta82|pd1*lD`~ lI_?HT7SB10Woh*);}3%IHe#UYCx!q3002ovPDHLkV1nMxsXPDx literal 0 HcmV?d00001 diff --git a/tools/editor/plugins/navigation_polygon_editor_plugin.cpp b/tools/editor/plugins/navigation_polygon_editor_plugin.cpp new file mode 100644 index 000000000000..599d18c8bb89 --- /dev/null +++ b/tools/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -0,0 +1,547 @@ +#include "navigation_polygon_editor_plugin.h" + +#include "canvas_item_editor_plugin.h" +#include "os/file_access.h" +#include "tools/editor/editor_settings.h" + +void NavigationPolygonEditor::_notification(int p_what) { + + switch(p_what) { + + case NOTIFICATION_READY: { + + button_create->set_icon( get_icon("Edit","EditorIcons")); + button_edit->set_icon( get_icon("MovePoint","EditorIcons")); + button_edit->set_pressed(true); + get_tree()->connect("node_removed",this,"_node_removed"); + create_nav->connect("confirmed",this,"_create_nav"); + + } break; + case NOTIFICATION_FIXED_PROCESS: { + + + } break; + } + +} +void NavigationPolygonEditor::_node_removed(Node *p_node) { + + if(p_node==node) { + node=NULL; + hide(); + canvas_item_editor->get_viewport_control()->update(); + } + +} + +void NavigationPolygonEditor::_create_nav() { + + undo_redo->create_action("Create Navigation Polygon"); + undo_redo->add_do_method(node,"set_navigation_polygon",Ref(memnew( NavigationPolygon))); + undo_redo->add_undo_method(node,"set_navigation_polygon",Variant(REF())); + undo_redo->commit_action(); +} + +Vector2 NavigationPolygonEditor::snap_point(const Vector2& p_point) const { + + if (canvas_item_editor->is_snap_active()) { + + return p_point.snapped(Vector2(1,1)*canvas_item_editor->get_snap()); + + } else { + return p_point; + } +} + +void NavigationPolygonEditor::_menu_option(int p_option) { + + switch(p_option) { + + case MODE_CREATE: { + + mode=MODE_CREATE; + button_create->set_pressed(true); + button_edit->set_pressed(false); + } break; + case MODE_EDIT: { + + mode=MODE_EDIT; + button_create->set_pressed(false); + button_edit->set_pressed(true); + } break; + + } +} + +void NavigationPolygonEditor::_wip_close() { + + + if (wip.size()>=3) { + + undo_redo->create_action("Create Poly"); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"remove_outline",node->get_navigation_polygon()->get_outline_count()); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"add_outline",wip); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + mode=MODE_EDIT; + button_edit->set_pressed(true); + button_create->set_pressed(false); + } + + wip.clear(); + wip_active=false; + edited_point=-1; +} + +bool NavigationPolygonEditor::forward_input_event(const InputEvent& p_event) { + + + if (!node) + return false; + + if (node->get_navigation_polygon().is_null()) { + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { + create_nav->set_text("No NavigationPolygon resource on this node.\nCreate and assign one?"); + create_nav->popup_centered_minsize(); + } + return false; + } + + + switch(p_event.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb=p_event.mouse_button; + + Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + + + Vector2 gpoint = Point2(mb.x,mb.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=snap_point(cpoint); + cpoint = node->get_global_transform().affine_inverse().xform(cpoint); + + + + //first check if a point is to be added (segment split) + real_t grab_treshold=EDITOR_DEF("poly_editor/point_grab_radius",8); + + switch(mode) { + + + case MODE_CREATE: { + + if (mb.button_index==BUTTON_LEFT && mb.pressed) { + + + if (!wip_active) { + + wip.clear(); + wip.push_back( cpoint ); + wip_active=true; + edited_point_pos=cpoint; + edited_outline=-1; + canvas_item_editor->get_viewport_control()->update(); + edited_point=1; + return true; + } else { + + + if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)get_viewport_control()->update(); + return true; + + //add wip point + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { + _wip_close(); + } + + + + } break; + + case MODE_EDIT: { + + if (mb.button_index==BUTTON_LEFT) { + if (mb.pressed) { + + if (mb.mod.control) { + + + //search edges + int closest_outline=-1; + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + + for(int j=0;jget_navigation_polygon()->get_outline_count();j++) { + + + DVector points=node->get_navigation_polygon()->get_outline(j); + + int pc=points.size(); + DVector::Read poly=points.read(); + + for(int i=0;i=0) { + + pre_move_edit=node->get_navigation_polygon()->get_outline(closest_outline); + DVector poly = pre_move_edit; + poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)); + edited_point=closest_idx+1; + edited_outline=closest_outline; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + node->get_navigation_polygon()->set_outline(closest_outline,poly); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } else { + + //look for points to move + int closest_outline=-1; + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + + for(int j=0;jget_navigation_polygon()->get_outline_count();j++) { + + + DVector points=node->get_navigation_polygon()->get_outline(j); + + int pc=points.size(); + DVector::Read poly=points.read(); + + for(int i=0;i=0) { + + pre_move_edit=node->get_navigation_polygon()->get_outline(closest_outline); + edited_point=closest_idx; + edited_outline=closest_outline; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } + } else { + + if (edited_point!=-1) { + + //apply + + DVector poly = node->get_navigation_polygon()->get_outline(edited_outline); + ERR_FAIL_INDEX_V(edited_point,poly.size(),false); + poly.set(edited_point,edited_point_pos); + undo_redo->create_action("Edit Poly"); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"set_outline",edited_outline,poly); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"set_outline",edited_outline,pre_move_edit); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + edited_point=-1; + return true; + } + } + } if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { + + int closest_outline=-1; + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + + for(int j=0;jget_navigation_polygon()->get_outline_count();j++) { + + + DVector points=node->get_navigation_polygon()->get_outline(j); + + int pc=points.size(); + DVector::Read poly=points.read(); + + for(int i=0;i=0) { + + + DVector poly = node->get_navigation_polygon()->get_outline(closest_outline); + + if (poly.size()>3) { + undo_redo->create_action("Edit Poly (Remove Point)"); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"set_outline",closest_outline,poly); + poly.remove(closest_idx); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"set_outline",closest_outline,poly); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + } else { + + undo_redo->create_action("Remove Poly And Point"); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"add_outline_at_index",poly,closest_outline); + poly.remove(closest_idx); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"remove_outline",closest_outline); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + } + return true; + } + } + + + + } break; + } + + + + } break; + case InputEvent::MOUSE_MOTION: { + + const InputEventMouseMotion &mm=p_event.mouse_motion; + + if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { + + Vector2 gpoint = Point2(mm.x,mm.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=snap_point(cpoint); + edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); + + canvas_item_editor->get_viewport_control()->update(); + + } + + } break; + } + + return false; +} +void NavigationPolygonEditor::_canvas_draw() { + + if (!node) + return; + + Control *vpc = canvas_item_editor->get_viewport_control(); + if (node->get_navigation_polygon().is_null()) + return; + + Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + Ref handle= get_icon("EditorHandle","EditorIcons"); + + + + for(int j=-1;jget_navigation_polygon()->get_outline_count();j++) { + Vector poly; + + if (wip_active && j==edited_outline) { + poly=wip; + } else { + if (j==-1) + continue; + poly = Variant(node->get_navigation_polygon()->get_outline(j)); + } + + int len = poly.size(); + + for(int i=0;idraw_line(point,next_point,col,2); + vpc->draw_texture(handle,point-handle->get_size()*0.5); + } + } +} + + + +void NavigationPolygonEditor::edit(Node *p_collision_polygon) { + + if (!canvas_item_editor) { + canvas_item_editor=CanvasItemEditor::get_singleton(); + } + + if (p_collision_polygon) { + + node=p_collision_polygon->cast_to(); + if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); + wip.clear(); + wip_active=false; + edited_point=-1; + + } else { + node=NULL; + + if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); + + } + +} + +void NavigationPolygonEditor::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("_menu_option"),&NavigationPolygonEditor::_menu_option); + ObjectTypeDB::bind_method(_MD("_canvas_draw"),&NavigationPolygonEditor::_canvas_draw); + ObjectTypeDB::bind_method(_MD("_node_removed"),&NavigationPolygonEditor::_node_removed); + ObjectTypeDB::bind_method(_MD("_create_nav"),&NavigationPolygonEditor::_create_nav); + +} + +NavigationPolygonEditor::NavigationPolygonEditor(EditorNode *p_editor) { + + canvas_item_editor=NULL; + editor=p_editor; + undo_redo = editor->get_undo_redo(); + + add_child( memnew( VSeparator )); + button_create = memnew( ToolButton ); + add_child(button_create); + button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); + button_create->set_toggle_mode(true); + button_create->set_tooltip("Create a new polygon from scratch"); + + button_edit = memnew( ToolButton ); + add_child(button_edit); + button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); + button_edit->set_toggle_mode(true); + button_edit->set_tooltip("Edit existing polygon:\nLMB: Move Point.\nCtrl+LMB: Split Segment.\nRMB: Erase Point."); + create_nav = memnew( ConfirmationDialog ); + add_child(create_nav); + create_nav->get_ok()->set_text("Create"); + + + //add_constant_override("separation",0); + +#if 0 + options = memnew( MenuButton ); + add_child(options); + options->set_area_as_parent_rect(); + options->set_text("Polygon"); + //options->get_popup()->add_item("Parse BBCODE",PARSE_BBCODE); + options->get_popup()->connect("item_pressed", this,"_menu_option"); +#endif + + mode = MODE_EDIT; + wip_active=false; + edited_outline=-1; + +} + + +void NavigationPolygonEditorPlugin::edit(Object *p_object) { + + collision_polygon_editor->edit(p_object->cast_to()); +} + +bool NavigationPolygonEditorPlugin::handles(Object *p_object) const { + + return p_object->is_type("NavigationPolygonInstance"); +} + +void NavigationPolygonEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + collision_polygon_editor->show(); + } else { + + collision_polygon_editor->hide(); + collision_polygon_editor->edit(NULL); + } + +} + +NavigationPolygonEditorPlugin::NavigationPolygonEditorPlugin(EditorNode *p_node) { + + editor=p_node; + collision_polygon_editor = memnew( NavigationPolygonEditor(p_node) ); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); + + collision_polygon_editor->hide(); + + + +} + + +NavigationPolygonEditorPlugin::~NavigationPolygonEditorPlugin() +{ +} + diff --git a/tools/editor/plugins/navigation_polygon_editor_plugin.h b/tools/editor/plugins/navigation_polygon_editor_plugin.h new file mode 100644 index 000000000000..a86d28c8a81f --- /dev/null +++ b/tools/editor/plugins/navigation_polygon_editor_plugin.h @@ -0,0 +1,91 @@ +#ifndef NAVIGATIONPOLYGONEDITORPLUGIN_H +#define NAVIGATIONPOLYGONEDITORPLUGIN_H + + + +#include "tools/editor/editor_plugin.h" +#include "tools/editor/editor_node.h" +#include "scene/2d/navigation_polygon.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/button_group.h" + +/** + @author Juan Linietsky +*/ +class CanvasItemEditor; + +class NavigationPolygonEditor : public HBoxContainer { + + OBJ_TYPE(NavigationPolygonEditor, HBoxContainer ); + + UndoRedo *undo_redo; + enum Mode { + + MODE_CREATE, + MODE_EDIT, + + }; + + Mode mode; + + ToolButton *button_create; + ToolButton *button_edit; + + ConfirmationDialog *create_nav; + + CanvasItemEditor *canvas_item_editor; + EditorNode *editor; + Panel *panel; + NavigationPolygonInstance *node; + MenuButton *options; + + int edited_outline; + int edited_point; + Vector2 edited_point_pos; + DVector pre_move_edit; + Vector wip; + bool wip_active; + + + void _wip_close(); + void _canvas_draw(); + void _create_nav(); + + void _menu_option(int p_option); + +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + Vector2 snap_point(const Vector2& p_point) const; + bool forward_input_event(const InputEvent& p_event); + void edit(Node *p_collision_polygon); + NavigationPolygonEditor(EditorNode *p_editor); +}; + +class NavigationPolygonEditorPlugin : public EditorPlugin { + + OBJ_TYPE( NavigationPolygonEditorPlugin, EditorPlugin ); + + NavigationPolygonEditor *collision_polygon_editor; + EditorNode *editor; + +public: + + virtual bool forward_input_event(const InputEvent& p_event) { return collision_polygon_editor->forward_input_event(p_event); } + + virtual String get_name() const { return "NavigationPolygonInstance"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + NavigationPolygonEditorPlugin(EditorNode *p_node); + ~NavigationPolygonEditorPlugin(); + +}; + + +#endif // NAVIGATIONPOLYGONEDITORPLUGIN_H From a49802ae332e34542c0f835cce74fb3d5e49675a Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sat, 14 Feb 2015 14:54:58 -0300 Subject: [PATCH 4/6] -resolved shader set parameter bug, closes #1361 --- drivers/gles2/rasterizer_gles2.cpp | 114 ++++++++++++++++------------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index c1631a527e2c..d1e55f2488c7 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -8330,7 +8330,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { CanvasItem *current_clip=NULL; - + Shader *shader_cache=NULL; canvas_opacity=1.0; while(p_item_list) { @@ -8375,6 +8375,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { } } + shader_cache=shader; + if (shader) { canvas_shader.set_custom_shader(shader->custom_code_id); if (canvas_shader.bind()) @@ -8384,50 +8386,6 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { //todo optimize uniforms shader_owner->shader_version=shader->version; } - //this can be optimized.. - int tex_id=1; - int idx=0; - for(Map::Element *E=shader->uniforms.front();E;E=E->next()) { - - Map::Element *F=shader_owner->shader_param.find(E->key()); - - if ((E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP)) { - - RID rid; - if (F) { - rid=F->get(); - } - - if (!rid.is_valid()) { - - Map::Element *DT=shader->default_textures.find(E->key()); - if (DT) { - rid=DT->get(); - } - } - - if (rid.is_valid()) { - - int loc = canvas_shader.get_custom_uniform_location(idx); //should be automatic.. - - glActiveTexture(GL_TEXTURE0+tex_id); - Texture *t=texture_owner.get(rid); - if (!t) - glBindTexture(GL_TEXTURE_2D,white_tex); - else - glBindTexture(t->target,t->tex_id); - - glUniform1i(loc,tex_id); - tex_id++; - } - } else { - Variant &v=F?F->get():E->get().default_value; - canvas_shader.set_custom_uniform(idx,v); - } - - idx++; - } - if (shader->has_texscreen && framebuffer.active) { @@ -8436,8 +8394,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height)); canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(float(x)/framebuffer.width,float(y)/framebuffer.height,float(x+viewport.width)/framebuffer.width,float(y+viewport.height)/framebuffer.height)); - canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX,tex_id); - glActiveTexture(GL_TEXTURE0+tex_id); + canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX,max_texture_units-1); + glActiveTexture(GL_TEXTURE0+max_texture_units-1); glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color); if (framebuffer.scale==1 && !canvas_texscreen_used) { #ifdef GLEW_ENABLED @@ -8449,14 +8407,12 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { } canvas_texscreen_used=true; - } - tex_id++; + } - } - - if (tex_id>1) { glActiveTexture(GL_TEXTURE0); + } + if (shader->has_screen_uv) { canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_UV_MULT,Vector2(1.0/viewport.width,1.0/viewport.height)); } @@ -8470,6 +8426,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { uses_texpixel_size=shader->uses_texpixel_size; } else { + shader_cache=NULL; canvas_shader.set_custom_shader(0); canvas_shader.bind(); uses_texpixel_size=false; @@ -8481,6 +8438,59 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { canvas_last_shader=shader_owner->shader; } + if (shader_cache) { + + Shader *shader = shader_cache; + //this can be optimized.. + int tex_id=1; + int idx=0; + for(Map::Element *E=shader->uniforms.front();E;E=E->next()) { + + Map::Element *F=shader_owner->shader_param.find(E->key()); + + if ((E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP)) { + + RID rid; + if (F) { + rid=F->get(); + } + + if (!rid.is_valid()) { + + Map::Element *DT=shader->default_textures.find(E->key()); + if (DT) { + rid=DT->get(); + } + } + + if (rid.is_valid()) { + + int loc = canvas_shader.get_custom_uniform_location(idx); //should be automatic.. + + glActiveTexture(GL_TEXTURE0+tex_id); + Texture *t=texture_owner.get(rid); + if (!t) + glBindTexture(GL_TEXTURE_2D,white_tex); + else + glBindTexture(t->target,t->tex_id); + + glUniform1i(loc,tex_id); + tex_id++; + } + } else { + Variant &v=F?F->get():E->get().default_value; + canvas_shader.set_custom_uniform(idx,v); + } + + idx++; + } + + if (tex_id>1) { + glActiveTexture(GL_TEXTURE0); + } + + } + canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform); canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Matrix32()); From d2f86cc09bf4136ebc1c2bbb8ec7b48a439c0371 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sat, 14 Feb 2015 19:22:06 -0300 Subject: [PATCH 5/6] fixes to mouse warp -can warp now from viewport and control, in their respective coordinate systems -warp is now local to the window on Windows and OSX. IF YOU RUN OSX, PLEASE TEST THIS! And make sure it works!, new code is in OS_OSX::warp_mouse_pos. I don't have OSX so i can't test! --- platform/osx/os_osx.mm | 13 ++++++++++++- platform/windows/os_windows.cpp | 7 ++++++- platform/x11/os_x11.cpp | 6 +++++- scene/gui/control.cpp | 9 +++++++++ scene/gui/control.h | 2 +- scene/main/viewport.cpp | 9 +++++++++ scene/main/viewport.h | 2 ++ 7 files changed, 44 insertions(+), 4 deletions(-) diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 5bc47a74c186..af2552496be1 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -1093,8 +1093,19 @@ void OS_OSX::warp_mouse_pos(const Point2& p_to) { mouse_y = p_to.y; } else{ //set OS position - CGPoint lMouseWarpPos = {p_to.x, p_to.y}; + /* this code has not been tested, please be a kind soul and fix it if it fails! */ + + //local point in window coords + NSPoint localPoint = { p_to.x, p_to.y }; + + NSPoint pointInWindow = [window_view convertPoint:localPoint toView:nil]; + NSPoint pointOnScreen = [[window_view window] convertRectToScreen:(CGRect){.origin=pointInWindow}]; + + //point in scren coords + CGPoint lMouseWarpPos = { pointOnScreen.x, pointOnScreen.y}; + + //do the warping CGEventSourceRef lEventRef = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState); CGEventSourceSetLocalEventsSuppressionInterval(lEventRef, 0.0); CGAssociateMouseAndMouseCursorPosition(false); diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 086b4d7d122a..ad54a327cfd3 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -1432,7 +1432,12 @@ void OS_Windows::warp_mouse_pos(const Point2& p_to) { old_y=p_to.y; } else { - SetCursorPos(p_to.x, p_to.y); + POINT p; + p.x=p_to.x; + p.y=p_to.y; + ClientToScreen(hWnd,&p); + + SetCursorPos(p.x,p.y); } } diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index a40af8d2a96d..ac1818d2000b 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -479,8 +479,12 @@ void OS_X11::warp_mouse_pos(const Point2& p_to) { last_mouse_pos=p_to; } else { + /*XWindowAttributes xwa; + XGetWindowAttributes(x11_display, x11_window, &xwa); + printf("%d %d\n", xwa.x, xwa.y); needed? */ + XWarpPointer(x11_display, None, x11_window, - 0,0,0,0, (int)p_to.x, (int)p_to.y); + 0,0,0,0, (int)p_to.x , (int)p_to.y); } } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index ce268843b1a0..4d32c7ea9a34 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2688,6 +2688,12 @@ Control *Control::get_focus_owner() const { return data.window->window->key_focus; } + +void Control::warp_mouse(const Point2& p_to_pos) { + ERR_FAIL_COND(!is_inside_tree()); + get_viewport()->warp_mouse(get_global_transform().xform(p_to_pos)); +} + void Control::_bind_methods() { ObjectTypeDB::bind_method(_MD("_window_input_event"),&Control::_window_input_event); @@ -2784,6 +2790,9 @@ void Control::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_drag_preview","control:Control"),&Control::set_drag_preview); + ObjectTypeDB::bind_method(_MD("warp_mouse","to_pos"),&Control::warp_mouse); + + BIND_VMETHOD(MethodInfo("_input_event",PropertyInfo(Variant::INPUT_EVENT,"event"))); BIND_VMETHOD(MethodInfo(Variant::VECTOR2,"get_minimum_size")); BIND_VMETHOD(MethodInfo(Variant::OBJECT,"get_drag_data",PropertyInfo(Variant::VECTOR2,"pos"))); diff --git a/scene/gui/control.h b/scene/gui/control.h index 64b5a9b661f2..7e14bff09848 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -380,7 +380,7 @@ public: void grab_click_focus(); - + void warp_mouse(const Point2& p_to_pos); Control(); ~Control(); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index e6c787cf9e0c..fa163bf96d18 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -29,6 +29,8 @@ #include "viewport.h" #include "os/os.h" #include "scene/3d/spatial.h" +#include "os/input.h" + //#include "scene/3d/camera.h" #include "servers/spatial_sound_server.h" @@ -1100,6 +1102,12 @@ void Viewport::_vp_unhandled_input(const InputEvent& p_ev) { } +void Viewport::warp_mouse(const Vector2& p_pos) { + + Vector2 gpos = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse().xform(p_pos); + Input::get_singleton()->warp_mouse_pos(gpos); +} + void Viewport::input(const InputEvent& p_event) { ERR_FAIL_COND(!is_inside_tree()); @@ -1289,6 +1297,7 @@ void Viewport::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_audio_listener_2d","enable"), &Viewport::is_audio_listener_2d); ObjectTypeDB::bind_method(_MD("set_render_target_to_screen_rect"), &Viewport::set_render_target_to_screen_rect); + ObjectTypeDB::bind_method(_MD("warp_mouse","to_pos"), &Viewport::warp_mouse); ADD_PROPERTY( PropertyInfo(Variant::RECT2,"rect"), _SCS("set_rect"), _SCS("get_rect") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"own_world"), _SCS("set_use_own_world"), _SCS("is_using_own_world") ); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 4bb5735731e3..832a6b610736 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -246,6 +246,8 @@ public: void set_render_target_to_screen_rect(const Rect2& p_rect); Rect2 get_render_target_to_screen_rect() const; + void warp_mouse(const Vector2& p_pos); + void set_physics_object_picking(bool p_enable); bool get_physics_object_picking(); From 2185c018f6593e6d64b2beb62202d2291e2e008e Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 15 Feb 2015 01:19:46 -0300 Subject: [PATCH 6/6] begin new serialization framework also got rid of STL dependency on triangulator --- core/bind/core_bind.cpp | 7 + core/bind/core_bind.h | 2 + core/math/triangulator.cpp | 325 +++++++++++----------- core/math/triangulator.h | 41 ++- core/set.h | 37 +++ core/variant.cpp | 43 +-- core/variant.h | 6 +- core/variant_construct_string.cpp | 433 ++++++++++++++++++++++++++++++ demos/2d/navpoly/navigation.scn | Bin 3471 -> 3456 bytes modules/gdscript/gd_functions.cpp | 32 ++- modules/gdscript/gd_functions.h | 2 + platform/windows/os_windows.cpp | 1 - scene/2d/navigation_polygon.cpp | 6 +- 13 files changed, 729 insertions(+), 206 deletions(-) create mode 100644 core/variant_construct_string.cpp diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index a03fd7fe4ab6..8d18acdc23a5 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -316,6 +316,11 @@ float _OS::get_time_scale() { return OS::get_singleton()->get_time_scale(); } +bool _OS::is_ok_left_and_cancel_right() const { + + return OS::get_singleton()->get_swap_ok_cancel(); +} + /* enum Weekday { DAY_SUNDAY, @@ -699,6 +704,8 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_system_dir","dir"),&_OS::get_system_dir); ObjectTypeDB::bind_method(_MD("get_unique_ID"),&_OS::get_unique_ID); + ObjectTypeDB::bind_method(_MD("is_ok_left_and_cancel_right"),&_OS::is_ok_left_and_cancel_right); + ObjectTypeDB::bind_method(_MD("get_frames_per_second"),&_OS::get_frames_per_second); ObjectTypeDB::bind_method(_MD("print_all_textures_by_size"),&_OS::print_all_textures_by_size); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index f5043ba71fa4..057ad90fe980 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -220,6 +220,8 @@ public: void set_time_scale(float p_scale); float get_time_scale(); + bool is_ok_left_and_cancel_right() const; + static _OS *get_singleton() { return singleton; } _OS(); diff --git a/core/math/triangulator.cpp b/core/math/triangulator.cpp index 6be1cdb3304c..8f82d7682375 100644 --- a/core/math/triangulator.cpp +++ b/core/math/triangulator.cpp @@ -22,9 +22,9 @@ #include #include #include -#include + #include "triangulator.h" -using namespace std; + #define TRIANGULATOR_VERTEXTYPE_REGULAR 0 #define TRIANGULATOR_VERTEXTYPE_START 1 @@ -163,9 +163,9 @@ int TriangulatorPartition::Intersects(Vector2 &p11, Vector2 &p12, Vector2 &p21, } //removes holes from inpolys by merging them with non-holes -int TriangulatorPartition::RemoveHoles(list *inpolys, list *outpolys) { - list polys; - list::iterator holeiter,polyiter,iter,iter2; +int TriangulatorPartition::RemoveHoles(List *inpolys, List *outpolys) { + List polys; + List::Element *holeiter,*polyiter,*iter,*iter2; long i,i2,holepointindex,polypointindex; Vector2 holepoint,polypoint,bestpolypoint; Vector2 linep1,linep2; @@ -177,15 +177,15 @@ int TriangulatorPartition::RemoveHoles(list *inpolys, listbegin(); iter!=inpolys->end(); iter++) { - if(iter->IsHole()) { + for(iter = inpolys->front(); iter; iter=iter->next()) { + if(iter->get().IsHole()) { hasholes = true; break; } } if(!hasholes) { - for(iter = inpolys->begin(); iter!=inpolys->end(); iter++) { - outpolys->push_back(*iter); + for(iter = inpolys->front(); iter; iter=iter->next()) { + outpolys->push_back(iter->get()); } return 1; } @@ -195,8 +195,8 @@ int TriangulatorPartition::RemoveHoles(list *inpolys, listIsHole()) continue; + for(iter = polys.front(); iter; iter=iter->next()) { + if(!iter->get().IsHole()) continue; if(!hasholes) { hasholes = true; @@ -204,38 +204,38 @@ int TriangulatorPartition::RemoveHoles(list *inpolys, listGetNumPoints(); i++) { - if(iter->GetPoint(i).x > holeiter->GetPoint(holepointindex).x) { + for(i=0; i < iter->get().GetNumPoints(); i++) { + if(iter->get().GetPoint(i).x > holeiter->get().GetPoint(holepointindex).x) { holeiter = iter; holepointindex = i; } } } if(!hasholes) break; - holepoint = holeiter->GetPoint(holepointindex); + holepoint = holeiter->get().GetPoint(holepointindex); pointfound = false; - for(iter = polys.begin(); iter!=polys.end(); iter++) { - if(iter->IsHole()) continue; - for(i=0; i < iter->GetNumPoints(); i++) { - if(iter->GetPoint(i).x <= holepoint.x) continue; - if(!InCone(iter->GetPoint((i+iter->GetNumPoints()-1)%(iter->GetNumPoints())), - iter->GetPoint(i), - iter->GetPoint((i+1)%(iter->GetNumPoints())), + for(iter = polys.front(); iter; iter=iter->next()) { + if(iter->get().IsHole()) continue; + for(i=0; i < iter->get().GetNumPoints(); i++) { + if(iter->get().GetPoint(i).x <= holepoint.x) continue; + if(!InCone(iter->get().GetPoint((i+iter->get().GetNumPoints()-1)%(iter->get().GetNumPoints())), + iter->get().GetPoint(i), + iter->get().GetPoint((i+1)%(iter->get().GetNumPoints())), holepoint)) continue; - polypoint = iter->GetPoint(i); + polypoint = iter->get().GetPoint(i); if(pointfound) { v1 = Normalize(polypoint-holepoint); v2 = Normalize(bestpolypoint-holepoint); if(v2.x > v1.x) continue; } pointvisible = true; - for(iter2 = polys.begin(); iter2!=polys.end(); iter2++) { - if(iter2->IsHole()) continue; - for(i2=0; i2 < iter2->GetNumPoints(); i2++) { - linep1 = iter2->GetPoint(i2); - linep2 = iter2->GetPoint((i2+1)%(iter2->GetNumPoints())); + for(iter2 = polys.front(); iter2; iter2=iter2->next()) { + if(iter2->get().IsHole()) continue; + for(i2=0; i2 < iter2->get().GetNumPoints(); i2++) { + linep1 = iter2->get().GetPoint(i2); + linep2 = iter2->get().GetPoint((i2+1)%(iter2->get().GetNumPoints())); if(Intersects(holepoint,polypoint,linep1,linep2)) { pointvisible = false; break; @@ -254,18 +254,18 @@ int TriangulatorPartition::RemoveHoles(list *inpolys, listGetNumPoints() + polyiter->GetNumPoints() + 2); + newpoly.Init(holeiter->get().GetNumPoints() + polyiter->get().GetNumPoints() + 2); i2 = 0; for(i=0;i<=polypointindex;i++) { - newpoly[i2] = polyiter->GetPoint(i); + newpoly[i2] = polyiter->get().GetPoint(i); i2++; } - for(i=0;i<=holeiter->GetNumPoints();i++) { - newpoly[i2] = holeiter->GetPoint((i+holepointindex)%holeiter->GetNumPoints()); + for(i=0;i<=holeiter->get().GetNumPoints();i++) { + newpoly[i2] = holeiter->get().GetPoint((i+holepointindex)%holeiter->get().GetNumPoints()); i2++; } - for(i=polypointindex;iGetNumPoints();i++) { - newpoly[i2] = polyiter->GetPoint(i); + for(i=polypointindex;iget().GetNumPoints();i++) { + newpoly[i2] = polyiter->get().GetPoint(i); i2++; } @@ -274,8 +274,8 @@ int TriangulatorPartition::RemoveHoles(list *inpolys, listpush_back(*iter); + for(iter = polys.front(); iter; iter=iter->next()) { + outpolys->push_back(iter->get()); } return 1; @@ -366,7 +366,7 @@ void TriangulatorPartition::UpdateVertex(PartitionVertex *v, PartitionVertex *ve } //triangulation by ear removal -int TriangulatorPartition::Triangulate_EC(TriangulatorPoly *poly, list *triangles) { +int TriangulatorPartition::Triangulate_EC(TriangulatorPoly *poly, List *triangles) { long numvertices; PartitionVertex *vertices; PartitionVertex *ear; @@ -440,20 +440,20 @@ int TriangulatorPartition::Triangulate_EC(TriangulatorPoly *poly, list *inpolys, list *triangles) { - list outpolys; - list::iterator iter; +int TriangulatorPartition::Triangulate_EC(List *inpolys, List *triangles) { + List outpolys; + List::Element*iter; if(!RemoveHoles(inpolys,&outpolys)) return 0; - for(iter=outpolys.begin();iter!=outpolys.end();iter++) { - if(!Triangulate_EC(&(*iter),triangles)) return 0; + for(iter=outpolys.front();iter;iter=iter->next()) { + if(!Triangulate_EC(&(iter->get()),triangles)) return 0; } return 1; } -int TriangulatorPartition::ConvexPartition_HM(TriangulatorPoly *poly, list *parts) { - list triangles; - list::iterator iter1,iter2; +int TriangulatorPartition::ConvexPartition_HM(TriangulatorPoly *poly, List *parts) { + List triangles; + List::Element *iter1,*iter2; TriangulatorPoly *poly1,*poly2; TriangulatorPoly newpoly; Vector2 d1,d2,p1,p2,p3; @@ -480,17 +480,17 @@ int TriangulatorPartition::ConvexPartition_HM(TriangulatorPoly *poly, listnext()) { + poly1 = &(iter1->get()); for(i11=0;i11GetNumPoints();i11++) { d1 = poly1->GetPoint(i11); i12 = (i11+1)%(poly1->GetNumPoints()); d2 = poly1->GetPoint(i12); isdiagonal = false; - for(iter2 = iter1; iter2 != triangles.end(); iter2++) { + for(iter2 = iter1; iter2 ; iter2=iter2->next()) { if(iter1 == iter2) continue; - poly2 = &(*iter2); + poly2 = &(iter2->get()); for(i21=0;i21GetNumPoints();i21++) { if((d2.x != poly2->GetPoint(i21).x)||(d2.y != poly2->GetPoint(i21).y)) continue; @@ -536,28 +536,28 @@ int TriangulatorPartition::ConvexPartition_HM(TriangulatorPoly *poly, listget() = newpoly; + poly1 = &(iter1->get()); i11 = -1; continue; } } - for(iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) { - parts->push_back(*iter1); + for(iter1 = triangles.front(); iter1 ; iter1=iter1->next()) { + parts->push_back(iter1->get()); } return 1; } -int TriangulatorPartition::ConvexPartition_HM(list *inpolys, list *parts) { - list outpolys; - list::iterator iter; +int TriangulatorPartition::ConvexPartition_HM(List *inpolys, List *parts) { + List outpolys; + List::Element* iter; if(!RemoveHoles(inpolys,&outpolys)) return 0; - for(iter=outpolys.begin();iter!=outpolys.end();iter++) { - if(!ConvexPartition_HM(&(*iter),parts)) return 0; + for(iter=outpolys.front();iter;iter=iter->next()) { + if(!ConvexPartition_HM(&(iter->get()),parts)) return 0; } return 1; } @@ -565,14 +565,14 @@ int TriangulatorPartition::ConvexPartition_HM(list *inpolys, l //minimum-weight polygon triangulation by dynamic programming //O(n^3) time complexity //O(n^2) space complexity -int TriangulatorPartition::Triangulate_OPT(TriangulatorPoly *poly, list *triangles) { +int TriangulatorPartition::Triangulate_OPT(TriangulatorPoly *poly, List *triangles) { long i,j,k,gap,n; DPState **dpstates; Vector2 p1,p2,p3,p4; long bestvertex; real_t weight,minweight,d1,d2; Diagonal diagonal,newdiagonal; - list diagonals; + List diagonals; TriangulatorPoly triangle; int ret = 1; @@ -666,7 +666,7 @@ int TriangulatorPartition::Triangulate_OPT(TriangulatorPoly *poly, listget()); diagonals.pop_front(); bestvertex = dpstates[diagonal.index2][diagonal.index1].bestvertex; if(bestvertex == -1) { @@ -697,7 +697,7 @@ int TriangulatorPartition::Triangulate_OPT(TriangulatorPoly *poly, list *pairs; + List *pairs; long w2; w2 = dpstates[a][b].weight; @@ -712,15 +712,15 @@ void TriangulatorPartition::UpdateState(long a, long b, long w, long i, long j, pairs->push_front(newdiagonal); dpstates[a][b].weight = w; } else { - if((!pairs->empty())&&(i <= pairs->begin()->index1)) return; - while((!pairs->empty())&&(pairs->begin()->index2 >= j)) pairs->pop_front(); + if((!pairs->empty())&&(i <= pairs->front()->get().index1)) return; + while((!pairs->empty())&&(pairs->front()->get().index2 >= j)) pairs->pop_front(); pairs->push_front(newdiagonal); } } void TriangulatorPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) { - list *pairs; - list::iterator iter,lastiter; + List *pairs; + List::Element *iter,*lastiter; long top; long w; @@ -733,25 +733,29 @@ void TriangulatorPartition::TypeA(long i, long j, long k, PartitionVertex *verti } if(j-i > 1) { pairs = &(dpstates[i][j].pairs); - iter = pairs->end(); - lastiter = pairs->end(); - while(iter!=pairs->begin()) { - iter--; - if(!IsReflex(vertices[iter->index2].p,vertices[j].p,vertices[k].p)) lastiter = iter; + iter = NULL; + lastiter = NULL; + while(iter!=pairs->front()) { + if (!iter) + iter=pairs->back(); + else + iter=iter->prev(); + + if(!IsReflex(vertices[iter->get().index2].p,vertices[j].p,vertices[k].p)) lastiter = iter; else break; } - if(lastiter == pairs->end()) w++; + if(lastiter == NULL) w++; else { - if(IsReflex(vertices[k].p,vertices[i].p,vertices[lastiter->index1].p)) w++; - else top = lastiter->index1; + if(IsReflex(vertices[k].p,vertices[i].p,vertices[lastiter->get().index1].p)) w++; + else top = lastiter->get().index1; } } UpdateState(i,k,w,top,j,dpstates); } void TriangulatorPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) { - list *pairs; - list::iterator iter,lastiter; + List *pairs; + List::Element* iter,*lastiter; long top; long w; @@ -766,36 +770,36 @@ void TriangulatorPartition::TypeB(long i, long j, long k, PartitionVertex *verti if (k-j > 1) { pairs = &(dpstates[j][k].pairs); - iter = pairs->begin(); - if((!pairs->empty())&&(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->index1].p))) { + iter = pairs->front(); + if((!pairs->empty())&&(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->get().index1].p))) { lastiter = iter; - while(iter!=pairs->end()) { - if(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->index1].p)) { + while(iter!=NULL) { + if(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->get().index1].p)) { lastiter = iter; - iter++; + iter=iter->next(); } else break; } - if(IsReflex(vertices[lastiter->index2].p,vertices[k].p,vertices[i].p)) w++; - else top = lastiter->index2; + if(IsReflex(vertices[lastiter->get().index2].p,vertices[k].p,vertices[i].p)) w++; + else top = lastiter->get().index2; } else w++; } UpdateState(i,k,w,j,top,dpstates); } -int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, list *parts) { +int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, List *parts) { Vector2 p1,p2,p3,p4; PartitionVertex *vertices; DPState2 **dpstates; long i,j,k,n,gap; - list diagonals,diagonals2; + List diagonals,diagonals2; Diagonal diagonal,newdiagonal; - list *pairs,*pairs2; - list::iterator iter,iter2; + List *pairs,*pairs2; + List::Element* iter,*iter2; int ret; TriangulatorPoly newpoly; - list indices; - list::iterator iiter; + List indices; + List::Element* iiter; bool ijreal,jkreal; n = poly->GetNumPoints(); @@ -903,7 +907,7 @@ int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, listget()); diagonals.pop_front(); if((diagonal.index2 - diagonal.index1) <=1) continue; pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs); @@ -912,23 +916,23 @@ int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, listend(); - iter--; - j = iter->index2; + iter = pairs->back(); + + j = iter->get().index2; newdiagonal.index1 = j; newdiagonal.index2 = diagonal.index2; diagonals.push_front(newdiagonal); if((j - diagonal.index1)>1) { - if(iter->index1 != iter->index2) { + if(iter->get().index1 != iter->get().index2) { pairs2 = &(dpstates[diagonal.index1][j].pairs); while(1) { if(pairs2->empty()) { ret = 0; break; } - iter2 = pairs2->end(); - iter2--; - if(iter->index1 != iter2->index1) pairs2->pop_back(); + iter2 = pairs2->back(); + + if(iter->get().index1 != iter2->get().index1) pairs2->pop_back(); else break; } if(ret == 0) break; @@ -938,21 +942,21 @@ int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, listbegin(); - j = iter->index1; + iter = pairs->front(); + j = iter->get().index1; newdiagonal.index1 = diagonal.index1; newdiagonal.index2 = j; diagonals.push_front(newdiagonal); if((diagonal.index2 - j) > 1) { - if(iter->index1 != iter->index2) { + if(iter->get().index1 != iter->get().index2) { pairs2 = &(dpstates[j][diagonal.index2].pairs); while(1) { if(pairs2->empty()) { ret = 0; break; } - iter2 = pairs2->begin(); - if(iter->index2 != iter2->index2) pairs2->pop_front(); + iter2 = pairs2->front(); + if(iter->get().index2 != iter2->get().index2) pairs2->pop_front(); else break; } if(ret == 0) break; @@ -978,7 +982,7 @@ int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, listget(); diagonals.pop_front(); if((diagonal.index2 - diagonal.index1) <= 1) continue; @@ -989,21 +993,20 @@ int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, listget()); diagonals2.pop_front(); if((diagonal.index2 - diagonal.index1) <= 1) continue; ijreal = true; jkreal = true; pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs); if(!vertices[diagonal.index1].isConvex) { - iter = pairs->end(); - iter--; - j = iter->index2; - if(iter->index1 != iter->index2) ijreal = false; + iter = pairs->back(); + j = iter->get().index2; + if(iter->get().index1 != iter->get().index2) ijreal = false; } else { - iter = pairs->begin(); - j = iter->index1; - if(iter->index1 != iter->index2) jkreal = false; + iter = pairs->front(); + j = iter->get().index1; + if(iter->get().index1 != iter->get().index2) jkreal = false; } newdiagonal.index1 = diagonal.index1; @@ -1028,8 +1031,8 @@ int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, listnext()) { + newpoly[k] = vertices[iiter->get()].p; k++; } parts->push_back(newpoly); @@ -1049,8 +1052,8 @@ int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, list *inpolys, list *monotonePolys) { - list::iterator iter; +int TriangulatorPartition::MonotonePartition(List *inpolys, List *monotonePolys) { + List::Element *iter; MonotoneVertex *vertices; long i,numvertices,vindex,vindex2,newnumvertices,maxnumvertices; long polystartindex, polyendindex; @@ -1060,8 +1063,8 @@ int TriangulatorPartition::MonotonePartition(list *inpolys, li bool error = false; numvertices = 0; - for(iter = inpolys->begin(); iter != inpolys->end(); iter++) { - numvertices += iter->GetNumPoints(); + for(iter = inpolys->front(); iter ; iter=iter->next()) { + numvertices += iter->get().GetNumPoints(); } maxnumvertices = numvertices*3; @@ -1069,8 +1072,8 @@ int TriangulatorPartition::MonotonePartition(list *inpolys, li newnumvertices = numvertices; polystartindex = 0; - for(iter = inpolys->begin(); iter != inpolys->end(); iter++) { - poly = &(*iter); + for(iter = inpolys->front(); iter ; iter=iter->next()) { + poly = &(iter->get()); polyendindex = polystartindex + poly->GetNumPoints()-1; for(i=0;iGetNumPoints();i++) { vertices[i+polystartindex].p = poly->GetPoint(i); @@ -1085,7 +1088,9 @@ int TriangulatorPartition::MonotonePartition(list *inpolys, li //construct the priority queue long *priority = new long [numvertices]; for(i=0;i sorter; + sorter.compare.vertices=vertices; + sorter.sort(priority,numvertices); //determine vertex types char *vertextypes = new char[maxnumvertices]; @@ -1118,13 +1123,13 @@ int TriangulatorPartition::MonotonePartition(list *inpolys, li //binary search tree that holds edges intersecting the scanline //note that while set doesn't actually have to be implemented as a tree //complexity requirements for operations are the same as for the balanced binary search tree - set edgeTree; + Set edgeTree; //store iterators to the edge tree elements //this makes deleting existing edges much faster - set::iterator *edgeTreeIterators,edgeIter; - edgeTreeIterators = new set::iterator[maxnumvertices]; - pair::iterator,bool> edgeTreeRet; - for(i = 0; i::Element **edgeTreeIterators,*edgeIter; + edgeTreeIterators = new Set::Element*[maxnumvertices]; +// Pair::Element*,bool> edgeTreeRet; + for(i = 0; i *inpolys, li newedge.p1 = v->p; newedge.p2 = vertices[v->next].p; newedge.index = vindex; - edgeTreeRet = edgeTree.insert(newedge); - edgeTreeIterators[vindex] = edgeTreeRet.first; + edgeTreeIterators[vindex] = edgeTree.insert(newedge); helpers[vindex] = vindex; break; @@ -1162,24 +1166,24 @@ int TriangulatorPartition::MonotonePartition(list *inpolys, li newedge.p1 = v->p; newedge.p2 = v->p; edgeIter = edgeTree.lower_bound(newedge); - if(edgeIter == edgeTree.begin()) { + if(edgeIter == edgeTree.front()) { error = true; break; } - edgeIter--; + edgeIter=edgeIter->prev(); //Insert the diagonal connecting vi to helper(ej) in D. - AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->index], + AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->get().index], vertextypes, edgeTreeIterators, &edgeTree, helpers); vindex2 = newnumvertices-2; v2 = &(vertices[vindex2]); //helper(e j)�vi - helpers[edgeIter->index] = vindex; + helpers[edgeIter->get().index] = vindex; //Insert ei in T and set helper(ei) to vi. newedge.p1 = v2->p; newedge.p2 = vertices[v2->next].p; newedge.index = vindex2; - edgeTreeRet = edgeTree.insert(newedge); - edgeTreeIterators[vindex2] = edgeTreeRet.first; + + edgeTreeIterators[vindex2] = edgeTree.insert(newedge); helpers[vindex2] = vindex2; break; @@ -1198,19 +1202,19 @@ int TriangulatorPartition::MonotonePartition(list *inpolys, li newedge.p1 = v->p; newedge.p2 = v->p; edgeIter = edgeTree.lower_bound(newedge); - if(edgeIter == edgeTree.begin()) { + if(edgeIter == edgeTree.front()) { error = true; break; } - edgeIter--; + edgeIter=edgeIter->prev(); //if helper(ej) is a merge vertex - if(vertextypes[helpers[edgeIter->index]]==TRIANGULATOR_VERTEXTYPE_MERGE) { + if(vertextypes[helpers[edgeIter->get().index]]==TRIANGULATOR_VERTEXTYPE_MERGE) { //Insert the diagonal connecting vi to helper(e j) in D. - AddDiagonal(vertices,&newnumvertices,vindex2,helpers[edgeIter->index], + AddDiagonal(vertices,&newnumvertices,vindex2,helpers[edgeIter->get().index], vertextypes, edgeTreeIterators, &edgeTree, helpers); } //helper(e j)�vi - helpers[edgeIter->index] = vindex2; + helpers[edgeIter->get().index] = vindex2; break; case TRIANGULATOR_VERTEXTYPE_REGULAR: @@ -1230,27 +1234,26 @@ int TriangulatorPartition::MonotonePartition(list *inpolys, li newedge.p1 = v2->p; newedge.p2 = vertices[v2->next].p; newedge.index = vindex2; - edgeTreeRet = edgeTree.insert(newedge); - edgeTreeIterators[vindex2] = edgeTreeRet.first; + edgeTreeIterators[vindex2] = edgeTree.insert(newedge); helpers[vindex2] = vindex; } else { //Search in T to find the edge ej directly left of vi. newedge.p1 = v->p; newedge.p2 = v->p; edgeIter = edgeTree.lower_bound(newedge); - if(edgeIter == edgeTree.begin()) { + if(edgeIter == edgeTree.front()) { error = true; break; } - edgeIter--; + edgeIter=edgeIter->prev(); //if helper(ej) is a merge vertex - if(vertextypes[helpers[edgeIter->index]]==TRIANGULATOR_VERTEXTYPE_MERGE) { + if(vertextypes[helpers[edgeIter->get().index]]==TRIANGULATOR_VERTEXTYPE_MERGE) { //Insert the diagonal connecting vi to helper(e j) in D. - AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->index], + AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->get().index], vertextypes, edgeTreeIterators, &edgeTree, helpers); } //helper(e j)�vi - helpers[edgeIter->index] = vindex; + helpers[edgeIter->get().index] = vindex; } break; } @@ -1308,8 +1311,8 @@ int TriangulatorPartition::MonotonePartition(list *inpolys, li //adds a diagonal to the doubly-connected list of vertices void TriangulatorPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2, - char *vertextypes, set::iterator *edgeTreeIterators, - set *edgeTree, long *helpers) + char *vertextypes, Set::Element **edgeTreeIterators, + Set *edgeTree, long *helpers) { long newindex1,newindex2; @@ -1337,13 +1340,13 @@ void TriangulatorPartition::AddDiagonal(MonotoneVertex *vertices, long *numverti vertextypes[newindex1] = vertextypes[index1]; edgeTreeIterators[newindex1] = edgeTreeIterators[index1]; helpers[newindex1] = helpers[index1]; - if(edgeTreeIterators[newindex1] != edgeTree->end()) - edgeTreeIterators[newindex1]->index = newindex1; + if(edgeTreeIterators[newindex1] != NULL) + edgeTreeIterators[newindex1]->get().index = newindex1; vertextypes[newindex2] = vertextypes[index2]; edgeTreeIterators[newindex2] = edgeTreeIterators[index2]; helpers[newindex2] = helpers[index2]; - if(edgeTreeIterators[newindex2] != edgeTree->end()) - edgeTreeIterators[newindex2]->index = newindex2; + if(edgeTreeIterators[newindex2] != NULL) + edgeTreeIterators[newindex2]->get().index = newindex2; } bool TriangulatorPartition::Below(Vector2 &p1, Vector2 &p2) { @@ -1354,8 +1357,12 @@ bool TriangulatorPartition::Below(Vector2 &p1, Vector2 &p2) { return false; } + + + + //sorts in the falling order of y values, if y is equal, x is used instead -bool TriangulatorPartition::VertexSorter::operator() (long index1, long index2) { +bool TriangulatorPartition::VertexSorter::operator() (long index1, long index2) const { if(vertices[index1].p.y > vertices[index2].p.y) return true; else if(vertices[index1].p.y == vertices[index2].p.y) { if(vertices[index1].p.x > vertices[index2].p.x) return true; @@ -1392,7 +1399,7 @@ bool TriangulatorPartition::ScanLineEdge::operator < (const ScanLineEdge & other //triangulates monotone polygon //O(n) time, O(n) space complexity -int TriangulatorPartition::TriangulateMonotone(TriangulatorPoly *inPoly, list *triangles) { +int TriangulatorPartition::TriangulateMonotone(TriangulatorPoly *inPoly, List *triangles) { long i,i2,j,topindex,bottomindex,leftindex,rightindex,vindex; Vector2 *points; long numpoints; @@ -1524,19 +1531,19 @@ int TriangulatorPartition::TriangulateMonotone(TriangulatorPoly *inPoly, list *inpolys, list *triangles) { - list monotone; - list::iterator iter; +int TriangulatorPartition::Triangulate_MONO(List *inpolys, List *triangles) { + List monotone; + List::Element* iter; if(!MonotonePartition(inpolys,&monotone)) return 0; - for(iter = monotone.begin(); iter!=monotone.end();iter++) { - if(!TriangulateMonotone(&(*iter),triangles)) return 0; + for(iter = monotone.front(); iter;iter=iter->next()) { + if(!TriangulateMonotone(&(iter->get()),triangles)) return 0; } return 1; } -int TriangulatorPartition::Triangulate_MONO(TriangulatorPoly *poly, list *triangles) { - list polys; +int TriangulatorPartition::Triangulate_MONO(TriangulatorPoly *poly, List *triangles) { + List polys; polys.push_back(*poly); return Triangulate_MONO(&polys, triangles); diff --git a/core/math/triangulator.h b/core/math/triangulator.h index c34c445892f2..b6dd7e82364b 100644 --- a/core/math/triangulator.h +++ b/core/math/triangulator.h @@ -22,9 +22,8 @@ #define TRIANGULATOR_H #include "math_2d.h" -#include -#include - +#include "list.h" +#include "set.h" //2D point structure @@ -119,11 +118,9 @@ protected: long next; }; - class VertexSorter{ - MonotoneVertex *vertices; - public: - VertexSorter(MonotoneVertex *v) : vertices(v) {} - bool operator() (long index1, long index2); + struct VertexSorter{ + mutable MonotoneVertex *vertices; + bool operator() (long index1, long index2) const; }; struct Diagonal { @@ -142,7 +139,7 @@ protected: struct DPState2 { bool visible; long weight; - std::list pairs; + List pairs; }; //edge that intersects the scanline @@ -182,11 +179,11 @@ protected: //helper functions for MonotonePartition bool Below(Vector2 &p1, Vector2 &p2); void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2, - char *vertextypes, std::set::iterator *edgeTreeIterators, - std::set *edgeTree, long *helpers); + char *vertextypes, Set::Element **edgeTreeIterators, + Set *edgeTree, long *helpers); //triangulates a monotone polygon, used in Triangulate_MONO - int TriangulateMonotone(TriangulatorPoly *inPoly, std::list *triangles); + int TriangulateMonotone(TriangulatorPoly *inPoly, List *triangles); public: @@ -200,7 +197,7 @@ public: // vertices of all hole polys have to be in clockwise order // outpolys : a list of polygons without holes //returns 1 on success, 0 on failure - int RemoveHoles(std::list *inpolys, std::list *outpolys); + int RemoveHoles(List *inpolys, List *outpolys); //triangulates a polygon by ear clipping //time complexity O(n^2), n is the number of vertices @@ -210,7 +207,7 @@ public: // vertices have to be in counter-clockwise order // triangles : a list of triangles (result) //returns 1 on success, 0 on failure - int Triangulate_EC(TriangulatorPoly *poly, std::list *triangles); + int Triangulate_EC(TriangulatorPoly *poly, List *triangles); //triangulates a list of polygons that may contain holes by ear clipping algorithm //first calls RemoveHoles to get rid of the holes, and then Triangulate_EC for each resulting polygon @@ -222,7 +219,7 @@ public: // vertices of all hole polys have to be in clockwise order // triangles : a list of triangles (result) //returns 1 on success, 0 on failure - int Triangulate_EC(std::list *inpolys, std::list *triangles); + int Triangulate_EC(List *inpolys, List *triangles); //creates an optimal polygon triangulation in terms of minimal edge length //time complexity: O(n^3), n is the number of vertices @@ -232,7 +229,7 @@ public: // vertices have to be in counter-clockwise order // triangles : a list of triangles (result) //returns 1 on success, 0 on failure - int Triangulate_OPT(TriangulatorPoly *poly, std::list *triangles); + int Triangulate_OPT(TriangulatorPoly *poly, List *triangles); //triangulates a polygons by firstly partitioning it into monotone polygons //time complexity: O(n*log(n)), n is the number of vertices @@ -242,7 +239,7 @@ public: // vertices have to be in counter-clockwise order // triangles : a list of triangles (result) //returns 1 on success, 0 on failure - int Triangulate_MONO(TriangulatorPoly *poly, std::list *triangles); + int Triangulate_MONO(TriangulatorPoly *poly, List *triangles); //triangulates a list of polygons by firstly partitioning them into monotone polygons //time complexity: O(n*log(n)), n is the number of vertices @@ -253,7 +250,7 @@ public: // vertices of all hole polys have to be in clockwise order // triangles : a list of triangles (result) //returns 1 on success, 0 on failure - int Triangulate_MONO(std::list *inpolys, std::list *triangles); + int Triangulate_MONO(List *inpolys, List *triangles); //creates a monotone partition of a list of polygons that can contain holes //time complexity: O(n*log(n)), n is the number of vertices @@ -264,7 +261,7 @@ public: // vertices of all hole polys have to be in clockwise order // monotonePolys : a list of monotone polygons (result) //returns 1 on success, 0 on failure - int MonotonePartition(std::list *inpolys, std::list *monotonePolys); + int MonotonePartition(List *inpolys, List *monotonePolys); //partitions a polygon into convex polygons by using Hertel-Mehlhorn algorithm //the algorithm gives at most four times the number of parts as the optimal algorithm @@ -277,7 +274,7 @@ public: // vertices have to be in counter-clockwise order // parts : resulting list of convex polygons //returns 1 on success, 0 on failure - int ConvexPartition_HM(TriangulatorPoly *poly, std::list *parts); + int ConvexPartition_HM(TriangulatorPoly *poly, List *parts); //partitions a list of polygons into convex parts by using Hertel-Mehlhorn algorithm //the algorithm gives at most four times the number of parts as the optimal algorithm @@ -291,7 +288,7 @@ public: // vertices of all hole polys have to be in clockwise order // parts : resulting list of convex polygons //returns 1 on success, 0 on failure - int ConvexPartition_HM(std::list *inpolys, std::list *parts); + int ConvexPartition_HM(List *inpolys, List *parts); //optimal convex partitioning (in terms of number of resulting convex polygons) //using the Keil-Snoeyink algorithm @@ -302,7 +299,7 @@ public: // vertices have to be in counter-clockwise order // parts : resulting list of convex polygons //returns 1 on success, 0 on failure - int ConvexPartition_OPT(TriangulatorPoly *poly, std::list *parts); + int ConvexPartition_OPT(TriangulatorPoly *poly, List *parts); }; diff --git a/core/set.h b/core/set.h index d87f63557736..95f38d71082e 100644 --- a/core/set.h +++ b/core/set.h @@ -249,6 +249,37 @@ private: return (node!=_data._nil)?node:NULL; } + Element *_lower_bound(const T& p_value) const { + + Element *node = _data._root->left; + Element *prev = NULL; + C less; + + while(node!=_data._nil) { + prev=node; + + if (less(p_value,node->value)) + node=node->left; + else if (less(node->value,p_value)) + node=node->right; + else + break; // found + } + + if (node==_data._nil) { + if (prev==NULL) + return NULL; + if (less(prev->value,p_value)) { + + prev=prev->_next; + } + + return prev; + + } else + return node; + } + Element *_insert(const T& p_value, bool& r_exists) { @@ -582,6 +613,12 @@ public: return e; } + + Element *lower_bound(const T& p_value) const { + + return _lower_bound(p_value); + } + inline int size() const { return _data.size_cache; } int calculate_depth() const { diff --git a/core/variant.cpp b/core/variant.cpp index 2f0eca9e911a..667a7d8648a2 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -2631,8 +2631,13 @@ Variant Variant::call(const StringName& p_method,VARIANT_ARG_DECLARE) { return ret; } +void Variant::construct_from_string(const String& p_string,Variant& r_value,ObjectConstruct p_obj_construct,void *p_construct_ud) { -String Variant::get_construct_string() const { + r_value=Variant(); +} + + +String Variant::get_construct_string(ObjectDeConstruct p_obj_deconstruct,void *p_deconstruct_ud) const { switch( type ) { @@ -2640,7 +2645,7 @@ String Variant::get_construct_string() const { case BOOL: return _data._bool ? "true" : "false"; case INT: return String::num(_data._int); case REAL: return String::num(_data._real); - case STRING: return "\""+*reinterpret_cast(_data._mem)+"\""; + case STRING: return "\""+reinterpret_cast(_data._mem)->c_escape()+"\""; case VECTOR2: return "Vector2("+operator Vector2()+")"; case RECT2: return "Rect2("+operator Rect2()+")"; case MATRIX32: return "Matrix32("+operator Matrix32()+")"; @@ -2651,7 +2656,7 @@ String Variant::get_construct_string() const { case QUAT: return "Quat("+operator Quat()+")"; case MATRIX3: return "Matrix3("+operator Matrix3()+")"; case TRANSFORM: return "Transform("+operator Transform()+")"; - case NODE_PATH: return "@\""+operator NodePath()+"\""; + case NODE_PATH: return "@\""+String(operator NodePath()).c_escape()+"\""; case INPUT_EVENT: return "InputEvent()"; case COLOR: return "Color("+String::num( operator Color().r)+","+String::num( operator Color().g)+","+String::num( operator Color().b)+","+String::num( operator Color().a)+")" ; case DICTIONARY: { @@ -2667,8 +2672,8 @@ String Variant::get_construct_string() const { for(List::Element *E=keys.front();E;E=E->next()) { _VariantStrPair sp; - sp.key=E->get().get_construct_string(); - sp.value=d[E->get()].get_construct_string(); + sp.key=E->get().get_construct_string(p_obj_deconstruct,p_deconstruct_ud); + sp.value=d[E->get()].get_construct_string(p_obj_deconstruct,p_deconstruct_ud); pairs.push_back(sp); } @@ -2686,50 +2691,50 @@ String Variant::get_construct_string() const { case VECTOR3_ARRAY: { DVector vec = operator DVector(); - String str="["; + String str="Vector3Array(["; for(int i=0;i0) str+=", "; str+=Variant( vec[i] ).get_construct_string(); } - return str+"]"; + return str+"])"; } break; case STRING_ARRAY: { DVector vec = operator DVector(); - String str="["; + String str="StringArray(["; for(int i=0;i0) str+=", "; str=str+=Variant( vec[i] ).get_construct_string(); } - return str+"]"; + return str+"])"; } break; case INT_ARRAY: { DVector vec = operator DVector(); - String str="["; + String str="IntArray(["; for(int i=0;i0) str+=", "; str=str+itos(vec[i]); } - return str+"]"; + return str+"])"; } break; case REAL_ARRAY: { DVector vec = operator DVector(); - String str="["; + String str="FloatArray(["; for(int i=0;i0) str+=", "; str=str+rtos(vec[i]); } - return str+"]"; + return str+"])"; } break; case ARRAY: { @@ -2738,16 +2743,20 @@ String Variant::get_construct_string() const { for (int i=0; iget_type()+".new()"; - else + if (_get_obj().obj) { + if (p_obj_deconstruct) { + return "Object(\""+p_obj_deconstruct(Variant(*this),p_deconstruct_ud).c_escape()+")"; + } else { + return _get_obj().obj->get_type()+".new()"; + } + } else return "null"; } break; diff --git a/core/variant.h b/core/variant.h index 47fc3f43ac1a..d5d4792422bb 100644 --- a/core/variant.h +++ b/core/variant.h @@ -419,7 +419,11 @@ public: static bool has_numeric_constant(Variant::Type p_type, const StringName& p_value); static int get_numeric_constant_value(Variant::Type p_type, const StringName& p_value); - String get_construct_string() const; + typedef String (*ObjectDeConstruct)(const Variant& p_object,void *ud); + typedef void (*ObjectConstruct)(const String& p_text,void *ud,Variant& r_value); + + String get_construct_string(ObjectDeConstruct p_obj_deconstruct=NULL,void *p_deconstruct_ud=NULL) const; + static void construct_from_string(const String& p_string,Variant& r_value,ObjectConstruct p_obj_construct=NULL,void *p_construct_ud=NULL); void operator=(const Variant& p_variant); // only this is enough for all the other types Variant(const Variant& p_variant); diff --git a/core/variant_construct_string.cpp b/core/variant_construct_string.cpp new file mode 100644 index 000000000000..0308fd3180bd --- /dev/null +++ b/core/variant_construct_string.cpp @@ -0,0 +1,433 @@ + +#include "variant.h" + +class VariantConstruct { + + enum TokenType { + TK_CURLY_BRACKET_OPEN, + TK_CURLY_BRACKET_CLOSE, + TK_BRACKET_OPEN, + TK_BRACKET_CLOSE, + TK_IDENTIFIER, + TK_STRING, + TK_NUMBER, + TK_COLON, + TK_COMMA, + TK_EOF, + TK_MAX + }; + + enum Expecting { + + EXPECT_OBJECT, + EXPECT_OBJECT_KEY, + EXPECT_COLON, + EXPECT_OBJECT_VALUE, + }; + + struct Token { + + TokenType type; + Variant value; + }; + + static const char * tk_name[TK_MAX]; + + static String _print_var(const Variant& p_var); + + static Error _get_token(const CharType *p_str,int &index, int p_len,Token& r_token,int &line,String &r_err_str); + static Error _parse_value(Variant &value,Token& token,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str,Variant::ObjectConstruct* p_construct,void* p_ud); + static Error _parse_array(Array &array,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str,Variant::ObjectConstruct* p_construct,void* p_ud); + static Error _parse_dict(Dictionary &object,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str,Variant::ObjectConstruct* p_construct,void* p_ud); + +public: + + static Error parse(const String& p_string,Variant& r_ret,String &r_err_str,int &r_err_line,Variant::ObjectConstruct* p_construct,void* p_ud); +}; + + +const char * VariantConstruct::tk_name[TK_MAX] = { + "'{'", + "'}'", + "'['", + "']'", + "identifier", + "string", + "number", + "':'", + "','", + "EOF", +}; + + + +Error VariantConstruct::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_token,int &line,String &r_err_str) { + + while (true) { + switch(p_str[idx]) { + + case '\n': { + + line++; + idx++; + break; + }; + case 0: { + r_token.type=TK_EOF; + return OK; + } break; + case '{': { + + r_token.type=TK_CURLY_BRACKET_OPEN; + idx++; + return OK; + }; + case '}': { + + r_token.type=TK_CURLY_BRACKET_CLOSE; + idx++; + return OK; + }; + case '[': { + + r_token.type=TK_BRACKET_OPEN; + idx++; + return OK; + }; + case ']': { + + r_token.type=TK_BRACKET_CLOSE; + idx++; + return OK; + }; + case ':': { + + r_token.type=TK_COLON; + idx++; + return OK; + }; + case ',': { + + r_token.type=TK_COMMA; + idx++; + return OK; + }; + case '"': { + + idx++; + String str; + while(true) { + if (p_str[idx]==0) { + r_err_str="Unterminated String"; + return ERR_PARSE_ERROR; + } else if (p_str[idx]=='"') { + idx++; + break; + } else if (p_str[idx]=='\\') { + //escaped characters... + idx++; + CharType next = p_str[idx]; + if (next==0) { + r_err_str="Unterminated String"; + return ERR_PARSE_ERROR; + } + CharType res=0; + + switch(next) { + + case 'b': res=8; break; + case 't': res=9; break; + case 'n': res=10; break; + case 'f': res=12; break; + case 'r': res=13; break; + case '\"': res='\"'; break; + case '\\': res='\\'; break; + case '/': res='/'; break; //wtf + case 'u': { + //hexnumbarh - oct is deprecated + + + for(int j=0;j<4;j++) { + CharType c = p_str[idx+j+1]; + if (c==0) { + r_err_str="Unterminated String"; + return ERR_PARSE_ERROR; + } + if (!((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F'))) { + + r_err_str="Malformed hex constant in string"; + return ERR_PARSE_ERROR; + } + CharType v; + if (c>='0' && c<='9') { + v=c-'0'; + } else if (c>='a' && c<='f') { + v=c-'a'; + v+=10; + } else if (c>='A' && c<='F') { + v=c-'A'; + v+=10; + } else { + ERR_PRINT("BUG"); + v=0; + } + + res<<=4; + res|=v; + + + } + idx+=4; //will add at the end anyway + + + } break; + default: { + + r_err_str="Invalid escape sequence"; + return ERR_PARSE_ERROR; + } break; + } + + str+=res; + + } else { + if (p_str[idx]=='\n') + line++; + str+=p_str[idx]; + } + idx++; + } + + r_token.type=TK_STRING; + r_token.value=str; + return OK; + + } break; + default: { + + if (p_str[idx]<=32) { + idx++; + break; + } + + if (p_str[idx]=='-' || (p_str[idx]>='0' && p_str[idx]<='9')) { + //a number + const CharType *rptr; + double number = String::to_double(&p_str[idx],&rptr); + idx+=(rptr - &p_str[idx]); + r_token.type=TK_NUMBER; + r_token.value=number; + return OK; + + } else if ((p_str[idx]>='A' && p_str[idx]<='Z') || (p_str[idx]>='a' && p_str[idx]<='z')) { + + String id; + + while((p_str[idx]>='A' && p_str[idx]<='Z') || (p_str[idx]>='a' && p_str[idx]<='z')) { + + id+=p_str[idx]; + idx++; + } + + r_token.type=TK_IDENTIFIER; + r_token.value=id; + return OK; + } else { + r_err_str="Unexpected character."; + return ERR_PARSE_ERROR; + } + } + + } + } + + return ERR_PARSE_ERROR; +} + + + +Error VariantConstruct::_parse_value(Variant &value,Token& token,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str,Variant::ObjectConstruct* p_construct,void* p_ud) { + + + if (token.type==TK_CURLY_BRACKET_OPEN) { + + Dictionary d; + Error err = _parse_dict(d,p_str,index,p_len,line,r_err_str,p_construct,p_ud); + if (err) + return err; + value=d; + return OK; + } else if (token.type==TK_BRACKET_OPEN) { + + Array a; + Error err = _parse_array(a,p_str,index,p_len,line,r_err_str,p_construct,p_ud); + if (err) + return err; + value=a; + return OK; + + } else if (token.type==TK_IDENTIFIER) { + + String id = token.value; + if (id=="true") + value=true; + else if (id=="false") + value=false; + else if (id=="null") + value=Variant(); + else { + r_err_str="Expected 'true','false' or 'null', got '"+id+"'."; + return ERR_PARSE_ERROR; + } + return OK; + + } else if (token.type==TK_NUMBER) { + + value=token.value; + return OK; + } else if (token.type==TK_STRING) { + + value=token.value; + return OK; + } else { + r_err_str="Expected value, got "+String(tk_name[token.type])+"."; + return ERR_PARSE_ERROR; + } + + return ERR_PARSE_ERROR; +} + + +Error VariantConstruct::_parse_array(Array &array,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str,Variant::ObjectConstruct* p_construct,void* p_ud) { + + Token token; + bool need_comma=false; + + + while(indexi;2R{3v@qpn(v-Tt)$R1R zdObz%W=JObho9uMEJpQ6Ck2|h1f-Vk5uFL7)E3E>SWIzhxR2|+X zX9xK{yAB$q_u@%eY%v@bDhWUa;b3bVf>0N{1whAX4Xl>6Ok2Qsxw!-*f=&z_O~rd# zOyUlW5vPApEN&<(!L~Es6jQcc-GM<{mYDc1mE6X<36W31>7elnRQE@XU$mZ7`2>10118h!`cG)IwXxQWKkxc#_hX9CaNpR%3_ zNQ@X9+-3Fls>QquGuB6-7LDKfwHYste2#;s^3b%nh^+dO_1daI?0D|9^@HNGXv}!` zHS4~K%Xs|#?RX&jD*pYC4m|bpPci4v02ZrGpmDy`jXBqc&=S~$zZnrwx;cvvdwcMs z@%y-A#N8|7V(8kn|;f@69w(aO;mfoW^G!e1)29wb;CY6GNk~h&}61Vd3>JPwwvGSFN+!7c-6uEJaRA6QOww1V1kjLlSZ z>miHqAw9DKf|=9+dZMLz+Ri)%!K3uFd|0I~d>f2}rw00}@?fMo%F%wt1VKI3u{lb3 zo;Im+6~yKdPRy4>DocPh1324hAkOtdG0_Vs*l9jIsiZBT4yvV@LOso-TET4VQk5v4 zPZ3TjpcDowg)(@WXhTY9VO$te&Ie2x1WRZptS4Hq5Kf6;usu?hD_#`}Og9itm3b3cv`aq}_ zYLymcW$RS6ifJ9;{^v*QX+kM(8w49^FAd0<>LN{rVs#oDuv*@%J`v~-`{wv|TVqw` zyv|@Ve5}Rk_L(NIjP}p#ZqMmnoJmZ-8D5;>z`KxU4=3jM#W~&w1*5)seo)BA&*yn< z_-}Lk?95%Ep{hT;W@aip9-a(2!V`kKYARA6X^#v>j)W(}!$P2HFgzY^Rx4OVn&W8qIT-VKujAQj!wk1F#}w@v?i7r%Y{$I#-p>;Tyq=jW3!Rl zu_G~=281gMOd~Ub3!FVN5y41(v?5j!D~V#XLac;4FlXsb0&J%Z;7H0XAqLj`%T06VE-F}Dtx9;D`i@c@oOq^NHc6>5Yc80ga&)_z{L)5K5V{Kg?7Z|3=J4e^>Kc#F@ANbUf62N$PE#i| zOYY8g=`VC(?HAyq4%<%QE8)KI0pH~HcpOdM9#Q~Yj)ux!rOy|rL1>zDQY7t+m9%m4rY delta 1759 zcmYjSe^3)w9{+AOWC;rdMH(d5EF#50N~Ed9$SH60U9c2XDjxKj(QJg6Mj?qLh+=ON zkDIX;>yOzRt}U%?rD8R2yfzkdWBkT&uNrz0R4QHPFeOmE)#&US`^R-rOIz zGrQmSzVGw)^LewM?|wsuV}_zFZHRF1Dgbz^7~pL!z=tP__5~qZV6(S6_XYZTouCtV z!IiVtWb!!zPgVOouB3V?6eMA(+Tn6~0;W3rZg24lX+1WyWby zCq)kB;@?_IrL9^cdIXd4?{jN#*9-Sck6+k|p@t$U^8~?+O)n*?zsB)UiImg6E{-pK zW0YS1;-VZhwq{RZZIeNgTIO-?Qjs*f@H@1;lE(EX4&c+HpQ3S>_7E~1*YP`cFRpwt zgRkDcY<)ovGE!({o7LN|k&Mev#jM|hMq2T<2~Usx6Gw)ZW9j@nsx;@U?=KxeWB1R0 zY5lV1MO=98J?ox{^LXrwEx5nr0^azY9fx241sazKdwXFqNDA&tlWgkb1K2Y zZ+Rz6TH?ElKe>`Gi5*>6nT9_!o ztcG^tRX5S(V^r)=M9(xsC{1oai@+yY%EfHF$Dt>RY7@YY&DI+t7x{rG^h7$?ER;bj z-Daj@bYzfZ==R4UG(?wOia}GYT}fd<+<>*p7R~YC?r3Lg6Hc$#JuZ?v5H_6VZ`qIAV{Eimt|qX`HrA4^8`{;iw`88;7DJ(>7w?8LS;k!=BlE zC8or}Gu-7FE*%?;r{i_Ri@|s%uEa;aok8 zlYqSdgg96&G-Hqzht8L4#~ zJa~#cd9EpRi(=*5}^m?6&(o4xik|QTIU> zy$kL=2E5)LP}9NH#>Mrd0JH+H?ejbTiv^XCOMn!U|RF(fC&9ke;r zYyQ_9VI_GBHfbk}O!?w^k^l bxfRTIget_construct_string(); + } break; + case STR_TO_VAR: { + VALIDATE_ARG_COUNT(1); + if (p_args[0]->get_type()!=Variant::STRING) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::STRING; + r_ret=Variant(); + return; + } + Variant::construct_from_string(*p_args[0],r_ret); + } break; case GEN_RANGE: { - - switch(p_arg_count) { case 0: { @@ -861,7 +876,6 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va } } - r_ret = gdscr->_new(NULL,0,r_error); } break; @@ -1224,6 +1238,18 @@ MethodInfo GDFunctions::get_info(Function p_func) { return mi; } break; + case VAR_TO_STR: { + MethodInfo mi("var2str",PropertyInfo(Variant::NIL,"var")); + mi.return_val.type=Variant::STRING; + return mi; + + } break; + case STR_TO_VAR: { + + MethodInfo mi("str2var:var",PropertyInfo(Variant::STRING,"string")); + mi.return_val.type=Variant::NIL; + return mi; + } break; case GEN_RANGE: { MethodInfo mi("range",PropertyInfo(Variant::NIL,"...")); diff --git a/modules/gdscript/gd_functions.h b/modules/gdscript/gd_functions.h index 340763fb8c2c..05ff6a2e737d 100644 --- a/modules/gdscript/gd_functions.h +++ b/modules/gdscript/gd_functions.h @@ -85,6 +85,8 @@ public: TEXT_PRINT_TABBED, TEXT_PRINTERR, TEXT_PRINTRAW, + VAR_TO_STR, + STR_TO_VAR, GEN_RANGE, RESOURCE_LOAD, INST2DICT, diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index ad54a327cfd3..13f2c32e7781 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -1439,7 +1439,6 @@ void OS_Windows::warp_mouse_pos(const Point2& p_to) { SetCursorPos(p.x,p.y); } - } Point2 OS_Windows::get_mouse_pos() const { diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index 570a5b95b0dc..fc69ea8a0d41 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -113,7 +113,7 @@ void NavigationPolygon::clear_outlines(){ } void NavigationPolygon::make_polygons_from_outlines(){ - std::list in_poly,out_poly; + List in_poly,out_poly; Vector2 outside_point(-1e10,-1e10); @@ -194,9 +194,9 @@ void NavigationPolygon::make_polygons_from_outlines(){ vertices.resize(0); Map points; - for(std::list::iterator I = out_poly.begin();I!=out_poly.end();I++) { + for(List::Element*I = out_poly.front();I;I=I->next()) { - TriangulatorPoly& tp = *I; + TriangulatorPoly& tp = I->get(); struct Polygon p;