shape_2d_sw.cpp 23 KB

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