mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-10 17:18:44 +08:00
[haxe] More porting from 4.0 -> 4.1, WIP
This commit is contained in:
parent
51b108f2e1
commit
30311f2cd8
@ -10,7 +10,7 @@ import openfl.geom.Rectangle;
|
||||
import openfl.utils.ByteArray;
|
||||
import openfl.utils.Endian;
|
||||
import spine.animation.AnimationStateData;
|
||||
import spine.atlas.Atlas;
|
||||
import spine.atlas.TextureAtlas;
|
||||
import spine.attachments.AtlasAttachmentLoader;
|
||||
import spine.SkeletonBinary;
|
||||
import spine.SkeletonData;
|
||||
@ -22,7 +22,7 @@ import starling.events.Event;
|
||||
import starling.textures.Texture;
|
||||
|
||||
class Main extends Sprite {
|
||||
private static inline var loadBinary:Bool = true;
|
||||
private static inline var loadBinary:Bool = false;
|
||||
|
||||
private var starlingSingleton:Starling;
|
||||
|
||||
@ -44,13 +44,13 @@ class Main extends Sprite {
|
||||
|
||||
private function loadSpineAnimation():Void {
|
||||
var textureAtlasBitmapData:BitmapData = Assets.getBitmapData("assets/coin.png");
|
||||
var stAtlas:String = Assets.getText("assets/coin.atlas");
|
||||
var binaryData:Bytes = Assets.getBytes("assets/coin-pro.skel");
|
||||
var jsonData:String = Assets.getText("assets/coin-pro.json");
|
||||
var stAtlas = Assets.getText("assets/coin.atlas");
|
||||
var binaryData = Assets.getBytes("assets/coin-pro.skel");
|
||||
var jsonData = Assets.getText("assets/coin-pro.json");
|
||||
|
||||
var textureAtlas:Texture = Texture.fromBitmapData(textureAtlasBitmapData);
|
||||
var textureloader:StarlingTextureLoader = new StarlingTextureLoader(textureAtlas);
|
||||
var atlas:Atlas = new Atlas(stAtlas, textureloader);
|
||||
var textureAtlas = Texture.fromBitmapData(textureAtlasBitmapData);
|
||||
var textureloader = new StarlingTextureLoader(textureAtlas);
|
||||
var atlas = new TextureAtlas(stAtlas, textureloader);
|
||||
|
||||
var skeletondata:SkeletonData;
|
||||
if (loadBinary) {
|
||||
|
||||
9
spine-haxe/spine-haxe/spine/HasTextureRegion.hx
Normal file
9
spine-haxe/spine-haxe/spine/HasTextureRegion.hx
Normal file
@ -0,0 +1,9 @@
|
||||
package spine;
|
||||
|
||||
interface HasTextureRegion {
|
||||
public var path:String;
|
||||
public var region:TextureRegion;
|
||||
public var color:Color;
|
||||
public var sequence:Sequence;
|
||||
public function updateRegion():Void;
|
||||
}
|
||||
@ -72,7 +72,7 @@ class IkConstraint implements Updatable {
|
||||
tx = targetX - bone.worldX;
|
||||
ty = targetY - bone.worldY;
|
||||
case TransformMode.noRotationOrReflection:
|
||||
var s:Float = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
|
||||
var s = Math.abs(pa * pd - pb * pc) / Math.max(0.0001, pa * pa + pc * pc);
|
||||
var sa:Float = pa / bone.skeleton.scaleX;
|
||||
var sc:Float = pc / bone.skeleton.scaleY;
|
||||
pb = -sc * s * bone.skeleton.scaleX;
|
||||
@ -85,8 +85,13 @@ class IkConstraint implements Updatable {
|
||||
default:
|
||||
var x:Float = targetX - p.worldX, y:Float = targetY - p.worldY;
|
||||
var d:Float = pa * pd - pb * pc;
|
||||
tx = (x * pd - y * pb) / d - bone.ax;
|
||||
ty = (y * pa - x * pc) / d - bone.ay;
|
||||
if (Math.abs(d) <= 0.0001) {
|
||||
tx = 0;
|
||||
ty = 0;
|
||||
} else {
|
||||
tx = (x * pd - y * pb) / d - bone.ax;
|
||||
ty = (y * pa - x * pc) / d - bone.ay;
|
||||
}
|
||||
}
|
||||
|
||||
rotationIK += Math.atan2(ty, tx) * MathUtils.radDeg;
|
||||
@ -172,9 +177,8 @@ class IkConstraint implements Updatable {
|
||||
b = pp.b;
|
||||
c = pp.c;
|
||||
d = pp.d;
|
||||
var id:Float = 1 / (a * d - b * c),
|
||||
x:Float = cwx - pp.worldX,
|
||||
y:Float = cwy - pp.worldY;
|
||||
var id = a * d - b * c, x = cwx - pp.worldX, y = cwy - pp.worldY;
|
||||
id = Math.abs(id) <= 0.0001 ? 0 : 1 / id;
|
||||
var dx:Float = (x * d - y * b) * id - px,
|
||||
dy:Float = (y * a - x * c) * id - py;
|
||||
var l1:Float = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
package spine;
|
||||
|
||||
class Interpolation {
|
||||
private function applyInternal(a:Float):Float {
|
||||
return a;
|
||||
}
|
||||
|
||||
public function apply(start:Float, end:Float, a:Float):Float {
|
||||
return start + (end - start) * applyInternal(a);
|
||||
}
|
||||
}
|
||||
@ -6,9 +6,9 @@ class PathConstraintData extends ConstraintData {
|
||||
private var _bones:Vector<BoneData> = new Vector<BoneData>();
|
||||
|
||||
public var target:SlotData;
|
||||
public var positionMode:PositionMode;
|
||||
public var spacingMode:SpacingMode;
|
||||
public var rotateMode:RotateMode;
|
||||
public var positionMode:PositionMode = PositionMode.fixed;
|
||||
public var spacingMode:SpacingMode = SpacingMode.fixed;
|
||||
public var rotateMode:RotateMode = RotateMode.chain;
|
||||
public var offsetRotation:Float = 0;
|
||||
public var position:Float = 0;
|
||||
public var spacing:Float = 0;
|
||||
|
||||
54
spine-haxe/spine-haxe/spine/Sequence.hx
Normal file
54
spine-haxe/spine-haxe/spine/Sequence.hx
Normal file
@ -0,0 +1,54 @@
|
||||
package spine;
|
||||
|
||||
import openfl.Vector;
|
||||
|
||||
class Sequence {
|
||||
private static var _nextID = 0;
|
||||
|
||||
public var id = _nextID++;
|
||||
public var regions:Vector<TextureRegion>;
|
||||
public var start = 0;
|
||||
public var digits = 0;
|
||||
|
||||
/** The index of the region to show for the setup pose. */
|
||||
public var setupIndex = 0;
|
||||
|
||||
public function new(count:Int) {
|
||||
this.regions = new Vector<TextureRegion>(count);
|
||||
}
|
||||
|
||||
public function copy():Sequence {
|
||||
var copy = new Sequence(this.regions.length);
|
||||
for (i in 0...this.regions.length) {
|
||||
copy.regions[i] = this.regions[i];
|
||||
}
|
||||
copy.start = this.start;
|
||||
copy.digits = this.digits;
|
||||
copy.setupIndex = this.setupIndex;
|
||||
return copy;
|
||||
}
|
||||
|
||||
public function apply(slot:Slot, attachment:HasTextureRegion) {
|
||||
var index:Int = slot.sequenceIndex;
|
||||
if (index == -1)
|
||||
index = this.setupIndex;
|
||||
if (index >= this.regions.length)
|
||||
index = this.regions.length - 1;
|
||||
var region = this.regions[index];
|
||||
if (attachment.region != region) {
|
||||
attachment.region = region;
|
||||
attachment.updateRegion();
|
||||
}
|
||||
}
|
||||
|
||||
public function getPath(basePath:String, index:Int):String {
|
||||
var result = basePath;
|
||||
var frame = Std.string(this.start + index);
|
||||
|
||||
for (i in 0...(this.digits - frame.length)) {
|
||||
result += "0";
|
||||
}
|
||||
result += frame;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
27
spine-haxe/spine-haxe/spine/SequenceMode.hx
Normal file
27
spine-haxe/spine-haxe/spine/SequenceMode.hx
Normal file
@ -0,0 +1,27 @@
|
||||
package spine;
|
||||
|
||||
class SequenceMode {
|
||||
public static var hold(default, never):RotateMode = new SequenceMode("hold");
|
||||
public static var once(default, never):RotateMode = new SequenceMode("once");
|
||||
public static var loop(default, never):RotateMode = new SequenceMode("loop");
|
||||
public static var pingpong(default, never):RotateMode = new SequenceMode("pingpong");
|
||||
public static var onceReverse(default, never):RotateMode = new SequenceMode("onceReverse");
|
||||
public static var loopReverse(default, never):RotateMode = new SequenceMode("loopReverse");
|
||||
public static var pingpongReverse(default, never):RotateMode = new SequenceMode("pingpongReverse");
|
||||
|
||||
public static var values(default, never):Vector<SequenceMode> = Vector.ofArray([tangent, chain, chainScale]);
|
||||
|
||||
public var name(default, null):String;
|
||||
|
||||
public function new(name:String) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static function fromName(name:String):SequenceMode {
|
||||
for (value in values) {
|
||||
if (value.name == name)
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -22,7 +22,6 @@ class Skeleton {
|
||||
private var _skin:Skin;
|
||||
|
||||
public var color:Color = new Color(1, 1, 1, 1);
|
||||
public var time:Float = 0;
|
||||
public var scaleX:Float = 1;
|
||||
public var scaleY:Float = 1;
|
||||
public var x:Float = 0;
|
||||
@ -558,10 +557,6 @@ class Skeleton {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function update(delta:Float):Void {
|
||||
time += delta;
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return _data.name != null ? _data.name : "Skeleton?";
|
||||
}
|
||||
@ -583,7 +578,7 @@ class Skeleton {
|
||||
verticesLength = 8;
|
||||
temp.length = verticesLength;
|
||||
vertices = temp;
|
||||
cast(attachment, RegionAttachment).computeWorldVertices(slot.bone, vertices, 0, 2);
|
||||
cast(attachment, RegionAttachment).computeWorldVertices(slot, vertices, 0, 2);
|
||||
} else if (Std.isOfType(attachment, MeshAttachment)) {
|
||||
var mesh:MeshAttachment = cast(attachment, MeshAttachment);
|
||||
verticesLength = mesh.worldVerticesLength;
|
||||
|
||||
@ -119,7 +119,7 @@ class Skin {
|
||||
public function removeAttachment(slotIndex:Int, name:String):Void {
|
||||
var dictionary:Dictionary<String, Attachment> = _attachments[slotIndex];
|
||||
if (dictionary != null)
|
||||
dictionary[name] = null;
|
||||
dictionary.remove(name);
|
||||
}
|
||||
|
||||
public function getAttachments():Vector<SkinEntry> {
|
||||
|
||||
@ -13,7 +13,8 @@ class Slot {
|
||||
public var darkColor:Color;
|
||||
|
||||
private var _attachment:Attachment;
|
||||
private var _attachmentTime:Float = 0;
|
||||
|
||||
public var sequenceIndex = -1;
|
||||
|
||||
public var attachmentState:Int = 0;
|
||||
public var deform:Vector<Float> = new Vector<Float>();
|
||||
@ -63,26 +64,14 @@ class Slot {
|
||||
return attachmentNew;
|
||||
if (!Std.isOfType(attachmentNew, VertexAttachment)
|
||||
|| !Std.isOfType(attachment, VertexAttachment)
|
||||
|| cast(attachmentNew, VertexAttachment).deformAttachment != cast(attachment, VertexAttachment).deformAttachment) {
|
||||
|| cast(attachmentNew, VertexAttachment).timelineAttachment != cast(attachment, VertexAttachment).timelineAttachment) {
|
||||
deform = new Vector<Float>();
|
||||
}
|
||||
_attachment = attachmentNew;
|
||||
_attachmentTime = skeleton.time;
|
||||
sequenceIndex = -1;
|
||||
return attachmentNew;
|
||||
}
|
||||
|
||||
public var attachmentTime(get, set):Float;
|
||||
|
||||
private function set_attachmentTime(time:Float):Float {
|
||||
_attachmentTime = skeleton.time - time;
|
||||
return _attachmentTime;
|
||||
}
|
||||
|
||||
/** Returns the time since the attachment was set. */
|
||||
private function get_attachmentTime():Float {
|
||||
return skeleton.time - _attachmentTime;
|
||||
}
|
||||
|
||||
public function setToSetupPose():Void {
|
||||
color.setFromColor(data.color);
|
||||
if (darkColor != null)
|
||||
|
||||
@ -10,7 +10,7 @@ class SlotData {
|
||||
public var color:Color = new Color(1, 1, 1, 1);
|
||||
public var darkColor:Color = null;
|
||||
public var attachmentName:String;
|
||||
public var blendMode:BlendMode;
|
||||
public var blendMode:BlendMode = BlendMode.normal;
|
||||
|
||||
public function new(index:Int, name:String, boneData:BoneData) {
|
||||
if (index < 0)
|
||||
|
||||
18
spine-haxe/spine-haxe/spine/TextureRegion.hx
Normal file
18
spine-haxe/spine-haxe/spine/TextureRegion.hx
Normal file
@ -0,0 +1,18 @@
|
||||
package spine;
|
||||
|
||||
class TextureRegion {
|
||||
public var width:Int = 0;
|
||||
public var height:Int = 0;
|
||||
public var u:Float = 0;
|
||||
public var v:Float = 0;
|
||||
public var u2:Float = 0;
|
||||
public var v2:Float = 0;
|
||||
public var degrees:Int = 0;
|
||||
public var offsetX:Float = 0;
|
||||
public var offsetY:Float = 0;
|
||||
public var originalWidth:Int = 0;
|
||||
public var originalHeight:Int = 0;
|
||||
public var texture:Dynamic;
|
||||
|
||||
public function new() {}
|
||||
}
|
||||
@ -43,7 +43,7 @@ class TransformConstraint implements Updatable {
|
||||
}
|
||||
|
||||
public function update():Void {
|
||||
if (mixRotate == 0 && mixX == 0 && mixY == 0 && mixScaleX == 0 && mixScaleX == 0 && mixShearY == 0)
|
||||
if (mixRotate == 0 && mixX == 0 && mixY == 0 && mixScaleX == 0 && mixScaleY == 0 && mixShearY == 0)
|
||||
return;
|
||||
|
||||
if (data.local) {
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
package spine;
|
||||
|
||||
interface VertexEffect {
|
||||
function begin(skeleton:Skeleton):Void;
|
||||
|
||||
function transform(vertex:Vertex):Void;
|
||||
|
||||
function end():Void;
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
package spine.atlas;
|
||||
|
||||
import openfl.Vector;
|
||||
|
||||
class AtlasRegion {
|
||||
public var page:AtlasPage;
|
||||
public var name:String;
|
||||
public var x:Int = 0;
|
||||
public var y:Int = 0;
|
||||
public var width:Int = 0;
|
||||
public var height:Int = 0;
|
||||
public var u:Float = 0;
|
||||
public var v:Float = 0;
|
||||
public var u2:Float = 0;
|
||||
public var v2:Float = 0;
|
||||
public var offsetX:Float = 0;
|
||||
public var offsetY:Float = 0;
|
||||
public var originalWidth:Int = 0;
|
||||
public var originalHeight:Int = 0;
|
||||
public var index:Int = 0;
|
||||
public var degrees:Int = 0;
|
||||
public var splits:Vector<Int>;
|
||||
public var pads:Vector<Int>;
|
||||
public var rendererObject:Dynamic;
|
||||
public var names:Vector<String>;
|
||||
public var values:Vector<Vector<Float>>;
|
||||
|
||||
public function new() {}
|
||||
}
|
||||
@ -5,9 +5,9 @@ import openfl.utils.ByteArray;
|
||||
import openfl.utils.Dictionary;
|
||||
import openfl.Vector;
|
||||
|
||||
class Atlas {
|
||||
private var pages:Vector<AtlasPage> = new Vector<AtlasPage>();
|
||||
private var regions:Vector<AtlasRegion> = new Vector<AtlasRegion>();
|
||||
class TextureAtlas {
|
||||
private var pages = new Vector<TextureAtlasPage>();
|
||||
private var regions = new Vector<TextureAtlasRegion>();
|
||||
private var textureLoader:TextureLoader;
|
||||
|
||||
/** @param object A String or ByteArray. */
|
||||
@ -20,7 +20,7 @@ class Atlas {
|
||||
} else if (Std.isOfType(object, ByteArrayData)) {
|
||||
load(cast(object, ByteArray).readUTFBytes(cast(object, ByteArray).length), textureLoader);
|
||||
} else {
|
||||
throw new ArgumentError("object must be a TextureAtlas or AttachmentLoader.");
|
||||
throw new ArgumentError("object must be a string or ByteArrayData.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,8 +32,8 @@ class Atlas {
|
||||
|
||||
var reader:Reader = new Reader(atlasText);
|
||||
var entry:Vector<String> = new Vector<String>(5, true);
|
||||
var page:AtlasPage = null;
|
||||
var region:AtlasRegion = null;
|
||||
var page:TextureAtlasPage = null;
|
||||
var region:TextureAtlasRegion = null;
|
||||
|
||||
var pageFields:Dictionary<String, Void->Void> = new Dictionary<String, Void->Void>();
|
||||
pageFields["size"] = function():Void {
|
||||
@ -58,12 +58,28 @@ class Atlas {
|
||||
};
|
||||
|
||||
var regionFields:Dictionary<String, Void->Void> = new Dictionary<String, Void->Void>();
|
||||
regionFields["xy"] = function():Void {
|
||||
region.x = Std.parseInt(entry[1]);
|
||||
region.y = Std.parseInt(entry[2]);
|
||||
};
|
||||
regionFields["size"] = function():Void {
|
||||
region.width = Std.parseInt(entry[1]);
|
||||
region.height = Std.parseInt(entry[2]);
|
||||
};
|
||||
regionFields["bounds"] = function():Void {
|
||||
region.x = Std.parseInt(entry[1]);
|
||||
region.y = Std.parseInt(entry[2]);
|
||||
region.width = Std.parseInt(entry[3]);
|
||||
region.height = Std.parseInt(entry[4]);
|
||||
};
|
||||
regionFields["offset"] = function():Void {
|
||||
region.offsetX = Std.parseInt(entry[1]);
|
||||
region.offsetY = Std.parseInt(entry[2]);
|
||||
};
|
||||
regionFields["orig"] = function():Void {
|
||||
region.originalWidth = Std.parseInt(entry[1]);
|
||||
region.originalHeight = Std.parseInt(entry[2]);
|
||||
};
|
||||
regionFields["offsets"] = function():Void {
|
||||
region.offsetX = Std.parseInt(entry[1]);
|
||||
region.offsetY = Std.parseInt(entry[2]);
|
||||
@ -107,8 +123,7 @@ class Atlas {
|
||||
page = null;
|
||||
line = reader.readLine();
|
||||
} else if (page == null) {
|
||||
page = new AtlasPage();
|
||||
page.name = line;
|
||||
page = new TextureAtlasPage(line);
|
||||
while (true) {
|
||||
if (reader.readEntry(entry, line = reader.readLine()) == 0)
|
||||
break;
|
||||
@ -120,9 +135,7 @@ class Atlas {
|
||||
textureLoader.loadPage(page, line);
|
||||
pages.push(page);
|
||||
} else {
|
||||
region = new AtlasRegion();
|
||||
region.page = page;
|
||||
region.name = line;
|
||||
region = new TextureAtlasRegion(page, line);
|
||||
while (true) {
|
||||
var count:Int = reader.readEntry(entry, line = reader.readLine());
|
||||
if (count == 0)
|
||||
@ -149,7 +162,7 @@ class Atlas {
|
||||
region.originalHeight = region.height;
|
||||
}
|
||||
|
||||
if (names != null && names.length > 0) {
|
||||
if (names != null && names.length > 0 && values != null && values.length > 0) {
|
||||
region.names = names;
|
||||
region.values = values;
|
||||
names = null;
|
||||
@ -174,7 +187,7 @@ class Atlas {
|
||||
/** Returns the first region found with the specified name. This method uses string comparison to find the region, so the result
|
||||
* should be cached rather than calling this method multiple times.
|
||||
* @return The region, or null. */
|
||||
public function findRegion(name:String):AtlasRegion {
|
||||
public function findRegion(name:String):TextureAtlasRegion {
|
||||
for (region in regions) {
|
||||
if (region.name == name) {
|
||||
return region;
|
||||
@ -1,16 +1,19 @@
|
||||
package spine.atlas;
|
||||
|
||||
class AtlasPage {
|
||||
class TextureAtlasPage {
|
||||
public var name:String;
|
||||
public var format:Format;
|
||||
public var minFilter:TextureFilter = TextureFilter.nearest;
|
||||
public var magFilter:TextureFilter = TextureFilter.nearest;
|
||||
public var uWrap:TextureWrap = TextureWrap.clampToEdge;
|
||||
public var vWrap:TextureWrap = TextureWrap.clampToEdge;
|
||||
public var width:Int = 0;
|
||||
public var height:Int = 0;
|
||||
public var pma:Bool = false;
|
||||
public var rendererObject:Dynamic;
|
||||
public var width = 0;
|
||||
public var height = 0;
|
||||
public var pma = false;
|
||||
public var texture:Dynamic;
|
||||
public var regions = new Array<TextureAtlasRegion>();
|
||||
|
||||
public function new() {}
|
||||
public function new(name:String) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
22
spine-haxe/spine-haxe/spine/atlas/TextureAtlasRegion.hx
Normal file
22
spine-haxe/spine-haxe/spine/atlas/TextureAtlasRegion.hx
Normal file
@ -0,0 +1,22 @@
|
||||
package spine.atlas;
|
||||
|
||||
import openfl.Vector;
|
||||
|
||||
class TextureAtlasRegion extends TextureRegion {
|
||||
public var page:TextureAtlasPage;
|
||||
public var name:String;
|
||||
public var x:Int = 0;
|
||||
public var y:Int = 0;
|
||||
public var index:Int = 0;
|
||||
public var splits:Vector<Int>;
|
||||
public var pads:Vector<Int>;
|
||||
public var names:Vector<String>;
|
||||
public var values:Vector<Vector<Float>>;
|
||||
|
||||
public function new(page:TextureAtlasPage, name:String) {
|
||||
super();
|
||||
this.page = page;
|
||||
this.name = name;
|
||||
page.regions.push(this);
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,9 @@
|
||||
package spine.atlas;
|
||||
|
||||
interface TextureLoader {
|
||||
function loadPage(page:AtlasPage, path:String):Void;
|
||||
function loadPage(page:TextureAtlasPage, path:String):Void;
|
||||
|
||||
function loadRegion(region:AtlasRegion):Void;
|
||||
function loadRegion(region:TextureAtlasRegion):Void;
|
||||
|
||||
function unloadPage(page:AtlasPage):Void;
|
||||
function unloadPage(page:TextureAtlasPage):Void;
|
||||
}
|
||||
|
||||
@ -1,22 +1,32 @@
|
||||
package spine.attachments;
|
||||
|
||||
import openfl.errors.ArgumentError;
|
||||
import spine.atlas.Atlas;
|
||||
import spine.atlas.AtlasRegion;
|
||||
import spine.atlas.TextureAtlas;
|
||||
import spine.Skin;
|
||||
|
||||
class AtlasAttachmentLoader implements AttachmentLoader {
|
||||
private var atlas:Atlas;
|
||||
private var atlas:TextureAtlas;
|
||||
|
||||
public function new(atlas:Atlas) {
|
||||
public function new(atlas:TextureAtlas) {
|
||||
if (atlas == null) {
|
||||
throw new ArgumentError("atlas cannot be null.");
|
||||
}
|
||||
this.atlas = atlas;
|
||||
}
|
||||
|
||||
private function loadSequence(name:String, basePath:String, sequence:Sequence) {
|
||||
var regions = sequence.regions;
|
||||
for (i in 0...regions.length) {
|
||||
var path = sequence.getPath(basePath, i);
|
||||
var region = this.atlas.findRegion(path);
|
||||
if (region == null)
|
||||
trace("Region not found in atlas: " + path + " (sequence: " + name + ")");
|
||||
regions[i] = region;
|
||||
}
|
||||
}
|
||||
|
||||
public function newRegionAttachment(skin:Skin, name:String, path:String):RegionAttachment {
|
||||
var region:AtlasRegion = atlas.findRegion(path);
|
||||
var region = atlas.findRegion(path);
|
||||
if (region == null) {
|
||||
trace("Region not found in atlas: " + path + " (region attachment: " + name + ")");
|
||||
return null;
|
||||
@ -34,7 +44,7 @@ class AtlasAttachmentLoader implements AttachmentLoader {
|
||||
}
|
||||
|
||||
public function newMeshAttachment(skin:Skin, name:String, path:String):MeshAttachment {
|
||||
var region:AtlasRegion = atlas.findRegion(path);
|
||||
var region = atlas.findRegion(path);
|
||||
if (region == null) {
|
||||
trace("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
|
||||
return null;
|
||||
|
||||
@ -4,10 +4,10 @@ import spine.Skin;
|
||||
|
||||
interface AttachmentLoader {
|
||||
/** @return May be null to not load an attachment. */
|
||||
function newRegionAttachment(skin:Skin, name:String, path:String):RegionAttachment;
|
||||
function newRegionAttachment(skin:Skin, name:String, path:String, sequence:Sequence):RegionAttachment;
|
||||
|
||||
/** @return May be null to not load an attachment. */
|
||||
function newMeshAttachment(skin:Skin, name:String, path:String):MeshAttachment;
|
||||
function newMeshAttachment(skin:Skin, name:String, path:String, sequence:Sequence):MeshAttachment;
|
||||
|
||||
/** @return May be null to not load an attachment. */
|
||||
function newBoundingBoxAttachment(skin:Skin, name:String):BoundingBoxAttachment;
|
||||
|
||||
@ -2,107 +2,95 @@ package spine.attachments;
|
||||
|
||||
import openfl.Vector;
|
||||
import spine.Color;
|
||||
import spine.atlas.TextureAtlasRegion;
|
||||
|
||||
class MeshAttachment extends VertexAttachment {
|
||||
public var uvs:Vector<Float>;
|
||||
public var regionUVs:Vector<Float>;
|
||||
public var triangles:Vector<Int>;
|
||||
class MeshAttachment extends VertexAttachment implements HasTextureRegion {
|
||||
public var region:TextureRegion;
|
||||
public var path:String;
|
||||
public var regionUVs = new Vector<Float>();
|
||||
public var uvs = new Vector<Float>();
|
||||
public var triangles = new Vector<Int>();
|
||||
public var color:Color = new Color(1, 1, 1, 1);
|
||||
public var width:Float = 0;
|
||||
public var height:Float = 0;
|
||||
public var hullLength:Int = 0;
|
||||
public var edges = new Vector<Int>();
|
||||
public var rendererObject:Dynamic;
|
||||
public var sequence:Sequence;
|
||||
|
||||
private var _parentMesh:MeshAttachment;
|
||||
|
||||
public var path:String;
|
||||
public var rendererObject:Dynamic;
|
||||
public var regionU:Float = 0;
|
||||
public var regionV:Float = 0;
|
||||
public var regionU2:Float = 0;
|
||||
public var regionV2:Float = 0;
|
||||
public var regionDegrees:Int = 0;
|
||||
public var regionOffsetX:Float = 0; // Pixels stripped from the bottom left, unrotated.
|
||||
public var regionOffsetY:Float = 0;
|
||||
public var regionWidth:Float = 0; // Unrotated, stripped size.
|
||||
public var regionHeight:Float = 0;
|
||||
public var regionOriginalWidth:Float = 0; // Unrotated, unstripped size.
|
||||
public var regionOriginalHeight:Float = 0;
|
||||
// Nonessential.
|
||||
public var edges:Vector<Int>;
|
||||
public var width:Float = 0;
|
||||
public var height:Float = 0;
|
||||
|
||||
public function new(name:String) {
|
||||
public function new(name:String, path:String) {
|
||||
super(name);
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public function updateUVs():Void {
|
||||
var i:Int = 0, n:Int = regionUVs.length;
|
||||
var u:Float = regionU, v:Float = regionV;
|
||||
var width:Float = 0, height:Float = 0;
|
||||
var textureWidth:Float, textureHeight:Float;
|
||||
if (uvs == null || uvs.length != n)
|
||||
uvs = new Vector<Float>(n, true);
|
||||
|
||||
switch (regionDegrees) {
|
||||
case 90:
|
||||
{
|
||||
textureWidth = regionHeight / (regionU2 - regionU);
|
||||
textureHeight = regionWidth / (regionV2 - regionV);
|
||||
u -= (regionOriginalHeight - regionOffsetY - regionHeight) / textureWidth;
|
||||
v -= (regionOriginalWidth - regionOffsetX - regionWidth) / textureHeight;
|
||||
width = regionOriginalHeight / textureWidth;
|
||||
height = regionOriginalWidth / textureHeight;
|
||||
i = 0;
|
||||
public function updateRegion():Void {
|
||||
if (region == null) {
|
||||
trace("Region not set.");
|
||||
return;
|
||||
}
|
||||
var regionUVs = this.regionUVs;
|
||||
if (uvs.length != regionUVs.length)
|
||||
uvs = new Vector<Float>(regionUVs.length, true);
|
||||
var n = uvs.length;
|
||||
var u = region.u, v = region.v, width:Float = 0, height:Float = 0;
|
||||
if (Std.isOfType(region, TextureAtlasRegion)) {
|
||||
var atlasRegion:TextureAtlasRegion = cast(region, TextureAtlasRegion);
|
||||
var textureWidth = atlasRegion.page.width,
|
||||
textureHeight = atlasRegion.page.height;
|
||||
switch (atlasRegion.degrees) {
|
||||
case 90:
|
||||
u -= (region.originalHeight - region.offsetY - region.height) / textureWidth;
|
||||
v -= (region.originalWidth - region.offsetX - region.width) / textureHeight;
|
||||
width = region.originalHeight / textureWidth;
|
||||
height = region.originalWidth / textureHeight;
|
||||
var i = 0;
|
||||
while (i < n) {
|
||||
uvs[i] = u + regionUVs[i + 1] * width;
|
||||
uvs[i + 1] = v + (1 - regionUVs[i]) * height;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
case 180:
|
||||
{
|
||||
textureWidth = regionWidth / (regionU2 - regionU);
|
||||
textureHeight = regionHeight / (regionV2 - regionV);
|
||||
u -= (regionOriginalWidth - regionOffsetX - regionWidth) / textureWidth;
|
||||
v -= regionOffsetY / textureHeight;
|
||||
width = regionOriginalWidth / textureWidth;
|
||||
height = regionOriginalHeight / textureHeight;
|
||||
i = 0;
|
||||
return;
|
||||
case 180:
|
||||
u -= (region.originalWidth - region.offsetX - region.width) / textureWidth;
|
||||
v -= region.offsetY / textureHeight;
|
||||
width = region.originalWidth / textureWidth;
|
||||
height = region.originalHeight / textureHeight;
|
||||
var i = 0;
|
||||
while (i < n) {
|
||||
uvs[i] = u + (1 - regionUVs[i]) * width;
|
||||
uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
case 270:
|
||||
{
|
||||
textureWidth = regionWidth / (regionU2 - regionU);
|
||||
textureHeight = regionHeight / (regionV2 - regionV);
|
||||
u -= regionOffsetY / textureWidth;
|
||||
v -= regionOffsetX / textureHeight;
|
||||
width = regionOriginalHeight / textureWidth;
|
||||
height = regionOriginalWidth / textureHeight;
|
||||
i = 0;
|
||||
return;
|
||||
case 270:
|
||||
u -= region.offsetY / textureWidth;
|
||||
v -= region.offsetX / textureHeight;
|
||||
width = region.originalHeight / textureWidth;
|
||||
height = region.originalWidth / textureHeight;
|
||||
var i = 0;
|
||||
while (i < n) {
|
||||
uvs[i] = u + (1 - regionUVs[i + 1]) * width;
|
||||
uvs[i + 1] = v + regionUVs[i] * height;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
textureWidth = regionWidth / (regionU2 - regionU);
|
||||
textureHeight = regionHeight / (regionV2 - regionV);
|
||||
u -= regionOffsetX / textureWidth;
|
||||
v -= (regionOriginalHeight - regionOffsetY - regionHeight) / textureHeight;
|
||||
width = regionOriginalWidth / textureWidth;
|
||||
height = regionOriginalHeight / textureHeight;
|
||||
i = 0;
|
||||
while (i < n) {
|
||||
uvs[i] = u + regionUVs[i] * width;
|
||||
uvs[i + 1] = v + regionUVs[i + 1] * height;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
u -= region.offsetX / textureWidth;
|
||||
v -= (region.originalHeight - region.offsetY - region.height) / textureHeight;
|
||||
width = region.originalWidth / textureWidth;
|
||||
height = region.originalHeight / textureHeight;
|
||||
} else if (region == null) {
|
||||
u = v = 0;
|
||||
width = height = 1;
|
||||
} else {
|
||||
width = this.region.u2 - u;
|
||||
height = this.region.v2 - v;
|
||||
}
|
||||
var i = 0;
|
||||
while (i < n) {
|
||||
uvs[i] = u + regionUVs[i] * width;
|
||||
uvs[i + 1] = v + regionUVs[i + 1] * height;
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,62 +117,46 @@ class MeshAttachment extends VertexAttachment {
|
||||
}
|
||||
|
||||
override public function copy():Attachment {
|
||||
var copy:MeshAttachment = new MeshAttachment(name);
|
||||
copy.rendererObject = rendererObject;
|
||||
copy.regionU = regionU;
|
||||
copy.regionV = regionV;
|
||||
copy.regionU2 = regionU2;
|
||||
copy.regionV2 = regionV2;
|
||||
copy.regionDegrees = regionDegrees;
|
||||
copy.regionOffsetX = regionOffsetX;
|
||||
copy.regionOffsetY = regionOffsetY;
|
||||
copy.regionWidth = regionWidth;
|
||||
copy.regionHeight = regionHeight;
|
||||
copy.regionOriginalWidth = regionOriginalWidth;
|
||||
copy.regionOriginalHeight = regionOriginalHeight;
|
||||
copy.path = path;
|
||||
if (parentMesh != null)
|
||||
return newLinkedMesh();
|
||||
|
||||
var copy:MeshAttachment = new MeshAttachment(name, this.path);
|
||||
copy.region = region;
|
||||
copy.color.setFromColor(color);
|
||||
copy.rendererObject = rendererObject;
|
||||
|
||||
if (parentMesh == null) {
|
||||
this.copyTo(copy);
|
||||
copy.regionUVs = regionUVs.concat();
|
||||
copy.uvs = uvs.concat();
|
||||
copy.triangles = triangles.concat();
|
||||
copy.hullLength = hullLength;
|
||||
this.copyTo(copy);
|
||||
copy.regionUVs = regionUVs.concat();
|
||||
copy.uvs = uvs.concat();
|
||||
copy.triangles = triangles.concat();
|
||||
copy.hullLength = hullLength;
|
||||
|
||||
// Nonessential.
|
||||
if (edges != null) {
|
||||
copy.edges = edges.concat();
|
||||
}
|
||||
copy.width = width;
|
||||
copy.height = height;
|
||||
} else {
|
||||
copy.parentMesh = parentMesh;
|
||||
copy.updateUVs();
|
||||
copy.sequence = sequence != null ? sequence.copy() : null;
|
||||
|
||||
if (edges != null) {
|
||||
copy.edges = edges.concat();
|
||||
}
|
||||
copy.width = width;
|
||||
copy.height = height;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
public override function computeWorldVertices(slot:Slot, start:Int, count:Int, worldVertices:Vector<Float>, offset:Int, stride:Int):Void {
|
||||
if (sequence != null)
|
||||
sequence.apply(slot, this);
|
||||
super.computeWorldVertices(slot, start, count, worldVertices, offset, stride);
|
||||
}
|
||||
|
||||
public function newLinkedMesh():MeshAttachment {
|
||||
var copy:MeshAttachment = new MeshAttachment(name);
|
||||
var copy:MeshAttachment = new MeshAttachment(name, path);
|
||||
copy.rendererObject = rendererObject;
|
||||
copy.regionU = regionU;
|
||||
copy.regionV = regionV;
|
||||
copy.regionU2 = regionU2;
|
||||
copy.regionV2 = regionV2;
|
||||
copy.regionDegrees = regionDegrees;
|
||||
copy.regionOffsetX = regionOffsetX;
|
||||
copy.regionOffsetY = regionOffsetY;
|
||||
copy.regionWidth = regionWidth;
|
||||
copy.regionHeight = regionHeight;
|
||||
copy.regionOriginalWidth = regionOriginalWidth;
|
||||
copy.regionOriginalHeight = regionOriginalHeight;
|
||||
copy.path = path;
|
||||
copy.region = region;
|
||||
copy.color.setFromColor(color);
|
||||
copy.deformAttachment = deformAttachment;
|
||||
copy.parentMesh = parentMesh != null ? parentMesh : this;
|
||||
copy.updateUVs();
|
||||
copy.timelineAttachment = timelineAttachment;
|
||||
copy.parentMesh = this.parentMesh != null ? this.parentMesh : this;
|
||||
if (copy.region != null)
|
||||
copy.updateRegion();
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import openfl.Vector;
|
||||
import spine.Bone;
|
||||
import spine.Color;
|
||||
|
||||
class RegionAttachment extends Attachment {
|
||||
class RegionAttachment extends Attachment implements HasTextureRegion {
|
||||
public static inline var BLX:Int = 0;
|
||||
public static inline var BLY:Int = 1;
|
||||
public static inline var ULX:Int = 2;
|
||||
@ -24,49 +24,79 @@ class RegionAttachment extends Attachment {
|
||||
public var color:Color = new Color(1, 1, 1, 1);
|
||||
public var path:String;
|
||||
public var rendererObject:Dynamic;
|
||||
public var regionOffsetX:Float = 0; // Pixels stripped from the bottom left, unrotated.
|
||||
public var regionOffsetY:Float = 0;
|
||||
public var regionWidth:Float = 0; // Unrotated, stripped size.
|
||||
public var regionHeight:Float = 0;
|
||||
public var regionOriginalWidth:Float = 0; // Unrotated, unstripped size.
|
||||
public var regionOriginalHeight:Float = 0;
|
||||
public var region:TextureRegion;
|
||||
public var sequence:Sequence;
|
||||
|
||||
private var offsets:Vector<Float> = new Vector<Float>(8, true);
|
||||
|
||||
public var uvs:Vector<Float> = new Vector<Float>(8, true);
|
||||
|
||||
public function new(name:String) {
|
||||
public function new(name:String, path:String) {
|
||||
super(name);
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public function updateOffset():Void {
|
||||
var regionScaleX:Float = width / regionOriginalWidth * scaleX;
|
||||
var regionScaleY:Float = height / regionOriginalHeight * scaleY;
|
||||
var localX:Float = -width * 0.5 * scaleX + regionOffsetX * regionScaleX;
|
||||
var localY:Float = -height * 0.5 * scaleY + regionOffsetY * regionScaleY;
|
||||
var localX2:Float = localX + regionWidth * regionScaleX;
|
||||
var localY2:Float = localY + regionHeight * regionScaleY;
|
||||
public function updateRegion():Void {
|
||||
if (region == null) {
|
||||
trace("Region not set.");
|
||||
uvs[0] = 0;
|
||||
uvs[1] = 0;
|
||||
uvs[2] = 0;
|
||||
uvs[3] = 1;
|
||||
uvs[4] = 1;
|
||||
uvs[5] = 1;
|
||||
uvs[6] = 1;
|
||||
uvs[7] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
var radians:Float = rotation * MathUtils.degRad;
|
||||
var cos:Float = Math.cos(radians);
|
||||
var sin:Float = Math.sin(radians);
|
||||
var localXCos:Float = localX * cos + x;
|
||||
var localXSin:Float = localX * sin;
|
||||
var localYCos:Float = localY * cos + y;
|
||||
var localYSin:Float = localY * sin;
|
||||
var localX2Cos:Float = localX2 * cos + x;
|
||||
var localX2Sin:Float = localX2 * sin;
|
||||
var localY2Cos:Float = localY2 * cos + y;
|
||||
var localY2Sin:Float = localY2 * sin;
|
||||
var regionScaleX = width / region.originalWidth * scaleX;
|
||||
var regionScaleY = height / region.originalHeight * scaleY;
|
||||
var localX = -width / 2 * scaleX + region.offsetX * regionScaleX;
|
||||
var localY = -height / 2 * scaleY + region.offsetY * regionScaleY;
|
||||
var localX2 = localX + region.width * regionScaleX;
|
||||
var localY2 = localY + region.height * regionScaleY;
|
||||
var radians = rotation * Math.PI / 180;
|
||||
var cos = Math.cos(radians);
|
||||
var sin = Math.sin(radians);
|
||||
var x = this.x, y = this.y;
|
||||
var localXCos = localX * cos + x;
|
||||
var localXSin = localX * sin;
|
||||
var localYCos = localY * cos + y;
|
||||
var localYSin = localY * sin;
|
||||
var localX2Cos = localX2 * cos + x;
|
||||
var localX2Sin = localX2 * sin;
|
||||
var localY2Cos = localY2 * cos + y;
|
||||
var localY2Sin = localY2 * sin;
|
||||
|
||||
offsets[BLX] = localXCos - localYSin;
|
||||
offsets[BLY] = localYCos + localXSin;
|
||||
offsets[ULX] = localXCos - localY2Sin;
|
||||
offsets[ULY] = localY2Cos + localXSin;
|
||||
offsets[URX] = localX2Cos - localY2Sin;
|
||||
offsets[URY] = localY2Cos + localX2Sin;
|
||||
offsets[BRX] = localX2Cos - localYSin;
|
||||
offsets[BRY] = localYCos + localX2Sin;
|
||||
offsets[0] = localXCos - localYSin;
|
||||
offsets[1] = localYCos + localXSin;
|
||||
offsets[2] = localXCos - localY2Sin;
|
||||
offsets[3] = localY2Cos + localXSin;
|
||||
offsets[4] = localX2Cos - localY2Sin;
|
||||
offsets[5] = localY2Cos + localX2Sin;
|
||||
offsets[6] = localX2Cos - localYSin;
|
||||
offsets[7] = localYCos + localX2Sin;
|
||||
|
||||
if (region.degrees == 90) {
|
||||
uvs[0] = region.u2;
|
||||
uvs[1] = region.v2;
|
||||
uvs[2] = region.u;
|
||||
uvs[3] = region.v2;
|
||||
uvs[4] = region.u;
|
||||
uvs[5] = region.v;
|
||||
uvs[6] = region.u2;
|
||||
uvs[7] = region.v;
|
||||
} else {
|
||||
uvs[0] = region.u;
|
||||
uvs[1] = region.v2;
|
||||
uvs[2] = region.u;
|
||||
uvs[3] = region.v;
|
||||
uvs[4] = region.u2;
|
||||
uvs[5] = region.v;
|
||||
uvs[6] = region.u2;
|
||||
uvs[7] = region.v2;
|
||||
}
|
||||
}
|
||||
|
||||
public function setUVs(u:Float, v:Float, u2:Float, v2:Float, degrees:Int):Void {
|
||||
@ -91,48 +121,44 @@ class RegionAttachment extends Attachment {
|
||||
}
|
||||
}
|
||||
|
||||
public function computeWorldVertices(bone:Bone, worldVertices:Vector<Float>, offset:Int, stride:Int):Void {
|
||||
var x:Float = bone.worldX, y:Float = bone.worldY;
|
||||
var a:Float = bone.a,
|
||||
b:Float = bone.b,
|
||||
c:Float = bone.c,
|
||||
d:Float = bone.d;
|
||||
public function computeWorldVertices(slot:Slot, worldVertices:Vector<Float>, offset:Int, stride:Int):Void {
|
||||
if (sequence != null)
|
||||
sequence.apply(slot, this);
|
||||
|
||||
var bone = slot.bone;
|
||||
var vertexOffset = this.offsets;
|
||||
var x = bone.worldX, y = bone.worldY;
|
||||
var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
||||
var offsetX:Float = 0, offsetY:Float = 0;
|
||||
|
||||
offsetX = offsets[BRX];
|
||||
offsetY = offsets[BRY];
|
||||
offsetX = vertexOffset[0];
|
||||
offsetY = vertexOffset[1];
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x; // br
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
|
||||
offset += stride;
|
||||
|
||||
offsetX = offsets[BLX];
|
||||
offsetY = offsets[BLY];
|
||||
offsetX = vertexOffset[2];
|
||||
offsetY = vertexOffset[3];
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x; // bl
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
|
||||
offset += stride;
|
||||
|
||||
offsetX = offsets[ULX];
|
||||
offsetY = offsets[ULY];
|
||||
offsetX = vertexOffset[4];
|
||||
offsetY = vertexOffset[5];
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x; // ul
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
|
||||
offset += stride;
|
||||
|
||||
offsetX = offsets[URX];
|
||||
offsetY = offsets[URY];
|
||||
offsetX = vertexOffset[6];
|
||||
offsetY = vertexOffset[7];
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x; // ur
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
|
||||
}
|
||||
|
||||
override public function copy():Attachment {
|
||||
var copy:RegionAttachment = new RegionAttachment(name);
|
||||
copy.regionWidth = regionWidth;
|
||||
copy.regionHeight = regionHeight;
|
||||
copy.regionOffsetX = regionOffsetX;
|
||||
copy.regionOffsetY = regionOffsetY;
|
||||
copy.regionOriginalWidth = regionOriginalWidth;
|
||||
copy.regionOriginalHeight = regionOriginalHeight;
|
||||
var copy:RegionAttachment = new RegionAttachment(name, path);
|
||||
copy.region = region;
|
||||
copy.rendererObject = rendererObject;
|
||||
copy.path = path;
|
||||
copy.x = x;
|
||||
copy.y = y;
|
||||
copy.scaleX = scaleX;
|
||||
@ -143,6 +169,7 @@ class RegionAttachment extends Attachment {
|
||||
copy.uvs = uvs.concat();
|
||||
copy.offsets = offsets.concat();
|
||||
copy.color.setFromColor(color);
|
||||
copy.sequence = sequence != null ? sequence.copy() : null;
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,14 +9,14 @@ class VertexAttachment extends Attachment {
|
||||
private static var nextID:Int = 0;
|
||||
|
||||
public var bones:Vector<Int>;
|
||||
public var vertices:Vector<Float>;
|
||||
public var vertices = new Vector<Float>();
|
||||
public var worldVerticesLength:Int = 0;
|
||||
public var id:Int = nextID++;
|
||||
public var deformAttachment:VertexAttachment;
|
||||
public var timelineAttachment:VertexAttachment;
|
||||
|
||||
public function new(name:String) {
|
||||
super(name);
|
||||
deformAttachment = this;
|
||||
timelineAttachment = this;
|
||||
}
|
||||
|
||||
/** Transforms the attachment's local {@link #vertices} to world coordinates. If the slot's {@link Slot#deform} is
|
||||
@ -130,11 +130,9 @@ class VertexAttachment extends Attachment {
|
||||
|
||||
if (this.vertices != null) {
|
||||
attachment.vertices = vertices.concat();
|
||||
} else {
|
||||
attachment.vertices = null;
|
||||
}
|
||||
|
||||
attachment.worldVerticesLength = worldVerticesLength;
|
||||
attachment.deformAttachment = deformAttachment;
|
||||
attachment.timelineAttachment = timelineAttachment;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import openfl.geom.Matrix;
|
||||
import openfl.geom.Point;
|
||||
import openfl.geom.Rectangle;
|
||||
import openfl.Vector;
|
||||
import spine.atlas.AtlasRegion;
|
||||
import spine.atlas.TextureAtlasRegion;
|
||||
import spine.attachments.Attachment;
|
||||
import spine.attachments.ClippingAttachment;
|
||||
import spine.attachments.MeshAttachment;
|
||||
@ -15,7 +15,6 @@ import spine.Skeleton;
|
||||
import spine.SkeletonClipping;
|
||||
import spine.SkeletonData;
|
||||
import spine.Slot;
|
||||
import spine.VertexEffect;
|
||||
import starling.display.BlendMode;
|
||||
import starling.display.DisplayObject;
|
||||
import starling.display.Image;
|
||||
@ -37,11 +36,8 @@ class SkeletonSprite extends DisplayObject {
|
||||
private static var clipper:SkeletonClipping = new SkeletonClipping();
|
||||
private static var QUAD_INDICES:Vector<Int> = Vector.ofArray([0, 1, 2, 2, 3, 0]);
|
||||
|
||||
public var vertexEffect:VertexEffect;
|
||||
|
||||
private var tempLight:spine.Color = new spine.Color(0, 0, 0);
|
||||
private var tempDark:spine.Color = new spine.Color(0, 0, 0);
|
||||
private var tempVertex:spine.Vertex = new spine.Vertex();
|
||||
|
||||
public function new(skeletonData:SkeletonData) {
|
||||
super();
|
||||
@ -71,9 +67,6 @@ class SkeletonSprite extends DisplayObject {
|
||||
var vertexData:VertexData;
|
||||
var uvs:Vector<Float>;
|
||||
|
||||
if (vertexEffect != null)
|
||||
vertexEffect.begin(skeleton);
|
||||
|
||||
for (slot in drawOrder) {
|
||||
if (!slot.bone.active) {
|
||||
clipper.clipEndWithSlot(slot);
|
||||
@ -96,8 +89,8 @@ class SkeletonSprite extends DisplayObject {
|
||||
} else {
|
||||
if (Std.isOfType(region.rendererObject, Image)) {
|
||||
region.rendererObject = mesh = new SkeletonMesh(cast(region.rendererObject, Image).texture);
|
||||
} else if (Std.isOfType(region.rendererObject, AtlasRegion)) {
|
||||
region.rendererObject = mesh = new SkeletonMesh(cast(cast(region.rendererObject, AtlasRegion).rendererObject, Image).texture);
|
||||
} else if (Std.isOfType(region.rendererObject, TextureAtlasRegion)) {
|
||||
region.rendererObject = mesh = new SkeletonMesh(cast(region.rendererObject, TextureAtlasRegion).texture);
|
||||
}
|
||||
|
||||
indexData = mesh.getIndexData();
|
||||
@ -127,9 +120,8 @@ class SkeletonSprite extends DisplayObject {
|
||||
} else {
|
||||
if (Std.isOfType(meshAttachment.rendererObject, Image)) {
|
||||
meshAttachment.rendererObject = mesh = new SkeletonMesh(cast(meshAttachment.rendererObject, Image).texture);
|
||||
} else if (Std.isOfType(meshAttachment.rendererObject, AtlasRegion)) {
|
||||
meshAttachment.rendererObject = mesh = new SkeletonMesh(cast(cast(meshAttachment.rendererObject, AtlasRegion).rendererObject, Image)
|
||||
.texture);
|
||||
} else if (Std.isOfType(meshAttachment.rendererObject, TextureAtlasRegion)) {
|
||||
meshAttachment.rendererObject = mesh = new SkeletonMesh(cast(meshAttachment.rendererObject, TextureAtlasRegion).texture);
|
||||
}
|
||||
|
||||
indexData = mesh.getIndexData();
|
||||
@ -189,39 +181,12 @@ class SkeletonSprite extends DisplayObject {
|
||||
|
||||
vertexData = mesh.getVertexData();
|
||||
vertexData.numVertices = verticesCount;
|
||||
if (vertexEffect != null) {
|
||||
tempLight.r = ((rgb >> 16) & 0xff) / 255.0;
|
||||
tempLight.g = ((rgb >> 8) & 0xff) / 255.0;
|
||||
tempLight.b = (rgb & 0xff) / 255.0;
|
||||
tempLight.a = a;
|
||||
tempDark.r = ((dark >> 16) & 0xff) / 255.0;
|
||||
tempDark.g = ((dark >> 8) & 0xff) / 255.0;
|
||||
tempDark.b = (dark & 0xff) / 255.0;
|
||||
tempDark.a = 0;
|
||||
var ii:Int = 0;
|
||||
for (i in 0...verticesCount) {
|
||||
tempVertex.x = worldVertices[ii];
|
||||
tempVertex.y = worldVertices[ii + 1];
|
||||
tempVertex.u = uvs[ii];
|
||||
tempVertex.v = uvs[ii + 1];
|
||||
tempVertex.light.setFromColor(tempLight);
|
||||
tempVertex.dark.setFromColor(tempDark);
|
||||
vertexEffect.transform(tempVertex);
|
||||
vertexData.colorize("color",
|
||||
Color.rgb(Std.int(tempVertex.light.r * 255), Std.int(tempVertex.light.g * 255), Std.int(tempVertex.light.b * 255)),
|
||||
tempVertex.light.a, i, 1);
|
||||
mesh.setVertexPosition(i, tempVertex.x, tempVertex.y);
|
||||
mesh.setTexCoords(i, tempVertex.u, tempVertex.v);
|
||||
ii += 2;
|
||||
}
|
||||
} else {
|
||||
vertexData.colorize("color", rgb, a);
|
||||
var ii:Int = 0;
|
||||
for (i in 0...verticesCount) {
|
||||
mesh.setVertexPosition(i, worldVertices[ii], worldVertices[ii + 1]);
|
||||
mesh.setTexCoords(i, uvs[ii], uvs[ii + 1]);
|
||||
ii += 2;
|
||||
}
|
||||
vertexData.colorize("color", rgb, a);
|
||||
var ii:Int = 0;
|
||||
for (i in 0...verticesCount) {
|
||||
mesh.setVertexPosition(i, worldVertices[ii], worldVertices[ii + 1]);
|
||||
mesh.setTexCoords(i, uvs[ii], uvs[ii + 1]);
|
||||
ii += 2;
|
||||
}
|
||||
|
||||
if (indexData.numIndices > 0 && vertexData.numVertices > 0) {
|
||||
@ -233,9 +198,6 @@ class SkeletonSprite extends DisplayObject {
|
||||
}
|
||||
painter.state.blendMode = originalBlendMode;
|
||||
clipper.clipEnd();
|
||||
|
||||
if (vertexEffect != null)
|
||||
vertexEffect.end();
|
||||
}
|
||||
|
||||
override public function hitTest(localPoint:Point):DisplayObject {
|
||||
|
||||
@ -4,8 +4,8 @@ import openfl.display.Bitmap;
|
||||
import openfl.display.BitmapData;
|
||||
import openfl.errors.ArgumentError;
|
||||
import openfl.utils.Object;
|
||||
import spine.atlas.AtlasPage;
|
||||
import spine.atlas.AtlasRegion;
|
||||
import spine.atlas.TextureAtlasPage;
|
||||
import spine.atlas.TextureAtlasRegion;
|
||||
import spine.atlas.TextureLoader;
|
||||
import starling.display.Image;
|
||||
import starling.textures.Texture;
|
||||
@ -46,37 +46,39 @@ class StarlingTextureLoader implements TextureLoader {
|
||||
}
|
||||
}
|
||||
|
||||
public function loadPage(page:AtlasPage, path:String):Void {
|
||||
public function loadPage(page:TextureAtlasPage, path:String):Void {
|
||||
var bitmapDataOrTexture:Dynamic = singleBitmapDataOrTexture != null ? singleBitmapDataOrTexture : bitmapDatasOrTextures[path];
|
||||
if (bitmapDataOrTexture == null) {
|
||||
throw new ArgumentError("BitmapData/Texture not found with name: " + path);
|
||||
}
|
||||
if (Std.isOfType(bitmapDataOrTexture, BitmapData)) {
|
||||
var bitmapData:BitmapData = cast(bitmapDataOrTexture, BitmapData);
|
||||
page.rendererObject = Texture.fromBitmapData(bitmapData);
|
||||
page.texture = Texture.fromBitmapData(bitmapData);
|
||||
} else {
|
||||
var texture:Texture = cast(bitmapDataOrTexture, Texture);
|
||||
page.rendererObject = texture;
|
||||
page.texture = texture;
|
||||
}
|
||||
}
|
||||
|
||||
public function loadRegion(region:AtlasRegion):Void {
|
||||
var image:Image = new Image(cast(region.page.rendererObject, Texture));
|
||||
if (region.degrees == 90) {
|
||||
image.setTexCoords(0, region.u, region.v2);
|
||||
image.setTexCoords(1, region.u, region.v);
|
||||
image.setTexCoords(2, region.u2, region.v2);
|
||||
image.setTexCoords(3, region.u2, region.v);
|
||||
} else {
|
||||
image.setTexCoords(0, region.u, region.v);
|
||||
image.setTexCoords(1, region.u2, region.v);
|
||||
image.setTexCoords(2, region.u, region.v2);
|
||||
image.setTexCoords(3, region.u2, region.v2);
|
||||
}
|
||||
region.rendererObject = image;
|
||||
public function loadRegion(region:TextureAtlasRegion):Void {
|
||||
// FIXME rotation shouldn't be implemented like this
|
||||
/*var image:Image = new Image(cast(region.page.texture, Texture));
|
||||
if (region.degrees == 90) {
|
||||
image.setTexCoords(0, region.u, region.v2);
|
||||
image.setTexCoords(1, region.u, region.v);
|
||||
image.setTexCoords(2, region.u2, region.v2);
|
||||
image.setTexCoords(3, region.u2, region.v);
|
||||
} else {
|
||||
image.setTexCoords(0, region.u, region.v);
|
||||
image.setTexCoords(1, region.u2, region.v);
|
||||
image.setTexCoords(2, region.u, region.v2);
|
||||
image.setTexCoords(3, region.u2, region.v2);
|
||||
}
|
||||
region.texture = image; */
|
||||
region.texture = region.page.texture;
|
||||
}
|
||||
|
||||
public function unloadPage(page:AtlasPage):Void {
|
||||
cast(page.rendererObject, Texture).dispose();
|
||||
public function unloadPage(page:TextureAtlasPage):Void {
|
||||
cast(page.texture, Texture).dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
package spine.vertexeffects;
|
||||
|
||||
import spine.MathUtils;
|
||||
import spine.Skeleton;
|
||||
import spine.Vertex;
|
||||
import spine.VertexEffect;
|
||||
|
||||
class JitterEffect implements VertexEffect {
|
||||
public var jitterX:Float = 0;
|
||||
public var jitterY:Float = 0;
|
||||
|
||||
public function new(jitterX:Float, jitterY:Float) {
|
||||
this.jitterX = jitterX;
|
||||
this.jitterY = jitterY;
|
||||
}
|
||||
|
||||
public function begin(skeleton:Skeleton):Void {}
|
||||
|
||||
public function transform(vertex:Vertex):Void {
|
||||
vertex.x += MathUtils.randomTriangular(-jitterX, jitterY);
|
||||
vertex.y += MathUtils.randomTriangular(-jitterX, jitterY);
|
||||
}
|
||||
|
||||
public function end():Void {}
|
||||
}
|
||||
@ -1,97 +0,0 @@
|
||||
package spine.vertexeffects;
|
||||
|
||||
import spine.interpolation.Pow;
|
||||
import spine.Interpolation;
|
||||
import spine.MathUtils;
|
||||
import spine.Skeleton;
|
||||
import spine.Vertex;
|
||||
import spine.VertexEffect;
|
||||
|
||||
class SwirlEffect implements VertexEffect {
|
||||
private var worldX:Float = 0;
|
||||
private var worldY:Float = 0;
|
||||
private var _radius:Float = 0;
|
||||
private var _angle:Float = 0;
|
||||
private var _interpolation:Interpolation;
|
||||
private var _centerX:Float = 0;
|
||||
private var _centerY:Float = 0;
|
||||
|
||||
public function new(radius:Float) {
|
||||
this._interpolation = new Pow(2);
|
||||
this._radius = radius;
|
||||
}
|
||||
|
||||
public function begin(skeleton:Skeleton):Void {
|
||||
worldX = skeleton.x + _centerX;
|
||||
worldY = skeleton.y + _centerY;
|
||||
}
|
||||
|
||||
public function transform(vertex:Vertex):Void {
|
||||
var x:Float = vertex.x - worldX;
|
||||
var y:Float = vertex.y - worldY;
|
||||
var dist:Float = Math.sqrt(x * x + y * y);
|
||||
if (dist < radius) {
|
||||
var theta:Float = interpolation.apply(0, angle, (radius - dist) / radius);
|
||||
var cos:Float = Math.cos(theta), sin:Float = Math.sin(theta);
|
||||
vertex.x = cos * x - sin * y + worldX;
|
||||
vertex.y = sin * x + cos * y + worldY;
|
||||
}
|
||||
}
|
||||
|
||||
public function end():Void {}
|
||||
|
||||
public var radius(get, set):Float;
|
||||
|
||||
private function get_radius():Float {
|
||||
return _radius;
|
||||
}
|
||||
|
||||
private function set_radius(radius:Float):Float {
|
||||
_radius = radius;
|
||||
return _radius;
|
||||
}
|
||||
|
||||
public var angle(get, set):Float;
|
||||
|
||||
private function get_angle():Float {
|
||||
return _angle;
|
||||
}
|
||||
|
||||
private function set_angle(angle:Float):Float {
|
||||
_angle = angle * MathUtils.degRad;
|
||||
return _angle;
|
||||
}
|
||||
|
||||
public var centerX(get, set):Float;
|
||||
|
||||
private function get_centerX():Float {
|
||||
return _centerX;
|
||||
}
|
||||
|
||||
private function set_centerX(centerX:Float):Float {
|
||||
_centerX = centerX;
|
||||
return _centerX;
|
||||
}
|
||||
|
||||
public var centerY(get, set):Float;
|
||||
|
||||
private function get_centerY():Float {
|
||||
return _centerY;
|
||||
}
|
||||
|
||||
private function set_centerY(centerY:Float):Float {
|
||||
_centerY = centerY;
|
||||
return _centerY;
|
||||
}
|
||||
|
||||
public var interpolation(get, set):Interpolation;
|
||||
|
||||
private function get_interpolation():Interpolation {
|
||||
return _interpolation;
|
||||
}
|
||||
|
||||
private function set_interpolation(interpolation:Interpolation):Interpolation {
|
||||
_interpolation = interpolation;
|
||||
return _interpolation;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user