Skip to content

Commit

Permalink
[haxe] Skeleton.getBounds() applies clipping, see #2515. Port of comm…
Browse files Browse the repository at this point in the history
…its b043e5c, 637321a and 2049bed.
  • Loading branch information
davidetan committed May 4, 2024
1 parent ad82b56 commit eb80431
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 3 deletions.
19 changes: 18 additions & 1 deletion spine-haxe/spine-haxe/spine/Skeleton.hx
Expand Up @@ -32,11 +32,13 @@ package spine;
import lime.math.Rectangle;
import haxe.ds.StringMap;
import spine.attachments.Attachment;
import spine.attachments.ClippingAttachment;
import spine.attachments.MeshAttachment;
import spine.attachments.PathAttachment;
import spine.attachments.RegionAttachment;

class Skeleton {
private static var quadTriangles:Array<Int> = [0, 1, 2, 2, 3, 0];
private var _data:SkeletonData;

public var bones:Array<Bone>;
Expand Down Expand Up @@ -611,28 +613,41 @@ class Skeleton {
private var _tempVertices = new Array<Float>();
private var _bounds = new Rectangle();

public function getBounds():Rectangle {
public function getBounds(clipper: SkeletonClipping = null):Rectangle {
var minX:Float = Math.POSITIVE_INFINITY;
var minY:Float = Math.POSITIVE_INFINITY;
var maxX:Float = Math.NEGATIVE_INFINITY;
var maxY:Float = Math.NEGATIVE_INFINITY;
for (slot in drawOrder) {
var verticesLength:Int = 0;
var vertices:Array<Float> = null;
var triangles:Array<Int> = null;
var attachment:Attachment = slot.attachment;

if (Std.isOfType(attachment, RegionAttachment)) {
verticesLength = 8;
_tempVertices.resize(verticesLength);
vertices = _tempVertices;
cast(attachment, RegionAttachment).computeWorldVertices(slot, vertices, 0, 2);
triangles = Skeleton.quadTriangles;
} else if (Std.isOfType(attachment, MeshAttachment)) {
var mesh:MeshAttachment = cast(attachment, MeshAttachment);
verticesLength = mesh.worldVerticesLength;
_tempVertices.resize(verticesLength);
vertices = _tempVertices;
mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
triangles = mesh.triangles;
} else if (Std.isOfType(attachment, ClippingAttachment) && clipper != null) {
clipper.clipStart(slot, cast(attachment, ClippingAttachment));
continue;
}

if (vertices != null) {
if (clipper != null && clipper.isClipping()) {
clipper.clipTriangles(vertices, triangles, triangles.length);
vertices = clipper.clippedVertices;
verticesLength = clipper.clippedVertices.length;
}
var ii:Int = 0;
var nn:Int = vertices.length;
while (ii < nn) {
Expand All @@ -644,7 +659,9 @@ class Skeleton {
ii += 2;
}
}
if (clipper != null) clipper.clipEndWithSlot(slot);
}
if (clipper != null) clipper.clipEnd();
_bounds.x = minX;
_bounds.y = minY;
_bounds.width = maxX - minX;
Expand Down
86 changes: 85 additions & 1 deletion spine-haxe/spine-haxe/spine/SkeletonClipping.hx
Expand Up @@ -84,7 +84,91 @@ class SkeletonClipping {
return clipAttachment != null;
}

public function clipTriangles(vertices:Array<Float>, triangles:Array<Int>, trianglesLength:Float, uvs:Array<Float>):Void {
private function clipTrianglesNoRender(vertices:Array<Float>, triangles:Array<Int>, trianglesLength:Float):Void {
var polygonsCount:Int = clippingPolygons.length;
var index:Int = 0;
clippedVertices.resize(0);
clippedUvs.resize(0);
clippedTriangles.resize(0);
var i:Int = 0;
while (i < trianglesLength) {
var vertexOffset:Int = triangles[i] << 1;
var x1:Float = vertices[vertexOffset],
y1:Float = vertices[vertexOffset + 1];

vertexOffset = triangles[i + 1] << 1;
var x2:Float = vertices[vertexOffset],
y2:Float = vertices[vertexOffset + 1];

vertexOffset = triangles[i + 2] << 1;
var x3:Float = vertices[vertexOffset],
y3:Float = vertices[vertexOffset + 1];

for (p in 0...polygonsCount) {
var s:Int = clippedVertices.length;
var clippedVerticesItems:Array<Float>;
var clippedTrianglesItems:Array<Int>;
if (this.clip(x1, y1, x2, y2, x3, y3, clippingPolygons[p], clipOutput)) {
var clipOutputLength:Int = clipOutput.length;
if (clipOutputLength == 0)
continue;

var clipOutputCount:Int = clipOutputLength >> 1;
var clipOutputItems:Array<Float> = clipOutput;
clippedVerticesItems = clippedVertices;
clippedVerticesItems.resize(s + clipOutputLength);
var ii:Int = 0;
while (ii < clipOutputLength) {
var x:Float = clipOutputItems[ii],
y:Float = clipOutputItems[ii + 1];
clippedVerticesItems[s] = x;
clippedVerticesItems[s + 1] = y;
s += 2;
ii += 2;
}

s = clippedTriangles.length;
clippedTrianglesItems = clippedTriangles;
clippedTrianglesItems.resize(s + 3 * (clipOutputCount - 2));
clipOutputCount--;
for (ii in 1...clipOutputCount) {
clippedTrianglesItems[s] = index;
clippedTrianglesItems[s + 1] = (index + ii);
clippedTrianglesItems[s + 2] = (index + ii + 1);
s += 3;
}
index += clipOutputCount + 1;
} else {
clippedVerticesItems = clippedVertices;
clippedVerticesItems.resize(s + 3 * 2);
clippedVerticesItems[s] = x1;
clippedVerticesItems[s + 1] = y1;
clippedVerticesItems[s + 2] = x2;
clippedVerticesItems[s + 3] = y2;
clippedVerticesItems[s + 4] = x3;
clippedVerticesItems[s + 5] = y3;

s = clippedTriangles.length;
clippedTrianglesItems = clippedTriangles;
clippedTrianglesItems.resize(s + 3);
clippedTrianglesItems[s] = index;
clippedTrianglesItems[s + 1] = (index + 1);
clippedTrianglesItems[s + 2] = (index + 2);
index += 3;
break;
}
}

i += 3;
}
}

public function clipTriangles(vertices:Array<Float>, triangles:Array<Int>, trianglesLength:Float, uvs:Array<Float> = null):Void {
if (uvs == null) {
clipTrianglesNoRender(vertices, triangles, trianglesLength);
return;
}

var polygonsCount:Int = clippingPolygons.length;
var index:Int = 0;
clippedVertices.resize(0);
Expand Down
2 changes: 1 addition & 1 deletion spine-haxe/spine-haxe/spine/starling/SkeletonSprite.hx
Expand Up @@ -66,7 +66,7 @@ class SkeletonSprite extends DisplayObject implements IAnimatable {

private var _smoothing:String = "bilinear";

private static var clipper:SkeletonClipping = new SkeletonClipping();
public static var clipper(default, never):SkeletonClipping = new SkeletonClipping();
private static var QUAD_INDICES:Array<Int> = [0, 1, 2, 2, 3, 0];

private var tempLight:spine.Color = new spine.Color(0, 0, 0);
Expand Down

0 comments on commit eb80431

Please sign in to comment.