diff --git a/CHANGELOG.md b/CHANGELOG.md index fbe7a6b52..df1472f66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -124,6 +124,8 @@ ### Love2D ### Corona +* **Breaking changes** +* spine-corona has been renamed to spine-solar2d. Change your `require "spine-corona.spine"` statements to `require "spine-solar2d.spine"` ## Typescript/Javascript * **Breaking changes** diff --git a/examples/export/runtimes.sh b/examples/export/runtimes.sh index 0435907a4..451363beb 100755 --- a/examples/export/runtimes.sh +++ b/examples/export/runtimes.sh @@ -118,43 +118,43 @@ cp -f ../mix-and-match/export/mix-and-match.atlas "$ROOT/spine-cocos2dx/example- cp -f ../mix-and-match/export/mix-and-match.png "$ROOT/spine-cocos2dx/example-v4/Resources/common/" -echo "spine-corona" -rm "$ROOT/spine-corona/data/"* -cp -f ../coin/export/coin-pro.json "$ROOT/spine-corona/data" -cp -f ../coin/export/coin.atlas "$ROOT/spine-corona/data" -cp -f ../coin/export/coin.png "$ROOT/spine-corona/data" +echo "spine-solar2d" +rm "$ROOT/spine-solar2d/data/"* +cp -f ../coin/export/coin-pro.json "$ROOT/spine-solar2d/data" +cp -f ../coin/export/coin.atlas "$ROOT/spine-solar2d/data" +cp -f ../coin/export/coin.png "$ROOT/spine-solar2d/data" -cp -f ../goblins/export/goblins-pro.json "$ROOT/spine-corona/data" -cp -f ../goblins/export/goblins.atlas "$ROOT/spine-corona/data" -cp -f ../goblins/export/goblins.png "$ROOT/spine-corona/data" +cp -f ../goblins/export/goblins-pro.json "$ROOT/spine-solar2d/data" +cp -f ../goblins/export/goblins.atlas "$ROOT/spine-solar2d/data" +cp -f ../goblins/export/goblins.png "$ROOT/spine-solar2d/data" -cp -f ../raptor/export/raptor-pro.json "$ROOT/spine-corona/data" -cp -f ../raptor/export/raptor.atlas "$ROOT/spine-corona/data" -cp -f ../raptor/export/raptor.png "$ROOT/spine-corona/data" +cp -f ../raptor/export/raptor-pro.json "$ROOT/spine-solar2d/data" +cp -f ../raptor/export/raptor.atlas "$ROOT/spine-solar2d/data" +cp -f ../raptor/export/raptor.png "$ROOT/spine-solar2d/data" -cp -f ../spineboy/export/spineboy-pro.json "$ROOT/spine-corona/data" -cp -f ../spineboy/export/spineboy.atlas "$ROOT/spine-corona/data" -cp -f ../spineboy/export/spineboy.png "$ROOT/spine-corona/data" +cp -f ../spineboy/export/spineboy-pro.json "$ROOT/spine-solar2d/data" +cp -f ../spineboy/export/spineboy.atlas "$ROOT/spine-solar2d/data" +cp -f ../spineboy/export/spineboy.png "$ROOT/spine-solar2d/data" -cp -f ../tank/export/tank-pro.json "$ROOT/spine-corona/data" -cp -f ../tank/export/tank.atlas "$ROOT/spine-corona/data" -cp -f ../tank/export/tank.png "$ROOT/spine-corona/data" +cp -f ../tank/export/tank-pro.json "$ROOT/spine-solar2d/data" +cp -f ../tank/export/tank.atlas "$ROOT/spine-solar2d/data" +cp -f ../tank/export/tank.png "$ROOT/spine-solar2d/data" -cp -f ../vine/export/vine-pro.json "$ROOT/spine-corona/data" -cp -f ../vine/export/vine.atlas "$ROOT/spine-corona/data" -cp -f ../vine/export/vine.png "$ROOT/spine-corona/data" +cp -f ../vine/export/vine-pro.json "$ROOT/spine-solar2d/data" +cp -f ../vine/export/vine.atlas "$ROOT/spine-solar2d/data" +cp -f ../vine/export/vine.png "$ROOT/spine-solar2d/data" -cp -f ../stretchyman/export/stretchyman-pro.json "$ROOT/spine-corona/data" -cp -f ../stretchyman/export/stretchyman.atlas "$ROOT/spine-corona/data" -cp -f ../stretchyman/export/stretchyman.png "$ROOT/spine-corona/data" +cp -f ../stretchyman/export/stretchyman-pro.json "$ROOT/spine-solar2d/data" +cp -f ../stretchyman/export/stretchyman.atlas "$ROOT/spine-solar2d/data" +cp -f ../stretchyman/export/stretchyman.png "$ROOT/spine-solar2d/data" -cp -f ../owl/export/owl-pro.json "$ROOT/spine-corona/data" -cp -f ../owl/export/owl.atlas "$ROOT/spine-corona/data" -cp -f ../owl/export/owl.png "$ROOT/spine-corona/data" +cp -f ../owl/export/owl-pro.json "$ROOT/spine-solar2d/data" +cp -f ../owl/export/owl.atlas "$ROOT/spine-solar2d/data" +cp -f ../owl/export/owl.png "$ROOT/spine-solar2d/data" -cp -f ../mix-and-match/export/mix-and-match-pro.json "$ROOT/spine-corona/data" -cp -f ../mix-and-match/export/mix-and-match.atlas "$ROOT/spine-corona/data" -cp -f ../mix-and-match/export/mix-and-match.png "$ROOT/spine-corona/data" +cp -f ../mix-and-match/export/mix-and-match-pro.json "$ROOT/spine-solar2d/data" +cp -f ../mix-and-match/export/mix-and-match.atlas "$ROOT/spine-solar2d/data" +cp -f ../mix-and-match/export/mix-and-match.png "$ROOT/spine-solar2d/data" echo "spine-love" rm "$ROOT/spine-love/data/"* diff --git a/spine-corona/test.lua b/spine-corona/test.lua deleted file mode 100644 index 540c6c689..000000000 --- a/spine-corona/test.lua +++ /dev/null @@ -1,79 +0,0 @@ -require("mobdebug").start() - -local spine = require "spine-corona.spine" - -function loadSkeleton(atlasFile, jsonFile, x, y, scale, animation, skin) - -- to load an atlas, we need to define a function that returns - -- a Corona paint object. This allows you to resolve images - -- however you see fit - local imageLoader = function (path) - local paint = { type = "image", filename = "data/" .. path } - return paint - end - - -- load the atlas - local atlas = spine.TextureAtlas.new(spine.utils.readFile("data/" .. atlasFile), imageLoader) - - -- load the JSON and create a Skeleton from it - local json = spine.SkeletonJson.new(spine.AtlasAttachmentLoader.new(atlas)) - json.scale = scale - local skeletonData = json:readSkeletonDataFile("data/" .. jsonFile) - local skeleton = spine.Skeleton.new(skeletonData) - skeleton.scaleY = -1 -- Corona's coordinate system has its y-axis point downwards - skeleton.group.x = x - skeleton.group.y = y - - -- Set the skin if we got one - if skin then skeleton:setSkin(skin) end - - -- create an animation state object to apply animations to the skeleton - local animationStateData = spine.AnimationStateData.new(skeletonData) - animationStateData.defaultMix = 0.5 - local animationState = spine.AnimationState.new(animationStateData) - - -- set a name on the group of the skeleton so we can find it during debugging - skeleton.group.name = jsonFile - - -- set some event callbacks - animationState.onStart = function (entry) - print(entry.trackIndex.." start: "..entry.animation.name) - end - animationState.onInterrupt = function (entry) - print(entry.trackIndex.." interrupt: "..entry.animation.name) - end - animationState.onEnd = function (entry) - print(entry.trackIndex.." end: "..entry.animation.name) - end - animationState.onComplete = function (entry) - print(entry.trackIndex.." complete: "..entry.animation.name) - end - animationState.onDispose = function (entry) - print(entry.trackIndex.." dispose: "..entry.animation.name) - end - animationState.onEvent = function (entry, event) - print(entry.trackIndex.." event: "..entry.animation.name..", "..event.data.name..", "..event.intValue..", "..event.floatValue..", '"..(event.stringValue or "").."'" .. ", " .. event.volume .. ", " .. event.balance) - end - - -- return the skeleton an animation state - return { skeleton = skeleton, state = animationState } -end - -local lastTime = 0 -local result = loadSkeleton("spineboy.atlas", "spineboy-pro.json", 240, 300, 0.4, "walk") -local skeleton = result.skeleton; -local state = result.state; - -state:setAnimationByName(0, "idle", true) -state:setAnimationByName(5, "shoot", true, 0) - -display.setDefault("background", 0.2, 0.2, 0.2, 1) - -Runtime:addEventListener("enterFrame", function (event) - local currentTime = event.time / 1000 - local delta = currentTime - lastTime - lastTime = currentTime - - state:update(delta) - state:apply(skeleton) - skeleton:updateWorldTransform() -end) \ No newline at end of file diff --git a/spine-corona/LICENSE b/spine-solar2d/LICENSE similarity index 100% rename from spine-corona/LICENSE rename to spine-solar2d/LICENSE diff --git a/spine-corona/README.md b/spine-solar2d/README.md similarity index 64% rename from spine-corona/README.md rename to spine-solar2d/README.md index bf8d2e3ba..e070d7b66 100644 --- a/spine-corona/README.md +++ b/spine-solar2d/README.md @@ -1,6 +1,6 @@ -# spine-corona +# spine-solar2d -The spine-corona runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [Corona](http://coronalabs.com/products/corona-sdk/). spine-corona is based on [spine-lua](../spine-lua). +The spine-solar2d runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [Solar2D](https://solar2d.com/) (previously Corona). spine-solar2d is based on [spine-lua](../spine-lua). ## Licensing @@ -14,18 +14,18 @@ For the official legal terms governing the Spine Runtimes, please read the [Spin ## Spine version -spine-corona works with data exported from Spine 3.9.xx. +spine-solar2d works with data exported from Spine 3.9.xx. -spine-corona supports all Spine features. +spine-solar2d supports all Spine features. -spine-corona does not yet support loading the binary format. +spine-solar2d does not yet support loading the binary format. ## Setup 1. Download the Spine Runtimes source using [git](https://help.github.com/articles/set-up-git) or by downloading it as a zip via the download button above. -2. Copy the `spine-lua/spine-lua` folder to `spine-corona`. -3. Run the `main.lua` file using Corona. Tap/click to switch between skeletons +2. Copy the `spine-lua/spine-lua` folder to `spine-solar2d`. +3. Run the `main.lua` file using Solar2D. Tap/click to switch between skeletons -Alternatively, the `spine-lua` and `spine-corona/spine-corona` directories can be copied into your project. Note that the spine-corona `require` statements use `spine-lua.Xxx`, so the spine-lua files must be in a `spine-lua` directory in your project. +Alternatively, the `spine-lua` and `spine-solar2d/spine-solar2d` directories can be copied into your project. Note that the spine-solar2d `require` statements use `spine-lua.Xxx`, so the spine-lua files must be in a `spine-lua` directory in your project. -When using the `EmmyLua` plugin for IntelliJ IDEA, create a launch configuration pointing at the `Corona Simulator` executable (e.g. ` /Applications/Corona/Corona Simulator.app/Contents/MacOS/Corona Simulator` on macOS), set the working directory to `spine-corona`, and set the parameters to `main.lua`. +When using the `EmmyLua` plugin for IntelliJ IDEA, create a launch configuration pointing at the `Corona Simulator` executable (e.g. ` /Applications/Corona/Corona Simulator.app/Contents/MacOS/Corona Simulator` on macOS), set the working directory to `spine-solar2d`, and set the parameters to `main.lua`. diff --git a/spine-corona/build.settings b/spine-solar2d/build.settings similarity index 100% rename from spine-corona/build.settings rename to spine-solar2d/build.settings diff --git a/spine-corona/config.lua b/spine-solar2d/config.lua similarity index 100% rename from spine-corona/config.lua rename to spine-solar2d/config.lua diff --git a/spine-corona/data/coin-pro.json b/spine-solar2d/data/coin-pro.json similarity index 100% rename from spine-corona/data/coin-pro.json rename to spine-solar2d/data/coin-pro.json diff --git a/spine-corona/data/coin.atlas b/spine-solar2d/data/coin.atlas similarity index 100% rename from spine-corona/data/coin.atlas rename to spine-solar2d/data/coin.atlas diff --git a/spine-corona/data/coin.png b/spine-solar2d/data/coin.png similarity index 100% rename from spine-corona/data/coin.png rename to spine-solar2d/data/coin.png diff --git a/spine-corona/data/goblins-pro.json b/spine-solar2d/data/goblins-pro.json similarity index 100% rename from spine-corona/data/goblins-pro.json rename to spine-solar2d/data/goblins-pro.json diff --git a/spine-corona/data/goblins.atlas b/spine-solar2d/data/goblins.atlas similarity index 100% rename from spine-corona/data/goblins.atlas rename to spine-solar2d/data/goblins.atlas diff --git a/spine-corona/data/goblins.png b/spine-solar2d/data/goblins.png similarity index 100% rename from spine-corona/data/goblins.png rename to spine-solar2d/data/goblins.png diff --git a/spine-corona/data/mix-and-match-pro.json b/spine-solar2d/data/mix-and-match-pro.json similarity index 100% rename from spine-corona/data/mix-and-match-pro.json rename to spine-solar2d/data/mix-and-match-pro.json diff --git a/spine-corona/data/mix-and-match.atlas b/spine-solar2d/data/mix-and-match.atlas similarity index 100% rename from spine-corona/data/mix-and-match.atlas rename to spine-solar2d/data/mix-and-match.atlas diff --git a/spine-corona/data/mix-and-match.png b/spine-solar2d/data/mix-and-match.png similarity index 100% rename from spine-corona/data/mix-and-match.png rename to spine-solar2d/data/mix-and-match.png diff --git a/spine-corona/data/owl-pro.json b/spine-solar2d/data/owl-pro.json similarity index 100% rename from spine-corona/data/owl-pro.json rename to spine-solar2d/data/owl-pro.json diff --git a/spine-corona/data/owl.atlas b/spine-solar2d/data/owl.atlas similarity index 100% rename from spine-corona/data/owl.atlas rename to spine-solar2d/data/owl.atlas diff --git a/spine-corona/data/owl.png b/spine-solar2d/data/owl.png similarity index 100% rename from spine-corona/data/owl.png rename to spine-solar2d/data/owl.png diff --git a/spine-corona/data/raptor-pro.json b/spine-solar2d/data/raptor-pro.json similarity index 100% rename from spine-corona/data/raptor-pro.json rename to spine-solar2d/data/raptor-pro.json diff --git a/spine-corona/data/raptor.atlas b/spine-solar2d/data/raptor.atlas similarity index 100% rename from spine-corona/data/raptor.atlas rename to spine-solar2d/data/raptor.atlas diff --git a/spine-corona/data/raptor.png b/spine-solar2d/data/raptor.png similarity index 100% rename from spine-corona/data/raptor.png rename to spine-solar2d/data/raptor.png diff --git a/spine-corona/data/spineboy-pro.json b/spine-solar2d/data/spineboy-pro.json similarity index 100% rename from spine-corona/data/spineboy-pro.json rename to spine-solar2d/data/spineboy-pro.json diff --git a/spine-corona/data/spineboy.atlas b/spine-solar2d/data/spineboy.atlas similarity index 100% rename from spine-corona/data/spineboy.atlas rename to spine-solar2d/data/spineboy.atlas diff --git a/spine-corona/data/spineboy.png b/spine-solar2d/data/spineboy.png similarity index 100% rename from spine-corona/data/spineboy.png rename to spine-solar2d/data/spineboy.png diff --git a/spine-corona/data/stretchyman-pro.json b/spine-solar2d/data/stretchyman-pro.json similarity index 100% rename from spine-corona/data/stretchyman-pro.json rename to spine-solar2d/data/stretchyman-pro.json diff --git a/spine-corona/data/stretchyman.atlas b/spine-solar2d/data/stretchyman.atlas similarity index 100% rename from spine-corona/data/stretchyman.atlas rename to spine-solar2d/data/stretchyman.atlas diff --git a/spine-corona/data/stretchyman.png b/spine-solar2d/data/stretchyman.png similarity index 100% rename from spine-corona/data/stretchyman.png rename to spine-solar2d/data/stretchyman.png diff --git a/spine-corona/data/tank-pro.json b/spine-solar2d/data/tank-pro.json similarity index 100% rename from spine-corona/data/tank-pro.json rename to spine-solar2d/data/tank-pro.json diff --git a/spine-corona/data/tank.atlas b/spine-solar2d/data/tank.atlas similarity index 100% rename from spine-corona/data/tank.atlas rename to spine-solar2d/data/tank.atlas diff --git a/spine-corona/data/tank.png b/spine-solar2d/data/tank.png similarity index 100% rename from spine-corona/data/tank.png rename to spine-solar2d/data/tank.png diff --git a/spine-corona/data/vine-pro.json b/spine-solar2d/data/vine-pro.json similarity index 100% rename from spine-corona/data/vine-pro.json rename to spine-solar2d/data/vine-pro.json diff --git a/spine-corona/data/vine.atlas b/spine-solar2d/data/vine.atlas similarity index 100% rename from spine-corona/data/vine.atlas rename to spine-solar2d/data/vine.atlas diff --git a/spine-corona/data/vine.png b/spine-solar2d/data/vine.png similarity index 100% rename from spine-corona/data/vine.png rename to spine-solar2d/data/vine.png diff --git a/spine-corona/main.lua b/spine-solar2d/main.lua similarity index 99% rename from spine-corona/main.lua rename to spine-solar2d/main.lua index beb910340..fbab2cc72 100644 --- a/spine-corona/main.lua +++ b/spine-solar2d/main.lua @@ -29,7 +29,7 @@ require("mobdebug").start() -local spine = require "spine-corona.spine" +local spine = require "spine-solar2d.spine" local skeletons = {} local activeSkeleton = 1 diff --git a/spine-corona/mobdebug.lua b/spine-solar2d/mobdebug.lua similarity index 100% rename from spine-corona/mobdebug.lua rename to spine-solar2d/mobdebug.lua diff --git a/spine-corona/spine-corona/spine.lua b/spine-solar2d/spine-solar2d/spine.lua similarity index 97% rename from spine-corona/spine-corona/spine.lua rename to spine-solar2d/spine-solar2d/spine.lua index d5dcba1e4..144e84248 100644 --- a/spine-corona/spine-corona/spine.lua +++ b/spine-solar2d/spine-solar2d/spine.lua @@ -1,300 +1,300 @@ -------------------------------------------------------------------------------- --- Spine Runtimes License Agreement --- Last updated January 1, 2020. Replaces all prior versions. --- --- Copyright (c) 2013-2020, Esoteric Software LLC --- --- Integration of the Spine Runtimes into software or otherwise creating --- derivative works of the Spine Runtimes is permitted under the terms and --- conditions of Section 2 of the Spine Editor License Agreement: --- http://esotericsoftware.com/spine-editor-license --- --- Otherwise, it is permitted to integrate the Spine Runtimes into software --- or otherwise create derivative works of the Spine Runtimes (collectively, --- "Products"), provided that each user of the Products must obtain their own --- Spine Editor license and redistribution of the Products in any form must --- include this license and copyright notice. --- --- THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY --- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED --- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE --- DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY --- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES --- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, --- BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND --- 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. -------------------------------------------------------------------------------- - -local spine = {} - -spine.utils = require "spine-lua.utils" -spine.SkeletonJson = require "spine-lua.SkeletonJson" -spine.SkeletonData = require "spine-lua.SkeletonData" -spine.BoneData = require "spine-lua.BoneData" -spine.SlotData = require "spine-lua.SlotData" -spine.IkConstraintData = require "spine-lua.IkConstraintData" -spine.Skin = require "spine-lua.Skin" -spine.Attachment = require "spine-lua.attachments.Attachment" -spine.BoundingBoxAttachment = require "spine-lua.attachments.BoundingBoxAttachment" -spine.RegionAttachment = require "spine-lua.attachments.RegionAttachment" -spine.MeshAttachment = require "spine-lua.attachments.MeshAttachment" -spine.VertexAttachment = require "spine-lua.attachments.VertexAttachment" -spine.PathAttachment = require "spine-lua.attachments.PathAttachment" -spine.PointAttachment = require "spine-lua.attachments.PointAttachment" -spine.ClippingAttachment = require "spine-lua.attachments.ClippingAttachment" -spine.Skeleton = require "spine-lua.Skeleton" -spine.Bone = require "spine-lua.Bone" -spine.Slot = require "spine-lua.Slot" -spine.IkConstraint = require "spine-lua.IkConstraint" -spine.AttachmentType = require "spine-lua.attachments.AttachmentType" -spine.AttachmentLoader = require "spine-lua.AttachmentLoader" -spine.Animation = require "spine-lua.Animation" -spine.AnimationStateData = require "spine-lua.AnimationStateData" -spine.AnimationState = require "spine-lua.AnimationState" -spine.EventData = require "spine-lua.EventData" -spine.Event = require "spine-lua.Event" -spine.SkeletonBounds = require "spine-lua.SkeletonBounds" -spine.BlendMode = require "spine-lua.BlendMode" -spine.TextureAtlas = require "spine-lua.TextureAtlas" -spine.TextureRegion = require "spine-lua.TextureRegion" -spine.TextureAtlasRegion = require "spine-lua.TextureAtlasRegion" -spine.AtlasAttachmentLoader = require "spine-lua.AtlasAttachmentLoader" -spine.Color = require "spine-lua.Color" -spine.Triangulator = require "spine-lua.Triangulator" -spine.SkeletonClipping = require "spine-lua.SkeletonClipping" -spine.JitterEffect = require "spine-lua.vertexeffects.JitterEffect" -spine.SwirlEffect = require "spine-lua.vertexeffects.SwirlEffect" -spine.Interpolation = require "spine-lua.Interpolation" - -spine.utils.readFile = function (fileName, base) - if not base then base = system.ResourceDirectory end - local path = system.pathForFile(fileName, base) - local file = io.open(path, "r") - if not file then return nil end - local contents = file:read("*a") - io.close(file) - return contents -end - -local json = require "json" -spine.utils.readJSON = function (text) - return json.decode(text) -end - -local QUAD_TRIANGLES = { 1, 2, 3, 3, 4, 1 } -spine.Skeleton.new_super = spine.Skeleton.new -spine.Skeleton.updateWorldTransform_super = spine.Skeleton.updateWorldTransform -spine.Skeleton.new = function(skeletonData, group) - local self = spine.Skeleton.new_super(skeletonData) - self.group = group or display.newGroup() - self.drawingGroup = nil - self.premultipliedAlpha = false - self.batches = 0 - self.tempColor = spine.Color.newWith(1, 1, 1, 1) - self.tempColor2 = spine.Color.newWith(-1, 1, 1, 1) - self.tempVertex = { - x = 0, - y = 0, - u = 0, - v = 0, - light = spine.Color.newWith(1, 1, 1, 1), - dark = spine.Color.newWith(0, 0, 0, 0) - } - self.clipper = spine.SkeletonClipping.new() - return self -end - -local function colorEquals(color1, color2) - return color1.r == color2.r and color1.g == color2.g and color1.b == color2.b and color1.a == color2.a -end - -local function toCoronaBlendMode(blendMode) - if blendMode == spine.BlendMode.normal then - return "normal" - elseif blendMode == spine.BlendMode.additive then - return "add" - elseif blendMode == spine.BlendMode.multiply then - return "multiply" - elseif blendMode == spine.BlendMode.screen then - return "screen" - end -end - -local worldVertices = spine.utils.newNumberArray(10000 * 8) - -function spine.Skeleton:updateWorldTransform() - spine.Skeleton.updateWorldTransform_super(self) - local premultipliedAlpha = self.premultipliedAlpha - - self.batches = 0 - - if (self.vertexEffect) then self.vertexEffect:beginEffect(self) end - - -- Remove old drawing group, we will start anew - if self.drawingGroup then self.drawingGroup:removeSelf() end - local drawingGroup = display.newGroup() - self.drawingGroup = drawingGroup - self.group:insert(drawingGroup) - - local drawOrder = self.drawOrder - local currentGroup = nil - local groupVertices = {} - local groupIndices = {} - local groupUvs = {} - local color = self.tempColor - local lastColor = self.tempColor2 - lastColor.r = -1 - local texture = nil - local lastTexture = nil - local blendMode = nil - local lastBlendMode = nil - local renderable = { - vertices = nil, - uvs = nil - } - - for _,slot in ipairs(drawOrder) do - local attachment = slot.attachment - local vertices = nil - local uvs = nil - local numVertices = 0 - local indices = nil - - if slot.bone.active then - local isClippingAttachment = false - if attachment then - if attachment.type == spine.AttachmentType.region then - numVertices = 4 - vertices = worldVertices - attachment:computeWorldVertices(slot.bone, vertices, 0, 2) - uvs = attachment.uvs - indices = QUAD_TRIANGLES - texture = attachment.region.renderObject.texture - blendMode = toCoronaBlendMode(slot.data.blendMode) - elseif attachment.type == spine.AttachmentType.mesh then - numVertices = attachment.worldVerticesLength / 2 - vertices = worldVertices - attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2) - uvs = attachment.uvs - indices = attachment.triangles - texture = attachment.region.renderObject.texture - blendMode = toCoronaBlendMode(slot.data.blendMode) - elseif attachment.type == spine.AttachmentType.clipping then - self.clipper:clipStart(slot, attachment) - isClippingAttachment = true - end - - if texture and vertices and indices then - local skeleton = slot.bone.skeleton - local skeletonColor = skeleton.color - local slotColor = slot.color - local attachmentColor = attachment.color - local alpha = skeletonColor.a * slotColor.a * attachmentColor.a - local multiplier = 1 - if premultipliedAlpha then multiplier = alpha end - - color:set(skeletonColor.r * slotColor.r * attachmentColor.r * multiplier, - skeletonColor.g * slotColor.g * attachmentColor.g * multiplier, - skeletonColor.b * slotColor.b * attachmentColor.b * multiplier, - alpha) - - if not lastTexture then lastTexture = texture end - if lastColor.r == -1 then lastColor:setFrom(color) end - if not lastBlendMode then lastBlendMode = blendMode end - - if (texture ~= lastTexture or not colorEquals(color, lastColor) or blendMode ~= lastBlendMode) then - self:flush(groupVertices, groupUvs, groupIndices, lastTexture, lastColor, lastBlendMode, drawingGroup) - lastTexture = texture - lastColor:setFrom(color) - lastBlendMode = blendMode - groupVertices = {} - groupUvs = {} - groupIndices = {} - end - - if self.clipper:isClipping() then - self.clipper:clipTriangles(vertices, uvs, indices, #indices) - vertices = self.clipper.clippedVertices - numVertices = #vertices / 2 - uvs = self.clipper.clippedUVs - indices = self.clipper.clippedTriangles - end - - self:batch(vertices, uvs, numVertices, indices, groupVertices, groupUvs, groupIndices) - - end - if not isClippingAttachment then self.clipper:clipEnd(slot) end - end - end - end - - if #groupVertices > 0 then - self:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup) - end - - self.clipper:clipEnd2() - if (self.vertexEffect) then self.vertexEffect:endEffect() end -end - -function spine.Skeleton:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup) - local mesh = display.newMesh(drawingGroup, 0, 0, { - mode = "indexed", - vertices = groupVertices, - uvs = groupUvs, - indices = groupIndices - }) - mesh.fill = texture - mesh:setFillColor(color.r, color.g, color.b) - mesh.alpha = color.a - mesh.blendMode = blendMode - mesh:translate(mesh.path:getVertexOffset()) - self.batches = self.batches + 1 -end - -function spine.Skeleton:batch(vertices, uvs, numVertices, indices, groupVertices, groupUvs, groupIndices) - local numIndices = #indices - local i = 1 - local indexStart = #groupIndices + 1 - local offset = #groupVertices / 2 - local indexEnd = indexStart + numIndices - - while indexStart < indexEnd do - groupIndices[indexStart] = indices[i] + offset - indexStart = indexStart + 1 - i = i + 1 - end - - i = 1 - local vertexStart = #groupVertices + 1 - local vertexEnd = vertexStart + numVertices * 2 - if (self.vertexEffect) then - local effect = self.vertexEffect - local vertex = self.tempVertex - while vertexStart < vertexEnd do - vertex.x = vertices[i] - vertex.y = vertices[i+1] - vertex.u = uvs[i] - vertex.v = uvs[i+1] - effect:transform(vertex); - groupVertices[vertexStart] = vertex.x - groupVertices[vertexStart+1] = vertex.y - groupUvs[vertexStart] = vertex.u - groupUvs[vertexStart+1] = vertex.v - vertexStart = vertexStart + 2 - i = i + 2 - end - else - while vertexStart < vertexEnd do - groupVertices[vertexStart] = vertices[i] - groupVertices[vertexStart+1] = vertices[i+1] - groupUvs[vertexStart] = uvs[i] - groupUvs[vertexStart+1] = uvs[i+1] - vertexStart = vertexStart + 2 - i = i + 2 - end - end -end - -return spine +------------------------------------------------------------------------------- +-- Spine Runtimes License Agreement +-- Last updated January 1, 2020. Replaces all prior versions. +-- +-- Copyright (c) 2013-2020, Esoteric Software LLC +-- +-- Integration of the Spine Runtimes into software or otherwise creating +-- derivative works of the Spine Runtimes is permitted under the terms and +-- conditions of Section 2 of the Spine Editor License Agreement: +-- http://esotericsoftware.com/spine-editor-license +-- +-- Otherwise, it is permitted to integrate the Spine Runtimes into software +-- or otherwise create derivative works of the Spine Runtimes (collectively, +-- "Products"), provided that each user of the Products must obtain their own +-- Spine Editor license and redistribution of the Products in any form must +-- include this license and copyright notice. +-- +-- THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY +-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +-- DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY +-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, +-- BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND +-- 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. +------------------------------------------------------------------------------- + +local spine = {} + +spine.utils = require "spine-lua.utils" +spine.SkeletonJson = require "spine-lua.SkeletonJson" +spine.SkeletonData = require "spine-lua.SkeletonData" +spine.BoneData = require "spine-lua.BoneData" +spine.SlotData = require "spine-lua.SlotData" +spine.IkConstraintData = require "spine-lua.IkConstraintData" +spine.Skin = require "spine-lua.Skin" +spine.Attachment = require "spine-lua.attachments.Attachment" +spine.BoundingBoxAttachment = require "spine-lua.attachments.BoundingBoxAttachment" +spine.RegionAttachment = require "spine-lua.attachments.RegionAttachment" +spine.MeshAttachment = require "spine-lua.attachments.MeshAttachment" +spine.VertexAttachment = require "spine-lua.attachments.VertexAttachment" +spine.PathAttachment = require "spine-lua.attachments.PathAttachment" +spine.PointAttachment = require "spine-lua.attachments.PointAttachment" +spine.ClippingAttachment = require "spine-lua.attachments.ClippingAttachment" +spine.Skeleton = require "spine-lua.Skeleton" +spine.Bone = require "spine-lua.Bone" +spine.Slot = require "spine-lua.Slot" +spine.IkConstraint = require "spine-lua.IkConstraint" +spine.AttachmentType = require "spine-lua.attachments.AttachmentType" +spine.AttachmentLoader = require "spine-lua.AttachmentLoader" +spine.Animation = require "spine-lua.Animation" +spine.AnimationStateData = require "spine-lua.AnimationStateData" +spine.AnimationState = require "spine-lua.AnimationState" +spine.EventData = require "spine-lua.EventData" +spine.Event = require "spine-lua.Event" +spine.SkeletonBounds = require "spine-lua.SkeletonBounds" +spine.BlendMode = require "spine-lua.BlendMode" +spine.TextureAtlas = require "spine-lua.TextureAtlas" +spine.TextureRegion = require "spine-lua.TextureRegion" +spine.TextureAtlasRegion = require "spine-lua.TextureAtlasRegion" +spine.AtlasAttachmentLoader = require "spine-lua.AtlasAttachmentLoader" +spine.Color = require "spine-lua.Color" +spine.Triangulator = require "spine-lua.Triangulator" +spine.SkeletonClipping = require "spine-lua.SkeletonClipping" +spine.JitterEffect = require "spine-lua.vertexeffects.JitterEffect" +spine.SwirlEffect = require "spine-lua.vertexeffects.SwirlEffect" +spine.Interpolation = require "spine-lua.Interpolation" + +spine.utils.readFile = function (fileName, base) + if not base then base = system.ResourceDirectory end + local path = system.pathForFile(fileName, base) + local file = io.open(path, "r") + if not file then return nil end + local contents = file:read("*a") + io.close(file) + return contents +end + +local json = require "json" +spine.utils.readJSON = function (text) + return json.decode(text) +end + +local QUAD_TRIANGLES = { 1, 2, 3, 3, 4, 1 } +spine.Skeleton.new_super = spine.Skeleton.new +spine.Skeleton.updateWorldTransform_super = spine.Skeleton.updateWorldTransform +spine.Skeleton.new = function(skeletonData, group) + local self = spine.Skeleton.new_super(skeletonData) + self.group = group or display.newGroup() + self.drawingGroup = nil + self.premultipliedAlpha = false + self.batches = 0 + self.tempColor = spine.Color.newWith(1, 1, 1, 1) + self.tempColor2 = spine.Color.newWith(-1, 1, 1, 1) + self.tempVertex = { + x = 0, + y = 0, + u = 0, + v = 0, + light = spine.Color.newWith(1, 1, 1, 1), + dark = spine.Color.newWith(0, 0, 0, 0) + } + self.clipper = spine.SkeletonClipping.new() + return self +end + +local function colorEquals(color1, color2) + return color1.r == color2.r and color1.g == color2.g and color1.b == color2.b and color1.a == color2.a +end + +local function toCoronaBlendMode(blendMode) + if blendMode == spine.BlendMode.normal then + return "normal" + elseif blendMode == spine.BlendMode.additive then + return "add" + elseif blendMode == spine.BlendMode.multiply then + return "multiply" + elseif blendMode == spine.BlendMode.screen then + return "screen" + end +end + +local worldVertices = spine.utils.newNumberArray(10000 * 8) + +function spine.Skeleton:updateWorldTransform() + spine.Skeleton.updateWorldTransform_super(self) + local premultipliedAlpha = self.premultipliedAlpha + + self.batches = 0 + + if (self.vertexEffect) then self.vertexEffect:beginEffect(self) end + + -- Remove old drawing group, we will start anew + if self.drawingGroup then self.drawingGroup:removeSelf() end + local drawingGroup = display.newGroup() + self.drawingGroup = drawingGroup + self.group:insert(drawingGroup) + + local drawOrder = self.drawOrder + local currentGroup = nil + local groupVertices = {} + local groupIndices = {} + local groupUvs = {} + local color = self.tempColor + local lastColor = self.tempColor2 + lastColor.r = -1 + local texture = nil + local lastTexture = nil + local blendMode = nil + local lastBlendMode = nil + local renderable = { + vertices = nil, + uvs = nil + } + + for _,slot in ipairs(drawOrder) do + local attachment = slot.attachment + local vertices = nil + local uvs = nil + local numVertices = 0 + local indices = nil + + if slot.bone.active then + local isClippingAttachment = false + if attachment then + if attachment.type == spine.AttachmentType.region then + numVertices = 4 + vertices = worldVertices + attachment:computeWorldVertices(slot.bone, vertices, 0, 2) + uvs = attachment.uvs + indices = QUAD_TRIANGLES + texture = attachment.region.renderObject.texture + blendMode = toCoronaBlendMode(slot.data.blendMode) + elseif attachment.type == spine.AttachmentType.mesh then + numVertices = attachment.worldVerticesLength / 2 + vertices = worldVertices + attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2) + uvs = attachment.uvs + indices = attachment.triangles + texture = attachment.region.renderObject.texture + blendMode = toCoronaBlendMode(slot.data.blendMode) + elseif attachment.type == spine.AttachmentType.clipping then + self.clipper:clipStart(slot, attachment) + isClippingAttachment = true + end + + if texture and vertices and indices then + local skeleton = slot.bone.skeleton + local skeletonColor = skeleton.color + local slotColor = slot.color + local attachmentColor = attachment.color + local alpha = skeletonColor.a * slotColor.a * attachmentColor.a + local multiplier = 1 + if premultipliedAlpha then multiplier = alpha end + + color:set(skeletonColor.r * slotColor.r * attachmentColor.r * multiplier, + skeletonColor.g * slotColor.g * attachmentColor.g * multiplier, + skeletonColor.b * slotColor.b * attachmentColor.b * multiplier, + alpha) + + if not lastTexture then lastTexture = texture end + if lastColor.r == -1 then lastColor:setFrom(color) end + if not lastBlendMode then lastBlendMode = blendMode end + + if (texture ~= lastTexture or not colorEquals(color, lastColor) or blendMode ~= lastBlendMode) then + self:flush(groupVertices, groupUvs, groupIndices, lastTexture, lastColor, lastBlendMode, drawingGroup) + lastTexture = texture + lastColor:setFrom(color) + lastBlendMode = blendMode + groupVertices = {} + groupUvs = {} + groupIndices = {} + end + + if self.clipper:isClipping() then + self.clipper:clipTriangles(vertices, uvs, indices, #indices) + vertices = self.clipper.clippedVertices + numVertices = #vertices / 2 + uvs = self.clipper.clippedUVs + indices = self.clipper.clippedTriangles + end + + self:batch(vertices, uvs, numVertices, indices, groupVertices, groupUvs, groupIndices) + + end + if not isClippingAttachment then self.clipper:clipEnd(slot) end + end + end + end + + if #groupVertices > 0 then + self:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup) + end + + self.clipper:clipEnd2() + if (self.vertexEffect) then self.vertexEffect:endEffect() end +end + +function spine.Skeleton:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup) + local mesh = display.newMesh(drawingGroup, 0, 0, { + mode = "indexed", + vertices = groupVertices, + uvs = groupUvs, + indices = groupIndices + }) + mesh.fill = texture + mesh:setFillColor(color.r, color.g, color.b) + mesh.alpha = color.a + mesh.blendMode = blendMode + mesh:translate(mesh.path:getVertexOffset()) + self.batches = self.batches + 1 +end + +function spine.Skeleton:batch(vertices, uvs, numVertices, indices, groupVertices, groupUvs, groupIndices) + local numIndices = #indices + local i = 1 + local indexStart = #groupIndices + 1 + local offset = #groupVertices / 2 + local indexEnd = indexStart + numIndices + + while indexStart < indexEnd do + groupIndices[indexStart] = indices[i] + offset + indexStart = indexStart + 1 + i = i + 1 + end + + i = 1 + local vertexStart = #groupVertices + 1 + local vertexEnd = vertexStart + numVertices * 2 + if (self.vertexEffect) then + local effect = self.vertexEffect + local vertex = self.tempVertex + while vertexStart < vertexEnd do + vertex.x = vertices[i] + vertex.y = vertices[i+1] + vertex.u = uvs[i] + vertex.v = uvs[i+1] + effect:transform(vertex); + groupVertices[vertexStart] = vertex.x + groupVertices[vertexStart+1] = vertex.y + groupUvs[vertexStart] = vertex.u + groupUvs[vertexStart+1] = vertex.v + vertexStart = vertexStart + 2 + i = i + 2 + end + else + while vertexStart < vertexEnd do + groupVertices[vertexStart] = vertices[i] + groupVertices[vertexStart+1] = vertices[i+1] + groupUvs[vertexStart] = uvs[i] + groupUvs[vertexStart+1] = uvs[i+1] + vertexStart = vertexStart + 2 + i = i + 2 + end + end +end + +return spine