mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[lua] Move spine-lua source to spine-lua subfolder.
This commit is contained in:
parent
d285e25dcd
commit
fe9baaf849
@ -23,10 +23,9 @@ spine-corona 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.
|
||||
1. Copy the contents of `spine-lua` to `spine-corona/spine-lua`.
|
||||
1. Run the `main.lua` file using Corona. Tap/click to switch between skeletons
|
||||
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
|
||||
|
||||
Alternatively, the `spine-lua` and `spine-corona/spine-corona` directories can be copied into your project. Note that the 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`.
|
||||
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.
|
||||
|
||||
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`.
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
The spine-love runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [LÖVE](https://love2d.org/). spine-love is based on [spine-lua](../spine-lua).
|
||||
|
||||
## Licensing
|
||||
|
||||
You are welcome to evaluate the Spine Runtimes and the examples we provide in this repository free of charge.
|
||||
|
||||
You can integrate the Spine Runtimes into your software free of charge, but users of your software must have their own [Spine license](https://esotericsoftware.com/spine-purchase). Please make your users aware of this requirement! This option is often chosen by those making development tools, such as an SDK, game toolkit, or software library.
|
||||
@ -15,7 +16,7 @@ For the official legal terms governing the Spine Runtimes, please read the [Spin
|
||||
|
||||
spine-love works with data exported from Spine 3.9.x.
|
||||
|
||||
spine-love supports all Spine features except for blending modes other than normal.
|
||||
spine-love supports all Spine features except for blending modes other than `normal`.
|
||||
|
||||
spine-love does not yet support loading the binary format.
|
||||
|
||||
@ -32,11 +33,12 @@ Alternatively, the `spine-lua` and `spine-love/spine-love` directories can be co
|
||||
* To enable two color tinting, pass `true` to `SkeletonRenderer.new()`.
|
||||
|
||||
## Examples
|
||||
|
||||
If you want to run and debug the example project, use IntelliJ IDEA with the EmmyLua plugin.
|
||||
|
||||
1. Install IntelliJ IDEA and the EmmyLua plugin.
|
||||
2. Install LÖVE.
|
||||
3. Copy the contents of `spine-lua` to `spine-love/spine-lua`.
|
||||
1. Install [IntelliJ IDEA](https://www.jetbrains.com/idea/) and the [EmmyLua plugin](https://plugins.jetbrains.com/plugin/9768-emmylua).
|
||||
2. Install [LÖVE](https://love2d.org/).
|
||||
3. Copy the `spine-lua/spine-lua` folder to `spine-love`.
|
||||
4. Open the `spine-love` folder in IntelliJ IDEA.
|
||||
5. Create a new launch configuration of the type `Lua Application`, with the following settings
|
||||
1. `Program` should point at the `love` or `love.exe` executable, e.g. `/Applications/love.app/Contents/MacOS/love` on macOS.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,58 +1,58 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AnimationStateData = {}
|
||||
|
||||
function AnimationStateData.new (skeletonData)
|
||||
if not skeletonData then error("skeletonData cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
skeletonData = skeletonData,
|
||||
animationToMixTime = {},
|
||||
defaultMix = 0
|
||||
}
|
||||
|
||||
function self:setMix (fromName, toName, duration)
|
||||
if not self.animationToMixTime[fromName] then
|
||||
self.animationToMixTime[fromName] = {}
|
||||
end
|
||||
self.animationToMixTime[fromName][toName] = duration
|
||||
end
|
||||
|
||||
function self:getMix (fromName, toName)
|
||||
local first = self.animationToMixTime[fromName]
|
||||
if not first then return self.defaultMix end
|
||||
local duration = first[toName]
|
||||
if not duration then return self.defaultMix end
|
||||
return duration
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
return AnimationStateData
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AnimationStateData = {}
|
||||
|
||||
function AnimationStateData.new (skeletonData)
|
||||
if not skeletonData then error("skeletonData cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
skeletonData = skeletonData,
|
||||
animationToMixTime = {},
|
||||
defaultMix = 0
|
||||
}
|
||||
|
||||
function self:setMix (fromName, toName, duration)
|
||||
if not self.animationToMixTime[fromName] then
|
||||
self.animationToMixTime[fromName] = {}
|
||||
end
|
||||
self.animationToMixTime[fromName][toName] = duration
|
||||
end
|
||||
|
||||
function self:getMix (fromName, toName)
|
||||
local first = self.animationToMixTime[fromName]
|
||||
if not first then return self.defaultMix end
|
||||
local duration = first[toName]
|
||||
if not duration then return self.defaultMix end
|
||||
return duration
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
return AnimationStateData
|
||||
@ -1,104 +1,104 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 Atlas = {}
|
||||
|
||||
function Atlas.parse(atlasPath, atlasBase)
|
||||
local function parseIntTuple4( l )
|
||||
local a,b,c,d = string.match( l , " ? ?%a+: ([+-]?%d+), ?([+-]?%d+), ?([+-]?%d+), ?([+-]?%d+)" )
|
||||
a,b,c,d = tonumber( a ), tonumber( b ), tonumber( c ), tonumber( d )
|
||||
return a and b and c and d and {a, b, c ,d}
|
||||
end
|
||||
|
||||
local function parseIntTuple2( l )
|
||||
local a,b = string.match( l , " ? ?%a+: ([+-]?%d+), ?([+-]?%d+)" )
|
||||
a,b = tonumber( a ), tonumber( b )
|
||||
return a and b and {a, b}
|
||||
end
|
||||
|
||||
if not atlasPath then
|
||||
error("Error: " .. atlasPath .. ".atlas" .. " doesn't exist!")
|
||||
return nil
|
||||
end
|
||||
|
||||
local atlasLines = spine.utils.readFile( atlasPath, atlasBase )
|
||||
if not atlasLines then
|
||||
error("Error: " .. atlasPath .. ".atlas" .. " unable to read!")
|
||||
return nil
|
||||
end
|
||||
|
||||
local pages = {}
|
||||
|
||||
|
||||
local it = string.gmatch(atlasLines, "(.-)\r?\n") -- iterate over lines
|
||||
for l in it do
|
||||
if #l == 0 then
|
||||
l = it()
|
||||
if l then
|
||||
local page = { name = l }
|
||||
l = it()
|
||||
page.size = parseIntTuple2( l )
|
||||
if page.size then
|
||||
l = it()
|
||||
end
|
||||
page.format = string.match( l, "%a+: (.+)" )
|
||||
page.filter = {string.match( it(), "%a+: (.+),(.+)" )}
|
||||
page.wrap = string.match( it(), "%a+: (.+)" )
|
||||
page.regions = {}
|
||||
table.insert( pages, page )
|
||||
else
|
||||
break
|
||||
end
|
||||
else
|
||||
local region = {name = l}
|
||||
|
||||
region.rotate = string.match( it(), "%a+: (.+)" ) == "true"
|
||||
region.xy = parseIntTuple2( it() )
|
||||
region.size = parseIntTuple2( it() )
|
||||
l = it()
|
||||
region.splits = parseIntTuple4(l)
|
||||
if region.splits then
|
||||
l = it()
|
||||
region.pad = parseIntTuple4(l)
|
||||
if region.pad then
|
||||
l = it()
|
||||
end
|
||||
end
|
||||
region.orig = parseIntTuple2( l )
|
||||
region.offset = parseIntTuple2( it() )
|
||||
region.index = tonumber( string.match( it() , "%a+: ([+-]?%d+)" ) )
|
||||
|
||||
table.insert( pages[#pages].regions, region )
|
||||
end
|
||||
end
|
||||
|
||||
return pages
|
||||
end
|
||||
|
||||
return Atlas
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 Atlas = {}
|
||||
|
||||
function Atlas.parse(atlasPath, atlasBase)
|
||||
local function parseIntTuple4( l )
|
||||
local a,b,c,d = string.match( l , " ? ?%a+: ([+-]?%d+), ?([+-]?%d+), ?([+-]?%d+), ?([+-]?%d+)" )
|
||||
a,b,c,d = tonumber( a ), tonumber( b ), tonumber( c ), tonumber( d )
|
||||
return a and b and c and d and {a, b, c ,d}
|
||||
end
|
||||
|
||||
local function parseIntTuple2( l )
|
||||
local a,b = string.match( l , " ? ?%a+: ([+-]?%d+), ?([+-]?%d+)" )
|
||||
a,b = tonumber( a ), tonumber( b )
|
||||
return a and b and {a, b}
|
||||
end
|
||||
|
||||
if not atlasPath then
|
||||
error("Error: " .. atlasPath .. ".atlas" .. " doesn't exist!")
|
||||
return nil
|
||||
end
|
||||
|
||||
local atlasLines = spine.utils.readFile( atlasPath, atlasBase )
|
||||
if not atlasLines then
|
||||
error("Error: " .. atlasPath .. ".atlas" .. " unable to read!")
|
||||
return nil
|
||||
end
|
||||
|
||||
local pages = {}
|
||||
|
||||
|
||||
local it = string.gmatch(atlasLines, "(.-)\r?\n") -- iterate over lines
|
||||
for l in it do
|
||||
if #l == 0 then
|
||||
l = it()
|
||||
if l then
|
||||
local page = { name = l }
|
||||
l = it()
|
||||
page.size = parseIntTuple2( l )
|
||||
if page.size then
|
||||
l = it()
|
||||
end
|
||||
page.format = string.match( l, "%a+: (.+)" )
|
||||
page.filter = {string.match( it(), "%a+: (.+),(.+)" )}
|
||||
page.wrap = string.match( it(), "%a+: (.+)" )
|
||||
page.regions = {}
|
||||
table.insert( pages, page )
|
||||
else
|
||||
break
|
||||
end
|
||||
else
|
||||
local region = {name = l}
|
||||
|
||||
region.rotate = string.match( it(), "%a+: (.+)" ) == "true"
|
||||
region.xy = parseIntTuple2( it() )
|
||||
region.size = parseIntTuple2( it() )
|
||||
l = it()
|
||||
region.splits = parseIntTuple4(l)
|
||||
if region.splits then
|
||||
l = it()
|
||||
region.pad = parseIntTuple4(l)
|
||||
if region.pad then
|
||||
l = it()
|
||||
end
|
||||
end
|
||||
region.orig = parseIntTuple2( l )
|
||||
region.offset = parseIntTuple2( it() )
|
||||
region.index = tonumber( string.match( it() , "%a+: ([+-]?%d+)" ) )
|
||||
|
||||
table.insert( pages[#pages].regions, region )
|
||||
end
|
||||
end
|
||||
|
||||
return pages
|
||||
end
|
||||
|
||||
return Atlas
|
||||
@ -1,68 +1,68 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local RegionAttachment = require "spine-lua.attachments.RegionAttachment"
|
||||
local BoundingBoxAttachment = require "spine-lua.attachments.BoundingBoxAttachment"
|
||||
local MeshAttachment = require "spine-lua.attachments.MeshAttachment"
|
||||
local PathAttachment = require "spine-lua.attachments.PathAttachment"
|
||||
local PointAttachment = require "spine-lua.attachments.PointAttachment"
|
||||
local ClippingAttachment = require "spine-lua.attachments.ClippingAttachment"
|
||||
|
||||
local AttachmentLoader = {}
|
||||
function AttachmentLoader.new ()
|
||||
local self = {}
|
||||
|
||||
function self:newRegionAttachment (skin, name, path)
|
||||
return RegionAttachment.new(name)
|
||||
end
|
||||
|
||||
function self:newMeshAttachment (skin, name, path)
|
||||
return MeshAttachment.new(name)
|
||||
end
|
||||
|
||||
function self:newBoundingBoxAttachment (skin, name)
|
||||
return BoundingBoxAttachment.new(name)
|
||||
end
|
||||
|
||||
function self:newPathAttachment(skin, name)
|
||||
return PathAttachment.new(name)
|
||||
end
|
||||
|
||||
function self:newPointAttachment(skin, name)
|
||||
return PointAttachment.new(name)
|
||||
end
|
||||
|
||||
function self:newClippingAttachment(skin, name)
|
||||
return ClippingAttachment.new(name)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
return AttachmentLoader
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local RegionAttachment = require "spine-lua.attachments.RegionAttachment"
|
||||
local BoundingBoxAttachment = require "spine-lua.attachments.BoundingBoxAttachment"
|
||||
local MeshAttachment = require "spine-lua.attachments.MeshAttachment"
|
||||
local PathAttachment = require "spine-lua.attachments.PathAttachment"
|
||||
local PointAttachment = require "spine-lua.attachments.PointAttachment"
|
||||
local ClippingAttachment = require "spine-lua.attachments.ClippingAttachment"
|
||||
|
||||
local AttachmentLoader = {}
|
||||
function AttachmentLoader.new ()
|
||||
local self = {}
|
||||
|
||||
function self:newRegionAttachment (skin, name, path)
|
||||
return RegionAttachment.new(name)
|
||||
end
|
||||
|
||||
function self:newMeshAttachment (skin, name, path)
|
||||
return MeshAttachment.new(name)
|
||||
end
|
||||
|
||||
function self:newBoundingBoxAttachment (skin, name)
|
||||
return BoundingBoxAttachment.new(name)
|
||||
end
|
||||
|
||||
function self:newPathAttachment(skin, name)
|
||||
return PathAttachment.new(name)
|
||||
end
|
||||
|
||||
function self:newPointAttachment(skin, name)
|
||||
return PointAttachment.new(name)
|
||||
end
|
||||
|
||||
function self:newClippingAttachment(skin, name)
|
||||
return ClippingAttachment.new(name)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
return AttachmentLoader
|
||||
@ -1,36 +1,36 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = {
|
||||
region = 0,
|
||||
boundingbox = 1,
|
||||
mesh = 2,
|
||||
skinnedmesh = 3
|
||||
}
|
||||
return AttachmentType
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = {
|
||||
region = 0,
|
||||
boundingbox = 1,
|
||||
mesh = 2,
|
||||
skinnedmesh = 3
|
||||
}
|
||||
return AttachmentType
|
||||
@ -1,36 +1,36 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 BlendMode = {
|
||||
normal = 0,
|
||||
additive = 1,
|
||||
multiply = 2,
|
||||
screen = 3
|
||||
}
|
||||
return BlendMode
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 BlendMode = {
|
||||
normal = 0,
|
||||
additive = 1,
|
||||
multiply = 2,
|
||||
screen = 3
|
||||
}
|
||||
return BlendMode
|
||||
@ -1,320 +1,320 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local math_rad = math.rad
|
||||
local math_deg = math.deg
|
||||
local math_sin = math.sin
|
||||
local math_cos = math.cos
|
||||
local math_atan2 = math.atan2
|
||||
local math_sqrt = math.sqrt
|
||||
local math_abs = math.abs
|
||||
local math_pi = math.pi
|
||||
|
||||
local TransformMode = require "spine-lua.TransformMode"
|
||||
|
||||
function math.sign(x)
|
||||
if x<0 then
|
||||
return -1
|
||||
elseif x>0 then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
local math_sign = math.sign
|
||||
|
||||
local Bone = {}
|
||||
Bone.__index = Bone
|
||||
|
||||
function Bone.new (data, skeleton, parent)
|
||||
if not data then error("data cannot be nil", 2) end
|
||||
if not skeleton then error("skeleton cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
data = data,
|
||||
skeleton = skeleton,
|
||||
parent = parent,
|
||||
children = { },
|
||||
x = 0, y = 0, rotation = 0, scaleX = 1, scaleY = 1, shearX = 0, shearY = 0,
|
||||
ax = 0, ay = 0, arotation = 0, ascaleX = 0, ascaleY = 0, ashearX = 0, ashearY = 0,
|
||||
appliedValid = false,
|
||||
|
||||
a = 0, b = 0, worldX = 0, -- a b x
|
||||
c = 0, d = 0, worldY = 0, -- c d y
|
||||
sorted = false,
|
||||
active = false
|
||||
}
|
||||
setmetatable(self, Bone)
|
||||
|
||||
self:setToSetupPose()
|
||||
return self
|
||||
end
|
||||
|
||||
function Bone:update ()
|
||||
self:updateWorldTransformWith(self.x, self.y, self.rotation, self.scaleX, self.scaleY, self.shearX, self.shearY)
|
||||
end
|
||||
|
||||
function Bone:updateWorldTransform ()
|
||||
self:updateWorldTransformWith(self.x, self.y, self.rotation, self.scaleX, self.scaleY, self.shearX, self.shearY)
|
||||
end
|
||||
|
||||
function Bone:updateWorldTransformWith (x, y, rotation, scaleX, scaleY, shearX, shearY)
|
||||
self.ax = x
|
||||
self.ay = y
|
||||
self.arotation = rotation
|
||||
self.ascaleX = scaleX
|
||||
self.ascaleY = scaleY
|
||||
self.ashearX = shearX
|
||||
self.ashearY = shearY
|
||||
self.appliedValid = true
|
||||
|
||||
local sx = self.skeleton.scaleX;
|
||||
local sy = self.skeleton.scaleY;
|
||||
|
||||
local parent = self.parent
|
||||
if parent == nil then
|
||||
local rotationY = rotation + 90 + shearY
|
||||
local rotationRad = math_rad(rotation + shearX)
|
||||
local rotationYRad = math_rad(rotationY)
|
||||
local skeleton = self.skeleton
|
||||
self.a = math_cos(rotationRad) * scaleX * sx
|
||||
self.b = math_cos(rotationYRad) * scaleY * sx
|
||||
self.c = math_sin(rotationRad) * scaleX * sy
|
||||
self.d = math_sin(rotationYRad) * scaleY * sy
|
||||
self.worldX = x * sx + skeleton.x
|
||||
self.worldY = y * sy + skeleton.y
|
||||
return
|
||||
end
|
||||
|
||||
local pa = parent.a
|
||||
local pb = parent.b
|
||||
local pc = parent.c
|
||||
local pd = parent.d
|
||||
self.worldX = pa * x + pb * y + parent.worldX
|
||||
self.worldY = pc * x + pd * y + parent.worldY
|
||||
|
||||
local transformMode = self.data.transformMode
|
||||
if transformMode == TransformMode.normal then
|
||||
local rotationY = rotation + 90 + shearY
|
||||
local la = math_cos(math_rad(rotation + shearX)) * scaleX
|
||||
local lb = math_cos(math_rad(rotationY)) * scaleY
|
||||
local lc = math_sin(math_rad(rotation + shearX)) * scaleX
|
||||
local ld = math_sin(math_rad(rotationY)) * scaleY
|
||||
self.a = pa * la + pb * lc
|
||||
self.b = pa * lb + pb * ld
|
||||
self.c = pc * la + pd * lc
|
||||
self.d = pc * lb + pd * ld
|
||||
return;
|
||||
elseif transformMode == TransformMode.onlyTranslation then
|
||||
local rotationY = rotation + 90 + shearY
|
||||
self.a = math_cos(math_rad(rotation + shearX)) * scaleX
|
||||
self.b = math_cos(math_rad(rotationY)) * scaleY
|
||||
self.c = math_sin(math_rad(rotation + shearX)) * scaleX
|
||||
self.d = math_sin(math_rad(rotationY)) * scaleY
|
||||
elseif transformMode == TransformMode.noRotationOrReflection then
|
||||
local s = pa * pa + pc * pc
|
||||
local prx = 0
|
||||
if s > 0.0001 then
|
||||
s = math_abs(pa * pd - pb * pc) / s
|
||||
pa = pa / self.skeleton.scaleX
|
||||
pc = pc / self.skeleton.scaleY
|
||||
pb = pc * s
|
||||
pd = pa * s
|
||||
prx = math_deg(math_atan2(pc, pa));
|
||||
else
|
||||
pa = 0;
|
||||
pc = 0;
|
||||
prx = 90 - math_deg(math_atan2(pd, pb));
|
||||
end
|
||||
local rx = rotation + shearX - prx
|
||||
local ry = rotation + shearY - prx + 90
|
||||
local la = math_cos(math_rad(rx)) * scaleX
|
||||
local lb = math_cos(math_rad(ry)) * scaleY
|
||||
local lc = math_sin(math_rad(rx)) * scaleX
|
||||
local ld = math_sin(math_rad(ry)) * scaleY
|
||||
self.a = pa * la - pb * lc
|
||||
self.b = pa * lb - pb * ld
|
||||
self.c = pc * la + pd * lc
|
||||
self.d = pc * lb + pd * ld
|
||||
|
||||
elseif transformMode == TransformMode.noScale or transformMode == TransformMode.noScaleOrReflection then
|
||||
local cos = math_cos(math_rad(rotation))
|
||||
local sin = math_sin(math_rad(rotation))
|
||||
local za = (pa * cos + pb * sin) / sx
|
||||
local zc = (pc * cos + pd * sin) / sy
|
||||
local s = math_sqrt(za * za + zc * zc)
|
||||
if s > 0.00001 then s = 1 / s end
|
||||
za = za * s
|
||||
zc = zc * s
|
||||
s = math_sqrt(za * za + zc * zc)
|
||||
if transformMode == TransformMode.noScale and pa * pd - pb * pc < 0 ~= (sx < 0) ~= (sy < 0) then
|
||||
s = -s
|
||||
end
|
||||
local r = math_pi / 2 + math_atan2(zc, za)
|
||||
local zb = math_cos(r) * s
|
||||
local zd = math_sin(r) * s
|
||||
local la = math_cos(math_rad(shearX)) * scaleX;
|
||||
local lb = math_cos(math_rad(90 + shearY)) * scaleY;
|
||||
local lc = math_sin(math_rad(shearX)) * scaleX;
|
||||
local ld = math_sin(math_rad(90 + shearY)) * scaleY;
|
||||
self.a = za * la + zb * lc
|
||||
self.b = za * lb + zb * ld
|
||||
self.c = zc * la + zd * lc
|
||||
self.d = zc * lb + zd * ld
|
||||
end
|
||||
|
||||
self.a = self.a * sx
|
||||
self.b = self.b * sx
|
||||
self.c = self.c * sy
|
||||
self.d = self.d * sy
|
||||
end
|
||||
|
||||
function Bone:setToSetupPose ()
|
||||
local data = self.data
|
||||
self.x = data.x
|
||||
self.y = data.y
|
||||
self.rotation = data.rotation
|
||||
self.scaleX = data.scaleX
|
||||
self.scaleY = data.scaleY
|
||||
self.shearX = data.shearX
|
||||
self.shearY = data.shearY
|
||||
end
|
||||
|
||||
function Bone:getWorldRotationX ()
|
||||
return math_deg(math_atan2(self.c, self.a))
|
||||
end
|
||||
|
||||
function Bone:getWorldRotationY ()
|
||||
return math_deg(math_atan2(self.d, self.b))
|
||||
end
|
||||
|
||||
function Bone:getWorldScaleX ()
|
||||
return math_sqrt(self.a * self.a + self.c * self.c)
|
||||
end
|
||||
|
||||
function Bone:getWorldScaleY ()
|
||||
return math_sqrt(self.b * self.b + self.d * self.d)
|
||||
end
|
||||
|
||||
function Bone:updateAppliedTransform ()
|
||||
local parent = self.parent
|
||||
if parent == nil then
|
||||
self.ax = self.worldX
|
||||
self.ay = self.worldY
|
||||
self.arotation = math_deg(math_atan2(self.c, self.a))
|
||||
self.ascaleX = math_sqrt(self.a * self.a + self.c * self.c)
|
||||
self.ascaleY = math_sqrt(self.b * self.b + self.d * self.d)
|
||||
self.ashearX = 0
|
||||
self.ashearY = math_deg(math_atan2(self.a * self.b + self.c * self.d, self.a * self.d - self.b * self.c))
|
||||
return
|
||||
end
|
||||
local pa = parent.a
|
||||
local pb = parent.b
|
||||
local pc = parent.c
|
||||
local pd = parent.d
|
||||
local pid = 1 / (pa * pd - pb * pc)
|
||||
local dx = self.worldX - parent.worldX
|
||||
local dy = self.worldY - parent.worldY
|
||||
self.ax = (dx * pd * pid - dy * pb * pid)
|
||||
self.ay = (dy * pa * pid - dx * pc * pid)
|
||||
local ia = pid * pd
|
||||
local id = pid * pa
|
||||
local ib = pid * pb
|
||||
local ic = pid * pc
|
||||
local ra = ia * self.a - ib * self.c
|
||||
local rb = ia * self.b - ib * self.d
|
||||
local rc = id * self.c - ic * self.a
|
||||
local rd = id * self.d - ic * self.b
|
||||
self.ashearX = 0
|
||||
self.ascaleX = math_sqrt(ra * ra + rc * rc)
|
||||
if self.ascaleX > 0.0001 then
|
||||
local det = ra * rd - rb * rc
|
||||
self.ascaleY = det / self.ascaleX
|
||||
self.ashearY = math_deg(math_atan2(ra * rb + rc * rd, det))
|
||||
self.arotation = math_deg(math_atan2(rc, ra))
|
||||
else
|
||||
self.ascaleX = 0
|
||||
self.ascaleY = math_sqrt(rb * rb + rd * rd)
|
||||
self.ashearY = 0
|
||||
self.arotation = 90 - math_deg(math_atan2(rd, rb))
|
||||
end
|
||||
end
|
||||
|
||||
function Bone:worldToLocal (world)
|
||||
local a = self.a
|
||||
local b = self.b
|
||||
local c = self.c
|
||||
local d = self.d
|
||||
local invDet = 1 / (a * d - b * c)
|
||||
local x = world[1] - self.worldX
|
||||
local y = world[2] - self.worldY
|
||||
world[1] = (x * d * invDet - y * b * invDet)
|
||||
world[2] = (y * a * invDet - x * c * invDet)
|
||||
return world
|
||||
end
|
||||
|
||||
function Bone:localToWorld (localCoords)
|
||||
local x = localCoords[1]
|
||||
local y = localCoords[2]
|
||||
localCoords[1] = x * self.a + y * self.b + self.worldX
|
||||
localCoords[2] = x * self.c + y * self.d + self.worldY
|
||||
return localCoords
|
||||
end
|
||||
|
||||
function Bone:worldToLocalRotation (worldRotation)
|
||||
local sin = math_sin(math_rad(worldRotation))
|
||||
local cos = math_cos(math_rad(worldRotation))
|
||||
return math_deg(math_atan2(self.a * sin - self.c * cos, self.d * cos - self.b * sin)) + self.rotation - self.shearX
|
||||
end
|
||||
|
||||
function Bone:localToWorldRotation (localRotation)
|
||||
localRotation = localRotation - (self.rotation - self.shearX)
|
||||
local sin = math_sin(math_rad(localRotation))
|
||||
local cos = math_cos(math_rad(localRotation))
|
||||
return math_deg(math_atan2(cos * self.c + sin * self.d, cos * self.a + sin * self.b))
|
||||
end
|
||||
|
||||
function Bone:rotateWorld (degrees)
|
||||
local a = self.a
|
||||
local b = self.b
|
||||
local c = self.c
|
||||
local d = self.d
|
||||
local degreesRad = math_rad(degrees)
|
||||
local cos = math_cos(degreesRad)
|
||||
local sin = math_sin(degreesRad)
|
||||
self.a = cos * a - sin * c
|
||||
self.b = cos * b - sin * d
|
||||
self.c = sin * a + cos * c
|
||||
self.d = sin * b + cos * d
|
||||
self.appliedValid = false
|
||||
end
|
||||
|
||||
return Bone
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local math_rad = math.rad
|
||||
local math_deg = math.deg
|
||||
local math_sin = math.sin
|
||||
local math_cos = math.cos
|
||||
local math_atan2 = math.atan2
|
||||
local math_sqrt = math.sqrt
|
||||
local math_abs = math.abs
|
||||
local math_pi = math.pi
|
||||
|
||||
local TransformMode = require "spine-lua.TransformMode"
|
||||
|
||||
function math.sign(x)
|
||||
if x<0 then
|
||||
return -1
|
||||
elseif x>0 then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
local math_sign = math.sign
|
||||
|
||||
local Bone = {}
|
||||
Bone.__index = Bone
|
||||
|
||||
function Bone.new (data, skeleton, parent)
|
||||
if not data then error("data cannot be nil", 2) end
|
||||
if not skeleton then error("skeleton cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
data = data,
|
||||
skeleton = skeleton,
|
||||
parent = parent,
|
||||
children = { },
|
||||
x = 0, y = 0, rotation = 0, scaleX = 1, scaleY = 1, shearX = 0, shearY = 0,
|
||||
ax = 0, ay = 0, arotation = 0, ascaleX = 0, ascaleY = 0, ashearX = 0, ashearY = 0,
|
||||
appliedValid = false,
|
||||
|
||||
a = 0, b = 0, worldX = 0, -- a b x
|
||||
c = 0, d = 0, worldY = 0, -- c d y
|
||||
sorted = false,
|
||||
active = false
|
||||
}
|
||||
setmetatable(self, Bone)
|
||||
|
||||
self:setToSetupPose()
|
||||
return self
|
||||
end
|
||||
|
||||
function Bone:update ()
|
||||
self:updateWorldTransformWith(self.x, self.y, self.rotation, self.scaleX, self.scaleY, self.shearX, self.shearY)
|
||||
end
|
||||
|
||||
function Bone:updateWorldTransform ()
|
||||
self:updateWorldTransformWith(self.x, self.y, self.rotation, self.scaleX, self.scaleY, self.shearX, self.shearY)
|
||||
end
|
||||
|
||||
function Bone:updateWorldTransformWith (x, y, rotation, scaleX, scaleY, shearX, shearY)
|
||||
self.ax = x
|
||||
self.ay = y
|
||||
self.arotation = rotation
|
||||
self.ascaleX = scaleX
|
||||
self.ascaleY = scaleY
|
||||
self.ashearX = shearX
|
||||
self.ashearY = shearY
|
||||
self.appliedValid = true
|
||||
|
||||
local sx = self.skeleton.scaleX;
|
||||
local sy = self.skeleton.scaleY;
|
||||
|
||||
local parent = self.parent
|
||||
if parent == nil then
|
||||
local rotationY = rotation + 90 + shearY
|
||||
local rotationRad = math_rad(rotation + shearX)
|
||||
local rotationYRad = math_rad(rotationY)
|
||||
local skeleton = self.skeleton
|
||||
self.a = math_cos(rotationRad) * scaleX * sx
|
||||
self.b = math_cos(rotationYRad) * scaleY * sx
|
||||
self.c = math_sin(rotationRad) * scaleX * sy
|
||||
self.d = math_sin(rotationYRad) * scaleY * sy
|
||||
self.worldX = x * sx + skeleton.x
|
||||
self.worldY = y * sy + skeleton.y
|
||||
return
|
||||
end
|
||||
|
||||
local pa = parent.a
|
||||
local pb = parent.b
|
||||
local pc = parent.c
|
||||
local pd = parent.d
|
||||
self.worldX = pa * x + pb * y + parent.worldX
|
||||
self.worldY = pc * x + pd * y + parent.worldY
|
||||
|
||||
local transformMode = self.data.transformMode
|
||||
if transformMode == TransformMode.normal then
|
||||
local rotationY = rotation + 90 + shearY
|
||||
local la = math_cos(math_rad(rotation + shearX)) * scaleX
|
||||
local lb = math_cos(math_rad(rotationY)) * scaleY
|
||||
local lc = math_sin(math_rad(rotation + shearX)) * scaleX
|
||||
local ld = math_sin(math_rad(rotationY)) * scaleY
|
||||
self.a = pa * la + pb * lc
|
||||
self.b = pa * lb + pb * ld
|
||||
self.c = pc * la + pd * lc
|
||||
self.d = pc * lb + pd * ld
|
||||
return;
|
||||
elseif transformMode == TransformMode.onlyTranslation then
|
||||
local rotationY = rotation + 90 + shearY
|
||||
self.a = math_cos(math_rad(rotation + shearX)) * scaleX
|
||||
self.b = math_cos(math_rad(rotationY)) * scaleY
|
||||
self.c = math_sin(math_rad(rotation + shearX)) * scaleX
|
||||
self.d = math_sin(math_rad(rotationY)) * scaleY
|
||||
elseif transformMode == TransformMode.noRotationOrReflection then
|
||||
local s = pa * pa + pc * pc
|
||||
local prx = 0
|
||||
if s > 0.0001 then
|
||||
s = math_abs(pa * pd - pb * pc) / s
|
||||
pa = pa / self.skeleton.scaleX
|
||||
pc = pc / self.skeleton.scaleY
|
||||
pb = pc * s
|
||||
pd = pa * s
|
||||
prx = math_deg(math_atan2(pc, pa));
|
||||
else
|
||||
pa = 0;
|
||||
pc = 0;
|
||||
prx = 90 - math_deg(math_atan2(pd, pb));
|
||||
end
|
||||
local rx = rotation + shearX - prx
|
||||
local ry = rotation + shearY - prx + 90
|
||||
local la = math_cos(math_rad(rx)) * scaleX
|
||||
local lb = math_cos(math_rad(ry)) * scaleY
|
||||
local lc = math_sin(math_rad(rx)) * scaleX
|
||||
local ld = math_sin(math_rad(ry)) * scaleY
|
||||
self.a = pa * la - pb * lc
|
||||
self.b = pa * lb - pb * ld
|
||||
self.c = pc * la + pd * lc
|
||||
self.d = pc * lb + pd * ld
|
||||
|
||||
elseif transformMode == TransformMode.noScale or transformMode == TransformMode.noScaleOrReflection then
|
||||
local cos = math_cos(math_rad(rotation))
|
||||
local sin = math_sin(math_rad(rotation))
|
||||
local za = (pa * cos + pb * sin) / sx
|
||||
local zc = (pc * cos + pd * sin) / sy
|
||||
local s = math_sqrt(za * za + zc * zc)
|
||||
if s > 0.00001 then s = 1 / s end
|
||||
za = za * s
|
||||
zc = zc * s
|
||||
s = math_sqrt(za * za + zc * zc)
|
||||
if transformMode == TransformMode.noScale and pa * pd - pb * pc < 0 ~= (sx < 0) ~= (sy < 0) then
|
||||
s = -s
|
||||
end
|
||||
local r = math_pi / 2 + math_atan2(zc, za)
|
||||
local zb = math_cos(r) * s
|
||||
local zd = math_sin(r) * s
|
||||
local la = math_cos(math_rad(shearX)) * scaleX;
|
||||
local lb = math_cos(math_rad(90 + shearY)) * scaleY;
|
||||
local lc = math_sin(math_rad(shearX)) * scaleX;
|
||||
local ld = math_sin(math_rad(90 + shearY)) * scaleY;
|
||||
self.a = za * la + zb * lc
|
||||
self.b = za * lb + zb * ld
|
||||
self.c = zc * la + zd * lc
|
||||
self.d = zc * lb + zd * ld
|
||||
end
|
||||
|
||||
self.a = self.a * sx
|
||||
self.b = self.b * sx
|
||||
self.c = self.c * sy
|
||||
self.d = self.d * sy
|
||||
end
|
||||
|
||||
function Bone:setToSetupPose ()
|
||||
local data = self.data
|
||||
self.x = data.x
|
||||
self.y = data.y
|
||||
self.rotation = data.rotation
|
||||
self.scaleX = data.scaleX
|
||||
self.scaleY = data.scaleY
|
||||
self.shearX = data.shearX
|
||||
self.shearY = data.shearY
|
||||
end
|
||||
|
||||
function Bone:getWorldRotationX ()
|
||||
return math_deg(math_atan2(self.c, self.a))
|
||||
end
|
||||
|
||||
function Bone:getWorldRotationY ()
|
||||
return math_deg(math_atan2(self.d, self.b))
|
||||
end
|
||||
|
||||
function Bone:getWorldScaleX ()
|
||||
return math_sqrt(self.a * self.a + self.c * self.c)
|
||||
end
|
||||
|
||||
function Bone:getWorldScaleY ()
|
||||
return math_sqrt(self.b * self.b + self.d * self.d)
|
||||
end
|
||||
|
||||
function Bone:updateAppliedTransform ()
|
||||
local parent = self.parent
|
||||
if parent == nil then
|
||||
self.ax = self.worldX
|
||||
self.ay = self.worldY
|
||||
self.arotation = math_deg(math_atan2(self.c, self.a))
|
||||
self.ascaleX = math_sqrt(self.a * self.a + self.c * self.c)
|
||||
self.ascaleY = math_sqrt(self.b * self.b + self.d * self.d)
|
||||
self.ashearX = 0
|
||||
self.ashearY = math_deg(math_atan2(self.a * self.b + self.c * self.d, self.a * self.d - self.b * self.c))
|
||||
return
|
||||
end
|
||||
local pa = parent.a
|
||||
local pb = parent.b
|
||||
local pc = parent.c
|
||||
local pd = parent.d
|
||||
local pid = 1 / (pa * pd - pb * pc)
|
||||
local dx = self.worldX - parent.worldX
|
||||
local dy = self.worldY - parent.worldY
|
||||
self.ax = (dx * pd * pid - dy * pb * pid)
|
||||
self.ay = (dy * pa * pid - dx * pc * pid)
|
||||
local ia = pid * pd
|
||||
local id = pid * pa
|
||||
local ib = pid * pb
|
||||
local ic = pid * pc
|
||||
local ra = ia * self.a - ib * self.c
|
||||
local rb = ia * self.b - ib * self.d
|
||||
local rc = id * self.c - ic * self.a
|
||||
local rd = id * self.d - ic * self.b
|
||||
self.ashearX = 0
|
||||
self.ascaleX = math_sqrt(ra * ra + rc * rc)
|
||||
if self.ascaleX > 0.0001 then
|
||||
local det = ra * rd - rb * rc
|
||||
self.ascaleY = det / self.ascaleX
|
||||
self.ashearY = math_deg(math_atan2(ra * rb + rc * rd, det))
|
||||
self.arotation = math_deg(math_atan2(rc, ra))
|
||||
else
|
||||
self.ascaleX = 0
|
||||
self.ascaleY = math_sqrt(rb * rb + rd * rd)
|
||||
self.ashearY = 0
|
||||
self.arotation = 90 - math_deg(math_atan2(rd, rb))
|
||||
end
|
||||
end
|
||||
|
||||
function Bone:worldToLocal (world)
|
||||
local a = self.a
|
||||
local b = self.b
|
||||
local c = self.c
|
||||
local d = self.d
|
||||
local invDet = 1 / (a * d - b * c)
|
||||
local x = world[1] - self.worldX
|
||||
local y = world[2] - self.worldY
|
||||
world[1] = (x * d * invDet - y * b * invDet)
|
||||
world[2] = (y * a * invDet - x * c * invDet)
|
||||
return world
|
||||
end
|
||||
|
||||
function Bone:localToWorld (localCoords)
|
||||
local x = localCoords[1]
|
||||
local y = localCoords[2]
|
||||
localCoords[1] = x * self.a + y * self.b + self.worldX
|
||||
localCoords[2] = x * self.c + y * self.d + self.worldY
|
||||
return localCoords
|
||||
end
|
||||
|
||||
function Bone:worldToLocalRotation (worldRotation)
|
||||
local sin = math_sin(math_rad(worldRotation))
|
||||
local cos = math_cos(math_rad(worldRotation))
|
||||
return math_deg(math_atan2(self.a * sin - self.c * cos, self.d * cos - self.b * sin)) + self.rotation - self.shearX
|
||||
end
|
||||
|
||||
function Bone:localToWorldRotation (localRotation)
|
||||
localRotation = localRotation - (self.rotation - self.shearX)
|
||||
local sin = math_sin(math_rad(localRotation))
|
||||
local cos = math_cos(math_rad(localRotation))
|
||||
return math_deg(math_atan2(cos * self.c + sin * self.d, cos * self.a + sin * self.b))
|
||||
end
|
||||
|
||||
function Bone:rotateWorld (degrees)
|
||||
local a = self.a
|
||||
local b = self.b
|
||||
local c = self.c
|
||||
local d = self.d
|
||||
local degreesRad = math_rad(degrees)
|
||||
local cos = math_cos(degreesRad)
|
||||
local sin = math_sin(degreesRad)
|
||||
self.a = cos * a - sin * c
|
||||
self.b = cos * b - sin * d
|
||||
self.c = sin * a + cos * c
|
||||
self.d = sin * b + cos * d
|
||||
self.appliedValid = false
|
||||
end
|
||||
|
||||
return Bone
|
||||
@ -1,55 +1,55 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local TransformMode = require "spine-lua.TransformMode"
|
||||
|
||||
local BoneData = {}
|
||||
function BoneData.new (index, name, parent)
|
||||
if index < 0 then error("index must be >= 0", 2) end
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
index = index,
|
||||
name = name,
|
||||
transformMode = TransformMode.normal,
|
||||
parent = parent,
|
||||
length = 0,
|
||||
x = 0, y = 0,
|
||||
rotation = 0,
|
||||
scaleX = 1, scaleY = 1,
|
||||
shearX = 0, shearY = 0,
|
||||
inheritRotation = true,
|
||||
inheritScale = true,
|
||||
skinRequired = false
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
return BoneData
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local TransformMode = require "spine-lua.TransformMode"
|
||||
|
||||
local BoneData = {}
|
||||
function BoneData.new (index, name, parent)
|
||||
if index < 0 then error("index must be >= 0", 2) end
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
index = index,
|
||||
name = name,
|
||||
transformMode = TransformMode.normal,
|
||||
parent = parent,
|
||||
length = 0,
|
||||
x = 0, y = 0,
|
||||
rotation = 0,
|
||||
scaleX = 1, scaleY = 1,
|
||||
shearX = 0, shearY = 0,
|
||||
inheritRotation = true,
|
||||
inheritScale = true,
|
||||
skinRequired = false
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
return BoneData
|
||||
@ -1,61 +1,61 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.AttachmentType"
|
||||
|
||||
local BoundingBoxAttachment = {}
|
||||
function BoundingBoxAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
type = AttachmentType.boundingbox,
|
||||
vertices = {}
|
||||
}
|
||||
|
||||
function self:computeWorldVertices (x, y, bone, worldVertices)
|
||||
x = x + bone.worldX
|
||||
y = y + bone.worldY
|
||||
local m00 = bone.m00
|
||||
local m01 = bone.m01
|
||||
local m10 = bone.m10
|
||||
local m11 = bone.m11
|
||||
local vertices = self.vertices
|
||||
local count = #vertices
|
||||
for i = 1, count, 2 do
|
||||
local px = vertices[i]
|
||||
local py = vertices[i + 1]
|
||||
worldVertices[i] = px * m00 + py * m01 + x
|
||||
worldVertices[i + 1] = px * m10 + py * m11 + y
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
return BoundingBoxAttachment
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.AttachmentType"
|
||||
|
||||
local BoundingBoxAttachment = {}
|
||||
function BoundingBoxAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
type = AttachmentType.boundingbox,
|
||||
vertices = {}
|
||||
}
|
||||
|
||||
function self:computeWorldVertices (x, y, bone, worldVertices)
|
||||
x = x + bone.worldX
|
||||
y = y + bone.worldY
|
||||
local m00 = bone.m00
|
||||
local m01 = bone.m01
|
||||
local m10 = bone.m10
|
||||
local m11 = bone.m11
|
||||
local vertices = self.vertices
|
||||
local count = #vertices
|
||||
for i = 1, count, 2 do
|
||||
local px = vertices[i]
|
||||
local py = vertices[i + 1]
|
||||
worldVertices[i] = px * m00 + py * m01 + x
|
||||
worldVertices[i + 1] = px * m10 + py * m11 + y
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
return BoundingBoxAttachment
|
||||
@ -1,83 +1,83 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local utils = require "spine-lua.utils"
|
||||
|
||||
local Color = {}
|
||||
Color.__index = Color
|
||||
|
||||
function Color.new ()
|
||||
local self = {
|
||||
r = 0, g = 0, b = 0, a = 0
|
||||
}
|
||||
setmetatable(self, Color)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Color.newWith (r, g, b, a)
|
||||
local self = {
|
||||
r = r, g = g, b = b, a = a
|
||||
}
|
||||
setmetatable(self, Color)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Color:set(r, g, b, a)
|
||||
self.r = r
|
||||
self.g = g
|
||||
self.b = b
|
||||
self.a = a
|
||||
end
|
||||
|
||||
function Color:setFrom(color)
|
||||
self.r = color.r
|
||||
self.g = color.g
|
||||
self.b = color.b
|
||||
self.a = color.a
|
||||
end
|
||||
|
||||
function Color:add(r, g, b, a)
|
||||
self.r = self.r + r
|
||||
self.g = self.g + g
|
||||
self.b = self.b + b
|
||||
self.a = self.a + a
|
||||
self:clamp()
|
||||
end
|
||||
|
||||
function Color:clamp()
|
||||
self.r = utils.clamp(self.r, 0, 1)
|
||||
self.g = utils.clamp(self.g, 0, 1)
|
||||
self.b = utils.clamp(self.b, 0, 1)
|
||||
self.a = utils.clamp(self.a, 0, 1)
|
||||
end
|
||||
|
||||
return Color
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local utils = require "spine-lua.utils"
|
||||
|
||||
local Color = {}
|
||||
Color.__index = Color
|
||||
|
||||
function Color.new ()
|
||||
local self = {
|
||||
r = 0, g = 0, b = 0, a = 0
|
||||
}
|
||||
setmetatable(self, Color)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Color.newWith (r, g, b, a)
|
||||
local self = {
|
||||
r = r, g = g, b = b, a = a
|
||||
}
|
||||
setmetatable(self, Color)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Color:set(r, g, b, a)
|
||||
self.r = r
|
||||
self.g = g
|
||||
self.b = b
|
||||
self.a = a
|
||||
end
|
||||
|
||||
function Color:setFrom(color)
|
||||
self.r = color.r
|
||||
self.g = color.g
|
||||
self.b = color.b
|
||||
self.a = color.a
|
||||
end
|
||||
|
||||
function Color:add(r, g, b, a)
|
||||
self.r = self.r + r
|
||||
self.g = self.g + g
|
||||
self.b = self.b + b
|
||||
self.a = self.a + a
|
||||
self:clamp()
|
||||
end
|
||||
|
||||
function Color:clamp()
|
||||
self.r = utils.clamp(self.r, 0, 1)
|
||||
self.g = utils.clamp(self.g, 0, 1)
|
||||
self.b = utils.clamp(self.b, 0, 1)
|
||||
self.a = utils.clamp(self.a, 0, 1)
|
||||
end
|
||||
|
||||
return Color
|
||||
@ -1,46 +1,46 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 Event = {}
|
||||
function Event.new (time, data)
|
||||
if not data then error("data cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
data = data,
|
||||
intValue = 0,
|
||||
floatValue = 0,
|
||||
stringValue = nil,
|
||||
time = time,
|
||||
volume = 1,
|
||||
balance = 0
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
return Event
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 Event = {}
|
||||
function Event.new (time, data)
|
||||
if not data then error("data cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
data = data,
|
||||
intValue = 0,
|
||||
floatValue = 0,
|
||||
stringValue = nil,
|
||||
time = time,
|
||||
volume = 1,
|
||||
balance = 0
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
return Event
|
||||
@ -1,46 +1,46 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 EventData = {}
|
||||
function EventData.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
intValue = 0,
|
||||
floatValue = 0,
|
||||
stringValue = nil,
|
||||
audioPath = nil,
|
||||
volume = 1,
|
||||
balance = 0
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
return EventData
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 EventData = {}
|
||||
function EventData.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
intValue = 0,
|
||||
floatValue = 0,
|
||||
stringValue = nil,
|
||||
audioPath = nil,
|
||||
volume = 1,
|
||||
balance = 0
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
return EventData
|
||||
@ -1,334 +1,334 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local math_pi = math.pi
|
||||
local math_atan2 = math.atan2
|
||||
local math_sqrt = math.sqrt
|
||||
local math_acos = math.acos
|
||||
local math_sin = math.sin
|
||||
local math_cos = math.cos
|
||||
local math_min = math.min
|
||||
local table_insert = table.insert
|
||||
local math_deg = math.deg
|
||||
local math_rad = math.rad
|
||||
local math_abs = math.abs
|
||||
|
||||
local TransformMode = require "spine-lua.TransformMode"
|
||||
|
||||
local IkConstraint = {}
|
||||
IkConstraint.__index = IkConstraint
|
||||
|
||||
function IkConstraint.new (data, skeleton)
|
||||
if not data then error("data cannot be nil", 2) end
|
||||
if not skeleton then error("skeleton cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
data = data,
|
||||
bones = {},
|
||||
target = nil,
|
||||
mix = data.mix,
|
||||
softness = data.softness,
|
||||
compress = data.compress,
|
||||
stretch = data.stretch,
|
||||
bendDirection = data.bendDirection,
|
||||
active = false
|
||||
}
|
||||
setmetatable(self, IkConstraint)
|
||||
|
||||
local self_bones = self.bones
|
||||
for _,boneData in ipairs(data.bones) do
|
||||
table_insert(self_bones, skeleton:findBone(boneData.name))
|
||||
end
|
||||
self.target = skeleton:findBone(data.target.name)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function IkConstraint:apply ()
|
||||
self:update()
|
||||
end
|
||||
|
||||
function IkConstraint:update ()
|
||||
local target = self.target
|
||||
local bones = self.bones
|
||||
local boneCount = #bones
|
||||
if boneCount == 1 then
|
||||
self:apply1(bones[1], target.worldX, target.worldY, self.compress, self.stretch, self.data.uniform, self.mix)
|
||||
elseif boneCount == 2 then
|
||||
self:apply2(bones[1], bones[2], target.worldX, target.worldY, self.bendDirection, self.stretch, self.softness, self.mix)
|
||||
end
|
||||
end
|
||||
|
||||
function IkConstraint:apply1 (bone, targetX, targetY, compress, stretch, uniform, alpha)
|
||||
if not bone.appliedValid then bone:updateAppliedTransform() end
|
||||
local p = bone.parent
|
||||
|
||||
local pa = p.a
|
||||
local pb = p.b
|
||||
local pc = p.c
|
||||
local pd = p.d
|
||||
local rotationIK = -bone.ashearX - bone.arotation
|
||||
local tx = 0
|
||||
local ty = 0
|
||||
|
||||
if bone.data.transformMode == TransformMode.onlyTranslation then
|
||||
tx = targetX - bone.worldX
|
||||
ty = targetY - bone.worldY
|
||||
elseif bone.data.transformMode == TransformMode.noRotationOrReflection then
|
||||
local s = math_abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
|
||||
local sa = pa / bone.skeleton.scaleX;
|
||||
local sc = pc / bone.skeleton.scaleY;
|
||||
pb = -sc * s * bone.skeleton.scaleX;
|
||||
pd = sa * s * bone.skeleton.scaleY;
|
||||
rotationIK = rotationIK + math_deg(math_atan2(sc, sa));
|
||||
|
||||
|
||||
local x = targetX - p.worldX
|
||||
local y = targetY - p.worldY
|
||||
local d = pa * pd - pb * pc
|
||||
tx = (x * pd - y * pb) / d - bone.ax
|
||||
ty = (y * pa - x * pc) / d - bone.ay
|
||||
else
|
||||
local x = targetX - p.worldX
|
||||
local y = targetY - p.worldY
|
||||
local d = pa * pd - pb * pc
|
||||
tx = (x * pd - y * pb) / d - bone.ax
|
||||
ty = (y * pa - x * pc) / d - bone.ay
|
||||
end
|
||||
rotationIK = rotationIK + math_deg(math_atan2(ty, tx))
|
||||
if bone.ascaleX < 0 then rotationIK = rotationIK + 180 end
|
||||
if rotationIK > 180 then
|
||||
rotationIK = rotationIK - 360
|
||||
elseif (rotationIK < -180) then
|
||||
rotationIK = rotationIK + 360
|
||||
end
|
||||
local sx = bone.ascaleX
|
||||
local sy = bone.ascaleY
|
||||
if compress or stretch then
|
||||
if bone.data.transformMode == TransformMode.noScale or bone.data.transformMode == TransformMode.noScaleOrReflection then
|
||||
tx = targetX - bone.worldX
|
||||
ty = targetY - bone.worldY
|
||||
end
|
||||
local b = bone.data.length * sx
|
||||
local dd = math_sqrt(tx * tx + ty * ty)
|
||||
if (compress and dd < b) or (stretch and dd > b) and b > 0.0001 then
|
||||
local s = (dd / b - 1) * alpha + 1
|
||||
sx = sx * s
|
||||
if uniform then sy = sy * s end
|
||||
end
|
||||
end
|
||||
bone:updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY)
|
||||
end
|
||||
|
||||
function IkConstraint:apply2 (parent, child, targetX, targetY, bendDir, stretch, softness, alpha)
|
||||
if alpha == 0 then
|
||||
child:updateWorldTransform()
|
||||
return
|
||||
end
|
||||
if not parent.appliedValid then parent:updateAppliedTransform() end
|
||||
if not child.appliedValid then child:updateAppliedTransform() end
|
||||
local px = parent.ax
|
||||
local py = parent.ay
|
||||
local psx = parent.ascaleX
|
||||
local sx = psx
|
||||
local psy = parent.ascaleY
|
||||
local csx = child.ascaleX
|
||||
local os1 = 0
|
||||
local os2 = 0
|
||||
local s2 = 0
|
||||
if psx < 0 then
|
||||
psx = -psx
|
||||
os1 = 180
|
||||
s2 = -1
|
||||
else
|
||||
os1 = 0
|
||||
s2 = 1
|
||||
end
|
||||
if psy < 0 then
|
||||
psy = -psy
|
||||
s2 = -s2
|
||||
end
|
||||
if csx < 0 then
|
||||
csx = -csx
|
||||
os2 = 180
|
||||
else
|
||||
os2 = 0
|
||||
end
|
||||
local cx = child.ax
|
||||
local cy = 0
|
||||
local cwx = 0
|
||||
local cwy = 0
|
||||
local a = parent.a
|
||||
local b = parent.b
|
||||
local c = parent.c
|
||||
local d = parent.d
|
||||
local u = math_abs(psx - psy) <= 0.0001
|
||||
if not u then
|
||||
cy = 0
|
||||
cwx = a * cx + parent.worldX
|
||||
cwy = c * cx + parent.worldY
|
||||
else
|
||||
cy = child.ay
|
||||
cwx = a * cx + b * cy + parent.worldX
|
||||
cwy = c * cx + d * cy + parent.worldY
|
||||
end
|
||||
local pp = parent.parent
|
||||
a = pp.a
|
||||
b = pp.b
|
||||
c = pp.c
|
||||
d = pp.d
|
||||
local id = 1 / (a * d - b * c)
|
||||
local x = cwx - pp.worldX
|
||||
local y = cwy - pp.worldY
|
||||
local dx = (x * d - y * b) * id - px
|
||||
local dy = (y * a - x * c) * id - py
|
||||
local l1 = math_sqrt(dx * dx + dy * dy)
|
||||
local l2 = child.data.length * csx
|
||||
local a1 = 0
|
||||
local a2 = 0
|
||||
if l1 < 0.0001 then
|
||||
self:apply1(parent, targetX, targetY, false, stretch, false, alpha)
|
||||
child:updateWorldTransformWith(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY)
|
||||
return
|
||||
end
|
||||
x = targetX - pp.worldX
|
||||
y = targetY - pp.worldY
|
||||
local tx = (x * d - y * b) * id - px
|
||||
local ty = (y * a - x * c) * id - py
|
||||
local dd = tx * tx + ty * ty
|
||||
if softness ~= 0 then
|
||||
softness = softness * (psx * (csx + 1) / 2)
|
||||
local td = math_sqrt(dd)
|
||||
local sd = td - l1 - l2 * psx + softness
|
||||
if sd > 0 then
|
||||
local p = math_min(1, sd / (softness * 2)) - 1
|
||||
p = (sd - softness * (1 - p * p)) / td
|
||||
tx = tx - p * tx
|
||||
ty = ty - p * ty
|
||||
dd = tx * tx + ty * ty
|
||||
end
|
||||
end
|
||||
|
||||
if u then
|
||||
l2 = l2 * psx
|
||||
local cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2)
|
||||
if cos < -1 then
|
||||
cos = -1
|
||||
elseif cos > 1 then
|
||||
cos = 1
|
||||
if stretch then sx = sx * ((math_sqrt(dd) / (l1 + l2) - 1) * alpha + 1) end
|
||||
end
|
||||
a2 = math_acos(cos) * bendDir
|
||||
a = l1 + l2 * cos
|
||||
b = l2 * math_sin(a2)
|
||||
a1 = math_atan2(ty * a - tx * b, tx * a + ty * b)
|
||||
else
|
||||
local skip = false
|
||||
a = psx * l2
|
||||
b = psy * l2
|
||||
local aa = a * a
|
||||
local bb = b * b
|
||||
local ta = math_atan2(ty, tx);
|
||||
c = bb * l1 * l1 + aa * dd - aa * bb
|
||||
local c1 = -2 * bb * l1
|
||||
local c2 = bb - aa
|
||||
d = c1 * c1 - 4 * c2 * c
|
||||
if d >= 0 then
|
||||
local q = math_sqrt(d);
|
||||
if (c1 < 0) then q = -q end
|
||||
q = -(c1 + q) / 2
|
||||
local r0 = q / c2
|
||||
local r1 = c / q
|
||||
local r = r1
|
||||
if math_abs(r0) < math_abs(r1) then r = r0 end
|
||||
if r * r <= dd then
|
||||
y = math_sqrt(dd - r * r) * bendDir
|
||||
a1 = ta - math_atan2(y, r)
|
||||
a2 = math_atan2(y / psy, (r - l1) / psx)
|
||||
skip = true
|
||||
end
|
||||
end
|
||||
if not skip then
|
||||
local minAngle = math_pi
|
||||
local minX = l1 - a
|
||||
local minDist = minX * minX
|
||||
local minY = 0;
|
||||
local maxAngle = 0
|
||||
local maxX = l1 + a
|
||||
local maxDist = maxX * maxX
|
||||
local maxY = 0
|
||||
c = -a * l1 / (aa - bb)
|
||||
if (c >= -1 and c <= 1) then
|
||||
c = math_acos(c)
|
||||
x = a * math_cos(c) + l1
|
||||
y = b * math_sin(c)
|
||||
d = x * x + y * y
|
||||
if d < minDist then
|
||||
minAngle = c
|
||||
minDist = d
|
||||
minX = x
|
||||
minY = y
|
||||
end
|
||||
if d > maxDist then
|
||||
maxAngle = c
|
||||
maxDist = d
|
||||
maxX = x
|
||||
maxY = y
|
||||
end
|
||||
end
|
||||
if dd <= (minDist + maxDist) / 2 then
|
||||
a1 = ta - math_atan2(minY * bendDir, minX)
|
||||
a2 = minAngle * bendDir
|
||||
else
|
||||
a1 = ta - math_atan2(maxY * bendDir, maxX)
|
||||
a2 = maxAngle * bendDir
|
||||
end
|
||||
end
|
||||
end
|
||||
local os = math_atan2(cy, cx) * s2
|
||||
local rotation = parent.arotation
|
||||
a1 = math_deg(a1 - os) + os1 - rotation
|
||||
if a1 > 180 then
|
||||
a1 = a1 - 360
|
||||
elseif a1 < -180 then
|
||||
a1 = a1 + 360
|
||||
end
|
||||
parent:updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0)
|
||||
rotation = child.rotation
|
||||
a2 = (math_deg(a2 + os) - child.ashearX) * s2 + os2 - rotation
|
||||
if a2 > 180 then
|
||||
a2 = a2 - 360
|
||||
elseif a2 < -180 then
|
||||
a2 = a2 + 360
|
||||
end
|
||||
child:updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY);
|
||||
end
|
||||
|
||||
return IkConstraint
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local math_pi = math.pi
|
||||
local math_atan2 = math.atan2
|
||||
local math_sqrt = math.sqrt
|
||||
local math_acos = math.acos
|
||||
local math_sin = math.sin
|
||||
local math_cos = math.cos
|
||||
local math_min = math.min
|
||||
local table_insert = table.insert
|
||||
local math_deg = math.deg
|
||||
local math_rad = math.rad
|
||||
local math_abs = math.abs
|
||||
|
||||
local TransformMode = require "spine-lua.TransformMode"
|
||||
|
||||
local IkConstraint = {}
|
||||
IkConstraint.__index = IkConstraint
|
||||
|
||||
function IkConstraint.new (data, skeleton)
|
||||
if not data then error("data cannot be nil", 2) end
|
||||
if not skeleton then error("skeleton cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
data = data,
|
||||
bones = {},
|
||||
target = nil,
|
||||
mix = data.mix,
|
||||
softness = data.softness,
|
||||
compress = data.compress,
|
||||
stretch = data.stretch,
|
||||
bendDirection = data.bendDirection,
|
||||
active = false
|
||||
}
|
||||
setmetatable(self, IkConstraint)
|
||||
|
||||
local self_bones = self.bones
|
||||
for _,boneData in ipairs(data.bones) do
|
||||
table_insert(self_bones, skeleton:findBone(boneData.name))
|
||||
end
|
||||
self.target = skeleton:findBone(data.target.name)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function IkConstraint:apply ()
|
||||
self:update()
|
||||
end
|
||||
|
||||
function IkConstraint:update ()
|
||||
local target = self.target
|
||||
local bones = self.bones
|
||||
local boneCount = #bones
|
||||
if boneCount == 1 then
|
||||
self:apply1(bones[1], target.worldX, target.worldY, self.compress, self.stretch, self.data.uniform, self.mix)
|
||||
elseif boneCount == 2 then
|
||||
self:apply2(bones[1], bones[2], target.worldX, target.worldY, self.bendDirection, self.stretch, self.softness, self.mix)
|
||||
end
|
||||
end
|
||||
|
||||
function IkConstraint:apply1 (bone, targetX, targetY, compress, stretch, uniform, alpha)
|
||||
if not bone.appliedValid then bone:updateAppliedTransform() end
|
||||
local p = bone.parent
|
||||
|
||||
local pa = p.a
|
||||
local pb = p.b
|
||||
local pc = p.c
|
||||
local pd = p.d
|
||||
local rotationIK = -bone.ashearX - bone.arotation
|
||||
local tx = 0
|
||||
local ty = 0
|
||||
|
||||
if bone.data.transformMode == TransformMode.onlyTranslation then
|
||||
tx = targetX - bone.worldX
|
||||
ty = targetY - bone.worldY
|
||||
elseif bone.data.transformMode == TransformMode.noRotationOrReflection then
|
||||
local s = math_abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
|
||||
local sa = pa / bone.skeleton.scaleX;
|
||||
local sc = pc / bone.skeleton.scaleY;
|
||||
pb = -sc * s * bone.skeleton.scaleX;
|
||||
pd = sa * s * bone.skeleton.scaleY;
|
||||
rotationIK = rotationIK + math_deg(math_atan2(sc, sa));
|
||||
|
||||
|
||||
local x = targetX - p.worldX
|
||||
local y = targetY - p.worldY
|
||||
local d = pa * pd - pb * pc
|
||||
tx = (x * pd - y * pb) / d - bone.ax
|
||||
ty = (y * pa - x * pc) / d - bone.ay
|
||||
else
|
||||
local x = targetX - p.worldX
|
||||
local y = targetY - p.worldY
|
||||
local d = pa * pd - pb * pc
|
||||
tx = (x * pd - y * pb) / d - bone.ax
|
||||
ty = (y * pa - x * pc) / d - bone.ay
|
||||
end
|
||||
rotationIK = rotationIK + math_deg(math_atan2(ty, tx))
|
||||
if bone.ascaleX < 0 then rotationIK = rotationIK + 180 end
|
||||
if rotationIK > 180 then
|
||||
rotationIK = rotationIK - 360
|
||||
elseif (rotationIK < -180) then
|
||||
rotationIK = rotationIK + 360
|
||||
end
|
||||
local sx = bone.ascaleX
|
||||
local sy = bone.ascaleY
|
||||
if compress or stretch then
|
||||
if bone.data.transformMode == TransformMode.noScale or bone.data.transformMode == TransformMode.noScaleOrReflection then
|
||||
tx = targetX - bone.worldX
|
||||
ty = targetY - bone.worldY
|
||||
end
|
||||
local b = bone.data.length * sx
|
||||
local dd = math_sqrt(tx * tx + ty * ty)
|
||||
if (compress and dd < b) or (stretch and dd > b) and b > 0.0001 then
|
||||
local s = (dd / b - 1) * alpha + 1
|
||||
sx = sx * s
|
||||
if uniform then sy = sy * s end
|
||||
end
|
||||
end
|
||||
bone:updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY)
|
||||
end
|
||||
|
||||
function IkConstraint:apply2 (parent, child, targetX, targetY, bendDir, stretch, softness, alpha)
|
||||
if alpha == 0 then
|
||||
child:updateWorldTransform()
|
||||
return
|
||||
end
|
||||
if not parent.appliedValid then parent:updateAppliedTransform() end
|
||||
if not child.appliedValid then child:updateAppliedTransform() end
|
||||
local px = parent.ax
|
||||
local py = parent.ay
|
||||
local psx = parent.ascaleX
|
||||
local sx = psx
|
||||
local psy = parent.ascaleY
|
||||
local csx = child.ascaleX
|
||||
local os1 = 0
|
||||
local os2 = 0
|
||||
local s2 = 0
|
||||
if psx < 0 then
|
||||
psx = -psx
|
||||
os1 = 180
|
||||
s2 = -1
|
||||
else
|
||||
os1 = 0
|
||||
s2 = 1
|
||||
end
|
||||
if psy < 0 then
|
||||
psy = -psy
|
||||
s2 = -s2
|
||||
end
|
||||
if csx < 0 then
|
||||
csx = -csx
|
||||
os2 = 180
|
||||
else
|
||||
os2 = 0
|
||||
end
|
||||
local cx = child.ax
|
||||
local cy = 0
|
||||
local cwx = 0
|
||||
local cwy = 0
|
||||
local a = parent.a
|
||||
local b = parent.b
|
||||
local c = parent.c
|
||||
local d = parent.d
|
||||
local u = math_abs(psx - psy) <= 0.0001
|
||||
if not u then
|
||||
cy = 0
|
||||
cwx = a * cx + parent.worldX
|
||||
cwy = c * cx + parent.worldY
|
||||
else
|
||||
cy = child.ay
|
||||
cwx = a * cx + b * cy + parent.worldX
|
||||
cwy = c * cx + d * cy + parent.worldY
|
||||
end
|
||||
local pp = parent.parent
|
||||
a = pp.a
|
||||
b = pp.b
|
||||
c = pp.c
|
||||
d = pp.d
|
||||
local id = 1 / (a * d - b * c)
|
||||
local x = cwx - pp.worldX
|
||||
local y = cwy - pp.worldY
|
||||
local dx = (x * d - y * b) * id - px
|
||||
local dy = (y * a - x * c) * id - py
|
||||
local l1 = math_sqrt(dx * dx + dy * dy)
|
||||
local l2 = child.data.length * csx
|
||||
local a1 = 0
|
||||
local a2 = 0
|
||||
if l1 < 0.0001 then
|
||||
self:apply1(parent, targetX, targetY, false, stretch, false, alpha)
|
||||
child:updateWorldTransformWith(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY)
|
||||
return
|
||||
end
|
||||
x = targetX - pp.worldX
|
||||
y = targetY - pp.worldY
|
||||
local tx = (x * d - y * b) * id - px
|
||||
local ty = (y * a - x * c) * id - py
|
||||
local dd = tx * tx + ty * ty
|
||||
if softness ~= 0 then
|
||||
softness = softness * (psx * (csx + 1) / 2)
|
||||
local td = math_sqrt(dd)
|
||||
local sd = td - l1 - l2 * psx + softness
|
||||
if sd > 0 then
|
||||
local p = math_min(1, sd / (softness * 2)) - 1
|
||||
p = (sd - softness * (1 - p * p)) / td
|
||||
tx = tx - p * tx
|
||||
ty = ty - p * ty
|
||||
dd = tx * tx + ty * ty
|
||||
end
|
||||
end
|
||||
|
||||
if u then
|
||||
l2 = l2 * psx
|
||||
local cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2)
|
||||
if cos < -1 then
|
||||
cos = -1
|
||||
elseif cos > 1 then
|
||||
cos = 1
|
||||
if stretch then sx = sx * ((math_sqrt(dd) / (l1 + l2) - 1) * alpha + 1) end
|
||||
end
|
||||
a2 = math_acos(cos) * bendDir
|
||||
a = l1 + l2 * cos
|
||||
b = l2 * math_sin(a2)
|
||||
a1 = math_atan2(ty * a - tx * b, tx * a + ty * b)
|
||||
else
|
||||
local skip = false
|
||||
a = psx * l2
|
||||
b = psy * l2
|
||||
local aa = a * a
|
||||
local bb = b * b
|
||||
local ta = math_atan2(ty, tx);
|
||||
c = bb * l1 * l1 + aa * dd - aa * bb
|
||||
local c1 = -2 * bb * l1
|
||||
local c2 = bb - aa
|
||||
d = c1 * c1 - 4 * c2 * c
|
||||
if d >= 0 then
|
||||
local q = math_sqrt(d);
|
||||
if (c1 < 0) then q = -q end
|
||||
q = -(c1 + q) / 2
|
||||
local r0 = q / c2
|
||||
local r1 = c / q
|
||||
local r = r1
|
||||
if math_abs(r0) < math_abs(r1) then r = r0 end
|
||||
if r * r <= dd then
|
||||
y = math_sqrt(dd - r * r) * bendDir
|
||||
a1 = ta - math_atan2(y, r)
|
||||
a2 = math_atan2(y / psy, (r - l1) / psx)
|
||||
skip = true
|
||||
end
|
||||
end
|
||||
if not skip then
|
||||
local minAngle = math_pi
|
||||
local minX = l1 - a
|
||||
local minDist = minX * minX
|
||||
local minY = 0;
|
||||
local maxAngle = 0
|
||||
local maxX = l1 + a
|
||||
local maxDist = maxX * maxX
|
||||
local maxY = 0
|
||||
c = -a * l1 / (aa - bb)
|
||||
if (c >= -1 and c <= 1) then
|
||||
c = math_acos(c)
|
||||
x = a * math_cos(c) + l1
|
||||
y = b * math_sin(c)
|
||||
d = x * x + y * y
|
||||
if d < minDist then
|
||||
minAngle = c
|
||||
minDist = d
|
||||
minX = x
|
||||
minY = y
|
||||
end
|
||||
if d > maxDist then
|
||||
maxAngle = c
|
||||
maxDist = d
|
||||
maxX = x
|
||||
maxY = y
|
||||
end
|
||||
end
|
||||
if dd <= (minDist + maxDist) / 2 then
|
||||
a1 = ta - math_atan2(minY * bendDir, minX)
|
||||
a2 = minAngle * bendDir
|
||||
else
|
||||
a1 = ta - math_atan2(maxY * bendDir, maxX)
|
||||
a2 = maxAngle * bendDir
|
||||
end
|
||||
end
|
||||
end
|
||||
local os = math_atan2(cy, cx) * s2
|
||||
local rotation = parent.arotation
|
||||
a1 = math_deg(a1 - os) + os1 - rotation
|
||||
if a1 > 180 then
|
||||
a1 = a1 - 360
|
||||
elseif a1 < -180 then
|
||||
a1 = a1 + 360
|
||||
end
|
||||
parent:updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0)
|
||||
rotation = child.rotation
|
||||
a2 = (math_deg(a2 + os) - child.ashearX) * s2 + os2 - rotation
|
||||
if a2 > 180 then
|
||||
a2 = a2 - 360
|
||||
elseif a2 < -180 then
|
||||
a2 = a2 + 360
|
||||
end
|
||||
child:updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY);
|
||||
end
|
||||
|
||||
return IkConstraint
|
||||
@ -1,50 +1,50 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 IkConstraintData = {}
|
||||
function IkConstraintData.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
order = 0,
|
||||
skinRequired = false,
|
||||
bones = {},
|
||||
target = nil,
|
||||
bendDirection = 1,
|
||||
compress = false,
|
||||
stretch = false,
|
||||
uniform = false,
|
||||
mix = 1,
|
||||
softness = 0
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
return IkConstraintData
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 IkConstraintData = {}
|
||||
function IkConstraintData.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
order = 0,
|
||||
skinRequired = false,
|
||||
bones = {},
|
||||
target = nil,
|
||||
bendDirection = 1,
|
||||
compress = false,
|
||||
stretch = false,
|
||||
uniform = false,
|
||||
mix = 1,
|
||||
softness = 0
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
return IkConstraintData
|
||||
@ -1,93 +1,93 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.AttachmentType"
|
||||
|
||||
local MeshAttachment = {}
|
||||
function MeshAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
type = AttachmentType.mesh,
|
||||
vertices = nil,
|
||||
uvs = nil,
|
||||
regionUVs = nil,
|
||||
triangles = nil,
|
||||
hullLength = 0,
|
||||
r = 1, g = 1, b = 1, a = 1,
|
||||
path = nil,
|
||||
rendererObject = nil,
|
||||
regionU = 0, regionV = 0, regionU2 = 1, regionV2 = 1, regionRotate = false,
|
||||
regionOffsetX = 0, regionOffsetY = 0,
|
||||
regionWidth = 0, regionHeight = 0,
|
||||
regionOriginalWidth = 0, regionOriginalHeight = 0,
|
||||
edges = nil,
|
||||
width = 0, height = 0
|
||||
}
|
||||
|
||||
function self:updateUVs ()
|
||||
local width, height = self.regionU2 - self.regionU, self.regionV2 - self.regionV
|
||||
local n = #self.regionUVs
|
||||
if not self.uvs or #self.uvs ~= n then
|
||||
self.uvs = {}
|
||||
end
|
||||
if self.regionRotate then
|
||||
for i = 1, n, 2 do
|
||||
self.uvs[i] = self.regionU + self.regionUVs[i + 1] * width
|
||||
self.uvs[i + 1] = self.regionV + height - self.regionUVs[i] * height
|
||||
end
|
||||
else
|
||||
for i = 1, n, 2 do
|
||||
self.uvs[i] = self.regionU + self.regionUVs[i] * width
|
||||
self.uvs[i + 1] = self.regionV + self.regionUVs[i + 1] * height
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function self:computeWorldVertices (x, y, slot, worldVertices)
|
||||
local bone = slot.bone
|
||||
x,y=slot.bone.skeleton.x,slot.bone.skeleton.y
|
||||
x = x + bone.worldX
|
||||
y = y + bone.worldY
|
||||
local m00, m01, m10, m11 = bone.m00, bone.m01, bone.m10, bone.m11
|
||||
local vertices = self.vertices
|
||||
local verticesCount = #vertices
|
||||
if slot.deform and #slot.deform == verticesCount then vertices = slot.deform end
|
||||
for i = 1, verticesCount, 2 do
|
||||
local vx = vertices[i]
|
||||
local vy = vertices[i + 1]
|
||||
worldVertices[i] = vx * m00 + vy * m01 + x
|
||||
worldVertices[i + 1] = vx * m10 + vy * m11 + y
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
return MeshAttachment
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.AttachmentType"
|
||||
|
||||
local MeshAttachment = {}
|
||||
function MeshAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
type = AttachmentType.mesh,
|
||||
vertices = nil,
|
||||
uvs = nil,
|
||||
regionUVs = nil,
|
||||
triangles = nil,
|
||||
hullLength = 0,
|
||||
r = 1, g = 1, b = 1, a = 1,
|
||||
path = nil,
|
||||
rendererObject = nil,
|
||||
regionU = 0, regionV = 0, regionU2 = 1, regionV2 = 1, regionRotate = false,
|
||||
regionOffsetX = 0, regionOffsetY = 0,
|
||||
regionWidth = 0, regionHeight = 0,
|
||||
regionOriginalWidth = 0, regionOriginalHeight = 0,
|
||||
edges = nil,
|
||||
width = 0, height = 0
|
||||
}
|
||||
|
||||
function self:updateUVs ()
|
||||
local width, height = self.regionU2 - self.regionU, self.regionV2 - self.regionV
|
||||
local n = #self.regionUVs
|
||||
if not self.uvs or #self.uvs ~= n then
|
||||
self.uvs = {}
|
||||
end
|
||||
if self.regionRotate then
|
||||
for i = 1, n, 2 do
|
||||
self.uvs[i] = self.regionU + self.regionUVs[i + 1] * width
|
||||
self.uvs[i + 1] = self.regionV + height - self.regionUVs[i] * height
|
||||
end
|
||||
else
|
||||
for i = 1, n, 2 do
|
||||
self.uvs[i] = self.regionU + self.regionUVs[i] * width
|
||||
self.uvs[i + 1] = self.regionV + self.regionUVs[i + 1] * height
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function self:computeWorldVertices (x, y, slot, worldVertices)
|
||||
local bone = slot.bone
|
||||
x,y=slot.bone.skeleton.x,slot.bone.skeleton.y
|
||||
x = x + bone.worldX
|
||||
y = y + bone.worldY
|
||||
local m00, m01, m10, m11 = bone.m00, bone.m01, bone.m10, bone.m11
|
||||
local vertices = self.vertices
|
||||
local verticesCount = #vertices
|
||||
if slot.deform and #slot.deform == verticesCount then vertices = slot.deform end
|
||||
for i = 1, verticesCount, 2 do
|
||||
local vx = vertices[i]
|
||||
local vy = vertices[i + 1]
|
||||
worldVertices[i] = vx * m00 + vy * m01 + x
|
||||
worldVertices[i + 1] = vx * m10 + vy * m11 + y
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
return MeshAttachment
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,70 +1,70 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 PathConstraintData = {}
|
||||
function PathConstraintData.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
order = 0,
|
||||
skinRequired = false,
|
||||
bones = {},
|
||||
target = nil,
|
||||
positionMode = nil,
|
||||
spacingMode = nil,
|
||||
rotateMode = nil,
|
||||
offsetRotation = 0,
|
||||
position = 0,
|
||||
spacing = 0,
|
||||
rotateMix = 0,
|
||||
translateMix = 0
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
PathConstraintData.PositionMode = {
|
||||
fixed = 0,
|
||||
percent = 1
|
||||
}
|
||||
|
||||
PathConstraintData.SpacingMode = {
|
||||
length = 0,
|
||||
fixed = 1,
|
||||
percent = 2
|
||||
}
|
||||
|
||||
PathConstraintData.RotateMode = {
|
||||
tangent = 0,
|
||||
chain = 1,
|
||||
chainscale = 2
|
||||
}
|
||||
|
||||
return PathConstraintData
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 PathConstraintData = {}
|
||||
function PathConstraintData.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
order = 0,
|
||||
skinRequired = false,
|
||||
bones = {},
|
||||
target = nil,
|
||||
positionMode = nil,
|
||||
spacingMode = nil,
|
||||
rotateMode = nil,
|
||||
offsetRotation = 0,
|
||||
position = 0,
|
||||
spacing = 0,
|
||||
rotateMix = 0,
|
||||
translateMix = 0
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
PathConstraintData.PositionMode = {
|
||||
fixed = 0,
|
||||
percent = 1
|
||||
}
|
||||
|
||||
PathConstraintData.SpacingMode = {
|
||||
length = 0,
|
||||
fixed = 1,
|
||||
percent = 2
|
||||
}
|
||||
|
||||
PathConstraintData.RotateMode = {
|
||||
tangent = 0,
|
||||
chain = 1,
|
||||
chainscale = 2
|
||||
}
|
||||
|
||||
return PathConstraintData
|
||||
@ -1,100 +1,100 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.AttachmentType"
|
||||
|
||||
local RegionAttachment = {}
|
||||
function RegionAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
type = AttachmentType.region,
|
||||
x = 0, y = 0,
|
||||
rotation = 0,
|
||||
scaleX = 1, scaleY = 1,
|
||||
width = 0, height = 0,
|
||||
offset = {},
|
||||
uvs = {},
|
||||
r = 1, g = 1, b = 1, a = 1,
|
||||
path = nil,
|
||||
rendererObject = nil,
|
||||
regionOffsetX = 0, regionOffsetY = 0,
|
||||
regionWidth = 0, regionHeight = 0,
|
||||
regionOriginalWidth = 0, regionOriginalHeight = 0
|
||||
}
|
||||
|
||||
function self:updateOffset ()
|
||||
local regionScaleX = self.width / self.regionOriginalWidth * self.scaleX
|
||||
local regionScaleY = self.height / self.regionOriginalHeight * self.scaleY
|
||||
local localX = -self.width / 2 * self.scaleX + self.regionOffsetX * regionScaleX
|
||||
local localY = -self.height / 2 * self.scaleY + self.regionOffsetY * regionScaleY
|
||||
local localX2 = localX + self.regionWidth * regionScaleX
|
||||
local localY2 = localY + self.regionHeight * regionScaleY
|
||||
local radians = self.rotation * math.pi / 180
|
||||
local cos = math.cos(radians)
|
||||
local sin = math.sin(radians)
|
||||
local localXCos = localX * cos + self.x
|
||||
local localXSin = localX * sin
|
||||
local localYCos = localY * cos + self.y
|
||||
local localYSin = localY * sin
|
||||
local localX2Cos = localX2 * cos + self.x
|
||||
local localX2Sin = localX2 * sin
|
||||
local localY2Cos = localY2 * cos + self.y
|
||||
local localY2Sin = localY2 * sin
|
||||
local offset = self.offset
|
||||
offset[0] = localXCos - localYSin -- X1
|
||||
offset[1] = localYCos + localXSin -- Y1
|
||||
offset[2] = localXCos - localY2Sin -- X2
|
||||
offset[3] = localY2Cos + localXSin -- Y2
|
||||
offset[4] = localX2Cos - localY2Sin -- X3
|
||||
offset[5] = localY2Cos + localX2Sin -- Y3
|
||||
offset[6] = localX2Cos - localYSin -- X4
|
||||
offset[7] = localYCos + localX2Sin -- Y4
|
||||
end
|
||||
|
||||
function self:computeWorldVertices (x, y, bone, worldVertices)
|
||||
x = x + bone.worldX
|
||||
y = y + bone.worldY
|
||||
local m00, m01, m10, m11 = bone.m00, bone.m01, bone.m10, bone.m11
|
||||
local offset = self.offset
|
||||
local vertices = self.vertices;
|
||||
vertices[0] = offset[0] * m00 + offset[1] * m01 + x
|
||||
vertices[1] = offset[0] * m10 + offset[1] * m11 + y
|
||||
vertices[2] = offset[2] * m00 + offset[3] * m01 + x
|
||||
vertices[3] = offset[2] * m10 + offset[3] * m11 + y
|
||||
vertices[4] = offset[4] * m00 + offset[5] * m01 + x
|
||||
vertices[5] = offset[4] * m10 + offset[5] * m11 + y
|
||||
vertices[6] = offset[6] * m00 + offset[7] * m01 + x
|
||||
vertices[7] = offset[6] * m10 + offset[7] * m11 + y
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
return RegionAttachment
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.AttachmentType"
|
||||
|
||||
local RegionAttachment = {}
|
||||
function RegionAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
type = AttachmentType.region,
|
||||
x = 0, y = 0,
|
||||
rotation = 0,
|
||||
scaleX = 1, scaleY = 1,
|
||||
width = 0, height = 0,
|
||||
offset = {},
|
||||
uvs = {},
|
||||
r = 1, g = 1, b = 1, a = 1,
|
||||
path = nil,
|
||||
rendererObject = nil,
|
||||
regionOffsetX = 0, regionOffsetY = 0,
|
||||
regionWidth = 0, regionHeight = 0,
|
||||
regionOriginalWidth = 0, regionOriginalHeight = 0
|
||||
}
|
||||
|
||||
function self:updateOffset ()
|
||||
local regionScaleX = self.width / self.regionOriginalWidth * self.scaleX
|
||||
local regionScaleY = self.height / self.regionOriginalHeight * self.scaleY
|
||||
local localX = -self.width / 2 * self.scaleX + self.regionOffsetX * regionScaleX
|
||||
local localY = -self.height / 2 * self.scaleY + self.regionOffsetY * regionScaleY
|
||||
local localX2 = localX + self.regionWidth * regionScaleX
|
||||
local localY2 = localY + self.regionHeight * regionScaleY
|
||||
local radians = self.rotation * math.pi / 180
|
||||
local cos = math.cos(radians)
|
||||
local sin = math.sin(radians)
|
||||
local localXCos = localX * cos + self.x
|
||||
local localXSin = localX * sin
|
||||
local localYCos = localY * cos + self.y
|
||||
local localYSin = localY * sin
|
||||
local localX2Cos = localX2 * cos + self.x
|
||||
local localX2Sin = localX2 * sin
|
||||
local localY2Cos = localY2 * cos + self.y
|
||||
local localY2Sin = localY2 * sin
|
||||
local offset = self.offset
|
||||
offset[0] = localXCos - localYSin -- X1
|
||||
offset[1] = localYCos + localXSin -- Y1
|
||||
offset[2] = localXCos - localY2Sin -- X2
|
||||
offset[3] = localY2Cos + localXSin -- Y2
|
||||
offset[4] = localX2Cos - localY2Sin -- X3
|
||||
offset[5] = localY2Cos + localX2Sin -- Y3
|
||||
offset[6] = localX2Cos - localYSin -- X4
|
||||
offset[7] = localYCos + localX2Sin -- Y4
|
||||
end
|
||||
|
||||
function self:computeWorldVertices (x, y, bone, worldVertices)
|
||||
x = x + bone.worldX
|
||||
y = y + bone.worldY
|
||||
local m00, m01, m10, m11 = bone.m00, bone.m01, bone.m10, bone.m11
|
||||
local offset = self.offset
|
||||
local vertices = self.vertices;
|
||||
vertices[0] = offset[0] * m00 + offset[1] * m01 + x
|
||||
vertices[1] = offset[0] * m10 + offset[1] * m11 + y
|
||||
vertices[2] = offset[2] * m00 + offset[3] * m01 + x
|
||||
vertices[3] = offset[2] * m10 + offset[3] * m11 + y
|
||||
vertices[4] = offset[4] * m00 + offset[5] * m01 + x
|
||||
vertices[5] = offset[4] * m10 + offset[5] * m11 + y
|
||||
vertices[6] = offset[6] * m00 + offset[7] * m01 + x
|
||||
vertices[7] = offset[6] * m10 + offset[7] * m11 + y
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
return RegionAttachment
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,199 +1,199 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local utils = require "spine-lua.utils"
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local math_min = math.min
|
||||
local math_max = math.max
|
||||
local ipairs = ipairs
|
||||
local table_insert = table.insert
|
||||
|
||||
local SkeletonBounds = {}
|
||||
SkeletonBounds.__index = SkeletonBounds
|
||||
|
||||
function SkeletonBounds.new ()
|
||||
local self = {
|
||||
minX = 0, minY = 0, maxX = 0, maxY = 0,
|
||||
polygons = {},
|
||||
boundingBoxes = {},
|
||||
}
|
||||
setmetatable(self, SkeletonBounds)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function SkeletonBounds:update (skeleton, updateAabb)
|
||||
if skeleton == nil then error("skeleton cannot be null", 2) end
|
||||
local boundingBoxes = {}
|
||||
self.boundingBoxes = boundingBoxes
|
||||
local polygons = {}
|
||||
self.polygons = polygons
|
||||
local slots = skeleton.slots
|
||||
|
||||
for _,slot in ipairs(skeleton.slots) do
|
||||
if (slot.bone.active) then
|
||||
local attachment = slot.attachment
|
||||
if attachment and attachment.type == AttachmentType.boundingbox then
|
||||
local boundingBox = attachment
|
||||
table_insert(boundingBoxes, boundingBox)
|
||||
|
||||
local polygon = {}
|
||||
table_insert(polygons, polygon)
|
||||
|
||||
boundingBox:computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if updateAabb then
|
||||
self:aabbCompute()
|
||||
else
|
||||
self.minX = 9999999
|
||||
self.minY = 9999999
|
||||
self.maxX = -9999999
|
||||
self.maxY = -9999999
|
||||
end
|
||||
end
|
||||
|
||||
function SkeletonBounds:aabbCompute ()
|
||||
local minX, minY, maxX, maxY = 9999999, 9999999, -9999999, -9999999
|
||||
local polygons = self.polygons
|
||||
for _,vertices in ipairs(polygons) do
|
||||
local count = #vertices
|
||||
for ii = 1, count, 2 do
|
||||
local x = vertices[ii]
|
||||
local y = vertices[ii + 1]
|
||||
minX = math_min(minX, x)
|
||||
minY = math_min(minY, y)
|
||||
maxX = math_max(maxX, x)
|
||||
maxY = math_max(maxY, y)
|
||||
end
|
||||
end
|
||||
self.minX = minX
|
||||
self.minY = minY
|
||||
self.maxX = maxX
|
||||
self.maxY = maxY
|
||||
end
|
||||
|
||||
function SkeletonBounds:aabbContainsPoint (x, y)
|
||||
return x >= self.minX and x <= self.maxX and y >= self.minY and y <= self.maxY
|
||||
end
|
||||
|
||||
function SkeletonBounds:aabbIntersectsSegment (x1, y1, x2, y2)
|
||||
local minX, minY, maxX, maxY = self.minX, self.minY, self.maxX, self.maxY
|
||||
if (x1 <= minX and x2 <= minX) or (y1 <= minY and y2 <= minY) or (x1 >= maxX and x2 >= maxX) or (y1 >= maxY and y2 >= maxY) then
|
||||
return false
|
||||
end
|
||||
local m = (y2 - y1) / (x2 - x1)
|
||||
local y = m * (minX - x1) + y1
|
||||
if y > minY and y < maxY then return true end
|
||||
y = m * (maxX - x1) + y1
|
||||
if y > minY and y < maxY then return true end
|
||||
local x = (minY - y1) / m + x1
|
||||
if x > minX and x < maxX then return true end
|
||||
x = (maxY - y1) / m + x1
|
||||
if x > minX and x < maxX then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
function SkeletonBounds:aabbIntersectsSkeleton (bounds)
|
||||
return self.minX < bounds.maxX and self.maxX > bounds.minX and self.minY < bounds.maxY and self.maxY > bounds.minY
|
||||
end
|
||||
|
||||
function SkeletonBounds:containsPoint (x, y)
|
||||
for i,polygon in ipairs(self.polygons) do
|
||||
if self:polygonContainsPoint(polygon, x, y) then return self.boundingBoxes[i] end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonBounds:intersectsSegment (x1, y1, x2, y2)
|
||||
for i,polygon in ipairs(self.polygons) do
|
||||
if self:polygonIntersectsSegment(polygon, x1, y1, x2, y2) then return self.boundingBoxes[i] end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonBounds:polygonContainsPoint (polygon, x, y)
|
||||
local nn = #polygon
|
||||
local prevIndex = nn - 1
|
||||
local inside = false
|
||||
for ii = 1, nn, 2 do
|
||||
local vertexY = polygon[ii + 1]
|
||||
local prevY = polygon[prevIndex + 1]
|
||||
if (vertexY < y and prevY >= y) or (prevY < y and vertexY >= y) then
|
||||
local vertexX = polygon[ii]
|
||||
if vertexX + (y - vertexY) / (prevY - vertexY) * (polygon[prevIndex] - vertexX) < x then inside = not inside end
|
||||
end
|
||||
prevIndex = ii
|
||||
end
|
||||
return inside
|
||||
end
|
||||
|
||||
function SkeletonBounds:polygonIntersectsSegment (polygon, x1, y1, x2, y2)
|
||||
local nn = #polygon
|
||||
local width12, height12 = x1 - x2, y1 - y2
|
||||
local det1 = x1 * y2 - y1 * x2
|
||||
local x3, y3 = polygon[nn - 2], polygon[nn - 1]
|
||||
for ii = 1, nn, 2 do
|
||||
local x4, y4 = polygon[ii], polygon[ii + 1]
|
||||
local det2 = x3 * y4 - y3 * x4
|
||||
local width34, height34 = x3 - x4, y3 - y4
|
||||
local det3 = width12 * height34 - height12 * width34
|
||||
local x = (det1 * width34 - width12 * det2) / det3
|
||||
if ((x >= x3 and x <= x4) or (x >= x4 and x <= x3)) and ((x >= x1 and x <= x2) or (x >= x2 and x <= x1)) then
|
||||
local y = (det1 * height34 - height12 * det2) / det3
|
||||
if ((y >= y3 and y <= y4) or (y >= y4 and y <= y3)) and ((y >= y1 and y <= y2) or (y >= y2 and y <= y1)) then return true end
|
||||
end
|
||||
x3 = x4
|
||||
y3 = y4
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function SkeletonBounds:getPolygon (attachment)
|
||||
local index = utils.indexOf(self.boundingBoxes, attachment)
|
||||
if index == -1 then
|
||||
return nil
|
||||
else
|
||||
return self.polygons[index]
|
||||
end
|
||||
end
|
||||
|
||||
function SkeletonBounds:getWidth()
|
||||
return self.maxX - self.minX
|
||||
end
|
||||
|
||||
function SkeletonBounds:getHeight()
|
||||
return self.maxY - self.minY
|
||||
end
|
||||
|
||||
return SkeletonBounds
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local utils = require "spine-lua.utils"
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local math_min = math.min
|
||||
local math_max = math.max
|
||||
local ipairs = ipairs
|
||||
local table_insert = table.insert
|
||||
|
||||
local SkeletonBounds = {}
|
||||
SkeletonBounds.__index = SkeletonBounds
|
||||
|
||||
function SkeletonBounds.new ()
|
||||
local self = {
|
||||
minX = 0, minY = 0, maxX = 0, maxY = 0,
|
||||
polygons = {},
|
||||
boundingBoxes = {},
|
||||
}
|
||||
setmetatable(self, SkeletonBounds)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function SkeletonBounds:update (skeleton, updateAabb)
|
||||
if skeleton == nil then error("skeleton cannot be null", 2) end
|
||||
local boundingBoxes = {}
|
||||
self.boundingBoxes = boundingBoxes
|
||||
local polygons = {}
|
||||
self.polygons = polygons
|
||||
local slots = skeleton.slots
|
||||
|
||||
for _,slot in ipairs(skeleton.slots) do
|
||||
if (slot.bone.active) then
|
||||
local attachment = slot.attachment
|
||||
if attachment and attachment.type == AttachmentType.boundingbox then
|
||||
local boundingBox = attachment
|
||||
table_insert(boundingBoxes, boundingBox)
|
||||
|
||||
local polygon = {}
|
||||
table_insert(polygons, polygon)
|
||||
|
||||
boundingBox:computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if updateAabb then
|
||||
self:aabbCompute()
|
||||
else
|
||||
self.minX = 9999999
|
||||
self.minY = 9999999
|
||||
self.maxX = -9999999
|
||||
self.maxY = -9999999
|
||||
end
|
||||
end
|
||||
|
||||
function SkeletonBounds:aabbCompute ()
|
||||
local minX, minY, maxX, maxY = 9999999, 9999999, -9999999, -9999999
|
||||
local polygons = self.polygons
|
||||
for _,vertices in ipairs(polygons) do
|
||||
local count = #vertices
|
||||
for ii = 1, count, 2 do
|
||||
local x = vertices[ii]
|
||||
local y = vertices[ii + 1]
|
||||
minX = math_min(minX, x)
|
||||
minY = math_min(minY, y)
|
||||
maxX = math_max(maxX, x)
|
||||
maxY = math_max(maxY, y)
|
||||
end
|
||||
end
|
||||
self.minX = minX
|
||||
self.minY = minY
|
||||
self.maxX = maxX
|
||||
self.maxY = maxY
|
||||
end
|
||||
|
||||
function SkeletonBounds:aabbContainsPoint (x, y)
|
||||
return x >= self.minX and x <= self.maxX and y >= self.minY and y <= self.maxY
|
||||
end
|
||||
|
||||
function SkeletonBounds:aabbIntersectsSegment (x1, y1, x2, y2)
|
||||
local minX, minY, maxX, maxY = self.minX, self.minY, self.maxX, self.maxY
|
||||
if (x1 <= minX and x2 <= minX) or (y1 <= minY and y2 <= minY) or (x1 >= maxX and x2 >= maxX) or (y1 >= maxY and y2 >= maxY) then
|
||||
return false
|
||||
end
|
||||
local m = (y2 - y1) / (x2 - x1)
|
||||
local y = m * (minX - x1) + y1
|
||||
if y > minY and y < maxY then return true end
|
||||
y = m * (maxX - x1) + y1
|
||||
if y > minY and y < maxY then return true end
|
||||
local x = (minY - y1) / m + x1
|
||||
if x > minX and x < maxX then return true end
|
||||
x = (maxY - y1) / m + x1
|
||||
if x > minX and x < maxX then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
function SkeletonBounds:aabbIntersectsSkeleton (bounds)
|
||||
return self.minX < bounds.maxX and self.maxX > bounds.minX and self.minY < bounds.maxY and self.maxY > bounds.minY
|
||||
end
|
||||
|
||||
function SkeletonBounds:containsPoint (x, y)
|
||||
for i,polygon in ipairs(self.polygons) do
|
||||
if self:polygonContainsPoint(polygon, x, y) then return self.boundingBoxes[i] end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonBounds:intersectsSegment (x1, y1, x2, y2)
|
||||
for i,polygon in ipairs(self.polygons) do
|
||||
if self:polygonIntersectsSegment(polygon, x1, y1, x2, y2) then return self.boundingBoxes[i] end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonBounds:polygonContainsPoint (polygon, x, y)
|
||||
local nn = #polygon
|
||||
local prevIndex = nn - 1
|
||||
local inside = false
|
||||
for ii = 1, nn, 2 do
|
||||
local vertexY = polygon[ii + 1]
|
||||
local prevY = polygon[prevIndex + 1]
|
||||
if (vertexY < y and prevY >= y) or (prevY < y and vertexY >= y) then
|
||||
local vertexX = polygon[ii]
|
||||
if vertexX + (y - vertexY) / (prevY - vertexY) * (polygon[prevIndex] - vertexX) < x then inside = not inside end
|
||||
end
|
||||
prevIndex = ii
|
||||
end
|
||||
return inside
|
||||
end
|
||||
|
||||
function SkeletonBounds:polygonIntersectsSegment (polygon, x1, y1, x2, y2)
|
||||
local nn = #polygon
|
||||
local width12, height12 = x1 - x2, y1 - y2
|
||||
local det1 = x1 * y2 - y1 * x2
|
||||
local x3, y3 = polygon[nn - 2], polygon[nn - 1]
|
||||
for ii = 1, nn, 2 do
|
||||
local x4, y4 = polygon[ii], polygon[ii + 1]
|
||||
local det2 = x3 * y4 - y3 * x4
|
||||
local width34, height34 = x3 - x4, y3 - y4
|
||||
local det3 = width12 * height34 - height12 * width34
|
||||
local x = (det1 * width34 - width12 * det2) / det3
|
||||
if ((x >= x3 and x <= x4) or (x >= x4 and x <= x3)) and ((x >= x1 and x <= x2) or (x >= x2 and x <= x1)) then
|
||||
local y = (det1 * height34 - height12 * det2) / det3
|
||||
if ((y >= y3 and y <= y4) or (y >= y4 and y <= y3)) and ((y >= y1 and y <= y2) or (y >= y2 and y <= y1)) then return true end
|
||||
end
|
||||
x3 = x4
|
||||
y3 = y4
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function SkeletonBounds:getPolygon (attachment)
|
||||
local index = utils.indexOf(self.boundingBoxes, attachment)
|
||||
if index == -1 then
|
||||
return nil
|
||||
else
|
||||
return self.polygons[index]
|
||||
end
|
||||
end
|
||||
|
||||
function SkeletonBounds:getWidth()
|
||||
return self.maxX - self.minX
|
||||
end
|
||||
|
||||
function SkeletonBounds:getHeight()
|
||||
return self.maxY - self.minY
|
||||
end
|
||||
|
||||
return SkeletonBounds
|
||||
@ -1,141 +1,141 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
|
||||
local SkeletonData = {}
|
||||
SkeletonData.__index = SkeletonData
|
||||
|
||||
function SkeletonData.new ()
|
||||
local self = {
|
||||
name,
|
||||
bones = {},
|
||||
slots = {},
|
||||
skins = {},
|
||||
defaultSkin = nil,
|
||||
events = {},
|
||||
animations = {},
|
||||
ikConstraints = {},
|
||||
transformConstraints = {},
|
||||
pathConstraints = {},
|
||||
x, y, width, height,
|
||||
version, hash, imagesPath,
|
||||
slotNameIndices = {}
|
||||
}
|
||||
setmetatable(self, SkeletonData)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function SkeletonData:findBone (boneName)
|
||||
if not boneName then error("boneName cannot be nil.", 2) end
|
||||
for _,bone in ipairs(self.bones) do
|
||||
if bone.name == boneName then return bone end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findBoneIndex (boneName)
|
||||
if not boneName then error("boneName cannot be nil.", 2) end
|
||||
for i,bone in ipairs(self.bones) do
|
||||
if bone.name == boneName then return i end
|
||||
end
|
||||
return -1
|
||||
end
|
||||
|
||||
function SkeletonData:findSlot (slotName)
|
||||
if not slotName then error("slotName cannot be nil.", 2) end
|
||||
for i,slot in ipairs(self.slots) do
|
||||
if slot.name == slotName then return slot end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findSlotIndex (slotName)
|
||||
if not slotName then error("slotName cannot be nil.", 2) end
|
||||
return self.slotNameIndices[slotName] or -1
|
||||
end
|
||||
|
||||
function SkeletonData:findSkin (skinName)
|
||||
if not skinName then error("skinName cannot be nil.", 2) end
|
||||
for _,skin in ipairs(self.skins) do
|
||||
if skin.name == skinName then return skin end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findEvent (eventName)
|
||||
if not eventName then error("eventName cannot be nil.", 2) end
|
||||
for _,event in ipairs(self.events) do
|
||||
if event.name == eventName then return event end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findAnimation (animationName)
|
||||
if not animationName then error("animationName cannot be nil.", 2) end
|
||||
for _,animation in ipairs(self.animations) do
|
||||
if animation.name == animationName then return animation end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findIkConstraint (constraintName)
|
||||
if not constraintName then error("constraintName cannot be nil.", 2) end
|
||||
for _,constraint in ipairs(self.ikConstraints) do
|
||||
if constraint.name == constraintName then return constraint end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findTransformConstraint (constraintName)
|
||||
if not constraintName then error("constraintName cannot be nil.", 2) end
|
||||
for _,constraint in ipairs(self.transformConstraints) do
|
||||
if constraint.name == constraintName then return constraint end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findPathConstraint (constraintName)
|
||||
if not constraintName then error("constraintName cannot be nil.", 2) end
|
||||
for _,constraint in ipairs(self.pathConstraints) do
|
||||
if constraint.name == constraintName then return constraint end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findPathConstraintIndex (constraintName)
|
||||
if not constraintName then error("constraintName cannot be nil.", 2) end
|
||||
for i,constraint in ipairs(self.pathConstraints) do
|
||||
if constraint.name == constraintName then return i end
|
||||
end
|
||||
return -1
|
||||
end
|
||||
|
||||
return SkeletonData
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
|
||||
local SkeletonData = {}
|
||||
SkeletonData.__index = SkeletonData
|
||||
|
||||
function SkeletonData.new ()
|
||||
local self = {
|
||||
name,
|
||||
bones = {},
|
||||
slots = {},
|
||||
skins = {},
|
||||
defaultSkin = nil,
|
||||
events = {},
|
||||
animations = {},
|
||||
ikConstraints = {},
|
||||
transformConstraints = {},
|
||||
pathConstraints = {},
|
||||
x, y, width, height,
|
||||
version, hash, imagesPath,
|
||||
slotNameIndices = {}
|
||||
}
|
||||
setmetatable(self, SkeletonData)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function SkeletonData:findBone (boneName)
|
||||
if not boneName then error("boneName cannot be nil.", 2) end
|
||||
for _,bone in ipairs(self.bones) do
|
||||
if bone.name == boneName then return bone end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findBoneIndex (boneName)
|
||||
if not boneName then error("boneName cannot be nil.", 2) end
|
||||
for i,bone in ipairs(self.bones) do
|
||||
if bone.name == boneName then return i end
|
||||
end
|
||||
return -1
|
||||
end
|
||||
|
||||
function SkeletonData:findSlot (slotName)
|
||||
if not slotName then error("slotName cannot be nil.", 2) end
|
||||
for i,slot in ipairs(self.slots) do
|
||||
if slot.name == slotName then return slot end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findSlotIndex (slotName)
|
||||
if not slotName then error("slotName cannot be nil.", 2) end
|
||||
return self.slotNameIndices[slotName] or -1
|
||||
end
|
||||
|
||||
function SkeletonData:findSkin (skinName)
|
||||
if not skinName then error("skinName cannot be nil.", 2) end
|
||||
for _,skin in ipairs(self.skins) do
|
||||
if skin.name == skinName then return skin end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findEvent (eventName)
|
||||
if not eventName then error("eventName cannot be nil.", 2) end
|
||||
for _,event in ipairs(self.events) do
|
||||
if event.name == eventName then return event end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findAnimation (animationName)
|
||||
if not animationName then error("animationName cannot be nil.", 2) end
|
||||
for _,animation in ipairs(self.animations) do
|
||||
if animation.name == animationName then return animation end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findIkConstraint (constraintName)
|
||||
if not constraintName then error("constraintName cannot be nil.", 2) end
|
||||
for _,constraint in ipairs(self.ikConstraints) do
|
||||
if constraint.name == constraintName then return constraint end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findTransformConstraint (constraintName)
|
||||
if not constraintName then error("constraintName cannot be nil.", 2) end
|
||||
for _,constraint in ipairs(self.transformConstraints) do
|
||||
if constraint.name == constraintName then return constraint end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findPathConstraint (constraintName)
|
||||
if not constraintName then error("constraintName cannot be nil.", 2) end
|
||||
for _,constraint in ipairs(self.pathConstraints) do
|
||||
if constraint.name == constraintName then return constraint end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function SkeletonData:findPathConstraintIndex (constraintName)
|
||||
if not constraintName then error("constraintName cannot be nil.", 2) end
|
||||
for i,constraint in ipairs(self.pathConstraints) do
|
||||
if constraint.name == constraintName then return i end
|
||||
end
|
||||
return -1
|
||||
end
|
||||
|
||||
return SkeletonData
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,220 +1,220 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local table_insert = table.insert
|
||||
local AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
|
||||
local SkinEntry = {}
|
||||
SkinEntry.__index = SkinEntry
|
||||
|
||||
function SkinEntry.new (slotIndex, name, attachment)
|
||||
local self = {
|
||||
slotIndex = slotIndex,
|
||||
name = name,
|
||||
attachment = attachment
|
||||
}
|
||||
setmetatable(self, SkinEntry)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
local Skin = {}
|
||||
Skin.__index = Skin
|
||||
|
||||
function Skin.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
attachments = {},
|
||||
bones = {},
|
||||
constraints = {}
|
||||
}
|
||||
setmetatable(self, Skin)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Skin:setAttachment (slotIndex, name, attachment)
|
||||
if not name then error("name cannot be nil.", 2) end
|
||||
if not self.attachments[slotIndex] then self.attachments[slotIndex] = {} end
|
||||
self.attachments[slotIndex][name] = attachment
|
||||
end
|
||||
|
||||
function Skin:addSkin (skin)
|
||||
for i, bone in ipairs(skin.bones) do
|
||||
local contained = false
|
||||
for j, otherBone in ipairs(self.bones) do
|
||||
if otherBone == bone then
|
||||
contained = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not contained then table_insert(self.bones, bone) end
|
||||
end
|
||||
|
||||
for i, constraint in ipairs(skin.constraints) do
|
||||
local contained = false
|
||||
for j, otherConstraint in ipairs(self.constraints) do
|
||||
if otherConstraint == constraint then
|
||||
contained = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not contained then table_insert(self.constraints, constraint) end
|
||||
end
|
||||
|
||||
local attachments = skin:getAttachments()
|
||||
for i, entry in ipairs(attachments) do
|
||||
self:setAttachment(entry.slotIndex, entry.name, entry.attachment)
|
||||
end
|
||||
end
|
||||
|
||||
function Skin:copySkin (skin)
|
||||
for i, bone in ipairs(skin.bones) do
|
||||
local contained = false
|
||||
for j, otherBone in ipairs(self.bones) do
|
||||
if otherBone == bone then
|
||||
contained = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not contained then table_insert(self.bones, bone) end
|
||||
end
|
||||
|
||||
for i, constraint in ipairs(skin.constraints) do
|
||||
local contained = false
|
||||
for j, otherConstraint in ipairs(self.constraints) do
|
||||
if otherConstraint == constraint then
|
||||
contained = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not contained then table_insert(self.constraints, constraint) end
|
||||
end
|
||||
|
||||
local attachments = skin:getAttachments()
|
||||
for i, entry in ipairs(attachments) do
|
||||
if entry.attachment.type == AttachmentType.mesh then
|
||||
entry.attachment = entry.attachment:newLinkedMesh()
|
||||
self:setAttachment(entry.slotIndex, entry.name, entry.attachment)
|
||||
else
|
||||
entry.attachment = entry.attachment:copy()
|
||||
self:setAttachment(entry.slotIndex, entry.name, entry.attachment)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Skin:getAttachment (slotIndex, name)
|
||||
if not name then error("name cannot be nil.", 2) end
|
||||
local dictionary = self.attachments[slotIndex]
|
||||
if dictionary then
|
||||
return dictionary[name]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function Skin:removeAttachment (slotIndex, name)
|
||||
local slotAttachments = self.attachments[slotIndex]
|
||||
if slotAttachments then
|
||||
slotAttachments[name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Skin:getAttachments ()
|
||||
local entries = {}
|
||||
for slotIndex, slotAttachments in pairs(self.attachments) do
|
||||
if slotAttachments then
|
||||
for name, attachment in pairs(slotAttachments) do
|
||||
if attachment then
|
||||
table_insert(entries, SkinEntry.new(slotIndex, name, attachment))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return entries
|
||||
end
|
||||
|
||||
function Skin:getAttachmentsForSlot (slotIndex)
|
||||
local entries = {}
|
||||
local slotAttachments = self.attachments[slotIndex]
|
||||
if slotAttachments then
|
||||
for name, attachment in pairs(slotAttachments) do
|
||||
if attachment then
|
||||
table_insert(entries, SkinEntry.new(slotIndex, name, attachment))
|
||||
end
|
||||
end
|
||||
end
|
||||
return entries
|
||||
end
|
||||
|
||||
function Skin:clear ()
|
||||
self.attachments = {}
|
||||
self.bones = {}
|
||||
self.constraints = {}
|
||||
end
|
||||
|
||||
function Skin:attachAll(skeleton, oldSkin)
|
||||
for i, slot in ipairs(skeleton.slots) do
|
||||
local slotAttachment = slot.attachment
|
||||
if slotAttachment then
|
||||
local dictionary = oldSkin.attachments[i]
|
||||
if (dictionary) then
|
||||
for key, value in pairs(dictionary) do
|
||||
local skinAttachment = value
|
||||
if slotAttachment == skinAttachment then
|
||||
local attachment = self:getAttachment(i, key)
|
||||
if attachment then
|
||||
slot:setAttachment(attachment)
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Skin:findNamesForSlot (slotIndex)
|
||||
local names = {}
|
||||
for _,v in self.attachments do
|
||||
if v[1] == slotIndex then table_insert(names, v[2]) end
|
||||
end
|
||||
end
|
||||
|
||||
function Skin:findAttachmentsForSlot (slotIndex)
|
||||
local attachments = {}
|
||||
for _,v in self.attachments do
|
||||
if v[1] == slotIndex then table_insert(attachments, v[3]) end
|
||||
end
|
||||
end
|
||||
|
||||
return Skin
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local table_insert = table.insert
|
||||
local AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
|
||||
local SkinEntry = {}
|
||||
SkinEntry.__index = SkinEntry
|
||||
|
||||
function SkinEntry.new (slotIndex, name, attachment)
|
||||
local self = {
|
||||
slotIndex = slotIndex,
|
||||
name = name,
|
||||
attachment = attachment
|
||||
}
|
||||
setmetatable(self, SkinEntry)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
local Skin = {}
|
||||
Skin.__index = Skin
|
||||
|
||||
function Skin.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
attachments = {},
|
||||
bones = {},
|
||||
constraints = {}
|
||||
}
|
||||
setmetatable(self, Skin)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Skin:setAttachment (slotIndex, name, attachment)
|
||||
if not name then error("name cannot be nil.", 2) end
|
||||
if not self.attachments[slotIndex] then self.attachments[slotIndex] = {} end
|
||||
self.attachments[slotIndex][name] = attachment
|
||||
end
|
||||
|
||||
function Skin:addSkin (skin)
|
||||
for i, bone in ipairs(skin.bones) do
|
||||
local contained = false
|
||||
for j, otherBone in ipairs(self.bones) do
|
||||
if otherBone == bone then
|
||||
contained = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not contained then table_insert(self.bones, bone) end
|
||||
end
|
||||
|
||||
for i, constraint in ipairs(skin.constraints) do
|
||||
local contained = false
|
||||
for j, otherConstraint in ipairs(self.constraints) do
|
||||
if otherConstraint == constraint then
|
||||
contained = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not contained then table_insert(self.constraints, constraint) end
|
||||
end
|
||||
|
||||
local attachments = skin:getAttachments()
|
||||
for i, entry in ipairs(attachments) do
|
||||
self:setAttachment(entry.slotIndex, entry.name, entry.attachment)
|
||||
end
|
||||
end
|
||||
|
||||
function Skin:copySkin (skin)
|
||||
for i, bone in ipairs(skin.bones) do
|
||||
local contained = false
|
||||
for j, otherBone in ipairs(self.bones) do
|
||||
if otherBone == bone then
|
||||
contained = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not contained then table_insert(self.bones, bone) end
|
||||
end
|
||||
|
||||
for i, constraint in ipairs(skin.constraints) do
|
||||
local contained = false
|
||||
for j, otherConstraint in ipairs(self.constraints) do
|
||||
if otherConstraint == constraint then
|
||||
contained = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not contained then table_insert(self.constraints, constraint) end
|
||||
end
|
||||
|
||||
local attachments = skin:getAttachments()
|
||||
for i, entry in ipairs(attachments) do
|
||||
if entry.attachment.type == AttachmentType.mesh then
|
||||
entry.attachment = entry.attachment:newLinkedMesh()
|
||||
self:setAttachment(entry.slotIndex, entry.name, entry.attachment)
|
||||
else
|
||||
entry.attachment = entry.attachment:copy()
|
||||
self:setAttachment(entry.slotIndex, entry.name, entry.attachment)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Skin:getAttachment (slotIndex, name)
|
||||
if not name then error("name cannot be nil.", 2) end
|
||||
local dictionary = self.attachments[slotIndex]
|
||||
if dictionary then
|
||||
return dictionary[name]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function Skin:removeAttachment (slotIndex, name)
|
||||
local slotAttachments = self.attachments[slotIndex]
|
||||
if slotAttachments then
|
||||
slotAttachments[name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Skin:getAttachments ()
|
||||
local entries = {}
|
||||
for slotIndex, slotAttachments in pairs(self.attachments) do
|
||||
if slotAttachments then
|
||||
for name, attachment in pairs(slotAttachments) do
|
||||
if attachment then
|
||||
table_insert(entries, SkinEntry.new(slotIndex, name, attachment))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return entries
|
||||
end
|
||||
|
||||
function Skin:getAttachmentsForSlot (slotIndex)
|
||||
local entries = {}
|
||||
local slotAttachments = self.attachments[slotIndex]
|
||||
if slotAttachments then
|
||||
for name, attachment in pairs(slotAttachments) do
|
||||
if attachment then
|
||||
table_insert(entries, SkinEntry.new(slotIndex, name, attachment))
|
||||
end
|
||||
end
|
||||
end
|
||||
return entries
|
||||
end
|
||||
|
||||
function Skin:clear ()
|
||||
self.attachments = {}
|
||||
self.bones = {}
|
||||
self.constraints = {}
|
||||
end
|
||||
|
||||
function Skin:attachAll(skeleton, oldSkin)
|
||||
for i, slot in ipairs(skeleton.slots) do
|
||||
local slotAttachment = slot.attachment
|
||||
if slotAttachment then
|
||||
local dictionary = oldSkin.attachments[i]
|
||||
if (dictionary) then
|
||||
for key, value in pairs(dictionary) do
|
||||
local skinAttachment = value
|
||||
if slotAttachment == skinAttachment then
|
||||
local attachment = self:getAttachment(i, key)
|
||||
if attachment then
|
||||
slot:setAttachment(attachment)
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Skin:findNamesForSlot (slotIndex)
|
||||
local names = {}
|
||||
for _,v in self.attachments do
|
||||
if v[1] == slotIndex then table_insert(names, v[2]) end
|
||||
end
|
||||
end
|
||||
|
||||
function Skin:findAttachmentsForSlot (slotIndex)
|
||||
local attachments = {}
|
||||
for _,v in self.attachments do
|
||||
if v[1] == slotIndex then table_insert(attachments, v[3]) end
|
||||
end
|
||||
end
|
||||
|
||||
return Skin
|
||||
@ -1,89 +1,89 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
|
||||
local Color = require "spine-lua.Color"
|
||||
|
||||
local Slot = {}
|
||||
Slot.__index = Slot
|
||||
|
||||
function Slot.new (data, bone)
|
||||
if not data then error("slotData cannot be nil", 2) end
|
||||
if not bone then error("bone cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
data = data,
|
||||
bone = bone,
|
||||
color = Color.newWith(1, 1, 1, 1),
|
||||
darkColor = nil,
|
||||
attachment = nil,
|
||||
attachmentTime = 0,
|
||||
attachmentState = 0,
|
||||
deform = {}
|
||||
}
|
||||
|
||||
setmetatable(self, Slot)
|
||||
|
||||
if data.darkColor then self.darkColor = Color.newWith(1, 1, 1, 1) end
|
||||
|
||||
self:setToSetupPose()
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Slot:setAttachment (attachment)
|
||||
if self.attachment == attachment then return end
|
||||
self.attachment = attachment
|
||||
self.attachmentTime = self.bone.skeleton.time
|
||||
self.deform = {}
|
||||
end
|
||||
|
||||
function Slot:setAttachmentTime (time)
|
||||
self.attachmentTime = self.bone.skeleton.time - time
|
||||
end
|
||||
|
||||
function Slot:getAttachmentTime ()
|
||||
return self.bone.skeleton.time - self.attachmentTime
|
||||
end
|
||||
|
||||
function Slot:setToSetupPose ()
|
||||
local data = self.data
|
||||
|
||||
self.color:setFrom(data.color)
|
||||
if self.darkColor then self.darkColor:setFrom(data.darkColor) end
|
||||
|
||||
local attachment = nil
|
||||
if data.attachmentName then
|
||||
attachment = self.bone.skeleton:getAttachmentByIndex(data.index, data.attachmentName)
|
||||
end
|
||||
self:setAttachment(attachment)
|
||||
end
|
||||
|
||||
return Slot
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
|
||||
local Color = require "spine-lua.Color"
|
||||
|
||||
local Slot = {}
|
||||
Slot.__index = Slot
|
||||
|
||||
function Slot.new (data, bone)
|
||||
if not data then error("slotData cannot be nil", 2) end
|
||||
if not bone then error("bone cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
data = data,
|
||||
bone = bone,
|
||||
color = Color.newWith(1, 1, 1, 1),
|
||||
darkColor = nil,
|
||||
attachment = nil,
|
||||
attachmentTime = 0,
|
||||
attachmentState = 0,
|
||||
deform = {}
|
||||
}
|
||||
|
||||
setmetatable(self, Slot)
|
||||
|
||||
if data.darkColor then self.darkColor = Color.newWith(1, 1, 1, 1) end
|
||||
|
||||
self:setToSetupPose()
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Slot:setAttachment (attachment)
|
||||
if self.attachment == attachment then return end
|
||||
self.attachment = attachment
|
||||
self.attachmentTime = self.bone.skeleton.time
|
||||
self.deform = {}
|
||||
end
|
||||
|
||||
function Slot:setAttachmentTime (time)
|
||||
self.attachmentTime = self.bone.skeleton.time - time
|
||||
end
|
||||
|
||||
function Slot:getAttachmentTime ()
|
||||
return self.bone.skeleton.time - self.attachmentTime
|
||||
end
|
||||
|
||||
function Slot:setToSetupPose ()
|
||||
local data = self.data
|
||||
|
||||
self.color:setFrom(data.color)
|
||||
if self.darkColor then self.darkColor:setFrom(data.darkColor) end
|
||||
|
||||
local attachment = nil
|
||||
if data.attachmentName then
|
||||
attachment = self.bone.skeleton:getAttachmentByIndex(data.index, data.attachmentName)
|
||||
end
|
||||
self:setAttachment(attachment)
|
||||
end
|
||||
|
||||
return Slot
|
||||
@ -1,57 +1,57 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 BlendMode = require "spine-lua.BlendMode"
|
||||
local Color = require "spine-lua.Color"
|
||||
|
||||
local setmetatable = setmetatable
|
||||
|
||||
local SlotData = {}
|
||||
SlotData.__index = SlotData
|
||||
|
||||
function SlotData.new (index, name, boneData)
|
||||
if index < 0 then error("index must be >= 0", 2) end
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
if not boneData then error("boneData cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
index = index,
|
||||
name = name,
|
||||
boneData = boneData,
|
||||
color = Color.newWith(1, 1, 1, 1),
|
||||
darkColor = nil,
|
||||
attachmentName = nil,
|
||||
blendMode = BlendMode.normal
|
||||
}
|
||||
setmetatable(self, SlotData)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return SlotData
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 BlendMode = require "spine-lua.BlendMode"
|
||||
local Color = require "spine-lua.Color"
|
||||
|
||||
local setmetatable = setmetatable
|
||||
|
||||
local SlotData = {}
|
||||
SlotData.__index = SlotData
|
||||
|
||||
function SlotData.new (index, name, boneData)
|
||||
if index < 0 then error("index must be >= 0", 2) end
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
if not boneData then error("boneData cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
index = index,
|
||||
name = name,
|
||||
boneData = boneData,
|
||||
color = Color.newWith(1, 1, 1, 1),
|
||||
darkColor = nil,
|
||||
attachmentName = nil,
|
||||
blendMode = BlendMode.normal
|
||||
}
|
||||
setmetatable(self, SlotData)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return SlotData
|
||||
@ -1,258 +1,258 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local table_insert = table.insert
|
||||
local math_abs = math.abs
|
||||
|
||||
local TextureAtlasRegion = require "spine-lua.TextureAtlasRegion"
|
||||
local TextureWrap = require "spine-lua.TextureWrap"
|
||||
local TextureFilter = require "spine-lua.TextureFilter"
|
||||
|
||||
local TextureAtlasPage = {}
|
||||
TextureAtlasPage.__index = TextureAtlasPage
|
||||
|
||||
function TextureAtlasPage.new ()
|
||||
local self = {
|
||||
name = nil,
|
||||
minFilter = nil,
|
||||
magFilter = nil,
|
||||
uWrap = nil,
|
||||
vWrap = nil,
|
||||
texture = nil,
|
||||
width = 0,
|
||||
height = 0
|
||||
}
|
||||
setmetatable(self, TextureAtlasPage)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
local TextureAtlas = {}
|
||||
TextureAtlas.__index = TextureAtlas
|
||||
|
||||
function TextureAtlas.new (atlasContent, imageLoader)
|
||||
local self = {
|
||||
pages = {},
|
||||
regions = {}
|
||||
}
|
||||
setmetatable(self, TextureAtlas)
|
||||
|
||||
self:parse(atlasContent, imageLoader)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function TextureAtlas:parse (atlasContent, imageLoader)
|
||||
if not atlasContent then error("atlasContent cannot be nil.", 2) end
|
||||
if not imageLoader then error("imageLoader cannot be nil.", 2) end
|
||||
|
||||
function lineIterator(s)
|
||||
if s:sub(-1)~="\n" then s=s.."\n" end
|
||||
return s:gmatch("(.-)\n")
|
||||
end
|
||||
|
||||
local lines = {}
|
||||
local index = 0
|
||||
local numLines = 0
|
||||
for line in lineIterator(atlasContent) do
|
||||
lines[numLines] = line
|
||||
numLines = numLines + 1
|
||||
end
|
||||
|
||||
local readLine = function ()
|
||||
if index >= numLines then return nil end
|
||||
local line = lines[index]
|
||||
index = index + 1
|
||||
return line
|
||||
end
|
||||
|
||||
local readValue = function ()
|
||||
local line = readLine()
|
||||
local idx = line:find(":")
|
||||
if not idx then error("Invalid line: " .. line, 2) end
|
||||
return line:sub(idx + 1):match'^%s*(.*%S)' or ''
|
||||
end
|
||||
|
||||
local readTuple = function ()
|
||||
local line = readLine()
|
||||
local idx = line:find(":")
|
||||
if not idx then
|
||||
error("Invalid line: " .. line, 2)
|
||||
end
|
||||
local i = 1
|
||||
local lastMatch = idx + 1
|
||||
local tuple = {}
|
||||
while i <= 3 do
|
||||
local comma = line:find(",", lastMatch)
|
||||
if not comma then break end
|
||||
tuple[i] = line:sub(lastMatch, comma - 1):match'^%s*(.*%S)' or ''
|
||||
lastMatch = comma + 1
|
||||
i = i + 1
|
||||
end
|
||||
tuple[i] = line:sub(lastMatch):match'^%s*(.*%S)' or ''
|
||||
return tuple
|
||||
end
|
||||
|
||||
local parseInt = function (str)
|
||||
return tonumber(str)
|
||||
end
|
||||
|
||||
local filterFromString = function (str)
|
||||
str = str:lower()
|
||||
if str == "nearest" then return TextureFilter.Nearest
|
||||
elseif str == "linear" then return TextureFilter.Linear
|
||||
elseif str == "mipmap" then return TextureFilter.MipMap
|
||||
elseif str == "mipmapnearestnearest" then return TextureFilter.MipMapNearestNearest
|
||||
elseif str == "mipmaplinearnearest" then return TextureFilter.MipMapLinearNearest
|
||||
elseif str == "mipmapnearestlinear" then return TextureFilter.MipMapNearestLinear
|
||||
elseif str == "mipmaplinearlinear" then return TextureFilter.MipMapLinearLinear
|
||||
else error("Unknown texture wrap: " .. str, 2)
|
||||
end
|
||||
end
|
||||
|
||||
local page = nil
|
||||
while true do
|
||||
local line = readLine()
|
||||
if not line then break end
|
||||
line = line:match'^%s*(.*%S)' or ''
|
||||
if line:len() == 0 then
|
||||
page = nil
|
||||
elseif not page then
|
||||
page = TextureAtlasPage.new()
|
||||
page.name = line
|
||||
|
||||
local tuple = readTuple()
|
||||
if #tuple == 2 then
|
||||
page.width = parseInt(tuple[1])
|
||||
page.height = parseInt(tuple[2])
|
||||
tuple = readTuple()
|
||||
else
|
||||
-- We only support atlases that have the page width/height
|
||||
-- encoded in them. That way we don't rely on any special
|
||||
-- wrapper objects for images to get the page size from
|
||||
error("Atlas must specify page width/height. Please export to the latest atlas format", 2)
|
||||
end
|
||||
|
||||
tuple = readTuple()
|
||||
page.minFilter = filterFromString(tuple[1])
|
||||
page.magFilter = filterFromString(tuple[2])
|
||||
|
||||
local direction = readValue()
|
||||
page.uWrap = TextureWrap.ClampToEdge
|
||||
page.vWrap = TextureWrap.ClampToEdge
|
||||
if direction == "x" then
|
||||
page.uWrap = TextureWrap.Repeat
|
||||
elseif direction == "y" then
|
||||
page.vWrap = TextureWrap.Repeat
|
||||
elseif direction == "xy" then
|
||||
page.uWrap = TextureWrap.Repeat
|
||||
page.vWrap = TextureWrap.Repeat
|
||||
end
|
||||
|
||||
page.texture = imageLoader(line)
|
||||
-- FIXME page.texture:setFilters(page.minFilter, page.magFilter)
|
||||
-- FIXME page.texture:setWraps(page.uWrap, page.vWrap)
|
||||
table_insert(self.pages, page)
|
||||
else
|
||||
local region = TextureAtlasRegion.new()
|
||||
region.name = line
|
||||
region.page = page
|
||||
|
||||
local rotateValue = readValue()
|
||||
if rotateValue == "true" then
|
||||
region.degrees = 90
|
||||
elseif rotateValue == "false" then
|
||||
region.degrees = 0
|
||||
else
|
||||
region.degrees = tonumber(rotateValue)
|
||||
end
|
||||
if region.degrees == 90 then region.rotate = true end
|
||||
|
||||
local tuple = readTuple()
|
||||
local x = parseInt(tuple[1])
|
||||
local y = parseInt(tuple[2])
|
||||
|
||||
tuple = readTuple()
|
||||
local width = parseInt(tuple[1])
|
||||
local height = parseInt(tuple[2])
|
||||
|
||||
region.u = x / page.width
|
||||
region.v = y / page.height
|
||||
if region.rotate then
|
||||
region.u2 = (x + height) / page.width
|
||||
region.v2 = (y + width) / page.height
|
||||
else
|
||||
region.u2 = (x + width) / page.width
|
||||
region.v2 = (y + height) / page.height
|
||||
end
|
||||
|
||||
region.x = x
|
||||
region.y = y
|
||||
region.width = math_abs(width)
|
||||
region.height = math_abs(height)
|
||||
|
||||
-- Read and skip optional splits
|
||||
tuple = readTuple()
|
||||
if #tuple == 4 then
|
||||
tuple = readTuple()
|
||||
if #tuple == 4 then
|
||||
readTuple()
|
||||
end
|
||||
end
|
||||
|
||||
region.originalWidth = parseInt(tuple[1])
|
||||
region.originalHeight = parseInt(tuple[2])
|
||||
|
||||
tuple = readTuple()
|
||||
region.offsetX = parseInt(tuple[1])
|
||||
region.offsetY = parseInt(tuple[2])
|
||||
|
||||
region.index = parseInt(readValue())
|
||||
region.texture = page.texture
|
||||
table_insert(self.regions, region)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TextureAtlas:findRegion(name)
|
||||
for _, region in ipairs(self.regions) do
|
||||
if region.name == name then return region end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function TextureAtlas:dispose()
|
||||
for _, page in ipairs(self.pairs) do
|
||||
-- FIXME implement disposing of pages
|
||||
-- love2d doesn't support manual disposing
|
||||
end
|
||||
end
|
||||
|
||||
return TextureAtlas
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local table_insert = table.insert
|
||||
local math_abs = math.abs
|
||||
|
||||
local TextureAtlasRegion = require "spine-lua.TextureAtlasRegion"
|
||||
local TextureWrap = require "spine-lua.TextureWrap"
|
||||
local TextureFilter = require "spine-lua.TextureFilter"
|
||||
|
||||
local TextureAtlasPage = {}
|
||||
TextureAtlasPage.__index = TextureAtlasPage
|
||||
|
||||
function TextureAtlasPage.new ()
|
||||
local self = {
|
||||
name = nil,
|
||||
minFilter = nil,
|
||||
magFilter = nil,
|
||||
uWrap = nil,
|
||||
vWrap = nil,
|
||||
texture = nil,
|
||||
width = 0,
|
||||
height = 0
|
||||
}
|
||||
setmetatable(self, TextureAtlasPage)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
local TextureAtlas = {}
|
||||
TextureAtlas.__index = TextureAtlas
|
||||
|
||||
function TextureAtlas.new (atlasContent, imageLoader)
|
||||
local self = {
|
||||
pages = {},
|
||||
regions = {}
|
||||
}
|
||||
setmetatable(self, TextureAtlas)
|
||||
|
||||
self:parse(atlasContent, imageLoader)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function TextureAtlas:parse (atlasContent, imageLoader)
|
||||
if not atlasContent then error("atlasContent cannot be nil.", 2) end
|
||||
if not imageLoader then error("imageLoader cannot be nil.", 2) end
|
||||
|
||||
function lineIterator(s)
|
||||
if s:sub(-1)~="\n" then s=s.."\n" end
|
||||
return s:gmatch("(.-)\n")
|
||||
end
|
||||
|
||||
local lines = {}
|
||||
local index = 0
|
||||
local numLines = 0
|
||||
for line in lineIterator(atlasContent) do
|
||||
lines[numLines] = line
|
||||
numLines = numLines + 1
|
||||
end
|
||||
|
||||
local readLine = function ()
|
||||
if index >= numLines then return nil end
|
||||
local line = lines[index]
|
||||
index = index + 1
|
||||
return line
|
||||
end
|
||||
|
||||
local readValue = function ()
|
||||
local line = readLine()
|
||||
local idx = line:find(":")
|
||||
if not idx then error("Invalid line: " .. line, 2) end
|
||||
return line:sub(idx + 1):match'^%s*(.*%S)' or ''
|
||||
end
|
||||
|
||||
local readTuple = function ()
|
||||
local line = readLine()
|
||||
local idx = line:find(":")
|
||||
if not idx then
|
||||
error("Invalid line: " .. line, 2)
|
||||
end
|
||||
local i = 1
|
||||
local lastMatch = idx + 1
|
||||
local tuple = {}
|
||||
while i <= 3 do
|
||||
local comma = line:find(",", lastMatch)
|
||||
if not comma then break end
|
||||
tuple[i] = line:sub(lastMatch, comma - 1):match'^%s*(.*%S)' or ''
|
||||
lastMatch = comma + 1
|
||||
i = i + 1
|
||||
end
|
||||
tuple[i] = line:sub(lastMatch):match'^%s*(.*%S)' or ''
|
||||
return tuple
|
||||
end
|
||||
|
||||
local parseInt = function (str)
|
||||
return tonumber(str)
|
||||
end
|
||||
|
||||
local filterFromString = function (str)
|
||||
str = str:lower()
|
||||
if str == "nearest" then return TextureFilter.Nearest
|
||||
elseif str == "linear" then return TextureFilter.Linear
|
||||
elseif str == "mipmap" then return TextureFilter.MipMap
|
||||
elseif str == "mipmapnearestnearest" then return TextureFilter.MipMapNearestNearest
|
||||
elseif str == "mipmaplinearnearest" then return TextureFilter.MipMapLinearNearest
|
||||
elseif str == "mipmapnearestlinear" then return TextureFilter.MipMapNearestLinear
|
||||
elseif str == "mipmaplinearlinear" then return TextureFilter.MipMapLinearLinear
|
||||
else error("Unknown texture wrap: " .. str, 2)
|
||||
end
|
||||
end
|
||||
|
||||
local page = nil
|
||||
while true do
|
||||
local line = readLine()
|
||||
if not line then break end
|
||||
line = line:match'^%s*(.*%S)' or ''
|
||||
if line:len() == 0 then
|
||||
page = nil
|
||||
elseif not page then
|
||||
page = TextureAtlasPage.new()
|
||||
page.name = line
|
||||
|
||||
local tuple = readTuple()
|
||||
if #tuple == 2 then
|
||||
page.width = parseInt(tuple[1])
|
||||
page.height = parseInt(tuple[2])
|
||||
tuple = readTuple()
|
||||
else
|
||||
-- We only support atlases that have the page width/height
|
||||
-- encoded in them. That way we don't rely on any special
|
||||
-- wrapper objects for images to get the page size from
|
||||
error("Atlas must specify page width/height. Please export to the latest atlas format", 2)
|
||||
end
|
||||
|
||||
tuple = readTuple()
|
||||
page.minFilter = filterFromString(tuple[1])
|
||||
page.magFilter = filterFromString(tuple[2])
|
||||
|
||||
local direction = readValue()
|
||||
page.uWrap = TextureWrap.ClampToEdge
|
||||
page.vWrap = TextureWrap.ClampToEdge
|
||||
if direction == "x" then
|
||||
page.uWrap = TextureWrap.Repeat
|
||||
elseif direction == "y" then
|
||||
page.vWrap = TextureWrap.Repeat
|
||||
elseif direction == "xy" then
|
||||
page.uWrap = TextureWrap.Repeat
|
||||
page.vWrap = TextureWrap.Repeat
|
||||
end
|
||||
|
||||
page.texture = imageLoader(line)
|
||||
-- FIXME page.texture:setFilters(page.minFilter, page.magFilter)
|
||||
-- FIXME page.texture:setWraps(page.uWrap, page.vWrap)
|
||||
table_insert(self.pages, page)
|
||||
else
|
||||
local region = TextureAtlasRegion.new()
|
||||
region.name = line
|
||||
region.page = page
|
||||
|
||||
local rotateValue = readValue()
|
||||
if rotateValue == "true" then
|
||||
region.degrees = 90
|
||||
elseif rotateValue == "false" then
|
||||
region.degrees = 0
|
||||
else
|
||||
region.degrees = tonumber(rotateValue)
|
||||
end
|
||||
if region.degrees == 90 then region.rotate = true end
|
||||
|
||||
local tuple = readTuple()
|
||||
local x = parseInt(tuple[1])
|
||||
local y = parseInt(tuple[2])
|
||||
|
||||
tuple = readTuple()
|
||||
local width = parseInt(tuple[1])
|
||||
local height = parseInt(tuple[2])
|
||||
|
||||
region.u = x / page.width
|
||||
region.v = y / page.height
|
||||
if region.rotate then
|
||||
region.u2 = (x + height) / page.width
|
||||
region.v2 = (y + width) / page.height
|
||||
else
|
||||
region.u2 = (x + width) / page.width
|
||||
region.v2 = (y + height) / page.height
|
||||
end
|
||||
|
||||
region.x = x
|
||||
region.y = y
|
||||
region.width = math_abs(width)
|
||||
region.height = math_abs(height)
|
||||
|
||||
-- Read and skip optional splits
|
||||
tuple = readTuple()
|
||||
if #tuple == 4 then
|
||||
tuple = readTuple()
|
||||
if #tuple == 4 then
|
||||
readTuple()
|
||||
end
|
||||
end
|
||||
|
||||
region.originalWidth = parseInt(tuple[1])
|
||||
region.originalHeight = parseInt(tuple[2])
|
||||
|
||||
tuple = readTuple()
|
||||
region.offsetX = parseInt(tuple[1])
|
||||
region.offsetY = parseInt(tuple[2])
|
||||
|
||||
region.index = parseInt(readValue())
|
||||
region.texture = page.texture
|
||||
table_insert(self.regions, region)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TextureAtlas:findRegion(name)
|
||||
for _, region in ipairs(self.regions) do
|
||||
if region.name == name then return region end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function TextureAtlas:dispose()
|
||||
for _, page in ipairs(self.pairs) do
|
||||
-- FIXME implement disposing of pages
|
||||
-- love2d doesn't support manual disposing
|
||||
end
|
||||
end
|
||||
|
||||
return TextureAtlas
|
||||
@ -1,53 +1,53 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
|
||||
local TextureRegion = require "spine-lua.TextureRegion"
|
||||
|
||||
local TextureAtlasRegion = {}
|
||||
TextureAtlasRegion.__index = TextureAtlasRegion
|
||||
setmetatable(TextureAtlasRegion, { __index = TextureRegion })
|
||||
|
||||
function TextureAtlasRegion.new ()
|
||||
local self = TextureRegion.new()
|
||||
self.page = nil
|
||||
self.name = nil
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.index = 0
|
||||
self.rotate = false
|
||||
self.degrees = 0
|
||||
self.texture = nil
|
||||
setmetatable(self, TextureAtlasRegion)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return TextureAtlasRegion
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
|
||||
local TextureRegion = require "spine-lua.TextureRegion"
|
||||
|
||||
local TextureAtlasRegion = {}
|
||||
TextureAtlasRegion.__index = TextureAtlasRegion
|
||||
setmetatable(TextureAtlasRegion, { __index = TextureRegion })
|
||||
|
||||
function TextureAtlasRegion.new ()
|
||||
local self = TextureRegion.new()
|
||||
self.page = nil
|
||||
self.name = nil
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.index = 0
|
||||
self.rotate = false
|
||||
self.degrees = 0
|
||||
self.texture = nil
|
||||
setmetatable(self, TextureAtlasRegion)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return TextureAtlasRegion
|
||||
@ -1,39 +1,39 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 TextureFilter = {
|
||||
Nearest = 0,
|
||||
Linear = 1,
|
||||
MipMap = 2,
|
||||
MipMapNearestNearest = 3,
|
||||
MipMapLinearNearest = 4,
|
||||
MipMapNearestLinear = 5,
|
||||
MipMapLinearLinear = 6
|
||||
}
|
||||
return TextureFilter
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 TextureFilter = {
|
||||
Nearest = 0,
|
||||
Linear = 1,
|
||||
MipMap = 2,
|
||||
MipMapNearestNearest = 3,
|
||||
MipMapLinearNearest = 4,
|
||||
MipMapNearestLinear = 5,
|
||||
MipMapLinearLinear = 6
|
||||
}
|
||||
return TextureFilter
|
||||
@ -1,51 +1,51 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
|
||||
local TextureRegion = {}
|
||||
TextureRegion.__index = TextureRegion
|
||||
|
||||
function TextureRegion.new ()
|
||||
|
||||
local self = {
|
||||
renderObject = nil,
|
||||
u = 0, v = 0,
|
||||
u2 = 0, v2 = 0,
|
||||
width = 0, height = 0,
|
||||
rotate = false,
|
||||
offsetX = 0, offsetY = 0,
|
||||
originalWidth = 0, originalHeight = 0
|
||||
}
|
||||
setmetatable(self, TextureRegion)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return TextureRegion
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
|
||||
local TextureRegion = {}
|
||||
TextureRegion.__index = TextureRegion
|
||||
|
||||
function TextureRegion.new ()
|
||||
|
||||
local self = {
|
||||
renderObject = nil,
|
||||
u = 0, v = 0,
|
||||
u2 = 0, v2 = 0,
|
||||
width = 0, height = 0,
|
||||
rotate = false,
|
||||
offsetX = 0, offsetY = 0,
|
||||
originalWidth = 0, originalHeight = 0
|
||||
}
|
||||
setmetatable(self, TextureRegion)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return TextureRegion
|
||||
@ -1,34 +1,34 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 TextureWrap = {
|
||||
ClampToEdge = 0,
|
||||
Repeat = 1
|
||||
}
|
||||
return TextureWrap
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 TextureWrap = {
|
||||
ClampToEdge = 0,
|
||||
Repeat = 1
|
||||
}
|
||||
return TextureWrap
|
||||
@ -1,343 +1,343 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local utils = require "spine-lua.utils"
|
||||
local math_pi = math.pi
|
||||
local math_pi2 = math.pi * 2
|
||||
local math_atan2 = math.atan2
|
||||
local math_sqrt = math.sqrt
|
||||
local math_acos = math.acos
|
||||
local math_sin = math.sin
|
||||
local math_cos = math.cos
|
||||
local table_insert = table.insert
|
||||
local math_deg = math.deg
|
||||
local math_rad = math.rad
|
||||
local math_abs = math.abs
|
||||
local math_floor = math.floor
|
||||
|
||||
local TransformConstraint = {}
|
||||
TransformConstraint.__index = TransformConstraint
|
||||
|
||||
function TransformConstraint.new (data, skeleton)
|
||||
if not data then error("data cannot be nil", 2) end
|
||||
if not skeleton then error("skeleton cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
data = data,
|
||||
bones = {},
|
||||
target = nil,
|
||||
rotateMix = data.rotateMix, translateMix = data.translateMix, scaleMix = data.scaleMix, shearMix = data.shearMix,
|
||||
temp = { 0, 0 },
|
||||
active = false
|
||||
}
|
||||
setmetatable(self, TransformConstraint)
|
||||
|
||||
for _,bone in ipairs(data.bones) do
|
||||
table_insert(self.bones, skeleton:findBone(bone.name))
|
||||
end
|
||||
self.target = skeleton:findBone(data.target.name)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function TransformConstraint:apply ()
|
||||
self:update()
|
||||
end
|
||||
|
||||
function TransformConstraint:update ()
|
||||
if self.data.local_ then
|
||||
if self.data.relative then
|
||||
self:applyRelativeLocal()
|
||||
else
|
||||
self:applyAbsoluteLocal()
|
||||
end
|
||||
else
|
||||
if self.data.relative then
|
||||
self:applyRelativeWorld()
|
||||
else
|
||||
self:applyAbsoluteWorld()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TransformConstraint:applyAbsoluteWorld ()
|
||||
local rotateMix = self.rotateMix
|
||||
local translateMix = self.translateMix
|
||||
local scaleMix = self.scaleMix
|
||||
local shearMix = self.shearMix
|
||||
local target = self.target
|
||||
local ta = target.a
|
||||
local tb = target.b
|
||||
local tc = target.c
|
||||
local td = target.d
|
||||
local degRadReflect = 0;
|
||||
if ta * td - tb * tc > 0 then degRadReflect = utils.degRad else degRadReflect = -utils.degRad end
|
||||
local offsetRotation = self.data.offsetRotation * degRadReflect
|
||||
local offsetShearY = self.data.offsetShearY * degRadReflect
|
||||
local bones = self.bones
|
||||
for _, bone in ipairs(bones) do
|
||||
local modified = false
|
||||
if rotateMix ~= 0 then
|
||||
local a = bone.a
|
||||
local b = bone.b
|
||||
local c = bone.c
|
||||
local d = bone.d
|
||||
local r = math_atan2(tc, ta) - math_atan2(c, a) + offsetRotation
|
||||
if r > math_pi then
|
||||
r = r - math_pi2
|
||||
elseif r < -math_pi then
|
||||
r = r + math_pi2
|
||||
end
|
||||
r = r * rotateMix
|
||||
local cos = math_cos(r)
|
||||
local sin = math_sin(r)
|
||||
bone.a = cos * a - sin * c
|
||||
bone.b = cos * b - sin * d
|
||||
bone.c = sin * a + cos * c
|
||||
bone.d = sin * b + cos * d
|
||||
modified = true
|
||||
end
|
||||
|
||||
if translateMix ~= 0 then
|
||||
local temp = self.temp
|
||||
temp[1] = self.data.offsetX
|
||||
temp[2] = self.data.offsetY
|
||||
target:localToWorld(temp)
|
||||
bone.worldX = bone.worldX + (temp[1] - bone.worldX) * translateMix
|
||||
bone.worldY = bone.worldY + (temp[2] - bone.worldY) * translateMix
|
||||
modified = true
|
||||
end
|
||||
|
||||
if scaleMix > 0 then
|
||||
local s = math_sqrt(bone.a * bone.a + bone.c * bone.c)
|
||||
local ts = math_sqrt(ta * ta + tc * tc)
|
||||
if s > 0.00001 then
|
||||
s = (s + (ts - s + self.data.offsetScaleX) * scaleMix) / s
|
||||
end
|
||||
bone.a = bone.a * s
|
||||
bone.c = bone.c * s
|
||||
s = math_sqrt(bone.b * bone.b + bone.d * bone.d)
|
||||
ts = math_sqrt(tb * tb + td * td)
|
||||
if s > 0.00001 then
|
||||
s = (s + (ts - s + self.data.offsetScaleY) * scaleMix) / s
|
||||
end
|
||||
bone.b = bone.b * s
|
||||
bone.d = bone.d * s
|
||||
modified = true
|
||||
end
|
||||
|
||||
if shearMix > 0 then
|
||||
local b = bone.b
|
||||
local d = bone.d
|
||||
local by = math_atan2(d, b)
|
||||
local r = math_atan2(td, tb) - math_atan2(tc, ta) - (by - math_atan2(bone.c, bone.a))
|
||||
if r > math_pi then
|
||||
r = r - math_pi2
|
||||
elseif r < -math_pi then
|
||||
r = r + math_pi2
|
||||
end
|
||||
r = by + (r + offsetShearY) * shearMix
|
||||
local s = math_sqrt(b * b + d * d)
|
||||
bone.b = math_cos(r) * s
|
||||
bone.d = math_sin(r) * s
|
||||
modified = true
|
||||
end
|
||||
|
||||
if modified then bone.appliedValid = false end
|
||||
end
|
||||
end
|
||||
|
||||
function TransformConstraint:applyRelativeWorld ()
|
||||
local rotateMix = self.rotateMix
|
||||
local translateMix = self.translateMix
|
||||
local scaleMix = self.scaleMix
|
||||
local shearMix = self.shearMix
|
||||
local target = self.target
|
||||
local ta = target.a
|
||||
local tb = target.b
|
||||
local tc = target.c
|
||||
local td = target.d
|
||||
local degRadReflect = 0;
|
||||
if ta * td - tb * tc > 0 then degRadReflect = utils.degRad else degRadReflect = -utils.degRad end
|
||||
local offsetRotation = self.data.offsetRotation * degRadReflect
|
||||
local offsetShearY = self.data.offsetShearY * degRadReflect
|
||||
local bones = self.bones
|
||||
for _, bone in ipairs(bones) do
|
||||
local modified = false
|
||||
|
||||
if rotateMix ~= 0 then
|
||||
local a = bone.a
|
||||
local b = bone.b
|
||||
local c = bone.c
|
||||
local d = bone.d
|
||||
local r = math_atan2(tc, ta) + offsetRotation
|
||||
if r > math_pi then
|
||||
r = r - math_pi2
|
||||
elseif r < -math_pi then
|
||||
r = r + math_pi2
|
||||
end
|
||||
r = r * rotateMix
|
||||
local cos = math_cos(r)
|
||||
local sin = math_sin(r)
|
||||
bone.a = cos * a - sin * c
|
||||
bone.b = cos * b - sin * d
|
||||
bone.c = sin * a + cos * c
|
||||
bone.d = sin * b + cos * d
|
||||
modified = true
|
||||
end
|
||||
|
||||
if translateMix ~= 0 then
|
||||
local temp = self.temp
|
||||
temp[1] = self.data.offsetX
|
||||
temp[2] = self.data.offsetY
|
||||
target:localToWorld(temp)
|
||||
bone.worldX = bone.worldX + temp[1] * translateMix
|
||||
bone.worldY = bone.worldY + temp[2] * translateMix
|
||||
modified = true
|
||||
end
|
||||
|
||||
if scaleMix > 0 then
|
||||
local s = (math_sqrt(ta * ta + tc * tc) - 1 + self.data.offsetScaleX) * scaleMix + 1
|
||||
bone.a = bone.a * s
|
||||
bone.c = bone.c * s
|
||||
s = (math_sqrt(tb * tb + td * td) - 1 + self.data.offsetScaleY) * scaleMix + 1
|
||||
bone.b = bone.b * s
|
||||
bone.d = bone.d * s
|
||||
modified = true
|
||||
end
|
||||
|
||||
if shearMix > 0 then
|
||||
local r = math_atan2(td, tb) - math_atan2(tc, ta)
|
||||
if r > math_pi then
|
||||
r = r - math_pi2
|
||||
elseif r < -math_pi then
|
||||
r = r + math_pi2
|
||||
end
|
||||
local b = bone.b
|
||||
local d = bone.d
|
||||
r = math_atan2(d, b) + (r - math_pi / 2 + offsetShearY) * shearMix;
|
||||
local s = math_sqrt(b * b + d * d)
|
||||
bone.b = math_cos(r) * s
|
||||
bone.d = math_sin(r) * s
|
||||
modified = true
|
||||
end
|
||||
|
||||
if modified then bone.appliedValid = false end
|
||||
end
|
||||
end
|
||||
|
||||
function TransformConstraint:applyAbsoluteLocal ()
|
||||
local rotateMix = self.rotateMix
|
||||
local translateMix = self.translateMix
|
||||
local scaleMix = self.scaleMix
|
||||
local shearMix = self.shearMix
|
||||
local target = self.target
|
||||
if not target.appliedValid then target:updatedAppliedTransform() end
|
||||
local bones = self.bones
|
||||
for _, bone in ipairs(bones) do
|
||||
local modified = false
|
||||
if not bone.appliedValid then bone:updateAppliedTransform() end
|
||||
|
||||
local rotation = bone.arotation
|
||||
if rotateMix ~= 0 then
|
||||
local r = target.arotation - rotation + self.data.offsetRotation
|
||||
r = r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360
|
||||
rotation = rotation + r * rotateMix
|
||||
end
|
||||
|
||||
local x = bone.ax
|
||||
local y = bone.ay
|
||||
if translateMix ~= 0 then
|
||||
x = x + (target.ax - x + self.data.offsetX) * translateMix
|
||||
y = x + (target.ay - y + self.data.offsetY) * translateMix
|
||||
end
|
||||
|
||||
local scaleX = bone.ascaleX
|
||||
local scaleY = bone.ascaleY
|
||||
if scaleMix ~= 0 then
|
||||
if scaleX > 0.00001 then
|
||||
scaleX = (scaleX + (target.ascaleX - scaleX + self.data.offsetScaleX) * scaleMix) / scaleX
|
||||
end
|
||||
if scaleY > 0.00001 then
|
||||
scaleY = (scaleY + (target.ascaleY - scaleY + self.data.offsetScaleY) * scaleMix) / scaleY
|
||||
end
|
||||
end
|
||||
|
||||
local shearY = bone.ashearY
|
||||
if shearMix ~= 0 then
|
||||
local r = target.ashearY - shearY + self.data.offsetShearY
|
||||
r = r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360
|
||||
bone.shearY = bone.shearY + r * shearMix
|
||||
end
|
||||
|
||||
bone:updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
|
||||
end
|
||||
end
|
||||
|
||||
function TransformConstraint:applyRelativeLocal ()
|
||||
local rotateMix = self.rotateMix
|
||||
local translateMix = self.translateMix
|
||||
local scaleMix = self.scaleMix
|
||||
local shearMix = self.shearMix
|
||||
local target = self.target
|
||||
if not target.appliedValid then target:updateAppliedTransform() end
|
||||
local bones = self.bones
|
||||
for _, bone in ipairs(bones) do
|
||||
if not bone.appliedValid then bone:updateAppliedTransform() end
|
||||
|
||||
local rotation = bone.arotation
|
||||
if rotateMix ~= 0 then rotation = rotation + (target.arotation + self.data.offsetRotation) * rotateMix end
|
||||
|
||||
local x = bone.ax
|
||||
local y = bone.ay
|
||||
if translateMix ~= 0 then
|
||||
x = x + (target.ax + self.data.offsetX) * translateMix
|
||||
y = y + (target.ay + self.data.offsetY) * translateMix
|
||||
end
|
||||
|
||||
local scaleX = bone.ascaleX
|
||||
local scaleY = bone.ascaleY
|
||||
if scaleMix ~= 0 then
|
||||
if scaleX > 0.00001 then
|
||||
scaleX = scaleX * (((target.ascaleX - 1 + self.data.offsetScaleX) * scaleMix) + 1)
|
||||
end
|
||||
if scaleY > 0.00001 then
|
||||
scaleY = scaleY * (((target.ascaleY - 1 + self.data.offsetScaleY) * scaleMix) + 1)
|
||||
end
|
||||
end
|
||||
|
||||
local shearY = bone.ashearY
|
||||
if shearMix ~= 0 then shearY = shearY + (target.ashearY + self.data.offsetShearY) * shearMix end
|
||||
|
||||
bone:updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY)
|
||||
end
|
||||
end
|
||||
|
||||
return TransformConstraint
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local utils = require "spine-lua.utils"
|
||||
local math_pi = math.pi
|
||||
local math_pi2 = math.pi * 2
|
||||
local math_atan2 = math.atan2
|
||||
local math_sqrt = math.sqrt
|
||||
local math_acos = math.acos
|
||||
local math_sin = math.sin
|
||||
local math_cos = math.cos
|
||||
local table_insert = table.insert
|
||||
local math_deg = math.deg
|
||||
local math_rad = math.rad
|
||||
local math_abs = math.abs
|
||||
local math_floor = math.floor
|
||||
|
||||
local TransformConstraint = {}
|
||||
TransformConstraint.__index = TransformConstraint
|
||||
|
||||
function TransformConstraint.new (data, skeleton)
|
||||
if not data then error("data cannot be nil", 2) end
|
||||
if not skeleton then error("skeleton cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
data = data,
|
||||
bones = {},
|
||||
target = nil,
|
||||
rotateMix = data.rotateMix, translateMix = data.translateMix, scaleMix = data.scaleMix, shearMix = data.shearMix,
|
||||
temp = { 0, 0 },
|
||||
active = false
|
||||
}
|
||||
setmetatable(self, TransformConstraint)
|
||||
|
||||
for _,bone in ipairs(data.bones) do
|
||||
table_insert(self.bones, skeleton:findBone(bone.name))
|
||||
end
|
||||
self.target = skeleton:findBone(data.target.name)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function TransformConstraint:apply ()
|
||||
self:update()
|
||||
end
|
||||
|
||||
function TransformConstraint:update ()
|
||||
if self.data.local_ then
|
||||
if self.data.relative then
|
||||
self:applyRelativeLocal()
|
||||
else
|
||||
self:applyAbsoluteLocal()
|
||||
end
|
||||
else
|
||||
if self.data.relative then
|
||||
self:applyRelativeWorld()
|
||||
else
|
||||
self:applyAbsoluteWorld()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TransformConstraint:applyAbsoluteWorld ()
|
||||
local rotateMix = self.rotateMix
|
||||
local translateMix = self.translateMix
|
||||
local scaleMix = self.scaleMix
|
||||
local shearMix = self.shearMix
|
||||
local target = self.target
|
||||
local ta = target.a
|
||||
local tb = target.b
|
||||
local tc = target.c
|
||||
local td = target.d
|
||||
local degRadReflect = 0;
|
||||
if ta * td - tb * tc > 0 then degRadReflect = utils.degRad else degRadReflect = -utils.degRad end
|
||||
local offsetRotation = self.data.offsetRotation * degRadReflect
|
||||
local offsetShearY = self.data.offsetShearY * degRadReflect
|
||||
local bones = self.bones
|
||||
for _, bone in ipairs(bones) do
|
||||
local modified = false
|
||||
if rotateMix ~= 0 then
|
||||
local a = bone.a
|
||||
local b = bone.b
|
||||
local c = bone.c
|
||||
local d = bone.d
|
||||
local r = math_atan2(tc, ta) - math_atan2(c, a) + offsetRotation
|
||||
if r > math_pi then
|
||||
r = r - math_pi2
|
||||
elseif r < -math_pi then
|
||||
r = r + math_pi2
|
||||
end
|
||||
r = r * rotateMix
|
||||
local cos = math_cos(r)
|
||||
local sin = math_sin(r)
|
||||
bone.a = cos * a - sin * c
|
||||
bone.b = cos * b - sin * d
|
||||
bone.c = sin * a + cos * c
|
||||
bone.d = sin * b + cos * d
|
||||
modified = true
|
||||
end
|
||||
|
||||
if translateMix ~= 0 then
|
||||
local temp = self.temp
|
||||
temp[1] = self.data.offsetX
|
||||
temp[2] = self.data.offsetY
|
||||
target:localToWorld(temp)
|
||||
bone.worldX = bone.worldX + (temp[1] - bone.worldX) * translateMix
|
||||
bone.worldY = bone.worldY + (temp[2] - bone.worldY) * translateMix
|
||||
modified = true
|
||||
end
|
||||
|
||||
if scaleMix > 0 then
|
||||
local s = math_sqrt(bone.a * bone.a + bone.c * bone.c)
|
||||
local ts = math_sqrt(ta * ta + tc * tc)
|
||||
if s > 0.00001 then
|
||||
s = (s + (ts - s + self.data.offsetScaleX) * scaleMix) / s
|
||||
end
|
||||
bone.a = bone.a * s
|
||||
bone.c = bone.c * s
|
||||
s = math_sqrt(bone.b * bone.b + bone.d * bone.d)
|
||||
ts = math_sqrt(tb * tb + td * td)
|
||||
if s > 0.00001 then
|
||||
s = (s + (ts - s + self.data.offsetScaleY) * scaleMix) / s
|
||||
end
|
||||
bone.b = bone.b * s
|
||||
bone.d = bone.d * s
|
||||
modified = true
|
||||
end
|
||||
|
||||
if shearMix > 0 then
|
||||
local b = bone.b
|
||||
local d = bone.d
|
||||
local by = math_atan2(d, b)
|
||||
local r = math_atan2(td, tb) - math_atan2(tc, ta) - (by - math_atan2(bone.c, bone.a))
|
||||
if r > math_pi then
|
||||
r = r - math_pi2
|
||||
elseif r < -math_pi then
|
||||
r = r + math_pi2
|
||||
end
|
||||
r = by + (r + offsetShearY) * shearMix
|
||||
local s = math_sqrt(b * b + d * d)
|
||||
bone.b = math_cos(r) * s
|
||||
bone.d = math_sin(r) * s
|
||||
modified = true
|
||||
end
|
||||
|
||||
if modified then bone.appliedValid = false end
|
||||
end
|
||||
end
|
||||
|
||||
function TransformConstraint:applyRelativeWorld ()
|
||||
local rotateMix = self.rotateMix
|
||||
local translateMix = self.translateMix
|
||||
local scaleMix = self.scaleMix
|
||||
local shearMix = self.shearMix
|
||||
local target = self.target
|
||||
local ta = target.a
|
||||
local tb = target.b
|
||||
local tc = target.c
|
||||
local td = target.d
|
||||
local degRadReflect = 0;
|
||||
if ta * td - tb * tc > 0 then degRadReflect = utils.degRad else degRadReflect = -utils.degRad end
|
||||
local offsetRotation = self.data.offsetRotation * degRadReflect
|
||||
local offsetShearY = self.data.offsetShearY * degRadReflect
|
||||
local bones = self.bones
|
||||
for _, bone in ipairs(bones) do
|
||||
local modified = false
|
||||
|
||||
if rotateMix ~= 0 then
|
||||
local a = bone.a
|
||||
local b = bone.b
|
||||
local c = bone.c
|
||||
local d = bone.d
|
||||
local r = math_atan2(tc, ta) + offsetRotation
|
||||
if r > math_pi then
|
||||
r = r - math_pi2
|
||||
elseif r < -math_pi then
|
||||
r = r + math_pi2
|
||||
end
|
||||
r = r * rotateMix
|
||||
local cos = math_cos(r)
|
||||
local sin = math_sin(r)
|
||||
bone.a = cos * a - sin * c
|
||||
bone.b = cos * b - sin * d
|
||||
bone.c = sin * a + cos * c
|
||||
bone.d = sin * b + cos * d
|
||||
modified = true
|
||||
end
|
||||
|
||||
if translateMix ~= 0 then
|
||||
local temp = self.temp
|
||||
temp[1] = self.data.offsetX
|
||||
temp[2] = self.data.offsetY
|
||||
target:localToWorld(temp)
|
||||
bone.worldX = bone.worldX + temp[1] * translateMix
|
||||
bone.worldY = bone.worldY + temp[2] * translateMix
|
||||
modified = true
|
||||
end
|
||||
|
||||
if scaleMix > 0 then
|
||||
local s = (math_sqrt(ta * ta + tc * tc) - 1 + self.data.offsetScaleX) * scaleMix + 1
|
||||
bone.a = bone.a * s
|
||||
bone.c = bone.c * s
|
||||
s = (math_sqrt(tb * tb + td * td) - 1 + self.data.offsetScaleY) * scaleMix + 1
|
||||
bone.b = bone.b * s
|
||||
bone.d = bone.d * s
|
||||
modified = true
|
||||
end
|
||||
|
||||
if shearMix > 0 then
|
||||
local r = math_atan2(td, tb) - math_atan2(tc, ta)
|
||||
if r > math_pi then
|
||||
r = r - math_pi2
|
||||
elseif r < -math_pi then
|
||||
r = r + math_pi2
|
||||
end
|
||||
local b = bone.b
|
||||
local d = bone.d
|
||||
r = math_atan2(d, b) + (r - math_pi / 2 + offsetShearY) * shearMix;
|
||||
local s = math_sqrt(b * b + d * d)
|
||||
bone.b = math_cos(r) * s
|
||||
bone.d = math_sin(r) * s
|
||||
modified = true
|
||||
end
|
||||
|
||||
if modified then bone.appliedValid = false end
|
||||
end
|
||||
end
|
||||
|
||||
function TransformConstraint:applyAbsoluteLocal ()
|
||||
local rotateMix = self.rotateMix
|
||||
local translateMix = self.translateMix
|
||||
local scaleMix = self.scaleMix
|
||||
local shearMix = self.shearMix
|
||||
local target = self.target
|
||||
if not target.appliedValid then target:updatedAppliedTransform() end
|
||||
local bones = self.bones
|
||||
for _, bone in ipairs(bones) do
|
||||
local modified = false
|
||||
if not bone.appliedValid then bone:updateAppliedTransform() end
|
||||
|
||||
local rotation = bone.arotation
|
||||
if rotateMix ~= 0 then
|
||||
local r = target.arotation - rotation + self.data.offsetRotation
|
||||
r = r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360
|
||||
rotation = rotation + r * rotateMix
|
||||
end
|
||||
|
||||
local x = bone.ax
|
||||
local y = bone.ay
|
||||
if translateMix ~= 0 then
|
||||
x = x + (target.ax - x + self.data.offsetX) * translateMix
|
||||
y = x + (target.ay - y + self.data.offsetY) * translateMix
|
||||
end
|
||||
|
||||
local scaleX = bone.ascaleX
|
||||
local scaleY = bone.ascaleY
|
||||
if scaleMix ~= 0 then
|
||||
if scaleX > 0.00001 then
|
||||
scaleX = (scaleX + (target.ascaleX - scaleX + self.data.offsetScaleX) * scaleMix) / scaleX
|
||||
end
|
||||
if scaleY > 0.00001 then
|
||||
scaleY = (scaleY + (target.ascaleY - scaleY + self.data.offsetScaleY) * scaleMix) / scaleY
|
||||
end
|
||||
end
|
||||
|
||||
local shearY = bone.ashearY
|
||||
if shearMix ~= 0 then
|
||||
local r = target.ashearY - shearY + self.data.offsetShearY
|
||||
r = r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360
|
||||
bone.shearY = bone.shearY + r * shearMix
|
||||
end
|
||||
|
||||
bone:updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
|
||||
end
|
||||
end
|
||||
|
||||
function TransformConstraint:applyRelativeLocal ()
|
||||
local rotateMix = self.rotateMix
|
||||
local translateMix = self.translateMix
|
||||
local scaleMix = self.scaleMix
|
||||
local shearMix = self.shearMix
|
||||
local target = self.target
|
||||
if not target.appliedValid then target:updateAppliedTransform() end
|
||||
local bones = self.bones
|
||||
for _, bone in ipairs(bones) do
|
||||
if not bone.appliedValid then bone:updateAppliedTransform() end
|
||||
|
||||
local rotation = bone.arotation
|
||||
if rotateMix ~= 0 then rotation = rotation + (target.arotation + self.data.offsetRotation) * rotateMix end
|
||||
|
||||
local x = bone.ax
|
||||
local y = bone.ay
|
||||
if translateMix ~= 0 then
|
||||
x = x + (target.ax + self.data.offsetX) * translateMix
|
||||
y = y + (target.ay + self.data.offsetY) * translateMix
|
||||
end
|
||||
|
||||
local scaleX = bone.ascaleX
|
||||
local scaleY = bone.ascaleY
|
||||
if scaleMix ~= 0 then
|
||||
if scaleX > 0.00001 then
|
||||
scaleX = scaleX * (((target.ascaleX - 1 + self.data.offsetScaleX) * scaleMix) + 1)
|
||||
end
|
||||
if scaleY > 0.00001 then
|
||||
scaleY = scaleY * (((target.ascaleY - 1 + self.data.offsetScaleY) * scaleMix) + 1)
|
||||
end
|
||||
end
|
||||
|
||||
local shearY = bone.ashearY
|
||||
if shearMix ~= 0 then shearY = shearY + (target.ashearY + self.data.offsetShearY) * shearMix end
|
||||
|
||||
bone:updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY)
|
||||
end
|
||||
end
|
||||
|
||||
return TransformConstraint
|
||||
@ -1,49 +1,49 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 TransformConstraintData = {}
|
||||
function TransformConstraintData.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
order = 0,
|
||||
skinRequired = false,
|
||||
bones = {},
|
||||
target = nil,
|
||||
rotateMix = 0, translateMix = 0, scaleMix = 0, shearMix = 0,
|
||||
offsetRotation = 0, offsetX = 0, offsetY = 0, offsetScaleX = 0, offsetScaleY = 0, offsetShearY = 0,
|
||||
relative = false,
|
||||
local_ = false
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return TransformConstraintData
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 TransformConstraintData = {}
|
||||
function TransformConstraintData.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
order = 0,
|
||||
skinRequired = false,
|
||||
bones = {},
|
||||
target = nil,
|
||||
rotateMix = 0, translateMix = 0, scaleMix = 0, shearMix = 0,
|
||||
offsetRotation = 0, offsetX = 0, offsetY = 0, offsetScaleX = 0, offsetScaleY = 0, offsetShearY = 0,
|
||||
relative = false,
|
||||
local_ = false
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return TransformConstraintData
|
||||
@ -1,53 +1,53 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
|
||||
local AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
|
||||
local Attachment = {}
|
||||
Attachment.__index = Attachment
|
||||
|
||||
function Attachment.new (name, attachmentType)
|
||||
if not name then error("name cannot be nil.", 2) end
|
||||
if not attachmentType then error("attachmentType cannot be nil.", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
type = attachmentType
|
||||
}
|
||||
setmetatable(self, Attachment)
|
||||
return self
|
||||
end
|
||||
|
||||
function Attachment:copy ()
|
||||
error("Attachment copy not implemented.")
|
||||
end
|
||||
|
||||
return Attachment
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
|
||||
local AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
|
||||
local Attachment = {}
|
||||
Attachment.__index = Attachment
|
||||
|
||||
function Attachment.new (name, attachmentType)
|
||||
if not name then error("name cannot be nil.", 2) end
|
||||
if not attachmentType then error("attachmentType cannot be nil.", 2) end
|
||||
|
||||
local self = {
|
||||
name = name,
|
||||
type = attachmentType
|
||||
}
|
||||
setmetatable(self, Attachment)
|
||||
return self
|
||||
end
|
||||
|
||||
function Attachment:copy ()
|
||||
error("Attachment copy not implemented.")
|
||||
end
|
||||
|
||||
return Attachment
|
||||
@ -1,39 +1,39 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = {
|
||||
region = 0,
|
||||
boundingbox = 1,
|
||||
mesh = 2,
|
||||
linkedmesh = 3,
|
||||
path = 4,
|
||||
point = 5,
|
||||
clipping = 6
|
||||
}
|
||||
return AttachmentType
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = {
|
||||
region = 0,
|
||||
boundingbox = 1,
|
||||
mesh = 2,
|
||||
linkedmesh = 3,
|
||||
path = 4,
|
||||
point = 5,
|
||||
clipping = 6
|
||||
}
|
||||
return AttachmentType
|
||||
@ -1,53 +1,53 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local VertexAttachment = require "spine-lua.attachments.VertexAttachment"
|
||||
local Color = require "spine-lua.Color"
|
||||
|
||||
local BoundingBoxAttachment = {}
|
||||
BoundingBoxAttachment.__index = BoundingBoxAttachment
|
||||
setmetatable(BoundingBoxAttachment, { __index = VertexAttachment })
|
||||
|
||||
function BoundingBoxAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = VertexAttachment.new(name, AttachmentType.boundingbox)
|
||||
self.color = Color.newWith(1, 1, 1, 1)
|
||||
setmetatable(self, BoundingBoxAttachment)
|
||||
return self
|
||||
end
|
||||
|
||||
function BoundingBoxAttachment:copy ()
|
||||
local copy = BoundingBoxAttachment.new(self.name)
|
||||
self:copyTo(copy)
|
||||
copy.color:setFrom(self.color)
|
||||
return copy
|
||||
end
|
||||
return BoundingBoxAttachment
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local VertexAttachment = require "spine-lua.attachments.VertexAttachment"
|
||||
local Color = require "spine-lua.Color"
|
||||
|
||||
local BoundingBoxAttachment = {}
|
||||
BoundingBoxAttachment.__index = BoundingBoxAttachment
|
||||
setmetatable(BoundingBoxAttachment, { __index = VertexAttachment })
|
||||
|
||||
function BoundingBoxAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = VertexAttachment.new(name, AttachmentType.boundingbox)
|
||||
self.color = Color.newWith(1, 1, 1, 1)
|
||||
setmetatable(self, BoundingBoxAttachment)
|
||||
return self
|
||||
end
|
||||
|
||||
function BoundingBoxAttachment:copy ()
|
||||
local copy = BoundingBoxAttachment.new(self.name)
|
||||
self:copyTo(copy)
|
||||
copy.color:setFrom(self.color)
|
||||
return copy
|
||||
end
|
||||
return BoundingBoxAttachment
|
||||
@ -1,180 +1,180 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local VertexAttachment = require "spine-lua.attachments.VertexAttachment"
|
||||
local utils = require "spine-lua.utils"
|
||||
local Color = require "spine-lua.Color"
|
||||
|
||||
local MeshAttachment = {}
|
||||
MeshAttachment.__index = MeshAttachment
|
||||
setmetatable(MeshAttachment, { __index = VertexAttachment })
|
||||
|
||||
function MeshAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = VertexAttachment.new(name, AttachmentType.mesh)
|
||||
self.region = nil
|
||||
self.path = nil
|
||||
self.regionUVs = nil
|
||||
self.uvs = nil
|
||||
self.triangles = nil
|
||||
self.color = Color.newWith(1, 1, 1, 1)
|
||||
self.hullLength = 0
|
||||
self.parentMesh = nil
|
||||
self.tempColor = Color.newWith(1, 1, 1, 1)
|
||||
self.width = 0
|
||||
self.height = 0
|
||||
setmetatable(self, MeshAttachment)
|
||||
return self
|
||||
end
|
||||
|
||||
function MeshAttachment:updateUVs ()
|
||||
local u = 0
|
||||
local v = 0
|
||||
local width = 0
|
||||
local height = 0
|
||||
|
||||
local regionUVs = self.regionUVs
|
||||
if not self.uvs or (#self.uvs ~= #regionUVs) then self.uvs = utils.newNumberArray(#regionUVs) end
|
||||
local uvs = self.uvs
|
||||
|
||||
if not self.region then
|
||||
u = 0
|
||||
v = 0
|
||||
width = 1
|
||||
height = 1
|
||||
else
|
||||
local region = self.region
|
||||
local textureWidth = region.page.width
|
||||
local textureHeight = region.page.height
|
||||
|
||||
if region.degrees == 90 then
|
||||
u = region.u - (region.originalHeight - region.offsetY - region.height) / textureWidth
|
||||
v = region.v - (region.originalWidth - region.offsetX - region.width) / textureHeight
|
||||
width = region.originalHeight / textureWidth
|
||||
height = region.originalWidth / textureHeight
|
||||
local i = 0
|
||||
local n = #uvs
|
||||
while i < n do
|
||||
uvs[i + 1] = u + regionUVs[i + 2] * width;
|
||||
uvs[i + 2] = v + (1 - regionUVs[i + 1]) * height;
|
||||
i = i + 2
|
||||
end
|
||||
elseif region.degrees == 180 then
|
||||
u = region.u - (region.originalWidth - region.offsetX - region.width) / textureWidth
|
||||
v = region.v - region.offsetY / textureHeight
|
||||
width = region.originalWidth / textureWidth
|
||||
height = region.originalHeight / textureHeight
|
||||
local i = 0
|
||||
local n = #uvs
|
||||
while i < n do
|
||||
uvs[i + 1] = u + (1 - regionUVs[i + 1]) * width;
|
||||
uvs[i + 2] = v + (1 - regionUVs[i + 2]) * height;
|
||||
i = i + 2
|
||||
end
|
||||
elseif region.degrees == 270 then
|
||||
u = region.u - region.offsetY / textureWidth
|
||||
v = region.v - region.offsetX / textureHeight
|
||||
width = region.originalHeight / textureWidth
|
||||
height = region.originalWidth / textureHeight
|
||||
local i = 0
|
||||
local n = #uvs
|
||||
while i < n do
|
||||
uvs[i + 1] = u + (1 - regionUVs[i + 2]) * width;
|
||||
uvs[i + 2] = v + regionUVs[i + 1] * height;
|
||||
i = i + 2
|
||||
end
|
||||
else
|
||||
u = region.u - region.offsetX / textureWidth;
|
||||
v = region.v - (region.originalHeight - region.offsetY - region.height) / textureHeight;
|
||||
width = region.originalWidth / textureWidth;
|
||||
height = region.originalHeight / textureHeight;
|
||||
local i = 0
|
||||
local n = #uvs
|
||||
while i < n do
|
||||
uvs[i + 1] = u + regionUVs[i + 1] * width;
|
||||
uvs[i + 2] = v + regionUVs[i + 2] * height;
|
||||
i = i + 2
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MeshAttachment:setParentMesh (parentMesh)
|
||||
self.parentMesh = parentMesh
|
||||
if parentMesh then
|
||||
self.bones = parentMesh.bones
|
||||
self.vertices = parentMesh.vertices
|
||||
self.worldVerticesLength = parentMesh.worldVerticesLength
|
||||
self.regionUVs = parentMesh.regionUVs
|
||||
self.triangles = parentMesh.triangles
|
||||
self.hullLength = parentMesh.hullLength
|
||||
end
|
||||
end
|
||||
|
||||
function MeshAttachment:copy ()
|
||||
if self.parentMesh then return self:newLinkedMesh() end
|
||||
|
||||
local copy = MeshAttachment.new(self.name)
|
||||
copy.region = self.region
|
||||
copy.path = self.path
|
||||
copy.color:setFrom(self.color)
|
||||
|
||||
self:copyTo(copy)
|
||||
copy.regionUVs = utils.copy(self.regionUVs)
|
||||
copy.uvs = utils.copy(self.uvs)
|
||||
copy.triangles = utils.copy(self.triangles)
|
||||
copy.hullLength = self.hullLength
|
||||
if self.edges then
|
||||
copy.edges = utils.copy(edges)
|
||||
end
|
||||
copy.width = self.width
|
||||
copy.height = self.height
|
||||
|
||||
return copy
|
||||
end
|
||||
|
||||
function MeshAttachment:newLinkedMesh ()
|
||||
local copy = MeshAttachment.new(self.name)
|
||||
copy.region = self.region
|
||||
copy.path = self.path
|
||||
copy.color:setFrom(self.color)
|
||||
if self.parentMesh then
|
||||
copy.deformAttachment = self.parentMesh
|
||||
else
|
||||
copy.deformAttachment = self
|
||||
end
|
||||
copy:setParentMesh(self.parentMesh)
|
||||
copy:updateUVs()
|
||||
return copy
|
||||
end
|
||||
|
||||
return MeshAttachment
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local VertexAttachment = require "spine-lua.attachments.VertexAttachment"
|
||||
local utils = require "spine-lua.utils"
|
||||
local Color = require "spine-lua.Color"
|
||||
|
||||
local MeshAttachment = {}
|
||||
MeshAttachment.__index = MeshAttachment
|
||||
setmetatable(MeshAttachment, { __index = VertexAttachment })
|
||||
|
||||
function MeshAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = VertexAttachment.new(name, AttachmentType.mesh)
|
||||
self.region = nil
|
||||
self.path = nil
|
||||
self.regionUVs = nil
|
||||
self.uvs = nil
|
||||
self.triangles = nil
|
||||
self.color = Color.newWith(1, 1, 1, 1)
|
||||
self.hullLength = 0
|
||||
self.parentMesh = nil
|
||||
self.tempColor = Color.newWith(1, 1, 1, 1)
|
||||
self.width = 0
|
||||
self.height = 0
|
||||
setmetatable(self, MeshAttachment)
|
||||
return self
|
||||
end
|
||||
|
||||
function MeshAttachment:updateUVs ()
|
||||
local u = 0
|
||||
local v = 0
|
||||
local width = 0
|
||||
local height = 0
|
||||
|
||||
local regionUVs = self.regionUVs
|
||||
if not self.uvs or (#self.uvs ~= #regionUVs) then self.uvs = utils.newNumberArray(#regionUVs) end
|
||||
local uvs = self.uvs
|
||||
|
||||
if not self.region then
|
||||
u = 0
|
||||
v = 0
|
||||
width = 1
|
||||
height = 1
|
||||
else
|
||||
local region = self.region
|
||||
local textureWidth = region.page.width
|
||||
local textureHeight = region.page.height
|
||||
|
||||
if region.degrees == 90 then
|
||||
u = region.u - (region.originalHeight - region.offsetY - region.height) / textureWidth
|
||||
v = region.v - (region.originalWidth - region.offsetX - region.width) / textureHeight
|
||||
width = region.originalHeight / textureWidth
|
||||
height = region.originalWidth / textureHeight
|
||||
local i = 0
|
||||
local n = #uvs
|
||||
while i < n do
|
||||
uvs[i + 1] = u + regionUVs[i + 2] * width;
|
||||
uvs[i + 2] = v + (1 - regionUVs[i + 1]) * height;
|
||||
i = i + 2
|
||||
end
|
||||
elseif region.degrees == 180 then
|
||||
u = region.u - (region.originalWidth - region.offsetX - region.width) / textureWidth
|
||||
v = region.v - region.offsetY / textureHeight
|
||||
width = region.originalWidth / textureWidth
|
||||
height = region.originalHeight / textureHeight
|
||||
local i = 0
|
||||
local n = #uvs
|
||||
while i < n do
|
||||
uvs[i + 1] = u + (1 - regionUVs[i + 1]) * width;
|
||||
uvs[i + 2] = v + (1 - regionUVs[i + 2]) * height;
|
||||
i = i + 2
|
||||
end
|
||||
elseif region.degrees == 270 then
|
||||
u = region.u - region.offsetY / textureWidth
|
||||
v = region.v - region.offsetX / textureHeight
|
||||
width = region.originalHeight / textureWidth
|
||||
height = region.originalWidth / textureHeight
|
||||
local i = 0
|
||||
local n = #uvs
|
||||
while i < n do
|
||||
uvs[i + 1] = u + (1 - regionUVs[i + 2]) * width;
|
||||
uvs[i + 2] = v + regionUVs[i + 1] * height;
|
||||
i = i + 2
|
||||
end
|
||||
else
|
||||
u = region.u - region.offsetX / textureWidth;
|
||||
v = region.v - (region.originalHeight - region.offsetY - region.height) / textureHeight;
|
||||
width = region.originalWidth / textureWidth;
|
||||
height = region.originalHeight / textureHeight;
|
||||
local i = 0
|
||||
local n = #uvs
|
||||
while i < n do
|
||||
uvs[i + 1] = u + regionUVs[i + 1] * width;
|
||||
uvs[i + 2] = v + regionUVs[i + 2] * height;
|
||||
i = i + 2
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MeshAttachment:setParentMesh (parentMesh)
|
||||
self.parentMesh = parentMesh
|
||||
if parentMesh then
|
||||
self.bones = parentMesh.bones
|
||||
self.vertices = parentMesh.vertices
|
||||
self.worldVerticesLength = parentMesh.worldVerticesLength
|
||||
self.regionUVs = parentMesh.regionUVs
|
||||
self.triangles = parentMesh.triangles
|
||||
self.hullLength = parentMesh.hullLength
|
||||
end
|
||||
end
|
||||
|
||||
function MeshAttachment:copy ()
|
||||
if self.parentMesh then return self:newLinkedMesh() end
|
||||
|
||||
local copy = MeshAttachment.new(self.name)
|
||||
copy.region = self.region
|
||||
copy.path = self.path
|
||||
copy.color:setFrom(self.color)
|
||||
|
||||
self:copyTo(copy)
|
||||
copy.regionUVs = utils.copy(self.regionUVs)
|
||||
copy.uvs = utils.copy(self.uvs)
|
||||
copy.triangles = utils.copy(self.triangles)
|
||||
copy.hullLength = self.hullLength
|
||||
if self.edges then
|
||||
copy.edges = utils.copy(edges)
|
||||
end
|
||||
copy.width = self.width
|
||||
copy.height = self.height
|
||||
|
||||
return copy
|
||||
end
|
||||
|
||||
function MeshAttachment:newLinkedMesh ()
|
||||
local copy = MeshAttachment.new(self.name)
|
||||
copy.region = self.region
|
||||
copy.path = self.path
|
||||
copy.color:setFrom(self.color)
|
||||
if self.parentMesh then
|
||||
copy.deformAttachment = self.parentMesh
|
||||
else
|
||||
copy.deformAttachment = self
|
||||
end
|
||||
copy:setParentMesh(self.parentMesh)
|
||||
copy:updateUVs()
|
||||
return copy
|
||||
end
|
||||
|
||||
return MeshAttachment
|
||||
@ -1,61 +1,61 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local VertexAttachment = require "spine-lua.attachments.VertexAttachment"
|
||||
local Color = require "spine-lua.Color"
|
||||
local utils = require "spine-lua.utils"
|
||||
|
||||
local PathAttachment = {}
|
||||
PathAttachment.__index = PathAttachment
|
||||
setmetatable(PathAttachment, { __index = VertexAttachment })
|
||||
|
||||
function PathAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = VertexAttachment.new(name, AttachmentType.path)
|
||||
self.lengths = nil
|
||||
self.color = Color.newWith(1, 1, 1, 1)
|
||||
self.closed = false
|
||||
self.constantSpeed = false
|
||||
setmetatable(self, PathAttachment)
|
||||
return self
|
||||
end
|
||||
|
||||
function PathAttachment:copy ()
|
||||
local copy = PathAttachment.new(self.name)
|
||||
self:copyTo(copy)
|
||||
copy.length = utils.copy(self.lengths)
|
||||
copy.closed = self.closed
|
||||
copy.constantSpeed = self.constantSpeed
|
||||
copy.color:setFrom(self.color)
|
||||
return copy
|
||||
end
|
||||
|
||||
return PathAttachment
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local VertexAttachment = require "spine-lua.attachments.VertexAttachment"
|
||||
local Color = require "spine-lua.Color"
|
||||
local utils = require "spine-lua.utils"
|
||||
|
||||
local PathAttachment = {}
|
||||
PathAttachment.__index = PathAttachment
|
||||
setmetatable(PathAttachment, { __index = VertexAttachment })
|
||||
|
||||
function PathAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = VertexAttachment.new(name, AttachmentType.path)
|
||||
self.lengths = nil
|
||||
self.color = Color.newWith(1, 1, 1, 1)
|
||||
self.closed = false
|
||||
self.constantSpeed = false
|
||||
setmetatable(self, PathAttachment)
|
||||
return self
|
||||
end
|
||||
|
||||
function PathAttachment:copy ()
|
||||
local copy = PathAttachment.new(self.name)
|
||||
self:copyTo(copy)
|
||||
copy.length = utils.copy(self.lengths)
|
||||
copy.closed = self.closed
|
||||
copy.constantSpeed = self.constantSpeed
|
||||
copy.color:setFrom(self.color)
|
||||
return copy
|
||||
end
|
||||
|
||||
return PathAttachment
|
||||
@ -1,264 +1,264 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local math_pi = math.pi
|
||||
local math_sin = math.sin
|
||||
local math_cos = math.cos
|
||||
|
||||
local AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local Attachment = require "spine-lua.attachments.Attachment"
|
||||
local Color = require "spine-lua.Color"
|
||||
local Utils = require "spine-lua.utils"
|
||||
|
||||
local OX1 = 1
|
||||
local OY1 = 2
|
||||
local OX2 = 3
|
||||
local OY2 = 4
|
||||
local OX3 = 5
|
||||
local OY3 = 6
|
||||
local OX4 = 7
|
||||
local OY4 = 8
|
||||
|
||||
local X1 = 1
|
||||
local Y1 = 2
|
||||
local U1 = 3
|
||||
local V1 = 4
|
||||
local C1R = 5
|
||||
local C1G = 6
|
||||
local C1B = 7
|
||||
local C1A = 8
|
||||
|
||||
local X2 = 9
|
||||
local Y2 = 10
|
||||
local U2 = 11
|
||||
local V2 = 12
|
||||
local C2R = 13
|
||||
local C2G = 14
|
||||
local C2B = 15
|
||||
local C2A = 16
|
||||
|
||||
local X3 = 17
|
||||
local Y3 = 18
|
||||
local U3 = 19
|
||||
local V3 = 20
|
||||
local C3R = 21
|
||||
local C3G = 22
|
||||
local C3B = 23
|
||||
local C3A = 24
|
||||
|
||||
local X4 = 25
|
||||
local Y4 = 26
|
||||
local U4 = 27
|
||||
local V4 = 28
|
||||
local C4R = 29
|
||||
local C4G = 30
|
||||
local C4B = 31
|
||||
local C4A = 32
|
||||
|
||||
local RegionAttachment = {}
|
||||
RegionAttachment.__index = RegionAttachment
|
||||
setmetatable(RegionAttachment, { __index = Attachment })
|
||||
|
||||
RegionAttachment.OX1 = 1
|
||||
RegionAttachment.OY1 = 2
|
||||
RegionAttachment.OX2 = 3
|
||||
RegionAttachment.OY2 = 4
|
||||
RegionAttachment.OX3 = 5
|
||||
RegionAttachment.OY3 = 6
|
||||
RegionAttachment.OX4 = 7
|
||||
RegionAttachment.OY4 = 8
|
||||
|
||||
RegionAttachment.X1 = 1
|
||||
RegionAttachment.Y1 = 2
|
||||
RegionAttachment.U1 = 3
|
||||
RegionAttachment.V1 = 4
|
||||
RegionAttachment.C1R = 5
|
||||
RegionAttachment.C1G = 6
|
||||
RegionAttachment.C1B = 7
|
||||
RegionAttachment.C1A = 8
|
||||
|
||||
RegionAttachment.X2 = 9
|
||||
RegionAttachment.Y2 = 10
|
||||
RegionAttachment.U2 = 11
|
||||
RegionAttachment.V2 = 12
|
||||
RegionAttachment.C2R = 13
|
||||
RegionAttachment.C2G = 14
|
||||
RegionAttachment.C2B = 15
|
||||
RegionAttachment.C2A = 16
|
||||
|
||||
RegionAttachment.X3 = 17
|
||||
RegionAttachment.Y3 = 18
|
||||
RegionAttachment.U3 = 19
|
||||
RegionAttachment.V3 = 20
|
||||
RegionAttachment.C3R = 21
|
||||
RegionAttachment.C3G = 22
|
||||
RegionAttachment.C3B = 23
|
||||
RegionAttachment.C3A = 24
|
||||
|
||||
RegionAttachment.X4 = 25
|
||||
RegionAttachment.Y4 = 26
|
||||
RegionAttachment.U4 = 27
|
||||
RegionAttachment.V4 = 28
|
||||
RegionAttachment.C4R = 29
|
||||
RegionAttachment.C4G = 30
|
||||
RegionAttachment.C4B = 31
|
||||
RegionAttachment.C4A = 32
|
||||
|
||||
function RegionAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = Attachment.new(name, AttachmentType.region)
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.scaleX = 1
|
||||
self.scaleY = 1
|
||||
self.rotation = 0
|
||||
self.width = 0
|
||||
self.height = 0
|
||||
self.color = Color.newWith(1, 1, 1, 1)
|
||||
self.path = nil
|
||||
self.rendererObject = nil
|
||||
self.region = nil
|
||||
self.offset = Utils.newNumberArray(8)
|
||||
self.uvs = Utils.newNumberArray(8)
|
||||
self.tempColor = Color.newWith(1, 1, 1, 1)
|
||||
setmetatable(self, RegionAttachment)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function RegionAttachment:updateOffset ()
|
||||
local regionScaleX = self.width / self.region.originalWidth * self.scaleX
|
||||
local regionScaleY = self.height / self.region.originalHeight * self.scaleY
|
||||
local localX = -self.width / 2 * self.scaleX + self.region.offsetX * regionScaleX
|
||||
local localY = -self.height / 2 * self.scaleY + self.region.offsetY * regionScaleY
|
||||
local localX2 = localX + self.region.width * regionScaleX
|
||||
local localY2 = localY + self.region.height * regionScaleY
|
||||
local radians = self.rotation * math_pi / 180
|
||||
local cos = math_cos(radians)
|
||||
local sin = math_sin(radians)
|
||||
local localXCos = localX * cos + self.x
|
||||
local localXSin = localX * sin
|
||||
local localYCos = localY * cos + self.y
|
||||
local localYSin = localY * sin
|
||||
local localX2Cos = localX2 * cos + self.x
|
||||
local localX2Sin = localX2 * sin
|
||||
local localY2Cos = localY2 * cos + self.y
|
||||
local localY2Sin = localY2 * sin
|
||||
local offset = self.offset
|
||||
offset[OX1] = localXCos - localYSin
|
||||
offset[OY1] = localYCos + localXSin
|
||||
offset[OX2] = localXCos - localY2Sin
|
||||
offset[OY2] = localY2Cos + localXSin
|
||||
offset[OX3] = localX2Cos - localY2Sin
|
||||
offset[OY3] = localY2Cos + localX2Sin
|
||||
offset[OX4] = localX2Cos - localYSin
|
||||
offset[OY4] = localYCos + localX2Sin
|
||||
end
|
||||
|
||||
function RegionAttachment:setRegion (region)
|
||||
local uvs = self.uvs
|
||||
if region.rotate then
|
||||
uvs[5] = region.u
|
||||
uvs[6] = region.v2
|
||||
uvs[7] = region.u
|
||||
uvs[8] = region.v
|
||||
uvs[1] = region.u2
|
||||
uvs[2] = region.v
|
||||
uvs[3] = region.u2
|
||||
uvs[4] = region.v2
|
||||
else
|
||||
uvs[3] = region.u
|
||||
uvs[4] = region.v2
|
||||
uvs[5] = region.u
|
||||
uvs[6] = region.v
|
||||
uvs[7] = region.u2
|
||||
uvs[8] = region.v
|
||||
uvs[1] = region.u2
|
||||
uvs[2] = region.v2
|
||||
end
|
||||
end
|
||||
|
||||
function RegionAttachment:computeWorldVertices (bone, worldVertices, offset, stride)
|
||||
offset = offset + 1
|
||||
local vertexOffset = self.offset
|
||||
local x = bone.worldX
|
||||
local y = bone.worldY
|
||||
local a = bone.a
|
||||
local b = bone.b
|
||||
local c = bone.c
|
||||
local d = bone.d
|
||||
local offsetX = 0
|
||||
local offsetY = 0
|
||||
|
||||
offsetX = vertexOffset[7]
|
||||
offsetY = vertexOffset[8]
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x -- br
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||
offset = offset + stride
|
||||
|
||||
offsetX = vertexOffset[1]
|
||||
offsetY = vertexOffset[2]
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x -- bl
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||
offset = offset + stride
|
||||
|
||||
offsetX = vertexOffset[3]
|
||||
offsetY = vertexOffset[4]
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x -- ul
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||
offset = offset + stride
|
||||
|
||||
offsetX = vertexOffset[5]
|
||||
offsetY = vertexOffset[6]
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x -- ur
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||
end
|
||||
|
||||
function RegionAttachment:copy ()
|
||||
local copy = RegionAttachment.new(self.name)
|
||||
copy.x = self.x
|
||||
copy.y = self.y
|
||||
copy.scaleX = self.scaleX
|
||||
copy.scaleY = self.scaleY
|
||||
copy.rotation = self.rotation
|
||||
copy.width = self.width
|
||||
copy.height = self.height
|
||||
copy.color:setFrom(self.color)
|
||||
copy.path = self.path
|
||||
copy.rendererObject = self.rendererObject
|
||||
copy.region = self.region
|
||||
copy.offset = Utils.copy(self.offset)
|
||||
copy.uvs = Utils.copy(self.uvs)
|
||||
copy.tempColor:setFrom(self.tempColor)
|
||||
return copy
|
||||
end
|
||||
|
||||
return RegionAttachment
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 setmetatable = setmetatable
|
||||
local math_pi = math.pi
|
||||
local math_sin = math.sin
|
||||
local math_cos = math.cos
|
||||
|
||||
local AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local Attachment = require "spine-lua.attachments.Attachment"
|
||||
local Color = require "spine-lua.Color"
|
||||
local Utils = require "spine-lua.utils"
|
||||
|
||||
local OX1 = 1
|
||||
local OY1 = 2
|
||||
local OX2 = 3
|
||||
local OY2 = 4
|
||||
local OX3 = 5
|
||||
local OY3 = 6
|
||||
local OX4 = 7
|
||||
local OY4 = 8
|
||||
|
||||
local X1 = 1
|
||||
local Y1 = 2
|
||||
local U1 = 3
|
||||
local V1 = 4
|
||||
local C1R = 5
|
||||
local C1G = 6
|
||||
local C1B = 7
|
||||
local C1A = 8
|
||||
|
||||
local X2 = 9
|
||||
local Y2 = 10
|
||||
local U2 = 11
|
||||
local V2 = 12
|
||||
local C2R = 13
|
||||
local C2G = 14
|
||||
local C2B = 15
|
||||
local C2A = 16
|
||||
|
||||
local X3 = 17
|
||||
local Y3 = 18
|
||||
local U3 = 19
|
||||
local V3 = 20
|
||||
local C3R = 21
|
||||
local C3G = 22
|
||||
local C3B = 23
|
||||
local C3A = 24
|
||||
|
||||
local X4 = 25
|
||||
local Y4 = 26
|
||||
local U4 = 27
|
||||
local V4 = 28
|
||||
local C4R = 29
|
||||
local C4G = 30
|
||||
local C4B = 31
|
||||
local C4A = 32
|
||||
|
||||
local RegionAttachment = {}
|
||||
RegionAttachment.__index = RegionAttachment
|
||||
setmetatable(RegionAttachment, { __index = Attachment })
|
||||
|
||||
RegionAttachment.OX1 = 1
|
||||
RegionAttachment.OY1 = 2
|
||||
RegionAttachment.OX2 = 3
|
||||
RegionAttachment.OY2 = 4
|
||||
RegionAttachment.OX3 = 5
|
||||
RegionAttachment.OY3 = 6
|
||||
RegionAttachment.OX4 = 7
|
||||
RegionAttachment.OY4 = 8
|
||||
|
||||
RegionAttachment.X1 = 1
|
||||
RegionAttachment.Y1 = 2
|
||||
RegionAttachment.U1 = 3
|
||||
RegionAttachment.V1 = 4
|
||||
RegionAttachment.C1R = 5
|
||||
RegionAttachment.C1G = 6
|
||||
RegionAttachment.C1B = 7
|
||||
RegionAttachment.C1A = 8
|
||||
|
||||
RegionAttachment.X2 = 9
|
||||
RegionAttachment.Y2 = 10
|
||||
RegionAttachment.U2 = 11
|
||||
RegionAttachment.V2 = 12
|
||||
RegionAttachment.C2R = 13
|
||||
RegionAttachment.C2G = 14
|
||||
RegionAttachment.C2B = 15
|
||||
RegionAttachment.C2A = 16
|
||||
|
||||
RegionAttachment.X3 = 17
|
||||
RegionAttachment.Y3 = 18
|
||||
RegionAttachment.U3 = 19
|
||||
RegionAttachment.V3 = 20
|
||||
RegionAttachment.C3R = 21
|
||||
RegionAttachment.C3G = 22
|
||||
RegionAttachment.C3B = 23
|
||||
RegionAttachment.C3A = 24
|
||||
|
||||
RegionAttachment.X4 = 25
|
||||
RegionAttachment.Y4 = 26
|
||||
RegionAttachment.U4 = 27
|
||||
RegionAttachment.V4 = 28
|
||||
RegionAttachment.C4R = 29
|
||||
RegionAttachment.C4G = 30
|
||||
RegionAttachment.C4B = 31
|
||||
RegionAttachment.C4A = 32
|
||||
|
||||
function RegionAttachment.new (name)
|
||||
if not name then error("name cannot be nil", 2) end
|
||||
|
||||
local self = Attachment.new(name, AttachmentType.region)
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.scaleX = 1
|
||||
self.scaleY = 1
|
||||
self.rotation = 0
|
||||
self.width = 0
|
||||
self.height = 0
|
||||
self.color = Color.newWith(1, 1, 1, 1)
|
||||
self.path = nil
|
||||
self.rendererObject = nil
|
||||
self.region = nil
|
||||
self.offset = Utils.newNumberArray(8)
|
||||
self.uvs = Utils.newNumberArray(8)
|
||||
self.tempColor = Color.newWith(1, 1, 1, 1)
|
||||
setmetatable(self, RegionAttachment)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function RegionAttachment:updateOffset ()
|
||||
local regionScaleX = self.width / self.region.originalWidth * self.scaleX
|
||||
local regionScaleY = self.height / self.region.originalHeight * self.scaleY
|
||||
local localX = -self.width / 2 * self.scaleX + self.region.offsetX * regionScaleX
|
||||
local localY = -self.height / 2 * self.scaleY + self.region.offsetY * regionScaleY
|
||||
local localX2 = localX + self.region.width * regionScaleX
|
||||
local localY2 = localY + self.region.height * regionScaleY
|
||||
local radians = self.rotation * math_pi / 180
|
||||
local cos = math_cos(radians)
|
||||
local sin = math_sin(radians)
|
||||
local localXCos = localX * cos + self.x
|
||||
local localXSin = localX * sin
|
||||
local localYCos = localY * cos + self.y
|
||||
local localYSin = localY * sin
|
||||
local localX2Cos = localX2 * cos + self.x
|
||||
local localX2Sin = localX2 * sin
|
||||
local localY2Cos = localY2 * cos + self.y
|
||||
local localY2Sin = localY2 * sin
|
||||
local offset = self.offset
|
||||
offset[OX1] = localXCos - localYSin
|
||||
offset[OY1] = localYCos + localXSin
|
||||
offset[OX2] = localXCos - localY2Sin
|
||||
offset[OY2] = localY2Cos + localXSin
|
||||
offset[OX3] = localX2Cos - localY2Sin
|
||||
offset[OY3] = localY2Cos + localX2Sin
|
||||
offset[OX4] = localX2Cos - localYSin
|
||||
offset[OY4] = localYCos + localX2Sin
|
||||
end
|
||||
|
||||
function RegionAttachment:setRegion (region)
|
||||
local uvs = self.uvs
|
||||
if region.rotate then
|
||||
uvs[5] = region.u
|
||||
uvs[6] = region.v2
|
||||
uvs[7] = region.u
|
||||
uvs[8] = region.v
|
||||
uvs[1] = region.u2
|
||||
uvs[2] = region.v
|
||||
uvs[3] = region.u2
|
||||
uvs[4] = region.v2
|
||||
else
|
||||
uvs[3] = region.u
|
||||
uvs[4] = region.v2
|
||||
uvs[5] = region.u
|
||||
uvs[6] = region.v
|
||||
uvs[7] = region.u2
|
||||
uvs[8] = region.v
|
||||
uvs[1] = region.u2
|
||||
uvs[2] = region.v2
|
||||
end
|
||||
end
|
||||
|
||||
function RegionAttachment:computeWorldVertices (bone, worldVertices, offset, stride)
|
||||
offset = offset + 1
|
||||
local vertexOffset = self.offset
|
||||
local x = bone.worldX
|
||||
local y = bone.worldY
|
||||
local a = bone.a
|
||||
local b = bone.b
|
||||
local c = bone.c
|
||||
local d = bone.d
|
||||
local offsetX = 0
|
||||
local offsetY = 0
|
||||
|
||||
offsetX = vertexOffset[7]
|
||||
offsetY = vertexOffset[8]
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x -- br
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||
offset = offset + stride
|
||||
|
||||
offsetX = vertexOffset[1]
|
||||
offsetY = vertexOffset[2]
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x -- bl
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||
offset = offset + stride
|
||||
|
||||
offsetX = vertexOffset[3]
|
||||
offsetY = vertexOffset[4]
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x -- ul
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||
offset = offset + stride
|
||||
|
||||
offsetX = vertexOffset[5]
|
||||
offsetY = vertexOffset[6]
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x -- ur
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||
end
|
||||
|
||||
function RegionAttachment:copy ()
|
||||
local copy = RegionAttachment.new(self.name)
|
||||
copy.x = self.x
|
||||
copy.y = self.y
|
||||
copy.scaleX = self.scaleX
|
||||
copy.scaleY = self.scaleY
|
||||
copy.rotation = self.rotation
|
||||
copy.width = self.width
|
||||
copy.height = self.height
|
||||
copy.color:setFrom(self.color)
|
||||
copy.path = self.path
|
||||
copy.rendererObject = self.rendererObject
|
||||
copy.region = self.region
|
||||
copy.offset = Utils.copy(self.offset)
|
||||
copy.uvs = Utils.copy(self.uvs)
|
||||
copy.tempColor:setFrom(self.tempColor)
|
||||
return copy
|
||||
end
|
||||
|
||||
return RegionAttachment
|
||||
@ -1,168 +1,168 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-- FIXME the logic in this file uses 0-based indexing. Each array
|
||||
-- access adds 1 to the calculated index. We should switch the logic
|
||||
-- to 1-based indexing eventually.
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local utils = require "spine-lua.utils"
|
||||
local AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local Attachment = require "spine-lua.attachments.Attachment"
|
||||
|
||||
local nextID = 0;
|
||||
local SHL_11 = 2048;
|
||||
|
||||
local VertexAttachment = {}
|
||||
VertexAttachment.__index = VertexAttachment
|
||||
setmetatable(VertexAttachment, { __index = Attachment })
|
||||
|
||||
function VertexAttachment.new (name, attachmentType)
|
||||
local self = Attachment.new(name, attachmentType)
|
||||
self.bones = nil
|
||||
self.vertices = nil
|
||||
self.worldVerticesLength = 0
|
||||
while nextID > 65535 do
|
||||
nextID = nextID - 65535
|
||||
end
|
||||
self.id = nextID * SHL_11
|
||||
self.deformAttachment = self
|
||||
nextID = nextID + 1
|
||||
setmetatable(self, VertexAttachment)
|
||||
return self
|
||||
end
|
||||
|
||||
function VertexAttachment:computeWorldVertices (slot, start, count, worldVertices, offset, stride)
|
||||
count = offset + (count / 2) * stride
|
||||
local skeleton = slot.bone.skeleton
|
||||
local deformArray = slot.deform
|
||||
local vertices = self.vertices
|
||||
local bones = self.bones
|
||||
if not bones then
|
||||
if #deformArray > 0 then vertices = deformArray end
|
||||
local bone = slot.bone
|
||||
x = bone.worldX
|
||||
y = bone.worldY
|
||||
local a = bone.a
|
||||
local b = bone.b
|
||||
local c = bone.c
|
||||
local d = bone.d
|
||||
local v = start
|
||||
local w = offset
|
||||
while w < count do
|
||||
local vx = vertices[v + 1]
|
||||
local vy = vertices[v + 2]
|
||||
worldVertices[w + 1] = vx * a + vy * b + x
|
||||
worldVertices[w + 2] = vx * c + vy * d + y
|
||||
v = v + 2
|
||||
w = w + stride
|
||||
end
|
||||
return
|
||||
end
|
||||
local v = 0
|
||||
local skip = 0
|
||||
local i = 0
|
||||
while i < start do
|
||||
local n = bones[v + 1]
|
||||
v = v + n + 1
|
||||
skip = skip + n
|
||||
i = i + 2
|
||||
end
|
||||
local skeletonBones = skeleton.bones
|
||||
if #deformArray == 0 then
|
||||
local w = offset
|
||||
local b = skip * 3
|
||||
while w < count do
|
||||
local wx = 0
|
||||
local wy = 0
|
||||
local n = bones[v + 1]
|
||||
v = v + 1
|
||||
n = n + v
|
||||
while v < n do
|
||||
local bone = skeletonBones[bones[v + 1]]
|
||||
local vx = vertices[b + 1]
|
||||
local vy = vertices[b + 2]
|
||||
local weight = vertices[b + 3]
|
||||
wx = wx + (vx * bone.a + vy * bone.b + bone.worldX) * weight
|
||||
wy = wy + (vx * bone.c + vy * bone.d + bone.worldY) * weight
|
||||
v = v + 1
|
||||
b = b + 3
|
||||
end
|
||||
worldVertices[w + 1] = wx
|
||||
worldVertices[w + 2] = wy
|
||||
w = w + stride
|
||||
end
|
||||
else
|
||||
local deform = deformArray
|
||||
local w = offset
|
||||
local b = skip * 3
|
||||
local f = skip * 2
|
||||
while w < count do
|
||||
local wx = 0
|
||||
local wy = 0
|
||||
local n = bones[v + 1]
|
||||
v = v + 1
|
||||
n = n + v
|
||||
|
||||
while v < n do
|
||||
local bone = skeletonBones[bones[v + 1]]
|
||||
local vx = vertices[b + 1] + deform[f + 1]
|
||||
local vy = vertices[b + 2] + deform[f + 2]
|
||||
local weight = vertices[b + 3]
|
||||
wx = wx + (vx * bone.a + vy * bone.b + bone.worldX) * weight
|
||||
wy = wy + (vx * bone.c + vy * bone.d + bone.worldY) * weight
|
||||
v = v + 1
|
||||
b = b + 3
|
||||
f = f + 2
|
||||
end
|
||||
worldVertices[w + 1] = wx
|
||||
worldVertices[w + 2] = wy
|
||||
w = w + stride
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function VertexAttachment:copyTo (attachment)
|
||||
if self.bones then
|
||||
attachment.bones = utils.copy(self.bones)
|
||||
else
|
||||
attachment.bones = nil
|
||||
end
|
||||
|
||||
if self.vertices then
|
||||
attachment.vertices = utils.copy(self.vertices)
|
||||
else
|
||||
attachment.vertices = nil
|
||||
end
|
||||
|
||||
attachment.worldVerticesLength = self.worldVerticesLength
|
||||
attachment.deformAttachment = self.deformAttachment
|
||||
end
|
||||
|
||||
return VertexAttachment
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-- FIXME the logic in this file uses 0-based indexing. Each array
|
||||
-- access adds 1 to the calculated index. We should switch the logic
|
||||
-- to 1-based indexing eventually.
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local utils = require "spine-lua.utils"
|
||||
local AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||
local Attachment = require "spine-lua.attachments.Attachment"
|
||||
|
||||
local nextID = 0;
|
||||
local SHL_11 = 2048;
|
||||
|
||||
local VertexAttachment = {}
|
||||
VertexAttachment.__index = VertexAttachment
|
||||
setmetatable(VertexAttachment, { __index = Attachment })
|
||||
|
||||
function VertexAttachment.new (name, attachmentType)
|
||||
local self = Attachment.new(name, attachmentType)
|
||||
self.bones = nil
|
||||
self.vertices = nil
|
||||
self.worldVerticesLength = 0
|
||||
while nextID > 65535 do
|
||||
nextID = nextID - 65535
|
||||
end
|
||||
self.id = nextID * SHL_11
|
||||
self.deformAttachment = self
|
||||
nextID = nextID + 1
|
||||
setmetatable(self, VertexAttachment)
|
||||
return self
|
||||
end
|
||||
|
||||
function VertexAttachment:computeWorldVertices (slot, start, count, worldVertices, offset, stride)
|
||||
count = offset + (count / 2) * stride
|
||||
local skeleton = slot.bone.skeleton
|
||||
local deformArray = slot.deform
|
||||
local vertices = self.vertices
|
||||
local bones = self.bones
|
||||
if not bones then
|
||||
if #deformArray > 0 then vertices = deformArray end
|
||||
local bone = slot.bone
|
||||
x = bone.worldX
|
||||
y = bone.worldY
|
||||
local a = bone.a
|
||||
local b = bone.b
|
||||
local c = bone.c
|
||||
local d = bone.d
|
||||
local v = start
|
||||
local w = offset
|
||||
while w < count do
|
||||
local vx = vertices[v + 1]
|
||||
local vy = vertices[v + 2]
|
||||
worldVertices[w + 1] = vx * a + vy * b + x
|
||||
worldVertices[w + 2] = vx * c + vy * d + y
|
||||
v = v + 2
|
||||
w = w + stride
|
||||
end
|
||||
return
|
||||
end
|
||||
local v = 0
|
||||
local skip = 0
|
||||
local i = 0
|
||||
while i < start do
|
||||
local n = bones[v + 1]
|
||||
v = v + n + 1
|
||||
skip = skip + n
|
||||
i = i + 2
|
||||
end
|
||||
local skeletonBones = skeleton.bones
|
||||
if #deformArray == 0 then
|
||||
local w = offset
|
||||
local b = skip * 3
|
||||
while w < count do
|
||||
local wx = 0
|
||||
local wy = 0
|
||||
local n = bones[v + 1]
|
||||
v = v + 1
|
||||
n = n + v
|
||||
while v < n do
|
||||
local bone = skeletonBones[bones[v + 1]]
|
||||
local vx = vertices[b + 1]
|
||||
local vy = vertices[b + 2]
|
||||
local weight = vertices[b + 3]
|
||||
wx = wx + (vx * bone.a + vy * bone.b + bone.worldX) * weight
|
||||
wy = wy + (vx * bone.c + vy * bone.d + bone.worldY) * weight
|
||||
v = v + 1
|
||||
b = b + 3
|
||||
end
|
||||
worldVertices[w + 1] = wx
|
||||
worldVertices[w + 2] = wy
|
||||
w = w + stride
|
||||
end
|
||||
else
|
||||
local deform = deformArray
|
||||
local w = offset
|
||||
local b = skip * 3
|
||||
local f = skip * 2
|
||||
while w < count do
|
||||
local wx = 0
|
||||
local wy = 0
|
||||
local n = bones[v + 1]
|
||||
v = v + 1
|
||||
n = n + v
|
||||
|
||||
while v < n do
|
||||
local bone = skeletonBones[bones[v + 1]]
|
||||
local vx = vertices[b + 1] + deform[f + 1]
|
||||
local vy = vertices[b + 2] + deform[f + 2]
|
||||
local weight = vertices[b + 3]
|
||||
wx = wx + (vx * bone.a + vy * bone.b + bone.worldX) * weight
|
||||
wy = wy + (vx * bone.c + vy * bone.d + bone.worldY) * weight
|
||||
v = v + 1
|
||||
b = b + 3
|
||||
f = f + 2
|
||||
end
|
||||
worldVertices[w + 1] = wx
|
||||
worldVertices[w + 2] = wy
|
||||
w = w + stride
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function VertexAttachment:copyTo (attachment)
|
||||
if self.bones then
|
||||
attachment.bones = utils.copy(self.bones)
|
||||
else
|
||||
attachment.bones = nil
|
||||
end
|
||||
|
||||
if self.vertices then
|
||||
attachment.vertices = utils.copy(self.vertices)
|
||||
else
|
||||
attachment.vertices = nil
|
||||
end
|
||||
|
||||
attachment.worldVerticesLength = self.worldVerticesLength
|
||||
attachment.deformAttachment = self.deformAttachment
|
||||
end
|
||||
|
||||
return VertexAttachment
|
||||
@ -1,197 +1,197 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 utils = {}
|
||||
|
||||
local math_sqrt = math.sqrt
|
||||
local math_random = math.random
|
||||
|
||||
utils.degRad = math.pi / 180
|
||||
|
||||
function tablePrint (tt, indent, done)
|
||||
done = done or {}
|
||||
for key, value in pairs(tt) do
|
||||
local spaces = string.rep (" ", indent)
|
||||
if type(value) == "table" and not done [value] then
|
||||
done [value] = true
|
||||
print(spaces .. "{")
|
||||
utils.print(value, indent + 2, done)
|
||||
print(spaces .. "}")
|
||||
else
|
||||
io.write(spaces .. tostring(key) .. " = ")
|
||||
utils.print(value, indent + 2, done)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function utils.print (value, indent, done)
|
||||
indent = indent or 0
|
||||
if "nil" == type(value) then
|
||||
print(tostring(nil))
|
||||
elseif "table" == type(value) then
|
||||
local spaces = string.rep (" ", indent)
|
||||
print(spaces .. "{")
|
||||
tablePrint(value, indent + 2)
|
||||
print(spaces .. "}")
|
||||
elseif "string" == type(value) then
|
||||
print("\"" .. value .. "\"")
|
||||
else
|
||||
print(tostring(value))
|
||||
end
|
||||
end
|
||||
|
||||
function utils.indexOf (haystack, needle)
|
||||
for i,value in ipairs(haystack) do
|
||||
if value == needle then return i end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function utils.copy (from, to)
|
||||
if not to then to = {} end
|
||||
for k,v in pairs(from) do
|
||||
to[k] = v
|
||||
end
|
||||
return to
|
||||
end
|
||||
|
||||
function utils.newNumberArray (size)
|
||||
local a = {}
|
||||
local i = 1
|
||||
while i <= size do
|
||||
a[i] = 0
|
||||
i = i + 1
|
||||
end
|
||||
return a
|
||||
end
|
||||
|
||||
function utils.newNumberArrayZero (size)
|
||||
local a = {}
|
||||
local i = 0
|
||||
while i < size do
|
||||
a[i] = 0
|
||||
i = i + 1
|
||||
end
|
||||
return a
|
||||
end
|
||||
|
||||
function utils.setArraySize (array, size)
|
||||
if #array == size then return array end
|
||||
if #array < size then
|
||||
local i = #array + 1
|
||||
while i <= size do
|
||||
array[i] = 0
|
||||
i = i + 1
|
||||
end
|
||||
else
|
||||
local originalSize = #array
|
||||
local i = originalSize
|
||||
while i > size do
|
||||
array[i] = nil -- dirty trick to appease # without realloc
|
||||
i = i - 1
|
||||
end
|
||||
end
|
||||
return array
|
||||
end
|
||||
|
||||
function utils.arrayCopy (src, srcOffset, dst, dstOffset, size)
|
||||
local n = srcOffset + size
|
||||
while srcOffset < n do
|
||||
dst[dstOffset] = src[srcOffset]
|
||||
dstOffset = dstOffset + 1
|
||||
srcOffset = srcOffset + 1
|
||||
end
|
||||
end
|
||||
|
||||
function utils.arrayContains(array, element)
|
||||
for i, arrayElement in ipairs(array) do
|
||||
if arrayElement == element then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function utils.clamp (value, min, max)
|
||||
if value < min then return min end
|
||||
if value > max then return max end
|
||||
return value
|
||||
end
|
||||
|
||||
function utils.signum (value)
|
||||
if value < 0 then
|
||||
return -1
|
||||
elseif value > 0 then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
-- Implements Java float modulo
|
||||
function utils.mod(a, b)
|
||||
if b < 0 then b = -b end
|
||||
if a < 0 then
|
||||
return -(-a % b)
|
||||
else
|
||||
return a % b
|
||||
end
|
||||
end
|
||||
|
||||
function utils.randomTriangular(min, max)
|
||||
return utils.randomTriangularWith(min, max, (min + max) * 0.5)
|
||||
end
|
||||
|
||||
function utils.randomTriangularWith(min, max, mode)
|
||||
local u = math.random()
|
||||
local d = max - min
|
||||
if (u <= (mode - min) / d) then return min + math_sqrt(u * d * (mode - min)) end
|
||||
return max - math_sqrt((1 - u) * d * (max - mode))
|
||||
end
|
||||
|
||||
function utils.testBit(value, bit)
|
||||
if (value == nil) then return 0 end
|
||||
return value % (2 * bit) >= bit
|
||||
end
|
||||
|
||||
function utils.setBit(value, bit)
|
||||
if (value == nil) then return 0 end
|
||||
if value % (2 * bit) >= bit then
|
||||
return value
|
||||
end
|
||||
return value + bit
|
||||
end
|
||||
|
||||
function utils.clearBit(value, bit)
|
||||
if (value == nil) then return 0 end
|
||||
if value % (2 * bit) >= bit then
|
||||
return value - bit
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
return utils
|
||||
-------------------------------------------------------------------------------
|
||||
-- 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 utils = {}
|
||||
|
||||
local math_sqrt = math.sqrt
|
||||
local math_random = math.random
|
||||
|
||||
utils.degRad = math.pi / 180
|
||||
|
||||
function tablePrint (tt, indent, done)
|
||||
done = done or {}
|
||||
for key, value in pairs(tt) do
|
||||
local spaces = string.rep (" ", indent)
|
||||
if type(value) == "table" and not done [value] then
|
||||
done [value] = true
|
||||
print(spaces .. "{")
|
||||
utils.print(value, indent + 2, done)
|
||||
print(spaces .. "}")
|
||||
else
|
||||
io.write(spaces .. tostring(key) .. " = ")
|
||||
utils.print(value, indent + 2, done)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function utils.print (value, indent, done)
|
||||
indent = indent or 0
|
||||
if "nil" == type(value) then
|
||||
print(tostring(nil))
|
||||
elseif "table" == type(value) then
|
||||
local spaces = string.rep (" ", indent)
|
||||
print(spaces .. "{")
|
||||
tablePrint(value, indent + 2)
|
||||
print(spaces .. "}")
|
||||
elseif "string" == type(value) then
|
||||
print("\"" .. value .. "\"")
|
||||
else
|
||||
print(tostring(value))
|
||||
end
|
||||
end
|
||||
|
||||
function utils.indexOf (haystack, needle)
|
||||
for i,value in ipairs(haystack) do
|
||||
if value == needle then return i end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function utils.copy (from, to)
|
||||
if not to then to = {} end
|
||||
for k,v in pairs(from) do
|
||||
to[k] = v
|
||||
end
|
||||
return to
|
||||
end
|
||||
|
||||
function utils.newNumberArray (size)
|
||||
local a = {}
|
||||
local i = 1
|
||||
while i <= size do
|
||||
a[i] = 0
|
||||
i = i + 1
|
||||
end
|
||||
return a
|
||||
end
|
||||
|
||||
function utils.newNumberArrayZero (size)
|
||||
local a = {}
|
||||
local i = 0
|
||||
while i < size do
|
||||
a[i] = 0
|
||||
i = i + 1
|
||||
end
|
||||
return a
|
||||
end
|
||||
|
||||
function utils.setArraySize (array, size)
|
||||
if #array == size then return array end
|
||||
if #array < size then
|
||||
local i = #array + 1
|
||||
while i <= size do
|
||||
array[i] = 0
|
||||
i = i + 1
|
||||
end
|
||||
else
|
||||
local originalSize = #array
|
||||
local i = originalSize
|
||||
while i > size do
|
||||
array[i] = nil -- dirty trick to appease # without realloc
|
||||
i = i - 1
|
||||
end
|
||||
end
|
||||
return array
|
||||
end
|
||||
|
||||
function utils.arrayCopy (src, srcOffset, dst, dstOffset, size)
|
||||
local n = srcOffset + size
|
||||
while srcOffset < n do
|
||||
dst[dstOffset] = src[srcOffset]
|
||||
dstOffset = dstOffset + 1
|
||||
srcOffset = srcOffset + 1
|
||||
end
|
||||
end
|
||||
|
||||
function utils.arrayContains(array, element)
|
||||
for i, arrayElement in ipairs(array) do
|
||||
if arrayElement == element then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function utils.clamp (value, min, max)
|
||||
if value < min then return min end
|
||||
if value > max then return max end
|
||||
return value
|
||||
end
|
||||
|
||||
function utils.signum (value)
|
||||
if value < 0 then
|
||||
return -1
|
||||
elseif value > 0 then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
-- Implements Java float modulo
|
||||
function utils.mod(a, b)
|
||||
if b < 0 then b = -b end
|
||||
if a < 0 then
|
||||
return -(-a % b)
|
||||
else
|
||||
return a % b
|
||||
end
|
||||
end
|
||||
|
||||
function utils.randomTriangular(min, max)
|
||||
return utils.randomTriangularWith(min, max, (min + max) * 0.5)
|
||||
end
|
||||
|
||||
function utils.randomTriangularWith(min, max, mode)
|
||||
local u = math.random()
|
||||
local d = max - min
|
||||
if (u <= (mode - min) / d) then return min + math_sqrt(u * d * (mode - min)) end
|
||||
return max - math_sqrt((1 - u) * d * (max - mode))
|
||||
end
|
||||
|
||||
function utils.testBit(value, bit)
|
||||
if (value == nil) then return 0 end
|
||||
return value % (2 * bit) >= bit
|
||||
end
|
||||
|
||||
function utils.setBit(value, bit)
|
||||
if (value == nil) then return 0 end
|
||||
if value % (2 * bit) >= bit then
|
||||
return value
|
||||
end
|
||||
return value + bit
|
||||
end
|
||||
|
||||
function utils.clearBit(value, bit)
|
||||
if (value == nil) then return 0 end
|
||||
if value % (2 * bit) >= bit then
|
||||
return value - bit
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
return utils
|
||||
Loading…
x
Reference in New Issue
Block a user