shape_2d_sw.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083
  1. /*************************************************************************/
  2. /* shape_2d_sw.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "shape_2d_sw.h"
  31. #include "core/math/geometry.h"
  32. #include "core/sort.h"
  33. void Shape2DSW::configure(const Rect2 &p_aabb) {
  34. aabb = p_aabb;
  35. configured = true;
  36. for (Map<ShapeOwner2DSW *, int>::Element *E = owners.front(); E; E = E->next()) {
  37. ShapeOwner2DSW *co = (ShapeOwner2DSW *)E->key();
  38. co->_shape_changed();
  39. }
  40. }
  41. Vector2 Shape2DSW::get_support(const Vector2 &p_normal) const {
  42. Vector2 res[2];
  43. int amnt;
  44. get_supports(p_normal, res, amnt);
  45. return res[0];
  46. }
  47. void Shape2DSW::add_owner(ShapeOwner2DSW *p_owner) {
  48. Map<ShapeOwner2DSW *, int>::Element *E = owners.find(p_owner);
  49. if (E) {
  50. E->get()++;
  51. } else {
  52. owners[p_owner] = 1;
  53. }
  54. }
  55. void Shape2DSW::remove_owner(ShapeOwner2DSW *p_owner) {
  56. Map<ShapeOwner2DSW *, int>::Element *E = owners.find(p_owner);
  57. ERR_FAIL_COND(!E);
  58. E->get()--;
  59. if (E->get() == 0) {
  60. owners.erase(E);
  61. }
  62. }
  63. bool Shape2DSW::is_owner(ShapeOwner2DSW *p_owner) const {
  64. return owners.has(p_owner);
  65. }
  66. const Map<ShapeOwner2DSW *, int> &Shape2DSW::get_owners() const {
  67. return owners;
  68. }
  69. Shape2DSW::Shape2DSW() {
  70. custom_bias = 0;
  71. configured = false;
  72. }
  73. Shape2DSW::~Shape2DSW() {
  74. ERR_FAIL_COND(owners.size());
  75. }
  76. /*********************************************************/
  77. /*********************************************************/
  78. /*********************************************************/
  79. void LineShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  80. r_amount = 0;
  81. }
  82. bool LineShape2DSW::contains_point(const Vector2 &p_point) const {
  83. return normal.dot(p_point) < d;
  84. }
  85. bool LineShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  86. Vector2 segment = p_begin - p_end;
  87. real_t den = normal.dot(segment);
  88. //printf("den is %i\n",den);
  89. if (Math::abs(den) <= CMP_EPSILON) {
  90. return false;
  91. }
  92. real_t dist = (normal.dot(p_begin) - d) / den;
  93. //printf("dist is %i\n",dist);
  94. if (dist < -CMP_EPSILON || dist > (1.0 + CMP_EPSILON)) {
  95. return false;
  96. }
  97. r_point = p_begin + segment * -dist;
  98. r_normal = normal;
  99. return true;
  100. }
  101. real_t LineShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  102. return 0;
  103. }
  104. void LineShape2DSW::set_data(const Variant &p_data) {
  105. ERR_FAIL_COND(p_data.get_type() != Variant::ARRAY);
  106. Array arr = p_data;
  107. ERR_FAIL_COND(arr.size() != 2);
  108. normal = arr[0];
  109. d = arr[1];
  110. configure(Rect2(Vector2(-1e4, -1e4), Vector2(1e4 * 2, 1e4 * 2)));
  111. }
  112. Variant LineShape2DSW::get_data() const {
  113. Array arr;
  114. arr.resize(2);
  115. arr[0] = normal;
  116. arr[1] = d;
  117. return arr;
  118. }
  119. /*********************************************************/
  120. /*********************************************************/
  121. /*********************************************************/
  122. void RayShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  123. r_amount = 1;
  124. if (p_normal.y > 0)
  125. *r_supports = Vector2(0, length);
  126. else
  127. *r_supports = Vector2();
  128. }
  129. bool RayShape2DSW::contains_point(const Vector2 &p_point) const {
  130. return false;
  131. }
  132. bool RayShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  133. return false; //rays can't be intersected
  134. }
  135. real_t RayShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  136. return 0; //rays are mass-less
  137. }
  138. void RayShape2DSW::set_data(const Variant &p_data) {
  139. Dictionary d = p_data;
  140. length = d["length"];
  141. slips_on_slope = d["slips_on_slope"];
  142. configure(Rect2(0, 0, 0.001, length));
  143. }
  144. Variant RayShape2DSW::get_data() const {
  145. Dictionary d;
  146. d["length"] = length;
  147. d["slips_on_slope"] = slips_on_slope;
  148. return d;
  149. }
  150. /*********************************************************/
  151. /*********************************************************/
  152. /*********************************************************/
  153. void SegmentShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  154. if (Math::abs(p_normal.dot(n)) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
  155. r_supports[0] = a;
  156. r_supports[1] = b;
  157. r_amount = 2;
  158. return;
  159. }
  160. real_t dp = p_normal.dot(b - a);
  161. if (dp > 0)
  162. *r_supports = b;
  163. else
  164. *r_supports = a;
  165. r_amount = 1;
  166. }
  167. bool SegmentShape2DSW::contains_point(const Vector2 &p_point) const {
  168. return false;
  169. }
  170. bool SegmentShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  171. if (!Geometry::segment_intersects_segment_2d(p_begin, p_end, a, b, &r_point))
  172. return false;
  173. if (n.dot(p_begin) > n.dot(a)) {
  174. r_normal = n;
  175. } else {
  176. r_normal = -n;
  177. }
  178. return true;
  179. }
  180. real_t SegmentShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  181. Vector2 s[2] = { a * p_scale, b * p_scale };
  182. real_t l = s[1].distance_to(s[0]);
  183. Vector2 ofs = (s[0] + s[1]) * 0.5;
  184. return p_mass * (l * l / 12.0 + ofs.length_squared());
  185. }
  186. void SegmentShape2DSW::set_data(const Variant &p_data) {
  187. ERR_FAIL_COND(p_data.get_type() != Variant::RECT2);
  188. Rect2 r = p_data;
  189. a = r.position;
  190. b = r.size;
  191. n = (b - a).tangent();
  192. Rect2 aabb;
  193. aabb.position = a;
  194. aabb.expand_to(b);
  195. if (aabb.size.x == 0)
  196. aabb.size.x = 0.001;
  197. if (aabb.size.y == 0)
  198. aabb.size.y = 0.001;
  199. configure(aabb);
  200. }
  201. Variant SegmentShape2DSW::get_data() const {
  202. Rect2 r;
  203. r.position = a;
  204. r.size = b;
  205. return r;
  206. }
  207. /*********************************************************/
  208. /*********************************************************/
  209. /*********************************************************/
  210. void CircleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  211. r_amount = 1;
  212. *r_supports = p_normal * radius;
  213. }
  214. bool CircleShape2DSW::contains_point(const Vector2 &p_point) const {
  215. return p_point.length_squared() < radius * radius;
  216. }
  217. bool CircleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  218. Vector2 line_vec = p_end - p_begin;
  219. real_t a, b, c;
  220. a = line_vec.dot(line_vec);
  221. b = 2 * p_begin.dot(line_vec);
  222. c = p_begin.dot(p_begin) - radius * radius;
  223. real_t sqrtterm = b * b - 4 * a * c;
  224. if (sqrtterm < 0)
  225. return false;
  226. sqrtterm = Math::sqrt(sqrtterm);
  227. real_t res = (-b - sqrtterm) / (2 * a);
  228. if (res < 0 || res > 1 + CMP_EPSILON) {
  229. return false;
  230. }
  231. r_point = p_begin + line_vec * res;
  232. r_normal = r_point.normalized();
  233. return true;
  234. }
  235. real_t CircleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  236. return (radius * radius) * (p_scale.x * 0.5 + p_scale.y * 0.5);
  237. }
  238. void CircleShape2DSW::set_data(const Variant &p_data) {
  239. ERR_FAIL_COND(!p_data.is_num());
  240. radius = p_data;
  241. configure(Rect2(-radius, -radius, radius * 2, radius * 2));
  242. }
  243. Variant CircleShape2DSW::get_data() const {
  244. return radius;
  245. }
  246. /*********************************************************/
  247. /*********************************************************/
  248. /*********************************************************/
  249. void RectangleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  250. for (int i = 0; i < 2; i++) {
  251. Vector2 ag;
  252. ag[i] = 1.0;
  253. real_t dp = ag.dot(p_normal);
  254. if (Math::abs(dp) < _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)
  255. continue;
  256. real_t sgn = dp > 0 ? 1.0 : -1.0;
  257. r_amount = 2;
  258. r_supports[0][i] = half_extents[i] * sgn;
  259. r_supports[0][i ^ 1] = half_extents[i ^ 1];
  260. r_supports[1][i] = half_extents[i] * sgn;
  261. r_supports[1][i ^ 1] = -half_extents[i ^ 1];
  262. return;
  263. }
  264. /* USE POINT */
  265. r_amount = 1;
  266. r_supports[0] = Vector2(
  267. (p_normal.x < 0) ? -half_extents.x : half_extents.x,
  268. (p_normal.y < 0) ? -half_extents.y : half_extents.y);
  269. }
  270. bool RectangleShape2DSW::contains_point(const Vector2 &p_point) const {
  271. return Math::abs(p_point.x) < half_extents.x && Math::abs(p_point.y) < half_extents.y;
  272. }
  273. bool RectangleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  274. return get_aabb().intersects_segment(p_begin, p_end, &r_point, &r_normal);
  275. }
  276. real_t RectangleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  277. Vector2 he2 = half_extents * 2 * p_scale;
  278. return p_mass * he2.dot(he2) / 12.0;
  279. }
  280. void RectangleShape2DSW::set_data(const Variant &p_data) {
  281. ERR_FAIL_COND(p_data.get_type() != Variant::VECTOR2);
  282. half_extents = p_data;
  283. configure(Rect2(-half_extents, half_extents * 2.0));
  284. }
  285. Variant RectangleShape2DSW::get_data() const {
  286. return half_extents;
  287. }
  288. /*********************************************************/
  289. /*********************************************************/
  290. /*********************************************************/
  291. void CapsuleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  292. Vector2 n = p_normal;
  293. real_t d = n.y;
  294. if (Math::abs(d) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) {
  295. // make it flat
  296. n.y = 0.0;
  297. n.normalize();
  298. n *= radius;
  299. r_amount = 2;
  300. r_supports[0] = n;
  301. r_supports[0].y += height * 0.5;
  302. r_supports[1] = n;
  303. r_supports[1].y -= height * 0.5;
  304. } else {
  305. real_t h = (d > 0) ? height : -height;
  306. n *= radius;
  307. n.y += h * 0.5;
  308. r_amount = 1;
  309. *r_supports = n;
  310. }
  311. }
  312. bool CapsuleShape2DSW::contains_point(const Vector2 &p_point) const {
  313. Vector2 p = p_point;
  314. p.y = Math::abs(p.y);
  315. p.y -= height * 0.5;
  316. if (p.y < 0)
  317. p.y = 0;
  318. return p.length_squared() < radius * radius;
  319. }
  320. bool CapsuleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  321. real_t d = 1e10;
  322. Vector2 n = (p_end - p_begin).normalized();
  323. bool collided = false;
  324. //try spheres
  325. for (int i = 0; i < 2; i++) {
  326. Vector2 begin = p_begin;
  327. Vector2 end = p_end;
  328. real_t ofs = (i == 0) ? -height * 0.5 : height * 0.5;
  329. begin.y += ofs;
  330. end.y += ofs;
  331. Vector2 line_vec = end - begin;
  332. real_t a, b, c;
  333. a = line_vec.dot(line_vec);
  334. b = 2 * begin.dot(line_vec);
  335. c = begin.dot(begin) - radius * radius;
  336. real_t sqrtterm = b * b - 4 * a * c;
  337. if (sqrtterm < 0)
  338. continue;
  339. sqrtterm = Math::sqrt(sqrtterm);
  340. real_t res = (-b - sqrtterm) / (2 * a);
  341. if (res < 0 || res > 1 + CMP_EPSILON) {
  342. continue;
  343. }
  344. Vector2 point = begin + line_vec * res;
  345. Vector2 pointf(point.x, point.y - ofs);
  346. real_t pd = n.dot(pointf);
  347. if (pd < d) {
  348. r_point = pointf;
  349. r_normal = point.normalized();
  350. d = pd;
  351. collided = true;
  352. }
  353. }
  354. Vector2 rpos, rnorm;
  355. if (Rect2(Point2(-radius, -height * 0.5), Size2(radius * 2.0, height)).intersects_segment(p_begin, p_end, &rpos, &rnorm)) {
  356. real_t pd = n.dot(rpos);
  357. if (pd < d) {
  358. r_point = rpos;
  359. r_normal = rnorm;
  360. d = pd;
  361. collided = true;
  362. }
  363. }
  364. //return get_aabb().intersects_segment(p_begin,p_end,&r_point,&r_normal);
  365. return collided; //todo
  366. }
  367. real_t CapsuleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  368. Vector2 he2 = Vector2(radius * 2, height + radius * 2) * p_scale;
  369. return p_mass * he2.dot(he2) / 12.0;
  370. }
  371. void CapsuleShape2DSW::set_data(const Variant &p_data) {
  372. ERR_FAIL_COND(p_data.get_type() != Variant::ARRAY && p_data.get_type() != Variant::VECTOR2);
  373. if (p_data.get_type() == Variant::ARRAY) {
  374. Array arr = p_data;
  375. ERR_FAIL_COND(arr.size() != 2);
  376. height = arr[0];
  377. radius = arr[1];
  378. } else {
  379. Point2 p = p_data;
  380. radius = p.x;
  381. height = p.y;
  382. }
  383. Point2 he(radius, height * 0.5 + radius);
  384. configure(Rect2(-he, he * 2));
  385. }
  386. Variant CapsuleShape2DSW::get_data() const {
  387. return Point2(height, radius);
  388. }
  389. /*********************************************************/
  390. /*********************************************************/
  391. /*********************************************************/
  392. void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  393. int support_idx = -1;
  394. real_t d = -1e10;
  395. for (int i = 0; i < point_count; i++) {
  396. //test point
  397. real_t ld = p_normal.dot(points[i].pos);
  398. if (ld > d) {
  399. support_idx = i;
  400. d = ld;
  401. }
  402. //test segment
  403. if (points[i].normal.dot(p_normal) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
  404. r_amount = 2;
  405. r_supports[0] = points[i].pos;
  406. r_supports[1] = points[(i + 1) % point_count].pos;
  407. return;
  408. }
  409. }
  410. ERR_FAIL_COND(support_idx == -1);
  411. r_amount = 1;
  412. r_supports[0] = points[support_idx].pos;
  413. }
  414. bool ConvexPolygonShape2DSW::contains_point(const Vector2 &p_point) const {
  415. bool out = false;
  416. bool in = false;
  417. for (int i = 0; i < point_count; i++) {
  418. real_t d = points[i].normal.dot(p_point) - points[i].normal.dot(points[i].pos);
  419. if (d > 0)
  420. out = true;
  421. else
  422. in = true;
  423. }
  424. return (in && !out) || (!in && out);
  425. }
  426. bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  427. Vector2 n = (p_end - p_begin).normalized();
  428. real_t d = 1e10;
  429. bool inters = false;
  430. for (int i = 0; i < point_count; i++) {
  431. //hmm.. no can do..
  432. /*
  433. if (d.dot(points[i].normal)>=0)
  434. continue;
  435. */
  436. Vector2 res;
  437. if (!Geometry::segment_intersects_segment_2d(p_begin, p_end, points[i].pos, points[(i + 1) % point_count].pos, &res))
  438. continue;
  439. real_t nd = n.dot(res);
  440. if (nd < d) {
  441. d = nd;
  442. r_point = res;
  443. r_normal = points[i].normal;
  444. inters = true;
  445. }
  446. }
  447. if (inters) {
  448. if (n.dot(r_normal) > 0)
  449. r_normal = -r_normal;
  450. }
  451. //return get_aabb().intersects_segment(p_begin,p_end,&r_point,&r_normal);
  452. return inters; //todo
  453. }
  454. real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  455. Rect2 aabb;
  456. aabb.position = points[0].pos * p_scale;
  457. for (int i = 0; i < point_count; i++) {
  458. aabb.expand_to(points[i].pos * p_scale);
  459. }
  460. return p_mass * aabb.size.dot(aabb.size) / 12.0 + p_mass * (aabb.position + aabb.size * 0.5).length_squared();
  461. }
  462. void ConvexPolygonShape2DSW::set_data(const Variant &p_data) {
  463. ERR_FAIL_COND(p_data.get_type() != Variant::POOL_VECTOR2_ARRAY && p_data.get_type() != Variant::POOL_REAL_ARRAY);
  464. if (points)
  465. memdelete_arr(points);
  466. points = NULL;
  467. point_count = 0;
  468. if (p_data.get_type() == Variant::POOL_VECTOR2_ARRAY) {
  469. PoolVector<Vector2> arr = p_data;
  470. ERR_FAIL_COND(arr.size() == 0);
  471. point_count = arr.size();
  472. points = memnew_arr(Point, point_count);
  473. PoolVector<Vector2>::Read r = arr.read();
  474. for (int i = 0; i < point_count; i++) {
  475. points[i].pos = r[i];
  476. }
  477. for (int i = 0; i < point_count; i++) {
  478. Vector2 p = points[i].pos;
  479. Vector2 pn = points[(i + 1) % point_count].pos;
  480. points[i].normal = (pn - p).tangent().normalized();
  481. }
  482. } else {
  483. PoolVector<real_t> dvr = p_data;
  484. point_count = dvr.size() / 4;
  485. ERR_FAIL_COND(point_count == 0);
  486. points = memnew_arr(Point, point_count);
  487. PoolVector<real_t>::Read r = dvr.read();
  488. for (int i = 0; i < point_count; i++) {
  489. int idx = i << 2;
  490. points[i].pos.x = r[idx + 0];
  491. points[i].pos.y = r[idx + 1];
  492. points[i].normal.x = r[idx + 2];
  493. points[i].normal.y = r[idx + 3];
  494. }
  495. }
  496. ERR_FAIL_COND(point_count == 0);
  497. Rect2 aabb;
  498. aabb.position = points[0].pos;
  499. for (int i = 1; i < point_count; i++)
  500. aabb.expand_to(points[i].pos);
  501. configure(aabb);
  502. }
  503. Variant ConvexPolygonShape2DSW::get_data() const {
  504. PoolVector<Vector2> dvr;
  505. dvr.resize(point_count);
  506. for (int i = 0; i < point_count; i++) {
  507. dvr.set(i, points[i].pos);
  508. }
  509. return dvr;
  510. }
  511. ConvexPolygonShape2DSW::ConvexPolygonShape2DSW() {
  512. points = NULL;
  513. point_count = 0;
  514. }
  515. ConvexPolygonShape2DSW::~ConvexPolygonShape2DSW() {
  516. if (points)
  517. memdelete_arr(points);
  518. }
  519. //////////////////////////////////////////////////
  520. void ConcavePolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  521. real_t d = -1e10;
  522. int idx = -1;
  523. for (int i = 0; i < points.size(); i++) {
  524. real_t ld = p_normal.dot(points[i]);
  525. if (ld > d) {
  526. d = ld;
  527. idx = i;
  528. }
  529. }
  530. r_amount = 1;
  531. ERR_FAIL_COND(idx == -1);
  532. *r_supports = points[idx];
  533. }
  534. bool ConcavePolygonShape2DSW::contains_point(const Vector2 &p_point) const {
  535. return false; //sorry
  536. }
  537. bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  538. uint32_t *stack = (uint32_t *)alloca(sizeof(int) * bvh_depth);
  539. enum {
  540. TEST_AABB_BIT = 0,
  541. VISIT_LEFT_BIT = 1,
  542. VISIT_RIGHT_BIT = 2,
  543. VISIT_DONE_BIT = 3,
  544. VISITED_BIT_SHIFT = 29,
  545. NODE_IDX_MASK = (1 << VISITED_BIT_SHIFT) - 1,
  546. VISITED_BIT_MASK = ~NODE_IDX_MASK,
  547. };
  548. Vector2 n = (p_end - p_begin).normalized();
  549. real_t d = 1e10;
  550. bool inters = false;
  551. /*
  552. for(int i=0;i<bvh_depth;i++)
  553. stack[i]=0;
  554. */
  555. int level = 0;
  556. const Segment *segmentptr = &segments[0];
  557. const Vector2 *pointptr = &points[0];
  558. const BVH *bvhptr = &bvh[0];
  559. stack[0] = 0;
  560. while (true) {
  561. uint32_t node = stack[level] & NODE_IDX_MASK;
  562. const BVH &b = bvhptr[node];
  563. bool done = false;
  564. switch (stack[level] >> VISITED_BIT_SHIFT) {
  565. case TEST_AABB_BIT: {
  566. bool valid = b.aabb.intersects_segment(p_begin, p_end);
  567. if (!valid) {
  568. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  569. } else {
  570. if (b.left < 0) {
  571. const Segment &s = segmentptr[b.right];
  572. Vector2 a = pointptr[s.points[0]];
  573. Vector2 b = pointptr[s.points[1]];
  574. Vector2 res;
  575. if (Geometry::segment_intersects_segment_2d(p_begin, p_end, a, b, &res)) {
  576. real_t nd = n.dot(res);
  577. if (nd < d) {
  578. d = nd;
  579. r_point = res;
  580. r_normal = (b - a).tangent().normalized();
  581. inters = true;
  582. }
  583. }
  584. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  585. } else {
  586. stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
  587. }
  588. }
  589. }
  590. continue;
  591. case VISIT_LEFT_BIT: {
  592. stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
  593. stack[level + 1] = b.left | TEST_AABB_BIT;
  594. level++;
  595. }
  596. continue;
  597. case VISIT_RIGHT_BIT: {
  598. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  599. stack[level + 1] = b.right | TEST_AABB_BIT;
  600. level++;
  601. }
  602. continue;
  603. case VISIT_DONE_BIT: {
  604. if (level == 0) {
  605. done = true;
  606. break;
  607. } else
  608. level--;
  609. }
  610. continue;
  611. }
  612. if (done)
  613. break;
  614. }
  615. if (inters) {
  616. if (n.dot(r_normal) > 0)
  617. r_normal = -r_normal;
  618. }
  619. return inters;
  620. }
  621. int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) {
  622. if (p_len == 1) {
  623. bvh_depth = MAX(p_depth, bvh_depth);
  624. bvh.push_back(*p_bvh);
  625. return bvh.size() - 1;
  626. }
  627. //else sort best
  628. Rect2 global_aabb = p_bvh[0].aabb;
  629. for (int i = 1; i < p_len; i++) {
  630. global_aabb = global_aabb.merge(p_bvh[i].aabb);
  631. }
  632. if (global_aabb.size.x > global_aabb.size.y) {
  633. SortArray<BVH, BVH_CompareX> sort;
  634. sort.sort(p_bvh, p_len);
  635. } else {
  636. SortArray<BVH, BVH_CompareY> sort;
  637. sort.sort(p_bvh, p_len);
  638. }
  639. int median = p_len / 2;
  640. BVH node;
  641. node.aabb = global_aabb;
  642. int node_idx = bvh.size();
  643. bvh.push_back(node);
  644. int l = _generate_bvh(p_bvh, median, p_depth + 1);
  645. int r = _generate_bvh(&p_bvh[median], p_len - median, p_depth + 1);
  646. bvh.write[node_idx].left = l;
  647. bvh.write[node_idx].right = r;
  648. return node_idx;
  649. }
  650. void ConcavePolygonShape2DSW::set_data(const Variant &p_data) {
  651. ERR_FAIL_COND(p_data.get_type() != Variant::POOL_VECTOR2_ARRAY && p_data.get_type() != Variant::POOL_REAL_ARRAY);
  652. Rect2 aabb;
  653. if (p_data.get_type() == Variant::POOL_VECTOR2_ARRAY) {
  654. PoolVector<Vector2> p2arr = p_data;
  655. int len = p2arr.size();
  656. ERR_FAIL_COND(len % 2);
  657. segments.clear();
  658. points.clear();
  659. bvh.clear();
  660. bvh_depth = 1;
  661. if (len == 0) {
  662. configure(aabb);
  663. return;
  664. }
  665. PoolVector<Vector2>::Read arr = p2arr.read();
  666. Map<Point2, int> pointmap;
  667. for (int i = 0; i < len; i += 2) {
  668. Point2 p1 = arr[i];
  669. Point2 p2 = arr[i + 1];
  670. int idx_p1, idx_p2;
  671. if (pointmap.has(p1)) {
  672. idx_p1 = pointmap[p1];
  673. } else {
  674. idx_p1 = pointmap.size();
  675. pointmap[p1] = idx_p1;
  676. }
  677. if (pointmap.has(p2)) {
  678. idx_p2 = pointmap[p2];
  679. } else {
  680. idx_p2 = pointmap.size();
  681. pointmap[p2] = idx_p2;
  682. }
  683. Segment s;
  684. s.points[0] = idx_p1;
  685. s.points[1] = idx_p2;
  686. segments.push_back(s);
  687. }
  688. points.resize(pointmap.size());
  689. aabb.position = pointmap.front()->key();
  690. for (Map<Point2, int>::Element *E = pointmap.front(); E; E = E->next()) {
  691. aabb.expand_to(E->key());
  692. points.write[E->get()] = E->key();
  693. }
  694. Vector<BVH> main_vbh;
  695. main_vbh.resize(segments.size());
  696. for (int i = 0; i < main_vbh.size(); i++) {
  697. main_vbh.write[i].aabb.position = points[segments[i].points[0]];
  698. main_vbh.write[i].aabb.expand_to(points[segments[i].points[1]]);
  699. main_vbh.write[i].left = -1;
  700. main_vbh.write[i].right = i;
  701. }
  702. _generate_bvh(main_vbh.ptrw(), main_vbh.size(), 1);
  703. } else {
  704. //dictionary with arrays
  705. }
  706. configure(aabb);
  707. }
  708. Variant ConcavePolygonShape2DSW::get_data() const {
  709. PoolVector<Vector2> rsegments;
  710. int len = segments.size();
  711. rsegments.resize(len * 2);
  712. PoolVector<Vector2>::Write w = rsegments.write();
  713. for (int i = 0; i < len; i++) {
  714. w[(i << 1) + 0] = points[segments[i].points[0]];
  715. w[(i << 1) + 1] = points[segments[i].points[1]];
  716. }
  717. w = PoolVector<Vector2>::Write();
  718. return rsegments;
  719. }
  720. void ConcavePolygonShape2DSW::cull(const Rect2 &p_local_aabb, Callback p_callback, void *p_userdata) const {
  721. uint32_t *stack = (uint32_t *)alloca(sizeof(int) * bvh_depth);
  722. enum {
  723. TEST_AABB_BIT = 0,
  724. VISIT_LEFT_BIT = 1,
  725. VISIT_RIGHT_BIT = 2,
  726. VISIT_DONE_BIT = 3,
  727. VISITED_BIT_SHIFT = 29,
  728. NODE_IDX_MASK = (1 << VISITED_BIT_SHIFT) - 1,
  729. VISITED_BIT_MASK = ~NODE_IDX_MASK,
  730. };
  731. /*
  732. for(int i=0;i<bvh_depth;i++)
  733. stack[i]=0;
  734. */
  735. if (segments.size() == 0 || points.size() == 0 || bvh.size() == 0) {
  736. return;
  737. }
  738. int level = 0;
  739. const Segment *segmentptr = &segments[0];
  740. const Vector2 *pointptr = &points[0];
  741. const BVH *bvhptr = &bvh[0];
  742. stack[0] = 0;
  743. while (true) {
  744. uint32_t node = stack[level] & NODE_IDX_MASK;
  745. const BVH &b = bvhptr[node];
  746. switch (stack[level] >> VISITED_BIT_SHIFT) {
  747. case TEST_AABB_BIT: {
  748. bool valid = p_local_aabb.intersects(b.aabb);
  749. if (!valid) {
  750. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  751. } else {
  752. if (b.left < 0) {
  753. const Segment &s = segmentptr[b.right];
  754. Vector2 a = pointptr[s.points[0]];
  755. Vector2 b = pointptr[s.points[1]];
  756. SegmentShape2DSW ss(a, b, (b - a).tangent().normalized());
  757. p_callback(p_userdata, &ss);
  758. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  759. } else {
  760. stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
  761. }
  762. }
  763. }
  764. continue;
  765. case VISIT_LEFT_BIT: {
  766. stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
  767. stack[level + 1] = b.left | TEST_AABB_BIT;
  768. level++;
  769. }
  770. continue;
  771. case VISIT_RIGHT_BIT: {
  772. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  773. stack[level + 1] = b.right | TEST_AABB_BIT;
  774. level++;
  775. }
  776. continue;
  777. case VISIT_DONE_BIT: {
  778. if (level == 0)
  779. return;
  780. else
  781. level--;
  782. }
  783. continue;
  784. }
  785. }
  786. }