SpineSprite.cpp 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171
  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 "SpineSprite.h"
  30. #include "SpineEvent.h"
  31. #include "SpineTrackEntry.h"
  32. #include "SpineSkeleton.h"
  33. #include "SpineRendererObject.h"
  34. #include "SpineSlotNode.h"
  35. #if VERSION_MAJOR > 3
  36. #include "core/config/engine.h"
  37. #include "core/math/geometry_2d.h"
  38. #include "core/math/transform_2d.h"
  39. #include "core/variant/array.h"
  40. #include "scene/resources/mesh.h"
  41. #include "servers/rendering_server.h"
  42. #else
  43. #include "core/engine.h"
  44. #endif
  45. #include "scene/gui/control.h"
  46. #include "scene/main/viewport.h"
  47. #if TOOLS_ENABLED
  48. #include "editor/editor_plugin.h"
  49. #endif
  50. Ref<CanvasItemMaterial> SpineSprite::default_materials[4] = {};
  51. static int sprite_count = 0;
  52. static spine::Vector<unsigned short> quad_indices;
  53. static spine::Vector<float> scratch_vertices;
  54. static Vector<Vector2> scratch_points;
  55. static void clear_triangles(SpineMesh2D *mesh_instance) {
  56. #if VERSION_MAJOR > 3
  57. RenderingServer::get_singleton()->canvas_item_clear(mesh_instance->get_canvas_item());
  58. #else
  59. VisualServer::get_singleton()->canvas_item_clear(mesh_instance->get_canvas_item());
  60. #endif
  61. }
  62. static void add_triangles(SpineMesh2D *mesh_instance,
  63. const Vector<Point2> &vertices,
  64. const Vector<Point2> &uvs,
  65. const Vector<Color> &colors,
  66. const Vector<int> &indices,
  67. SpineRendererObject *renderer_object) {
  68. #if VERSION_MAJOR > 3
  69. mesh_instance->update_mesh(vertices, uvs, colors, indices, renderer_object);
  70. #else
  71. #define USE_MESH 0
  72. #if USE_MESH
  73. mesh_instance->update_mesh(vertices, uvs, colors, indices, renderer_object);
  74. #else
  75. auto texture = renderer_object->texture;
  76. auto normal_map = renderer_object->normal_map;
  77. VisualServer::get_singleton()->canvas_item_add_triangle_array(mesh_instance->get_canvas_item(),
  78. indices,
  79. vertices,
  80. colors,
  81. uvs,
  82. Vector<int>(),
  83. Vector<float>(),
  84. texture.is_null() ? RID() : texture->get_rid(),
  85. -1,
  86. normal_map.is_null() ? RID() : normal_map->get_rid());
  87. #endif
  88. #endif
  89. }
  90. void SpineMesh2D::_notification(int what) {
  91. switch (what) {
  92. case NOTIFICATION_READY: {
  93. set_process_internal(true);
  94. break;
  95. }
  96. case NOTIFICATION_INTERNAL_PROCESS:
  97. #if VERSION_MAJOR > 3
  98. queue_redraw();
  99. #else
  100. update();
  101. #endif
  102. break;
  103. case NOTIFICATION_DRAW:
  104. clear_triangles(this);
  105. if (renderer_object)
  106. add_triangles(this, vertices, uvs, colors, indices, renderer_object);
  107. break;
  108. default:
  109. break;
  110. }
  111. }
  112. void SpineMesh2D::_bind_methods() {
  113. }
  114. void SpineMesh2D::update_mesh(const Vector<Point2> &vertices,
  115. const Vector<Point2> &uvs,
  116. const Vector<Color> &colors,
  117. const Vector<int> &indices,
  118. SpineRendererObject *renderer_object) {
  119. #if VERSION_MAJOR > 3
  120. if (!mesh.is_valid() || vertices.size() != num_vertices || indices.size() != num_indices || last_indices_id != indices_id) {
  121. if (mesh.is_valid()) {
  122. RS::get_singleton()->free(mesh);
  123. }
  124. mesh = RS::get_singleton()->mesh_create();
  125. Array arrays;
  126. arrays.resize(Mesh::ARRAY_MAX);
  127. arrays[Mesh::ARRAY_VERTEX] = vertices;
  128. arrays[Mesh::ARRAY_TEX_UV] = uvs;
  129. arrays[Mesh::ARRAY_COLOR] = colors;
  130. arrays[Mesh::ARRAY_INDEX] = indices;
  131. RS::SurfaceData surface;
  132. uint32_t skin_stride;
  133. RS::get_singleton()->mesh_create_surface_data_from_arrays(&surface, (RS::PrimitiveType) Mesh::PRIMITIVE_TRIANGLES, arrays, TypedArray<Array>(), Dictionary(), Mesh::ArrayFormat::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
  134. RS::get_singleton()->mesh_add_surface(mesh, surface);
  135. RS::get_singleton()->mesh_surface_make_offsets_from_format(surface.format, surface.vertex_count, surface.index_count, surface_offsets, vertex_stride, attribute_stride, skin_stride);
  136. num_vertices = vertices.size();
  137. num_indices = indices.size();
  138. vertex_buffer = surface.vertex_data;
  139. attribute_buffer = surface.attribute_data;
  140. last_indices_id = indices_id;
  141. } else {
  142. AABB aabb_new;
  143. uint8_t *vertex_write_buffer = vertex_buffer.ptrw();
  144. uint8_t *attribute_write_buffer = attribute_buffer.ptrw();
  145. uint8_t color[4] = {
  146. uint8_t(CLAMP(colors[0].r * 255.0, 0.0, 255.0)),
  147. uint8_t(CLAMP(colors[0].g * 255.0, 0.0, 255.0)),
  148. uint8_t(CLAMP(colors[0].b * 255.0, 0.0, 255.0)),
  149. uint8_t(CLAMP(colors[0].a * 255.0, 0.0, 255.0))};
  150. for (int i = 0; i < vertices.size(); i++) {
  151. Vector2 vertex(vertices[i]);
  152. if (i == 0) {
  153. aabb_new.position = Vector3(vertex.x, vertex.y, 0);
  154. aabb_new.size = Vector3();
  155. } else {
  156. aabb_new.expand_to(Vector3(vertex.x, vertex.y, 0));
  157. }
  158. float uv[2] = {(float) uvs[i].x, (float) uvs[i].y};
  159. memcpy(&vertex_write_buffer[i * vertex_stride + surface_offsets[RS::ARRAY_VERTEX]], &vertex, sizeof(float) * 2);
  160. memcpy(&attribute_write_buffer[i * attribute_stride + surface_offsets[RS::ARRAY_COLOR]], color, 4);
  161. memcpy(&attribute_write_buffer[i * attribute_stride + surface_offsets[RS::ARRAY_TEX_UV]], uv, 8);
  162. }
  163. RS::get_singleton()->mesh_surface_update_vertex_region(mesh, 0, 0, vertex_buffer);
  164. RS::get_singleton()->mesh_surface_update_attribute_region(mesh, 0, 0, attribute_buffer);
  165. RS::get_singleton()->mesh_set_custom_aabb(mesh, aabb_new);
  166. }
  167. RenderingServer::get_singleton()->canvas_item_add_mesh(this->get_canvas_item(), mesh, Transform2D(), Color(1, 1, 1, 1), renderer_object->canvas_texture->get_rid());
  168. #else
  169. if (!mesh.is_valid() || vertices.size() != num_vertices || indices.size() != num_indices || last_indices_id != indices_id) {
  170. if (mesh.is_valid()) {
  171. VS::get_singleton()->free(mesh);
  172. }
  173. mesh = VS::get_singleton()->mesh_create();
  174. Array arrays;
  175. arrays.resize(Mesh::ARRAY_MAX);
  176. arrays[Mesh::ARRAY_VERTEX] = vertices;
  177. arrays[Mesh::ARRAY_TEX_UV] = uvs;
  178. arrays[Mesh::ARRAY_COLOR] = colors;
  179. arrays[Mesh::ARRAY_INDEX] = indices;
  180. uint32_t compress_format = (VS::ARRAY_COMPRESS_DEFAULT & ~VS::ARRAY_COMPRESS_TEX_UV);
  181. VS::get_singleton()->mesh_add_surface_from_arrays(mesh, (VS::PrimitiveType) Mesh::PRIMITIVE_TRIANGLES, arrays, Array(), compress_format);
  182. int surface_vertex_len = VS::get_singleton()->mesh_surface_get_array_len(mesh, 0);
  183. int surface_index_len = VS::get_singleton()->mesh_surface_get_array_index_len(mesh, 0);
  184. mesh_surface_format = VS::get_singleton()->mesh_surface_get_format(mesh, 0);
  185. mesh_buffer = VS::get_singleton()->mesh_surface_get_array(mesh, 0);
  186. VS::get_singleton()->mesh_surface_make_offsets_from_format(mesh_surface_format, surface_vertex_len, surface_index_len, mesh_surface_offsets, mesh_stride);
  187. num_vertices = vertices.size();
  188. num_indices = indices.size();
  189. last_indices_id = indices_id;
  190. } else {
  191. AABB aabb_new;
  192. PoolVector<uint8_t>::Write write_buffer = mesh_buffer.write();
  193. uint8_t color[4] = {
  194. uint8_t(CLAMP(colors[0].r * 255.0, 0.0, 255.0)),
  195. uint8_t(CLAMP(colors[0].g * 255.0, 0.0, 255.0)),
  196. uint8_t(CLAMP(colors[0].b * 255.0, 0.0, 255.0)),
  197. uint8_t(CLAMP(colors[0].a * 255.0, 0.0, 255.0))};
  198. for (int i = 0; i < vertices.size(); i++) {
  199. Vector2 vertex(vertices[i]);
  200. if (i == 0) {
  201. aabb_new.position = Vector3(vertex.x, vertex.y, 0);
  202. aabb_new.size = Vector3();
  203. } else {
  204. aabb_new.expand_to(Vector3(vertex.x, vertex.y, 0));
  205. }
  206. float uv[2] = {(float) uvs[i].x, (float) uvs[i].y};
  207. memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_VERTEX] + mesh_surface_offsets[VS::ARRAY_VERTEX]], &vertex, sizeof(float) * 2);
  208. memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_TEX_UV] + mesh_surface_offsets[VS::ARRAY_TEX_UV]], uv, 8);
  209. memcpy(&write_buffer[i * mesh_stride[VS::ARRAY_COLOR] + mesh_surface_offsets[VS::ARRAY_COLOR]], color, 4);
  210. }
  211. write_buffer.release();
  212. VS::get_singleton()->mesh_surface_update_region(mesh, 0, 0, mesh_buffer);
  213. VS::get_singleton()->mesh_set_custom_aabb(mesh, aabb_new);
  214. }
  215. VS::get_singleton()->canvas_item_add_mesh(
  216. this->get_canvas_item(),
  217. mesh,
  218. Transform2D(),
  219. Color(1, 1, 1, 1),
  220. renderer_object->texture.is_null() ? RID() : renderer_object->texture->get_rid(),
  221. renderer_object->normal_map.is_null() ? RID() : renderer_object->normal_map->get_rid());
  222. #endif
  223. }
  224. void SpineSprite::_bind_methods() {
  225. ClassDB::bind_method(D_METHOD("set_skeleton_data_res", "skeleton_data_res"), &SpineSprite::set_skeleton_data_res);
  226. ClassDB::bind_method(D_METHOD("get_skeleton_data_res"), &SpineSprite::get_skeleton_data_res);
  227. ClassDB::bind_method(D_METHOD("get_skeleton"), &SpineSprite::get_skeleton);
  228. ClassDB::bind_method(D_METHOD("get_animation_state"), &SpineSprite::get_animation_state);
  229. ClassDB::bind_method(D_METHOD("on_skeleton_data_changed"), &SpineSprite::on_skeleton_data_changed);
  230. ClassDB::bind_method(D_METHOD("get_global_bone_transform", "bone_name"), &SpineSprite::get_global_bone_transform);
  231. ClassDB::bind_method(D_METHOD("set_global_bone_transform", "bone_name", "global_transform"), &SpineSprite::set_global_bone_transform);
  232. ClassDB::bind_method(D_METHOD("set_update_mode", "v"), &SpineSprite::set_update_mode);
  233. ClassDB::bind_method(D_METHOD("get_update_mode"), &SpineSprite::get_update_mode);
  234. ClassDB::bind_method(D_METHOD("set_normal_material", "material"), &SpineSprite::set_normal_material);
  235. ClassDB::bind_method(D_METHOD("get_normal_material"), &SpineSprite::get_normal_material);
  236. ClassDB::bind_method(D_METHOD("set_additive_material", "material"), &SpineSprite::set_additive_material);
  237. ClassDB::bind_method(D_METHOD("get_additive_material"), &SpineSprite::get_additive_material);
  238. ClassDB::bind_method(D_METHOD("set_multiply_material", "material"), &SpineSprite::set_multiply_material);
  239. ClassDB::bind_method(D_METHOD("get_multiply_material"), &SpineSprite::get_multiply_material);
  240. ClassDB::bind_method(D_METHOD("set_screen_material", "material"), &SpineSprite::set_screen_material);
  241. ClassDB::bind_method(D_METHOD("get_screen_material"), &SpineSprite::get_screen_material);
  242. ClassDB::bind_method(D_METHOD("set_debug_root", "v"), &SpineSprite::set_debug_root);
  243. ClassDB::bind_method(D_METHOD("get_debug_root"), &SpineSprite::get_debug_root);
  244. ClassDB::bind_method(D_METHOD("set_debug_root_color", "v"), &SpineSprite::set_debug_root_color);
  245. ClassDB::bind_method(D_METHOD("get_debug_root_color"), &SpineSprite::get_debug_root_color);
  246. ClassDB::bind_method(D_METHOD("set_debug_bones", "v"), &SpineSprite::set_debug_bones);
  247. ClassDB::bind_method(D_METHOD("get_debug_bones"), &SpineSprite::get_debug_bones);
  248. ClassDB::bind_method(D_METHOD("set_debug_bones_color", "v"), &SpineSprite::set_debug_bones_color);
  249. ClassDB::bind_method(D_METHOD("get_debug_bones_color"), &SpineSprite::get_debug_bones_color);
  250. ClassDB::bind_method(D_METHOD("set_debug_bones_thickness", "v"), &SpineSprite::set_debug_bones_thickness);
  251. ClassDB::bind_method(D_METHOD("get_debug_bones_thickness"), &SpineSprite::get_debug_bones_thickness);
  252. ClassDB::bind_method(D_METHOD("set_debug_regions", "v"), &SpineSprite::set_debug_regions);
  253. ClassDB::bind_method(D_METHOD("get_debug_regions"), &SpineSprite::get_debug_regions);
  254. ClassDB::bind_method(D_METHOD("set_debug_regions_color", "v"), &SpineSprite::set_debug_regions_color);
  255. ClassDB::bind_method(D_METHOD("get_debug_regions_color"), &SpineSprite::get_debug_regions_color);
  256. ClassDB::bind_method(D_METHOD("set_debug_meshes", "v"), &SpineSprite::set_debug_meshes);
  257. ClassDB::bind_method(D_METHOD("get_debug_meshes"), &SpineSprite::get_debug_meshes);
  258. ClassDB::bind_method(D_METHOD("set_debug_meshes_color", "v"), &SpineSprite::set_debug_meshes_color);
  259. ClassDB::bind_method(D_METHOD("get_debug_meshes_color"), &SpineSprite::get_debug_meshes_color);
  260. ClassDB::bind_method(D_METHOD("set_debug_bounding_boxes", "v"), &SpineSprite::set_debug_bounding_boxes);
  261. ClassDB::bind_method(D_METHOD("get_debug_bounding_boxes"), &SpineSprite::get_debug_bounding_boxes);
  262. ClassDB::bind_method(D_METHOD("set_debug_bounding_boxes_color", "v"), &SpineSprite::set_debug_bounding_boxes_color);
  263. ClassDB::bind_method(D_METHOD("get_debug_bounding_boxes_color"), &SpineSprite::get_debug_bounding_boxes_color);
  264. ClassDB::bind_method(D_METHOD("set_debug_paths", "v"), &SpineSprite::set_debug_paths);
  265. ClassDB::bind_method(D_METHOD("get_debug_paths"), &SpineSprite::get_debug_paths);
  266. ClassDB::bind_method(D_METHOD("set_debug_paths_color", "v"), &SpineSprite::set_debug_paths_color);
  267. ClassDB::bind_method(D_METHOD("get_debug_paths_color"), &SpineSprite::get_debug_paths_color);
  268. ClassDB::bind_method(D_METHOD("set_debug_clipping", "v"), &SpineSprite::set_debug_clipping);
  269. ClassDB::bind_method(D_METHOD("get_debug_clipping"), &SpineSprite::get_debug_clipping);
  270. ClassDB::bind_method(D_METHOD("set_debug_clipping_color", "v"), &SpineSprite::set_debug_clipping_color);
  271. ClassDB::bind_method(D_METHOD("get_debug_clipping_color"), &SpineSprite::get_debug_clipping_color);
  272. ClassDB::bind_method(D_METHOD("update_skeleton", "delta"), &SpineSprite::update_skeleton);
  273. ClassDB::bind_method(D_METHOD("new_skin", "name"), &SpineSprite::new_skin);
  274. ADD_SIGNAL(MethodInfo("animation_started", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite"), PropertyInfo(Variant::OBJECT, "animation_state", PROPERTY_HINT_TYPE_STRING, "SpineAnimationState"), PropertyInfo(Variant::OBJECT, "track_entry", PROPERTY_HINT_TYPE_STRING, "SpineTrackEntry")));
  275. ADD_SIGNAL(MethodInfo("animation_interrupted", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite"), PropertyInfo(Variant::OBJECT, "animation_state", PROPERTY_HINT_TYPE_STRING, "SpineAnimationState"), PropertyInfo(Variant::OBJECT, "track_entry", PROPERTY_HINT_TYPE_STRING, "SpineTrackEntry")));
  276. ADD_SIGNAL(MethodInfo("animation_ended", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite"), PropertyInfo(Variant::OBJECT, "animation_state", PROPERTY_HINT_TYPE_STRING, "SpineAnimationState"), PropertyInfo(Variant::OBJECT, "track_entry", PROPERTY_HINT_TYPE_STRING, "SpineTrackEntry")));
  277. ADD_SIGNAL(MethodInfo("animation_completed", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite"), PropertyInfo(Variant::OBJECT, "animation_state", PROPERTY_HINT_TYPE_STRING, "SpineAnimationState"), PropertyInfo(Variant::OBJECT, "track_entry", PROPERTY_HINT_TYPE_STRING, "SpineTrackEntry")));
  278. ADD_SIGNAL(MethodInfo("animation_disposed", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite"), PropertyInfo(Variant::OBJECT, "animation_state", PROPERTY_HINT_TYPE_STRING, "SpineAnimationState"), PropertyInfo(Variant::OBJECT, "track_entry", PROPERTY_HINT_TYPE_STRING, "SpineTrackEntry")));
  279. ADD_SIGNAL(MethodInfo("animation_event", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite"), PropertyInfo(Variant::OBJECT, "animation_state", PROPERTY_HINT_TYPE_STRING, "SpineAnimationState"), PropertyInfo(Variant::OBJECT, "track_entry", PROPERTY_HINT_TYPE_STRING, "SpineTrackEntry"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_TYPE_STRING, "SpineEvent")));
  280. ADD_SIGNAL(MethodInfo("before_animation_state_update", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite")));
  281. ADD_SIGNAL(MethodInfo("before_animation_state_apply", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite")));
  282. ADD_SIGNAL(MethodInfo("before_world_transforms_change", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite")));
  283. ADD_SIGNAL(MethodInfo("world_transforms_changed", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite")));
  284. ADD_SIGNAL(MethodInfo("_internal_spine_objects_invalidated"));
  285. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skeleton_data_res", PropertyHint::PROPERTY_HINT_RESOURCE_TYPE, "SpineSkeletonDataResource"), "set_skeleton_data_res", "get_skeleton_data_res");
  286. ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Process,Physics,Manual"), "set_update_mode", "get_update_mode");
  287. ADD_GROUP("Materials", "");
  288. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_normal_material", "get_normal_material");
  289. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "additive_material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_additive_material", "get_additive_material");
  290. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiply_material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_multiply_material", "get_multiply_material");
  291. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "screen_material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_screen_material", "get_screen_material");
  292. ADD_GROUP("Debug", "");
  293. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "root"), "set_debug_root", "get_debug_root");
  294. ADD_PROPERTY(PropertyInfo(Variant::COLOR, "root_color"), "set_debug_root_color", "get_debug_root_color");
  295. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bones"), "set_debug_bones", "get_debug_bones");
  296. ADD_PROPERTY(PropertyInfo(Variant::COLOR, "bones_color"), "set_debug_bones_color", "get_debug_bones_color");
  297. ADD_PROPERTY(PropertyInfo(VARIANT_FLOAT, "bones_thickness"), "set_debug_bones_thickness", "get_debug_bones_thickness");
  298. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "regions"), "set_debug_regions", "get_debug_regions");
  299. ADD_PROPERTY(PropertyInfo(Variant::COLOR, "regions_color"), "set_debug_regions_color", "get_debug_regions_color");
  300. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meshes"), "set_debug_meshes", "get_debug_meshes");
  301. ADD_PROPERTY(PropertyInfo(Variant::COLOR, "meshes_color"), "set_debug_meshes_color", "get_debug_meshes_color");
  302. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bounding_boxes"), "set_debug_bounding_boxes", "get_debug_bounding_boxes");
  303. ADD_PROPERTY(PropertyInfo(Variant::COLOR, "bounding_boxes_color"), "set_debug_bounding_boxes_color", "get_debug_bounding_boxes_color");
  304. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "paths"), "set_debug_paths", "get_debug_paths");
  305. ADD_PROPERTY(PropertyInfo(Variant::COLOR, "paths_color"), "set_debug_paths_color", "get_debug_paths_color");
  306. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clipping"), "set_debug_clipping", "get_debug_clipping");
  307. ADD_PROPERTY(PropertyInfo(Variant::COLOR, "paths_clipping"), "set_debug_clipping_color", "get_debug_clipping_color");
  308. ADD_GROUP("Preview", "");
  309. // Filled in in _get_property_list()
  310. }
  311. SpineSprite::SpineSprite() : update_mode(SpineConstant::UpdateMode_Process), preview_skin("Default"), preview_animation("-- Empty --"), preview_frame(false), preview_time(0), skeleton_clipper(nullptr), modified_bones(false) {
  312. skeleton_clipper = new spine::SkeletonClipping();
  313. // One material per blend mode, shared across all sprites.
  314. if (!default_materials[0].is_valid()) {
  315. Ref<CanvasItemMaterial> material_normal(memnew(CanvasItemMaterial));
  316. material_normal->set_blend_mode(CanvasItemMaterial::BLEND_MODE_MIX);
  317. default_materials[spine::BlendMode_Normal] = material_normal;
  318. Ref<CanvasItemMaterial> material_additive(memnew(CanvasItemMaterial));
  319. material_additive->set_blend_mode(CanvasItemMaterial::BLEND_MODE_ADD);
  320. default_materials[spine::BlendMode_Additive] = material_additive;
  321. Ref<CanvasItemMaterial> material_multiply(memnew(CanvasItemMaterial));
  322. material_multiply->set_blend_mode(CanvasItemMaterial::BLEND_MODE_MUL);
  323. default_materials[spine::BlendMode_Multiply] = material_multiply;
  324. Ref<CanvasItemMaterial> material_screen(memnew(CanvasItemMaterial));
  325. material_screen->set_blend_mode(CanvasItemMaterial::BLEND_MODE_SUB);
  326. default_materials[spine::BlendMode_Screen] = material_screen;
  327. }
  328. // Setup static scratch buffers
  329. if (quad_indices.size() == 0) {
  330. quad_indices.setSize(6, 0);
  331. quad_indices[0] = 0;
  332. quad_indices[1] = 1;
  333. quad_indices[2] = 2;
  334. quad_indices[3] = 2;
  335. quad_indices[4] = 3;
  336. quad_indices[5] = 0;
  337. scratch_vertices.ensureCapacity(1200);
  338. }
  339. // Default debug settings
  340. debug_root = false;
  341. debug_root_color = Color(1, 1, 1, 0.5);
  342. debug_bones = false;
  343. debug_bones_color = Color(1, 1, 0, 0.5);
  344. debug_bones_thickness = 5;
  345. debug_regions = false;
  346. debug_regions_color = Color(0, 0, 1, 0.5);
  347. debug_meshes = false;
  348. debug_meshes_color = Color(0, 0, 1, 0.5);
  349. debug_bounding_boxes = false;
  350. debug_bounding_boxes_color = Color(0, 1, 0, 0.5);
  351. debug_paths = false;
  352. debug_paths_color = Color::hex(0xff7f0077);
  353. debug_clipping = false;
  354. debug_clipping_color = Color(0.8, 0, 0, 0.8);
  355. sprite_count++;
  356. }
  357. SpineSprite::~SpineSprite() {
  358. delete skeleton_clipper;
  359. sprite_count--;
  360. if (!sprite_count) {
  361. for (int i = 0; i < 4; i++)
  362. default_materials[i].unref();
  363. }
  364. }
  365. void SpineSprite::set_skeleton_data_res(const Ref<SpineSkeletonDataResource> &_skeleton_data) {
  366. skeleton_data_res = _skeleton_data;
  367. on_skeleton_data_changed();
  368. }
  369. Ref<SpineSkeletonDataResource> SpineSprite::get_skeleton_data_res() {
  370. return skeleton_data_res;
  371. }
  372. void SpineSprite::on_skeleton_data_changed() {
  373. remove_meshes();
  374. skeleton.unref();
  375. animation_state.unref();
  376. emit_signal("_internal_spine_objects_invalidated");
  377. if (skeleton_data_res.is_valid()) {
  378. #if VERSION_MAJOR > 3
  379. if (!skeleton_data_res->is_connected("skeleton_data_changed", callable_mp(this, &SpineSprite::on_skeleton_data_changed)))
  380. skeleton_data_res->connect("skeleton_data_changed", callable_mp(this, &SpineSprite::on_skeleton_data_changed));
  381. #else
  382. if (!skeleton_data_res->is_connected("skeleton_data_changed", this, "on_skeleton_data_changed"))
  383. skeleton_data_res->connect("skeleton_data_changed", this, "on_skeleton_data_changed");
  384. #endif
  385. }
  386. if (skeleton_data_res.is_valid() && skeleton_data_res->is_skeleton_data_loaded()) {
  387. skeleton = Ref<SpineSkeleton>(memnew(SpineSkeleton));
  388. skeleton->set_spine_sprite(this);
  389. animation_state = Ref<SpineAnimationState>(memnew(SpineAnimationState));
  390. animation_state->set_spine_sprite(this);
  391. animation_state->get_spine_object()->setListener(this);
  392. animation_state->update(0);
  393. animation_state->apply(skeleton);
  394. skeleton->update_world_transform();
  395. generate_meshes_for_slots(skeleton);
  396. if (update_mode == SpineConstant::UpdateMode_Process) {
  397. _notification(NOTIFICATION_INTERNAL_PROCESS);
  398. } else if (update_mode == SpineConstant::UpdateMode_Physics) {
  399. _notification(NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
  400. }
  401. }
  402. NOTIFY_PROPERTY_LIST_CHANGED();
  403. }
  404. void SpineSprite::generate_meshes_for_slots(Ref<SpineSkeleton> skeleton_ref) {
  405. auto skeleton = skeleton_ref->get_spine_object();
  406. for (int i = 0, n = (int) skeleton->getSlots().size(); i < n; i++) {
  407. auto mesh_instance = memnew(SpineMesh2D);
  408. mesh_instance->set_position(Vector2(0, 0));
  409. mesh_instance->set_material(default_materials[spine::BlendMode_Normal]);
  410. // Needed so that debug drawables are rendered in front of attachments
  411. mesh_instance->set_draw_behind_parent(true);
  412. add_child(mesh_instance);
  413. mesh_instances.push_back(mesh_instance);
  414. slot_nodes.add(spine::Vector<SpineSlotNode *>());
  415. }
  416. }
  417. void SpineSprite::remove_meshes() {
  418. for (int i = 0; i < mesh_instances.size(); ++i) {
  419. remove_child(mesh_instances[i]);
  420. memdelete(mesh_instances[i]);
  421. }
  422. mesh_instances.clear();
  423. slot_nodes.clear();
  424. }
  425. void SpineSprite::sort_slot_nodes() {
  426. for (int i = 0; i < (int) slot_nodes.size(); i++) {
  427. slot_nodes[i].setSize(0, nullptr);
  428. }
  429. auto draw_order = skeleton->get_spine_object()->getDrawOrder();
  430. for (int i = 0; i < get_child_count(); i++) {
  431. auto child = cast_to<Node2D>(get_child(i));
  432. if (!child) continue;
  433. // Needed so that debug drawables are rendered in front of attachments and other nodes under the sprite.
  434. child->set_draw_behind_parent(true);
  435. auto slot_node = Object::cast_to<SpineSlotNode>(get_child(i));
  436. if (!slot_node) continue;
  437. if (slot_node->get_slot_index() == -1 || slot_node->get_slot_index() >= (int) draw_order.size()) {
  438. continue;
  439. }
  440. slot_nodes[slot_node->get_slot_index()].add(slot_node);
  441. }
  442. for (int i = 0; i < (int) draw_order.size(); i++) {
  443. int slot_index = draw_order[i]->getData().getIndex();
  444. int mesh_index = mesh_instances[i]->get_index();
  445. spine::Vector<SpineSlotNode *> &nodes = slot_nodes[slot_index];
  446. for (int j = 0; j < (int) nodes.size(); j++) {
  447. auto node = nodes[j];
  448. move_child(node, mesh_index + 1);
  449. }
  450. }
  451. }
  452. Ref<SpineSkeleton> SpineSprite::get_skeleton() {
  453. return skeleton;
  454. }
  455. Ref<SpineAnimationState> SpineSprite::get_animation_state() {
  456. return animation_state;
  457. }
  458. void SpineSprite::_notification(int what) {
  459. switch (what) {
  460. case NOTIFICATION_READY: {
  461. set_process_internal(update_mode == SpineConstant::UpdateMode_Process);
  462. set_physics_process_internal(update_mode == SpineConstant::UpdateMode_Physics);
  463. break;
  464. }
  465. case NOTIFICATION_INTERNAL_PROCESS: {
  466. if (update_mode == SpineConstant::UpdateMode_Process)
  467. update_skeleton(get_process_delta_time());
  468. break;
  469. }
  470. case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
  471. if (update_mode == SpineConstant::UpdateMode_Physics)
  472. update_skeleton(get_physics_process_delta_time());
  473. break;
  474. }
  475. case NOTIFICATION_DRAW: {
  476. draw();
  477. break;
  478. }
  479. default:
  480. break;
  481. }
  482. }
  483. void SpineSprite::_get_property_list(List<PropertyInfo> *list) const {
  484. if (!skeleton_data_res.is_valid() || !skeleton_data_res->is_skeleton_data_loaded()) return;
  485. Vector<String> animation_names;
  486. Vector<String> skin_names;
  487. skeleton_data_res->get_animation_names(animation_names);
  488. skeleton_data_res->get_skin_names(skin_names);
  489. animation_names.insert(0, "-- Empty --");
  490. PropertyInfo preview_skin_property;
  491. preview_skin_property.name = "preview_skin";
  492. preview_skin_property.type = Variant::STRING;
  493. preview_skin_property.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE;
  494. preview_skin_property.hint_string = String(",").join(skin_names);
  495. preview_skin_property.hint = PROPERTY_HINT_ENUM;
  496. list->push_back(preview_skin_property);
  497. PropertyInfo preview_anim_property;
  498. preview_anim_property.name = "preview_animation";
  499. preview_anim_property.type = Variant::STRING;
  500. preview_anim_property.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE;
  501. preview_anim_property.hint_string = String(",").join(animation_names);
  502. preview_anim_property.hint = PROPERTY_HINT_ENUM;
  503. list->push_back(preview_anim_property);
  504. PropertyInfo preview_frame_property;
  505. preview_frame_property.name = "preview_frame";
  506. preview_frame_property.type = Variant::BOOL;
  507. preview_frame_property.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE;
  508. list->push_back(preview_frame_property);
  509. PropertyInfo preview_time_property;
  510. preview_time_property.name = "preview_time";
  511. preview_time_property.type = VARIANT_FLOAT;
  512. preview_time_property.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE;
  513. float animation_duration = 0;
  514. if (!EMPTY(preview_animation) && preview_animation != "-- Empty --") {
  515. auto animation = skeleton_data_res->find_animation(preview_animation);
  516. if (animation.is_valid()) animation_duration = animation->get_duration();
  517. }
  518. preview_time_property.hint_string = String("0.0,{0},0.01").format(varray(animation_duration));
  519. preview_time_property.hint = PROPERTY_HINT_RANGE;
  520. list->push_back(preview_time_property);
  521. }
  522. bool SpineSprite::_get(const StringName &property, Variant &value) const {
  523. if (property == "preview_skin") {
  524. value = preview_skin;
  525. return true;
  526. }
  527. if (property == "preview_animation") {
  528. value = preview_animation;
  529. return true;
  530. }
  531. if (property == "preview_frame") {
  532. value = preview_frame;
  533. return true;
  534. }
  535. if (property == "preview_time") {
  536. value = preview_time;
  537. return true;
  538. }
  539. return false;
  540. }
  541. static void update_preview_animation(SpineSprite *sprite, const String &skin, const String &animation, bool frame, float time) {
  542. if (!sprite->get_skeleton().is_valid()) return;
  543. if (EMPTY(skin) || skin == "Default") {
  544. sprite->get_skeleton()->set_skin(nullptr);
  545. } else {
  546. sprite->get_skeleton()->set_skin_by_name(skin);
  547. }
  548. sprite->get_skeleton()->set_to_setup_pose();
  549. if (EMPTY(animation) || animation == "-- Empty --") {
  550. sprite->get_animation_state()->set_empty_animation(0, 0);
  551. return;
  552. }
  553. auto track_entry = sprite->get_animation_state()->set_animation(animation, true, 0);
  554. track_entry->set_mix_duration(0);
  555. if (frame) {
  556. track_entry->set_time_scale(0);
  557. track_entry->set_track_time(time);
  558. }
  559. }
  560. bool SpineSprite::_set(const StringName &property, const Variant &value) {
  561. if (property == "preview_skin") {
  562. preview_skin = value;
  563. update_preview_animation(this, preview_skin, preview_animation, preview_frame, preview_time);
  564. NOTIFY_PROPERTY_LIST_CHANGED();
  565. return true;
  566. }
  567. if (property == "preview_animation") {
  568. preview_animation = value;
  569. update_preview_animation(this, preview_skin, preview_animation, preview_frame, preview_time);
  570. NOTIFY_PROPERTY_LIST_CHANGED();
  571. return true;
  572. }
  573. if (property == "preview_frame") {
  574. preview_frame = value;
  575. update_preview_animation(this, preview_skin, preview_animation, preview_frame, preview_time);
  576. return true;
  577. }
  578. if (property == "preview_time") {
  579. preview_time = value;
  580. update_preview_animation(this, preview_skin, preview_animation, preview_frame, preview_time);
  581. return true;
  582. }
  583. return false;
  584. }
  585. void SpineSprite::update_skeleton(float delta) {
  586. if (!skeleton_data_res.is_valid() ||
  587. !skeleton_data_res->is_skeleton_data_loaded() ||
  588. !skeleton.is_valid() ||
  589. !skeleton->get_spine_object() ||
  590. !animation_state.is_valid() ||
  591. !animation_state->get_spine_object())
  592. return;
  593. emit_signal("before_animation_state_update", this);
  594. animation_state->update(delta);
  595. if (!is_visible_in_tree()) return;
  596. emit_signal("before_animation_state_apply", this);
  597. animation_state->apply(skeleton);
  598. emit_signal("before_world_transforms_change", this);
  599. skeleton->update_world_transform();
  600. modified_bones = false;
  601. emit_signal("world_transforms_changed", this);
  602. if (modified_bones) skeleton->update_world_transform();
  603. sort_slot_nodes();
  604. update_meshes(skeleton);
  605. #if VERSION_MAJOR > 3
  606. queue_redraw();
  607. #else
  608. update();
  609. #endif
  610. }
  611. void SpineSprite::update_meshes(Ref<SpineSkeleton> skeleton_ref) {
  612. spine::Skeleton *skeleton = skeleton_ref->get_spine_object();
  613. for (int i = 0, n = (int) skeleton->getSlots().size(); i < n; ++i) {
  614. spine::Slot *slot = skeleton->getDrawOrder()[i];
  615. spine::Attachment *attachment = slot->getAttachment();
  616. SpineMesh2D *mesh_instance = mesh_instances[i];
  617. mesh_instance->renderer_object = nullptr;
  618. if (!attachment) {
  619. skeleton_clipper->clipEnd(*slot);
  620. continue;
  621. }
  622. if (!slot->getBone().isActive()) {
  623. skeleton_clipper->clipEnd(*slot);
  624. continue;
  625. }
  626. spine::Color skeleton_color = skeleton->getColor();
  627. spine::Color slot_color = slot->getColor();
  628. spine::Color tint(skeleton_color.r * slot_color.r, skeleton_color.g * slot_color.g, skeleton_color.b * slot_color.b, skeleton_color.a * slot_color.a);
  629. SpineRendererObject *renderer_object;
  630. spine::Vector<float> *vertices = &scratch_vertices;
  631. spine::Vector<float> *uvs;
  632. spine::Vector<unsigned short> *indices;
  633. if (attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) {
  634. auto *region = (spine::RegionAttachment *) attachment;
  635. vertices->setSize(8, 0);
  636. region->computeWorldVertices(*slot, *vertices, 0);
  637. renderer_object = (SpineRendererObject *) ((spine::AtlasRegion *) region->getRendererObject())->page->getRendererObject();
  638. uvs = &region->getUVs();
  639. indices = &quad_indices;
  640. auto attachment_color = region->getColor();
  641. tint.r *= attachment_color.r;
  642. tint.g *= attachment_color.g;
  643. tint.b *= attachment_color.b;
  644. tint.a *= attachment_color.a;
  645. } else if (attachment->getRTTI().isExactly(spine::MeshAttachment::rtti)) {
  646. auto *mesh = (spine::MeshAttachment *) attachment;
  647. vertices->setSize(mesh->getWorldVerticesLength(), 0);
  648. mesh->computeWorldVertices(*slot, *vertices);
  649. renderer_object = (SpineRendererObject *) ((spine::AtlasRegion *) mesh->getRendererObject())->page->getRendererObject();
  650. uvs = &mesh->getUVs();
  651. indices = &mesh->getTriangles();
  652. auto attachment_color = mesh->getColor();
  653. tint.r *= attachment_color.r;
  654. tint.g *= attachment_color.g;
  655. tint.b *= attachment_color.b;
  656. tint.a *= attachment_color.a;
  657. } else if (attachment->getRTTI().isExactly(spine::ClippingAttachment::rtti)) {
  658. auto clip = (spine::ClippingAttachment *) attachment;
  659. skeleton_clipper->clipStart(*slot, clip);
  660. continue;
  661. } else {
  662. skeleton_clipper->clipEnd(*slot);
  663. continue;
  664. }
  665. if (skeleton_clipper->isClipping()) {
  666. skeleton_clipper->clipTriangles(*vertices, *indices, *uvs, 2);
  667. if (skeleton_clipper->getClippedTriangles().size() == 0) {
  668. skeleton_clipper->clipEnd(*slot);
  669. continue;
  670. }
  671. vertices = &skeleton_clipper->getClippedVertices();
  672. uvs = &skeleton_clipper->getClippedUVs();
  673. indices = &skeleton_clipper->getClippedTriangles();
  674. }
  675. if (indices->size() > 0) {
  676. mesh_instance->set_light_mask(get_light_mask());
  677. size_t num_vertices = vertices->size() / 2;
  678. mesh_instance->vertices.resize((int) num_vertices);
  679. memcpy(mesh_instance->vertices.ptrw(), vertices->buffer(), num_vertices * 2 * sizeof(float));
  680. mesh_instance->uvs.resize((int) num_vertices);
  681. memcpy(mesh_instance->uvs.ptrw(), uvs->buffer(), num_vertices * 2 * sizeof(float));
  682. mesh_instance->colors.resize((int) num_vertices);
  683. for (int j = 0; j < (int) num_vertices; j++) {
  684. mesh_instance->colors.set(j, Color(tint.r, tint.g, tint.b, tint.a));
  685. }
  686. mesh_instance->indices.resize((int) indices->size());
  687. for (int j = 0; j < (int) indices->size(); ++j) {
  688. mesh_instance->indices.set(j, indices->buffer()[j]);
  689. }
  690. mesh_instance->renderer_object = renderer_object;
  691. #if VERSION_MAJOR > 3
  692. mesh_instance->indices_id = (uint64_t) indices;
  693. #endif
  694. spine::BlendMode blend_mode = slot->getData().getBlendMode();
  695. Ref<Material> custom_material;
  696. // See if we have a slot node for this slot with a custom material
  697. auto &nodes = slot_nodes[slot->getData().getIndex()];
  698. if (nodes.size() > 0) {
  699. auto slot_node = nodes[0];
  700. if (slot_node) {
  701. switch (blend_mode) {
  702. case spine::BlendMode_Normal:
  703. custom_material = slot_node->get_normal_material();
  704. break;
  705. case spine::BlendMode_Additive:
  706. custom_material = slot_node->get_additive_material();
  707. break;
  708. case spine::BlendMode_Multiply:
  709. custom_material = slot_node->get_multiply_material();
  710. break;
  711. case spine::BlendMode_Screen:
  712. custom_material = slot_node->get_screen_material();
  713. break;
  714. }
  715. }
  716. }
  717. // Else, check if we have a material on the sprite itself
  718. if (!custom_material.is_valid()) {
  719. switch (blend_mode) {
  720. case spine::BlendMode_Normal:
  721. custom_material = normal_material;
  722. break;
  723. case spine::BlendMode_Additive:
  724. custom_material = additive_material;
  725. break;
  726. case spine::BlendMode_Multiply:
  727. custom_material = multiply_material;
  728. break;
  729. case spine::BlendMode_Screen:
  730. custom_material = screen_material;
  731. break;
  732. }
  733. }
  734. // Set the custom material, or the default material
  735. if (custom_material.is_valid()) mesh_instance->set_material(custom_material);
  736. else
  737. mesh_instance->set_material(default_materials[slot->getData().getBlendMode()]);
  738. }
  739. skeleton_clipper->clipEnd(*slot);
  740. }
  741. skeleton_clipper->clipEnd();
  742. }
  743. void SpineSprite::draw() {
  744. if (!animation_state.is_valid() && !skeleton.is_valid()) return;
  745. if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) return;
  746. #if VERSION_MAJOR > 3
  747. RS::get_singleton()->canvas_item_clear(this->get_canvas_item());
  748. #else
  749. VisualServer::get_singleton()->canvas_item_clear(this->get_canvas_item());
  750. #endif
  751. auto mouse_position = get_local_mouse_position();
  752. spine::Slot *hovered_slot = nullptr;
  753. if (debug_regions) {
  754. draw_set_transform(Vector2(0, 0), 0, Vector2(1, 1));
  755. auto &draw_order = skeleton->get_spine_object()->getDrawOrder();
  756. for (int i = 0; i < (int) draw_order.size(); i++) {
  757. auto *slot = draw_order[i];
  758. if (!slot->getBone().isActive()) continue;
  759. auto *attachment = slot->getAttachment();
  760. if (!attachment) continue;
  761. if (!attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) continue;
  762. auto *region = (spine::RegionAttachment *) attachment;
  763. auto *vertices = &scratch_vertices;
  764. vertices->setSize(8, 0);
  765. region->computeWorldVertices(*slot, *vertices, 0);
  766. scratch_points.resize(0);
  767. for (int i = 0, j = 0; i < 4; i++, j += 2) {
  768. float x = vertices->buffer()[j];
  769. float y = vertices->buffer()[j + 1];
  770. scratch_points.push_back(Vector2(x, y));
  771. }
  772. scratch_points.push_back(Vector2(vertices->buffer()[0], vertices->buffer()[1]));
  773. Color color = debug_regions_color;
  774. if (GEOMETRY2D::is_point_in_polygon(mouse_position, scratch_points)) {
  775. hovered_slot = slot;
  776. color = Color(1, 1, 1, 1);
  777. }
  778. scratch_points.push_back(Vector2(vertices->buffer()[0], vertices->buffer()[1]));
  779. draw_polyline(scratch_points, color, 2);
  780. }
  781. }
  782. if (debug_meshes) {
  783. draw_set_transform(Vector2(0, 0), 0, Vector2(1, 1));
  784. auto &draw_order = skeleton->get_spine_object()->getDrawOrder();
  785. for (int i = 0; i < (int) draw_order.size(); i++) {
  786. auto *slot = draw_order[i];
  787. if (!slot->getBone().isActive()) continue;
  788. auto *attachment = slot->getAttachment();
  789. if (!attachment) continue;
  790. if (!attachment->getRTTI().isExactly(spine::MeshAttachment::rtti)) continue;
  791. auto *mesh = (spine::MeshAttachment *) attachment;
  792. auto *vertices = &scratch_vertices;
  793. vertices->setSize(mesh->getWorldVerticesLength(), 0);
  794. mesh->computeWorldVertices(*slot, *vertices);
  795. scratch_points.resize(0);
  796. for (int i = 0, j = 0; i < mesh->getHullLength(); i++, j += 2) {
  797. float x = vertices->buffer()[j];
  798. float y = vertices->buffer()[j + 1];
  799. scratch_points.push_back(Vector2(x, y));
  800. }
  801. Color color = debug_meshes_color;
  802. if (GEOMETRY2D::is_point_in_polygon(mouse_position, scratch_points)) {
  803. hovered_slot = slot;
  804. color = Color(1, 1, 1, 1);
  805. }
  806. scratch_points.push_back(Vector2(vertices->buffer()[0], vertices->buffer()[1]));
  807. draw_polyline(scratch_points, color, 2);
  808. }
  809. }
  810. if (debug_bounding_boxes) {
  811. draw_set_transform(Vector2(0, 0), 0, Vector2(1, 1));
  812. auto &draw_order = skeleton->get_spine_object()->getDrawOrder();
  813. for (int i = 0; i < (int) draw_order.size(); i++) {
  814. auto *slot = draw_order[i];
  815. if (!slot->getBone().isActive()) continue;
  816. auto *attachment = slot->getAttachment();
  817. if (!attachment) continue;
  818. if (!attachment->getRTTI().isExactly(spine::BoundingBoxAttachment::rtti)) continue;
  819. auto *bounding_box = (spine::BoundingBoxAttachment *) attachment;
  820. auto *vertices = &scratch_vertices;
  821. vertices->setSize(bounding_box->getWorldVerticesLength(), 0);
  822. bounding_box->computeWorldVertices(*slot, *vertices);
  823. size_t num_vertices = vertices->size() / 2;
  824. scratch_points.resize((int) num_vertices);
  825. memcpy(scratch_points.ptrw(), vertices->buffer(), num_vertices * 2 * sizeof(float));
  826. scratch_points.push_back(Vector2(vertices->buffer()[0], vertices->buffer()[1]));
  827. draw_polyline(scratch_points, debug_bounding_boxes_color, 2);
  828. }
  829. }
  830. if (debug_clipping) {
  831. draw_set_transform(Vector2(0, 0), 0, Vector2(1, 1));
  832. auto &draw_order = skeleton->get_spine_object()->getDrawOrder();
  833. for (int i = 0; i < (int) draw_order.size(); i++) {
  834. auto *slot = draw_order[i];
  835. if (!slot->getBone().isActive()) continue;
  836. auto *attachment = slot->getAttachment();
  837. if (!attachment) continue;
  838. if (!attachment->getRTTI().isExactly(spine::ClippingAttachment::rtti)) continue;
  839. auto *clipping = (spine::ClippingAttachment *) attachment;
  840. auto *vertices = &scratch_vertices;
  841. vertices->setSize(clipping->getWorldVerticesLength(), 0);
  842. clipping->computeWorldVertices(*slot, *vertices);
  843. size_t num_vertices = vertices->size() / 2;
  844. scratch_points.resize((int) num_vertices);
  845. memcpy(scratch_points.ptrw(), vertices->buffer(), num_vertices * 2 * sizeof(float));
  846. scratch_points.push_back(Vector2(vertices->buffer()[0], vertices->buffer()[1]));
  847. draw_polyline(scratch_points, debug_clipping_color, 2);
  848. }
  849. }
  850. spine::Bone *hovered_bone = nullptr;
  851. if (debug_root) {
  852. auto bone = skeleton->get_spine_object()->getRootBone();
  853. draw_bone(bone, debug_root_color);
  854. float bone_length = bone->getData().getLength();
  855. if (bone_length == 0) bone_length = debug_bones_thickness * 2;
  856. scratch_points.resize(5);
  857. scratch_points.set(0, Vector2(-debug_bones_thickness, 0));
  858. scratch_points.set(1, Vector2(0, debug_bones_thickness));
  859. scratch_points.set(2, Vector2(bone_length, 0));
  860. scratch_points.set(3, Vector2(0, -debug_bones_thickness));
  861. scratch_points.set(4, Vector2(-debug_bones_thickness, 0));
  862. Transform2D bone_transform(spine::MathUtil::Deg_Rad * bone->getWorldRotationX(), Vector2(bone->getWorldX(), bone->getWorldY()));
  863. bone_transform.scale_basis(Vector2(bone->getWorldScaleX(), bone->getWorldScaleY()));
  864. auto mouse_local_position = bone_transform.affine_inverse().xform(mouse_position);
  865. if (GEOMETRY2D::is_point_in_polygon(mouse_local_position, scratch_points)) {
  866. hovered_bone = bone;
  867. }
  868. }
  869. if (debug_bones) {
  870. auto &bones = skeleton->get_spine_object()->getBones();
  871. for (int i = 0; i < (int) bones.size(); i++) {
  872. auto *bone = bones[i];
  873. if (!bone->isActive()) continue;
  874. draw_bone(bone, debug_bones_color);
  875. float bone_length = bone->getData().getLength();
  876. if (bone_length == 0) bone_length = debug_bones_thickness * 2;
  877. scratch_points.resize(5);
  878. scratch_points.set(0, Vector2(-debug_bones_thickness, 0));
  879. scratch_points.set(1, Vector2(0, debug_bones_thickness));
  880. scratch_points.set(2, Vector2(bone_length, 0));
  881. scratch_points.set(3, Vector2(0, -debug_bones_thickness));
  882. scratch_points.set(4, Vector2(-debug_bones_thickness, 0));
  883. Transform2D bone_transform(spine::MathUtil::Deg_Rad * bone->getWorldRotationX(), Vector2(bone->getWorldX(), bone->getWorldY()));
  884. bone_transform.scale_basis(Vector2(bone->getWorldScaleX(), bone->getWorldScaleY()));
  885. auto mouse_local_position = bone_transform.affine_inverse().xform(mouse_position);
  886. if (GEOMETRY2D::is_point_in_polygon(mouse_local_position, scratch_points)) {
  887. hovered_bone = bone;
  888. }
  889. }
  890. }
  891. #if TOOLS_ENABLED
  892. Ref<Font> default_font;
  893. auto control = memnew(Control);
  894. #if VERSION_MAJOR > 3
  895. default_font = control->get_theme_default_font();
  896. #else
  897. default_font = control->get_font("font", "Label");
  898. #endif
  899. memfree(control);
  900. float editor_scale = EditorInterface::get_singleton()->get_editor_scale();
  901. float inverse_zoom = 1 / get_viewport()->get_global_canvas_transform().get_scale().x * editor_scale;
  902. Vector<String> hover_text_lines;
  903. if (hovered_slot) {
  904. hover_text_lines.push_back(String("Slot: ") + hovered_slot->getData().getName().buffer());
  905. }
  906. if (hovered_bone) {
  907. float thickness = debug_bones_thickness;
  908. debug_bones_thickness *= 1.1;
  909. draw_bone(hovered_bone, Color(debug_bones_color.r, debug_bones_color.g, debug_bones_color.b, 1));
  910. debug_bones_thickness = thickness;
  911. hover_text_lines.push_back(String("Bone: ") + hovered_bone->getData().getName().buffer());
  912. }
  913. auto global_scale = get_global_scale();
  914. draw_set_transform(mouse_position + Vector2(20, 0), -get_global_rotation(), Vector2(inverse_zoom * (1 / global_scale.x), inverse_zoom * (1 / global_scale.y)));
  915. #if VERSION_MAJOR > 3
  916. float line_height = default_font->get_height(Font::DEFAULT_FONT_SIZE) + default_font->get_descent(Font::DEFAULT_FONT_SIZE);
  917. #else
  918. float line_height = default_font->get_height() + default_font->get_descent();
  919. #endif
  920. float rect_width = 0;
  921. for (int i = 0; i < hover_text_lines.size(); i++) {
  922. rect_width = MAX(rect_width, default_font->get_string_size(hover_text_lines[i]).x);
  923. }
  924. #if VERSION_MAJOR > 3
  925. Rect2 background_rect(0, -default_font->get_height(Font::DEFAULT_FONT_SIZE) - 5, rect_width + 20, line_height * hover_text_lines.size() + 10);
  926. #else
  927. Rect2 background_rect(0, -default_font->get_height() - 5, rect_width + 20, line_height * hover_text_lines.size() + 10);
  928. #endif
  929. if (hover_text_lines.size() > 0) draw_rect(background_rect, Color(0, 0, 0, 0.8));
  930. for (int i = 0; i < hover_text_lines.size(); i++) {
  931. #if VERSION_MAJOR > 3
  932. draw_string(default_font, Vector2(10, 0 + i * default_font->get_height(Font::DEFAULT_FONT_SIZE)), hover_text_lines[i], HORIZONTAL_ALIGNMENT_LEFT, -1, Font::DEFAULT_FONT_SIZE, Color(1, 1, 1, 1));
  933. #else
  934. draw_string(default_font, Vector2(10, 0 + i * default_font->get_height()), hover_text_lines[i], Color(1, 1, 1, 1));
  935. #endif
  936. }
  937. #endif
  938. }
  939. void SpineSprite::draw_bone(spine::Bone *bone, const Color &color) {
  940. draw_set_transform(Vector2(bone->getWorldX(), bone->getWorldY()), spine::MathUtil::Deg_Rad * bone->getWorldRotationX(), Vector2(bone->getWorldScaleX(), bone->getWorldScaleY()));
  941. float bone_length = bone->getData().getLength();
  942. if (bone_length == 0) bone_length = debug_bones_thickness * 2;
  943. Vector<Vector2> points;
  944. points.push_back(Vector2(-debug_bones_thickness, 0));
  945. points.push_back(Vector2(0, debug_bones_thickness));
  946. points.push_back(Vector2(bone_length, 0));
  947. points.push_back(Vector2(0, -debug_bones_thickness));
  948. draw_colored_polygon(points, color);
  949. }
  950. void SpineSprite::callback(spine::AnimationState *state, spine::EventType type, spine::TrackEntry *entry, spine::Event *event) {
  951. Ref<SpineTrackEntry> entry_ref = Ref<SpineTrackEntry>(memnew(SpineTrackEntry));
  952. entry_ref->set_spine_object(this, entry);
  953. Ref<SpineEvent> event_ref(nullptr);
  954. if (event) {
  955. event_ref = Ref<SpineEvent>(memnew(SpineEvent));
  956. event_ref->set_spine_object(this, event);
  957. }
  958. switch (type) {
  959. case spine::EventType_Start:
  960. emit_signal("animation_started", this, animation_state, entry_ref);
  961. break;
  962. case spine::EventType_Interrupt:
  963. emit_signal("animation_interrupted", this, animation_state, entry_ref);
  964. break;
  965. case spine::EventType_End:
  966. emit_signal("animation_ended", this, animation_state, entry_ref);
  967. break;
  968. case spine::EventType_Complete:
  969. emit_signal("animation_completed", this, animation_state, entry_ref);
  970. break;
  971. case spine::EventType_Dispose:
  972. emit_signal("animation_disposed", this, animation_state, entry_ref);
  973. break;
  974. case spine::EventType_Event:
  975. emit_signal("animation_event", this, animation_state, entry_ref, event_ref);
  976. break;
  977. }
  978. }
  979. Transform2D SpineSprite::get_global_bone_transform(const String &bone_name) {
  980. if (!animation_state.is_valid() && !skeleton.is_valid()) return get_global_transform();
  981. auto bone = skeleton->find_bone(bone_name);
  982. if (!bone.is_valid()) {
  983. print_error(vformat("Bone: '%s' not found.", bone_name));
  984. return get_global_transform();
  985. }
  986. return bone->get_global_transform();
  987. }
  988. void SpineSprite::set_global_bone_transform(const String &bone_name, Transform2D transform) {
  989. if (!animation_state.is_valid() && !skeleton.is_valid()) return;
  990. auto bone = skeleton->find_bone(bone_name);
  991. if (!bone.is_valid()) return;
  992. bone->set_global_transform(transform);
  993. }
  994. SpineConstant::UpdateMode SpineSprite::get_update_mode() {
  995. return update_mode;
  996. }
  997. void SpineSprite::set_update_mode(SpineConstant::UpdateMode v) {
  998. update_mode = v;
  999. set_process_internal(update_mode == SpineConstant::UpdateMode_Process);
  1000. set_physics_process_internal(update_mode == SpineConstant::UpdateMode_Physics);
  1001. }
  1002. Ref<SpineSkin> SpineSprite::new_skin(const String &name) {
  1003. Ref<SpineSkin> skin = memnew(SpineSkin);
  1004. skin->init(name, this);
  1005. return skin;
  1006. }
  1007. Ref<Material> SpineSprite::get_normal_material() {
  1008. return normal_material;
  1009. }
  1010. void SpineSprite::set_normal_material(Ref<Material> material) {
  1011. normal_material = material;
  1012. }
  1013. Ref<Material> SpineSprite::get_additive_material() {
  1014. return additive_material;
  1015. }
  1016. void SpineSprite::set_additive_material(Ref<Material> material) {
  1017. additive_material = material;
  1018. }
  1019. Ref<Material> SpineSprite::get_multiply_material() {
  1020. return multiply_material;
  1021. }
  1022. void SpineSprite::set_multiply_material(Ref<Material> material) {
  1023. multiply_material = material;
  1024. }
  1025. Ref<Material> SpineSprite::get_screen_material() {
  1026. return screen_material;
  1027. }
  1028. void SpineSprite::set_screen_material(Ref<Material> material) {
  1029. screen_material = material;
  1030. }
  1031. #ifdef TOOLS_ENABLED
  1032. Rect2 SpineSprite::_edit_get_rect() const {
  1033. if (skeleton_data_res.is_valid() && skeleton_data_res->is_skeleton_data_loaded()) {
  1034. auto data = skeleton_data_res->get_skeleton_data();
  1035. return Rect2(data->getX(), -data->getY() - data->getHeight(), data->getWidth(), data->getHeight());
  1036. }
  1037. return Node2D::_edit_get_rect();
  1038. }
  1039. bool SpineSprite::_edit_use_rect() const {
  1040. return skeleton_data_res.is_valid() && skeleton_data_res->is_skeleton_data_loaded();
  1041. }
  1042. #endif