shape_2d_sw.cpp 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  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-2021 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2021 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_2d.h"
  32. #include "core/templates/sort_array.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. }
  130. bool RayShape2DSW::contains_point(const Vector2 &p_point) const {
  131. return false;
  132. }
  133. bool RayShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  134. return false; //rays can't be intersected
  135. }
  136. real_t RayShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  137. return 0; //rays are mass-less
  138. }
  139. void RayShape2DSW::set_data(const Variant &p_data) {
  140. Dictionary d = p_data;
  141. length = d["length"];
  142. slips_on_slope = d["slips_on_slope"];
  143. configure(Rect2(0, 0, 0.001, length));
  144. }
  145. Variant RayShape2DSW::get_data() const {
  146. Dictionary d;
  147. d["length"] = length;
  148. d["slips_on_slope"] = slips_on_slope;
  149. return d;
  150. }
  151. /*********************************************************/
  152. /*********************************************************/
  153. /*********************************************************/
  154. void SegmentShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  155. if (Math::abs(p_normal.dot(n)) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
  156. r_supports[0] = a;
  157. r_supports[1] = b;
  158. r_amount = 2;
  159. return;
  160. }
  161. real_t dp = p_normal.dot(b - a);
  162. if (dp > 0) {
  163. *r_supports = b;
  164. } else {
  165. *r_supports = a;
  166. }
  167. r_amount = 1;
  168. }
  169. bool SegmentShape2DSW::contains_point(const Vector2 &p_point) const {
  170. return false;
  171. }
  172. bool SegmentShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  173. if (!Geometry2D::segment_intersects_segment(p_begin, p_end, a, b, &r_point)) {
  174. return false;
  175. }
  176. if (n.dot(p_begin) > n.dot(a)) {
  177. r_normal = n;
  178. } else {
  179. r_normal = -n;
  180. }
  181. return true;
  182. }
  183. real_t SegmentShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  184. return p_mass * ((a * p_scale).distance_squared_to(b * p_scale)) / 12;
  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).orthogonal();
  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. }
  198. if (aabb.size.y == 0) {
  199. aabb.size.y = 0.001;
  200. }
  201. configure(aabb);
  202. }
  203. Variant SegmentShape2DSW::get_data() const {
  204. Rect2 r;
  205. r.position = a;
  206. r.size = b;
  207. return r;
  208. }
  209. /*********************************************************/
  210. /*********************************************************/
  211. /*********************************************************/
  212. void CircleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  213. r_amount = 1;
  214. *r_supports = p_normal * radius;
  215. }
  216. bool CircleShape2DSW::contains_point(const Vector2 &p_point) const {
  217. return p_point.length_squared() < radius * radius;
  218. }
  219. bool CircleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  220. Vector2 line_vec = p_end - p_begin;
  221. real_t a, b, c;
  222. a = line_vec.dot(line_vec);
  223. b = 2 * p_begin.dot(line_vec);
  224. c = p_begin.dot(p_begin) - radius * radius;
  225. real_t sqrtterm = b * b - 4 * a * c;
  226. if (sqrtterm < 0) {
  227. return false;
  228. }
  229. sqrtterm = Math::sqrt(sqrtterm);
  230. real_t res = (-b - sqrtterm) / (2 * a);
  231. if (res < 0 || res > 1 + CMP_EPSILON) {
  232. return false;
  233. }
  234. r_point = p_begin + line_vec * res;
  235. r_normal = r_point.normalized();
  236. return true;
  237. }
  238. real_t CircleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  239. real_t a = radius * p_scale.x;
  240. real_t b = radius * p_scale.y;
  241. return p_mass * (a * a + b * b) / 4;
  242. }
  243. void CircleShape2DSW::set_data(const Variant &p_data) {
  244. ERR_FAIL_COND(!p_data.is_num());
  245. radius = p_data;
  246. configure(Rect2(-radius, -radius, radius * 2, radius * 2));
  247. }
  248. Variant CircleShape2DSW::get_data() const {
  249. return radius;
  250. }
  251. /*********************************************************/
  252. /*********************************************************/
  253. /*********************************************************/
  254. void RectangleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  255. for (int i = 0; i < 2; i++) {
  256. Vector2 ag;
  257. ag[i] = 1.0;
  258. real_t dp = ag.dot(p_normal);
  259. if (Math::abs(dp) < _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
  260. continue;
  261. }
  262. real_t sgn = dp > 0 ? 1.0 : -1.0;
  263. r_amount = 2;
  264. r_supports[0][i] = half_extents[i] * sgn;
  265. r_supports[0][i ^ 1] = half_extents[i ^ 1];
  266. r_supports[1][i] = half_extents[i] * sgn;
  267. r_supports[1][i ^ 1] = -half_extents[i ^ 1];
  268. return;
  269. }
  270. /* USE POINT */
  271. r_amount = 1;
  272. r_supports[0] = Vector2(
  273. (p_normal.x < 0) ? -half_extents.x : half_extents.x,
  274. (p_normal.y < 0) ? -half_extents.y : half_extents.y);
  275. }
  276. bool RectangleShape2DSW::contains_point(const Vector2 &p_point) const {
  277. real_t x = p_point.x;
  278. real_t y = p_point.y;
  279. real_t edge_x = half_extents.x;
  280. real_t edge_y = half_extents.y;
  281. return (x >= -edge_x) && (x < edge_x) && (y >= -edge_y) && (y < edge_y);
  282. }
  283. bool RectangleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  284. return get_aabb().intersects_segment(p_begin, p_end, &r_point, &r_normal);
  285. }
  286. real_t RectangleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  287. Vector2 he2 = half_extents * 2 * p_scale;
  288. return p_mass * he2.dot(he2) / 12.0;
  289. }
  290. void RectangleShape2DSW::set_data(const Variant &p_data) {
  291. ERR_FAIL_COND(p_data.get_type() != Variant::VECTOR2);
  292. half_extents = p_data;
  293. configure(Rect2(-half_extents, half_extents * 2.0));
  294. }
  295. Variant RectangleShape2DSW::get_data() const {
  296. return half_extents;
  297. }
  298. /*********************************************************/
  299. /*********************************************************/
  300. /*********************************************************/
  301. void CapsuleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  302. Vector2 n = p_normal;
  303. real_t d = n.y;
  304. if (Math::abs(d) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) {
  305. // make it flat
  306. n.y = 0.0;
  307. n.normalize();
  308. n *= radius;
  309. r_amount = 2;
  310. r_supports[0] = n;
  311. r_supports[0].y += height * 0.5;
  312. r_supports[1] = n;
  313. r_supports[1].y -= height * 0.5;
  314. } else {
  315. real_t h = (d > 0) ? height : -height;
  316. n *= radius;
  317. n.y += h * 0.5;
  318. r_amount = 1;
  319. *r_supports = n;
  320. }
  321. }
  322. bool CapsuleShape2DSW::contains_point(const Vector2 &p_point) const {
  323. Vector2 p = p_point;
  324. p.y = Math::abs(p.y);
  325. p.y -= height * 0.5;
  326. if (p.y < 0) {
  327. p.y = 0;
  328. }
  329. return p.length_squared() < radius * radius;
  330. }
  331. bool CapsuleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  332. real_t d = 1e10;
  333. Vector2 n = (p_end - p_begin).normalized();
  334. bool collided = false;
  335. //try spheres
  336. for (int i = 0; i < 2; i++) {
  337. Vector2 begin = p_begin;
  338. Vector2 end = p_end;
  339. real_t ofs = (i == 0) ? -height * 0.5 : height * 0.5;
  340. begin.y += ofs;
  341. end.y += ofs;
  342. Vector2 line_vec = end - begin;
  343. real_t a, b, c;
  344. a = line_vec.dot(line_vec);
  345. b = 2 * begin.dot(line_vec);
  346. c = begin.dot(begin) - radius * radius;
  347. real_t sqrtterm = b * b - 4 * a * c;
  348. if (sqrtterm < 0) {
  349. continue;
  350. }
  351. sqrtterm = Math::sqrt(sqrtterm);
  352. real_t res = (-b - sqrtterm) / (2 * a);
  353. if (res < 0 || res > 1 + CMP_EPSILON) {
  354. continue;
  355. }
  356. Vector2 point = begin + line_vec * res;
  357. Vector2 pointf(point.x, point.y - ofs);
  358. real_t pd = n.dot(pointf);
  359. if (pd < d) {
  360. r_point = pointf;
  361. r_normal = point.normalized();
  362. d = pd;
  363. collided = true;
  364. }
  365. }
  366. Vector2 rpos, rnorm;
  367. if (Rect2(Point2(-radius, -height * 0.5), Size2(radius * 2.0, height)).intersects_segment(p_begin, p_end, &rpos, &rnorm)) {
  368. real_t pd = n.dot(rpos);
  369. if (pd < d) {
  370. r_point = rpos;
  371. r_normal = rnorm;
  372. d = pd;
  373. collided = true;
  374. }
  375. }
  376. //return get_aabb().intersects_segment(p_begin,p_end,&r_point,&r_normal);
  377. return collided; //todo
  378. }
  379. real_t CapsuleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  380. Vector2 he2 = Vector2(radius * 2, height + radius * 2) * p_scale;
  381. return p_mass * he2.dot(he2) / 12.0;
  382. }
  383. void CapsuleShape2DSW::set_data(const Variant &p_data) {
  384. ERR_FAIL_COND(p_data.get_type() != Variant::ARRAY && p_data.get_type() != Variant::VECTOR2);
  385. if (p_data.get_type() == Variant::ARRAY) {
  386. Array arr = p_data;
  387. ERR_FAIL_COND(arr.size() != 2);
  388. height = arr[0];
  389. radius = arr[1];
  390. } else {
  391. Point2 p = p_data;
  392. radius = p.x;
  393. height = p.y;
  394. }
  395. Point2 he(radius, height * 0.5 + radius);
  396. configure(Rect2(-he, he * 2));
  397. }
  398. Variant CapsuleShape2DSW::get_data() const {
  399. return Point2(height, radius);
  400. }
  401. /*********************************************************/
  402. /*********************************************************/
  403. /*********************************************************/
  404. void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  405. int support_idx = -1;
  406. real_t d = -1e10;
  407. for (int i = 0; i < point_count; i++) {
  408. //test point
  409. real_t ld = p_normal.dot(points[i].pos);
  410. if (ld > d) {
  411. support_idx = i;
  412. d = ld;
  413. }
  414. //test segment
  415. if (points[i].normal.dot(p_normal) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
  416. r_amount = 2;
  417. r_supports[0] = points[i].pos;
  418. r_supports[1] = points[(i + 1) % point_count].pos;
  419. return;
  420. }
  421. }
  422. ERR_FAIL_COND(support_idx == -1);
  423. r_amount = 1;
  424. r_supports[0] = points[support_idx].pos;
  425. }
  426. bool ConvexPolygonShape2DSW::contains_point(const Vector2 &p_point) const {
  427. bool out = false;
  428. bool in = false;
  429. for (int i = 0; i < point_count; i++) {
  430. real_t d = points[i].normal.dot(p_point) - points[i].normal.dot(points[i].pos);
  431. if (d > 0) {
  432. out = true;
  433. } else {
  434. in = true;
  435. }
  436. }
  437. return in != out;
  438. }
  439. bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  440. Vector2 n = (p_end - p_begin).normalized();
  441. real_t d = 1e10;
  442. bool inters = false;
  443. for (int i = 0; i < point_count; i++) {
  444. //hmm.. no can do..
  445. /*
  446. if (d.dot(points[i].normal)>=0)
  447. continue;
  448. */
  449. Vector2 res;
  450. if (!Geometry2D::segment_intersects_segment(p_begin, p_end, points[i].pos, points[(i + 1) % point_count].pos, &res)) {
  451. continue;
  452. }
  453. real_t nd = n.dot(res);
  454. if (nd < d) {
  455. d = nd;
  456. r_point = res;
  457. r_normal = points[i].normal;
  458. inters = true;
  459. }
  460. }
  461. if (inters) {
  462. if (n.dot(r_normal) > 0) {
  463. r_normal = -r_normal;
  464. }
  465. }
  466. //return get_aabb().intersects_segment(p_begin,p_end,&r_point,&r_normal);
  467. return inters; //todo
  468. }
  469. real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
  470. Rect2 aabb;
  471. aabb.position = points[0].pos * p_scale;
  472. for (int i = 0; i < point_count; i++) {
  473. aabb.expand_to(points[i].pos * p_scale);
  474. }
  475. return p_mass * aabb.size.dot(aabb.size) / 12.0;
  476. }
  477. void ConvexPolygonShape2DSW::set_data(const Variant &p_data) {
  478. #ifdef REAL_T_IS_DOUBLE
  479. ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT64_ARRAY);
  480. #else
  481. ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT32_ARRAY);
  482. #endif
  483. if (points) {
  484. memdelete_arr(points);
  485. }
  486. points = nullptr;
  487. point_count = 0;
  488. if (p_data.get_type() == Variant::PACKED_VECTOR2_ARRAY) {
  489. Vector<Vector2> arr = p_data;
  490. ERR_FAIL_COND(arr.size() == 0);
  491. point_count = arr.size();
  492. points = memnew_arr(Point, point_count);
  493. const Vector2 *r = arr.ptr();
  494. for (int i = 0; i < point_count; i++) {
  495. points[i].pos = r[i];
  496. }
  497. for (int i = 0; i < point_count; i++) {
  498. Vector2 p = points[i].pos;
  499. Vector2 pn = points[(i + 1) % point_count].pos;
  500. points[i].normal = (pn - p).orthogonal().normalized();
  501. }
  502. } else {
  503. Vector<real_t> dvr = p_data;
  504. point_count = dvr.size() / 4;
  505. ERR_FAIL_COND(point_count == 0);
  506. points = memnew_arr(Point, point_count);
  507. const real_t *r = dvr.ptr();
  508. for (int i = 0; i < point_count; i++) {
  509. int idx = i << 2;
  510. points[i].pos.x = r[idx + 0];
  511. points[i].pos.y = r[idx + 1];
  512. points[i].normal.x = r[idx + 2];
  513. points[i].normal.y = r[idx + 3];
  514. }
  515. }
  516. ERR_FAIL_COND(point_count == 0);
  517. Rect2 aabb;
  518. aabb.position = points[0].pos;
  519. for (int i = 1; i < point_count; i++) {
  520. aabb.expand_to(points[i].pos);
  521. }
  522. configure(aabb);
  523. }
  524. Variant ConvexPolygonShape2DSW::get_data() const {
  525. Vector<Vector2> dvr;
  526. dvr.resize(point_count);
  527. for (int i = 0; i < point_count; i++) {
  528. dvr.set(i, points[i].pos);
  529. }
  530. return dvr;
  531. }
  532. ConvexPolygonShape2DSW::ConvexPolygonShape2DSW() {
  533. points = nullptr;
  534. point_count = 0;
  535. }
  536. ConvexPolygonShape2DSW::~ConvexPolygonShape2DSW() {
  537. if (points) {
  538. memdelete_arr(points);
  539. }
  540. }
  541. //////////////////////////////////////////////////
  542. void ConcavePolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
  543. real_t d = -1e10;
  544. int idx = -1;
  545. for (int i = 0; i < points.size(); i++) {
  546. real_t ld = p_normal.dot(points[i]);
  547. if (ld > d) {
  548. d = ld;
  549. idx = i;
  550. }
  551. }
  552. r_amount = 1;
  553. ERR_FAIL_COND(idx == -1);
  554. *r_supports = points[idx];
  555. }
  556. bool ConcavePolygonShape2DSW::contains_point(const Vector2 &p_point) const {
  557. return false; //sorry
  558. }
  559. bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
  560. uint32_t *stack = (uint32_t *)alloca(sizeof(int) * bvh_depth);
  561. enum {
  562. TEST_AABB_BIT = 0,
  563. VISIT_LEFT_BIT = 1,
  564. VISIT_RIGHT_BIT = 2,
  565. VISIT_DONE_BIT = 3,
  566. VISITED_BIT_SHIFT = 29,
  567. NODE_IDX_MASK = (1 << VISITED_BIT_SHIFT) - 1,
  568. VISITED_BIT_MASK = ~NODE_IDX_MASK,
  569. };
  570. Vector2 n = (p_end - p_begin).normalized();
  571. real_t d = 1e10;
  572. bool inters = false;
  573. /*
  574. for(int i=0;i<bvh_depth;i++)
  575. stack[i]=0;
  576. */
  577. int level = 0;
  578. const Segment *segmentptr = &segments[0];
  579. const Vector2 *pointptr = &points[0];
  580. const BVH *bvhptr = &bvh[0];
  581. stack[0] = 0;
  582. while (true) {
  583. uint32_t node = stack[level] & NODE_IDX_MASK;
  584. const BVH &bvh = bvhptr[node];
  585. bool done = false;
  586. switch (stack[level] >> VISITED_BIT_SHIFT) {
  587. case TEST_AABB_BIT: {
  588. bool valid = bvh.aabb.intersects_segment(p_begin, p_end);
  589. if (!valid) {
  590. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  591. } else {
  592. if (bvh.left < 0) {
  593. const Segment &s = segmentptr[bvh.right];
  594. Vector2 a = pointptr[s.points[0]];
  595. Vector2 b = pointptr[s.points[1]];
  596. Vector2 res;
  597. if (Geometry2D::segment_intersects_segment(p_begin, p_end, a, b, &res)) {
  598. real_t nd = n.dot(res);
  599. if (nd < d) {
  600. d = nd;
  601. r_point = res;
  602. r_normal = (b - a).orthogonal().normalized();
  603. inters = true;
  604. }
  605. }
  606. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  607. } else {
  608. stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
  609. }
  610. }
  611. }
  612. continue;
  613. case VISIT_LEFT_BIT: {
  614. stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
  615. stack[level + 1] = bvh.left | TEST_AABB_BIT;
  616. level++;
  617. }
  618. continue;
  619. case VISIT_RIGHT_BIT: {
  620. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  621. stack[level + 1] = bvh.right | TEST_AABB_BIT;
  622. level++;
  623. }
  624. continue;
  625. case VISIT_DONE_BIT: {
  626. if (level == 0) {
  627. done = true;
  628. break;
  629. } else {
  630. level--;
  631. }
  632. }
  633. continue;
  634. }
  635. if (done) {
  636. break;
  637. }
  638. }
  639. if (inters) {
  640. if (n.dot(r_normal) > 0) {
  641. r_normal = -r_normal;
  642. }
  643. }
  644. return inters;
  645. }
  646. int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) {
  647. if (p_len == 1) {
  648. bvh_depth = MAX(p_depth, bvh_depth);
  649. bvh.push_back(*p_bvh);
  650. return bvh.size() - 1;
  651. }
  652. //else sort best
  653. Rect2 global_aabb = p_bvh[0].aabb;
  654. for (int i = 1; i < p_len; i++) {
  655. global_aabb = global_aabb.merge(p_bvh[i].aabb);
  656. }
  657. if (global_aabb.size.x > global_aabb.size.y) {
  658. SortArray<BVH, BVH_CompareX> sort;
  659. sort.sort(p_bvh, p_len);
  660. } else {
  661. SortArray<BVH, BVH_CompareY> sort;
  662. sort.sort(p_bvh, p_len);
  663. }
  664. int median = p_len / 2;
  665. BVH node;
  666. node.aabb = global_aabb;
  667. int node_idx = bvh.size();
  668. bvh.push_back(node);
  669. int l = _generate_bvh(p_bvh, median, p_depth + 1);
  670. int r = _generate_bvh(&p_bvh[median], p_len - median, p_depth + 1);
  671. bvh.write[node_idx].left = l;
  672. bvh.write[node_idx].right = r;
  673. return node_idx;
  674. }
  675. void ConcavePolygonShape2DSW::set_data(const Variant &p_data) {
  676. #ifdef REAL_T_IS_DOUBLE
  677. ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT64_ARRAY);
  678. #else
  679. ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT32_ARRAY);
  680. #endif
  681. Rect2 aabb;
  682. if (p_data.get_type() == Variant::PACKED_VECTOR2_ARRAY) {
  683. Vector<Vector2> p2arr = p_data;
  684. int len = p2arr.size();
  685. ERR_FAIL_COND(len % 2);
  686. segments.clear();
  687. points.clear();
  688. bvh.clear();
  689. bvh_depth = 1;
  690. if (len == 0) {
  691. configure(aabb);
  692. return;
  693. }
  694. const Vector2 *arr = p2arr.ptr();
  695. Map<Point2, int> pointmap;
  696. for (int i = 0; i < len; i += 2) {
  697. Point2 p1 = arr[i];
  698. Point2 p2 = arr[i + 1];
  699. int idx_p1, idx_p2;
  700. if (pointmap.has(p1)) {
  701. idx_p1 = pointmap[p1];
  702. } else {
  703. idx_p1 = pointmap.size();
  704. pointmap[p1] = idx_p1;
  705. }
  706. if (pointmap.has(p2)) {
  707. idx_p2 = pointmap[p2];
  708. } else {
  709. idx_p2 = pointmap.size();
  710. pointmap[p2] = idx_p2;
  711. }
  712. Segment s;
  713. s.points[0] = idx_p1;
  714. s.points[1] = idx_p2;
  715. segments.push_back(s);
  716. }
  717. points.resize(pointmap.size());
  718. aabb.position = pointmap.front()->key();
  719. for (Map<Point2, int>::Element *E = pointmap.front(); E; E = E->next()) {
  720. aabb.expand_to(E->key());
  721. points.write[E->get()] = E->key();
  722. }
  723. Vector<BVH> main_vbh;
  724. main_vbh.resize(segments.size());
  725. for (int i = 0; i < main_vbh.size(); i++) {
  726. main_vbh.write[i].aabb.position = points[segments[i].points[0]];
  727. main_vbh.write[i].aabb.expand_to(points[segments[i].points[1]]);
  728. main_vbh.write[i].left = -1;
  729. main_vbh.write[i].right = i;
  730. }
  731. _generate_bvh(main_vbh.ptrw(), main_vbh.size(), 1);
  732. } else {
  733. //dictionary with arrays
  734. }
  735. configure(aabb);
  736. }
  737. Variant ConcavePolygonShape2DSW::get_data() const {
  738. Vector<Vector2> rsegments;
  739. int len = segments.size();
  740. rsegments.resize(len * 2);
  741. Vector2 *w = rsegments.ptrw();
  742. for (int i = 0; i < len; i++) {
  743. w[(i << 1) + 0] = points[segments[i].points[0]];
  744. w[(i << 1) + 1] = points[segments[i].points[1]];
  745. }
  746. return rsegments;
  747. }
  748. void ConcavePolygonShape2DSW::cull(const Rect2 &p_local_aabb, Callback p_callback, void *p_userdata) const {
  749. uint32_t *stack = (uint32_t *)alloca(sizeof(int) * bvh_depth);
  750. enum {
  751. TEST_AABB_BIT = 0,
  752. VISIT_LEFT_BIT = 1,
  753. VISIT_RIGHT_BIT = 2,
  754. VISIT_DONE_BIT = 3,
  755. VISITED_BIT_SHIFT = 29,
  756. NODE_IDX_MASK = (1 << VISITED_BIT_SHIFT) - 1,
  757. VISITED_BIT_MASK = ~NODE_IDX_MASK,
  758. };
  759. /*
  760. for(int i=0;i<bvh_depth;i++)
  761. stack[i]=0;
  762. */
  763. if (segments.size() == 0 || points.size() == 0 || bvh.size() == 0) {
  764. return;
  765. }
  766. int level = 0;
  767. const Segment *segmentptr = &segments[0];
  768. const Vector2 *pointptr = &points[0];
  769. const BVH *bvhptr = &bvh[0];
  770. stack[0] = 0;
  771. while (true) {
  772. uint32_t node = stack[level] & NODE_IDX_MASK;
  773. const BVH &bvh = bvhptr[node];
  774. switch (stack[level] >> VISITED_BIT_SHIFT) {
  775. case TEST_AABB_BIT: {
  776. bool valid = p_local_aabb.intersects(bvh.aabb);
  777. if (!valid) {
  778. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  779. } else {
  780. if (bvh.left < 0) {
  781. const Segment &s = segmentptr[bvh.right];
  782. Vector2 a = pointptr[s.points[0]];
  783. Vector2 b = pointptr[s.points[1]];
  784. SegmentShape2DSW ss(a, b, (b - a).orthogonal().normalized());
  785. p_callback(p_userdata, &ss);
  786. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  787. } else {
  788. stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
  789. }
  790. }
  791. }
  792. continue;
  793. case VISIT_LEFT_BIT: {
  794. stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
  795. stack[level + 1] = bvh.left | TEST_AABB_BIT;
  796. level++;
  797. }
  798. continue;
  799. case VISIT_RIGHT_BIT: {
  800. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  801. stack[level + 1] = bvh.right | TEST_AABB_BIT;
  802. level++;
  803. }
  804. continue;
  805. case VISIT_DONE_BIT: {
  806. if (level == 0) {
  807. return;
  808. } else {
  809. level--;
  810. }
  811. }
  812. continue;
  813. }
  814. }
  815. }