body_sw.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. /*************************************************************************/
  2. /* body_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 "body_sw.h"
  30. #include "space_sw.h"
  31. #include "area_sw.h"
  32. void BodySW::_update_inertia() {
  33. if (get_space() && !inertia_update_list.in_list())
  34. get_space()->body_add_to_inertia_update_list(&inertia_update_list);
  35. }
  36. void BodySW::_update_inertia_tensor() {
  37. Matrix3 tb = get_transform().basis;
  38. tb.scale(_inv_inertia);
  39. _inv_inertia_tensor = tb * get_transform().basis.transposed();
  40. }
  41. void BodySW::update_inertias() {
  42. //update shapes and motions
  43. switch(mode) {
  44. case PhysicsServer::BODY_MODE_RIGID: {
  45. //update tensor for allshapes, not the best way but should be somehow OK. (inspired from bullet)
  46. float total_area=0;
  47. for (int i=0;i<get_shape_count();i++) {
  48. total_area+=get_shape_aabb(i).get_area();
  49. }
  50. Vector3 _inertia;
  51. for (int i=0;i<get_shape_count();i++) {
  52. const ShapeSW* shape=get_shape(i);
  53. float area=get_shape_aabb(i).get_area();
  54. float mass = area * this->mass / total_area;
  55. _inertia += shape->get_moment_of_inertia(mass) + mass * get_shape_transform(i).get_origin();
  56. }
  57. if (_inertia!=Vector3())
  58. _inv_inertia=_inertia.inverse();
  59. else
  60. _inv_inertia=Vector3();
  61. if (mass)
  62. _inv_mass=1.0/mass;
  63. else
  64. _inv_mass=0;
  65. } break;
  66. case PhysicsServer::BODY_MODE_KINEMATIC:
  67. case PhysicsServer::BODY_MODE_STATIC: {
  68. _inv_inertia=Vector3();
  69. _inv_mass=0;
  70. } break;
  71. case PhysicsServer::BODY_MODE_CHARACTER: {
  72. _inv_inertia=Vector3();
  73. _inv_mass=1.0/mass;
  74. } break;
  75. }
  76. _update_inertia_tensor();
  77. //_update_shapes();
  78. }
  79. void BodySW::set_active(bool p_active) {
  80. if (active==p_active)
  81. return;
  82. active=p_active;
  83. if (!p_active) {
  84. if (get_space())
  85. get_space()->body_remove_from_active_list(&active_list);
  86. } else {
  87. if (mode==PhysicsServer::BODY_MODE_STATIC)
  88. return; //static bodies can't become active
  89. if (get_space())
  90. get_space()->body_add_to_active_list(&active_list);
  91. //still_time=0;
  92. }
  93. /*
  94. if (!space)
  95. return;
  96. for(int i=0;i<get_shape_count();i++) {
  97. Shape &s=shapes[i];
  98. if (s.bpid>0) {
  99. get_space()->get_broadphase()->set_active(s.bpid,active);
  100. }
  101. }
  102. */
  103. }
  104. void BodySW::set_param(PhysicsServer::BodyParameter p_param, float p_value) {
  105. switch(p_param) {
  106. case PhysicsServer::BODY_PARAM_BOUNCE: {
  107. bounce=p_value;
  108. } break;
  109. case PhysicsServer::BODY_PARAM_FRICTION: {
  110. friction=p_value;
  111. } break;
  112. case PhysicsServer::BODY_PARAM_MASS: {
  113. ERR_FAIL_COND(p_value<=0);
  114. mass=p_value;
  115. _update_inertia();
  116. } break;
  117. default:{}
  118. }
  119. }
  120. float BodySW::get_param(PhysicsServer::BodyParameter p_param) const {
  121. switch(p_param) {
  122. case PhysicsServer::BODY_PARAM_BOUNCE: {
  123. return bounce;
  124. } break;
  125. case PhysicsServer::BODY_PARAM_FRICTION: {
  126. return friction;
  127. } break;
  128. case PhysicsServer::BODY_PARAM_MASS: {
  129. return mass;
  130. } break;
  131. default:{}
  132. }
  133. return 0;
  134. }
  135. void BodySW::set_mode(PhysicsServer::BodyMode p_mode) {
  136. mode=p_mode;
  137. switch(p_mode) {
  138. //CLEAR UP EVERYTHING IN CASE IT NOT WORKS!
  139. case PhysicsServer::BODY_MODE_STATIC:
  140. case PhysicsServer::BODY_MODE_KINEMATIC: {
  141. _set_inv_transform(get_transform().affine_inverse());
  142. _inv_mass=0;
  143. _set_static(p_mode==PhysicsServer::BODY_MODE_STATIC);
  144. set_active(p_mode==PhysicsServer::BODY_MODE_KINEMATIC);
  145. linear_velocity=Vector3();
  146. angular_velocity=Vector3();
  147. } break;
  148. case PhysicsServer::BODY_MODE_RIGID: {
  149. _inv_mass=mass>0?(1.0/mass):0;
  150. _set_static(false);
  151. simulated_motion=false; //jic
  152. } break;
  153. case PhysicsServer::BODY_MODE_CHARACTER: {
  154. _inv_mass=mass>0?(1.0/mass):0;
  155. _set_static(false);
  156. simulated_motion=false; //jic
  157. } break;
  158. }
  159. _update_inertia();
  160. //if (get_space())
  161. // _update_queries();
  162. }
  163. PhysicsServer::BodyMode BodySW::get_mode() const {
  164. return mode;
  165. }
  166. void BodySW::_shapes_changed() {
  167. _update_inertia();
  168. }
  169. void BodySW::set_state(PhysicsServer::BodyState p_state, const Variant& p_variant) {
  170. switch(p_state) {
  171. case PhysicsServer::BODY_STATE_TRANSFORM: {
  172. if (mode==PhysicsServer::BODY_MODE_STATIC || mode==PhysicsServer::BODY_MODE_KINEMATIC) {
  173. _set_transform(p_variant);
  174. _set_inv_transform(get_transform().affine_inverse());
  175. wakeup_neighbours();
  176. } else {
  177. Transform t = p_variant;
  178. t.orthonormalize();
  179. _set_transform(t);
  180. _set_inv_transform(get_transform().inverse());
  181. }
  182. } break;
  183. case PhysicsServer::BODY_STATE_LINEAR_VELOCITY: {
  184. //if (mode==PhysicsServer::BODY_MODE_STATIC)
  185. // break;
  186. linear_velocity=p_variant;
  187. } break;
  188. case PhysicsServer::BODY_STATE_ANGULAR_VELOCITY: {
  189. //if (mode!=PhysicsServer::BODY_MODE_RIGID)
  190. // break;
  191. angular_velocity=p_variant;
  192. } break;
  193. case PhysicsServer::BODY_STATE_SLEEPING: {
  194. //?
  195. if (mode==PhysicsServer::BODY_MODE_STATIC || mode==PhysicsServer::BODY_MODE_KINEMATIC)
  196. break;
  197. bool do_sleep=p_variant;
  198. if (do_sleep) {
  199. linear_velocity=Vector3();
  200. //biased_linear_velocity=Vector3();
  201. angular_velocity=Vector3();
  202. //biased_angular_velocity=Vector3();
  203. set_active(false);
  204. } else {
  205. if (mode!=PhysicsServer::BODY_MODE_STATIC)
  206. set_active(true);
  207. }
  208. } break;
  209. case PhysicsServer::BODY_STATE_CAN_SLEEP: {
  210. can_sleep=p_variant;
  211. if (mode==PhysicsServer::BODY_MODE_RIGID && !active && !can_sleep)
  212. set_active(true);
  213. } break;
  214. }
  215. }
  216. Variant BodySW::get_state(PhysicsServer::BodyState p_state) const {
  217. switch(p_state) {
  218. case PhysicsServer::BODY_STATE_TRANSFORM: {
  219. return get_transform();
  220. } break;
  221. case PhysicsServer::BODY_STATE_LINEAR_VELOCITY: {
  222. return linear_velocity;
  223. } break;
  224. case PhysicsServer::BODY_STATE_ANGULAR_VELOCITY: {
  225. return angular_velocity;
  226. } break;
  227. case PhysicsServer::BODY_STATE_SLEEPING: {
  228. return !is_active();
  229. } break;
  230. case PhysicsServer::BODY_STATE_CAN_SLEEP: {
  231. return can_sleep;
  232. } break;
  233. }
  234. return Variant();
  235. }
  236. void BodySW::set_space(SpaceSW *p_space){
  237. if (get_space()) {
  238. if (inertia_update_list.in_list())
  239. get_space()->body_remove_from_inertia_update_list(&inertia_update_list);
  240. if (active_list.in_list())
  241. get_space()->body_remove_from_active_list(&active_list);
  242. if (direct_state_query_list.in_list())
  243. get_space()->body_remove_from_state_query_list(&direct_state_query_list);
  244. }
  245. _set_space(p_space);
  246. if (get_space()) {
  247. _update_inertia();
  248. if (active)
  249. get_space()->body_add_to_active_list(&active_list);
  250. // _update_queries();
  251. //if (is_active()) {
  252. // active=false;
  253. // set_active(true);
  254. //}
  255. }
  256. }
  257. void BodySW::_compute_area_gravity(const AreaSW *p_area) {
  258. if (p_area->is_gravity_point()) {
  259. gravity = (p_area->get_gravity_vector() - get_transform().get_origin()).normalized() * p_area->get_gravity();
  260. } else {
  261. gravity = p_area->get_gravity_vector() * p_area->get_gravity();
  262. }
  263. }
  264. void BodySW::integrate_forces(real_t p_step) {
  265. if (mode==PhysicsServer::BODY_MODE_STATIC || mode==PhysicsServer::BODY_MODE_KINEMATIC)
  266. return;
  267. AreaSW *current_area = get_space()->get_default_area();
  268. ERR_FAIL_COND(!current_area);
  269. int prio = current_area->get_priority();
  270. int ac = areas.size();
  271. if (ac) {
  272. const AreaCMP *aa = &areas[0];
  273. for(int i=0;i<ac;i++) {
  274. if (aa[i].area->get_priority() > prio) {
  275. current_area=aa[i].area;
  276. prio=current_area->get_priority();
  277. }
  278. }
  279. }
  280. _compute_area_gravity(current_area);
  281. density=current_area->get_density();
  282. if (!omit_force_integration) {
  283. //overriden by direct state query
  284. Vector3 force=gravity*mass;
  285. force+=applied_force;
  286. Vector3 torque=applied_torque;
  287. real_t damp = 1.0 - p_step * density;
  288. if (damp<0) // reached zero in the given time
  289. damp=0;
  290. real_t angular_damp = 1.0 - p_step * density * get_space()->get_body_angular_velocity_damp_ratio();
  291. if (angular_damp<0) // reached zero in the given time
  292. angular_damp=0;
  293. linear_velocity*=damp;
  294. angular_velocity*=angular_damp;
  295. linear_velocity+=_inv_mass * force * p_step;
  296. angular_velocity+=_inv_inertia_tensor.xform(torque)*p_step;
  297. }
  298. applied_force=Vector3();
  299. applied_torque=Vector3();
  300. //motion=linear_velocity*p_step;
  301. biased_angular_velocity=Vector3();
  302. biased_linear_velocity=Vector3();
  303. if (continuous_cd) //shapes temporarily extend for raycast
  304. _update_shapes_with_motion(linear_velocity*p_step);
  305. current_area=NULL; // clear the area, so it is set in the next frame
  306. contact_count=0;
  307. }
  308. void BodySW::integrate_velocities(real_t p_step) {
  309. if (mode==PhysicsServer::BODY_MODE_STATIC)
  310. return;
  311. if (mode==PhysicsServer::BODY_MODE_KINEMATIC) {
  312. if (fi_callback)
  313. get_space()->body_add_to_state_query_list(&direct_state_query_list);
  314. return;
  315. }
  316. //apply axis lock
  317. if (axis_lock!=PhysicsServer::BODY_AXIS_LOCK_DISABLED) {
  318. int axis=axis_lock-1;
  319. for(int i=0;i<3;i++) {
  320. if (i==axis) {
  321. linear_velocity[i]=0;
  322. biased_linear_velocity[i]=0;
  323. } else {
  324. angular_velocity[i]=0;
  325. biased_angular_velocity[i]=0;
  326. }
  327. }
  328. }
  329. Vector3 total_angular_velocity = angular_velocity+biased_angular_velocity;
  330. float ang_vel = total_angular_velocity.length();
  331. Transform transform = get_transform();
  332. if (ang_vel!=0.0) {
  333. Vector3 ang_vel_axis = total_angular_velocity / ang_vel;
  334. Matrix3 rot( ang_vel_axis, -ang_vel*p_step );
  335. transform.basis = rot * transform.basis;
  336. transform.orthonormalize();
  337. }
  338. Vector3 total_linear_velocity=linear_velocity+biased_linear_velocity;
  339. /*for(int i=0;i<3;i++) {
  340. if (axis_lock&(1<<i)) {
  341. transform.origin[i]=0.0;
  342. }
  343. }*/
  344. transform.origin+=total_linear_velocity * p_step;
  345. _set_transform(transform);
  346. _set_inv_transform(get_transform().inverse());
  347. _update_inertia_tensor();
  348. if (fi_callback) {
  349. get_space()->body_add_to_state_query_list(&direct_state_query_list);
  350. }
  351. }
  352. void BodySW::simulate_motion(const Transform& p_xform,real_t p_step) {
  353. Transform inv_xform = p_xform.affine_inverse();
  354. if (!get_space()) {
  355. _set_transform(p_xform);
  356. _set_inv_transform(inv_xform);
  357. return;
  358. }
  359. //compute a FAKE linear velocity - this is easy
  360. linear_velocity=(p_xform.origin - get_transform().origin)/p_step;
  361. //compute a FAKE angular velocity, not so easy
  362. Matrix3 rot=get_transform().basis.orthonormalized().transposed() * p_xform.basis.orthonormalized();
  363. Vector3 axis;
  364. float angle;
  365. rot.get_axis_and_angle(axis,angle);
  366. axis.normalize();
  367. angular_velocity=axis.normalized() * (angle/p_step);
  368. linear_velocity = (p_xform.origin - get_transform().origin)/p_step;
  369. if (!direct_state_query_list.in_list())// - callalways, so lv and av are cleared && (state_query || direct_state_query))
  370. get_space()->body_add_to_state_query_list(&direct_state_query_list);
  371. simulated_motion=true;
  372. _set_transform(p_xform);
  373. }
  374. void BodySW::wakeup_neighbours() {
  375. for(Map<ConstraintSW*,int>::Element *E=constraint_map.front();E;E=E->next()) {
  376. const ConstraintSW *c=E->key();
  377. BodySW **n = c->get_body_ptr();
  378. int bc=c->get_body_count();
  379. for(int i=0;i<bc;i++) {
  380. if (i==E->get())
  381. continue;
  382. BodySW *b = n[i];
  383. if (b->mode!=PhysicsServer::BODY_MODE_RIGID)
  384. continue;
  385. if (!b->is_active())
  386. b->set_active(true);
  387. }
  388. }
  389. }
  390. void BodySW::call_queries() {
  391. if (fi_callback) {
  392. PhysicsDirectBodyStateSW *dbs = PhysicsDirectBodyStateSW::singleton;
  393. dbs->body=this;
  394. Variant v=dbs;
  395. Object *obj = ObjectDB::get_instance(fi_callback->id);
  396. if (!obj) {
  397. set_force_integration_callback(0,StringName());
  398. } else {
  399. const Variant *vp[2]={&v,&fi_callback->udata};
  400. Variant::CallError ce;
  401. int argc=(fi_callback->udata.get_type()==Variant::NIL)?1:2;
  402. obj->call(fi_callback->method,vp,argc,ce);
  403. }
  404. }
  405. if (simulated_motion) {
  406. // linear_velocity=Vector3();
  407. // angular_velocity=0;
  408. simulated_motion=false;
  409. }
  410. }
  411. bool BodySW::sleep_test(real_t p_step) {
  412. if (mode==PhysicsServer::BODY_MODE_STATIC || mode==PhysicsServer::BODY_MODE_KINEMATIC)
  413. return true; //
  414. else if (mode==PhysicsServer::BODY_MODE_CHARACTER)
  415. return !active; // characters don't sleep unless asked to sleep
  416. else if (!can_sleep)
  417. return false;
  418. if (Math::abs(angular_velocity.length())<get_space()->get_body_angular_velocity_sleep_treshold() && Math::abs(linear_velocity.length_squared()) < get_space()->get_body_linear_velocity_sleep_treshold()*get_space()->get_body_linear_velocity_sleep_treshold()) {
  419. still_time+=p_step;
  420. return still_time > get_space()->get_body_time_to_sleep();
  421. } else {
  422. still_time=0; //maybe this should be set to 0 on set_active?
  423. return false;
  424. }
  425. }
  426. void BodySW::set_force_integration_callback(ObjectID p_id,const StringName& p_method,const Variant& p_udata) {
  427. if (fi_callback) {
  428. memdelete(fi_callback);
  429. fi_callback=NULL;
  430. }
  431. if (p_id!=0) {
  432. fi_callback=memnew(ForceIntegrationCallback);
  433. fi_callback->id=p_id;
  434. fi_callback->method=p_method;
  435. fi_callback->udata=p_udata;
  436. }
  437. }
  438. BodySW::BodySW() : CollisionObjectSW(TYPE_BODY), active_list(this), inertia_update_list(this), direct_state_query_list(this) {
  439. mode=PhysicsServer::BODY_MODE_RIGID;
  440. active=true;
  441. mass=1;
  442. // _inv_inertia=Transform();
  443. _inv_mass=1;
  444. bounce=0;
  445. friction=1;
  446. omit_force_integration=false;
  447. // applied_torque=0;
  448. island_step=0;
  449. island_next=NULL;
  450. island_list_next=NULL;
  451. _set_static(false);
  452. density=0;
  453. contact_count=0;
  454. simulated_motion=false;
  455. still_time=0;
  456. continuous_cd=false;
  457. can_sleep=false;
  458. fi_callback=NULL;
  459. axis_lock=PhysicsServer::BODY_AXIS_LOCK_DISABLED;
  460. }
  461. BodySW::~BodySW() {
  462. if (fi_callback)
  463. memdelete(fi_callback);
  464. }
  465. PhysicsDirectBodyStateSW *PhysicsDirectBodyStateSW::singleton=NULL;
  466. PhysicsDirectSpaceState* PhysicsDirectBodyStateSW::get_space_state() {
  467. return body->get_space()->get_direct_state();
  468. }