1 module spine.skeleton_bounds;
2 
3 import spine.skeleton;
4 
5 class SkeletonBounds
6 {
7     private spSkeletonBounds* sp_skeletonBounds;
8 
9     this()
10     {
11         sp_skeletonBounds = spSkeletonBounds_create();
12     }
13 
14     ~this()
15     {
16         spSkeletonBounds_dispose(sp_skeletonBounds);
17     }
18 
19     void update(Skeleton sk, bool updateAabb)
20     {
21         spSkeletonBounds_update(sp_skeletonBounds, sk.sp_skeleton, updateAabb);
22     }
23 
24     float minX() const { return sp_skeletonBounds.minX; }
25     float minY() const { return sp_skeletonBounds.minY; }
26     float maxX() const { return sp_skeletonBounds.maxX; }
27     float maxY() const { return sp_skeletonBounds.maxY; }
28 
29     /** Returns true if the axis aligned bounding box intersects the line segment. */
30     bool aabbIntersectsSegment(float x1, float y1, float x2, float y2)
31     {
32         return spSkeletonBounds_aabbIntersectsSegment(sp_skeletonBounds, x1, y1, x2, y2) != 0;
33     }
34 
35     /** Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually
36      * more efficient to only call this method if spSkeletonBounds_aabbIntersectsSegment returns true. */
37     spBoundingBoxAttachment* intersectsSegment(float x1, float y1, float x2, float y2)
38     {
39         return spSkeletonBounds_intersectsSegment(sp_skeletonBounds, x1, y1, x2, y2);
40     }
41 
42     debug override string toString() const
43     {
44         return sp_skeletonBounds.toString();
45     }
46 }
47 
48 extern(C):
49 
50 struct spSkeletonBounds
51 {
52 	int count;
53 	spBoundingBoxAttachment** boundingBoxes;
54 	spPolygon** polygons;
55 
56 	float minX, minY, maxX, maxY;
57 
58     debug string toString() const
59     {
60         import std.conv: to;
61 
62         string ret;
63 
64         foreach(i; 0 .. count)
65             ret ~= polygons[i].toString ~ ",\n";
66 
67         return
68             "minX="~minX.to!string~
69             " minY="~minY.to!string~
70             " maxX="~maxX.to!string~
71             " maxY="~maxY.to!string~
72             " polygons:{\n"~ret~"}\n";
73     }
74 }
75 
76 struct spBoundingBoxAttachment
77 {
78     import spine.atlas: spVertexAttachment;
79 
80     spVertexAttachment _super;
81 }
82 
83 private:
84 
85 struct spPolygon
86 {
87 	const(float)* vertices;
88 	int count;
89 	int capacity;
90 
91     debug string toString() const
92     {
93         import std.conv: to;
94 
95         string ret;
96 
97         foreach(i; 0 .. count)
98             ret ~= vertices[i].to!string ~ ",";
99 
100         return "["~ret~"], capacity: "~capacity.to!string;
101     }
102 }
103 
104 spSkeletonBounds* spSkeletonBounds_create ();
105 void spSkeletonBounds_dispose (spSkeletonBounds* self);
106 void spSkeletonBounds_update (spSkeletonBounds* self, spSkeleton* skeleton, int/*bool*/updateAabb);
107 
108 int/*bool*/spSkeletonBounds_aabbIntersectsSegment (spSkeletonBounds* self, float x1, float y1, float x2, float y2);
109 spBoundingBoxAttachment* spSkeletonBounds_intersectsSegment (spSkeletonBounds* self, float x1, float y1, float x2, float y2);