step_sw.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*************************************************************************/
  2. /* step_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 "step_sw.h"
  30. void StepSW::_populate_island(BodySW* p_body,BodySW** p_island,ConstraintSW **p_constraint_island) {
  31. p_body->set_island_step(_step);
  32. p_body->set_island_next(*p_island);
  33. *p_island=p_body;
  34. for(Map<ConstraintSW*,int>::Element *E=p_body->get_constraint_map().front();E;E=E->next()) {
  35. ConstraintSW *c=(ConstraintSW*)E->key();
  36. if (c->get_island_step()==_step)
  37. continue; //already processed
  38. c->set_island_step(_step);
  39. c->set_island_next(*p_constraint_island);
  40. *p_constraint_island=c;
  41. for(int i=0;i<c->get_body_count();i++) {
  42. if (i==E->get())
  43. continue;
  44. BodySW *b = c->get_body_ptr()[i];
  45. if (b->get_island_step()==_step || b->get_mode()==PhysicsServer::BODY_MODE_STATIC)
  46. continue; //no go
  47. _populate_island(c->get_body_ptr()[i],p_island,p_constraint_island);
  48. }
  49. }
  50. }
  51. void StepSW::_setup_island(ConstraintSW *p_island,float p_delta) {
  52. ConstraintSW *ci=p_island;
  53. while(ci) {
  54. bool process = ci->setup(p_delta);
  55. //todo remove from island if process fails
  56. ci=ci->get_island_next();
  57. }
  58. }
  59. void StepSW::_solve_island(ConstraintSW *p_island,int p_iterations,float p_delta){
  60. for(int i=0;i<p_iterations;i++) {
  61. ConstraintSW *ci=p_island;
  62. while(ci) {
  63. ci->solve(p_delta);
  64. ci=ci->get_island_next();
  65. }
  66. }
  67. }
  68. void StepSW::_check_suspend(BodySW *p_island,float p_delta) {
  69. bool can_sleep=true;
  70. BodySW *b = p_island;
  71. while(b) {
  72. if (b->get_mode()==PhysicsServer::BODY_MODE_STATIC)
  73. continue; //ignore for static
  74. if (!b->sleep_test(p_delta))
  75. can_sleep=false;
  76. b=b->get_island_next();
  77. }
  78. //put all to sleep or wake up everyoen
  79. b = p_island;
  80. while(b) {
  81. if (b->get_mode()==PhysicsServer::BODY_MODE_STATIC)
  82. continue; //ignore for static
  83. bool active = b->is_active();
  84. if (active==can_sleep)
  85. b->set_active(!can_sleep);
  86. b=b->get_island_next();
  87. }
  88. }
  89. void StepSW::step(SpaceSW* p_space,float p_delta,int p_iterations) {
  90. p_space->lock(); // can't access space during this
  91. p_space->setup(); //update inertias, etc
  92. const SelfList<BodySW>::List * body_list = &p_space->get_active_body_list();
  93. /* INTEGRATE FORCES */
  94. int active_count=0;
  95. const SelfList<BodySW>*b = body_list->first();
  96. while(b) {
  97. b->self()->integrate_forces(p_delta);
  98. b=b->next();
  99. active_count++;
  100. }
  101. /* GENERATE CONSTRAINT ISLANDS */
  102. BodySW *island_list=NULL;
  103. ConstraintSW *constraint_island_list=NULL;
  104. b = body_list->first();
  105. int island_count=0;
  106. while(b) {
  107. BodySW *body = b->self();
  108. if (body->get_island_step()!=_step) {
  109. BodySW *island=NULL;
  110. ConstraintSW *constraint_island=NULL;
  111. _populate_island(body,&island,&constraint_island);
  112. island->set_island_list_next(island_list);
  113. island_list=island;
  114. if (constraint_island) {
  115. constraint_island->set_island_list_next(constraint_island_list);
  116. constraint_island_list=constraint_island;
  117. island_count++;
  118. }
  119. }
  120. b=b->next();
  121. }
  122. const SelfList<AreaSW>::List &aml = p_space->get_moved_area_list();
  123. while(aml.first()) {
  124. for(const Set<ConstraintSW*>::Element *E=aml.first()->self()->get_constraints().front();E;E=E->next()) {
  125. ConstraintSW*c=E->get();
  126. if (c->get_island_step()==_step)
  127. continue;
  128. c->set_island_step(_step);
  129. c->set_island_next(NULL);
  130. c->set_island_list_next(constraint_island_list);
  131. constraint_island_list=c;
  132. }
  133. p_space->area_remove_from_moved_list((SelfList<AreaSW>*)aml.first()); //faster to remove here
  134. }
  135. // print_line("island count: "+itos(island_count)+" active count: "+itos(active_count));
  136. /* SETUP CONSTRAINT ISLANDS */
  137. {
  138. ConstraintSW *ci=constraint_island_list;
  139. while(ci) {
  140. _setup_island(ci,p_delta);
  141. ci=ci->get_island_list_next();
  142. }
  143. }
  144. /* SOLVE CONSTRAINT ISLANDS */
  145. {
  146. ConstraintSW *ci=constraint_island_list;
  147. while(ci) {
  148. //iterating each island separatedly improves cache efficiency
  149. _solve_island(ci,p_iterations,p_delta);
  150. ci=ci->get_island_list_next();
  151. }
  152. }
  153. /* INTEGRATE VELOCITIES */
  154. b = body_list->first();
  155. while(b) {
  156. b->self()->integrate_velocities(p_delta);
  157. b=b->next();
  158. }
  159. /* SLEEP / WAKE UP ISLANDS */
  160. {
  161. BodySW *bi=island_list;
  162. while(bi) {
  163. _check_suspend(bi,p_delta);
  164. bi=bi->get_island_list_next();
  165. }
  166. }
  167. p_space->update();
  168. p_space->unlock();
  169. _step++;
  170. }
  171. StepSW::StepSW() {
  172. _step=1;
  173. }