diff --git a/spine-haxe/spine-haxe/spine/Skeleton.hx b/spine-haxe/spine-haxe/spine/Skeleton.hx index 2f543143d..942f9804b 100644 --- a/spine-haxe/spine-haxe/spine/Skeleton.hx +++ b/spine-haxe/spine-haxe/spine/Skeleton.hx @@ -25,12 +25,11 @@ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ +*****************************************************************************/ package spine; -import lime.math.Rectangle; -import haxe.ds.StringMap; +import spine.Rectangle; import spine.attachments.Attachment; import spine.attachments.ClippingAttachment; import spine.attachments.MeshAttachment; @@ -43,20 +42,27 @@ import spine.attachments.RegionAttachment; */ class Skeleton { private static var quadTriangles:Array = [0, 1, 2, 2, 3, 0]; + private var _data:SkeletonData; /** The skeleton's bones, sorted parent first. The root bone is always the first bone. */ public var bones:Array; + /** The skeleton's slots. */ public var slots:Array; // Setup pose draw order. + /** The skeleton's slots in the order they should be drawn. The returned array may be modified to change the draw order. */ public var drawOrder:Array; + /** The skeleton's IK constraints. */ public var ikConstraints:Array; + /** The skeleton's transform constraints. */ public var transformConstraints:Array; + /** The skeleton's path constraints. */ public var pathConstraints:Array; + /** The skeleton's physics constraints. */ public var physicsConstraints:Array; @@ -65,6 +71,7 @@ class Skeleton { /** The color to tint all the skeleton's attachments. */ public var color:Color = new Color(1, 1, 1, 1); + /** Scales the entire skeleton on the X axis. * * Bones that do not inherit scale are still affected by this property. */ @@ -74,6 +81,7 @@ class Skeleton { * * Bones that do not inherit scale are still affected by this property. */ public var scaleY(get, default):Float = 1; + function get_scaleY() { return Bone.yDown ? -scaleY : scaleY; } @@ -82,10 +90,12 @@ class Skeleton { * * Bones that do not inherit translation are still affected by this property. */ public var x:Float = 0; + /** Sets the skeleton Y position, which is added to the root bone worldY position. * * Bones that do not inherit translation are still affected by this property. */ public var y:Float = 0; + /** Returns the skeleton's time. This is used for time-based manipulations, such as spine.PhysicsConstraint. * * See Skeleton.update(). */ @@ -317,7 +327,7 @@ class Skeleton { } private function sortPathConstraintAttachment(skin:Skin, slotIndex:Int, slotBone:Bone):Void { - var dict:StringMap = skin.attachments[slotIndex]; + var dict = skin.attachments[slotIndex]; if (dict != null) { for (attachment in dict.keyValueIterator()) { sortPathConstraintAttachment2(attachment.value, slotBone); @@ -345,10 +355,12 @@ class Skeleton { } } - private function sortPhysicsConstraint (constraint: PhysicsConstraint) { + private function sortPhysicsConstraint(constraint:PhysicsConstraint) { var bone:Bone = constraint.bone; - constraint.active = bone.active && (!constraint.data.skinRequired || (skin != null && contains(skin.constraints, constraint.data))); - if (!constraint.active) return; + constraint.active = bone.active + && (!constraint.data.skinRequired || (skin != null && contains(skin.constraints, constraint.data))); + if (!constraint.active) + return; sortBone(bone); @@ -383,7 +395,8 @@ class Skeleton { * @see https://esotericsoftware.com/spine-runtime-skeletons#World-transforms World transforms in the Spine Runtimes Guide */ public function updateWorldTransform(physics:Physics):Void { - if (physics == null) throw new SpineException("physics is undefined"); + if (physics == null) + throw new SpineException("physics is undefined"); for (bone in bones) { bone.ax = bone.x; bone.ay = bone.y; @@ -440,11 +453,16 @@ class Skeleton { /** Sets the bones and constraints to their setup pose values. */ public function setBonesToSetupPose():Void { - for (bone in this.bones) bone.setToSetupPose(); - for (constraint in this.ikConstraints) constraint.setToSetupPose(); - for (constraint in this.transformConstraints) constraint.setToSetupPose(); - for (constraint in this.pathConstraints) constraint.setToSetupPose(); - for (constraint in this.physicsConstraints) constraint.setToSetupPose(); + for (bone in this.bones) + bone.setToSetupPose(); + for (constraint in this.ikConstraints) + constraint.setToSetupPose(); + for (constraint in this.transformConstraints) + constraint.setToSetupPose(); + for (constraint in this.pathConstraints) + constraint.setToSetupPose(); + for (constraint in this.physicsConstraints) + constraint.setToSetupPose(); } /** Sets the slots and draw order to their setup pose values. */ @@ -686,7 +704,7 @@ class Skeleton { /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. Optionally applies * clipping. */ - public function getBounds(clipper: SkeletonClipping = null):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; @@ -732,9 +750,11 @@ class Skeleton { ii += 2; } } - if (clipper != null) clipper.clipEndWithSlot(slot); + if (clipper != null) + clipper.clipEndWithSlot(slot); } - if (clipper != null) clipper.clipEnd(); + if (clipper != null) + clipper.clipEnd(); _bounds.x = minX; _bounds.y = minY; _bounds.width = maxX - minX; @@ -743,18 +763,18 @@ class Skeleton { } /** Increments the skeleton's Skeleton.time. */ - public function update (delta:Float):Void { + public function update(delta:Float):Void { time += delta; } /** Calls spine.PhysicsConstraint.translate() for each physics constraint. */ - public function physicsTranslate (x:Float, y:Float):Void { + public function physicsTranslate(x:Float, y:Float):Void { for (physicsConstraint in physicsConstraints) physicsConstraint.translate(x, y); } /** Calls spine.PhysicsConstraint.rotate() for each physics constraint. */ - public function physicsRotate (x:Float, y:Float, degrees:Float):Void { + public function physicsRotate(x:Float, y:Float, degrees:Float):Void { for (physicsConstraint in physicsConstraints) physicsConstraint.rotate(x, y, degrees); } diff --git a/spine-haxe/spine-haxe/spine/flixel/SkeletonSprite.hx b/spine-haxe/spine-haxe/spine/flixel/SkeletonSprite.hx index 1730b2c29..d412b4478 100644 --- a/spine-haxe/spine-haxe/spine/flixel/SkeletonSprite.hx +++ b/spine-haxe/spine-haxe/spine/flixel/SkeletonSprite.hx @@ -25,7 +25,7 @@ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ +*****************************************************************************/ package spine.flixel; @@ -63,13 +63,13 @@ import spine.attachments.ClippingAttachment; import spine.flixel.SkeletonMesh; /** A FlxObject that draws a skeleton. The animation state and skeleton must be updated each frame. */ -class SkeletonSprite extends FlxObject -{ +class SkeletonSprite extends FlxObject { public var skeleton(default, null):Skeleton; public var state(default, null):AnimationState; public var stateData(default, null):AnimationStateData; - public var beforeUpdateWorldTransforms: SkeletonSprite -> Void = function(_) {}; - public var afterUpdateWorldTransforms: SkeletonSprite -> Void = function(_) {}; + public var beforeUpdateWorldTransforms:SkeletonSprite->Void = function(_) {}; + public var afterUpdateWorldTransforms:SkeletonSprite->Void = function(_) {}; + public static var clipper(default, never):SkeletonClipping = new SkeletonClipping(); public var offsetX = .0; @@ -93,9 +93,9 @@ class SkeletonSprite extends FlxObject private var _tempPoint = new Point(); private static var QUAD_INDICES:Array = [0, 1, 2, 2, 3, 0]; + /** Creates an uninitialized SkeletonSprite. The renderer, skeleton, and animation state must be set before use. */ - public function new(skeletonData:SkeletonData, animationStateData:AnimationStateData = null) - { + public function new(skeletonData:SkeletonData, animationStateData:AnimationStateData = null) { super(0, 0); Bone.yDown = true; skeleton = new Skeleton(skeletonData); @@ -114,30 +114,34 @@ class SkeletonSprite extends FlxObject } } - public function getAnimationBounds(animation:Animation, clip:Bool = true): lime.math.Rectangle { + public function getAnimationBounds(animation:Animation, clip:Bool = true):Rectangle { var clipper = clip ? SkeletonSprite.clipper : null; skeleton.setToSetupPose(); var steps = 100, time = 0.; var stepTime = animation.duration != 0 ? animation.duration / steps : 0; - var minX = 100000000., maxX = -100000000., minY = 100000000., maxY = -100000000.; + var minX = 100000000., + maxX = -100000000., + minY = 100000000., + maxY = -100000000.; - var bounds = new lime.math.Rectangle(); for (i in 0...steps) { - animation.apply(skeleton, time , time, false, [], 1, MixBlend.setup, MixDirection.mixIn); + animation.apply(skeleton, time, time, false, [], 1, MixBlend.setup, MixDirection.mixIn); skeleton.updateWorldTransform(Physics.update); - bounds = skeleton.getBounds(clipper); + var boundsSkel = skeleton.getBounds(clipper); - if (!Math.isNaN(bounds.x) && !Math.isNaN(bounds.y) && !Math.isNaN(bounds.width) && !Math.isNaN(bounds.height)) { - minX = Math.min(bounds.x, minX); - minY = Math.min(bounds.y, minY); - maxX = Math.max(bounds.right, maxX); - maxY = Math.max(bounds.bottom, maxY); + if (!Math.isNaN(boundsSkel.x) && !Math.isNaN(boundsSkel.y) && !Math.isNaN(boundsSkel.width) && !Math.isNaN(boundsSkel.height)) { + minX = Math.min(boundsSkel.x, minX); + minY = Math.min(boundsSkel.y, minY); + maxX = Math.max(boundsSkel.x + boundsSkel.width, maxX); + maxY = Math.max(boundsSkel.y + boundsSkel.height, maxY); } else - trace("ERROR"); + throw new SpineException("Animation bounds are invalid: " + animation.name); time += stepTime; } + + var bounds = new Rectangle(); bounds.x = minX; bounds.y = minY; bounds.width = maxX - minX; @@ -145,8 +149,7 @@ class SkeletonSprite extends FlxObject return bounds; } - override public function destroy():Void - { + override public function destroy():Void { state.clearListeners(); state = null; skeleton = null; @@ -157,15 +160,15 @@ class SkeletonSprite extends FlxObject _tempPoint = null; if (_meshes != null) { - for (mesh in _meshes) mesh.destroy(); + for (mesh in _meshes) + mesh.destroy(); _meshes = null; } super.destroy(); } - override public function update(elapsed:Float):Void - { + override public function update(elapsed:Float):Void { super.update(elapsed); state.update(elapsed); state.apply(skeleton); @@ -175,14 +178,15 @@ class SkeletonSprite extends FlxObject this.afterUpdateWorldTransforms(this); } - override public function draw():Void - { - if (alpha == 0) return; + override public function draw():Void { + if (alpha == 0) + return; renderMeshes(); #if FLX_DEBUG - if (FlxG.debugger.drawDebug) drawDebug(); + if (FlxG.debugger.drawDebug) + drawDebug(); #end } @@ -244,14 +248,10 @@ class SkeletonSprite extends FlxObject } if (mesh != null) { - // cannot use directly mesh.color.setRGBFloat otherwise the setter won't be called and transfor color not set - mesh.color = FlxColor.fromRGBFloat( - skeleton.color.r * slot.color.r * attachmentColor.r * color.redFloat, + mesh.color = FlxColor.fromRGBFloat(skeleton.color.r * slot.color.r * attachmentColor.r * color.redFloat, skeleton.color.g * slot.color.g * attachmentColor.g * color.greenFloat, - skeleton.color.b * slot.color.b * attachmentColor.b * color.blueFloat, - 1 - ); + skeleton.color.b * slot.color.b * attachmentColor.b * color.blueFloat, 1); mesh.alpha = skeleton.color.a * slot.color.a * attachmentColor.a * alpha; if (clipper.isClipping()) { @@ -272,7 +272,7 @@ class SkeletonSprite extends FlxObject _tempPoint = _tempMatrix.transformPoint(_tempPoint); mesh.vertices[i] = _tempPoint.x; mesh.vertices[i + 1] = _tempPoint.y; - i+=2; + i += 2; } } } else { @@ -321,7 +321,7 @@ class SkeletonSprite extends FlxObject _tempMatrix.identity(); // scale is connected to the skeleton scale - no need to rescale _tempMatrix.scale(1, 1); - _tempMatrix.rotate(angle * Math.PI / 180); + _tempMatrix.rotate(angle * Math.PI / 180); _tempMatrix.translate(x + offsetX, y + offsetY); return _tempMatrix; } @@ -334,10 +334,10 @@ class SkeletonSprite extends FlxObject d = transform.d, tx = transform.tx, ty = transform.ty; - var x = point[0]; - var y = point[1]; - point[0] = x * a + y * c + tx; - point[1] = x * b + y * d + ty; + var x = point[0]; + var y = point[1]; + point[0] = x * a + y * c + tx; + point[1] = x * b + y * d + ty; } public function haxeWorldCoordinatesToSkeleton(point:Array):Void { @@ -354,7 +354,7 @@ class SkeletonSprite extends FlxObject point[1] = x * b + y * d + ty; } - public function haxeWorldCoordinatesToBone(point:Array, bone: Bone):Void { + public function haxeWorldCoordinatesToBone(point:Array, bone:Bone):Void { this.haxeWorldCoordinatesToSkeleton(point); if (bone.parent != null) { bone.parent.worldToLocal(point); @@ -363,7 +363,7 @@ class SkeletonSprite extends FlxObject } } - private function getFlixelMeshFromRendererAttachment(region: RenderedAttachment) { + private function getFlixelMeshFromRendererAttachment(region:RenderedAttachment) { if (region.rendererObject == null) { var skeletonMesh = new SkeletonMesh(); region.rendererObject = skeletonMesh; @@ -373,15 +373,15 @@ class SkeletonSprite extends FlxObject return region.rendererObject; } - function set_flipX(value:Bool):Bool - { - if (value != flipX) skeleton.scaleX = -skeleton.scaleX; + function set_flipX(value:Bool):Bool { + if (value != flipX) + skeleton.scaleX = -skeleton.scaleX; return flipX = value; } - function set_flipY(value:Bool):Bool - { - if (value != flipY) skeleton.scaleY = -skeleton.scaleY; + function set_flipY(value:Bool):Bool { + if (value != flipY) + skeleton.scaleY = -skeleton.scaleY; return flipY = value; } @@ -404,7 +404,6 @@ class SkeletonSprite extends FlxObject function set_scaleY(value:Float):Float { return skeleton.scaleY = value; } - } typedef RenderedAttachment = { diff --git a/spine-haxe/spine-haxe/spine/starling/SkeletonSprite.hx b/spine-haxe/spine-haxe/spine/starling/SkeletonSprite.hx index 8a60d8534..006b08448 100644 --- a/spine-haxe/spine-haxe/spine/starling/SkeletonSprite.hx +++ b/spine-haxe/spine-haxe/spine/starling/SkeletonSprite.hx @@ -25,7 +25,7 @@ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ +*****************************************************************************/ package spine.starling; @@ -33,7 +33,7 @@ import spine.animation.Animation; import starling.animation.IAnimatable; import openfl.geom.Matrix; import openfl.geom.Point; -import openfl.geom.Rectangle; +import openfl.geom.Rectangle as OpenFlRectangle; import spine.Bone; import spine.Skeleton; import spine.SkeletonClipping; @@ -76,8 +76,8 @@ class SkeletonSprite extends DisplayObject implements IAnimatable { private var tempLight:spine.Color = new spine.Color(0, 0, 0); private var tempDark:spine.Color = new spine.Color(0, 0, 0); - public var beforeUpdateWorldTransforms: SkeletonSprite -> Void = function(_) {}; - public var afterUpdateWorldTransforms: SkeletonSprite -> Void = function(_) {}; + public var beforeUpdateWorldTransforms:SkeletonSprite->Void = function(_) {}; + public var afterUpdateWorldTransforms:SkeletonSprite->Void = function(_) {}; /** Creates an uninitialized SkeletonSprite. The skeleton and animation state must be set before use. */ public function new(skeletonData:SkeletonData, animationStateData:AnimationStateData = null) { @@ -306,9 +306,9 @@ class SkeletonSprite extends DisplayObject implements IAnimatable { return null; } - override public function getBounds(targetSpace:DisplayObject, resultRect:Rectangle = null):Rectangle { + override public function getBounds(targetSpace:DisplayObject, resultRect:OpenFlRectangle = null):OpenFlRectangle { if (resultRect == null) { - resultRect = new Rectangle(); + resultRect = new OpenFlRectangle(); } if (targetSpace == this) { resultRect.setTo(0, 0, 0, 0); @@ -322,31 +322,39 @@ class SkeletonSprite extends DisplayObject implements IAnimatable { return resultRect; } - public function getAnimationBounds(animation:Animation, clip:Bool = true): Rectangle { + public function getAnimationBounds(animation:Animation, clip:Bool = true):Rectangle { var clipper = clip ? SkeletonSprite.clipper : null; _skeleton.setToSetupPose(); var steps = 100, time = 0.; var stepTime = animation.duration != 0 ? animation.duration / steps : 0; - var minX = 100000000., maxX = -100000000., minY = 100000000., maxY = -100000000.; + var minX = 100000000., + maxX = -100000000., + minY = 100000000., + maxY = -100000000.; - var bound:lime.math.Rectangle; for (i in 0...steps) { - animation.apply(_skeleton, time , time, false, [], 1, MixBlend.setup, MixDirection.mixIn); + animation.apply(_skeleton, time, time, false, [], 1, MixBlend.setup, MixDirection.mixIn); _skeleton.updateWorldTransform(Physics.update); - bound = _skeleton.getBounds(clipper); + var boundsSkel = _skeleton.getBounds(clipper); - if (!Math.isNaN(bound.x) && !Math.isNaN(bound.y) && !Math.isNaN(bound.width) && !Math.isNaN(bound.height)) { - minX = Math.min(bound.x, minX); - minY = Math.min(bound.y, minY); - maxX = Math.max(bound.right, maxX); - maxY = Math.max(bound.bottom, maxY); + if (!Math.isNaN(boundsSkel.x) && !Math.isNaN(boundsSkel.y) && !Math.isNaN(boundsSkel.width) && !Math.isNaN(boundsSkel.height)) { + minX = Math.min(boundsSkel.x, minX); + minY = Math.min(boundsSkel.y, minY); + maxX = Math.max(boundsSkel.x + boundsSkel.width, maxX); + maxY = Math.max(boundsSkel.y + boundsSkel.height, maxY); } else - trace("ERROR"); + throw new SpineException("Animation bounds are invalid: " + animation.name); time += stepTime; } - return new Rectangle(minX, minY, maxX - minX, maxY - minY); + + var bounds = new Rectangle(); + bounds.x = minX; + bounds.y = minY; + bounds.width = maxX - minX; + bounds.height = maxY - minY; + return bounds; } public var skeleton(get, never):Skeleton; @@ -390,10 +398,10 @@ class SkeletonSprite extends DisplayObject implements IAnimatable { d = transform.d, tx = transform.tx, ty = transform.ty; - var x = point[0]; - var y = point[1]; - point[0] = x * a + y * c + tx; - point[1] = x * b + y * d + ty; + var x = point[0]; + var y = point[1]; + point[0] = x * a + y * c + tx; + point[1] = x * b + y * d + ty; } public function haxeWorldCoordinatesToSkeleton(point:Array):Void { @@ -410,7 +418,7 @@ class SkeletonSprite extends DisplayObject implements IAnimatable { point[1] = x * b + y * d + ty; } - public function haxeWorldCoordinatesToBone(point:Array, bone: Bone):Void { + public function haxeWorldCoordinatesToBone(point:Array, bone:Bone):Void { this.haxeWorldCoordinatesToSkeleton(point); if (bone.parent != null) { bone.parent.worldToLocal(point); @@ -424,7 +432,8 @@ class SkeletonSprite extends DisplayObject implements IAnimatable { _state.clearListeners(); _state = null; } - if (_skeleton != null) _skeleton = null; + if (_skeleton != null) + _skeleton = null; dispatchEventWith(starling.events.Event.REMOVE_FROM_JUGGLER); removeFromParent();