physical_bone_simulator_3d.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. /**************************************************************************/
  2. /* physical_bone_simulator_3d.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  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 "physical_bone_simulator_3d.h"
  31. void PhysicalBoneSimulator3D::_skeleton_changed(Skeleton3D *p_old, Skeleton3D *p_new) {
  32. if (p_old) {
  33. if (p_old->is_connected(SNAME("bone_list_changed"), callable_mp(this, &PhysicalBoneSimulator3D::_bone_list_changed))) {
  34. p_old->disconnect(SNAME("bone_list_changed"), callable_mp(this, &PhysicalBoneSimulator3D::_bone_list_changed));
  35. }
  36. if (p_old->is_connected(SceneStringName(pose_updated), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated))) {
  37. p_old->disconnect(SceneStringName(pose_updated), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated));
  38. }
  39. }
  40. if (p_new) {
  41. if (!p_new->is_connected(SNAME("bone_list_changed"), callable_mp(this, &PhysicalBoneSimulator3D::_bone_list_changed))) {
  42. p_new->connect(SNAME("bone_list_changed"), callable_mp(this, &PhysicalBoneSimulator3D::_bone_list_changed));
  43. }
  44. if (!p_new->is_connected(SceneStringName(pose_updated), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated))) {
  45. p_new->connect(SceneStringName(pose_updated), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated));
  46. }
  47. }
  48. _bone_list_changed();
  49. }
  50. void PhysicalBoneSimulator3D::_bone_list_changed() {
  51. bones.clear();
  52. Skeleton3D *skeleton = get_skeleton();
  53. if (!skeleton) {
  54. return;
  55. }
  56. for (int i = 0; i < skeleton->get_bone_count(); i++) {
  57. SimulatedBone sb;
  58. sb.parent = skeleton->get_bone_parent(i);
  59. sb.child_bones = skeleton->get_bone_children(i);
  60. bones.push_back(sb);
  61. }
  62. _rebuild_physical_bones_cache();
  63. _pose_updated();
  64. }
  65. void PhysicalBoneSimulator3D::_pose_updated() {
  66. Skeleton3D *skeleton = get_skeleton();
  67. if (!skeleton || simulating) {
  68. return;
  69. }
  70. ERR_FAIL_COND(skeleton->get_bone_count() != bones.size());
  71. for (int i = 0; i < skeleton->get_bone_count(); i++) {
  72. _bone_pose_updated(skeleton, i);
  73. }
  74. }
  75. void PhysicalBoneSimulator3D::_bone_pose_updated(Skeleton3D *p_skeleton, int p_bone_id) {
  76. ERR_FAIL_INDEX(p_bone_id, bones.size());
  77. bones.write[p_bone_id].global_pose = p_skeleton->get_bone_global_pose(p_bone_id);
  78. }
  79. void PhysicalBoneSimulator3D::_set_active(bool p_active) {
  80. if (!Engine::get_singleton()->is_editor_hint()) {
  81. _reset_physical_bones_state();
  82. }
  83. }
  84. void PhysicalBoneSimulator3D::_reset_physical_bones_state() {
  85. for (int i = 0; i < bones.size(); i += 1) {
  86. if (bones[i].physical_bone) {
  87. bones[i].physical_bone->reset_physics_simulation_state();
  88. }
  89. }
  90. }
  91. bool PhysicalBoneSimulator3D::is_simulating_physics() const {
  92. return simulating;
  93. }
  94. int PhysicalBoneSimulator3D::find_bone(const String &p_name) const {
  95. Skeleton3D *skeleton = get_skeleton();
  96. if (!skeleton) {
  97. return -1;
  98. }
  99. return skeleton->find_bone(p_name);
  100. }
  101. String PhysicalBoneSimulator3D::get_bone_name(int p_bone) const {
  102. Skeleton3D *skeleton = get_skeleton();
  103. if (!skeleton) {
  104. return String();
  105. }
  106. return skeleton->get_bone_name(p_bone);
  107. }
  108. int PhysicalBoneSimulator3D::get_bone_count() const {
  109. return bones.size();
  110. }
  111. bool PhysicalBoneSimulator3D::is_bone_parent_of(int p_bone, int p_parent_bone_id) const {
  112. Skeleton3D *skeleton = get_skeleton();
  113. if (!skeleton) {
  114. return false;
  115. }
  116. return skeleton->is_bone_parent_of(p_bone, p_parent_bone_id);
  117. }
  118. void PhysicalBoneSimulator3D::bind_physical_bone_to_bone(int p_bone, PhysicalBone3D *p_physical_bone) {
  119. const int bone_size = bones.size();
  120. ERR_FAIL_INDEX(p_bone, bone_size);
  121. ERR_FAIL_COND(bones[p_bone].physical_bone);
  122. ERR_FAIL_NULL(p_physical_bone);
  123. bones.write[p_bone].physical_bone = p_physical_bone;
  124. _rebuild_physical_bones_cache();
  125. }
  126. void PhysicalBoneSimulator3D::unbind_physical_bone_from_bone(int p_bone) {
  127. const int bone_size = bones.size();
  128. ERR_FAIL_INDEX(p_bone, bone_size);
  129. bones.write[p_bone].physical_bone = nullptr;
  130. _rebuild_physical_bones_cache();
  131. }
  132. PhysicalBone3D *PhysicalBoneSimulator3D::get_physical_bone(int p_bone) {
  133. const int bone_size = bones.size();
  134. ERR_FAIL_INDEX_V(p_bone, bone_size, nullptr);
  135. return bones[p_bone].physical_bone;
  136. }
  137. PhysicalBone3D *PhysicalBoneSimulator3D::get_physical_bone_parent(int p_bone) {
  138. const int bone_size = bones.size();
  139. ERR_FAIL_INDEX_V(p_bone, bone_size, nullptr);
  140. if (bones[p_bone].cache_parent_physical_bone) {
  141. return bones[p_bone].cache_parent_physical_bone;
  142. }
  143. return _get_physical_bone_parent(p_bone);
  144. }
  145. PhysicalBone3D *PhysicalBoneSimulator3D::_get_physical_bone_parent(int p_bone) {
  146. const int bone_size = bones.size();
  147. ERR_FAIL_INDEX_V(p_bone, bone_size, nullptr);
  148. const int parent_bone = bones[p_bone].parent;
  149. if (parent_bone < 0) {
  150. return nullptr;
  151. }
  152. PhysicalBone3D *pb = bones[parent_bone].physical_bone;
  153. if (pb) {
  154. return pb;
  155. } else {
  156. return get_physical_bone_parent(parent_bone);
  157. }
  158. }
  159. void PhysicalBoneSimulator3D::_rebuild_physical_bones_cache() {
  160. const int b_size = bones.size();
  161. for (int i = 0; i < b_size; ++i) {
  162. PhysicalBone3D *parent_pb = _get_physical_bone_parent(i);
  163. if (parent_pb != bones[i].cache_parent_physical_bone) {
  164. bones.write[i].cache_parent_physical_bone = parent_pb;
  165. if (bones[i].physical_bone) {
  166. bones[i].physical_bone->_on_bone_parent_changed();
  167. }
  168. }
  169. }
  170. }
  171. #ifndef DISABLE_DEPRECATED
  172. void _pb_stop_simulation_compat(Node *p_node) {
  173. PhysicalBoneSimulator3D *ps = Object::cast_to<PhysicalBoneSimulator3D>(p_node);
  174. if (ps) {
  175. return; // Prevent conflict.
  176. }
  177. for (int i = p_node->get_child_count() - 1; i >= 0; --i) {
  178. _pb_stop_simulation_compat(p_node->get_child(i));
  179. }
  180. PhysicalBone3D *pb = Object::cast_to<PhysicalBone3D>(p_node);
  181. if (pb) {
  182. pb->set_simulate_physics(false);
  183. }
  184. }
  185. #endif // _DISABLE_DEPRECATED
  186. void _pb_stop_simulation(Node *p_node) {
  187. for (int i = p_node->get_child_count() - 1; i >= 0; --i) {
  188. PhysicalBone3D *pb = Object::cast_to<PhysicalBone3D>(p_node->get_child(i));
  189. if (!pb) {
  190. continue;
  191. }
  192. _pb_stop_simulation(pb);
  193. }
  194. PhysicalBone3D *pb = Object::cast_to<PhysicalBone3D>(p_node);
  195. if (pb) {
  196. pb->set_simulate_physics(false);
  197. }
  198. }
  199. void PhysicalBoneSimulator3D::physical_bones_stop_simulation() {
  200. simulating = false;
  201. _reset_physical_bones_state();
  202. #ifndef DISABLE_DEPRECATED
  203. if (is_compat) {
  204. Skeleton3D *sk = get_skeleton();
  205. if (sk) {
  206. _pb_stop_simulation_compat(sk);
  207. }
  208. } else {
  209. _pb_stop_simulation(this);
  210. }
  211. #else
  212. _pb_stop_simulation(this);
  213. #endif // _DISABLE_DEPRECATED
  214. }
  215. #ifndef DISABLE_DEPRECATED
  216. void _pb_start_simulation_compat(const PhysicalBoneSimulator3D *p_simulator, Node *p_node, const Vector<int> &p_sim_bones) {
  217. PhysicalBoneSimulator3D *ps = Object::cast_to<PhysicalBoneSimulator3D>(p_node);
  218. if (ps) {
  219. return; // Prevent conflict.
  220. }
  221. for (int i = p_node->get_child_count() - 1; i >= 0; --i) {
  222. _pb_start_simulation_compat(p_simulator, p_node->get_child(i), p_sim_bones);
  223. }
  224. PhysicalBone3D *pb = Object::cast_to<PhysicalBone3D>(p_node);
  225. if (pb) {
  226. if (p_sim_bones.is_empty()) { // If no bones are specified, activate ragdoll on full body.
  227. pb->set_simulate_physics(true);
  228. } else {
  229. for (int i = p_sim_bones.size() - 1; i >= 0; --i) {
  230. if (p_sim_bones[i] == pb->get_bone_id() || p_simulator->is_bone_parent_of(pb->get_bone_id(), p_sim_bones[i])) {
  231. pb->set_simulate_physics(true);
  232. break;
  233. }
  234. }
  235. }
  236. }
  237. }
  238. #endif // _DISABLE_DEPRECATED
  239. void _pb_start_simulation(const PhysicalBoneSimulator3D *p_simulator, Node *p_node, const Vector<int> &p_sim_bones) {
  240. for (int i = p_node->get_child_count() - 1; i >= 0; --i) {
  241. PhysicalBone3D *pb = Object::cast_to<PhysicalBone3D>(p_node->get_child(i));
  242. if (!pb) {
  243. continue;
  244. }
  245. _pb_start_simulation(p_simulator, pb, p_sim_bones);
  246. }
  247. PhysicalBone3D *pb = Object::cast_to<PhysicalBone3D>(p_node);
  248. if (pb) {
  249. if (p_sim_bones.is_empty()) { // If no bones are specified, activate ragdoll on full body.
  250. pb->set_simulate_physics(true);
  251. } else {
  252. for (int i = p_sim_bones.size() - 1; i >= 0; --i) {
  253. if (p_sim_bones[i] == pb->get_bone_id() || p_simulator->is_bone_parent_of(pb->get_bone_id(), p_sim_bones[i])) {
  254. pb->set_simulate_physics(true);
  255. break;
  256. }
  257. }
  258. }
  259. }
  260. }
  261. void PhysicalBoneSimulator3D::physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones) {
  262. _pose_updated();
  263. simulating = true;
  264. _reset_physical_bones_state();
  265. Vector<int> sim_bones;
  266. if (p_bones.size() > 0) {
  267. sim_bones.resize(p_bones.size());
  268. int c = 0;
  269. for (int i = sim_bones.size() - 1; i >= 0; --i) {
  270. int bone_id = find_bone(p_bones[i]);
  271. if (bone_id != -1) {
  272. sim_bones.write[c++] = bone_id;
  273. }
  274. }
  275. sim_bones.resize(c);
  276. }
  277. #ifndef DISABLE_DEPRECATED
  278. if (is_compat) {
  279. Skeleton3D *sk = get_skeleton();
  280. if (sk) {
  281. _pb_start_simulation_compat(this, sk, sim_bones);
  282. }
  283. } else {
  284. _pb_start_simulation(this, this, sim_bones);
  285. }
  286. #else
  287. _pb_start_simulation(this, this, sim_bones);
  288. #endif // _DISABLE_DEPRECATED
  289. }
  290. void _physical_bones_add_remove_collision_exception(bool p_add, Node *p_node, RID p_exception) {
  291. for (int i = p_node->get_child_count() - 1; i >= 0; --i) {
  292. _physical_bones_add_remove_collision_exception(p_add, p_node->get_child(i), p_exception);
  293. }
  294. CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_node);
  295. if (co) {
  296. if (p_add) {
  297. PhysicsServer3D::get_singleton()->body_add_collision_exception(co->get_rid(), p_exception);
  298. } else {
  299. PhysicsServer3D::get_singleton()->body_remove_collision_exception(co->get_rid(), p_exception);
  300. }
  301. }
  302. }
  303. void PhysicalBoneSimulator3D::physical_bones_add_collision_exception(RID p_exception) {
  304. _physical_bones_add_remove_collision_exception(true, this, p_exception);
  305. }
  306. void PhysicalBoneSimulator3D::physical_bones_remove_collision_exception(RID p_exception) {
  307. _physical_bones_add_remove_collision_exception(false, this, p_exception);
  308. }
  309. Transform3D PhysicalBoneSimulator3D::get_bone_global_pose(int p_bone) const {
  310. const int bone_size = bones.size();
  311. ERR_FAIL_INDEX_V(p_bone, bone_size, Transform3D());
  312. return bones[p_bone].global_pose;
  313. }
  314. void PhysicalBoneSimulator3D::set_bone_global_pose(int p_bone, const Transform3D &p_pose) {
  315. const int bone_size = bones.size();
  316. ERR_FAIL_INDEX(p_bone, bone_size);
  317. bones.write[p_bone].global_pose = p_pose;
  318. }
  319. void PhysicalBoneSimulator3D::_process_modification() {
  320. Skeleton3D *skeleton = get_skeleton();
  321. if (!skeleton) {
  322. return;
  323. }
  324. ERR_FAIL_COND(skeleton->get_bone_count() != bones.size());
  325. for (int i = 0; i < skeleton->get_bone_count(); i++) {
  326. if (!bones[i].physical_bone) {
  327. continue;
  328. }
  329. if (bones[i].physical_bone->is_simulating_physics() == false) {
  330. _bone_pose_updated(skeleton, i);
  331. bones[i].physical_bone->reset_to_rest_position();
  332. } else if (simulating) {
  333. skeleton->set_bone_global_pose(i, bones[i].global_pose);
  334. }
  335. }
  336. }
  337. void PhysicalBoneSimulator3D::_bind_methods() {
  338. ClassDB::bind_method(D_METHOD("is_simulating_physics"), &PhysicalBoneSimulator3D::is_simulating_physics);
  339. ClassDB::bind_method(D_METHOD("physical_bones_stop_simulation"), &PhysicalBoneSimulator3D::physical_bones_stop_simulation);
  340. ClassDB::bind_method(D_METHOD("physical_bones_start_simulation", "bones"), &PhysicalBoneSimulator3D::physical_bones_start_simulation_on, DEFVAL(Array()));
  341. ClassDB::bind_method(D_METHOD("physical_bones_add_collision_exception", "exception"), &PhysicalBoneSimulator3D::physical_bones_add_collision_exception);
  342. ClassDB::bind_method(D_METHOD("physical_bones_remove_collision_exception", "exception"), &PhysicalBoneSimulator3D::physical_bones_remove_collision_exception);
  343. }
  344. PhysicalBoneSimulator3D::PhysicalBoneSimulator3D() {
  345. }