space_2d_sw.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. /*************************************************************************/
  2. /* space_2d_sw.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2014 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 "space_2d_sw.h"
  30. #include "collision_solver_2d_sw.h"
  31. #include "physics_2d_server_sw.h"
  32. _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_object, uint32_t p_layer_mask, uint32_t p_type_mask) {
  33. if ((p_object->get_layer_mask()&p_layer_mask)==0)
  34. return false;
  35. if (p_object->get_type()==CollisionObject2DSW::TYPE_AREA && !(p_type_mask&Physics2DDirectSpaceState::TYPE_MASK_AREA))
  36. return false;
  37. Body2DSW *body = static_cast<Body2DSW*>(p_object);
  38. return (1<<body->get_mode())&p_type_mask;
  39. }
  40. bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2& p_from, const Vector2& p_to,RayResult &r_result,const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
  41. ERR_FAIL_COND_V(space->locked,false);
  42. Vector2 begin,end;
  43. Vector2 normal;
  44. begin=p_from;
  45. end=p_to;
  46. normal=(end-begin).normalized();
  47. int amount = space->broadphase->cull_segment(begin,end,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results);
  48. //todo, create another array tha references results, compute AABBs and check closest point to ray origin, sort, and stop evaluating results when beyond first collision
  49. bool collided=false;
  50. Vector2 res_point,res_normal;
  51. int res_shape;
  52. const CollisionObject2DSW *res_obj;
  53. real_t min_d=1e10;
  54. for(int i=0;i<amount;i++) {
  55. if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
  56. continue;
  57. if (p_exclude.has( space->intersection_query_results[i]->get_self()))
  58. continue;
  59. const CollisionObject2DSW *col_obj=space->intersection_query_results[i];
  60. int shape_idx=space->intersection_query_subindex_results[i];
  61. Matrix32 inv_xform = col_obj->get_shape_inv_transform(shape_idx) * col_obj->get_inv_transform();
  62. Vector2 local_from = inv_xform.xform(begin);
  63. Vector2 local_to = inv_xform.xform(end);
  64. /*local_from = col_obj->get_inv_transform().xform(begin);
  65. local_from = col_obj->get_shape_inv_transform(shape_idx).xform(local_from);
  66. local_to = col_obj->get_inv_transform().xform(end);
  67. local_to = col_obj->get_shape_inv_transform(shape_idx).xform(local_to);*/
  68. const Shape2DSW *shape = col_obj->get_shape(shape_idx);
  69. Vector2 shape_point,shape_normal;
  70. if (shape->intersect_segment(local_from,local_to,shape_point,shape_normal)) {
  71. //print_line("inters sgment!");
  72. Matrix32 xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
  73. shape_point=xform.xform(shape_point);
  74. real_t ld = normal.dot(shape_point);
  75. if (ld<min_d) {
  76. min_d=ld;
  77. res_point=shape_point;
  78. res_normal=inv_xform.basis_xform_inv(shape_normal).normalized();
  79. res_shape=shape_idx;
  80. res_obj=col_obj;
  81. collided=true;
  82. }
  83. }
  84. }
  85. if (!collided)
  86. return false;
  87. r_result.collider_id=res_obj->get_instance_id();
  88. if (r_result.collider_id!=0)
  89. r_result.collider=ObjectDB::get_instance(r_result.collider_id);
  90. r_result.normal=res_normal;
  91. r_result.metadata=res_obj->get_shape_metadata(res_shape);
  92. r_result.position=res_point;
  93. r_result.rid=res_obj->get_self();
  94. r_result.shape=res_shape;
  95. return true;
  96. }
  97. int Physics2DDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
  98. if (p_result_max<=0)
  99. return 0;
  100. Shape2DSW *shape = static_cast<Physics2DServerSW*>(Physics2DServer::get_singleton())->shape_owner.get(p_shape);
  101. ERR_FAIL_COND_V(!shape,0);
  102. Rect2 aabb = p_xform.xform(shape->get_aabb());
  103. aabb=aabb.grow(p_margin);
  104. int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results);
  105. bool collided=false;
  106. int cc=0;
  107. for(int i=0;i<amount;i++) {
  108. if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
  109. continue;
  110. if (p_exclude.has( space->intersection_query_results[i]->get_self()))
  111. continue;
  112. const CollisionObject2DSW *col_obj=space->intersection_query_results[i];
  113. int shape_idx=space->intersection_query_subindex_results[i];
  114. if (!CollisionSolver2DSW::solve(shape,p_xform,p_motion,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2(),NULL,NULL,NULL,p_margin))
  115. continue;
  116. r_results[cc].collider_id=col_obj->get_instance_id();
  117. if (r_results[cc].collider_id!=0)
  118. r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id);
  119. r_results[cc].rid=col_obj->get_self();
  120. r_results[cc].shape=shape_idx;
  121. r_results[cc].metadata=col_obj->get_shape_metadata(shape_idx);
  122. cc++;
  123. }
  124. return cc;
  125. }
  126. bool Physics2DDirectSpaceStateSW::cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
  127. Shape2DSW *shape = static_cast<Physics2DServerSW*>(Physics2DServer::get_singleton())->shape_owner.get(p_shape);
  128. ERR_FAIL_COND_V(!shape,false);
  129. Rect2 aabb = p_xform.xform(shape->get_aabb());
  130. aabb=aabb.merge(Rect2(aabb.pos+p_motion,aabb.size)); //motion
  131. aabb=aabb.grow(p_margin);
  132. //if (p_motion!=Vector2())
  133. // print_line(p_motion);
  134. int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results);
  135. float best_safe=1;
  136. float best_unsafe=1;
  137. for(int i=0;i<amount;i++) {
  138. if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
  139. continue;
  140. if (p_exclude.has( space->intersection_query_results[i]->get_self()))
  141. continue; //ignore excluded
  142. const CollisionObject2DSW *col_obj=space->intersection_query_results[i];
  143. int shape_idx=space->intersection_query_subindex_results[i];
  144. Matrix32 col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
  145. //test initial overlap, does it collide if going all the way?
  146. if (!CollisionSolver2DSW::solve(shape,p_xform,p_motion,col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL,p_margin)) {
  147. continue;
  148. }
  149. //test initial overlap
  150. if (CollisionSolver2DSW::solve(shape,p_xform,Vector2(),col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL,p_margin)) {
  151. return false;
  152. }
  153. //just do kinematic solving
  154. float low=0;
  155. float hi=1;
  156. Vector2 mnormal=p_motion.normalized();
  157. for(int i=0;i<8;i++) { //steps should be customizable..
  158. Matrix32 xfa = p_xform;
  159. float ofs = (low+hi)*0.5;
  160. Vector2 sep=mnormal; //important optimization for this to work fast enough
  161. bool collided = CollisionSolver2DSW::solve(shape,p_xform,p_motion*ofs,col_obj->get_shape(shape_idx),col_obj_xform,Vector2(),NULL,NULL,&sep,p_margin);
  162. if (collided) {
  163. hi=ofs;
  164. } else {
  165. low=ofs;
  166. }
  167. }
  168. if (low<best_safe) {
  169. best_safe=low;
  170. best_unsafe=hi;
  171. }
  172. }
  173. p_closest_safe=best_safe;
  174. p_closest_unsafe=best_unsafe;
  175. return true;
  176. }
  177. bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,Vector2 *r_results,int p_result_max,int &r_result_count, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
  178. if (p_result_max<=0)
  179. return 0;
  180. Shape2DSW *shape = static_cast<Physics2DServerSW*>(Physics2DServer::get_singleton())->shape_owner.get(p_shape);
  181. ERR_FAIL_COND_V(!shape,0);
  182. Rect2 aabb = p_shape_xform.xform(shape->get_aabb());
  183. aabb=aabb.merge(Rect2(aabb.pos+p_motion,aabb.size)); //motion
  184. aabb=aabb.grow(p_margin);
  185. int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results);
  186. bool collided=false;
  187. int cc=0;
  188. r_result_count=0;
  189. Physics2DServerSW::CollCbkData cbk;
  190. cbk.max=p_result_max;
  191. cbk.amount=0;
  192. cbk.ptr=r_results;
  193. CollisionSolver2DSW::CallbackResult cbkres=NULL;
  194. Physics2DServerSW::CollCbkData *cbkptr=NULL;
  195. if (p_result_max>0) {
  196. cbkptr=&cbk;
  197. cbkres=Physics2DServerSW::_shape_col_cbk;
  198. }
  199. for(int i=0;i<amount;i++) {
  200. if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
  201. continue;
  202. const CollisionObject2DSW *col_obj=space->intersection_query_results[i];
  203. int shape_idx=space->intersection_query_subindex_results[i];
  204. if (p_exclude.has( col_obj->get_self() ))
  205. continue;
  206. if (CollisionSolver2DSW::solve(shape,p_shape_xform,p_motion,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2(),cbkres,cbkptr,NULL,p_margin)) {
  207. collided=true;
  208. }
  209. }
  210. r_result_count=cbk.amount;
  211. return collided;
  212. }
  213. struct _RestCallbackData2D {
  214. const CollisionObject2DSW *object;
  215. const CollisionObject2DSW *best_object;
  216. int shape;
  217. int best_shape;
  218. Vector2 best_contact;
  219. Vector2 best_normal;
  220. float best_len;
  221. };
  222. static void _rest_cbk_result(const Vector2& p_point_A,const Vector2& p_point_B,void *p_userdata) {
  223. _RestCallbackData2D *rd=(_RestCallbackData2D*)p_userdata;
  224. Vector2 contact_rel = p_point_B - p_point_A;
  225. float len = contact_rel.length();
  226. if (len <= rd->best_len)
  227. return;
  228. rd->best_len=len;
  229. rd->best_contact=p_point_B;
  230. rd->best_normal=contact_rel/len;
  231. rd->best_object=rd->object;
  232. rd->best_shape=rd->shape;
  233. }
  234. bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,ShapeRestInfo *r_info, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
  235. Shape2DSW *shape = static_cast<Physics2DServerSW*>(Physics2DServer::get_singleton())->shape_owner.get(p_shape);
  236. ERR_FAIL_COND_V(!shape,0);
  237. Rect2 aabb = p_shape_xform.xform(shape->get_aabb());
  238. aabb=aabb.merge(Rect2(aabb.pos+p_motion,aabb.size)); //motion
  239. aabb=aabb.grow(p_margin);
  240. int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results);
  241. _RestCallbackData2D rcd;
  242. rcd.best_len=0;
  243. rcd.best_object=NULL;
  244. rcd.best_shape=0;
  245. for(int i=0;i<amount;i++) {
  246. if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
  247. continue;
  248. const CollisionObject2DSW *col_obj=space->intersection_query_results[i];
  249. int shape_idx=space->intersection_query_subindex_results[i];
  250. if (p_exclude.has( col_obj->get_self() ))
  251. continue;
  252. rcd.object=col_obj;
  253. rcd.shape=shape_idx;
  254. bool sc = CollisionSolver2DSW::solve(shape,p_shape_xform,p_motion,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2() ,_rest_cbk_result,&rcd,NULL,p_margin);
  255. if (!sc)
  256. continue;
  257. }
  258. if (rcd.best_len==0)
  259. return false;
  260. r_info->collider_id=rcd.best_object->get_instance_id();
  261. r_info->shape=rcd.best_shape;
  262. r_info->normal=rcd.best_normal;
  263. r_info->point=rcd.best_contact;
  264. r_info->rid=rcd.best_object->get_self();
  265. r_info->metadata=rcd.best_object->get_shape_metadata(rcd.best_shape);
  266. if (rcd.best_object->get_type()==CollisionObject2DSW::TYPE_BODY) {
  267. const Body2DSW *body = static_cast<const Body2DSW*>(rcd.best_object);
  268. Vector2 rel_vec = r_info->point-body->get_transform().get_origin();
  269. r_info->linear_velocity = Vector2(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity();
  270. } else {
  271. r_info->linear_velocity=Vector2();
  272. }
  273. return true;
  274. }
  275. Physics2DDirectSpaceStateSW::Physics2DDirectSpaceStateSW() {
  276. space=NULL;
  277. }
  278. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  279. void* Space2DSW::_broadphase_pair(CollisionObject2DSW *A,int p_subindex_A,CollisionObject2DSW *B,int p_subindex_B,void *p_self) {
  280. CollisionObject2DSW::Type type_A=A->get_type();
  281. CollisionObject2DSW::Type type_B=B->get_type();
  282. if (type_A>type_B) {
  283. SWAP(A,B);
  284. SWAP(p_subindex_A,p_subindex_B);
  285. SWAP(type_A,type_B);
  286. }
  287. Space2DSW *self = (Space2DSW*)p_self;
  288. self->collision_pairs++;
  289. if (type_A==CollisionObject2DSW::TYPE_AREA) {
  290. ERR_FAIL_COND_V(type_B!=CollisionObject2DSW::TYPE_BODY,NULL);
  291. Area2DSW *area=static_cast<Area2DSW*>(A);
  292. Body2DSW *body=static_cast<Body2DSW*>(B);
  293. AreaPair2DSW *area_pair = memnew(AreaPair2DSW(body,p_subindex_B,area,p_subindex_A) );
  294. return area_pair;
  295. } else {
  296. BodyPair2DSW *b = memnew( BodyPair2DSW((Body2DSW*)A,p_subindex_A,(Body2DSW*)B,p_subindex_B) );
  297. return b;
  298. }
  299. return NULL;
  300. }
  301. void Space2DSW::_broadphase_unpair(CollisionObject2DSW *A,int p_subindex_A,CollisionObject2DSW *B,int p_subindex_B,void *p_data,void *p_self) {
  302. Space2DSW *self = (Space2DSW*)p_self;
  303. self->collision_pairs--;
  304. Constraint2DSW *c = (Constraint2DSW*)p_data;
  305. memdelete(c);
  306. }
  307. const SelfList<Body2DSW>::List& Space2DSW::get_active_body_list() const {
  308. return active_list;
  309. }
  310. void Space2DSW::body_add_to_active_list(SelfList<Body2DSW>* p_body) {
  311. active_list.add(p_body);
  312. }
  313. void Space2DSW::body_remove_from_active_list(SelfList<Body2DSW>* p_body) {
  314. active_list.remove(p_body);
  315. }
  316. void Space2DSW::body_add_to_inertia_update_list(SelfList<Body2DSW>* p_body) {
  317. inertia_update_list.add(p_body);
  318. }
  319. void Space2DSW::body_remove_from_inertia_update_list(SelfList<Body2DSW>* p_body) {
  320. inertia_update_list.remove(p_body);
  321. }
  322. BroadPhase2DSW *Space2DSW::get_broadphase() {
  323. return broadphase;
  324. }
  325. void Space2DSW::add_object(CollisionObject2DSW *p_object) {
  326. ERR_FAIL_COND( objects.has(p_object) );
  327. objects.insert(p_object);
  328. }
  329. void Space2DSW::remove_object(CollisionObject2DSW *p_object) {
  330. ERR_FAIL_COND( !objects.has(p_object) );
  331. objects.erase(p_object);
  332. }
  333. const Set<CollisionObject2DSW*> &Space2DSW::get_objects() const {
  334. return objects;
  335. }
  336. void Space2DSW::body_add_to_state_query_list(SelfList<Body2DSW>* p_body) {
  337. state_query_list.add(p_body);
  338. }
  339. void Space2DSW::body_remove_from_state_query_list(SelfList<Body2DSW>* p_body) {
  340. state_query_list.remove(p_body);
  341. }
  342. void Space2DSW::area_add_to_monitor_query_list(SelfList<Area2DSW>* p_area) {
  343. monitor_query_list.add(p_area);
  344. }
  345. void Space2DSW::area_remove_from_monitor_query_list(SelfList<Area2DSW>* p_area) {
  346. monitor_query_list.remove(p_area);
  347. }
  348. void Space2DSW::area_add_to_moved_list(SelfList<Area2DSW>* p_area) {
  349. area_moved_list.add(p_area);
  350. }
  351. void Space2DSW::area_remove_from_moved_list(SelfList<Area2DSW>* p_area) {
  352. area_moved_list.remove(p_area);
  353. }
  354. const SelfList<Area2DSW>::List& Space2DSW::get_moved_area_list() const {
  355. return area_moved_list;
  356. }
  357. void Space2DSW::call_queries() {
  358. while(state_query_list.first()) {
  359. Body2DSW * b = state_query_list.first()->self();
  360. b->call_queries();
  361. state_query_list.remove(state_query_list.first());
  362. }
  363. while(monitor_query_list.first()) {
  364. Area2DSW * a = monitor_query_list.first()->self();
  365. a->call_queries();
  366. monitor_query_list.remove(monitor_query_list.first());
  367. }
  368. }
  369. void Space2DSW::setup() {
  370. while(inertia_update_list.first()) {
  371. inertia_update_list.first()->self()->update_inertias();
  372. inertia_update_list.remove(inertia_update_list.first());
  373. }
  374. }
  375. void Space2DSW::update() {
  376. broadphase->update();
  377. }
  378. void Space2DSW::set_param(Physics2DServer::SpaceParameter p_param, real_t p_value) {
  379. switch(p_param) {
  380. case Physics2DServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: contact_recycle_radius=p_value; break;
  381. case Physics2DServer::SPACE_PARAM_CONTACT_MAX_SEPARATION: contact_max_separation=p_value; break;
  382. case Physics2DServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: contact_max_allowed_penetration=p_value; break;
  383. case Physics2DServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD: body_linear_velocity_sleep_treshold=p_value; break;
  384. case Physics2DServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD: body_angular_velocity_sleep_treshold=p_value; break;
  385. case Physics2DServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: body_time_to_sleep=p_value; break;
  386. case Physics2DServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: body_angular_velocity_damp_ratio=p_value; break;
  387. case Physics2DServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: constraint_bias=p_value; break;
  388. }
  389. }
  390. real_t Space2DSW::get_param(Physics2DServer::SpaceParameter p_param) const {
  391. switch(p_param) {
  392. case Physics2DServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: return contact_recycle_radius;
  393. case Physics2DServer::SPACE_PARAM_CONTACT_MAX_SEPARATION: return contact_max_separation;
  394. case Physics2DServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: return contact_max_allowed_penetration;
  395. case Physics2DServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD: return body_linear_velocity_sleep_treshold;
  396. case Physics2DServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD: return body_angular_velocity_sleep_treshold;
  397. case Physics2DServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: return body_time_to_sleep;
  398. case Physics2DServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: return body_angular_velocity_damp_ratio;
  399. case Physics2DServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: return constraint_bias;
  400. }
  401. return 0;
  402. }
  403. void Space2DSW::lock() {
  404. locked=true;
  405. }
  406. void Space2DSW::unlock() {
  407. locked=false;
  408. }
  409. bool Space2DSW::is_locked() const {
  410. return locked;
  411. }
  412. Physics2DDirectSpaceStateSW *Space2DSW::get_direct_state() {
  413. return direct_access;
  414. }
  415. Space2DSW::Space2DSW() {
  416. collision_pairs=0;
  417. active_objects=0;
  418. island_count=0;
  419. locked=false;
  420. contact_recycle_radius=0.01;
  421. contact_max_separation=0.05;
  422. contact_max_allowed_penetration= 0.01;
  423. constraint_bias = 0.01;
  424. body_linear_velocity_sleep_treshold=0.01;
  425. body_angular_velocity_sleep_treshold=(8.0 / 180.0 * Math_PI);
  426. body_time_to_sleep=0.5;
  427. body_angular_velocity_damp_ratio=15;
  428. broadphase = BroadPhase2DSW::create_func();
  429. broadphase->set_pair_callback(_broadphase_pair,this);
  430. broadphase->set_unpair_callback(_broadphase_unpair,this);
  431. area=NULL;
  432. direct_access = memnew( Physics2DDirectSpaceStateSW );
  433. direct_access->space=this;
  434. }
  435. Space2DSW::~Space2DSW() {
  436. memdelete(broadphase);
  437. memdelete( direct_access );
  438. }