SpineBone.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. /******************************************************************************
  2. * Spine Runtimes License Agreement
  3. * Last updated January 1, 2020. Replaces all prior versions.
  4. *
  5. * Copyright (c) 2013-2020, Esoteric Software LLC
  6. *
  7. * Integration of the Spine Runtimes into software or otherwise creating
  8. * derivative works of the Spine Runtimes is permitted under the terms and
  9. * conditions of Section 2 of the Spine Editor License Agreement:
  10. * http://esotericsoftware.com/spine-editor-license
  11. *
  12. * Otherwise, it is permitted to integrate the Spine Runtimes into software
  13. * or otherwise create derivative works of the Spine Runtimes (collectively,
  14. * "Products"), provided that each user of the Products must obtain their own
  15. * Spine Editor license and redistribution of the Products in any form must
  16. * include this license and copyright notice.
  17. *
  18. * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
  19. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
  24. * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *****************************************************************************/
  29. #include "SpineBone.h"
  30. #include "SpineSprite.h"
  31. #include "SpineSkeleton.h"
  32. void SpineBone::_bind_methods() {
  33. ClassDB::bind_method(D_METHOD("update_world_transform"), &SpineBone::update_world_transform);
  34. // void set_to_setup_pose();
  35. //
  36. // Vector2 world_to_local(Vector2 world_position);
  37. //
  38. // Vector2 local_to_world(Vector2 local_position);
  39. //
  40. // float world_to_local_rotation(float world_rotation);
  41. //
  42. // float local_to_world_rotation(float local_rotation);
  43. //
  44. // void rotate_world(float degrees);
  45. ClassDB::bind_method(D_METHOD("set_to_setup_pose"), &SpineBone::set_to_setup_pose);
  46. ClassDB::bind_method(D_METHOD("world_to_local", "world_position"), &SpineBone::world_to_local);
  47. ClassDB::bind_method(D_METHOD("local_to_world", "local_position"), &SpineBone::local_to_world);
  48. ClassDB::bind_method(D_METHOD("world_to_local_rotation", "world_rotation"), &SpineBone::world_to_local_rotation);
  49. ClassDB::bind_method(D_METHOD("local_to_world_rotation", "local_rotation"), &SpineBone::local_to_world_rotation);
  50. ClassDB::bind_method(D_METHOD("rotate_world"), &SpineBone::rotate_world);
  51. //
  52. // float get_world_to_local_rotation_x();
  53. // float get_world_to_local_rotation_y();
  54. //
  55. // Ref<SpineBoneData> get_data();
  56. //
  57. // Ref<SpineSkeleton> get_skeleton();
  58. //
  59. // Ref<SpineBone> get_parent();
  60. //
  61. // Array get_children();
  62. ClassDB::bind_method(D_METHOD("get_world_to_local_rotation_x"), &SpineBone::get_world_to_local_rotation_x);
  63. ClassDB::bind_method(D_METHOD("get_world_to_local_rotation_y"), &SpineBone::get_world_to_local_rotation_y);
  64. ClassDB::bind_method(D_METHOD("get_data"), &SpineBone::get_data);
  65. ClassDB::bind_method(D_METHOD("get_skeleton"), &SpineBone::get_skeleton);
  66. ClassDB::bind_method(D_METHOD("get_parent"), &SpineBone::get_parent);
  67. ClassDB::bind_method(D_METHOD("get_children"), &SpineBone::get_children);
  68. //
  69. // float get_x();
  70. // void set_x(float v);
  71. //
  72. // float get_y();
  73. // void set_y(float v);
  74. //
  75. // float get_rotation();
  76. // void set_rotation(float v);
  77. //
  78. // float get_scale_x();
  79. // void set_scale_x(float v);
  80. ClassDB::bind_method(D_METHOD("get_x"), &SpineBone::get_x);
  81. ClassDB::bind_method(D_METHOD("set_x", "v"), &SpineBone::set_x);
  82. ClassDB::bind_method(D_METHOD("get_y"), &SpineBone::get_y);
  83. ClassDB::bind_method(D_METHOD("set_y", "v"), &SpineBone::set_y);
  84. ClassDB::bind_method(D_METHOD("get_rotation"), &SpineBone::get_rotation);
  85. ClassDB::bind_method(D_METHOD("set_rotation", "v"), &SpineBone::set_rotation);
  86. ClassDB::bind_method(D_METHOD("get_scale_x"), &SpineBone::get_scale_x);
  87. ClassDB::bind_method(D_METHOD("set_scale_x", "v"), &SpineBone::set_scale_x);
  88. //
  89. // float get_scale_y();
  90. // void set_scale_y(float v);
  91. //
  92. // float get_shear_x();
  93. // void set_shear_x(float v);
  94. //
  95. // float get_shear_y();
  96. // void set_shear_y(float v);
  97. //
  98. // float get_applied_rotation();
  99. // void set_applied_rotation(float v);
  100. ClassDB::bind_method(D_METHOD("get_scale_y"), &SpineBone::get_scale_y);
  101. ClassDB::bind_method(D_METHOD("set_scale_y", "v"), &SpineBone::set_scale_y);
  102. ClassDB::bind_method(D_METHOD("get_shear_x"), &SpineBone::get_shear_x);
  103. ClassDB::bind_method(D_METHOD("set_shear_x", "v"), &SpineBone::set_shear_x);
  104. ClassDB::bind_method(D_METHOD("get_shear_y"), &SpineBone::get_shear_y);
  105. ClassDB::bind_method(D_METHOD("set_shear_y", "v"), &SpineBone::set_shear_y);
  106. ClassDB::bind_method(D_METHOD("get_applied_rotation"), &SpineBone::get_applied_rotation);
  107. ClassDB::bind_method(D_METHOD("set_applied_rotation", "v"), &SpineBone::set_applied_rotation);
  108. //
  109. // float get_a_x();
  110. // void set_a_x(float v);
  111. //
  112. // float get_a_y();
  113. // void set_a_y(float v);
  114. //
  115. // float get_a_scale_x();
  116. // void set_a_scale_x(float v);
  117. //
  118. // float get_a_scale_y();
  119. // void set_a_scale_y(float v);
  120. ClassDB::bind_method(D_METHOD("get_a_x"), &SpineBone::get_a_x);
  121. ClassDB::bind_method(D_METHOD("set_a_x", "v"), &SpineBone::set_a_x);
  122. ClassDB::bind_method(D_METHOD("get_a_y"), &SpineBone::get_a_y);
  123. ClassDB::bind_method(D_METHOD("set_a_y", "v"), &SpineBone::set_a_y);
  124. ClassDB::bind_method(D_METHOD("get_a_scale_x"), &SpineBone::get_a_scale_x);
  125. ClassDB::bind_method(D_METHOD("set_a_scale_x", "v"), &SpineBone::set_a_scale_x);
  126. ClassDB::bind_method(D_METHOD("get_a_scale_y"), &SpineBone::get_a_scale_y);
  127. ClassDB::bind_method(D_METHOD("set_a_scale_y", "v"), &SpineBone::set_a_scale_y);
  128. //
  129. // float get_a_shear_x();
  130. // void set_a_shear_x(float v);
  131. //
  132. // float get_a_shear_y();
  133. // void set_a_shear_y(float v);
  134. //
  135. // float get_a();
  136. // void set_a(float v);
  137. //
  138. // float get_b();
  139. // void set_b(float v);
  140. ClassDB::bind_method(D_METHOD("get_a_shear_x"), &SpineBone::get_a_shear_x);
  141. ClassDB::bind_method(D_METHOD("set_a_shear_x", "v"), &SpineBone::set_a_shear_x);
  142. ClassDB::bind_method(D_METHOD("get_a_shear_y"), &SpineBone::get_a_shear_y);
  143. ClassDB::bind_method(D_METHOD("set_a_shear_y", "v"), &SpineBone::set_a_shear_y);
  144. ClassDB::bind_method(D_METHOD("get_a"), &SpineBone::get_a);
  145. ClassDB::bind_method(D_METHOD("set_a", "v"), &SpineBone::set_a);
  146. ClassDB::bind_method(D_METHOD("get_b"), &SpineBone::get_b);
  147. ClassDB::bind_method(D_METHOD("set_b", "v"), &SpineBone::set_b);
  148. //
  149. // float get_c();
  150. // void set_c(float v);
  151. //
  152. // float get_d();
  153. // void set_d(float v);
  154. //
  155. // float get_world_x();
  156. // void set_world_x(float v);
  157. //
  158. // float get_world_y();
  159. // void set_world_y(float v);
  160. ClassDB::bind_method(D_METHOD("get_c"), &SpineBone::get_c);
  161. ClassDB::bind_method(D_METHOD("set_c", "v"), &SpineBone::set_c);
  162. ClassDB::bind_method(D_METHOD("get_d"), &SpineBone::get_d);
  163. ClassDB::bind_method(D_METHOD("set_d", "v"), &SpineBone::set_d);
  164. ClassDB::bind_method(D_METHOD("get_world_x"), &SpineBone::get_world_x);
  165. ClassDB::bind_method(D_METHOD("set_world_x", "v"), &SpineBone::set_world_x);
  166. ClassDB::bind_method(D_METHOD("get_world_y"), &SpineBone::get_world_y);
  167. ClassDB::bind_method(D_METHOD("set_world_y", "v"), &SpineBone::set_world_y);
  168. //
  169. // float get_world_rotation_x();
  170. // float get_world_rotation_y();
  171. //
  172. // float get_world_scale_x();
  173. // float get_world_scale_y();
  174. //
  175. // bool is_applied_valid();
  176. // void set_applied_valid(bool v);
  177. //
  178. // bool is_active();
  179. // void set_active(bool v);
  180. ClassDB::bind_method(D_METHOD("get_world_rotation_x"), &SpineBone::get_world_rotation_x);
  181. ClassDB::bind_method(D_METHOD("get_world_rotation_y"), &SpineBone::get_world_rotation_y);
  182. ClassDB::bind_method(D_METHOD("get_world_scale_x"), &SpineBone::get_world_scale_x);
  183. ClassDB::bind_method(D_METHOD("get_world_scale_y"), &SpineBone::get_world_scale_y);
  184. ClassDB::bind_method(D_METHOD("is_active"), &SpineBone::is_active);
  185. ClassDB::bind_method(D_METHOD("set_active", "v"), &SpineBone::set_active);
  186. ClassDB::bind_method(D_METHOD("get_godot_transform"), &SpineBone::get_godot_transform);
  187. ClassDB::bind_method(D_METHOD("set_godot_transform", "local_transform"), &SpineBone::set_godot_transform);
  188. ClassDB::bind_method(D_METHOD("get_godot_global_transform"), &SpineBone::get_godot_global_transform);
  189. ClassDB::bind_method(D_METHOD("set_godot_global_transform", "global_transform"), &SpineBone::set_godot_global_transform);
  190. ClassDB::bind_method(D_METHOD("apply_world_transform_2d", "node2d"), &SpineBone::apply_world_transform_2d);
  191. }
  192. SpineBone::SpineBone():bone(NULL), the_sprite(nullptr) {}
  193. SpineBone::~SpineBone() {}
  194. void SpineBone::update_world_transform(){
  195. bone->updateWorldTransform();
  196. }
  197. void SpineBone::set_to_setup_pose(){
  198. bone->setToSetupPose();
  199. }
  200. Vector2 SpineBone::world_to_local(Vector2 world_position){
  201. float x, y;
  202. bone->worldToLocal(world_position.x, world_position.y, x, y);
  203. return Vector2(x, y);
  204. }
  205. Vector2 SpineBone::local_to_world(Vector2 local_position){
  206. float x, y;
  207. bone->localToWorld(local_position.x, local_position.y, x, y);
  208. return Vector2(x, y);
  209. }
  210. float SpineBone::world_to_local_rotation(float world_rotation){
  211. return bone->worldToLocalRotation(world_rotation);
  212. }
  213. float SpineBone::local_to_world_rotation(float local_rotation){
  214. return bone->localToWorldRotation(local_rotation);
  215. }
  216. void SpineBone::rotate_world(float degrees){
  217. bone->rotateWorld(degrees);
  218. }
  219. float SpineBone::get_world_to_local_rotation_x(){
  220. return bone->getWorldToLocalRotationX();
  221. }
  222. float SpineBone::get_world_to_local_rotation_y(){
  223. return bone->getWorldToLocalRotationY();
  224. }
  225. Ref<SpineBoneData> SpineBone::get_data(){
  226. auto &bd = bone->getData();
  227. Ref<SpineBoneData> gd_bd(memnew(SpineBoneData));
  228. gd_bd->set_spine_object(&bd);
  229. return gd_bd;
  230. }
  231. Ref<SpineSkeleton> SpineBone::get_skeleton(){
  232. auto &s = bone->getSkeleton();
  233. Ref<SpineSkeleton> gd_s(memnew(SpineSkeleton));
  234. gd_s->set_spine_object(&s);
  235. gd_s->set_spine_sprite(the_sprite);
  236. return gd_s;
  237. }
  238. Ref<SpineBone> SpineBone::get_parent(){
  239. auto b = bone->getParent();
  240. if(b == NULL) return NULL;
  241. Ref<SpineBone> gd_b(memnew(SpineBone));
  242. gd_b->set_spine_object(b);
  243. gd_b->set_spine_sprite(the_sprite);
  244. return gd_b;
  245. }
  246. Array SpineBone::get_children(){
  247. auto bs = bone->getChildren();
  248. Array gd_bs;
  249. gd_bs.resize(bs.size());
  250. for(size_t i=0; i < bs.size(); ++i){
  251. auto b = bs[i];
  252. if(b == NULL) gd_bs[i] = Ref<SpineBone>(NULL);
  253. Ref<SpineBone> gd_b(memnew(SpineBone));
  254. gd_b->set_spine_object(b);
  255. gd_b->set_spine_sprite(the_sprite);
  256. gd_bs[i] = gd_b;
  257. }
  258. return gd_bs;
  259. }
  260. float SpineBone::get_x(){
  261. return bone->getX();
  262. }
  263. void SpineBone::set_x(float v){
  264. bone->setX(v);
  265. }
  266. float SpineBone::get_y(){
  267. return bone->getY();
  268. }
  269. void SpineBone::set_y(float v){
  270. bone->setY(v);
  271. }
  272. float SpineBone::get_rotation(){
  273. return bone->getRotation();
  274. }
  275. void SpineBone::set_rotation(float v){
  276. bone->setRotation(v);
  277. }
  278. float SpineBone::get_scale_x(){
  279. return bone->getScaleX();
  280. }
  281. void SpineBone::set_scale_x(float v){
  282. bone->setScaleX(v);
  283. }
  284. float SpineBone::get_scale_y(){
  285. return bone->getScaleY();
  286. }
  287. void SpineBone::set_scale_y(float v){
  288. bone->setScaleY(v);
  289. }
  290. float SpineBone::get_shear_x(){
  291. return bone->getShearX();
  292. }
  293. void SpineBone::set_shear_x(float v){
  294. bone->setShearX(v);
  295. }
  296. float SpineBone::get_shear_y(){
  297. return bone->getShearY();
  298. }
  299. void SpineBone::set_shear_y(float v){
  300. bone->setShearY(v);
  301. }
  302. float SpineBone::get_applied_rotation(){
  303. return bone->getAppliedRotation();
  304. }
  305. void SpineBone::set_applied_rotation(float v){
  306. bone->setAppliedRotation(v);
  307. }
  308. float SpineBone::get_a_x(){
  309. return bone->getAX();
  310. }
  311. void SpineBone::set_a_x(float v){
  312. bone->setAX(v);
  313. }
  314. float SpineBone::get_a_y(){
  315. return bone->getAY();
  316. }
  317. void SpineBone::set_a_y(float v){
  318. bone->setAY(v);
  319. }
  320. float SpineBone::get_a_scale_x(){
  321. return bone->getAScaleX();
  322. }
  323. void SpineBone::set_a_scale_x(float v){
  324. bone->setAScaleX(v);
  325. }
  326. float SpineBone::get_a_scale_y(){
  327. return bone->getAScaleY();
  328. }
  329. void SpineBone::set_a_scale_y(float v){
  330. bone->setAScaleY(v);
  331. }
  332. float SpineBone::get_a_shear_x(){
  333. return bone->getAShearX();
  334. }
  335. void SpineBone::set_a_shear_x(float v){
  336. bone->setAShearX(v);
  337. }
  338. float SpineBone::get_a_shear_y(){
  339. return bone->getAShearY();
  340. }
  341. void SpineBone::set_a_shear_y(float v){
  342. bone->setAShearY(v);
  343. }
  344. float SpineBone::get_a(){
  345. return bone->getA();
  346. }
  347. void SpineBone::set_a(float v){
  348. bone->setA(v);
  349. }
  350. float SpineBone::get_b(){
  351. return bone->getB();
  352. }
  353. void SpineBone::set_b(float v){
  354. bone->setB(v);
  355. }
  356. float SpineBone::get_c(){
  357. return bone->getC();
  358. }
  359. void SpineBone::set_c(float v){
  360. bone->setC(v);
  361. }
  362. float SpineBone::get_d(){
  363. return bone->getD();
  364. }
  365. void SpineBone::set_d(float v){
  366. bone->setD(v);
  367. }
  368. float SpineBone::get_world_x(){
  369. return bone->getWorldX();
  370. }
  371. void SpineBone::set_world_x(float v){
  372. bone->setWorldX(v);
  373. }
  374. float SpineBone::get_world_y(){
  375. return bone->getWorldY();
  376. }
  377. void SpineBone::set_world_y(float v){
  378. bone->setWorldY(v);
  379. }
  380. float SpineBone::get_world_rotation_x(){
  381. return bone->getWorldRotationX();
  382. }
  383. float SpineBone::get_world_rotation_y(){
  384. return bone->getWorldRotationY();
  385. }
  386. float SpineBone::get_world_scale_x(){
  387. return bone->getWorldScaleX();
  388. }
  389. float SpineBone::get_world_scale_y(){
  390. return bone->getWorldScaleY();
  391. }
  392. bool SpineBone::is_active(){
  393. return bone->isActive();
  394. }
  395. void SpineBone::set_active(bool v){
  396. bone->setActive(v);
  397. }
  398. // External feature functions
  399. void SpineBone::apply_world_transform_2d(Variant o){
  400. if(o.get_type() == Variant::OBJECT){
  401. auto node = (Node*) o;
  402. if(node->is_class("Node2D")){
  403. auto node2d = (Node2D*) node;
  404. // In godot the y-axis is nag to spine
  405. node2d->set_transform(Transform2D(
  406. get_a(), get_c(),
  407. get_b(), get_d(),
  408. get_world_x(), -get_world_y())
  409. );
  410. // Fix the rotation
  411. auto pos = node2d->get_position();
  412. node2d->translate(-pos);
  413. node2d->set_rotation(-node2d->get_rotation());
  414. node2d->translate(pos);
  415. }
  416. }
  417. }
  418. Transform2D SpineBone::get_godot_transform() {
  419. if (get_spine_object() == nullptr)
  420. return Transform2D();
  421. Transform2D trans;
  422. trans.translate(get_x(), -get_y());
  423. // It seems that spine uses degree for rotation
  424. trans.rotate(Math::deg2rad(-get_rotation()));
  425. trans.scale(Size2(get_scale_x(), get_scale_y()));
  426. return trans;
  427. }
  428. void SpineBone::set_godot_transform(Transform2D trans) {
  429. if (get_spine_object() == nullptr)
  430. return;
  431. Vector2 position = trans.get_origin();
  432. position.y *= -1;
  433. real_t rotation = trans.get_rotation();
  434. rotation = Math::rad2deg(-rotation);
  435. Vector2 scale = trans.get_scale();
  436. set_x(position.x);
  437. set_y(position.y);
  438. set_rotation(rotation);
  439. set_scale_x(scale.x);
  440. set_scale_y(scale.y);
  441. }
  442. Transform2D SpineBone::get_godot_global_transform() {
  443. if (get_spine_object() == nullptr)
  444. return Transform2D();
  445. if (the_sprite == nullptr)
  446. return get_godot_transform();
  447. Transform2D res = the_sprite->get_transform();
  448. res.translate(get_world_x(), -get_world_y());
  449. res.rotate(Math::deg2rad(-get_world_rotation_x()));
  450. res.scale(Vector2(get_world_scale_x(), get_world_scale_y()));
  451. auto p = the_sprite->get_parent() ? Object::cast_to<CanvasItem>(the_sprite->get_parent()) : nullptr;
  452. if (p) {
  453. return p->get_global_transform() * res;
  454. }
  455. return res;
  456. }
  457. void SpineBone::set_godot_global_transform(Transform2D transform) {
  458. if (get_spine_object() == nullptr)
  459. return;
  460. if (the_sprite == nullptr)
  461. set_godot_transform(transform);
  462. transform = the_sprite->get_global_transform().affine_inverse() * transform;
  463. Vector2 position = transform.get_origin();
  464. real_t rotation = transform.get_rotation();
  465. Vector2 scale = transform.get_scale();
  466. position.y *= -1;
  467. auto parent = get_parent();
  468. if (parent.is_valid()) {
  469. position = parent->world_to_local(position);
  470. if (parent->get_world_scale_x() != 0)
  471. scale.x /= parent->get_world_scale_x();
  472. else
  473. print_error("The parent scale.x is zero.");
  474. if (parent->get_world_scale_y() != 0)
  475. scale.y /= parent->get_world_scale_y();
  476. else
  477. print_error("The parent scale.y is zero.");
  478. }
  479. rotation = world_to_local_rotation(Math::rad2deg(-rotation));
  480. set_x(position.x);
  481. set_y(position.y);
  482. set_rotation(rotation);
  483. set_scale_x(scale.x);
  484. set_scale_y(scale.y);
  485. }
  486. void SpineBone::set_spine_sprite(SpineSprite *s) {
  487. the_sprite = s;
  488. }