mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
[lua][corona] Ported 3.6 changes except TransformConstraint update
This commit is contained in:
parent
0b8913691a
commit
0a2ca732cd
@ -75,6 +75,7 @@ function loadSkeleton(atlasFile, jsonFile, x, y, scale, animation, skin)
|
|||||||
return { skeleton = skeleton, state = animationState }
|
return { skeleton = skeleton, state = animationState }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
table.insert(skeletons, loadSkeleton("test.atlas", "test.json", 240, 300, 0.4, "animation"))
|
||||||
table.insert(skeletons, loadSkeleton("spineboy.atlas", "spineboy.json", 240, 300, 0.4, "walk"))
|
table.insert(skeletons, loadSkeleton("spineboy.atlas", "spineboy.json", 240, 300, 0.4, "walk"))
|
||||||
table.insert(skeletons, loadSkeleton("raptor.atlas", "raptor.json", 200, 300, 0.25, "walk"))
|
table.insert(skeletons, loadSkeleton("raptor.atlas", "raptor.json", 200, 300, 0.25, "walk"))
|
||||||
table.insert(skeletons, loadSkeleton("goblins.atlas", "goblins-mesh.json", 240, 300, 0.8, "walk", "goblin"))
|
table.insert(skeletons, loadSkeleton("goblins.atlas", "goblins-mesh.json", 240, 300, 0.8, "walk", "goblin"))
|
||||||
@ -82,6 +83,14 @@ table.insert(skeletons, loadSkeleton("stretchyman.atlas", "stretchyman.json", 40
|
|||||||
table.insert(skeletons, loadSkeleton("tank.atlas", "tank.json", 400, 300, 0.2, "drive"))
|
table.insert(skeletons, loadSkeleton("tank.atlas", "tank.json", 400, 300, 0.2, "drive"))
|
||||||
table.insert(skeletons, loadSkeleton("vine.atlas", "vine.json", 240, 300, 0.3, "animation"))
|
table.insert(skeletons, loadSkeleton("vine.atlas", "vine.json", 240, 300, 0.3, "animation"))
|
||||||
|
|
||||||
|
local bounds = spine.SkeletonBounds.new()
|
||||||
|
skeletons[1].skeleton:updateWorldTransform()
|
||||||
|
bounds:update(skeletons[1].skeleton, true)
|
||||||
|
|
||||||
|
local offset = {}
|
||||||
|
local size = {}
|
||||||
|
skeletons[1].skeleton:getBounds(offset, size)
|
||||||
|
|
||||||
display.setDefault("background", 0.2, 0.2, 0.2, 1)
|
display.setDefault("background", 0.2, 0.2, 0.2, 1)
|
||||||
|
|
||||||
Runtime:addEventListener("enterFrame", function (event)
|
Runtime:addEventListener("enterFrame", function (event)
|
||||||
|
|||||||
@ -43,6 +43,7 @@ spine.RegionAttachment = require "spine-lua.attachments.RegionAttachment"
|
|||||||
spine.MeshAttachment = require "spine-lua.attachments.MeshAttachment"
|
spine.MeshAttachment = require "spine-lua.attachments.MeshAttachment"
|
||||||
spine.VertexAttachment = require "spine-lua.attachments.VertexAttachment"
|
spine.VertexAttachment = require "spine-lua.attachments.VertexAttachment"
|
||||||
spine.PathAttachment = require "spine-lua.attachments.PathAttachment"
|
spine.PathAttachment = require "spine-lua.attachments.PathAttachment"
|
||||||
|
spine.PointAttachment = require "spine-lua.attachments.PointAttachment"
|
||||||
spine.Skeleton = require "spine-lua.Skeleton"
|
spine.Skeleton = require "spine-lua.Skeleton"
|
||||||
spine.Bone = require "spine-lua.Bone"
|
spine.Bone = require "spine-lua.Bone"
|
||||||
spine.Slot = require "spine-lua.Slot"
|
spine.Slot = require "spine-lua.Slot"
|
||||||
@ -86,6 +87,7 @@ spine.Skeleton.new = function(skeletonData, group)
|
|||||||
self.drawingGroup = nil
|
self.drawingGroup = nil
|
||||||
self.premultipliedAlpha = false
|
self.premultipliedAlpha = false
|
||||||
self.batches = 0
|
self.batches = 0
|
||||||
|
self.tempColor = spine.Color.newWith(1, 1, 1, 1)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -108,6 +110,8 @@ local function toCoronaBlendMode(blendMode)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local worldVertices = spine.utils.newNumberArray(10000 * 8)
|
||||||
|
|
||||||
function spine.Skeleton:updateWorldTransform()
|
function spine.Skeleton:updateWorldTransform()
|
||||||
spine.Skeleton.updateWorldTransform_super(self)
|
spine.Skeleton.updateWorldTransform_super(self)
|
||||||
local premultipliedAlpha = self.premultipliedAlpha
|
local premultipliedAlpha = self.premultipliedAlpha
|
||||||
@ -125,7 +129,7 @@ function spine.Skeleton:updateWorldTransform()
|
|||||||
local groupVertices = {}
|
local groupVertices = {}
|
||||||
local groupIndices = {}
|
local groupIndices = {}
|
||||||
local groupUvs = {}
|
local groupUvs = {}
|
||||||
local color = nil
|
local color = self.tempColor
|
||||||
local lastColor = nil
|
local lastColor = nil
|
||||||
local texture = nil
|
local texture = nil
|
||||||
local lastTexture = nil
|
local lastTexture = nil
|
||||||
@ -134,19 +138,20 @@ function spine.Skeleton:updateWorldTransform()
|
|||||||
for i,slot in ipairs(drawOrder) do
|
for i,slot in ipairs(drawOrder) do
|
||||||
local attachment = slot.attachment
|
local attachment = slot.attachment
|
||||||
local vertices = nil
|
local vertices = nil
|
||||||
|
local numVertices = 0
|
||||||
local indices = nil
|
local indices = nil
|
||||||
if attachment then
|
if attachment then
|
||||||
if attachment.type == spine.AttachmentType.region then
|
if attachment.type == spine.AttachmentType.region then
|
||||||
vertices = attachment:updateWorldVertices(slot, premultipliedAlpha)
|
numVertices = 4
|
||||||
|
vertices = self:computeRegionVertices(slot, attachment, premultipliedAlpha, color)
|
||||||
indices = QUAD_TRIANGLES
|
indices = QUAD_TRIANGLES
|
||||||
texture = attachment.region.renderObject.texture
|
texture = attachment.region.renderObject.texture
|
||||||
color = { vertices[5], vertices[6], vertices[7], vertices[8]}
|
|
||||||
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
||||||
elseif attachment.type == spine.AttachmentType.mesh then
|
elseif attachment.type == spine.AttachmentType.mesh then
|
||||||
vertices = attachment:updateWorldVertices(slot, premultipliedAlpha)
|
numVertices = attachment.worldVerticesLength / 2
|
||||||
|
vertices = self:computeMeshVertices(slot, attachment, premultipliedAlpha, color)
|
||||||
indices = attachment.triangles
|
indices = attachment.triangles
|
||||||
texture = attachment.region.renderObject.texture
|
texture = attachment.region.renderObject.texture
|
||||||
color = { vertices[5], vertices[6], vertices[7], vertices[8] }
|
|
||||||
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -165,7 +170,7 @@ function spine.Skeleton:updateWorldTransform()
|
|||||||
groupIndices = {}
|
groupIndices = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
self:batch(vertices, indices, groupVertices, groupUvs, groupIndices)
|
self:batch(vertices, numVertices, indices, groupVertices, groupUvs, groupIndices)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -175,22 +180,87 @@ function spine.Skeleton:updateWorldTransform()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function spine.Skeleton:computeRegionVertices(slot, region, pma, color)
|
||||||
|
local skeleton = slot.bone.skeleton
|
||||||
|
local skeletonColor = skeleton.color
|
||||||
|
local slotColor = slot.color
|
||||||
|
local regionColor = region.color
|
||||||
|
local alpha = skeletonColor.a * slotColor.a * regionColor.a
|
||||||
|
local multiplier = alpha
|
||||||
|
if pma then multiplier = 1 end
|
||||||
|
color:set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
|
||||||
|
skeletonColor.g * slotColor.g * regionColor.g * multiplier,
|
||||||
|
skeletonColor.b * slotColor.b * regionColor.b * multiplier,
|
||||||
|
alpha)
|
||||||
|
|
||||||
|
local vertices = worldVertices
|
||||||
|
region:computeWorldVertices(slot.bone, vertices, 0, 4)
|
||||||
|
|
||||||
|
local uvs = region.uvs
|
||||||
|
|
||||||
|
vertices[3] = uvs[1]
|
||||||
|
vertices[4] = uvs[2]
|
||||||
|
|
||||||
|
vertices[7] = uvs[3]
|
||||||
|
vertices[8] = uvs[4]
|
||||||
|
|
||||||
|
vertices[11] = uvs[5]
|
||||||
|
vertices[12] = uvs[6]
|
||||||
|
|
||||||
|
vertices[15] = uvs[7]
|
||||||
|
vertices[16] = uvs[8]
|
||||||
|
|
||||||
|
return vertices
|
||||||
|
end
|
||||||
|
|
||||||
|
function spine.Skeleton:computeMeshVertices(slot, mesh, pma, color)
|
||||||
|
local skeleton = slot.bone.skeleton
|
||||||
|
local skeletonColor = skeleton.color
|
||||||
|
local slotColor = slot.color
|
||||||
|
local meshColor = mesh.color
|
||||||
|
local alpha = skeletonColor.a * slotColor.a * meshColor.a
|
||||||
|
local multiplier = alpha
|
||||||
|
if pma then multiplier = 1 end
|
||||||
|
color:set(skeletonColor.r * slotColor.r * meshColor.r * multiplier,
|
||||||
|
skeletonColor.g * slotColor.g * meshColor.g * multiplier,
|
||||||
|
skeletonColor.b * slotColor.b * meshColor.b * multiplier,
|
||||||
|
alpha)
|
||||||
|
|
||||||
|
local numVertices = mesh.worldVerticesLength / 2
|
||||||
|
local vertices = worldVertices
|
||||||
|
mesh:computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, 4)
|
||||||
|
|
||||||
|
local uvs = mesh.uvs
|
||||||
|
local i = 1
|
||||||
|
local n = numVertices + 1
|
||||||
|
local u = 1
|
||||||
|
local v = 3
|
||||||
|
while i < n do
|
||||||
|
vertices[v] = uvs[u]
|
||||||
|
vertices[v + 1] = uvs[u + 1]
|
||||||
|
i = i + 1
|
||||||
|
u = u + 2
|
||||||
|
v = v + 4
|
||||||
|
end
|
||||||
|
return vertices
|
||||||
|
end
|
||||||
|
|
||||||
function spine.Skeleton:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup)
|
function spine.Skeleton:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup)
|
||||||
mesh = display.newMesh(drawingGroup, 0, 0, {
|
local mesh = display.newMesh(drawingGroup, 0, 0, {
|
||||||
mode = "indexed",
|
mode = "indexed",
|
||||||
vertices = groupVertices,
|
vertices = groupVertices,
|
||||||
uvs = groupUvs,
|
uvs = groupUvs,
|
||||||
indices = groupIndices
|
indices = groupIndices
|
||||||
})
|
})
|
||||||
mesh.fill = texture
|
mesh.fill = texture
|
||||||
mesh:setFillColor(color[1], color[2], color[3])
|
mesh:setFillColor(color.r, color.g, color.b)
|
||||||
mesh.alpha = color[4]
|
mesh.alpha = color.a
|
||||||
mesh.blendMode = blendMode
|
mesh.blendMode = blendMode
|
||||||
mesh:translate(mesh.path:getVertexOffset())
|
mesh:translate(mesh.path:getVertexOffset())
|
||||||
self.batches = self.batches + 1
|
self.batches = self.batches + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
function spine.Skeleton:batch(vertices, indices, groupVertices, groupUvs, groupIndices)
|
function spine.Skeleton:batch(vertices, numVertices, indices, groupVertices, groupUvs, groupIndices)
|
||||||
local numIndices = #indices
|
local numIndices = #indices
|
||||||
local i = 1
|
local i = 1
|
||||||
local indexStart = #groupIndices + 1
|
local indexStart = #groupIndices + 1
|
||||||
@ -204,16 +274,15 @@ function spine.Skeleton:batch(vertices, indices, groupVertices, groupUvs, groupI
|
|||||||
end
|
end
|
||||||
|
|
||||||
i = 1
|
i = 1
|
||||||
local numVertices = #vertices
|
|
||||||
local vertexStart = #groupVertices + 1
|
local vertexStart = #groupVertices + 1
|
||||||
local vertexEnd = vertexStart + numVertices / 4
|
local vertexEnd = vertexStart + numVertices * 2
|
||||||
while vertexStart < vertexEnd do
|
while vertexStart < vertexEnd do
|
||||||
groupVertices[vertexStart] = vertices[i]
|
groupVertices[vertexStart] = vertices[i]
|
||||||
groupVertices[vertexStart+1] = vertices[i+1]
|
groupVertices[vertexStart+1] = vertices[i+1]
|
||||||
groupUvs[vertexStart] = vertices[i+2]
|
groupUvs[vertexStart] = vertices[i+2]
|
||||||
groupUvs[vertexStart+1] = vertices[i+3]
|
groupUvs[vertexStart+1] = vertices[i+3]
|
||||||
vertexStart = vertexStart + 2
|
vertexStart = vertexStart + 2
|
||||||
i = i + 8
|
i = i + 4
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -118,7 +118,8 @@ Animation.TimelineType = {
|
|||||||
attachment = 4, color = 5, deform = 6,
|
attachment = 4, color = 5, deform = 6,
|
||||||
event = 7, drawOrder = 8,
|
event = 7, drawOrder = 8,
|
||||||
ikConstraint = 9, transformConstraint = 10,
|
ikConstraint = 9, transformConstraint = 10,
|
||||||
pathConstraintPosition = 11, pathConstraintSpacing = 12, pathConstraintMix = 13
|
pathConstraintPosition = 11, pathConstraintSpacing = 12, pathConstraintMix = 13,
|
||||||
|
twoColor = 14
|
||||||
}
|
}
|
||||||
local TimelineType = Animation.TimelineType
|
local TimelineType = Animation.TimelineType
|
||||||
local SHL_24 = 16777216
|
local SHL_24 = 16777216
|
||||||
@ -562,6 +563,108 @@ function Animation.ColorTimeline.new (frameCount)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Animation.TwoColorTimeline = {}
|
||||||
|
Animation.TwoColorTimeline.ENTRIES = 8
|
||||||
|
function Animation.TwoColorTimeline.new (frameCount)
|
||||||
|
local ENTRIES = Animation.TwoColorTimeline.ENTRIES
|
||||||
|
local PREV_TIME = -8
|
||||||
|
local PREV_R = -7
|
||||||
|
local PREV_G = -6
|
||||||
|
local PREV_B = -5
|
||||||
|
local PREV_A = -4
|
||||||
|
local PREV_R2 = -3
|
||||||
|
local PREV_G2 = -2
|
||||||
|
local PREV_B2 = -1
|
||||||
|
local R = 1
|
||||||
|
local G = 2
|
||||||
|
local B = 3
|
||||||
|
local A = 4
|
||||||
|
local R2 = 5
|
||||||
|
local G2 = 6
|
||||||
|
local B2 = 7
|
||||||
|
|
||||||
|
local self = Animation.CurveTimeline.new(frameCount)
|
||||||
|
self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
|
||||||
|
self.slotIndex = -1
|
||||||
|
self.type = TimelineType.twoColor
|
||||||
|
|
||||||
|
function self:getPropertyId ()
|
||||||
|
return TimelineType.twoColor * SHL_24 + self.slotIndex
|
||||||
|
end
|
||||||
|
|
||||||
|
function self:setFrame (frameIndex, time, r, g, b, a, r2, g2, b2)
|
||||||
|
frameIndex = frameIndex * ENTRIES
|
||||||
|
self.frames[frameIndex] = time
|
||||||
|
self.frames[frameIndex + R] = r
|
||||||
|
self.frames[frameIndex + G] = g
|
||||||
|
self.frames[frameIndex + B] = b
|
||||||
|
self.frames[frameIndex + A] = a
|
||||||
|
self.frames[frameIndex + R2] = r2
|
||||||
|
self.frames[frameIndex + G2] = g2
|
||||||
|
self.frames[frameIndex + B2] = b2
|
||||||
|
end
|
||||||
|
|
||||||
|
function self:apply (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut)
|
||||||
|
local frames = self.frames
|
||||||
|
local slot = skeleton.slots[self.slotIndex]
|
||||||
|
if time < frames[0] then
|
||||||
|
if setupPose then
|
||||||
|
slot.color:setFrom(slot.data.color)
|
||||||
|
slot.darkColor:setFrom(slot.data.darkColor)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local r, g, b, a, r2, g2, b2
|
||||||
|
if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
|
||||||
|
local i = zlen(frames)
|
||||||
|
r = frames[i + PREV_R]
|
||||||
|
g = frames[i + PREV_G]
|
||||||
|
b = frames[i + PREV_B]
|
||||||
|
a = frames[i + PREV_A]
|
||||||
|
r2 = frames[i + PREV_R2]
|
||||||
|
g2 = frames[i + PREV_G2]
|
||||||
|
b2 = frames[i + PREV_B2]
|
||||||
|
else
|
||||||
|
-- Interpolate between the last frame and the current frame.
|
||||||
|
local frame = binarySearch(frames, time, ENTRIES)
|
||||||
|
r = frames[frame + PREV_R]
|
||||||
|
g = frames[frame + PREV_G]
|
||||||
|
b = frames[frame + PREV_B]
|
||||||
|
a = frames[frame + PREV_A]
|
||||||
|
r2 = frames[frame + PREV_R2]
|
||||||
|
g2 = frames[frame + PREV_G2]
|
||||||
|
b2 = frames[frame + PREV_B2]
|
||||||
|
local frameTime = frames[frame]
|
||||||
|
local percent = self:getCurvePercent(math.floor(frame / ENTRIES) - 1,
|
||||||
|
1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
|
||||||
|
|
||||||
|
r = r + (frames[frame + R] - r) * percent
|
||||||
|
g = g + (frames[frame + G] - g) * percent
|
||||||
|
b = b + (frames[frame + B] - b) * percent
|
||||||
|
a = a + (frames[frame + A] - a) * percent
|
||||||
|
r2 = r2 + (frames[frame + R2] - r2) * percent
|
||||||
|
g2 = g2 + (frames[frame + G2] - g2) * percent
|
||||||
|
b2 = b2 + (frames[frame + B2] - b2) * percent
|
||||||
|
end
|
||||||
|
if alpha == 1 then
|
||||||
|
slot.color:set(r, g, b, a)
|
||||||
|
slot.darkColor:set(r2, g2, b2, 1)
|
||||||
|
else
|
||||||
|
local light = slot.color
|
||||||
|
local dark = slot.darkColor
|
||||||
|
if setupPose then
|
||||||
|
light:setFrom(slot.data.color)
|
||||||
|
dark:setFrom(slot.data.darkColor)
|
||||||
|
end
|
||||||
|
light:add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha)
|
||||||
|
dark:add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
Animation.AttachmentTimeline = {}
|
Animation.AttachmentTimeline = {}
|
||||||
function Animation.AttachmentTimeline.new (frameCount)
|
function Animation.AttachmentTimeline.new (frameCount)
|
||||||
local self = {
|
local self = {
|
||||||
|
|||||||
@ -35,6 +35,7 @@ local RegionAttachment = require "spine-lua.attachments.RegionAttachment"
|
|||||||
local BoundingBoxAttachment = require "spine-lua.attachments.BoundingBoxAttachment"
|
local BoundingBoxAttachment = require "spine-lua.attachments.BoundingBoxAttachment"
|
||||||
local MeshAttachment = require "spine-lua.attachments.MeshAttachment"
|
local MeshAttachment = require "spine-lua.attachments.MeshAttachment"
|
||||||
local PathAttachment = require "spine-lua.attachments.PathAttachment"
|
local PathAttachment = require "spine-lua.attachments.PathAttachment"
|
||||||
|
local PointAttachment = require "spine-lua.attachments.PointAttachment"
|
||||||
local TextureAtlas = require "spine-lua.TextureAtlas"
|
local TextureAtlas = require "spine-lua.TextureAtlas"
|
||||||
|
|
||||||
local AtlasAttachmentLoader = {}
|
local AtlasAttachmentLoader = {}
|
||||||
@ -79,4 +80,8 @@ function AtlasAttachmentLoader:newPathAttachment(skin, name)
|
|||||||
return PathAttachment.new(name)
|
return PathAttachment.new(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function AtlasAttachmentLoader:newPointAttachment(skin, name)
|
||||||
|
return PointAttachment.new(name)
|
||||||
|
end
|
||||||
|
|
||||||
return AtlasAttachmentLoader
|
return AtlasAttachmentLoader
|
||||||
|
|||||||
@ -33,6 +33,7 @@ local RegionAttachment = require "spine-lua.attachments.RegionAttachment"
|
|||||||
local BoundingBoxAttachment = require "spine-lua.attachments.BoundingBoxAttachment"
|
local BoundingBoxAttachment = require "spine-lua.attachments.BoundingBoxAttachment"
|
||||||
local MeshAttachment = require "spine-lua.attachments.MeshAttachment"
|
local MeshAttachment = require "spine-lua.attachments.MeshAttachment"
|
||||||
local PathAttachment = require "spine-lua.attachments.PathAttachment"
|
local PathAttachment = require "spine-lua.attachments.PathAttachment"
|
||||||
|
local PointAttachment = require "spine-lua.attachments.PointAttachment"
|
||||||
|
|
||||||
local AttachmentLoader = {}
|
local AttachmentLoader = {}
|
||||||
function AttachmentLoader.new ()
|
function AttachmentLoader.new ()
|
||||||
@ -58,6 +59,10 @@ function AttachmentLoader.new ()
|
|||||||
return PathAttachment.new(name)
|
return PathAttachment.new(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function self:newPointAttachment(skin, name)
|
||||||
|
return PointAttachment.new(name)
|
||||||
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
return AttachmentLoader
|
return AttachmentLoader
|
||||||
|
|||||||
@ -240,45 +240,6 @@ function Bone:getWorldScaleY ()
|
|||||||
return math_sqrt(self.b * self.b + self.d * self.d)
|
return math_sqrt(self.b * self.b + self.d * self.d)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Bone:worldToLocalRotationX ()
|
|
||||||
local parent = self.parent
|
|
||||||
if parent == nil then return self.arotation end
|
|
||||||
local pa = parent.a
|
|
||||||
local pb = parent.b
|
|
||||||
local pc = parent.c
|
|
||||||
local pd = parent.d
|
|
||||||
local a = self.a
|
|
||||||
local c = self.c
|
|
||||||
return math_deg(math_atan2(pa * c - pc * a, pd * a - pb * c))
|
|
||||||
end
|
|
||||||
|
|
||||||
function Bone:worldToLocalRotationY ()
|
|
||||||
local parent = self.parent
|
|
||||||
if parent == nil then return self.rotation end
|
|
||||||
local pa = parent.a
|
|
||||||
local pb = parent.b
|
|
||||||
local pc = parent.c
|
|
||||||
local pd = parent.d
|
|
||||||
local b = self.b
|
|
||||||
local d = self.d
|
|
||||||
return math_deg(math_atan2(pa * d - pc * b, pd * b - pb * d))
|
|
||||||
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
|
|
||||||
|
|
||||||
function updateAppliedTransform ()
|
function updateAppliedTransform ()
|
||||||
local parent = self.parent
|
local parent = self.parent
|
||||||
if parent == nil then
|
if parent == nil then
|
||||||
@ -344,4 +305,31 @@ function Bone:localToWorld (localCoords)
|
|||||||
return localCoords
|
return localCoords
|
||||||
end
|
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))
|
||||||
|
end
|
||||||
|
|
||||||
|
function Bone:localToWorldRotation (localRotation)
|
||||||
|
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
|
return Bone
|
||||||
|
|||||||
@ -117,13 +117,13 @@ function PathConstraint:update ()
|
|||||||
local n = spacesCount - 1
|
local n = spacesCount - 1
|
||||||
while i < n do
|
while i < n do
|
||||||
local bone = bones[i + 1];
|
local bone = bones[i + 1];
|
||||||
local length = bone.data.length
|
local setupLength = bone.data.length
|
||||||
local x = length * bone.a
|
local x = setupLength * bone.a
|
||||||
local y = length * bone.c
|
local y = setupLength * bone.c
|
||||||
length = math_sqrt(x * x + y * y)
|
local length = math_sqrt(x * x + y * y)
|
||||||
if scale then lengths[i + 1] = length end
|
if scale then lengths[i + 1] = length end
|
||||||
i = i + 1
|
i = i + 1
|
||||||
if lengthSpacing then spaces[i + 1] = math_max(0, length + spacing) else spaces[i + 1] = spacing end
|
if lengthSpacing then spaces[i + 1] = (setupLength + spacing) * length / setupLength else spaces[i + 1] = spacing * length / setupLength end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local i = 1
|
local i = 1
|
||||||
@ -254,14 +254,14 @@ function PathConstraint:computeWorldPositions (path, spacesCount, tangents, perc
|
|||||||
elseif p < 0 then
|
elseif p < 0 then
|
||||||
if prevCurve ~= PathConstraint.BEFORE then
|
if prevCurve ~= PathConstraint.BEFORE then
|
||||||
prevCurve = PathConstraint.BEFORE
|
prevCurve = PathConstraint.BEFORE
|
||||||
path:computeWorldVerticesWith(target, 2, 4, world, 0)
|
path:computeWorldVertices(target, 2, 4, world, 0, 2)
|
||||||
end
|
end
|
||||||
self:addBeforePosition(p, world, 0, out, o)
|
self:addBeforePosition(p, world, 0, out, o)
|
||||||
skip = true
|
skip = true
|
||||||
elseif p > pathLength then
|
elseif p > pathLength then
|
||||||
if prevCurve ~= PathConstraint.AFTER then
|
if prevCurve ~= PathConstraint.AFTER then
|
||||||
prevCurve = PathConstraint.AFTER
|
prevCurve = PathConstraint.AFTER
|
||||||
path:computeWorldVerticesWith(target, verticesLength - 6, 4, world, 0)
|
path:computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2)
|
||||||
end
|
end
|
||||||
self:addAfterPosition(p - pathLength, world, 0, out, o)
|
self:addAfterPosition(p - pathLength, world, 0, out, o)
|
||||||
skip = true
|
skip = true
|
||||||
@ -285,10 +285,10 @@ function PathConstraint:computeWorldPositions (path, spacesCount, tangents, perc
|
|||||||
if curve ~= prevCurve then
|
if curve ~= prevCurve then
|
||||||
prevCurve = curve
|
prevCurve = curve
|
||||||
if closed and curve == curveCount then
|
if closed and curve == curveCount then
|
||||||
path:computeWorldVerticesWith(target, verticesLength - 4, 4, world, 0)
|
path:computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2)
|
||||||
path:computeWorldVerticesWith(target, 0, 4, world, 4)
|
path:computeWorldVertices(target, 0, 4, world, 4, 2)
|
||||||
else
|
else
|
||||||
path:computeWorldVerticesWith(target, curve * 6 + 2, 8, world, 0)
|
path:computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self:addCurvePosition(p, world[1], world[2], world[3], world[4], world[5], world[6], world[7], world[8], out, o, tangents or (i > 0 and space == 0))
|
self:addCurvePosition(p, world[1], world[2], world[3], world[4], world[5], world[6], world[7], world[8], out, o, tangents or (i > 0 and space == 0))
|
||||||
@ -304,15 +304,15 @@ function PathConstraint:computeWorldPositions (path, spacesCount, tangents, perc
|
|||||||
if closed then
|
if closed then
|
||||||
verticesLength = verticesLength + 2
|
verticesLength = verticesLength + 2
|
||||||
world = utils.setArraySize(self.world, verticesLength)
|
world = utils.setArraySize(self.world, verticesLength)
|
||||||
path:computeWorldVerticesWith(target, 2, verticesLength - 4, world, 0)
|
path:computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2)
|
||||||
path:computeWorldVerticesWith(target, 0, 2, world, verticesLength - 4)
|
path:computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2)
|
||||||
world[verticesLength - 2 + 1] = world[0 + 1]
|
world[verticesLength - 2 + 1] = world[0 + 1]
|
||||||
world[verticesLength - 1 + 1] = world[1 + 1]
|
world[verticesLength - 1 + 1] = world[1 + 1]
|
||||||
else
|
else
|
||||||
curveCount = curveCount - 1
|
curveCount = curveCount - 1
|
||||||
verticesLength = verticesLength - 4;
|
verticesLength = verticesLength - 4;
|
||||||
world = utils.setArraySize(self.world, verticesLength)
|
world = utils.setArraySize(self.world, verticesLength)
|
||||||
path:computeWorldVerticesWith(target, 2, verticesLength, world, 0)
|
path:computeWorldVertices(target, 2, verticesLength, world, 0, 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Curve lengths.
|
-- Curve lengths.
|
||||||
|
|||||||
@ -206,7 +206,7 @@ function Skeleton:sortPathConstraint(constraint)
|
|||||||
if self.data.defaultSkin and not (self.data.defaultSkin == skin) then
|
if self.data.defaultSkin and not (self.data.defaultSkin == skin) then
|
||||||
self:sortPathConstraintAttachment(self.data.defaultSkin, slotIndex, slotBone)
|
self:sortPathConstraintAttachment(self.data.defaultSkin, slotIndex, slotBone)
|
||||||
end
|
end
|
||||||
for ii,skin in ipairs(self.data.skins) do
|
for i,skin in ipairs(self.data.skins) do
|
||||||
self:sortPathConstraintAttachment(skin, slotIndex, slotBone)
|
self:sortPathConstraintAttachment(skin, slotIndex, slotBone)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ function Skeleton:sortPathConstraint(constraint)
|
|||||||
if attachment.type == AttachmentType.path then self:sortPathConstraintAttachmentWith(attachment, slotBone) end
|
if attachment.type == AttachmentType.path then self:sortPathConstraintAttachmentWith(attachment, slotBone) end
|
||||||
|
|
||||||
local constrained = constraint.bones
|
local constrained = constraint.bones
|
||||||
for ii,bone in ipairs(constrained) do
|
for i,bone in ipairs(constrained) do
|
||||||
self:sortBone(bone)
|
self:sortBone(bone)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -233,8 +233,23 @@ function Skeleton:sortTransformConstraint(constraint)
|
|||||||
self:sortBone(constraint.target)
|
self:sortBone(constraint.target)
|
||||||
|
|
||||||
local constrained = constraint.bones
|
local constrained = constraint.bones
|
||||||
for ii,bone in ipairs(constrained) do
|
if constraint.data.local_ then
|
||||||
self:sortBone(bone)
|
for i,bone in ipairs(constrained) do
|
||||||
|
local child = constrained[#constrained]
|
||||||
|
local contains = false
|
||||||
|
sortBone(child.parent)
|
||||||
|
for i,updatable in ipairs(self._updateCache) do
|
||||||
|
if updatable == child then
|
||||||
|
contains = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not contains then table_insert(self.updateCacheReset, child) end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for i,bone in ipairs(constrained) do
|
||||||
|
self:sortBone(bone)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
table_insert(self._updateCache, constraint)
|
table_insert(self._updateCache, constraint)
|
||||||
@ -482,12 +497,16 @@ function Skeleton:getBounds(offset, size)
|
|||||||
local maxX = -99999999
|
local maxX = -99999999
|
||||||
local maxY = -99999999
|
local maxY = -99999999
|
||||||
for i, slot in ipairs(drawOrder) do
|
for i, slot in ipairs(drawOrder) do
|
||||||
local vertices = nil
|
local vertices = {}
|
||||||
local attachment = slot.attachment
|
local attachment = slot.attachment
|
||||||
if attachment and (attachment.type == AttachmentType.region or attachment.type == AttachmentType.mesh) then
|
if attachment then
|
||||||
vertices = attachment:updateWorldVertices(slot, false);
|
if attachment.type == AttachmentType.region then
|
||||||
|
attachment:computeWorldVertices(slot.bone, vertices, 0, 2)
|
||||||
|
elseif attachment.type == AttachmentType.mesh then
|
||||||
|
attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if vertices then
|
if #vertices > 0 then
|
||||||
local nn = #vertices
|
local nn = #vertices
|
||||||
local ii = 1
|
local ii = 1
|
||||||
while ii <= nn do
|
while ii <= nn do
|
||||||
@ -497,7 +516,7 @@ function Skeleton:getBounds(offset, size)
|
|||||||
minY = math_min(minY, y)
|
minY = math_min(minY, y)
|
||||||
maxX = math_max(maxX, x)
|
maxX = math_max(maxX, x)
|
||||||
maxY = math_max(maxY, y)
|
maxY = math_max(maxY, y)
|
||||||
ii = ii + 8
|
ii = ii + 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -68,7 +68,7 @@ function SkeletonBounds:update (skeleton, updateAabb)
|
|||||||
local polygon = {}
|
local polygon = {}
|
||||||
table_insert(polygons, polygon)
|
table_insert(polygons, polygon)
|
||||||
|
|
||||||
boundingBox:computeWorldVertices(slot, polygon)
|
boundingBox:computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -131,6 +131,15 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
tonumber(color:sub(7, 8), 16) / 255)
|
tonumber(color:sub(7, 8), 16) / 255)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local dark = slotMap["dark"]
|
||||||
|
if dark then
|
||||||
|
data.darkColor = Color.newWith(1, 1, 1, 1)
|
||||||
|
data.darkColor:set(tonumber(dark:sub(1, 2), 16) / 255,
|
||||||
|
tonumber(dark:sub(3, 4), 16) / 255,
|
||||||
|
tonumber(dark:sub(5, 6), 16) / 255,
|
||||||
|
tonumber(dark:sub(7, 8), 16) / 255)
|
||||||
|
end
|
||||||
|
|
||||||
data.attachmentName = getValue(slotMap, "attachment", nil)
|
data.attachmentName = getValue(slotMap, "attachment", nil)
|
||||||
data.blendMode = BlendMode[getValue(slotMap, "blend", "normal")]
|
data.blendMode = BlendMode[getValue(slotMap, "blend", "normal")]
|
||||||
|
|
||||||
@ -380,6 +389,23 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
tonumber(color:sub(7, 8), 16) / 255)
|
tonumber(color:sub(7, 8), 16) / 255)
|
||||||
end
|
end
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
|
elseif type == AttachmentType.point then
|
||||||
|
local point = self.attachmentLoader:newPointAttachment(skin, name)
|
||||||
|
if not point then return nil end
|
||||||
|
point.x = getValue(map, "x", 0) * scale
|
||||||
|
point.y = getValue(map, "y", 0) * scale
|
||||||
|
point.rotation = getValue(map, "rotation", 0)
|
||||||
|
|
||||||
|
local color = map.color
|
||||||
|
if color then
|
||||||
|
path.color:set(tonumber(color:sub(1, 2), 16) / 255,
|
||||||
|
tonumber(color:sub(3, 4), 16) / 255,
|
||||||
|
tonumber(color:sub(5, 6), 16) / 255,
|
||||||
|
tonumber(color:sub(7, 8), 16) / 255)
|
||||||
|
end
|
||||||
|
return point
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
error("Unknown attachment type: " .. type .. " (" .. name .. ")")
|
error("Unknown attachment type: " .. type .. " (" .. name .. ")")
|
||||||
|
|||||||
@ -43,6 +43,7 @@ function Slot.new (data, bone)
|
|||||||
data = data,
|
data = data,
|
||||||
bone = bone,
|
bone = bone,
|
||||||
color = Color.newWith(1, 1, 1, 1),
|
color = Color.newWith(1, 1, 1, 1),
|
||||||
|
darkColor = nil,
|
||||||
attachment = nil,
|
attachment = nil,
|
||||||
attachmentTime = 0,
|
attachmentTime = 0,
|
||||||
attachmentVertices = {},
|
attachmentVertices = {},
|
||||||
@ -50,6 +51,8 @@ function Slot.new (data, bone)
|
|||||||
}
|
}
|
||||||
setmetatable(self, Slot)
|
setmetatable(self, Slot)
|
||||||
|
|
||||||
|
if data.darkColor then self.darkColor = Color.newWith(1, 1, 1, 1) end
|
||||||
|
|
||||||
self:setToSetupPose()
|
self:setToSetupPose()
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -74,6 +77,7 @@ function Slot:setToSetupPose ()
|
|||||||
local data = self.data
|
local data = self.data
|
||||||
|
|
||||||
self.color:setFrom(data.color)
|
self.color:setFrom(data.color)
|
||||||
|
if self.darkColor then self.darkColor:setFrom(data.darkColor) end
|
||||||
|
|
||||||
local attachment = nil
|
local attachment = nil
|
||||||
if data.attachmentName then
|
if data.attachmentName then
|
||||||
|
|||||||
@ -46,6 +46,7 @@ function SlotData.new (index, name, boneData)
|
|||||||
name = name,
|
name = name,
|
||||||
boneData = boneData,
|
boneData = boneData,
|
||||||
color = Color.newWith(1, 1, 1, 1),
|
color = Color.newWith(1, 1, 1, 1),
|
||||||
|
darkColor = nil,
|
||||||
attachmentName = nil,
|
attachmentName = nil,
|
||||||
blendMode = BlendMode.normal
|
blendMode = BlendMode.normal
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,9 @@ function TransformConstraintData.new (name)
|
|||||||
bones = {},
|
bones = {},
|
||||||
target = nil,
|
target = nil,
|
||||||
rotateMix = 0, translateMix = 0, scaleMix = 0, shearMix = 0,
|
rotateMix = 0, translateMix = 0, scaleMix = 0, shearMix = 0,
|
||||||
offsetRotation = 0, offsetX = 0, offsetY = 0, offsetScaleX = 0, offsetScaleY = 0, offsetShearY = 0
|
offsetRotation = 0, offsetX = 0, offsetY = 0, offsetScaleX = 0, offsetScaleY = 0, offsetShearY = 0,
|
||||||
|
relative = false,
|
||||||
|
local_ = false
|
||||||
}
|
}
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|||||||
@ -33,6 +33,7 @@ local AttachmentType = {
|
|||||||
boundingbox = 1,
|
boundingbox = 1,
|
||||||
mesh = 2,
|
mesh = 2,
|
||||||
linkedmesh = 3,
|
linkedmesh = 3,
|
||||||
path = 4
|
path = 4,
|
||||||
|
point = 5
|
||||||
}
|
}
|
||||||
return AttachmentType
|
return AttachmentType
|
||||||
|
|||||||
@ -45,7 +45,7 @@ function MeshAttachment.new (name)
|
|||||||
self.region = nil
|
self.region = nil
|
||||||
self.path = nil
|
self.path = nil
|
||||||
self.regionUVs = nil
|
self.regionUVs = nil
|
||||||
self.worldVertices = nil
|
self.uvs = nil
|
||||||
self.triangles = nil
|
self.triangles = nil
|
||||||
self.color = Color.newWith(1, 1, 1, 1)
|
self.color = Color.newWith(1, 1, 1, 1)
|
||||||
self.hullLength = 0
|
self.hullLength = 0
|
||||||
@ -57,13 +57,6 @@ function MeshAttachment.new (name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function MeshAttachment:updateUVs ()
|
function MeshAttachment:updateUVs ()
|
||||||
local regionUVs = self.regionUVs
|
|
||||||
local verticesLength = #regionUVs
|
|
||||||
local worldVerticesLength = (verticesLength / 2) * 8
|
|
||||||
if not self.worldVertices or #self.worldVertices ~= worldVerticesLength then
|
|
||||||
self.worldVertices = utils.newNumberArray(worldVerticesLength)
|
|
||||||
end
|
|
||||||
|
|
||||||
local u = 0
|
local u = 0
|
||||||
local v = 0
|
local v = 0
|
||||||
local width = 0
|
local width = 0
|
||||||
@ -79,139 +72,28 @@ function MeshAttachment:updateUVs ()
|
|||||||
width = self.region.u2 - u;
|
width = self.region.u2 - u;
|
||||||
height = self.region.v2 - v;
|
height = self.region.v2 - v;
|
||||||
end
|
end
|
||||||
|
local regionUVs = self.regionUVs
|
||||||
|
if not self.uvs or (#self.uvs ~= #regionUVs) then self.uvs = utils.newNumberArray(#regionUVs) end
|
||||||
|
local uvs = self.uvs
|
||||||
if self.region and self.region.rotate then
|
if self.region and self.region.rotate then
|
||||||
local i = 0
|
local i = 0
|
||||||
local w = 2
|
local n = #uvs
|
||||||
while i < verticesLength do
|
while i < n do
|
||||||
self.worldVertices[w + 1] = u + regionUVs[i + 2] * width;
|
uvs[i + 1] = u + regionUVs[i + 2] * width;
|
||||||
self.worldVertices[w + 2] = v + height - regionUVs[i + 1] * height;
|
uvs[i + 2] = v + height - regionUVs[i + 1] * height;
|
||||||
i = i + 2
|
i = i + 2
|
||||||
w = w + 8
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local i = 0
|
local i = 0
|
||||||
local w = 2
|
local n = #uvs
|
||||||
while i < verticesLength do
|
while i < n do
|
||||||
self.worldVertices[w + 1] = u + regionUVs[i + 1] * width;
|
uvs[i + 1] = u + regionUVs[i + 1] * width;
|
||||||
self.worldVertices[w + 2] = v + regionUVs[i + 2] * height;
|
uvs[i + 2] = v + regionUVs[i + 2] * height;
|
||||||
i = i + 2
|
i = i + 2
|
||||||
w = w + 8
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function MeshAttachment:updateWorldVertices(slot, premultipliedAlpha)
|
|
||||||
local skeleton = slot.bone.skeleton
|
|
||||||
local skeletonColor = skeleton.color
|
|
||||||
local slotColor = slot.color
|
|
||||||
local meshColor = self.color
|
|
||||||
|
|
||||||
local alpha = skeletonColor.a * slotColor.a * meshColor.a
|
|
||||||
local multiplier = 1
|
|
||||||
if premultipliedAlpha then multiplier = alpha end
|
|
||||||
local color = self.tempColor
|
|
||||||
color:set(skeletonColor.r * slotColor.r * meshColor.r * multiplier,
|
|
||||||
skeletonColor.g * slotColor.g * meshColor.g * multiplier,
|
|
||||||
skeletonColor.b * slotColor.b * meshColor.b * multiplier,
|
|
||||||
alpha)
|
|
||||||
|
|
||||||
local deformArray = slot.attachmentVertices
|
|
||||||
local vertices = self.vertices
|
|
||||||
local worldVertices = self.worldVertices
|
|
||||||
local bones = self.bones
|
|
||||||
if not bones then
|
|
||||||
local verticesLength = #vertices
|
|
||||||
if #deformArray > 0 then vertices = deformArray end
|
|
||||||
local bone = slot.bone;
|
|
||||||
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 v = 0
|
|
||||||
local w = 0
|
|
||||||
while v < verticesLength 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
|
|
||||||
worldVertices[w + 5] = color.r
|
|
||||||
worldVertices[w + 6] = color.g
|
|
||||||
worldVertices[w + 7] = color.b
|
|
||||||
worldVertices[w + 8] = color.a
|
|
||||||
v = v + 2
|
|
||||||
w = w + 8
|
|
||||||
end
|
|
||||||
return worldVertices
|
|
||||||
end
|
|
||||||
|
|
||||||
local skeletonBones = skeleton.bones
|
|
||||||
if #deformArray == 0 then
|
|
||||||
local w = 0
|
|
||||||
local v = 0
|
|
||||||
local b = 0
|
|
||||||
local n = #bones
|
|
||||||
while v < n do
|
|
||||||
local wx = 0
|
|
||||||
local wy = 0
|
|
||||||
local nn = bones[v + 1];
|
|
||||||
v = v + 1
|
|
||||||
nn = nn + v
|
|
||||||
while v < nn 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
|
|
||||||
worldVertices[w + 5] = color.r
|
|
||||||
worldVertices[w + 6] = color.g
|
|
||||||
worldVertices[w + 7] = color.b
|
|
||||||
worldVertices[w + 8] = color.a
|
|
||||||
w = w + 8
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local deform = deformArray;
|
|
||||||
local w = 0
|
|
||||||
local v = 0
|
|
||||||
local b = 0
|
|
||||||
local f = 0
|
|
||||||
local n = #bones
|
|
||||||
while v < n do
|
|
||||||
local wx = 0
|
|
||||||
local wy = 0
|
|
||||||
local nn = bones[v + 1]
|
|
||||||
v = v + 1
|
|
||||||
nn = nn + v
|
|
||||||
while v < nn 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
|
|
||||||
b = b + 3
|
|
||||||
f = f + 2
|
|
||||||
v = v + 1
|
|
||||||
end
|
|
||||||
worldVertices[w + 1] = wx;
|
|
||||||
worldVertices[w + 2] = wy;
|
|
||||||
worldVertices[w + 5] = color.r;
|
|
||||||
worldVertices[w + 6] = color.g;
|
|
||||||
worldVertices[w + 7] = color.b;
|
|
||||||
worldVertices[w + 8] = color.a;
|
|
||||||
w = w + 8
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return worldVertices;
|
|
||||||
end
|
|
||||||
|
|
||||||
function MeshAttachment:applyDeform (sourceAttachment)
|
function MeshAttachment:applyDeform (sourceAttachment)
|
||||||
return self == sourceAttachment or (self.inheritDeform and self.parentMesh == sourceAttachment)
|
return self == sourceAttachment or (self.inheritDeform and self.parentMesh == sourceAttachment)
|
||||||
end
|
end
|
||||||
@ -224,7 +106,6 @@ function MeshAttachment:setParentMesh (parentMesh)
|
|||||||
self.regionUVs = parentMesh.regionUVs
|
self.regionUVs = parentMesh.regionUVs
|
||||||
self.triangles = parentMesh.triangles
|
self.triangles = parentMesh.triangles
|
||||||
self.hullLength = parentMesh.hullLength
|
self.hullLength = parentMesh.hullLength
|
||||||
self.worldVerticesLength = parentMesh.worldVerticesLength
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
68
spine-lua/attachments/PointAttachment.lua
Normal file
68
spine-lua/attachments/PointAttachment.lua
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Spine Runtimes Software License v2.5
|
||||||
|
--
|
||||||
|
-- Copyright (c) 2013-2016, Esoteric Software
|
||||||
|
-- All rights reserved.
|
||||||
|
--
|
||||||
|
-- You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||||
|
-- non-transferable license to use, install, execute, and perform the Spine
|
||||||
|
-- Runtimes software and derivative works solely for personal or internal
|
||||||
|
-- use. Without the written permission of Esoteric Software (see Section 2 of
|
||||||
|
-- the Spine Software License Agreement), you may not (a) modify, translate,
|
||||||
|
-- adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||||
|
-- create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||||
|
-- delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||||
|
-- or other intellectual property or proprietary rights notices on or in the
|
||||||
|
-- Software, including any copy thereof. Redistributions in binary or source
|
||||||
|
-- form must include this license and terms.
|
||||||
|
--
|
||||||
|
-- THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, 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 math_cos = math.cos
|
||||||
|
local math_sin = math.sin
|
||||||
|
|
||||||
|
local PointAttachment = {}
|
||||||
|
PointAttachment.__index = PointAttachment
|
||||||
|
setmetatable(PointAttachment, { __index = VertexAttachment })
|
||||||
|
|
||||||
|
function PointAttachment.new (name)
|
||||||
|
if not name then error("name cannot be nil", 2) end
|
||||||
|
|
||||||
|
local self = VertexAttachment.new(name, AttachmentType.point)
|
||||||
|
self.x = 0
|
||||||
|
self.y = 0
|
||||||
|
self.rotation = 0
|
||||||
|
self.color = Color.newWith(0.38, 0.94, 0, 1)
|
||||||
|
setmetatable(self, BoundingBoxAttachment)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function PointAttachment:computeWorldPosition(bone, point)
|
||||||
|
point.x = self.x * bone.a + self.y * bone.b + bone.worldX
|
||||||
|
point.y = self.x * bone.c + self.y * bone.d + bone.worldY
|
||||||
|
return point
|
||||||
|
end
|
||||||
|
|
||||||
|
function PointAttachment:computeWorldRotation(bone)
|
||||||
|
local cos = math_cos(math_rad(self.rotation))
|
||||||
|
local sin = math_sin(math_rad(self.rotation))
|
||||||
|
local x = cos * bone.a + sin * bone.b
|
||||||
|
local y = cos * bone.c + sin * bone.d
|
||||||
|
return math_deg(math_atan2(y, x))
|
||||||
|
end
|
||||||
|
|
||||||
|
return PointAttachment
|
||||||
@ -87,6 +87,51 @@ local RegionAttachment = {}
|
|||||||
RegionAttachment.__index = RegionAttachment
|
RegionAttachment.__index = RegionAttachment
|
||||||
setmetatable(RegionAttachment, { __index = Attachment })
|
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)
|
function RegionAttachment.new (name)
|
||||||
if not name then error("name cannot be nil", 2) end
|
if not name then error("name cannot be nil", 2) end
|
||||||
|
|
||||||
@ -103,36 +148,13 @@ function RegionAttachment.new (name)
|
|||||||
self.rendererObject = nil
|
self.rendererObject = nil
|
||||||
self.region = nil
|
self.region = nil
|
||||||
self.offset = Utils.newNumberArray(8)
|
self.offset = Utils.newNumberArray(8)
|
||||||
self.vertices = Utils.newNumberArray(8 * 4)
|
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)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function RegionAttachment:setRegion (region)
|
|
||||||
local vertices = self.vertices
|
|
||||||
if region.rotate then
|
|
||||||
vertices[U2] = region.u
|
|
||||||
vertices[V2] = region.v2
|
|
||||||
vertices[U3] = region.u
|
|
||||||
vertices[V3] = region.v
|
|
||||||
vertices[U4] = region.u2
|
|
||||||
vertices[V4] = region.v
|
|
||||||
vertices[U1] = region.u2
|
|
||||||
vertices[V1] = region.v2
|
|
||||||
else
|
|
||||||
vertices[U1] = region.u
|
|
||||||
vertices[V1] = region.v2
|
|
||||||
vertices[U2] = region.u
|
|
||||||
vertices[V2] = region.v
|
|
||||||
vertices[U3] = region.u2
|
|
||||||
vertices[V3] = region.v
|
|
||||||
vertices[U4] = region.u2
|
|
||||||
vertices[V4] = region.v2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function RegionAttachment:updateOffset ()
|
function RegionAttachment:updateOffset ()
|
||||||
local regionScaleX = self.width / self.region.originalWidth * self.scaleX
|
local regionScaleX = self.width / self.region.originalWidth * self.scaleX
|
||||||
local regionScaleY = self.height / self.region.originalHeight * self.scaleY
|
local regionScaleY = self.height / self.region.originalHeight * self.scaleY
|
||||||
@ -162,23 +184,32 @@ function RegionAttachment:updateOffset ()
|
|||||||
offset[OY4] = localYCos + localX2Sin
|
offset[OY4] = localYCos + localX2Sin
|
||||||
end
|
end
|
||||||
|
|
||||||
function RegionAttachment:updateWorldVertices (slot, premultipliedAlpha)
|
function RegionAttachment:setRegion (region)
|
||||||
local skeleton = slot.bone.skeleton
|
local uvs = self.uvs
|
||||||
local skeletonColor = skeleton.color
|
if region.rotate then
|
||||||
local slotColor = slot.color
|
uvs[3] = region.u
|
||||||
local regionColor = self.color
|
uvs[4] = region.v2
|
||||||
local alpha = skeletonColor.a * slotColor.a * regionColor.a
|
uvs[5] = region.u
|
||||||
local multiplier = alpha
|
uvs[6] = region.v
|
||||||
if premultipliedAlpha then multiplier = 1 end
|
uvs[7] = region.u2
|
||||||
local color = self.tempColor
|
uvs[8] = region.v
|
||||||
color:set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
|
uvs[1] = region.u2
|
||||||
skeletonColor.g * slotColor.g * regionColor.g * multiplier,
|
uvs[2] = region.v2
|
||||||
skeletonColor.b * slotColor.b * regionColor.b * multiplier,
|
else
|
||||||
alpha)
|
uvs[1] = region.u
|
||||||
|
uvs[2] = region.v2
|
||||||
|
uvs[3] = region.u
|
||||||
|
uvs[4] = region.v
|
||||||
|
uvs[5] = region.u2
|
||||||
|
uvs[6] = region.v
|
||||||
|
uvs[7] = region.u2
|
||||||
|
uvs[8] = region.v2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local vertices = self.vertices
|
function RegionAttachment:computeWorldVertices (bone, worldVertices, offset, stride)
|
||||||
local offset = self.offset
|
offset = offset + 1
|
||||||
local bone = slot.bone
|
local vertexOffset = self.offset
|
||||||
local x = bone.worldX
|
local x = bone.worldX
|
||||||
local y = bone.worldY
|
local y = bone.worldY
|
||||||
local a = bone.a
|
local a = bone.a
|
||||||
@ -188,43 +219,28 @@ function RegionAttachment:updateWorldVertices (slot, premultipliedAlpha)
|
|||||||
local offsetX = 0
|
local offsetX = 0
|
||||||
local offsetY = 0
|
local offsetY = 0
|
||||||
|
|
||||||
offsetX = offset[OX1]
|
offsetX = vertexOffset[OX1]
|
||||||
offsetY = offset[OY1]
|
offsetY = vertexOffset[OY1]
|
||||||
vertices[X1] = offsetX * a + offsetY * b + x -- br
|
worldVertices[offset] = offsetX * a + offsetY * b + x -- br
|
||||||
vertices[Y1] = offsetX * c + offsetY * d + y
|
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||||
vertices[C1R] = color.r
|
offset = offset + stride
|
||||||
vertices[C1G] = color.g
|
|
||||||
vertices[C1B] = color.b
|
|
||||||
vertices[C1A] = color.a
|
|
||||||
|
|
||||||
offsetX = offset[OX2]
|
offsetX = vertexOffset[OX2]
|
||||||
offsetY = offset[OY2]
|
offsetY = vertexOffset[OY2]
|
||||||
vertices[X2] = offsetX * a + offsetY * b + x -- bl
|
worldVertices[offset] = offsetX * a + offsetY * b + x -- bl
|
||||||
vertices[Y2] = offsetX * c + offsetY * d + y
|
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||||
vertices[C2R] = color.r
|
offset = offset + stride
|
||||||
vertices[C2G] = color.g
|
|
||||||
vertices[C2B] = color.b
|
|
||||||
vertices[C2A] = color.a
|
|
||||||
|
|
||||||
offsetX = offset[OX3]
|
offsetX = vertexOffset[OX3]
|
||||||
offsetY = offset[OY3]
|
offsetY = vertexOffset[OY3]
|
||||||
vertices[X3] = offsetX * a + offsetY * b + x -- ul
|
worldVertices[offset] = offsetX * a + offsetY * b + x -- ul
|
||||||
vertices[Y3] = offsetX * c + offsetY * d + y
|
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||||
vertices[C3R] = color.r
|
offset = offset + stride
|
||||||
vertices[C3G] = color.g
|
|
||||||
vertices[C3B] = color.b
|
|
||||||
vertices[C3A] = color.a
|
|
||||||
|
|
||||||
offsetX = offset[OX4]
|
offsetX = vertexOffset[OX4]
|
||||||
offsetY = offset[OY4]
|
offsetY = vertexOffset[OY4]
|
||||||
vertices[X4] = offsetX * a + offsetY * b + x -- ur
|
worldVertices[offset] = offsetX * a + offsetY * b + x -- ur
|
||||||
vertices[Y4] = offsetX * c + offsetY * d + y
|
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||||
vertices[C4R] = color.r
|
|
||||||
vertices[C4G] = color.g
|
|
||||||
vertices[C4B] = color.b
|
|
||||||
vertices[C4A] = color.a
|
|
||||||
|
|
||||||
return vertices
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return RegionAttachment
|
return RegionAttachment
|
||||||
|
|||||||
@ -50,12 +50,8 @@ function VertexAttachment.new (name, attachmentType)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function VertexAttachment:computeWorldVertices (slot, worldVertices)
|
function VertexAttachment:computeWorldVertices (slot, start, count, worldVertices, offset, stride)
|
||||||
self:computeWorldVerticesWith(slot, 0, self.worldVerticesLength, worldVertices, 0)
|
count = offset + (count / 2) * stride
|
||||||
end
|
|
||||||
|
|
||||||
function VertexAttachment:computeWorldVerticesWith (slot, start, count, worldVertices, offset)
|
|
||||||
count = count + offset
|
|
||||||
local skeleton = slot.bone.skeleton
|
local skeleton = slot.bone.skeleton
|
||||||
local deformArray = slot.attachmentVertices
|
local deformArray = slot.attachmentVertices
|
||||||
local vertices = self.vertices
|
local vertices = self.vertices
|
||||||
@ -77,7 +73,7 @@ function VertexAttachment:computeWorldVerticesWith (slot, start, count, worldVer
|
|||||||
worldVertices[w + 1] = vx * a + vy * b + x
|
worldVertices[w + 1] = vx * a + vy * b + x
|
||||||
worldVertices[w + 2] = vx * c + vy * d + y
|
worldVertices[w + 2] = vx * c + vy * d + y
|
||||||
v = v + 2
|
v = v + 2
|
||||||
w = w + 2
|
w = w + stride
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -112,7 +108,7 @@ function VertexAttachment:computeWorldVerticesWith (slot, start, count, worldVer
|
|||||||
end
|
end
|
||||||
worldVertices[w + 1] = wx
|
worldVertices[w + 1] = wx
|
||||||
worldVertices[w + 2] = wy
|
worldVertices[w + 2] = wy
|
||||||
w = w + 2
|
w = w + stride
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local deform = deformArray
|
local deform = deformArray
|
||||||
@ -139,7 +135,7 @@ function VertexAttachment:computeWorldVerticesWith (slot, start, count, worldVer
|
|||||||
end
|
end
|
||||||
worldVertices[w + 1] = wx
|
worldVertices[w + 1] = wx
|
||||||
worldVertices[w + 2] = wy
|
worldVertices[w + 2] = wy
|
||||||
w = w + 2
|
w = w + stride
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user