mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
[lua] 4.0 porting complete.
This commit is contained in:
parent
35650a6bb2
commit
0544e14102
@ -399,6 +399,7 @@ public class Bone implements Updatable {
|
|||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
ax = worldX;
|
ax = worldX;
|
||||||
ay = worldY;
|
ay = worldY;
|
||||||
|
float a = this.a, b = this.b, c = this.c, d = this.d;
|
||||||
arotation = atan2(c, a) * radDeg;
|
arotation = atan2(c, a) * radDeg;
|
||||||
ascaleX = (float)Math.sqrt(a * a + c * c);
|
ascaleX = (float)Math.sqrt(a * a + c * c);
|
||||||
ascaleY = (float)Math.sqrt(b * b + d * d);
|
ascaleY = (float)Math.sqrt(b * b + d * d);
|
||||||
|
|||||||
@ -65,25 +65,25 @@ function loadSkeleton (jsonFile, atlasFile, animation, skin, scale, x, y)
|
|||||||
skeleton.vertexEffect = swirl
|
skeleton.vertexEffect = swirl
|
||||||
-- skeleton.vertexEffect = spine.JitterEffect.new(10, 10)
|
-- skeleton.vertexEffect = spine.JitterEffect.new(10, 10)
|
||||||
end
|
end
|
||||||
|
|
||||||
if jsonFile == "mix-and-match-pro" then
|
|
||||||
-- Create a new skin, by mixing and matching other skins
|
|
||||||
-- that fit together. Items making up the girl are individual
|
|
||||||
-- skins. Using the skin API, a new skin is created which is
|
|
||||||
-- a combination of all these individual item skins.
|
|
||||||
local skin = spine.Skin.new("mix-and-match")
|
|
||||||
skin:addSkin(skeletonData:findSkin("skin-base"))
|
|
||||||
skin:addSkin(skeletonData:findSkin("nose/short"))
|
|
||||||
skin:addSkin(skeletonData:findSkin("eyelids/girly"))
|
|
||||||
skin:addSkin(skeletonData:findSkin("eyes/violet"))
|
|
||||||
skin:addSkin(skeletonData:findSkin("hair/brown"))
|
|
||||||
skin:addSkin(skeletonData:findSkin("clothes/hoodie-orange"))
|
|
||||||
skin:addSkin(skeletonData:findSkin("legs/pants-jeans"))
|
|
||||||
skin:addSkin(skeletonData:findSkin("accessories/bag"))
|
|
||||||
skin:addSkin(skeletonData:findSkin("accessories/hat-red-yellow"))
|
|
||||||
skeleton:setSkinByReference(skin)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
if jsonFile == "mix-and-match-pro" then
|
||||||
|
-- Create a new skin, by mixing and matching other skins
|
||||||
|
-- that fit together. Items making up the girl are individual
|
||||||
|
-- skins. Using the skin API, a new skin is created which is
|
||||||
|
-- a combination of all these individual item skins.
|
||||||
|
local skin = spine.Skin.new("mix-and-match")
|
||||||
|
skin:addSkin(skeletonData:findSkin("skin-base"))
|
||||||
|
skin:addSkin(skeletonData:findSkin("nose/short"))
|
||||||
|
skin:addSkin(skeletonData:findSkin("eyelids/girly"))
|
||||||
|
skin:addSkin(skeletonData:findSkin("eyes/violet"))
|
||||||
|
skin:addSkin(skeletonData:findSkin("hair/brown"))
|
||||||
|
skin:addSkin(skeletonData:findSkin("clothes/hoodie-orange"))
|
||||||
|
skin:addSkin(skeletonData:findSkin("legs/pants-jeans"))
|
||||||
|
skin:addSkin(skeletonData:findSkin("accessories/bag"))
|
||||||
|
skin:addSkin(skeletonData:findSkin("accessories/hat-red-yellow"))
|
||||||
|
skeleton:setSkinByReference(skin)
|
||||||
|
end
|
||||||
|
|
||||||
-- set some event callbacks
|
-- set some event callbacks
|
||||||
state.onStart = function (entry)
|
state.onStart = function (entry)
|
||||||
print(entry.trackIndex.." start: "..entry.animation.name)
|
print(entry.trackIndex.." start: "..entry.animation.name)
|
||||||
@ -103,21 +103,18 @@ function loadSkeleton (jsonFile, atlasFile, animation, skin, scale, x, y)
|
|||||||
state.onEvent = function (entry, event)
|
state.onEvent = function (entry, event)
|
||||||
print(entry.trackIndex.." event: "..entry.animation.name..", "..event.data.name..", "..event.intValue..", "..event.floatValue..", '"..(event.stringValue or "").."'" .. ", " .. event.volume .. ", " .. event.balance)
|
print(entry.trackIndex.." event: "..entry.animation.name..", "..event.data.name..", "..event.intValue..", "..event.floatValue..", '"..(event.stringValue or "").."'" .. ", " .. event.volume .. ", " .. event.balance)
|
||||||
end
|
end
|
||||||
|
|
||||||
state:update(0.5)
|
|
||||||
state:apply(skeleton)
|
|
||||||
|
|
||||||
return { state = state, skeleton = skeleton }
|
return { state = state, skeleton = skeleton }
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.load(arg)
|
function love.load(arg)
|
||||||
if arg[#arg] == "-debug" then require("mobdebug").start() end
|
if arg[#arg] == "-debug" then require("mobdebug").start() end
|
||||||
skeletonRenderer = spine.SkeletonRenderer.new(true)
|
skeletonRenderer = spine.SkeletonRenderer.new(true)
|
||||||
table.insert(skeletons, loadSkeleton("goblins-pro", "goblins", "walk", "goblin", 1, 400, 500))
|
|
||||||
table.insert(skeletons, loadSkeleton("mix-and-match-pro", "mix-and-match", "dance", nil, 0.5, 400, 500))
|
|
||||||
table.insert(skeletons, loadSkeleton("spineboy-pro", "spineboy", "walk", nil, 0.5, 400, 500))
|
|
||||||
table.insert(skeletons, loadSkeleton("stretchyman-pro", "stretchyman", "sneak", nil, 0.5, 200, 500))
|
table.insert(skeletons, loadSkeleton("stretchyman-pro", "stretchyman", "sneak", nil, 0.5, 200, 500))
|
||||||
|
table.insert(skeletons, loadSkeleton("spineboy-pro", "spineboy", "walk", nil, 0.5, 400, 500))
|
||||||
|
table.insert(skeletons, loadSkeleton("mix-and-match-pro", "mix-and-match", "dance", nil, 0.5, 400, 500))
|
||||||
table.insert(skeletons, loadSkeleton("coin-pro", "coin", "animation", nil, 0.5, 400, 300))
|
table.insert(skeletons, loadSkeleton("coin-pro", "coin", "animation", nil, 0.5, 400, 300))
|
||||||
|
table.insert(skeletons, loadSkeleton("goblins-pro", "goblins", "walk", "goblin", 1, 400, 500))
|
||||||
table.insert(skeletons, loadSkeleton("raptor-pro", "raptor", "walk", nil, 0.3, 400, 500))
|
table.insert(skeletons, loadSkeleton("raptor-pro", "raptor", "walk", nil, 0.3, 400, 500))
|
||||||
table.insert(skeletons, loadSkeleton("tank-pro", "tank", "drive", nil, 0.2, 600, 500))
|
table.insert(skeletons, loadSkeleton("tank-pro", "tank", "drive", nil, 0.2, 600, 500))
|
||||||
table.insert(skeletons, loadSkeleton("vine-pro", "vine", "grow", nil, 0.3, 400, 500))
|
table.insert(skeletons, loadSkeleton("vine-pro", "vine", "grow", nil, 0.3, 400, 500))
|
||||||
|
|||||||
@ -310,96 +310,107 @@ local tmpColor = spine.Color.newWith(0, 0, 0, 0)
|
|||||||
local tmpColor2 = spine.Color.newWith(0, 0, 0, 0)
|
local tmpColor2 = spine.Color.newWith(0, 0, 0, 0)
|
||||||
|
|
||||||
function SkeletonRenderer:draw (skeleton)
|
function SkeletonRenderer:draw (skeleton)
|
||||||
|
local vertexEffect = self.vertexEffect
|
||||||
|
if (vertexEffect) then vertexEffect:beginEffect(skeleton) end
|
||||||
|
|
||||||
local batcher = self.batcher
|
local batcher = self.batcher
|
||||||
local premultipliedAlpha = self.premultipliedAlpha
|
local premultipliedAlpha = self.premultipliedAlpha
|
||||||
|
local skeletonColor = skeleton.color
|
||||||
if (self.vertexEffect) then self.vertexEffect:beginEffect(skeleton) end
|
local color = tmpColor
|
||||||
|
local dark = tmpColor2
|
||||||
|
|
||||||
local lastLoveBlendMode = love.graphics.getBlendMode()
|
local lastLoveBlendMode = love.graphics.getBlendMode()
|
||||||
love.graphics.setBlendMode("alpha")
|
love.graphics.setBlendMode("alpha")
|
||||||
local lastBlendMode = spine.BlendMode.normal
|
local lastBlendMode = spine.BlendMode.normal
|
||||||
batcher:begin()
|
batcher:begin()
|
||||||
|
|
||||||
local drawOrder = skeleton.drawOrder
|
for i, slot in ipairs(skeleton.drawOrder) do repeat
|
||||||
for i, slot in ipairs(drawOrder) do
|
if not slot.bone.active then
|
||||||
if slot.bone.active then
|
self.clipper:clipEnd(slot)
|
||||||
local attachment = slot.attachment
|
break -- continues for loop
|
||||||
local vertices = worldVertices
|
|
||||||
local uvs = nil
|
|
||||||
local indices = nil
|
|
||||||
local texture = nil
|
|
||||||
local color = tmpColor
|
|
||||||
if attachment then
|
|
||||||
if attachment.type == spine.AttachmentType.region then
|
|
||||||
numVertices = 4
|
|
||||||
attachment:computeWorldVertices(slot.bone, vertices, 0, 2)
|
|
||||||
uvs = attachment.uvs
|
|
||||||
indices = SkeletonRenderer.QUAD_TRIANGLES
|
|
||||||
texture = attachment.region.renderObject.texture
|
|
||||||
elseif attachment.type == spine.AttachmentType.mesh then
|
|
||||||
numVertices = attachment.worldVerticesLength / 2
|
|
||||||
attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2)
|
|
||||||
uvs = attachment.uvs
|
|
||||||
indices = attachment.triangles
|
|
||||||
texture = attachment.region.renderObject.texture
|
|
||||||
elseif attachment.type == spine.AttachmentType.clipping then
|
|
||||||
self.clipper:clipStart(slot, attachment)
|
|
||||||
end
|
|
||||||
|
|
||||||
if texture then
|
|
||||||
local slotBlendMode = slot.data.blendMode
|
|
||||||
if lastBlendMode ~= slotBlendMode then
|
|
||||||
batcher:stop()
|
|
||||||
batcher:begin()
|
|
||||||
|
|
||||||
if slotBlendMode == spine.BlendMode.normal then
|
|
||||||
love.graphics.setBlendMode("alpha")
|
|
||||||
elseif slotBlendMode == spine.BlendMode.additive then
|
|
||||||
love.graphics.setBlendMode("add")
|
|
||||||
elseif slotBlendMode == spine.BlendMode.multiply then
|
|
||||||
love.graphics.setBlendMode("multiply", "premultiplied")
|
|
||||||
elseif slotBlendMode == spine.BlendMode.screen then
|
|
||||||
love.graphics.setBlendMode("screen")
|
|
||||||
end
|
|
||||||
lastBlendMode = slotBlendMode
|
|
||||||
end
|
|
||||||
|
|
||||||
local skeleton = slot.bone.skeleton
|
|
||||||
local skeletonColor = skeleton.color
|
|
||||||
local slotColor = slot.color
|
|
||||||
local attachmentColor = attachment.color
|
|
||||||
local alpha = skeletonColor.a * slotColor.a * attachmentColor.a
|
|
||||||
local multiplier = alpha
|
|
||||||
if premultipliedAlpha then multiplier = 1 end
|
|
||||||
color:set(skeletonColor.r * slotColor.r * attachmentColor.r * multiplier,
|
|
||||||
skeletonColor.g * slotColor.g * attachmentColor.g * multiplier,
|
|
||||||
skeletonColor.b * slotColor.b * attachmentColor.b * multiplier,
|
|
||||||
alpha)
|
|
||||||
|
|
||||||
local dark = tmpColor2
|
|
||||||
if slot.darkColor then dark = slot.darkColor
|
|
||||||
else dark:set(0, 0, 0, 0) end
|
|
||||||
|
|
||||||
if self.clipper:isClipping() then
|
|
||||||
self.clipper:clipTriangles(vertices, attachment.uvs, indices, #indices)
|
|
||||||
vertices = self.clipper.clippedVertices
|
|
||||||
numVertices = #vertices / 2
|
|
||||||
uvs = self.clipper.clippedUVs
|
|
||||||
indices = self.clipper.clippedTriangles
|
|
||||||
end
|
|
||||||
|
|
||||||
batcher:draw(texture, vertices, uvs, numVertices, indices, color, dark, self.vertexEffect)
|
|
||||||
end
|
|
||||||
|
|
||||||
self.clipper:clipEnd(slot)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
local attachment = slot.attachment
|
||||||
|
if attachment then
|
||||||
|
local vertices = worldVertices
|
||||||
|
local vertexCount
|
||||||
|
local uvs
|
||||||
|
local indices
|
||||||
|
local texture
|
||||||
|
if attachment.type == spine.AttachmentType.region then
|
||||||
|
vertexCount = 4
|
||||||
|
attachment:computeWorldVertices(slot.bone, vertices, 0, 2)
|
||||||
|
uvs = attachment.uvs
|
||||||
|
indices = SkeletonRenderer.QUAD_TRIANGLES
|
||||||
|
texture = attachment.region.renderObject.texture
|
||||||
|
elseif attachment.type == spine.AttachmentType.mesh then
|
||||||
|
vertexCount = attachment.worldVerticesLength / 2
|
||||||
|
attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2)
|
||||||
|
uvs = attachment.uvs
|
||||||
|
indices = attachment.triangles
|
||||||
|
texture = attachment.region.renderObject.texture
|
||||||
|
elseif attachment.type == spine.AttachmentType.clipping then
|
||||||
|
self.clipper:clipStart(slot, attachment)
|
||||||
|
break -- continues for loop
|
||||||
|
end
|
||||||
|
|
||||||
|
if texture then
|
||||||
|
local slotBlendMode = slot.data.blendMode
|
||||||
|
if lastBlendMode ~= slotBlendMode then
|
||||||
|
batcher:stop()
|
||||||
|
batcher:begin()
|
||||||
|
|
||||||
|
if slotBlendMode == spine.BlendMode.normal then
|
||||||
|
love.graphics.setBlendMode("alpha")
|
||||||
|
elseif slotBlendMode == spine.BlendMode.additive then
|
||||||
|
love.graphics.setBlendMode("add")
|
||||||
|
elseif slotBlendMode == spine.BlendMode.multiply then
|
||||||
|
love.graphics.setBlendMode("multiply", "premultiplied")
|
||||||
|
elseif slotBlendMode == spine.BlendMode.screen then
|
||||||
|
love.graphics.setBlendMode("screen")
|
||||||
|
end
|
||||||
|
lastBlendMode = slotBlendMode
|
||||||
|
end
|
||||||
|
|
||||||
|
local slotColor = slot.color
|
||||||
|
local attachmentColor = attachment.color
|
||||||
|
local alpha = skeletonColor.a * slotColor.a * attachmentColor.a
|
||||||
|
local multiplier
|
||||||
|
if premultipliedAlpha then
|
||||||
|
multiplier = 1
|
||||||
|
else
|
||||||
|
multiplier = alpha
|
||||||
|
end
|
||||||
|
color:set(skeletonColor.r * slotColor.r * attachmentColor.r * multiplier,
|
||||||
|
skeletonColor.g * slotColor.g * attachmentColor.g * multiplier,
|
||||||
|
skeletonColor.b * slotColor.b * attachmentColor.b * multiplier,
|
||||||
|
alpha)
|
||||||
|
|
||||||
|
if slot.darkColor then
|
||||||
|
dark = slot.darkColor
|
||||||
|
else
|
||||||
|
dark:set(0, 0, 0, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.clipper:isClipping() then
|
||||||
|
self.clipper:clipTriangles(vertices, attachment.uvs, indices, #indices)
|
||||||
|
vertices = self.clipper.clippedVertices
|
||||||
|
vertexCount = #vertices / 2
|
||||||
|
uvs = self.clipper.clippedUVs
|
||||||
|
indices = self.clipper.clippedTriangles
|
||||||
|
end
|
||||||
|
|
||||||
|
batcher:draw(texture, vertices, uvs, vertexCount, indices, color, dark, vertexEffect)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.clipper:clipEnd(slot)
|
||||||
|
end
|
||||||
|
until true end
|
||||||
|
|
||||||
batcher:stop()
|
batcher:stop()
|
||||||
love.graphics.setBlendMode(lastLoveBlendMode)
|
love.graphics.setBlendMode(lastLoveBlendMode)
|
||||||
self.clipper:clipEnd2()
|
self.clipper:clipEnd2()
|
||||||
if (self.vertexEffect) then self.vertexEffect:endEffect(skeleton) end
|
if (vertexEffect) then vertexEffect:endEffect(skeleton) end
|
||||||
end
|
end
|
||||||
|
|
||||||
spine.PolygonBatcher = PolygonBatcher
|
spine.PolygonBatcher = PolygonBatcher
|
||||||
|
|||||||
@ -1301,7 +1301,6 @@ function Animation.AttachmentTimeline.new (frameCount, bezierCount, slotIndex)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function setAttachment (skeleton, slot, attachmentName)
|
local function setAttachment (skeleton, slot, attachmentName)
|
||||||
local attachmentName = self.attachmentNames[frameIndex]
|
|
||||||
if not attachmentName then
|
if not attachmentName then
|
||||||
slot:setAttachment(nil)
|
slot:setAttachment(nil)
|
||||||
else
|
else
|
||||||
@ -1543,7 +1542,7 @@ function Animation.DeformTimeline.new (frameCount, bezierCount, slotIndex, attac
|
|||||||
local percent = self:getCurvePercent(time, frame)
|
local percent = self:getCurvePercent(time, frame)
|
||||||
local prevVertices = vertices[frame]
|
local prevVertices = vertices[frame]
|
||||||
local nextVertices = vertices[frame + 1]
|
local nextVertices = vertices[frame + 1]
|
||||||
|
|
||||||
if alpha == 1 then
|
if alpha == 1 then
|
||||||
if blend == MixBlend.add then
|
if blend == MixBlend.add then
|
||||||
if vertexAttachment.bones == nil then
|
if vertexAttachment.bones == nil then
|
||||||
@ -1764,7 +1763,6 @@ function Animation.IkConstraintTimeline.new (frameCount, bezierCount, ikConstrai
|
|||||||
function self:apply (skeleton, lastTime, time, events, alpha, blend, direction)
|
function self:apply (skeleton, lastTime, time, events, alpha, blend, direction)
|
||||||
local constraint = skeleton.ikConstraints[self.ikConstraintIndex]
|
local constraint = skeleton.ikConstraints[self.ikConstraintIndex]
|
||||||
if not constraint.active then return end
|
if not constraint.active then return end
|
||||||
|
|
||||||
local frames = self.frames
|
local frames = self.frames
|
||||||
if time < frames[0] then
|
if time < frames[0] then
|
||||||
if blend == MixBlend.setup then
|
if blend == MixBlend.setup then
|
||||||
@ -1786,7 +1784,7 @@ function Animation.IkConstraintTimeline.new (frameCount, bezierCount, ikConstrai
|
|||||||
local mix = 0
|
local mix = 0
|
||||||
local softness = 0
|
local softness = 0
|
||||||
local i = search(frames, time, ENTRIES)
|
local i = search(frames, time, ENTRIES)
|
||||||
local curveType = this.curves[i / ENTRIES]
|
local curveType = self.curves[i / ENTRIES]
|
||||||
if curveType == LINEAR then
|
if curveType == LINEAR then
|
||||||
local before = frames[i]
|
local before = frames[i]
|
||||||
mix = frames[i + MIX]
|
mix = frames[i + MIX]
|
||||||
@ -1888,7 +1886,7 @@ function Animation.TransformConstraintTimeline.new (frameCount, bezierCount, tra
|
|||||||
local scaleY
|
local scaleY
|
||||||
local shearY
|
local shearY
|
||||||
local i = search(frames, time, ENTRIES)
|
local i = search(frames, time, ENTRIES)
|
||||||
local curveType = this.curves[i / ENTRIES]
|
local curveType = self.curves[i / ENTRIES]
|
||||||
if curveType == LINEAR then
|
if curveType == LINEAR then
|
||||||
local before = frames[i]
|
local before = frames[i]
|
||||||
rotate = frames[i + ROTATE]
|
rotate = frames[i + ROTATE]
|
||||||
@ -2061,9 +2059,9 @@ function Animation.PathConstraintMixTimeline.new (frameCount, bezierCount, pathC
|
|||||||
x = frames[i + X]
|
x = frames[i + X]
|
||||||
y = frames[i + Y]
|
y = frames[i + Y]
|
||||||
else
|
else
|
||||||
rotate = this.getBezierValue(time, i, ROTATE, curveType - BEZIER)
|
rotate = self:getBezierValue(time, i, ROTATE, curveType - BEZIER)
|
||||||
x = this.getBezierValue(time, i, X, curveType + BEZIER_SIZE - BEZIER)
|
x = self:getBezierValue(time, i, X, curveType + BEZIER_SIZE - BEZIER)
|
||||||
y = this.getBezierValue(time, i, Y, curveType + BEZIER_SIZE * 2 - BEZIER)
|
y = self:getBezierValue(time, i, Y, curveType + BEZIER_SIZE * 2 - BEZIER)
|
||||||
end
|
end
|
||||||
|
|
||||||
if blend == MixBlend.setup then
|
if blend == MixBlend.setup then
|
||||||
|
|||||||
@ -37,7 +37,7 @@ local math_cos = math.cos
|
|||||||
local math_atan2 = math.atan2
|
local math_atan2 = math.atan2
|
||||||
local math_sqrt = math.sqrt
|
local math_sqrt = math.sqrt
|
||||||
local math_abs = math.abs
|
local math_abs = math.abs
|
||||||
local math_pi = math.pi
|
local math_pi_half = math.pi / 2
|
||||||
|
|
||||||
local Bone = {}
|
local Bone = {}
|
||||||
Bone.__index = Bone
|
Bone.__index = Bone
|
||||||
@ -119,7 +119,9 @@ function Bone:updateWorldTransformWith (x, y, rotation, scaleX, scaleY, shearX,
|
|||||||
self.c = pc * la + pd * lc
|
self.c = pc * la + pd * lc
|
||||||
self.d = pc * lb + pd * ld
|
self.d = pc * lb + pd * ld
|
||||||
return
|
return
|
||||||
elseif transformMode == TransformMode.onlyTranslation then
|
end
|
||||||
|
|
||||||
|
if transformMode == TransformMode.onlyTranslation then
|
||||||
local rotationY = rotation + 90 + shearY
|
local rotationY = rotation + 90 + shearY
|
||||||
self.a = math_cos(math_rad(rotation + shearX)) * scaleX
|
self.a = math_cos(math_rad(rotation + shearX)) * scaleX
|
||||||
self.b = math_cos(math_rad(rotationY)) * scaleY
|
self.b = math_cos(math_rad(rotationY)) * scaleY
|
||||||
@ -127,7 +129,7 @@ function Bone:updateWorldTransformWith (x, y, rotation, scaleX, scaleY, shearX,
|
|||||||
self.d = math_sin(math_rad(rotationY)) * scaleY
|
self.d = math_sin(math_rad(rotationY)) * scaleY
|
||||||
elseif transformMode == TransformMode.noRotationOrReflection then
|
elseif transformMode == TransformMode.noRotationOrReflection then
|
||||||
local s = pa * pa + pc * pc
|
local s = pa * pa + pc * pc
|
||||||
local prx = 0
|
local prx
|
||||||
if s > 0.0001 then
|
if s > 0.0001 then
|
||||||
s = math_abs(pa * pd - pb * pc) / s
|
s = math_abs(pa * pd - pb * pc) / s
|
||||||
pa = pa / self.skeleton.scaleX
|
pa = pa / self.skeleton.scaleX
|
||||||
@ -150,7 +152,6 @@ function Bone:updateWorldTransformWith (x, y, rotation, scaleX, scaleY, shearX,
|
|||||||
self.b = pa * lb - pb * ld
|
self.b = pa * lb - pb * ld
|
||||||
self.c = pc * la + pd * lc
|
self.c = pc * la + pd * lc
|
||||||
self.d = pc * lb + pd * ld
|
self.d = pc * lb + pd * ld
|
||||||
|
|
||||||
elseif transformMode == TransformMode.noScale or transformMode == TransformMode.noScaleOrReflection then
|
elseif transformMode == TransformMode.noScale or transformMode == TransformMode.noScaleOrReflection then
|
||||||
local cos = math_cos(math_rad(rotation))
|
local cos = math_cos(math_rad(rotation))
|
||||||
local sin = math_sin(math_rad(rotation))
|
local sin = math_sin(math_rad(rotation))
|
||||||
@ -161,10 +162,10 @@ function Bone:updateWorldTransformWith (x, y, rotation, scaleX, scaleY, shearX,
|
|||||||
za = za * s
|
za = za * s
|
||||||
zc = zc * s
|
zc = zc * s
|
||||||
s = math_sqrt(za * za + zc * zc)
|
s = math_sqrt(za * za + zc * zc)
|
||||||
if transformMode == TransformMode.noScale and pa * pd - pb * pc < 0 ~= (sx < 0) ~= (sy < 0) then
|
if transformMode == TransformMode.noScale and (pa * pd - pb * pc < 0) ~= ((sx < 0) ~= (sy < 0)) then
|
||||||
s = -s
|
s = -s
|
||||||
end
|
end
|
||||||
local r = math_pi / 2 + math_atan2(zc, za)
|
local r = math_pi_half + math_atan2(zc, za)
|
||||||
local zb = math_cos(r) * s
|
local zb = math_cos(r) * s
|
||||||
local zd = math_sin(r) * s
|
local zd = math_sin(r) * s
|
||||||
local la = math_cos(math_rad(shearX)) * scaleX
|
local la = math_cos(math_rad(shearX)) * scaleX
|
||||||
@ -215,11 +216,15 @@ function Bone:updateAppliedTransform ()
|
|||||||
if not parent then
|
if not parent then
|
||||||
self.ax = self.worldX
|
self.ax = self.worldX
|
||||||
self.ay = self.worldY
|
self.ay = self.worldY
|
||||||
self.arotation = math_deg(math_atan2(self.c, self.a))
|
local a = self.a
|
||||||
self.ascaleX = math_sqrt(self.a * self.a + self.c * self.c)
|
local b = self.b
|
||||||
self.ascaleY = math_sqrt(self.b * self.b + self.d * self.d)
|
local c = self.c
|
||||||
|
local d = self.d
|
||||||
|
self.arotation = math_deg(math_atan2(c, a))
|
||||||
|
self.ascaleX = math_sqrt(a * a + c * c)
|
||||||
|
self.ascaleY = math_sqrt(b * b + d * d)
|
||||||
self.ashearX = 0
|
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))
|
self.ashearY = math_deg(math_atan2(a * b + c * d, a * d - b * c))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local pa = parent.a
|
local pa = parent.a
|
||||||
|
|||||||
@ -101,11 +101,15 @@ function PathConstraint:update ()
|
|||||||
|
|
||||||
local bones = self.bones
|
local bones = self.bones
|
||||||
local boneCount = #bones
|
local boneCount = #bones
|
||||||
local spacesCount = boneCount
|
local spacesCount
|
||||||
if tangents then spacesCount = spacesCount + 1 end
|
if tangents then
|
||||||
|
spacesCount = boneCount
|
||||||
|
else
|
||||||
|
spacesCount = boneCount + 1
|
||||||
|
end
|
||||||
local spaces = utils.setArraySize(self.spaces, spacesCount)
|
local spaces = utils.setArraySize(self.spaces, spacesCount)
|
||||||
local lengths = nil
|
local lengths
|
||||||
if scale then lengths = Utils.setArraySize(this.lengths, boneCount) end
|
if scale then lengths = utils.setArraySize(self.lengths, boneCount) end
|
||||||
local spacing = self.spacing
|
local spacing = self.spacing
|
||||||
|
|
||||||
if data.spacingMode == PathConstraintData.SpacingMode.percent then
|
if data.spacingMode == PathConstraintData.SpacingMode.percent then
|
||||||
@ -113,20 +117,20 @@ function PathConstraint:update ()
|
|||||||
local i = 0
|
local i = 0
|
||||||
local n = spacesCount - 1
|
local n = spacesCount - 1
|
||||||
while i < n do
|
while i < n do
|
||||||
local bone = bones[i]
|
local bone = bones[i + 1]
|
||||||
local setupLength = bone.data.length
|
local setupLength = bone.data.length
|
||||||
if setupLength < epsilon then
|
if setupLength < epsilon then
|
||||||
lengths[i] = 0
|
lengths[i + 1] = 0
|
||||||
else
|
else
|
||||||
local x = setupLength * bone.a
|
local x = setupLength * bone.a
|
||||||
local y = setupLength * bone.c
|
local y = setupLength * bone.c
|
||||||
lengths[i] = math_sqrt(x * x + y * y)
|
lengths[i + 1] = math_sqrt(x * x + y * y)
|
||||||
end
|
end
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local i = 1
|
local i = 2
|
||||||
while i < spacesCount do
|
while i <= spacesCount do
|
||||||
spaces[i] = spacing
|
spaces[i] = spacing
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
@ -134,46 +138,46 @@ function PathConstraint:update ()
|
|||||||
local sum = 0
|
local sum = 0
|
||||||
local i = 0
|
local i = 0
|
||||||
while i < boneCount do
|
while i < boneCount do
|
||||||
local bone = bones[i]
|
local bone = bones[i + 1]
|
||||||
local setupLength = bone.data.length
|
local setupLength = bone.data.length
|
||||||
if setupLength < epsilon then
|
if setupLength < epsilon then
|
||||||
if scale then lengths[i] = 0 end
|
if scale then lengths[i + 1] = 0 end
|
||||||
i = i + 1
|
i = i + 1
|
||||||
spaces[i] = spacing
|
spaces[i + 1] = spacing
|
||||||
else
|
else
|
||||||
local x = setupLength * bone.a
|
local x = setupLength * bone.a
|
||||||
local y = setupLength * bone.c
|
local y = setupLength * bone.c
|
||||||
local length = math_sqrt(x * x + y * y)
|
local length = math_sqrt(x * x + y * y)
|
||||||
if scale then lengths[i] = length end
|
if scale then lengths[i + 1] = length end
|
||||||
i = i + 1
|
i = i + 1
|
||||||
spaces[i] = length
|
spaces[i + 1] = length
|
||||||
sum = sum + length
|
sum = sum + length
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if sum > 0 then
|
if sum > 0 then
|
||||||
sum = spacesCount / sum * spacing
|
sum = spacesCount / sum * spacing
|
||||||
local i = 1
|
local i = 2
|
||||||
while i < spacesCount do
|
while i <= spacesCount do
|
||||||
spaces[i] = spaces[i] * sum
|
spaces[i] = spaces[i] * sum
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local lengthSpacing = data.spacingMode == PathConstraintData.SpacingMode.length
|
local lengthSpacing = data.spacingMode == PathConstraintData.SpacingMode.length
|
||||||
local i = 1
|
local i = 0
|
||||||
local n = spacesCount - 1
|
local n = spacesCount - 1
|
||||||
while i < n do
|
while i < n do
|
||||||
local bone = bones[i]
|
local bone = bones[i + 1]
|
||||||
local setupLength = bone.data.length
|
local setupLength = bone.data.length
|
||||||
if setupLength < epsilon then
|
if setupLength < epsilon then
|
||||||
if scale then lengths[i] = 0 end
|
if scale then lengths[i + 1] = 0 end
|
||||||
i = i + 1
|
i = i + 1
|
||||||
spaces[i] = spacing
|
spaces[i + 1] = spacing
|
||||||
else
|
else
|
||||||
local x = setupLength * bone.a
|
local x = setupLength * bone.a
|
||||||
local y = setupLength * bone.c
|
local y = setupLength * bone.c
|
||||||
local length = math_sqrt(x * x + y * y)
|
local length = math_sqrt(x * x + y * y)
|
||||||
if scale then lengths[i] = length end
|
if scale then lengths[i + 1] = length end
|
||||||
i = i + 1
|
i = i + 1
|
||||||
local s
|
local s
|
||||||
if lengthSpacing then
|
if lengthSpacing then
|
||||||
@ -181,7 +185,7 @@ function PathConstraint:update ()
|
|||||||
else
|
else
|
||||||
s = spacing
|
s = spacing
|
||||||
end
|
end
|
||||||
spaces[i] = s * length / setupLength
|
spaces[i + 1] = s * length / setupLength
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -190,7 +194,7 @@ function PathConstraint:update ()
|
|||||||
local boneX = positions[1]
|
local boneX = positions[1]
|
||||||
local boneY = positions[2]
|
local boneY = positions[2]
|
||||||
local offsetRotation = data.offsetRotation
|
local offsetRotation = data.offsetRotation
|
||||||
local tip = false
|
local tip
|
||||||
if offsetRotation == 0 then
|
if offsetRotation == 0 then
|
||||||
tip = data.rotateMode == PathConstraintData.RotateMode.chain
|
tip = data.rotateMode == PathConstraintData.RotateMode.chain
|
||||||
else
|
else
|
||||||
@ -272,7 +276,7 @@ function PathConstraint:computeWorldPositions (path, spacesCount, tangents)
|
|||||||
local position = self.position
|
local position = self.position
|
||||||
local spaces = self.spaces
|
local spaces = self.spaces
|
||||||
local out = utils.setArraySize(self.positions, spacesCount * 3 + 2)
|
local out = utils.setArraySize(self.positions, spacesCount * 3 + 2)
|
||||||
local world = nil
|
local world
|
||||||
local closed = path.closed
|
local closed = path.closed
|
||||||
local verticesLength = path.worldVerticesLength
|
local verticesLength = path.worldVerticesLength
|
||||||
local curveCount = verticesLength / 6
|
local curveCount = verticesLength / 6
|
||||||
@ -292,7 +296,6 @@ function PathConstraint:computeWorldPositions (path, spacesCount, tangents)
|
|||||||
multiplier = pathLength / spacesCount
|
multiplier = pathLength / spacesCount
|
||||||
end
|
end
|
||||||
world = utils.setArraySize(self.world, 8)
|
world = utils.setArraySize(self.world, 8)
|
||||||
i = 0
|
|
||||||
local o = 0
|
local o = 0
|
||||||
local curve = 0
|
local curve = 0
|
||||||
while i < spacesCount do
|
while i < spacesCount do
|
||||||
|
|||||||
@ -96,7 +96,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
for i,boneMap in ipairs(root["bones"]) do
|
for i,boneMap in ipairs(root["bones"]) do
|
||||||
local boneName = boneMap["name"]
|
local boneName = boneMap["name"]
|
||||||
|
|
||||||
local parent = nil
|
local parent
|
||||||
local parentName = boneMap["parent"]
|
local parentName = boneMap["parent"]
|
||||||
if parentName then
|
if parentName then
|
||||||
parent = skeletonData:findBone(parentName)
|
parent = skeletonData:findBone(parentName)
|
||||||
@ -216,7 +216,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
data.offsetScaleY = getValue(constraintMap, "scaleY", 0)
|
data.offsetScaleY = getValue(constraintMap, "scaleY", 0)
|
||||||
data.offsetShearY = getValue(constraintMap, "shearY", 0)
|
data.offsetShearY = getValue(constraintMap, "shearY", 0)
|
||||||
|
|
||||||
data.mixRotate = getValue(constraintMap, "rotateMix", 1)
|
data.mixRotate = getValue(constraintMap, "mixRotate", 1)
|
||||||
data.mixX = getValue(constraintMap, "mixX", 1)
|
data.mixX = getValue(constraintMap, "mixX", 1)
|
||||||
data.mixY = getValue(constraintMap, "mixY", data.mixX)
|
data.mixY = getValue(constraintMap, "mixY", data.mixX)
|
||||||
data.mixScaleX = getValue(constraintMap, "mixScaleX", 1)
|
data.mixScaleX = getValue(constraintMap, "mixScaleX", 1)
|
||||||
@ -790,7 +790,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
for constraintName,timelineMap in pairs(ik) do
|
for constraintName,timelineMap in pairs(ik) do
|
||||||
local keyMap = timelineMap[1]
|
local keyMap = timelineMap[1]
|
||||||
if keyMap then
|
if keyMap then
|
||||||
local constraintIndex = -1
|
local constraintIndex
|
||||||
for i,other in pairs(skeletonData.ikConstraints) do
|
for i,other in pairs(skeletonData.ikConstraints) do
|
||||||
if other.name == constraintName then
|
if other.name == constraintName then
|
||||||
constraintIndex = i
|
constraintIndex = i
|
||||||
@ -829,8 +829,8 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
mix = mix2
|
mix = mix2
|
||||||
softness = softness2
|
softness = softness2
|
||||||
end
|
end
|
||||||
|
table_insert(timelines, timeline)
|
||||||
end
|
end
|
||||||
table_insert(timelines, timeline)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -840,7 +840,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
for constraintName, timelineMap in pairs(transform) do
|
for constraintName, timelineMap in pairs(transform) do
|
||||||
local keyMap = timelineMap[1]
|
local keyMap = timelineMap[1]
|
||||||
if keyMap then
|
if keyMap then
|
||||||
local constraintIndex = -1
|
local constraintIndex
|
||||||
for i,other in pairs(skeletonData.transformConstraints) do
|
for i,other in pairs(skeletonData.transformConstraints) do
|
||||||
if other.name == constraintName then
|
if other.name == constraintName then
|
||||||
constraintIndex = i
|
constraintIndex = i
|
||||||
@ -896,7 +896,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
-- Path constraint timelines.
|
-- Path constraint timelines.
|
||||||
if map.path then
|
if map.path then
|
||||||
for constraintName,constraintMap in pairs(map.path) do
|
for constraintName,constraintMap in pairs(map.path) do
|
||||||
local constraint, constraintIndex = -1
|
local constraint, constraintIndex
|
||||||
for i,other in pairs(skeletonData.pathConstraints) do
|
for i,other in pairs(skeletonData.pathConstraints) do
|
||||||
if other.name == constraintName then
|
if other.name == constraintName then
|
||||||
constraintIndex = i
|
constraintIndex = i
|
||||||
@ -978,7 +978,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
local bezier = 0
|
local bezier = 0
|
||||||
for i,keyMap in ipairs(timelineMap) do
|
for i,keyMap in ipairs(timelineMap) do
|
||||||
local frame = i - 1
|
local frame = i - 1
|
||||||
local deform = nil
|
local deform
|
||||||
local verticesValue = getValue(keyMap, "vertices", nil)
|
local verticesValue = getValue(keyMap, "vertices", nil)
|
||||||
if verticesValue == nil then
|
if verticesValue == nil then
|
||||||
if weighted then
|
if weighted then
|
||||||
@ -1031,7 +1031,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
local slotCount = #skeletonData.slots
|
local slotCount = #skeletonData.slots
|
||||||
local frame = 0
|
local frame = 0
|
||||||
for _,drawOrderMap in ipairs(map["drawOrder"]) do
|
for _,drawOrderMap in ipairs(map["drawOrder"]) do
|
||||||
local drawOrder = nil
|
local drawOrder
|
||||||
local offsets = drawOrderMap["offsets"]
|
local offsets = drawOrderMap["offsets"]
|
||||||
if offsets then
|
if offsets then
|
||||||
drawOrder = {}
|
drawOrder = {}
|
||||||
|
|||||||
@ -306,12 +306,12 @@ function TransformConstraint:applyRelativeLocal ()
|
|||||||
|
|
||||||
local bones = self.bones
|
local bones = self.bones
|
||||||
for _, bone in ipairs(bones) do
|
for _, bone in ipairs(bones) do
|
||||||
local rotation = bone.arotation + (target.arotation + this.data.offsetRotation) * mixRotate
|
local rotation = bone.arotation + (target.arotation + self.data.offsetRotation) * mixRotate
|
||||||
local x = bone.ax + (target.ax + this.data.offsetX) * mixX
|
local x = bone.ax + (target.ax + self.data.offsetX) * mixX
|
||||||
local y = bone.ay + (target.ay + this.data.offsetY) * mixY
|
local y = bone.ay + (target.ay + self.data.offsetY) * mixY
|
||||||
local scaleX = (bone.ascaleX * ((target.ascaleX - 1 + this.data.offsetScaleX) * mixScaleX) + 1)
|
local scaleX = (bone.ascaleX * ((target.ascaleX - 1 + self.data.offsetScaleX) * mixScaleX) + 1)
|
||||||
local scaleY = (bone.ascaleY * ((target.ascaleY - 1 + this.data.offsetScaleY) * mixScaleY) + 1)
|
local scaleY = (bone.ascaleY * ((target.ascaleY - 1 + self.data.offsetScaleY) * mixScaleY) + 1)
|
||||||
local shearY = bone.ashearY + (target.ashearY + this.data.offsetShearY) * mixShearY
|
local shearY = bone.ashearY + (target.ashearY + self.data.offsetShearY) * mixShearY
|
||||||
bone:updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY)
|
bone:updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -35,7 +35,7 @@ local math_cos = math.cos
|
|||||||
local AttachmentType = require "spine-lua.attachments.AttachmentType"
|
local AttachmentType = require "spine-lua.attachments.AttachmentType"
|
||||||
local Attachment = require "spine-lua.attachments.Attachment"
|
local Attachment = require "spine-lua.attachments.Attachment"
|
||||||
local Color = require "spine-lua.Color"
|
local Color = require "spine-lua.Color"
|
||||||
local Utils = require "spine-lua.utils"
|
local utils = require "spine-lua.utils"
|
||||||
|
|
||||||
local OX1 = 1
|
local OX1 = 1
|
||||||
local OY1 = 2
|
local OY1 = 2
|
||||||
@ -146,8 +146,8 @@ function RegionAttachment.new (name)
|
|||||||
self.path = nil
|
self.path = nil
|
||||||
self.rendererObject = nil
|
self.rendererObject = nil
|
||||||
self.region = nil
|
self.region = nil
|
||||||
self.offset = Utils.newNumberArray(8)
|
self.offset = utils.newNumberArray(8)
|
||||||
self.uvs = Utils.newNumberArray(8)
|
self.uvs = utils.newNumberArray(8)
|
||||||
self.tempColor = Color.newWith(1, 1, 1, 1)
|
self.tempColor = Color.newWith(1, 1, 1, 1)
|
||||||
setmetatable(self, RegionAttachment)
|
setmetatable(self, RegionAttachment)
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ end
|
|||||||
|
|
||||||
function RegionAttachment:setRegion (region)
|
function RegionAttachment:setRegion (region)
|
||||||
local uvs = self.uvs
|
local uvs = self.uvs
|
||||||
if region.rotate then
|
if region.degrees == 90 then
|
||||||
uvs[5] = region.u
|
uvs[5] = region.u
|
||||||
uvs[6] = region.v2
|
uvs[6] = region.v2
|
||||||
uvs[7] = region.u
|
uvs[7] = region.u
|
||||||
@ -256,8 +256,8 @@ function RegionAttachment:copy ()
|
|||||||
copy.path = self.path
|
copy.path = self.path
|
||||||
copy.rendererObject = self.rendererObject
|
copy.rendererObject = self.rendererObject
|
||||||
copy.region = self.region
|
copy.region = self.region
|
||||||
copy.offset = Utils.copy(self.offset)
|
copy.offset = utils.copy(self.offset)
|
||||||
copy.uvs = Utils.copy(self.uvs)
|
copy.uvs = utils.copy(self.uvs)
|
||||||
copy.tempColor:setFrom(self.tempColor)
|
copy.tempColor:setFrom(self.tempColor)
|
||||||
return copy
|
return copy
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user