skeleton.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. /*************************************************************************/
  2. /* skeleton.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
  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 "skeleton.h"
  31. #include "message_queue.h"
  32. #include "core/project_settings.h"
  33. #include "scene/resources/surface_tool.h"
  34. bool Skeleton::_set(const StringName &p_path, const Variant &p_value) {
  35. String path = p_path;
  36. if (!path.begins_with("bones/"))
  37. return false;
  38. int which = path.get_slicec('/', 1).to_int();
  39. String what = path.get_slicec('/', 2);
  40. if (which == bones.size() && what == "name") {
  41. add_bone(p_value);
  42. return true;
  43. }
  44. ERR_FAIL_INDEX_V(which, bones.size(), false);
  45. if (what == "parent")
  46. set_bone_parent(which, p_value);
  47. else if (what == "rest")
  48. set_bone_rest(which, p_value);
  49. else if (what == "enabled")
  50. set_bone_enabled(which, p_value);
  51. else if (what == "pose")
  52. set_bone_pose(which, p_value);
  53. else if (what == "bound_childs") {
  54. Array children = p_value;
  55. if (is_inside_tree()) {
  56. bones[which].nodes_bound.clear();
  57. for (int i = 0; i < children.size(); i++) {
  58. NodePath path = children[i];
  59. ERR_CONTINUE(path.operator String() == "");
  60. Node *node = get_node(path);
  61. ERR_CONTINUE(!node);
  62. bind_child_node_to_bone(which, node);
  63. }
  64. }
  65. } else {
  66. return false;
  67. }
  68. return true;
  69. }
  70. bool Skeleton::_get(const StringName &p_path, Variant &r_ret) const {
  71. String path = p_path;
  72. if (!path.begins_with("bones/"))
  73. return false;
  74. int which = path.get_slicec('/', 1).to_int();
  75. String what = path.get_slicec('/', 2);
  76. ERR_FAIL_INDEX_V(which, bones.size(), false);
  77. if (what == "name")
  78. r_ret = get_bone_name(which);
  79. else if (what == "parent")
  80. r_ret = get_bone_parent(which);
  81. else if (what == "rest")
  82. r_ret = get_bone_rest(which);
  83. else if (what == "enabled")
  84. r_ret = is_bone_enabled(which);
  85. else if (what == "pose")
  86. r_ret = get_bone_pose(which);
  87. else if (what == "bound_childs") {
  88. Array children;
  89. for (const List<uint32_t>::Element *E = bones[which].nodes_bound.front(); E; E = E->next()) {
  90. Object *obj = ObjectDB::get_instance(E->get());
  91. ERR_CONTINUE(!obj);
  92. Node *node = Object::cast_to<Node>(obj);
  93. ERR_CONTINUE(!node);
  94. NodePath path = get_path_to(node);
  95. children.push_back(path);
  96. }
  97. r_ret = children;
  98. } else
  99. return false;
  100. return true;
  101. }
  102. void Skeleton::_get_property_list(List<PropertyInfo> *p_list) const {
  103. for (int i = 0; i < bones.size(); i++) {
  104. String prep = "bones/" + itos(i) + "/";
  105. p_list->push_back(PropertyInfo(Variant::STRING, prep + "name"));
  106. p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(i - 1) + ",1"));
  107. p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "rest"));
  108. p_list->push_back(PropertyInfo(Variant::BOOL, prep + "enabled"));
  109. p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
  110. p_list->push_back(PropertyInfo(Variant::ARRAY, prep + "bound_childs"));
  111. }
  112. }
  113. void Skeleton::_notification(int p_what) {
  114. switch (p_what) {
  115. case NOTIFICATION_ENTER_WORLD: {
  116. if (dirty) {
  117. dirty = false;
  118. _make_dirty(); // property make it dirty
  119. }
  120. } break;
  121. case NOTIFICATION_EXIT_WORLD: {
  122. } break;
  123. case NOTIFICATION_UPDATE_SKELETON: {
  124. VisualServer *vs = VisualServer::get_singleton();
  125. Bone *bonesptr = &bones[0];
  126. int len = bones.size();
  127. vs->skeleton_allocate(skeleton, len); // if same size, nothin really happens
  128. // pose changed, rebuild cache of inverses
  129. if (rest_global_inverse_dirty) {
  130. // calculate global rests and invert them
  131. for (int i = 0; i < len; i++) {
  132. Bone &b = bonesptr[i];
  133. if (b.parent >= 0)
  134. b.rest_global_inverse = bonesptr[b.parent].rest_global_inverse * b.rest;
  135. else
  136. b.rest_global_inverse = b.rest;
  137. }
  138. for (int i = 0; i < len; i++) {
  139. Bone &b = bonesptr[i];
  140. b.rest_global_inverse.affine_invert();
  141. }
  142. rest_global_inverse_dirty = false;
  143. }
  144. for (int i = 0; i < len; i++) {
  145. Bone &b = bonesptr[i];
  146. if (b.disable_rest) {
  147. if (b.enabled) {
  148. Transform pose = b.pose;
  149. if (b.custom_pose_enable) {
  150. pose = b.custom_pose * pose;
  151. }
  152. if (b.parent >= 0) {
  153. b.pose_global = bonesptr[b.parent].pose_global * pose;
  154. } else {
  155. b.pose_global = pose;
  156. }
  157. } else {
  158. if (b.parent >= 0) {
  159. b.pose_global = bonesptr[b.parent].pose_global;
  160. } else {
  161. b.pose_global = Transform();
  162. }
  163. }
  164. } else {
  165. if (b.enabled) {
  166. Transform pose = b.pose;
  167. if (b.custom_pose_enable) {
  168. pose = b.custom_pose * pose;
  169. }
  170. if (b.parent >= 0) {
  171. b.pose_global = bonesptr[b.parent].pose_global * (b.rest * pose);
  172. } else {
  173. b.pose_global = b.rest * pose;
  174. }
  175. } else {
  176. if (b.parent >= 0) {
  177. b.pose_global = bonesptr[b.parent].pose_global * b.rest;
  178. } else {
  179. b.pose_global = b.rest;
  180. }
  181. }
  182. }
  183. vs->skeleton_bone_set_transform(skeleton, i, b.pose_global * b.rest_global_inverse);
  184. for (List<uint32_t>::Element *E = b.nodes_bound.front(); E; E = E->next()) {
  185. Object *obj = ObjectDB::get_instance(E->get());
  186. ERR_CONTINUE(!obj);
  187. Spatial *sp = Object::cast_to<Spatial>(obj);
  188. ERR_CONTINUE(!sp);
  189. sp->set_transform(b.pose_global);
  190. }
  191. }
  192. dirty = false;
  193. } break;
  194. }
  195. }
  196. Transform Skeleton::get_bone_transform(int p_bone) const {
  197. ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
  198. if (dirty)
  199. const_cast<Skeleton *>(this)->notification(NOTIFICATION_UPDATE_SKELETON);
  200. return bones[p_bone].pose_global * bones[p_bone].rest_global_inverse;
  201. }
  202. void Skeleton::set_bone_global_pose(int p_bone, const Transform &p_pose) {
  203. ERR_FAIL_INDEX(p_bone, bones.size());
  204. if (bones[p_bone].parent == -1) {
  205. set_bone_pose(p_bone, bones[p_bone].rest_global_inverse * p_pose); //fast
  206. } else {
  207. set_bone_pose(p_bone, bones[p_bone].rest.affine_inverse() * (get_bone_global_pose(bones[p_bone].parent).affine_inverse() * p_pose)); //slow
  208. }
  209. }
  210. Transform Skeleton::get_bone_global_pose(int p_bone) const {
  211. ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
  212. if (dirty)
  213. const_cast<Skeleton *>(this)->notification(NOTIFICATION_UPDATE_SKELETON);
  214. return bones[p_bone].pose_global;
  215. }
  216. RID Skeleton::get_skeleton() const {
  217. return skeleton;
  218. }
  219. // skeleton creation api
  220. void Skeleton::add_bone(const String &p_name) {
  221. ERR_FAIL_COND(p_name == "" || p_name.find(":") != -1 || p_name.find("/") != -1);
  222. for (int i = 0; i < bones.size(); i++) {
  223. ERR_FAIL_COND(bones[i].name == "p_name");
  224. }
  225. Bone b;
  226. b.name = p_name;
  227. bones.push_back(b);
  228. rest_global_inverse_dirty = true;
  229. _make_dirty();
  230. update_gizmo();
  231. }
  232. int Skeleton::find_bone(String p_name) const {
  233. for (int i = 0; i < bones.size(); i++) {
  234. if (bones[i].name == p_name)
  235. return i;
  236. }
  237. return -1;
  238. }
  239. String Skeleton::get_bone_name(int p_bone) const {
  240. ERR_FAIL_INDEX_V(p_bone, bones.size(), "");
  241. return bones[p_bone].name;
  242. }
  243. int Skeleton::get_bone_count() const {
  244. return bones.size();
  245. }
  246. void Skeleton::set_bone_parent(int p_bone, int p_parent) {
  247. ERR_FAIL_INDEX(p_bone, bones.size());
  248. ERR_FAIL_COND(p_parent != -1 && (p_parent < 0 || p_parent >= p_bone));
  249. bones[p_bone].parent = p_parent;
  250. rest_global_inverse_dirty = true;
  251. _make_dirty();
  252. }
  253. void Skeleton::unparent_bone_and_rest(int p_bone) {
  254. ERR_FAIL_INDEX(p_bone, bones.size());
  255. int parent = bones[p_bone].parent;
  256. while (parent >= 0) {
  257. bones[p_bone].rest = bones[parent].rest * bones[p_bone].rest;
  258. parent = bones[parent].parent;
  259. }
  260. bones[p_bone].parent = -1;
  261. bones[p_bone].rest_global_inverse = bones[p_bone].rest.affine_inverse(); //same thing
  262. _make_dirty();
  263. }
  264. void Skeleton::set_bone_disable_rest(int p_bone, bool p_disable) {
  265. ERR_FAIL_INDEX(p_bone, bones.size());
  266. bones[p_bone].disable_rest = p_disable;
  267. }
  268. bool Skeleton::is_bone_rest_disabled(int p_bone) const {
  269. ERR_FAIL_INDEX_V(p_bone, bones.size(), false);
  270. return bones[p_bone].disable_rest;
  271. }
  272. int Skeleton::get_bone_parent(int p_bone) const {
  273. ERR_FAIL_INDEX_V(p_bone, bones.size(), -1);
  274. return bones[p_bone].parent;
  275. }
  276. void Skeleton::set_bone_rest(int p_bone, const Transform &p_rest) {
  277. ERR_FAIL_INDEX(p_bone, bones.size());
  278. bones[p_bone].rest = p_rest;
  279. rest_global_inverse_dirty = true;
  280. _make_dirty();
  281. }
  282. Transform Skeleton::get_bone_rest(int p_bone) const {
  283. ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
  284. return bones[p_bone].rest;
  285. }
  286. void Skeleton::set_bone_enabled(int p_bone, bool p_enabled) {
  287. ERR_FAIL_INDEX(p_bone, bones.size());
  288. bones[p_bone].enabled = p_enabled;
  289. rest_global_inverse_dirty = true;
  290. _make_dirty();
  291. }
  292. bool Skeleton::is_bone_enabled(int p_bone) const {
  293. ERR_FAIL_INDEX_V(p_bone, bones.size(), false);
  294. return bones[p_bone].enabled;
  295. }
  296. void Skeleton::bind_child_node_to_bone(int p_bone, Node *p_node) {
  297. ERR_FAIL_NULL(p_node);
  298. ERR_FAIL_INDEX(p_bone, bones.size());
  299. uint32_t id = p_node->get_instance_id();
  300. for (List<uint32_t>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
  301. if (E->get() == id)
  302. return; // already here
  303. }
  304. bones[p_bone].nodes_bound.push_back(id);
  305. }
  306. void Skeleton::unbind_child_node_from_bone(int p_bone, Node *p_node) {
  307. ERR_FAIL_NULL(p_node);
  308. ERR_FAIL_INDEX(p_bone, bones.size());
  309. uint32_t id = p_node->get_instance_id();
  310. bones[p_bone].nodes_bound.erase(id);
  311. }
  312. void Skeleton::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const {
  313. ERR_FAIL_INDEX(p_bone, bones.size());
  314. for (const List<uint32_t>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
  315. Object *obj = ObjectDB::get_instance(E->get());
  316. ERR_CONTINUE(!obj);
  317. p_bound->push_back(Object::cast_to<Node>(obj));
  318. }
  319. }
  320. void Skeleton::clear_bones() {
  321. bones.clear();
  322. rest_global_inverse_dirty = true;
  323. _make_dirty();
  324. }
  325. // posing api
  326. void Skeleton::set_bone_pose(int p_bone, const Transform &p_pose) {
  327. ERR_FAIL_INDEX(p_bone, bones.size());
  328. ERR_FAIL_COND(!is_inside_tree());
  329. bones[p_bone].pose = p_pose;
  330. _make_dirty();
  331. }
  332. Transform Skeleton::get_bone_pose(int p_bone) const {
  333. ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
  334. return bones[p_bone].pose;
  335. }
  336. void Skeleton::set_bone_custom_pose(int p_bone, const Transform &p_custom_pose) {
  337. ERR_FAIL_INDEX(p_bone, bones.size());
  338. //ERR_FAIL_COND( !is_inside_scene() );
  339. bones[p_bone].custom_pose_enable = (p_custom_pose != Transform());
  340. bones[p_bone].custom_pose = p_custom_pose;
  341. _make_dirty();
  342. }
  343. Transform Skeleton::get_bone_custom_pose(int p_bone) const {
  344. ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
  345. return bones[p_bone].custom_pose;
  346. }
  347. void Skeleton::_make_dirty() {
  348. if (dirty)
  349. return;
  350. if (!is_inside_tree()) {
  351. dirty = true;
  352. return;
  353. }
  354. MessageQueue::get_singleton()->push_notification(this, NOTIFICATION_UPDATE_SKELETON);
  355. dirty = true;
  356. }
  357. void Skeleton::localize_rests() {
  358. for (int i = bones.size() - 1; i >= 0; i--) {
  359. if (bones[i].parent >= 0)
  360. set_bone_rest(i, bones[bones[i].parent].rest.affine_inverse() * bones[i].rest);
  361. }
  362. }
  363. void Skeleton::_bind_methods() {
  364. ClassDB::bind_method(D_METHOD("add_bone", "name"), &Skeleton::add_bone);
  365. ClassDB::bind_method(D_METHOD("find_bone", "name"), &Skeleton::find_bone);
  366. ClassDB::bind_method(D_METHOD("get_bone_name", "bone_idx"), &Skeleton::get_bone_name);
  367. ClassDB::bind_method(D_METHOD("get_bone_parent", "bone_idx"), &Skeleton::get_bone_parent);
  368. ClassDB::bind_method(D_METHOD("set_bone_parent", "bone_idx", "parent_idx"), &Skeleton::set_bone_parent);
  369. ClassDB::bind_method(D_METHOD("get_bone_count"), &Skeleton::get_bone_count);
  370. ClassDB::bind_method(D_METHOD("unparent_bone_and_rest", "bone_idx"), &Skeleton::unparent_bone_and_rest);
  371. ClassDB::bind_method(D_METHOD("get_bone_rest", "bone_idx"), &Skeleton::get_bone_rest);
  372. ClassDB::bind_method(D_METHOD("set_bone_rest", "bone_idx", "rest"), &Skeleton::set_bone_rest);
  373. ClassDB::bind_method(D_METHOD("set_bone_disable_rest", "bone_idx", "disable"), &Skeleton::set_bone_disable_rest);
  374. ClassDB::bind_method(D_METHOD("is_bone_rest_disabled", "bone_idx"), &Skeleton::is_bone_rest_disabled);
  375. ClassDB::bind_method(D_METHOD("bind_child_node_to_bone", "bone_idx", "node"), &Skeleton::bind_child_node_to_bone);
  376. ClassDB::bind_method(D_METHOD("unbind_child_node_from_bone", "bone_idx", "node"), &Skeleton::unbind_child_node_from_bone);
  377. ClassDB::bind_method(D_METHOD("get_bound_child_nodes_to_bone", "bone_idx"), &Skeleton::_get_bound_child_nodes_to_bone);
  378. ClassDB::bind_method(D_METHOD("clear_bones"), &Skeleton::clear_bones);
  379. ClassDB::bind_method(D_METHOD("get_bone_pose", "bone_idx"), &Skeleton::get_bone_pose);
  380. ClassDB::bind_method(D_METHOD("set_bone_pose", "bone_idx", "pose"), &Skeleton::set_bone_pose);
  381. ClassDB::bind_method(D_METHOD("set_bone_global_pose", "bone_idx", "pose"), &Skeleton::set_bone_global_pose);
  382. ClassDB::bind_method(D_METHOD("get_bone_global_pose", "bone_idx"), &Skeleton::get_bone_global_pose);
  383. ClassDB::bind_method(D_METHOD("get_bone_custom_pose", "bone_idx"), &Skeleton::get_bone_custom_pose);
  384. ClassDB::bind_method(D_METHOD("set_bone_custom_pose", "bone_idx", "custom_pose"), &Skeleton::set_bone_custom_pose);
  385. ClassDB::bind_method(D_METHOD("get_bone_transform", "bone_idx"), &Skeleton::get_bone_transform);
  386. BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON);
  387. }
  388. Skeleton::Skeleton() {
  389. rest_global_inverse_dirty = true;
  390. dirty = false;
  391. skeleton = VisualServer::get_singleton()->skeleton_create();
  392. }
  393. Skeleton::~Skeleton() {
  394. VisualServer::get_singleton()->free(skeleton);
  395. }