godot_shape_2d.cpp 25 KB

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