Is there a method to get the dimensions or axis aligned bounding box of a skeleton that doesn't have any explicit bounding box attachments? I just want to know the basic width and height of the skeleton using it's bones and attached images, and was wondering if a method already exists to compute this.
I made a class called SkeletonImageBounds that is mostly a copy of SkeletonBounds, but uses region attachments instead of bounding box attachments to get polygon data and compute an aabb. Still interested if there's a better way or a built-in way, but here this is for anyone that needs it:
(I'm using the Starling runtime, btw)
public class SkeletonImageBounds {
private var polygonPool:Vector.<Polygon> = new Vector.<Polygon>();
public var polygons:Vector.<Polygon> = new Vector.<Polygon>();
public var minX:Number, minY:Number, maxX:Number, maxY:Number;
public function update (skeleton:Skeleton, updateAabb:Boolean) : void {
var slots:Vector.<Slot> = skeleton.slots;
var slotCount:int = slots.length;
var x:Number = skeleton.x, y:Number = skeleton.y;
for each (var polygon:Polygon in polygons)
polygonPool[polygonPool.length] = polygon;
polygons.length = 0;
for (var i:int = 0; i < slotCount; i++) {
var slot:Slot = slots[i];
var regionAttachment:RegionAttachment = slot.attachment as RegionAttachment;
if (regionAttachment != null) {
var poolCount:int = polygonPool.length;
if (poolCount > 0) {
polygon = polygonPool[poolCount - 1];
polygonPool.splice(poolCount - 1, 1);
} else
polygon = new Polygon();
polygons[polygons.length] = polygon;
polygon.vertices.length = 4;
regionAttachment.computeWorldVertices(x, y, slot.bone, polygon.vertices);
}
}
if (updateAabb) aabbCompute();
}
private function aabbCompute () : void {
var minX:Number = int.MAX_VALUE, minY:Number = int.MAX_VALUE, maxX:Number = int.MIN_VALUE, maxY:Number = int.MIN_VALUE;
for (var i:int = 0, n:int = polygons.length; i < n; i++) {
var polygon:Polygon = polygons[i];
var vertices:Vector.<Number> = polygon.vertices;
for (var ii:int = 0, nn:int = vertices.length; ii < nn; ii += 2) {
var x:Number = vertices[ii];
var y:Number = vertices[ii + 1];
minX = Math.min(minX, x);
minY = Math.min(minY, y);
maxX = Math.max(maxX, x);
maxY = Math.max(maxY, y);
}
}
this.minX = minX;
this.minY = minY;
this.maxX = maxX;
this.maxY = maxY;
}
/** Returns true if the axis aligned bounding box contains the point. */
public function aabbContainsPoint (x:Number, y:Number) : Boolean {
return x >= minX && x <= maxX && y >= minY && y <= maxY;
}
/** Returns true if the axis aligned bounding box intersects the line segment. */
public function aabbIntersectsSegment (x1:Number, y1:Number, x2:Number, y2:Number) : Boolean {
if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY))
return false;
var m:Number = (y2 - y1) / (x2 - x1);
var y:Number = m * (minX - x1) + y1;
if (y > minY && y < maxY) return true;
y = m * (maxX - x1) + y1;
if (y > minY && y < maxY) return true;
var x:Number = (minY - y1) / m + x1;
if (x > minX && x < maxX) return true;
x = (maxY - y1) / m + x1;
if (x > minX && x < maxX) return true;
return false;
}
/** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */
public function aabbIntersectsSkeleton (bounds:SkeletonBounds) : Boolean {
return minX < bounds.maxX && maxX > bounds.minX && minY < bounds.maxY && maxY > bounds.minY;
}
public function get width () : Number {
return maxX - minX;
}
public function get height () : Number {
return maxY - minY;
}
}