From 6e582e724f4ec16a89bbbc1c3a89503119738389 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Sat, 14 Mar 2026 15:08:30 +0100 Subject: [PATCH] [cpp][c] Port parser and sequence attachment changes from libgdx --- spine-c/src/generated/mesh_attachment.cpp | 66 ++--- spine-c/src/generated/mesh_attachment.h | 29 +- spine-c/src/generated/region_attachment.cpp | 84 +++--- spine-c/src/generated/region_attachment.h | 38 +-- spine-c/src/generated/sequence.cpp | 52 +++- spine-c/src/generated/sequence.h | 32 ++- spine-cpp/include/spine/MeshAttachment.h | 73 ++--- .../include/spine/PhysicsConstraintTimeline.h | 8 +- spine-cpp/include/spine/RegionAttachment.h | 70 ++--- spine-cpp/include/spine/Sequence.h | 51 ++-- spine-cpp/include/spine/SkeletonBinary.h | 2 +- spine-cpp/src/spine/AtlasAttachmentLoader.cpp | 29 +- spine-cpp/src/spine/MeshAttachment.cpp | 220 +++++++--------- spine-cpp/src/spine/RegionAttachment.cpp | 249 ++++++++---------- spine-cpp/src/spine/Sequence.cpp | 77 +++--- spine-cpp/src/spine/SequenceTimeline.cpp | 8 +- spine-cpp/src/spine/Skeleton.cpp | 2 +- spine-cpp/src/spine/SkeletonBinary.cpp | 24 +- spine-cpp/src/spine/SkeletonJson.cpp | 13 +- spine-cpp/src/spine/SkeletonRenderer.cpp | 18 +- spine-cpp/tests/SkeletonSerializer.h | 32 ++- 21 files changed, 565 insertions(+), 612 deletions(-) diff --git a/spine-c/src/generated/mesh_attachment.cpp b/spine-c/src/generated/mesh_attachment.cpp index 78dfa5bef..f4ecc6e78 100644 --- a/spine-c/src/generated/mesh_attachment.cpp +++ b/spine-c/src/generated/mesh_attachment.cpp @@ -3,8 +3,8 @@ using namespace spine; -spine_mesh_attachment spine_mesh_attachment_create(const char *name) { - return (spine_mesh_attachment) new (__FILE__, __LINE__) MeshAttachment(String(name)); +spine_mesh_attachment spine_mesh_attachment_create(const char *name, /*@null*/ spine_sequence sequence) { + return (spine_mesh_attachment) new (__FILE__, __LINE__) MeshAttachment(String(name), (Sequence *) sequence); } void spine_mesh_attachment_dispose(spine_mesh_attachment self) { @@ -28,21 +28,6 @@ void spine_mesh_attachment_compute_world_vertices_2(spine_mesh_attachment self, _self->computeWorldVertices(*((Skeleton *) skeleton), *((Slot *) slot), start, count, *((Array *) worldVertices), offset, stride); } -void spine_mesh_attachment_update_region(spine_mesh_attachment self) { - MeshAttachment *_self = (MeshAttachment *) self; - _self->updateRegion(); -} - -int spine_mesh_attachment_get_hull_length(spine_mesh_attachment self) { - MeshAttachment *_self = (MeshAttachment *) self; - return _self->getHullLength(); -} - -void spine_mesh_attachment_set_hull_length(spine_mesh_attachment self, int inValue) { - MeshAttachment *_self = (MeshAttachment *) self; - _self->setHullLength(inValue); -} - spine_array_float spine_mesh_attachment_get_region_u_vs(spine_mesh_attachment self) { MeshAttachment *_self = (MeshAttachment *) self; return (spine_array_float) &_self->getRegionUVs(); @@ -53,11 +38,6 @@ void spine_mesh_attachment_set_region_u_vs(spine_mesh_attachment self, spine_arr _self->setRegionUVs(*((Array *) inValue)); } -spine_array_float spine_mesh_attachment_get_u_vs(spine_mesh_attachment self) { - MeshAttachment *_self = (MeshAttachment *) self; - return (spine_array_float) &_self->getUVs(); -} - spine_array_unsigned_short spine_mesh_attachment_get_triangles(spine_mesh_attachment self) { MeshAttachment *_self = (MeshAttachment *) self; return (spine_array_unsigned_short) &_self->getTriangles(); @@ -68,9 +48,24 @@ void spine_mesh_attachment_set_triangles(spine_mesh_attachment self, spine_array _self->setTriangles(*((Array *) inValue)); } -spine_color spine_mesh_attachment_get_color(spine_mesh_attachment self) { +int spine_mesh_attachment_get_hull_length(spine_mesh_attachment self) { MeshAttachment *_self = (MeshAttachment *) self; - return (spine_color) &_self->getColor(); + return _self->getHullLength(); +} + +void spine_mesh_attachment_set_hull_length(spine_mesh_attachment self, int inValue) { + MeshAttachment *_self = (MeshAttachment *) self; + _self->setHullLength(inValue); +} + +spine_sequence spine_mesh_attachment_get_sequence(spine_mesh_attachment self) { + MeshAttachment *_self = (MeshAttachment *) self; + return (spine_sequence) &_self->getSequence(); +} + +void spine_mesh_attachment_update_sequence(spine_mesh_attachment self) { + MeshAttachment *_self = (MeshAttachment *) self; + _self->updateSequence(); } const char *spine_mesh_attachment_get_path(spine_mesh_attachment self) { @@ -83,24 +78,9 @@ void spine_mesh_attachment_set_path(spine_mesh_attachment self, const char *inVa _self->setPath(String(inValue)); } -/*@null*/ spine_texture_region spine_mesh_attachment_get_region(spine_mesh_attachment self) { +spine_color spine_mesh_attachment_get_color(spine_mesh_attachment self) { MeshAttachment *_self = (MeshAttachment *) self; - return (spine_texture_region) _self->getRegion(); -} - -void spine_mesh_attachment_set_region(spine_mesh_attachment self, /*@null*/ spine_texture_region region) { - MeshAttachment *_self = (MeshAttachment *) self; - _self->setRegion((TextureRegion *) region); -} - -/*@null*/ spine_sequence spine_mesh_attachment_get_sequence(spine_mesh_attachment self) { - MeshAttachment *_self = (MeshAttachment *) self; - return (spine_sequence) _self->getSequence(); -} - -void spine_mesh_attachment_set_sequence(spine_mesh_attachment self, /*@null*/ spine_sequence sequence) { - MeshAttachment *_self = (MeshAttachment *) self; - _self->setSequence((Sequence *) sequence); + return (spine_color) &_self->getColor(); } /*@null*/ spine_mesh_attachment spine_mesh_attachment_get_parent_mesh(spine_mesh_attachment self) { @@ -153,6 +133,10 @@ spine_mesh_attachment spine_mesh_attachment_new_linked_mesh(spine_mesh_attachmen return (spine_mesh_attachment) &_self->newLinkedMesh(); } +void spine_mesh_attachment_compute_u_vs(/*@null*/ spine_texture_region region, spine_array_float regionUVs, spine_array_float uvs) { + MeshAttachment::computeUVs((TextureRegion *) region, *((Array *) regionUVs), *((Array *) uvs)); +} + int spine_mesh_attachment_get_id(spine_mesh_attachment self) { MeshAttachment *_self = (MeshAttachment *) self; return _self->getId(); diff --git a/spine-c/src/generated/mesh_attachment.h b/spine-c/src/generated/mesh_attachment.h index c9c379070..394b37acf 100644 --- a/spine-c/src/generated/mesh_attachment.h +++ b/spine-c/src/generated/mesh_attachment.h @@ -9,7 +9,7 @@ extern "C" { #endif -SPINE_C_API spine_mesh_attachment spine_mesh_attachment_create(const char *name); +SPINE_C_API spine_mesh_attachment spine_mesh_attachment_create(const char *name, /*@null*/ spine_sequence sequence); SPINE_C_API void spine_mesh_attachment_dispose(spine_mesh_attachment self); @@ -18,30 +18,19 @@ SPINE_C_API void spine_mesh_attachment_compute_world_vertices_1(spine_mesh_attac size_t count, /*@null*/ float *worldVertices, size_t offset, size_t stride); SPINE_C_API void spine_mesh_attachment_compute_world_vertices_2(spine_mesh_attachment self, spine_skeleton skeleton, spine_slot slot, size_t start, size_t count, spine_array_float worldVertices, size_t offset, size_t stride); -SPINE_C_API void spine_mesh_attachment_update_region(spine_mesh_attachment self); -SPINE_C_API int spine_mesh_attachment_get_hull_length(spine_mesh_attachment self); -SPINE_C_API void spine_mesh_attachment_set_hull_length(spine_mesh_attachment self, int inValue); SPINE_C_API spine_array_float spine_mesh_attachment_get_region_u_vs(spine_mesh_attachment self); SPINE_C_API void spine_mesh_attachment_set_region_u_vs(spine_mesh_attachment self, spine_array_float inValue); -/** - * The UV pair for each vertex, normalized within the entire texture. See also - * MeshAttachment::updateRegion - */ -SPINE_C_API spine_array_float spine_mesh_attachment_get_u_vs(spine_mesh_attachment self); SPINE_C_API spine_array_unsigned_short spine_mesh_attachment_get_triangles(spine_mesh_attachment self); SPINE_C_API void spine_mesh_attachment_set_triangles(spine_mesh_attachment self, spine_array_unsigned_short inValue); -SPINE_C_API spine_color spine_mesh_attachment_get_color(spine_mesh_attachment self); +SPINE_C_API int spine_mesh_attachment_get_hull_length(spine_mesh_attachment self); +SPINE_C_API void spine_mesh_attachment_set_hull_length(spine_mesh_attachment self, int inValue); +SPINE_C_API spine_sequence spine_mesh_attachment_get_sequence(spine_mesh_attachment self); +SPINE_C_API void spine_mesh_attachment_update_sequence(spine_mesh_attachment self); SPINE_C_API const char *spine_mesh_attachment_get_path(spine_mesh_attachment self); SPINE_C_API void spine_mesh_attachment_set_path(spine_mesh_attachment self, const char *inValue); -SPINE_C_API /*@null*/ spine_texture_region spine_mesh_attachment_get_region(spine_mesh_attachment self); -SPINE_C_API void spine_mesh_attachment_set_region(spine_mesh_attachment self, /*@null*/ spine_texture_region region); -SPINE_C_API /*@null*/ spine_sequence spine_mesh_attachment_get_sequence(spine_mesh_attachment self); -SPINE_C_API void spine_mesh_attachment_set_sequence(spine_mesh_attachment self, /*@null*/ spine_sequence sequence); +SPINE_C_API spine_color spine_mesh_attachment_get_color(spine_mesh_attachment self); SPINE_C_API /*@null*/ spine_mesh_attachment spine_mesh_attachment_get_parent_mesh(spine_mesh_attachment self); SPINE_C_API void spine_mesh_attachment_set_parent_mesh(spine_mesh_attachment self, /*@null*/ spine_mesh_attachment inValue); -/** - * Nonessential. - */ SPINE_C_API spine_array_unsigned_short spine_mesh_attachment_get_edges(spine_mesh_attachment self); SPINE_C_API void spine_mesh_attachment_set_edges(spine_mesh_attachment self, spine_array_unsigned_short inValue); SPINE_C_API float spine_mesh_attachment_get_width(spine_mesh_attachment self); @@ -50,6 +39,12 @@ SPINE_C_API float spine_mesh_attachment_get_height(spine_mesh_attachment self); SPINE_C_API void spine_mesh_attachment_set_height(spine_mesh_attachment self, float inValue); SPINE_C_API spine_attachment spine_mesh_attachment_copy(spine_mesh_attachment self); SPINE_C_API spine_mesh_attachment spine_mesh_attachment_new_linked_mesh(spine_mesh_attachment self); +/** + * Computes UVs for a mesh attachment. + * + * @param uvs Output array for the computed UVs, same length as regionUVs. + */ +SPINE_C_API void spine_mesh_attachment_compute_u_vs(/*@null*/ spine_texture_region region, spine_array_float regionUVs, spine_array_float uvs); /** * Gets a unique ID for this attachment. */ diff --git a/spine-c/src/generated/region_attachment.cpp b/spine-c/src/generated/region_attachment.cpp index 124b9b8d5..095ebb127 100644 --- a/spine-c/src/generated/region_attachment.cpp +++ b/spine-c/src/generated/region_attachment.cpp @@ -3,8 +3,8 @@ using namespace spine; -spine_region_attachment spine_region_attachment_create(const char *name) { - return (spine_region_attachment) new (__FILE__, __LINE__) RegionAttachment(String(name)); +spine_region_attachment spine_region_attachment_create(const char *name, /*@null*/ spine_sequence sequence) { + return (spine_region_attachment) new (__FILE__, __LINE__) RegionAttachment(String(name), (Sequence *) sequence); } void spine_region_attachment_dispose(spine_region_attachment self) { @@ -16,21 +16,21 @@ spine_rtti spine_region_attachment_get_rtti(spine_region_attachment self) { return (spine_rtti) &_self->getRTTI(); } -void spine_region_attachment_update_region(spine_region_attachment self) { +void spine_region_attachment_compute_world_vertices_1(spine_region_attachment self, spine_slot slot, /*@null*/ float *vertexOffsets, + /*@null*/ float *worldVertices, size_t offset, size_t stride) { RegionAttachment *_self = (RegionAttachment *) self; - _self->updateRegion(); + _self->computeWorldVertices(*((Slot *) slot), vertexOffsets, worldVertices, offset, stride); } -void spine_region_attachment_compute_world_vertices_1(spine_region_attachment self, spine_slot slot, /*@null*/ float *worldVertices, size_t offset, - size_t stride) { +void spine_region_attachment_compute_world_vertices_2(spine_region_attachment self, spine_slot slot, spine_array_float vertexOffsets, + spine_array_float worldVertices, size_t offset, size_t stride) { RegionAttachment *_self = (RegionAttachment *) self; - _self->computeWorldVertices(*((Slot *) slot), worldVertices, offset, stride); + _self->computeWorldVertices(*((Slot *) slot), *((Array *) vertexOffsets), *((Array *) worldVertices), offset, stride); } -void spine_region_attachment_compute_world_vertices_2(spine_region_attachment self, spine_slot slot, spine_array_float worldVertices, size_t offset, - size_t stride) { +spine_array_float spine_region_attachment_get_offsets(spine_region_attachment self, spine_slot_pose pose) { RegionAttachment *_self = (RegionAttachment *) self; - _self->computeWorldVertices(*((Slot *) slot), *((Array *) worldVertices), offset, stride); + return (spine_array_float) &_self->getOffsets(*((SlotPose *) pose)); } float spine_region_attachment_get_x(spine_region_attachment self) { @@ -53,16 +53,6 @@ void spine_region_attachment_set_y(spine_region_attachment self, float inValue) _self->setY(inValue); } -float spine_region_attachment_get_rotation(spine_region_attachment self) { - RegionAttachment *_self = (RegionAttachment *) self; - return _self->getRotation(); -} - -void spine_region_attachment_set_rotation(spine_region_attachment self, float inValue) { - RegionAttachment *_self = (RegionAttachment *) self; - _self->setRotation(inValue); -} - float spine_region_attachment_get_scale_x(spine_region_attachment self) { RegionAttachment *_self = (RegionAttachment *) self; return _self->getScaleX(); @@ -83,6 +73,16 @@ void spine_region_attachment_set_scale_y(spine_region_attachment self, float inV _self->setScaleY(inValue); } +float spine_region_attachment_get_rotation(spine_region_attachment self) { + RegionAttachment *_self = (RegionAttachment *) self; + return _self->getRotation(); +} + +void spine_region_attachment_set_rotation(spine_region_attachment self, float inValue) { + RegionAttachment *_self = (RegionAttachment *) self; + _self->setRotation(inValue); +} + float spine_region_attachment_get_width(spine_region_attachment self) { RegionAttachment *_self = (RegionAttachment *) self; return _self->getWidth(); @@ -103,9 +103,14 @@ void spine_region_attachment_set_height(spine_region_attachment self, float inVa _self->setHeight(inValue); } -spine_color spine_region_attachment_get_color(spine_region_attachment self) { +spine_sequence spine_region_attachment_get_sequence(spine_region_attachment self) { RegionAttachment *_self = (RegionAttachment *) self; - return (spine_color) &_self->getColor(); + return (spine_sequence) &_self->getSequence(); +} + +void spine_region_attachment_update_sequence(spine_region_attachment self) { + RegionAttachment *_self = (RegionAttachment *) self; + _self->updateSequence(); } const char *spine_region_attachment_get_path(spine_region_attachment self) { @@ -118,34 +123,9 @@ void spine_region_attachment_set_path(spine_region_attachment self, const char * _self->setPath(String(inValue)); } -/*@null*/ spine_texture_region spine_region_attachment_get_region(spine_region_attachment self) { +spine_color spine_region_attachment_get_color(spine_region_attachment self) { RegionAttachment *_self = (RegionAttachment *) self; - return (spine_texture_region) _self->getRegion(); -} - -void spine_region_attachment_set_region(spine_region_attachment self, /*@null*/ spine_texture_region region) { - RegionAttachment *_self = (RegionAttachment *) self; - _self->setRegion((TextureRegion *) region); -} - -/*@null*/ spine_sequence spine_region_attachment_get_sequence(spine_region_attachment self) { - RegionAttachment *_self = (RegionAttachment *) self; - return (spine_sequence) _self->getSequence(); -} - -void spine_region_attachment_set_sequence(spine_region_attachment self, /*@null*/ spine_sequence sequence) { - RegionAttachment *_self = (RegionAttachment *) self; - _self->setSequence((Sequence *) sequence); -} - -spine_array_float spine_region_attachment_get_offset(spine_region_attachment self) { - RegionAttachment *_self = (RegionAttachment *) self; - return (spine_array_float) &_self->getOffset(); -} - -spine_array_float spine_region_attachment_get_u_vs(spine_region_attachment self) { - RegionAttachment *_self = (RegionAttachment *) self; - return (spine_array_float) &_self->getUVs(); + return (spine_color) &_self->getColor(); } spine_attachment spine_region_attachment_copy(spine_region_attachment self) { @@ -153,6 +133,12 @@ spine_attachment spine_region_attachment_copy(spine_region_attachment self) { return (spine_attachment) &_self->copy(); } +void spine_region_attachment_compute_u_vs(/*@null*/ spine_texture_region region, float x, float y, float scaleX, float scaleY, float rotation, + float width, float height, spine_array_float offset, spine_array_float uvs) { + RegionAttachment::computeUVs((TextureRegion *) region, x, y, scaleX, scaleY, rotation, width, height, *((Array *) offset), + *((Array *) uvs)); +} + const char *spine_region_attachment_get_name(spine_region_attachment self) { RegionAttachment *_self = (RegionAttachment *) self; return _self->getName().buffer(); diff --git a/spine-c/src/generated/region_attachment.h b/spine-c/src/generated/region_attachment.h index 22c1365a9..feeddf5a1 100644 --- a/spine-c/src/generated/region_attachment.h +++ b/spine-c/src/generated/region_attachment.h @@ -9,48 +9,56 @@ extern "C" { #endif -SPINE_C_API spine_region_attachment spine_region_attachment_create(const char *name); +SPINE_C_API spine_region_attachment spine_region_attachment_create(const char *name, /*@null*/ spine_sequence sequence); SPINE_C_API void spine_region_attachment_dispose(spine_region_attachment self); SPINE_C_API spine_rtti spine_region_attachment_get_rtti(spine_region_attachment self); -SPINE_C_API void spine_region_attachment_update_region(spine_region_attachment self); /** * Transforms the attachment's four vertices to world coordinates. * * @param slot The parent slot. + * @param vertexOffsets The vertex offsets. * @param worldVertices The output world vertices. Must have a length greater than or equal to offset + 8. * @param offset The worldVertices index to begin writing values. * @param stride The number of worldVertices entries between the value pairs written. */ -SPINE_C_API void spine_region_attachment_compute_world_vertices_1(spine_region_attachment self, spine_slot slot, /*@null*/ float *worldVertices, - size_t offset, size_t stride); -SPINE_C_API void spine_region_attachment_compute_world_vertices_2(spine_region_attachment self, spine_slot slot, spine_array_float worldVertices, - size_t offset, size_t stride); +SPINE_C_API void spine_region_attachment_compute_world_vertices_1(spine_region_attachment self, spine_slot slot, /*@null*/ float *vertexOffsets, + /*@null*/ float *worldVertices, size_t offset, size_t stride); +SPINE_C_API void spine_region_attachment_compute_world_vertices_2(spine_region_attachment self, spine_slot slot, spine_array_float vertexOffsets, + spine_array_float worldVertices, size_t offset, size_t stride); +/** + * Returns the vertex offsets for the specified slot pose. + */ +SPINE_C_API spine_array_float spine_region_attachment_get_offsets(spine_region_attachment self, spine_slot_pose pose); SPINE_C_API float spine_region_attachment_get_x(spine_region_attachment self); SPINE_C_API void spine_region_attachment_set_x(spine_region_attachment self, float inValue); SPINE_C_API float spine_region_attachment_get_y(spine_region_attachment self); SPINE_C_API void spine_region_attachment_set_y(spine_region_attachment self, float inValue); -SPINE_C_API float spine_region_attachment_get_rotation(spine_region_attachment self); -SPINE_C_API void spine_region_attachment_set_rotation(spine_region_attachment self, float inValue); SPINE_C_API float spine_region_attachment_get_scale_x(spine_region_attachment self); SPINE_C_API void spine_region_attachment_set_scale_x(spine_region_attachment self, float inValue); SPINE_C_API float spine_region_attachment_get_scale_y(spine_region_attachment self); SPINE_C_API void spine_region_attachment_set_scale_y(spine_region_attachment self, float inValue); +SPINE_C_API float spine_region_attachment_get_rotation(spine_region_attachment self); +SPINE_C_API void spine_region_attachment_set_rotation(spine_region_attachment self, float inValue); SPINE_C_API float spine_region_attachment_get_width(spine_region_attachment self); SPINE_C_API void spine_region_attachment_set_width(spine_region_attachment self, float inValue); SPINE_C_API float spine_region_attachment_get_height(spine_region_attachment self); SPINE_C_API void spine_region_attachment_set_height(spine_region_attachment self, float inValue); -SPINE_C_API spine_color spine_region_attachment_get_color(spine_region_attachment self); +SPINE_C_API spine_sequence spine_region_attachment_get_sequence(spine_region_attachment self); +SPINE_C_API void spine_region_attachment_update_sequence(spine_region_attachment self); SPINE_C_API const char *spine_region_attachment_get_path(spine_region_attachment self); SPINE_C_API void spine_region_attachment_set_path(spine_region_attachment self, const char *inValue); -SPINE_C_API /*@null*/ spine_texture_region spine_region_attachment_get_region(spine_region_attachment self); -SPINE_C_API void spine_region_attachment_set_region(spine_region_attachment self, /*@null*/ spine_texture_region region); -SPINE_C_API /*@null*/ spine_sequence spine_region_attachment_get_sequence(spine_region_attachment self); -SPINE_C_API void spine_region_attachment_set_sequence(spine_region_attachment self, /*@null*/ spine_sequence sequence); -SPINE_C_API spine_array_float spine_region_attachment_get_offset(spine_region_attachment self); -SPINE_C_API spine_array_float spine_region_attachment_get_u_vs(spine_region_attachment self); +SPINE_C_API spine_color spine_region_attachment_get_color(spine_region_attachment self); SPINE_C_API spine_attachment spine_region_attachment_copy(spine_region_attachment self); +/** + * Computes UVs and offsets for a region attachment. + * + * @param uvs Output array for the computed UVs, length of 8. + * @param offset Output array for the computed vertex offsets, length of 8. + */ +SPINE_C_API void spine_region_attachment_compute_u_vs(/*@null*/ spine_texture_region region, float x, float y, float scaleX, float scaleY, + float rotation, float width, float height, spine_array_float offset, spine_array_float uvs); SPINE_C_API const char *spine_region_attachment_get_name(spine_region_attachment self); SPINE_C_API int spine_region_attachment_get_ref_count(spine_region_attachment self); SPINE_C_API void spine_region_attachment_reference(spine_region_attachment self); diff --git a/spine-c/src/generated/sequence.cpp b/spine-c/src/generated/sequence.cpp index 4baf9e6d2..f6a7bbe89 100644 --- a/spine-c/src/generated/sequence.cpp +++ b/spine-c/src/generated/sequence.cpp @@ -3,37 +3,51 @@ using namespace spine; -spine_sequence spine_sequence_create(int count) { - return (spine_sequence) new (__FILE__, __LINE__) Sequence(count); +spine_sequence spine_sequence_create(int count, bool pathSuffix) { + return (spine_sequence) new (__FILE__, __LINE__) Sequence(count, pathSuffix); +} + +spine_sequence spine_sequence_create2(spine_sequence other) { + return (spine_sequence) new (__FILE__, __LINE__) Sequence(*((const Sequence *) other)); } void spine_sequence_dispose(spine_sequence self) { delete (Sequence *) self; } -spine_sequence spine_sequence_copy(spine_sequence self) { +void spine_sequence_update_1(spine_sequence self, spine_region_attachment attachment) { Sequence *_self = (Sequence *) self; - return (spine_sequence) &_self->copy(); + _self->update(*((RegionAttachment *) attachment)); } -void spine_sequence_apply(spine_sequence self, /*@null*/ spine_slot_pose slot, /*@null*/ spine_attachment attachment) { +void spine_sequence_update_2(spine_sequence self, spine_mesh_attachment attachment) { Sequence *_self = (Sequence *) self; - _self->apply((SlotPose *) slot, (Attachment *) attachment); + _self->update(*((MeshAttachment *) attachment)); } -const char *spine_sequence_get_path(spine_sequence self, const char *basePath, int index) { +spine_array_texture_region spine_sequence_get_regions(spine_sequence self) { Sequence *_self = (Sequence *) self; - return (const char *) &_self->getPath(String(basePath), index); + return (spine_array_texture_region) &_self->getRegions(); } -int spine_sequence_get_id(spine_sequence self) { +int spine_sequence_resolve_index(spine_sequence self, spine_slot_pose pose) { Sequence *_self = (Sequence *) self; - return _self->getId(); + return _self->resolveIndex(*((SlotPose *) pose)); } -void spine_sequence_set_id(spine_sequence self, int id) { +/*@null*/ spine_texture_region spine_sequence_get_region(spine_sequence self, int index) { Sequence *_self = (Sequence *) self; - _self->setId(id); + return (spine_texture_region) _self->getRegion(index); +} + +spine_array_float spine_sequence_get_u_vs(spine_sequence self, int index) { + Sequence *_self = (Sequence *) self; + return (spine_array_float) &_self->getUVs(index); +} + +spine_array_float spine_sequence_get_offsets(spine_sequence self, int index) { + Sequence *_self = (Sequence *) self; + return (spine_array_float) &_self->getOffsets(index); } int spine_sequence_get_start(spine_sequence self) { @@ -66,7 +80,17 @@ void spine_sequence_set_setup_index(spine_sequence self, int setupIndex) { _self->setSetupIndex(setupIndex); } -spine_array_texture_region spine_sequence_get_regions(spine_sequence self) { +bool spine_sequence_get_path_suffix(spine_sequence self) { Sequence *_self = (Sequence *) self; - return (spine_array_texture_region) &_self->getRegions(); + return _self->getPathSuffix(); +} + +const char *spine_sequence_get_path(spine_sequence self, const char *basePath, int index) { + Sequence *_self = (Sequence *) self; + return (const char *) &_self->getPath(String(basePath), index); +} + +int spine_sequence_get_id(spine_sequence self) { + Sequence *_self = (Sequence *) self; + return _self->getId(); } diff --git a/spine-c/src/generated/sequence.h b/spine-c/src/generated/sequence.h index cfdbfb69b..8fd443c9e 100644 --- a/spine-c/src/generated/sequence.h +++ b/spine-c/src/generated/sequence.h @@ -9,18 +9,29 @@ extern "C" { #endif -SPINE_C_API spine_sequence spine_sequence_create(int count); +SPINE_C_API spine_sequence spine_sequence_create(int count, bool pathSuffix); +/** + * Copy constructor. + */ +SPINE_C_API spine_sequence spine_sequence_create2(spine_sequence other); SPINE_C_API void spine_sequence_dispose(spine_sequence self); -SPINE_C_API spine_sequence spine_sequence_copy(spine_sequence self); -SPINE_C_API void spine_sequence_apply(spine_sequence self, /*@null*/ spine_slot_pose slot, /*@null*/ spine_attachment attachment); -SPINE_C_API const char *spine_sequence_get_path(spine_sequence self, const char *basePath, int index); /** - * Returns a unique ID for this attachment. + * Computes UVs and offsets for the specified attachment. Must be called if the + * regions or attachment properties are changed. */ -SPINE_C_API int spine_sequence_get_id(spine_sequence self); -SPINE_C_API void spine_sequence_set_id(spine_sequence self, int id); +SPINE_C_API void spine_sequence_update_1(spine_sequence self, spine_region_attachment attachment); +SPINE_C_API void spine_sequence_update_2(spine_sequence self, spine_mesh_attachment attachment); +SPINE_C_API spine_array_texture_region spine_sequence_get_regions(spine_sequence self); +SPINE_C_API int spine_sequence_resolve_index(spine_sequence self, spine_slot_pose pose); +SPINE_C_API /*@null*/ spine_texture_region spine_sequence_get_region(spine_sequence self, int index); +SPINE_C_API spine_array_float spine_sequence_get_u_vs(spine_sequence self, int index); +/** + * Returns vertex offsets from the center of a RegionAttachment. Invalid to call + * for a MeshAttachment. + */ +SPINE_C_API spine_array_float spine_sequence_get_offsets(spine_sequence self, int index); SPINE_C_API int spine_sequence_get_start(spine_sequence self); SPINE_C_API void spine_sequence_set_start(spine_sequence self, int start); SPINE_C_API int spine_sequence_get_digits(spine_sequence self); @@ -30,7 +41,12 @@ SPINE_C_API void spine_sequence_set_digits(spine_sequence self, int digits); */ SPINE_C_API int spine_sequence_get_setup_index(spine_sequence self); SPINE_C_API void spine_sequence_set_setup_index(spine_sequence self, int setupIndex); -SPINE_C_API spine_array_texture_region spine_sequence_get_regions(spine_sequence self); +SPINE_C_API bool spine_sequence_get_path_suffix(spine_sequence self); +SPINE_C_API const char *spine_sequence_get_path(spine_sequence self, const char *basePath, int index); +/** + * Returns a unique ID for this attachment. + */ +SPINE_C_API int spine_sequence_get_id(spine_sequence self); #ifdef __cplusplus } diff --git a/spine-cpp/include/spine/MeshAttachment.h b/spine-cpp/include/spine/MeshAttachment.h index 29ee64799..aff94e276 100644 --- a/spine-cpp/include/spine/MeshAttachment.h +++ b/spine-cpp/include/spine/MeshAttachment.h @@ -30,26 +30,24 @@ #ifndef Spine_MeshAttachment_h #define Spine_MeshAttachment_h -#include -#include -#include #include #include #include +#include +#include +#include namespace spine { /// Attachment that displays a texture region using a mesh. class SP_API MeshAttachment : public VertexAttachment { friend class SkeletonBinary; - friend class SkeletonJson; - friend class AtlasAttachmentLoader; RTTI_DECL public: - explicit MeshAttachment(const String &name); + explicit MeshAttachment(const String &name, Sequence *sequence); virtual ~MeshAttachment(); @@ -58,72 +56,55 @@ namespace spine { virtual void computeWorldVertices(Skeleton &skeleton, Slot &slot, size_t start, size_t count, float *worldVertices, size_t offset, size_t stride = 2) override; - void updateRegion(); - - int getHullLength(); - - void setHullLength(int inValue); - Array &getRegionUVs(); - void setRegionUVs(Array &inValue); - /// The UV pair for each vertex, normalized within the entire texture. See also MeshAttachment::updateRegion - Array &getUVs(); - Array &getTriangles(); - void setTriangles(Array &inValue); + int getHullLength(); + void setHullLength(int inValue); + + Sequence &getSequence(); + + void updateSequence(); + + const String &getPath(); + void setPath(const String &inValue); + Color &getColor(); - const String &getPath(); - - void setPath(const String &inValue); - - TextureRegion *getRegion(); - - void setRegion(TextureRegion *region); - - Sequence *getSequence(); - - void setSequence(Sequence *sequence); - MeshAttachment *getParentMesh(); - void setParentMesh(MeshAttachment *inValue); - // Nonessential. Array &getEdges(); - void setEdges(Array &inValue); float getWidth(); - void setWidth(float inValue); float getHeight(); - void setHeight(float inValue); virtual Attachment ©() override; MeshAttachment &newLinkedMesh(); - private: - TextureRegion *_region; - String _path; - Array _regionUVs; - Array _uvs; - Array _triangles; - Color _color; - int _hullLength; - MeshAttachment *_parentMesh; - Sequence *_sequence; + /// Computes UVs for a mesh attachment. + /// @param uvs Output array for the computed UVs, same length as regionUVs. + static void computeUVs(TextureRegion *region, Array ®ionUVs, Array &uvs); + + private: + Sequence *_sequence; + Array _regionUVs; + Array _triangles; + int _hullLength; + String _path; + Color _color; + MeshAttachment *_parentMesh; - // Nonessential. Array _edges; - int _width, _height; + float _width, _height; }; } diff --git a/spine-cpp/include/spine/PhysicsConstraintTimeline.h b/spine-cpp/include/spine/PhysicsConstraintTimeline.h index 94c6dbe37..9fe0c946e 100644 --- a/spine-cpp/include/spine/PhysicsConstraintTimeline.h +++ b/spine-cpp/include/spine/PhysicsConstraintTimeline.h @@ -185,7 +185,9 @@ namespace spine { public: explicit PhysicsConstraintWindTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex) - : PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintWind) { _additive = true; }; + : PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintWind) { + _additive = true; + }; protected: float get(PhysicsConstraintPose &pose) override { @@ -211,7 +213,9 @@ namespace spine { public: explicit PhysicsConstraintGravityTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex) - : PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintGravity) { _additive = true; }; + : PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintGravity) { + _additive = true; + }; protected: float get(PhysicsConstraintPose &pose) override { diff --git a/spine-cpp/include/spine/RegionAttachment.h b/spine-cpp/include/spine/RegionAttachment.h index af5820e4b..449c7449c 100644 --- a/spine-cpp/include/spine/RegionAttachment.h +++ b/spine-cpp/include/spine/RegionAttachment.h @@ -33,89 +33,78 @@ #include #include #include +#include #include #include -#include - namespace spine { - class Bone; class Slot; + class SlotPose; /// Attachment that displays a texture region. class SP_API RegionAttachment : public Attachment { friend class SkeletonBinary; - friend class SkeletonJson; - friend class AtlasAttachmentLoader; RTTI_DECL public: - explicit RegionAttachment(const String &name); + explicit RegionAttachment(const String &name, Sequence *sequence); virtual ~RegionAttachment(); - void updateRegion(); - /// Transforms the attachment's four vertices to world coordinates. /// @param slot The parent slot. + /// @param vertexOffsets The vertex offsets. /// @param worldVertices The output world vertices. Must have a length greater than or equal to offset + 8. /// @param offset The worldVertices index to begin writing values. /// @param stride The number of worldVertices entries between the value pairs written. - void computeWorldVertices(Slot &slot, float *worldVertices, size_t offset, size_t stride = 2); + void computeWorldVertices(Slot &slot, float *vertexOffsets, float *worldVertices, size_t offset, size_t stride = 2); - void computeWorldVertices(Slot &slot, Array &worldVertices, size_t offset, size_t stride = 2); + void computeWorldVertices(Slot &slot, Array &vertexOffsets, Array &worldVertices, size_t offset, size_t stride = 2); + + /// Returns the vertex offsets for the specified slot pose. + Array &getOffsets(SlotPose &pose); float getX(); - void setX(float inValue); float getY(); - void setY(float inValue); - float getRotation(); - - void setRotation(float inValue); - float getScaleX(); - void setScaleX(float inValue); float getScaleY(); - void setScaleY(float inValue); - float getWidth(); + float getRotation(); + void setRotation(float inValue); + float getWidth(); void setWidth(float inValue); float getHeight(); - void setHeight(float inValue); + Sequence &getSequence(); + + void updateSequence(); + + const String &getPath(); + void setPath(const String &inValue); + Color &getColor(); - const String &getPath(); - - void setPath(const String &inValue); - - TextureRegion *getRegion(); - - void setRegion(TextureRegion *region); - - Sequence *getSequence(); - - void setSequence(Sequence *sequence); - - Array &getOffset(); - - Array &getUVs(); - virtual Attachment ©() override; + /// Computes UVs and offsets for a region attachment. + /// @param uvs Output array for the computed UVs, length of 8. + /// @param offset Output array for the computed vertex offsets, length of 8. + static void computeUVs(TextureRegion *region, float x, float y, float scaleX, float scaleY, float rotation, float width, float height, + Array &offset, Array &uvs); + private: static const int BLX; static const int BLY; @@ -126,13 +115,10 @@ namespace spine { static const int BRX; static const int BRY; - TextureRegion *_region; - String _path; - float _x, _y, _scaleX, _scaleY, _rotation, _width, _height; - Array _uvs; - Array _offset; - Color _color; Sequence *_sequence; + float _x, _y, _scaleX, _scaleY, _rotation, _width, _height; + String _path; + Color _color; }; } diff --git a/spine-cpp/include/spine/Sequence.h b/spine-cpp/include/spine/Sequence.h index 6b4554edd..4a9d8e4a8 100644 --- a/spine-cpp/include/spine/Sequence.h +++ b/spine-cpp/include/spine/Sequence.h @@ -31,40 +31,49 @@ #define Spine_Sequence_h #include +#include #include #include -#include namespace spine { class SlotPose; - class Attachment; + class RegionAttachment; + class MeshAttachment; class SkeletonBinary; class SkeletonJson; + /// Holds texture regions, UVs, and vertex offsets for rendering a region or mesh attachment. + /// Regions must be populated and update() called before use. class SP_API Sequence : public SpineObject { friend class SkeletonBinary; friend class SkeletonJson; public: - Sequence(int count); + Sequence(int count, bool pathSuffix); + + /// Copy constructor. + Sequence(const Sequence &other); ~Sequence(); - Sequence ©(); + /// Computes UVs and offsets for the specified attachment. Must be called if the regions + /// or attachment properties are changed. + void update(RegionAttachment &attachment); + void update(MeshAttachment &attachment); - void apply(SlotPose *slot, Attachment *attachment); - - String &getPath(const String &basePath, int index); - - /// Returns a unique ID for this attachment. - int getId() { - return _id; + Array &getRegions() { + return _regions; } - void setId(int id) { - _id = id; - } + int resolveIndex(SlotPose &pose); + + TextureRegion *getRegion(int index); + + Array &getUVs(int index); + + /// Returns vertex offsets from the center of a RegionAttachment. Invalid to call for a MeshAttachment. + Array &getOffsets(int index); int getStart() { return _start; @@ -91,14 +100,24 @@ namespace spine { _setupIndex = setupIndex; } - Array &getRegions() { - return _regions; + bool getPathSuffix() { + return _pathSuffix; + } + + String &getPath(const String &basePath, int index); + + /// Returns a unique ID for this attachment. + int getId() { + return _id; } private: static int _nextID; int _id; Array _regions; + bool _pathSuffix; + Array> _uvs; + Array> _offsets; int _start; int _digits; int _setupIndex; diff --git a/spine-cpp/include/spine/SkeletonBinary.h b/spine-cpp/include/spine/SkeletonBinary.h index a6179744f..920d8b19c 100644 --- a/spine-cpp/include/spine/SkeletonBinary.h +++ b/spine-cpp/include/spine/SkeletonBinary.h @@ -243,7 +243,7 @@ namespace spine { Attachment *readAttachment(DataInput &input, Skin &skin, int slotIndex, const String &attachmentName, SkeletonData &skeletonData, bool nonessential); - Sequence *readSequence(DataInput &input); + Sequence *readSequence(DataInput &input, bool hasPathSuffix); int readVertices(DataInput &input, Array &vertices, Array &bones, bool weighted); diff --git a/spine-cpp/src/spine/AtlasAttachmentLoader.cpp b/spine-cpp/src/spine/AtlasAttachmentLoader.cpp index 50f6257d8..c78e31c54 100644 --- a/spine-cpp/src/spine/AtlasAttachmentLoader.cpp +++ b/spine-cpp/src/spine/AtlasAttachmentLoader.cpp @@ -43,41 +43,24 @@ using namespace spine; AtlasAttachmentLoader::AtlasAttachmentLoader(Atlas &atlas) : AttachmentLoader(), _atlas(&atlas) { } -bool loadSequence(Atlas *atlas, const String &basePath, Sequence *sequence) { +static void findRegions(Atlas *atlas, AtlasAttachmentLoader *loader, const String &name, const String &basePath, Sequence *sequence) { Array ®ions = sequence->getRegions(); for (int i = 0, n = (int) regions.size(); i < n; i++) { String path = sequence->getPath(basePath, i); - regions[i] = atlas->findRegion(path); - if (!regions[i]) return false; + regions[i] = loader->findRegion(path); } - return true; } RegionAttachment *AtlasAttachmentLoader::newRegionAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) { SP_UNUSED(skin); - RegionAttachment *attachment = new (__FILE__, __LINE__) RegionAttachment(name); - if (sequence) { - if (!loadSequence(_atlas, path, sequence)) return NULL; - } else { - AtlasRegion *region = findRegion(path); - if (!region) return NULL; - attachment->setRegion(region); - } - return attachment; + findRegions(_atlas, this, name, path, sequence); + return new (__FILE__, __LINE__) RegionAttachment(name, sequence); } MeshAttachment *AtlasAttachmentLoader::newMeshAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) { SP_UNUSED(skin); - MeshAttachment *attachment = new (__FILE__, __LINE__) MeshAttachment(name); - - if (sequence) { - if (!loadSequence(_atlas, path, sequence)) return NULL; - } else { - AtlasRegion *region = findRegion(path); - if (!region) return NULL; - attachment->setRegion(region); - } - return attachment; + findRegions(_atlas, this, name, path, sequence); + return new (__FILE__, __LINE__) MeshAttachment(name, sequence); } BoundingBoxAttachment *AtlasAttachmentLoader::newBoundingBoxAttachment(Skin &skin, const String &name) { diff --git a/spine-cpp/src/spine/MeshAttachment.cpp b/spine-cpp/src/spine/MeshAttachment.cpp index fdc2ef007..00832683d 100644 --- a/spine-cpp/src/spine/MeshAttachment.cpp +++ b/spine-cpp/src/spine/MeshAttachment.cpp @@ -29,100 +29,26 @@ #include #include -#include + +#include using namespace spine; RTTI_IMPL(MeshAttachment, VertexAttachment) -MeshAttachment::MeshAttachment(const String &name) - : VertexAttachment(name), _region(NULL), _path(), _color(1, 1, 1, 1), _hullLength(0), _parentMesh(NULL), _sequence(NULL), _width(0), _height(0) { +MeshAttachment::MeshAttachment(const String &name, Sequence *sequence) + : VertexAttachment(name), _sequence(sequence), _regionUVs(), _triangles(), _hullLength(0), _path(), _color(1, 1, 1, 1), _parentMesh(NULL), + _edges(), _width(0), _height(0) { + assert(sequence); } MeshAttachment::~MeshAttachment() { - if (_sequence) delete _sequence; + delete _sequence; } -void MeshAttachment::updateRegion() { - if (_uvs.size() != _regionUVs.size()) _uvs.setSize(_regionUVs.size(), 0); - int n = (int) _regionUVs.size(); - float u, v, width, height; - if (_region != nullptr && _region->getRTTI().instanceOf(AtlasRegion::rtti)) { - AtlasRegion *atlasRegion = static_cast(_region); - u = _region->_u; - v = _region->_v; - - float textureWidth = atlasRegion->_packedWidth / (_region->_u2 - _region->_u); - float textureHeight = atlasRegion->_packedHeight / (_region->_v2 - _region->_v); - - switch (atlasRegion->_degrees) { - case 90: { - // Note: packed dimensions are swapped in Atlas.cpp for 90-degree regions - // So we need to un-swap them here to get the original atlas dimensions - textureWidth = atlasRegion->_packedWidth / (_region->_u2 - _region->_u); - textureHeight = atlasRegion->_packedHeight / (_region->_v2 - _region->_v); - u -= (atlasRegion->_originalHeight - atlasRegion->_offsetY - atlasRegion->_packedWidth) / textureWidth; - v -= (atlasRegion->_originalWidth - atlasRegion->_offsetX - atlasRegion->_packedHeight) / textureHeight; - width = atlasRegion->_originalHeight / textureWidth; - height = atlasRegion->_originalWidth / textureHeight; - for (int i = 0; i < n; i += 2) { - _uvs[i] = u + _regionUVs[i + 1] * width; - _uvs[i + 1] = v + (1 - _regionUVs[i]) * height; - } - return; - } - case 180: { - u -= (atlasRegion->_originalWidth - atlasRegion->_offsetX - atlasRegion->_packedWidth) / textureWidth; - v -= atlasRegion->_offsetY / textureHeight; - width = atlasRegion->_originalWidth / textureWidth; - height = atlasRegion->_originalHeight / textureHeight; - for (int i = 0; i < n; i += 2) { - _uvs[i] = u + (1 - _regionUVs[i]) * width; - _uvs[i + 1] = v + (1 - _regionUVs[i + 1]) * height; - } - return; - } - case 270: { - textureHeight = atlasRegion->_packedHeight / (_region->_v2 - _region->_v); - textureWidth = atlasRegion->_packedWidth / (_region->_u2 - _region->_u); - u -= atlasRegion->_offsetY / textureWidth; - v -= atlasRegion->_offsetX / textureHeight; - width = atlasRegion->_originalHeight / textureWidth; - height = atlasRegion->_originalWidth / textureHeight; - for (int i = 0; i < n; i += 2) { - _uvs[i] = u + (1 - _regionUVs[i + 1]) * width; - _uvs[i + 1] = v + _regionUVs[i] * height; - } - return; - } - default: { - u -= atlasRegion->_offsetX / textureWidth; - v -= (atlasRegion->_originalHeight - atlasRegion->_offsetY - atlasRegion->_packedHeight) / textureHeight; - width = atlasRegion->_originalWidth / textureWidth; - height = atlasRegion->_originalHeight / textureHeight; - } - } - } else if (_region == nullptr) { - u = v = 0; - width = height = 1; - } else { - u = _region->_u; - v = _region->_v; - width = _region->_u2 - u; - height = _region->_v2 - v; - } - for (int i = 0; i < n; i += 2) { - _uvs[i] = u + _regionUVs[i] * width; - _uvs[i + 1] = v + _regionUVs[i + 1] * height; - } -} - -int MeshAttachment::getHullLength() { - return _hullLength; -} - -void MeshAttachment::setHullLength(int inValue) { - _hullLength = inValue; +void MeshAttachment::computeWorldVertices(Skeleton &skeleton, Slot &slot, size_t start, size_t count, float *worldVertices, size_t offset, + size_t stride) { + VertexAttachment::computeWorldVertices(skeleton, slot, start, count, worldVertices, offset, stride); } Array &MeshAttachment::getRegionUVs() { @@ -133,10 +59,6 @@ void MeshAttachment::setRegionUVs(Array &inValue) { _regionUVs.clearAndAddAll(inValue); } -Array &MeshAttachment::getUVs() { - return _uvs; -} - Array &MeshAttachment::getTriangles() { return _triangles; } @@ -145,6 +67,22 @@ void MeshAttachment::setTriangles(Array &inValue) { _triangles.clearAndAddAll(inValue); } +int MeshAttachment::getHullLength() { + return _hullLength; +} + +void MeshAttachment::setHullLength(int inValue) { + _hullLength = inValue; +} + +Sequence &MeshAttachment::getSequence() { + return *_sequence; +} + +void MeshAttachment::updateSequence() { + _sequence->update(*this); +} + const String &MeshAttachment::getPath() { return _path; } @@ -153,20 +91,8 @@ void MeshAttachment::setPath(const String &inValue) { _path = inValue; } -TextureRegion *MeshAttachment::getRegion() { - return _region; -} - -void MeshAttachment::setRegion(TextureRegion *region) { - _region = region; -} - -Sequence *MeshAttachment::getSequence() { - return _sequence; -} - -void MeshAttachment::setSequence(Sequence *sequence) { - _sequence = sequence; +Color &MeshAttachment::getColor() { + return _color; } MeshAttachment *MeshAttachment::getParentMesh() { @@ -178,10 +104,10 @@ void MeshAttachment::setParentMesh(MeshAttachment *inValue) { if (inValue != NULL) { _bones.clearAndAddAll(inValue->_bones); _vertices.clearAndAddAll(inValue->_vertices); - _worldVerticesLength = inValue->_worldVerticesLength; _regionUVs.clearAndAddAll(inValue->_regionUVs); _triangles.clearAndAddAll(inValue->_triangles); _hullLength = inValue->_hullLength; + _worldVerticesLength = inValue->_worldVerticesLength; _edges.clearAndAddAll(inValue->_edges); _width = inValue->_width; _height = inValue->_height; @@ -212,26 +138,16 @@ void MeshAttachment::setHeight(float inValue) { _height = inValue; } -Color &MeshAttachment::getColor() { - return _color; -} - Attachment &MeshAttachment::copy() { if (_parentMesh) return newLinkedMesh(); - MeshAttachment *copy = new (__FILE__, __LINE__) MeshAttachment(getName()); - copy->setRegion(_region); - copy->setSequence(_sequence != NULL ? &_sequence->copy() : NULL); + MeshAttachment *copy = new (__FILE__, __LINE__) MeshAttachment(getName(), new (__FILE__, __LINE__) Sequence(*_sequence)); copy->_path = _path; copy->_color.set(_color); - copyTo(*copy); copy->_regionUVs.clearAndAddAll(_regionUVs); - copy->_uvs.clearAndAddAll(_uvs); copy->_triangles.clearAndAddAll(_triangles); copy->_hullLength = _hullLength; - - // Nonessential. copy->_edges.clearAndAddAll(_edges); copy->_width = _width; copy->_height = _height; @@ -239,18 +155,76 @@ Attachment &MeshAttachment::copy() { } MeshAttachment &MeshAttachment::newLinkedMesh() { - MeshAttachment *copy = new (__FILE__, __LINE__) MeshAttachment(getName()); - copy->setRegion(_region); + MeshAttachment *copy = new (__FILE__, __LINE__) MeshAttachment(getName(), new (__FILE__, __LINE__) Sequence(*_sequence)); + copy->_timelineAttachment = _timelineAttachment; copy->_path = _path; copy->_color.set(_color); - copy->_timelineAttachment = this->_timelineAttachment; - copy->setParentMesh(_parentMesh ? _parentMesh : this); - if (copy->_region) copy->updateRegion(); + copy->setParentMesh(_parentMesh != NULL ? _parentMesh : this); + copy->updateSequence(); return *copy; } -void MeshAttachment::computeWorldVertices(Skeleton &skeleton, Slot &slot, size_t start, size_t count, float *worldVertices, size_t offset, - size_t stride) { - if (_sequence) _sequence->apply(&slot.getAppliedPose(), this); - VertexAttachment::computeWorldVertices(skeleton, slot, start, count, worldVertices, offset, stride); +void MeshAttachment::computeUVs(TextureRegion *region, Array ®ionUVs, Array &uvs) { + int n = (int) uvs.size(); + float u, v, width, height; + if (region != NULL && region->getRTTI().instanceOf(AtlasRegion::rtti)) { + AtlasRegion *r = static_cast(region); + u = r->_u; + v = r->_v; + float textureWidth = r->getPage()->width; + float textureHeight = r->getPage()->height; + switch (r->_degrees) { + case 90: { + u -= (r->_originalHeight - r->_offsetY - r->_packedWidth) / textureWidth; + v -= (r->_originalWidth - r->_offsetX - r->_packedHeight) / textureHeight; + width = r->_originalHeight / textureWidth; + height = r->_originalWidth / textureHeight; + for (int i = 0; i < n; i += 2) { + uvs[i] = u + regionUVs[i + 1] * width; + uvs[i + 1] = v + (1 - regionUVs[i]) * height; + } + return; + } + case 180: { + u -= (r->_originalWidth - r->_offsetX - r->_packedWidth) / textureWidth; + v -= r->_offsetY / textureHeight; + width = r->_originalWidth / textureWidth; + height = r->_originalHeight / textureHeight; + for (int i = 0; i < n; i += 2) { + uvs[i] = u + (1 - regionUVs[i]) * width; + uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height; + } + return; + } + case 270: { + u -= r->_offsetY / textureWidth; + v -= r->_offsetX / textureHeight; + width = r->_originalHeight / textureWidth; + height = r->_originalWidth / textureHeight; + for (int i = 0; i < n; i += 2) { + uvs[i] = u + (1 - regionUVs[i + 1]) * width; + uvs[i + 1] = v + regionUVs[i] * height; + } + return; + } + default: { + u -= r->_offsetX / textureWidth; + v -= (r->_originalHeight - r->_offsetY - r->_packedHeight) / textureHeight; + width = r->_originalWidth / textureWidth; + height = r->_originalHeight / textureHeight; + } + } + } else if (region == NULL) { + u = v = 0; + width = height = 1; + } else { + u = region->_u; + v = region->_v; + width = region->_u2 - u; + height = region->_v2 - v; + } + for (int i = 0; i < n; i += 2) { + uvs[i] = u + regionUVs[i] * width; + uvs[i + 1] = v + regionUVs[i + 1] * height; + } } diff --git a/spine-cpp/src/spine/RegionAttachment.cpp b/spine-cpp/src/spine/RegionAttachment.cpp index 706569755..5a811e720 100644 --- a/spine-cpp/src/spine/RegionAttachment.cpp +++ b/spine-cpp/src/spine/RegionAttachment.cpp @@ -31,7 +31,9 @@ #include #include +#include #include +#include #include @@ -48,132 +50,53 @@ const int RegionAttachment::URY = 5; const int RegionAttachment::BRX = 6; const int RegionAttachment::BRY = 7; -RegionAttachment::RegionAttachment(const String &name) - : Attachment(name), _region(NULL), _path(), _x(0), _y(0), _scaleX(1), _scaleY(1), _rotation(0), _width(0), _height(0), _color(1, 1, 1, 1), - _sequence(NULL) { - _offset.setSize(8, 0); - _uvs.setSize(8, 0); +RegionAttachment::RegionAttachment(const String &name, Sequence *sequence) + : Attachment(name), _sequence(sequence), _x(0), _y(0), _scaleX(1), _scaleY(1), _rotation(0), _width(0), _height(0), _path(), _color(1, 1, 1, 1) { + assert(sequence); } RegionAttachment::~RegionAttachment() { - if (_sequence) delete _sequence; + delete _sequence; } -void RegionAttachment::updateRegion() { - float width = getWidth(), height = getHeight(); - float localX2 = width / 2; - float localY2 = height / 2; - float localX = -localX2; - float localY = -localY2; - bool rotated = false; - AtlasRegion *atlasRegion = NULL; - if (_region != NULL) { - atlasRegion = _region->getRTTI().isExactly(AtlasRegion::rtti) ? static_cast(_region) : NULL; - } - if (atlasRegion) { - localX += atlasRegion->_offsetX / atlasRegion->_originalWidth * width; - localY += atlasRegion->_offsetY / atlasRegion->_originalHeight * height; - if (atlasRegion->_degrees == 90) { - rotated = true; - localX2 -= (atlasRegion->_originalWidth - atlasRegion->_offsetX - atlasRegion->_packedHeight) / atlasRegion->_originalWidth * width; - localY2 -= (atlasRegion->_originalHeight - atlasRegion->_offsetY - atlasRegion->_packedWidth) / atlasRegion->_originalHeight * height; - } else { - localX2 -= (atlasRegion->_originalWidth - atlasRegion->_offsetX - atlasRegion->_packedWidth) / atlasRegion->_originalWidth * width; - localY2 -= (atlasRegion->_originalHeight - atlasRegion->_offsetY - atlasRegion->_packedHeight) / atlasRegion->_originalHeight * height; - } - } - float scaleX = getScaleX(), scaleY = getScaleY(); - localX *= scaleX; - localY *= scaleY; - localX2 *= scaleX; - localY2 *= scaleY; - float cos = MathUtil::cosDeg(_rotation); - float sin = MathUtil::sinDeg(_rotation); - float localXCos = localX * cos + _x; - float localXSin = localX * sin; - float localYCos = localY * cos + _y; - float localYSin = localY * sin; - float localX2Cos = localX2 * cos + _x; - float localX2Sin = localX2 * sin; - float localY2Cos = localY2 * cos + _y; - float localY2Sin = localY2 * sin; - - _offset[BLX] = localXCos - localYSin; - _offset[BLY] = localYCos + localXSin; - _offset[ULX] = localXCos - localY2Sin; - _offset[ULY] = localY2Cos + localXSin; - _offset[URX] = localX2Cos - localY2Sin; - _offset[URY] = localY2Cos + localX2Sin; - _offset[BRX] = localX2Cos - localYSin; - _offset[BRY] = localYCos + localX2Sin; - - if (_region == NULL) { - _uvs[BLX] = 0; - _uvs[BLY] = 0; - _uvs[ULX] = 0; - _uvs[ULY] = 1; - _uvs[URX] = 1; - _uvs[URY] = 1; - _uvs[BRX] = 1; - _uvs[BRY] = 0; - } else if (rotated) { - _uvs[BLX] = _region->_u2; - _uvs[BLY] = _region->_v; - _uvs[ULX] = _region->_u2; - _uvs[ULY] = _region->_v2; - _uvs[URX] = _region->_u; - _uvs[URY] = _region->_v2; - _uvs[BRX] = _region->_u; - _uvs[BRY] = _region->_v; - } else { - _uvs[BLX] = _region->_u2; - _uvs[BLY] = _region->_v2; - _uvs[ULX] = _region->_u; - _uvs[ULY] = _region->_v2; - _uvs[URX] = _region->_u; - _uvs[URY] = _region->_v; - _uvs[BRX] = _region->_u2; - _uvs[BRY] = _region->_v; - } -} - -void RegionAttachment::computeWorldVertices(Slot &slot, Array &worldVertices, size_t offset, size_t stride) { +void RegionAttachment::computeWorldVertices(Slot &slot, Array &vertexOffsets, Array &worldVertices, size_t offset, size_t stride) { assert(worldVertices.size() >= (offset + 8)); - computeWorldVertices(slot, worldVertices.buffer(), offset, stride); + computeWorldVertices(slot, vertexOffsets.buffer(), worldVertices.buffer(), offset, stride); } -void RegionAttachment::computeWorldVertices(Slot &slot, float *worldVertices, size_t offset, size_t stride) { - if (_sequence) _sequence->apply(&slot.getAppliedPose(), this); - +void RegionAttachment::computeWorldVertices(Slot &slot, float *vertexOffsets, float *worldVertices, size_t offset, size_t stride) { BonePose &bone = slot.getBone().getAppliedPose(); float x = bone.getWorldX(), y = bone.getWorldY(); float a = bone.getA(), b = bone.getB(), c = bone.getC(), d = bone.getD(); - float offsetX, offsetY; - offsetX = _offset[BRX]; - offsetY = _offset[BRY]; - worldVertices[offset] = offsetX * a + offsetY * b + x;// br + float offsetX = vertexOffsets[BRX]; + float offsetY = vertexOffsets[BRY]; + worldVertices[offset] = offsetX * a + offsetY * b + x; worldVertices[offset + 1] = offsetX * c + offsetY * d + y; offset += stride; - offsetX = _offset[BLX]; - offsetY = _offset[BLY]; - worldVertices[offset] = offsetX * a + offsetY * b + x;// bl + offsetX = vertexOffsets[BLX]; + offsetY = vertexOffsets[BLY]; + worldVertices[offset] = offsetX * a + offsetY * b + x; worldVertices[offset + 1] = offsetX * c + offsetY * d + y; offset += stride; - offsetX = _offset[ULX]; - offsetY = _offset[ULY]; - worldVertices[offset] = offsetX * a + offsetY * b + x;// ul + offsetX = vertexOffsets[ULX]; + offsetY = vertexOffsets[ULY]; + worldVertices[offset] = offsetX * a + offsetY * b + x; worldVertices[offset + 1] = offsetX * c + offsetY * d + y; offset += stride; - offsetX = _offset[URX]; - offsetY = _offset[URY]; - worldVertices[offset] = offsetX * a + offsetY * b + x;// ur + offsetX = vertexOffsets[URX]; + offsetY = vertexOffsets[URY]; + worldVertices[offset] = offsetX * a + offsetY * b + x; worldVertices[offset + 1] = offsetX * c + offsetY * d + y; } +Array &RegionAttachment::getOffsets(SlotPose &pose) { + return _sequence->getOffsets(_sequence->resolveIndex(pose)); +} + float RegionAttachment::getX() { return _x; } @@ -190,14 +113,6 @@ void RegionAttachment::setY(float inValue) { _y = inValue; } -float RegionAttachment::getRotation() { - return _rotation; -} - -void RegionAttachment::setRotation(float inValue) { - _rotation = inValue; -} - float RegionAttachment::getScaleX() { return _scaleX; } @@ -214,6 +129,14 @@ void RegionAttachment::setScaleY(float inValue) { _scaleY = inValue; } +float RegionAttachment::getRotation() { + return _rotation; +} + +void RegionAttachment::setRotation(float inValue) { + _rotation = inValue; +} + float RegionAttachment::getWidth() { return _width; } @@ -230,6 +153,14 @@ void RegionAttachment::setHeight(float inValue) { _height = inValue; } +Sequence &RegionAttachment::getSequence() { + return *_sequence; +} + +void RegionAttachment::updateSequence() { + _sequence->update(*this); +} + const String &RegionAttachment::getPath() { return _path; } @@ -238,37 +169,12 @@ void RegionAttachment::setPath(const String &inValue) { _path = inValue; } -TextureRegion *RegionAttachment::getRegion() { - return _region; -} - -void RegionAttachment::setRegion(TextureRegion *region) { - _region = region; -} - -Sequence *RegionAttachment::getSequence() { - return _sequence; -} - -void RegionAttachment::setSequence(Sequence *sequence) { - _sequence = sequence; -} - -Array &RegionAttachment::getOffset() { - return _offset; -} - -Array &RegionAttachment::getUVs() { - return _uvs; -} - Color &RegionAttachment::getColor() { return _color; } Attachment &RegionAttachment::copy() { - RegionAttachment *copy = new (__FILE__, __LINE__) RegionAttachment(getName()); - copy->_region = _region; + RegionAttachment *copy = new (__FILE__, __LINE__) RegionAttachment(getName(), new (__FILE__, __LINE__) Sequence(*_sequence)); copy->_path = _path; copy->_x = _x; copy->_y = _y; @@ -277,9 +183,74 @@ Attachment &RegionAttachment::copy() { copy->_rotation = _rotation; copy->_width = _width; copy->_height = _height; - copy->_uvs.clearAndAddAll(_uvs); - copy->_offset.clearAndAddAll(_offset); copy->_color.set(_color); - copy->_sequence = _sequence != NULL ? &_sequence->copy() : NULL; return *copy; } + +void RegionAttachment::computeUVs(TextureRegion *region, float x, float y, float scaleX, float scaleY, float rotation, float width, float height, + Array &offset, Array &uvs) { + float localX2 = width / 2, localY2 = height / 2; + float localX = -localX2, localY = -localY2; + bool rotated = false; + if (region != NULL && region->getRTTI().instanceOf(AtlasRegion::rtti)) { + AtlasRegion *r = static_cast(region); + localX += r->_offsetX / r->_originalWidth * width; + localY += r->_offsetY / r->_originalHeight * height; + if (r->_degrees == 90) { + rotated = true; + localX2 -= (r->_originalWidth - r->_offsetX - r->_packedHeight) / r->_originalWidth * width; + localY2 -= (r->_originalHeight - r->_offsetY - r->_packedWidth) / r->_originalHeight * height; + } else { + localX2 -= (r->_originalWidth - r->_offsetX - r->_packedWidth) / r->_originalWidth * width; + localY2 -= (r->_originalHeight - r->_offsetY - r->_packedHeight) / r->_originalHeight * height; + } + } + localX *= scaleX; + localY *= scaleY; + localX2 *= scaleX; + localY2 *= scaleY; + float cos = MathUtil::cosDeg(rotation); + float sin = MathUtil::sinDeg(rotation); + float localXCos = localX * cos + x; + float localXSin = localX * sin; + float localYCos = localY * cos + y; + float localYSin = localY * sin; + float localX2Cos = localX2 * cos + x; + float localX2Sin = localX2 * sin; + float localY2Cos = localY2 * cos + y; + float localY2Sin = localY2 * sin; + offset[BLX] = localXCos - localYSin; + offset[BLY] = localYCos + localXSin; + offset[ULX] = localXCos - localY2Sin; + offset[ULY] = localY2Cos + localXSin; + offset[URX] = localX2Cos - localY2Sin; + offset[URY] = localY2Cos + localX2Sin; + offset[BRX] = localX2Cos - localYSin; + offset[BRY] = localYCos + localX2Sin; + if (region == NULL) { + uvs[BLX] = 0; + uvs[BLY] = 0; + uvs[ULX] = 0; + uvs[ULY] = 1; + uvs[URX] = 1; + uvs[URY] = 1; + uvs[BRX] = 1; + uvs[BRY] = 0; + } else { + uvs[BLX] = region->_u2; + uvs[ULY] = region->_v2; + uvs[URX] = region->_u; + uvs[BRY] = region->_v; + if (rotated) { + uvs[BLY] = region->_v; + uvs[ULX] = region->_u2; + uvs[URY] = region->_v2; + uvs[BRX] = region->_u; + } else { + uvs[BLY] = region->_v2; + uvs[ULX] = region->_u; + uvs[URY] = region->_v; + uvs[BRX] = region->_u2; + } + } +} diff --git a/spine-cpp/src/spine/Sequence.cpp b/spine-cpp/src/spine/Sequence.cpp index 741714f81..f42825870 100644 --- a/spine-cpp/src/spine/Sequence.cpp +++ b/spine-cpp/src/spine/Sequence.cpp @@ -28,58 +28,75 @@ *****************************************************************************/ #include -#include -#include -#include -#include #include +#include +#include using namespace spine; int Sequence::_nextID = 0; -Sequence::Sequence(int count) : _id(nextID()), _regions(), _start(0), _digits(0), _setupIndex(0) { +Sequence::Sequence(int count, bool pathSuffix) + : _id(nextID()), _regions(count), _pathSuffix(pathSuffix), _uvs(), _offsets(), _start(0), _digits(0), _setupIndex(0) { _regions.setSize(count, NULL); } +Sequence::Sequence(const Sequence &other) + : _id(nextID()), _regions(other._regions), _pathSuffix(other._pathSuffix), _uvs(other._uvs), _offsets(other._offsets), _start(other._start), + _digits(other._digits), _setupIndex(other._setupIndex) { +} + Sequence::~Sequence() { } -Sequence &Sequence::copy() { - Sequence *copy = new (__FILE__, __LINE__) Sequence((int) _regions.size()); - for (size_t i = 0; i < _regions.size(); i++) { - copy->_regions[i] = _regions[i]; +void Sequence::update(RegionAttachment &attachment) { + int regionCount = (int) _regions.size(); + Array empty; + _uvs.setSize(regionCount, empty); + _offsets.setSize(regionCount, empty); + for (int i = 0; i < regionCount; i++) { + _uvs[i].setSize(8, 0); + _offsets[i].setSize(8, 0); + RegionAttachment::computeUVs(_regions[i], attachment.getX(), attachment.getY(), attachment.getScaleX(), attachment.getScaleY(), + attachment.getRotation(), attachment.getWidth(), attachment.getHeight(), _offsets[i], _uvs[i]); } - copy->_start = _start; - copy->_digits = _digits; - copy->_setupIndex = _setupIndex; - return *copy; } -void Sequence::apply(SlotPose *slot, Attachment *attachment) { - int index = slot->getSequenceIndex(); +void Sequence::update(MeshAttachment &attachment) { + int regionCount = (int) _regions.size(); + Array empty; + _uvs.setSize(regionCount, empty); + _offsets.clear(); + for (int i = 0; i < regionCount; i++) { + _uvs[i].setSize(attachment.getRegionUVs().size(), 0); + MeshAttachment::computeUVs(_regions[i], attachment.getRegionUVs(), _uvs[i]); + } +} + +int Sequence::resolveIndex(SlotPose &pose) { + int index = pose.getSequenceIndex(); if (index == -1) index = _setupIndex; if (index >= (int) _regions.size()) index = (int) _regions.size() - 1; - TextureRegion *region = _regions[index]; + return index; +} - if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) { - RegionAttachment *regionAttachment = static_cast(attachment); - if (regionAttachment->getRegion() != region) { - regionAttachment->setRegion(region); - regionAttachment->updateRegion(); - } - } +TextureRegion *Sequence::getRegion(int index) { + return _regions[index]; +} - if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) { - MeshAttachment *meshAttachment = static_cast(attachment); - if (meshAttachment->getRegion() != region) { - meshAttachment->setRegion(region); - meshAttachment->updateRegion(); - } - } +Array &Sequence::getUVs(int index) { + return _uvs[index]; +} + +Array &Sequence::getOffsets(int index) { + return _offsets[index]; } String &Sequence::getPath(const String &basePath, int index) { + if (!_pathSuffix) { + _tmpPath = basePath; + return _tmpPath; + } _tmpPath = basePath; String frame; frame.append(_start + index); diff --git a/spine-cpp/src/spine/SequenceTimeline.cpp b/spine-cpp/src/spine/SequenceTimeline.cpp index da04ce66b..26e065fe9 100644 --- a/spine-cpp/src/spine/SequenceTimeline.cpp +++ b/spine-cpp/src/spine/SequenceTimeline.cpp @@ -46,8 +46,8 @@ RTTI_IMPL_MULTI(SequenceTimeline, Timeline, SlotTimeline) SequenceTimeline::SequenceTimeline(size_t frameCount, int slotIndex, Attachment &attachment) : Timeline(frameCount, ENTRIES), SlotTimeline(), _slotIndex(slotIndex), _attachment((HasTextureRegion *) &attachment) { int sequenceId = 0; - if (attachment.getRTTI().instanceOf(RegionAttachment::rtti)) sequenceId = ((RegionAttachment *) &attachment)->getSequence()->getId(); - if (attachment.getRTTI().instanceOf(MeshAttachment::rtti)) sequenceId = ((MeshAttachment *) &attachment)->getSequence()->getId(); + if (attachment.getRTTI().instanceOf(RegionAttachment::rtti)) sequenceId = ((RegionAttachment *) &attachment)->getSequence().getId(); + if (attachment.getRTTI().instanceOf(MeshAttachment::rtti)) sequenceId = ((MeshAttachment *) &attachment)->getSequence().getId(); PropertyId ids[] = {((PropertyId) Property_Sequence << 32) | ((slotIndex << 16 | sequenceId) & 0xffffffff)}; setPropertyIds(ids, 1); } @@ -88,8 +88,8 @@ void SequenceTimeline::apply(Skeleton &skeleton, float lastTime, float time, Arr return; } Sequence *sequence = NULL; - if (((Attachment *) _attachment)->getRTTI().instanceOf(RegionAttachment::rtti)) sequence = ((RegionAttachment *) _attachment)->getSequence(); - if (((Attachment *) _attachment)->getRTTI().instanceOf(MeshAttachment::rtti)) sequence = ((MeshAttachment *) _attachment)->getSequence(); + if (((Attachment *) _attachment)->getRTTI().instanceOf(RegionAttachment::rtti)) sequence = &((RegionAttachment *) _attachment)->getSequence(); + if (((Attachment *) _attachment)->getRTTI().instanceOf(MeshAttachment::rtti)) sequence = &((MeshAttachment *) _attachment)->getSequence(); if (!sequence) return; if (direction == MixDirection_Out) { diff --git a/spine-cpp/src/spine/Skeleton.cpp b/spine-cpp/src/spine/Skeleton.cpp index fcf73ad73..2281e3ca4 100644 --- a/spine-cpp/src/spine/Skeleton.cpp +++ b/spine-cpp/src/spine/Skeleton.cpp @@ -393,7 +393,7 @@ void Skeleton::getBounds(float &outX, float &outY, float &outWidth, float &outHe RegionAttachment *regionAttachment = static_cast(attachment); verticesLength = 8; outVertexBuffer.setSize(8, 0); - regionAttachment->computeWorldVertices(*slot, outVertexBuffer.buffer(), 0, 2); + regionAttachment->computeWorldVertices(*slot, regionAttachment->getOffsets(slot->getAppliedPose()), outVertexBuffer, 0, 2); vertices = outVertexBuffer.buffer(); triangles = quadIndices; trianglesLength = 6; diff --git a/spine-cpp/src/spine/SkeletonBinary.cpp b/spine-cpp/src/spine/SkeletonBinary.cpp index 96e46541c..954863dbe 100644 --- a/spine-cpp/src/spine/SkeletonBinary.cpp +++ b/spine-cpp/src/spine/SkeletonBinary.cpp @@ -476,7 +476,7 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons } linkedMesh->_mesh->_timelineAttachment = linkedMesh->_inheritTimelines ? static_cast(parent) : linkedMesh->_mesh; linkedMesh->_mesh->setParentMesh(static_cast(parent)); - if (linkedMesh->_mesh->getSequence() == NULL) linkedMesh->_mesh->updateRegion(); + linkedMesh->_mesh->updateSequence(); } ArrayUtils::deleteElements(_linkedMeshes); _linkedMeshes.clear(); @@ -582,7 +582,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput &input, Skin &skin, int slo case AttachmentType_Region: { String path = (flags & 16) != 0 ? input.readStringRef() : name; int color = (flags & 32) != 0 ? input.readInt() : 0xffffffff; - Sequence *sequence = (flags & 64) != 0 ? readSequence(input) : nullptr; + Sequence *sequence = readSequence(input, (flags & 64) != 0); float rotation = (flags & 128) != 0 ? input.readFloat() : 0; float x = input.readFloat(); float y = input.readFloat(); @@ -602,8 +602,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput &input, Skin &skin, int slo region->setWidth(width * scale); region->setHeight(height * scale); Color::rgba8888ToColor(region->getColor(), color); - region->setSequence(sequence); - if (sequence == NULL) region->updateRegion(); + region->updateSequence(); return region; } case AttachmentType_Boundingbox: { @@ -623,7 +622,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput &input, Skin &skin, int slo case AttachmentType_Mesh: { String path = (flags & 16) != 0 ? input.readStringRef() : name; int color = (flags & 32) != 0 ? input.readInt() : 0xffffffff; - Sequence *sequence = (flags & 64) != 0 ? readSequence(input) : nullptr; + Sequence *sequence = readSequence(input, (flags & 64) != 0); int hullLength = input.readInt(true); Array vertices; Array bones; @@ -645,25 +644,24 @@ Attachment *SkeletonBinary::readAttachment(DataInput &input, Skin &skin, int slo if (!mesh) return NULL; mesh->setPath(path); Color::rgba8888ToColor(mesh->getColor(), color); + mesh->setHullLength(hullLength << 1); mesh->setBones(bones); mesh->setVertices(vertices); mesh->setWorldVerticesLength(verticesLength); - mesh->setTriangles(triangles); mesh->setRegionUVs(uvs); - if (sequence == NULL) mesh->updateRegion(); - mesh->setHullLength(hullLength << 1); - mesh->setSequence(sequence); + mesh->setTriangles(triangles); if (nonessential) { mesh->setEdges(edges); mesh->setWidth(width * scale); mesh->setHeight(height * scale); } + mesh->updateSequence(); return mesh; } case AttachmentType_Linkedmesh: { String path = (flags & 16) != 0 ? input.readStringRef() : name; int color = (flags & 32) != 0 ? input.readInt() : 0xffffffff; - Sequence *sequence = (flags & 64) != 0 ? readSequence(input) : nullptr; + Sequence *sequence = readSequence(input, (flags & 64) != 0); bool inheritTimelines = (flags & 128) != 0; int skinIndex = input.readInt(true); String parent = input.readStringRef(); @@ -677,7 +675,6 @@ Attachment *SkeletonBinary::readAttachment(DataInput &input, Skin &skin, int slo if (!mesh) return NULL; mesh->setPath(path); Color::rgba8888ToColor(mesh->getColor(), color); - mesh->setSequence(sequence); if (nonessential) { mesh->setWidth(width * scale); mesh->setHeight(height * scale); @@ -741,8 +738,9 @@ Attachment *SkeletonBinary::readAttachment(DataInput &input, Skin &skin, int slo return NULL; } -Sequence *SkeletonBinary::readSequence(DataInput &input) { - Sequence *sequence = new (__FILE__, __LINE__) Sequence(input.readInt(true)); +Sequence *SkeletonBinary::readSequence(DataInput &input, bool hasPathSuffix) { + if (!hasPathSuffix) return new (__FILE__, __LINE__) Sequence(1, false); + Sequence *sequence = new (__FILE__, __LINE__) Sequence(input.readInt(true), true); sequence->setStart(input.readInt(true)); sequence->setDigits(input.readInt(true)); sequence->setSetupIndex(input.readInt(true)); diff --git a/spine-cpp/src/spine/SkeletonJson.cpp b/spine-cpp/src/spine/SkeletonJson.cpp index c66d93516..d93d08058 100644 --- a/spine-cpp/src/spine/SkeletonJson.cpp +++ b/spine-cpp/src/spine/SkeletonJson.cpp @@ -561,7 +561,7 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) { if (parent == NULL) SKELETON_JSON_ERROR(root, "Parent mesh not found: ", linkedMesh->_parent.buffer()); linkedMesh->_mesh->_timelineAttachment = linkedMesh->_inheritTimelines ? static_cast(parent) : linkedMesh->_mesh; linkedMesh->_mesh->setParentMesh(static_cast(parent)); - if (linkedMesh->_mesh->_region != NULL) linkedMesh->_mesh->updateRegion(); + linkedMesh->_mesh->updateSequence(); } ArrayUtils::deleteElements(_linkedMeshes); _linkedMeshes.clear(); @@ -639,12 +639,11 @@ Attachment *SkeletonJson::readAttachment(Json *map, Skin *skin, int slotIndex, c region->setRotation(Json::getFloat(map, "rotation", 0)); region->setWidth(Json::getFloat(map, "width", 0) * scale); region->setHeight(Json::getFloat(map, "height", 0) * scale); - region->setSequence(sequence); const char *color = Json::getString(map, "color", NULL); if (color) Color::valueOf(color, region->getColor()); - if (region->_region != NULL) region->updateRegion(); + region->updateSequence(); return region; } case AttachmentType_Boundingbox: { @@ -669,7 +668,6 @@ Attachment *SkeletonJson::readAttachment(Json *map, Skin *skin, int slotIndex, c mesh->setWidth(Json::getFloat(map, "width", 0) * scale); mesh->setHeight(Json::getFloat(map, "height", 0) * scale); - mesh->setSequence(sequence); const char *parent = Json::getString(map, "parent", NULL); if (parent) { @@ -686,12 +684,13 @@ Attachment *SkeletonJson::readAttachment(Json *map, Skin *skin, int slotIndex, c if (!Json::asUnsignedShortArray(Json::getItem(map, "triangles"), triangles)) return NULL; mesh->_triangles.clearAndAddAll(triangles); mesh->_regionUVs.clearAndAddAll(uvs); - if (mesh->_region != NULL) mesh->updateRegion(); if (Json::getInt(map, "hull", 0)) mesh->setHullLength(Json::getInt(map, "hull", 0) << 1); Array edges; Json::asUnsignedShortArray(Json::getItem(map, "edges"), edges); if (edges.size() > 0) mesh->_edges.clearAndAddAll(edges); + + mesh->updateSequence(); return mesh; } case AttachmentType_Path: { @@ -744,8 +743,8 @@ Attachment *SkeletonJson::readAttachment(Json *map, Skin *skin, int slotIndex, c } Sequence *SkeletonJson::readSequence(Json *item) { - if (item == NULL) return NULL; - Sequence *sequence = new Sequence(Json::getInt(item, "count", 0)); + if (item == NULL) return new (__FILE__, __LINE__) Sequence(1, false); + Sequence *sequence = new (__FILE__, __LINE__) Sequence(Json::getInt(item, "count", 0), true); sequence->_start = Json::getInt(item, "start", 1); sequence->_digits = Json::getInt(item, "digits", 0); sequence->_setupIndex = Json::getInt(item, "setup", 0); diff --git a/spine-cpp/src/spine/SkeletonRenderer.cpp b/spine-cpp/src/spine/SkeletonRenderer.cpp index 2d20412ba..603cb08ad 100644 --- a/spine-cpp/src/spine/SkeletonRenderer.cpp +++ b/spine-cpp/src/spine/SkeletonRenderer.cpp @@ -167,37 +167,41 @@ RenderCommand *SkeletonRenderer::render(Skeleton &skeleton) { RegionAttachment *regionAttachment = (RegionAttachment *) attachment; attachmentColor = ®ionAttachment->getColor(); - // Early out if the slot color is 0 if (attachmentColor->a == 0) { clipper.clipEnd(slot); continue; } + Sequence &sequence = regionAttachment->getSequence(); + int sequenceIndex = sequence.resolveIndex(slot.getAppliedPose()); + TextureRegion *region = sequence.getRegion(sequenceIndex); worldVertices->setSize(8, 0); - regionAttachment->computeWorldVertices(slot, *worldVertices, 0, 2); + regionAttachment->computeWorldVertices(slot, regionAttachment->getOffsets(slot.getAppliedPose()), *worldVertices, 0, 2); verticesCount = 4; - uvs = ®ionAttachment->getUVs(); + uvs = &sequence.getUVs(sequenceIndex); indices = quadIndices; indicesCount = 6; - texture = regionAttachment->getRegion()->_rendererObject; + texture = region->_rendererObject; } else if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) { MeshAttachment *mesh = (MeshAttachment *) attachment; attachmentColor = &mesh->getColor(); - // Early out if the slot color is 0 if (attachmentColor->a == 0) { clipper.clipEnd(slot); continue; } + Sequence &sequence = mesh->getSequence(); + int sequenceIndex = sequence.resolveIndex(slot.getAppliedPose()); + TextureRegion *region = sequence.getRegion(sequenceIndex); worldVertices->setSize(mesh->getWorldVerticesLength(), 0); mesh->computeWorldVertices(skeleton, slot, 0, mesh->getWorldVerticesLength(), worldVertices->buffer(), 0, 2); verticesCount = (int32_t) (mesh->getWorldVerticesLength() >> 1); - uvs = &mesh->getUVs(); + uvs = &sequence.getUVs(sequenceIndex); indices = &mesh->getTriangles(); indicesCount = (int32_t) indices->size(); - texture = mesh->getRegion()->_rendererObject; + texture = region->_rendererObject; } else if (attachment->getRTTI().isExactly(ClippingAttachment::rtti)) { ClippingAttachment *clip = (ClippingAttachment *) slot.getAppliedPose().getAttachment(); diff --git a/spine-cpp/tests/SkeletonSerializer.h b/spine-cpp/tests/SkeletonSerializer.h index 9d021c029..3a7d0b69b 100644 --- a/spine-cpp/tests/SkeletonSerializer.h +++ b/spine-cpp/tests/SkeletonSerializer.h @@ -2552,11 +2552,13 @@ namespace spine { _json.writeName("type"); _json.writeValue("MeshAttachment"); + Sequence &sequence = obj->getSequence(); + int setupIndex = sequence.getSetupIndex(); _json.writeName("region"); - if (obj->getRegion() == nullptr) { + if (sequence.getRegion(setupIndex) == nullptr) { _json.writeNull(); } else { - writeTextureRegion(obj->getRegion()); + writeTextureRegion(sequence.getRegion(setupIndex)); } _json.writeName("triangles"); @@ -2575,8 +2577,8 @@ namespace spine { _json.writeName("uVs"); _json.writeArrayStart(); - for (size_t i = 0; i < obj->getUVs().size(); i++) { - _json.writeValue(obj->getUVs()[i]); + for (size_t i = 0; i < sequence.getUVs(setupIndex).size(); i++) { + _json.writeValue(sequence.getUVs(setupIndex)[i]); } _json.writeArrayEnd(); @@ -2603,10 +2605,10 @@ namespace spine { _json.writeValue(obj->getHeight()); _json.writeName("sequence"); - if (obj->getSequence() == nullptr) { + if (!obj->getSequence().getPathSuffix()) { _json.writeNull(); } else { - writeSequence(obj->getSequence()); + writeSequence(&obj->getSequence()); } _json.writeName("parentMesh"); @@ -3075,24 +3077,26 @@ namespace spine { _json.writeName("type"); _json.writeValue("RegionAttachment"); + Sequence &sequence = obj->getSequence(); + int setupIndex = sequence.getSetupIndex(); _json.writeName("region"); - if (obj->getRegion() == nullptr) { + if (sequence.getRegion(setupIndex) == nullptr) { _json.writeNull(); } else { - writeTextureRegion(obj->getRegion()); + writeTextureRegion(sequence.getRegion(setupIndex)); } _json.writeName("offset"); _json.writeArrayStart(); - for (size_t i = 0; i < obj->getOffset().size(); i++) { - _json.writeValue(obj->getOffset()[i]); + for (size_t i = 0; i < sequence.getOffsets(setupIndex).size(); i++) { + _json.writeValue(sequence.getOffsets(setupIndex)[i]); } _json.writeArrayEnd(); _json.writeName("uVs"); _json.writeArrayStart(); - for (size_t i = 0; i < obj->getUVs().size(); i++) { - _json.writeValue(obj->getUVs()[i]); + for (size_t i = 0; i < sequence.getUVs(setupIndex).size(); i++) { + _json.writeValue(sequence.getUVs(setupIndex)[i]); } _json.writeArrayEnd(); @@ -3124,10 +3128,10 @@ namespace spine { _json.writeValue(obj->getPath()); _json.writeName("sequence"); - if (obj->getSequence() == nullptr) { + if (!obj->getSequence().getPathSuffix()) { _json.writeNull(); } else { - writeSequence(obj->getSequence()); + writeSequence(&obj->getSequence()); } _json.writeName("name");