Skip to content

Commit

Permalink
[ios] Closes #2666, expose SkeletonBounds via spine-cpp-lite/Swift
Browse files Browse the repository at this point in the history
  • Loading branch information
badlogic committed Nov 5, 2024
1 parent 9207cd2 commit 19d3d1b
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 3 deletions.
109 changes: 109 additions & 0 deletions spine-cpp/spine-cpp-lite/spine-cpp-lite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4681,3 +4681,112 @@ void spine_texture_region_set_original_height(spine_texture_region textureRegion
TextureRegion *_region = (TextureRegion *) textureRegion;
_region->originalHeight = originalHeight;
}

spine_skeleton_bounds spine_skeleton_bounds_create() {
return (spine_skeleton_bounds) new (__FILE__, __LINE__) SkeletonBounds();
}

void spine_skeleton_bounds_dispose(spine_skeleton_bounds bounds) {
if (bounds == nullptr) return;
SkeletonBounds *_bounds = (SkeletonBounds *) bounds;
delete _bounds;
}

void spine_skeleton_bounds_update(spine_skeleton_bounds bounds, spine_skeleton skeleton, spine_bool updateAabb) {
if (bounds == nullptr) return;
if (skeleton == nullptr) return;

SkeletonBounds *_bounds = (SkeletonBounds *) bounds;
Skeleton *_skeleton = (Skeleton *) skeleton;
_bounds->update(*_skeleton, updateAabb != 0);
}

spine_bool spine_skeleton_bounds_aabb_contains_point(spine_skeleton_bounds bounds, float x, float y) {
if (bounds == nullptr) return false;
return ((SkeletonBounds *) bounds)->aabbcontainsPoint(x, y);
}

spine_bool spine_skeleton_bounds_aabb_intersects_segment(spine_skeleton_bounds bounds, float x1, float y1, float x2, float y2) {
if (bounds == nullptr) return false;
return ((SkeletonBounds *) bounds)->aabbintersectsSegment(x1, y1, x2, y2);
}

spine_bool spine_skeleton_bounds_aabb_intersects_skeleton(spine_skeleton_bounds bounds, spine_skeleton_bounds otherBounds) {
if (bounds == nullptr) return false;
if (otherBounds == nullptr) return false;
return ((SkeletonBounds *) bounds)->aabbIntersectsSkeleton(*((SkeletonBounds *) bounds));
}

spine_bool spine_skeleton_bounds_contains_point(spine_skeleton_bounds bounds, spine_polygon polygon, float x, float y) {
if (bounds == nullptr) return false;
if (polygon == nullptr) return false;
return ((SkeletonBounds *) bounds)->containsPoint((Polygon *) polygon, x, y);
}

spine_bounding_box_attachment spine_skeleton_bounds_contains_point_attachment(spine_skeleton_bounds bounds, float x, float y) {
if (bounds == nullptr) return nullptr;
return (spine_bounding_box_attachment) ((SkeletonBounds *) bounds)->containsPoint(x, y);
}

spine_bounding_box_attachment spine_skeleton_bounds_intersects_segment_attachment(spine_skeleton_bounds bounds, float x1, float y1, float x2, float y2) {
if (bounds == nullptr) return nullptr;
return (spine_bounding_box_attachment) ((SkeletonBounds *) bounds)->intersectsSegment(x1, y1, x2, y2);
}

spine_bool spine_skeleton_bounds_intersects_segment(spine_skeleton_bounds bounds, spine_polygon polygon, float x1, float y1, float x2, float y2) {
if (bounds == nullptr) return false;
if (polygon == nullptr) return false;
return ((SkeletonBounds *) bounds)->intersectsSegment((Polygon *) polygon, x1, y1, x2, y2);
}

spine_polygon spine_skeleton_bounds_get_polygon(spine_skeleton_bounds bounds, spine_bounding_box_attachment attachment) {
if (bounds == nullptr) return nullptr;
if (attachment == nullptr) return nullptr;
return (spine_polygon) ((SkeletonBounds *) bounds)->getPolygon((BoundingBoxAttachment *) attachment);
}

spine_bounding_box_attachment spine_skeleton_bounds_get_bounding_box(spine_skeleton_bounds bounds, spine_polygon polygon) {
if (bounds == nullptr) return nullptr;
if (polygon == nullptr) return nullptr;
return (spine_bounding_box_attachment) ((SkeletonBounds *) bounds)->getBoundingBox((Polygon *) polygon);
}

int32_t spine_skeleton_bounds_get_num_polygons(spine_skeleton_bounds bounds) {
if (bounds == nullptr) return 0;
return (int32_t) ((SkeletonBounds *) bounds)->getPolygons().size();
}

spine_polygon *spine_skeleton_bounds_get_polygons(spine_skeleton_bounds bounds) {
if (bounds == nullptr) return nullptr;
return (spine_polygon *) ((SkeletonBounds *) bounds)->getPolygons().buffer();
}

int32_t spine_skeleton_bounds_get_num_bounding_boxes(spine_skeleton_bounds bounds) {
if (bounds == nullptr) return 0;
return (int32_t) ((SkeletonBounds *) bounds)->getBoundingBoxes().size();
}

spine_bounding_box_attachment *spine_skeleton_bounds_get_bounding_boxes(spine_skeleton_bounds bounds) {
if (bounds == nullptr) return nullptr;
return (spine_bounding_box_attachment *) ((SkeletonBounds *) bounds)->getBoundingBoxes().buffer();
}

float spine_skeleton_bounds_get_width(spine_skeleton_bounds bounds) {
if (bounds == nullptr) return 0;
return ((SkeletonBounds *) bounds)->getWidth();
}

float spine_skeleton_bounds_get_height(spine_skeleton_bounds bounds) {
if (bounds == nullptr) return 0;
return ((SkeletonBounds *) bounds)->getHeight();
}

int32_t spine_polygon_get_num_vertices(spine_polygon polygon) {
if (polygon == nullptr) return 0;
return ((Polygon *) polygon)->_vertices.size();
}

float *spine_polygon_get_vertices(spine_polygon polygon) {
if (polygon == nullptr) return 0;
return ((Polygon *) polygon)->_vertices.buffer();
}
26 changes: 25 additions & 1 deletion spine-cpp/spine-cpp-lite/spine-cpp-lite.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ SPINE_OPAQUE_TYPE(spine_vector)
SPINE_OPAQUE_TYPE(spine_skeleton_drawable)
SPINE_OPAQUE_TYPE(spine_skin_entry)
SPINE_OPAQUE_TYPE(spine_skin_entries)
SPINE_OPAQUE_TYPE(spine_skeleton_bounds)
SPINE_OPAQUE_TYPE(spine_polygon)

// @end: opaque_types

Expand Down Expand Up @@ -263,7 +265,7 @@ SPINE_CPP_LITE_EXPORT void spine_skeleton_data_set_width(spine_skeleton_data dat
SPINE_CPP_LITE_EXPORT float spine_skeleton_data_get_height(spine_skeleton_data data);
SPINE_CPP_LITE_EXPORT void spine_skeleton_data_set_height(spine_skeleton_data data, float height);
SPINE_CPP_LITE_EXPORT const utf8 *spine_skeleton_data_get_version(spine_skeleton_data data);
// OMITTED setVersion()
// OMITTED setVersion()
// @ignore
SPINE_CPP_LITE_EXPORT const utf8 *spine_skeleton_data_get_hash(spine_skeleton_data data);
// OMITTED setHash()
Expand Down Expand Up @@ -1047,6 +1049,28 @@ SPINE_CPP_LITE_EXPORT void spine_texture_region_set_original_width(spine_texture
SPINE_CPP_LITE_EXPORT int32_t spine_texture_region_get_original_height(spine_texture_region textureRegion);
SPINE_CPP_LITE_EXPORT void spine_texture_region_set_original_height(spine_texture_region textureRegion, int32_t originalHeight);

SPINE_CPP_LITE_EXPORT spine_skeleton_bounds spine_skeleton_bounds_create();
SPINE_CPP_LITE_EXPORT void spine_skeleton_bounds_dispose(spine_skeleton_bounds bounds);
SPINE_CPP_LITE_EXPORT void spine_skeleton_bounds_update(spine_skeleton_bounds bounds, spine_skeleton skeleton, spine_bool updateAabb);
SPINE_CPP_LITE_EXPORT spine_bool spine_skeleton_bounds_aabb_contains_point(spine_skeleton_bounds bounds, float x, float y);
SPINE_CPP_LITE_EXPORT spine_bool spine_skeleton_bounds_aabb_intersects_segment(spine_skeleton_bounds bounds, float x1, float y1, float x2, float y2);
SPINE_CPP_LITE_EXPORT spine_bool spine_skeleton_bounds_aabb_intersects_skeleton(spine_skeleton_bounds bounds, spine_skeleton_bounds otherBounds);
SPINE_CPP_LITE_EXPORT spine_bool spine_skeleton_bounds_contains_point(spine_skeleton_bounds bounds, spine_polygon polygon, float x, float y);
SPINE_CPP_LITE_EXPORT spine_bounding_box_attachment spine_skeleton_bounds_contains_point_attachment(spine_skeleton_bounds bounds, float x, float y);
SPINE_CPP_LITE_EXPORT spine_bounding_box_attachment spine_skeleton_bounds_intersects_segment_attachment(spine_skeleton_bounds bounds, float x1, float y1, float x2, float y2);
SPINE_CPP_LITE_EXPORT spine_bool spine_skeleton_bounds_intersects_segment(spine_skeleton_bounds bounds, spine_polygon polygon, float x1, float y1, float x2, float y2);
SPINE_CPP_LITE_EXPORT spine_polygon spine_skeleton_bounds_get_polygon(spine_skeleton_bounds bounds, spine_bounding_box_attachment attachment);
SPINE_CPP_LITE_EXPORT spine_bounding_box_attachment spine_skeleton_bounds_get_bounding_box(spine_skeleton_bounds bounds, spine_polygon polygon);
SPINE_CPP_LITE_EXPORT int32_t spine_skeleton_bounds_get_num_polygons(spine_skeleton_bounds bounds);
SPINE_CPP_LITE_EXPORT spine_polygon *spine_skeleton_bounds_get_polygons(spine_skeleton_bounds bounds);
SPINE_CPP_LITE_EXPORT int32_t spine_skeleton_bounds_get_num_bounding_boxes(spine_skeleton_bounds bounds);
SPINE_CPP_LITE_EXPORT spine_bounding_box_attachment *spine_skeleton_bounds_get_bounding_boxes(spine_skeleton_bounds bounds);
SPINE_CPP_LITE_EXPORT float spine_skeleton_bounds_get_width(spine_skeleton_bounds bounds);
SPINE_CPP_LITE_EXPORT float spine_skeleton_bounds_get_height(spine_skeleton_bounds bounds);

SPINE_CPP_LITE_EXPORT int32_t spine_polygon_get_num_vertices(spine_polygon polygon);
SPINE_CPP_LITE_EXPORT float *spine_polygon_get_vertices(spine_polygon polygon);

// @end: function_declarations

#endif
4 changes: 2 additions & 2 deletions spine-glfw/example/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ int main() {
// Load the atlas and the skeleton data
GlTextureLoader textureLoader;
Atlas *atlas = new Atlas("data/spineboy-pma.atlas", &textureLoader);
SkeletonJson json(atlas);
SkeletonData *skeletonData = json.readSkeletonDataFile("data/spineboy-pro.skel");
SkeletonBinary binary(atlas);
SkeletonData *skeletonData = binary.readSkeletonDataFile("data/spineboy-pro.skel");

// Create a skeleton from the data, set the skeleton's position to the bottom center of
// the screen and scale it to make it smaller.
Expand Down
119 changes: 119 additions & 0 deletions spine-ios/Sources/Spine/Spine.Generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1721,6 +1721,104 @@ public final class AnimationState: NSObject {

}

@objc(SpineSkeletonBounds)
@objcMembers
public final class SkeletonBounds: NSObject {

internal let wrappee: spine_skeleton_bounds
internal var disposed = false

internal init(_ wrappee: spine_skeleton_bounds) {
self.wrappee = wrappee
super.init()
}

public var polygons: [Polygon] {
let num = Int(spine_skeleton_bounds_get_num_polygons(wrappee))
let ptr = spine_skeleton_bounds_get_polygons(wrappee)
return (0..<num).compactMap {
ptr?[$0].flatMap { .init($0) }
}
}

public var boundingBoxes: [BoundingBoxAttachment] {
let num = Int(spine_skeleton_bounds_get_num_bounding_boxes(wrappee))
let ptr = spine_skeleton_bounds_get_bounding_boxes(wrappee)
return (0..<num).compactMap {
ptr?[$0].flatMap { .init($0) }
}
}

public var width: Float {
return spine_skeleton_bounds_get_width(wrappee)
}

public var height: Float {
return spine_skeleton_bounds_get_height(wrappee)
}

@discardableResult
public func create() -> SkeletonBounds {
return .init(spine_skeleton_bounds_create())
}

public func dispose() {
if disposed { return }
disposed = true
spine_skeleton_bounds_dispose(wrappee)
}

public func update(skeleton: Skeleton, updateAabb: Bool) {
spine_skeleton_bounds_update(wrappee, skeleton.wrappee, updateAabb ? -1 : 0)
}

@discardableResult
public func aabbContainsPoint(x: Float, y: Float) -> Bool {
return spine_skeleton_bounds_aabb_contains_point(wrappee, x, y) != 0
}

@discardableResult
public func aabbIntersectsSegment(x1: Float, y1: Float, x2: Float, y2: Float) -> Bool {
return spine_skeleton_bounds_aabb_intersects_segment(wrappee, x1, y1, x2, y2) != 0
}

@discardableResult
public func aabbIntersectsSkeleton(otherBounds: SkeletonBounds) -> Bool {
return spine_skeleton_bounds_aabb_intersects_skeleton(wrappee, otherBounds.wrappee) != 0
}

@discardableResult
public func containsPoint(polygon: Polygon, x: Float, y: Float) -> Bool {
return spine_skeleton_bounds_contains_point(wrappee, polygon.wrappee, x, y) != 0
}

@discardableResult
public func containsPointAttachment(x: Float, y: Float) -> BoundingBoxAttachment {
return .init(spine_skeleton_bounds_contains_point_attachment(wrappee, x, y))
}

@discardableResult
public func intersectsSegmentAttachment(x1: Float, y1: Float, x2: Float, y2: Float) -> BoundingBoxAttachment {
return .init(spine_skeleton_bounds_intersects_segment_attachment(wrappee, x1, y1, x2, y2))
}

@discardableResult
public func intersectsSegment(polygon: Polygon, x1: Float, y1: Float, x2: Float, y2: Float) -> Bool {
return spine_skeleton_bounds_intersects_segment(wrappee, polygon.wrappee, x1, y1, x2, y2) != 0
}

@discardableResult
public func getPolygon(attachment: BoundingBoxAttachment) -> Polygon {
return .init(spine_skeleton_bounds_get_polygon(wrappee, attachment.wrappee))
}

@discardableResult
public func getBoundingBox(polygon: Polygon) -> BoundingBoxAttachment {
return .init(spine_skeleton_bounds_get_bounding_box(wrappee, polygon.wrappee))
}

}

@objc(SpineTextureRegion)
@objcMembers
public final class TextureRegion: NSObject {
Expand Down Expand Up @@ -3090,6 +3188,27 @@ public final class Sequence: NSObject {

}

@objc(SpinePolygon)
@objcMembers
public final class Polygon: NSObject {

internal let wrappee: spine_polygon

internal init(_ wrappee: spine_polygon) {
self.wrappee = wrappee
super.init()
}

public var vertices: [Float?] {
let num = Int(spine_polygon_get_num_vertices(wrappee))
let ptr = spine_polygon_get_vertices(wrappee)
return (0..<num).compactMap {
ptr?[$0]
}
}

}

@objc(SpineBounds)
@objcMembers
public final class Bounds: NSObject {
Expand Down

0 comments on commit 19d3d1b

Please sign in to comment.