[lua][corona] Ported 3.6 changes except TransformConstraint update

This commit is contained in:
badlogic 2017-02-22 14:40:55 +01:00
parent 0b8913691a
commit 0a2ca732cd
18 changed files with 488 additions and 295 deletions

View File

@ -75,6 +75,7 @@ function loadSkeleton(atlasFile, jsonFile, x, y, scale, animation, skin)
return { skeleton = skeleton, state = animationState }
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("raptor.atlas", "raptor.json", 200, 300, 0.25, "walk"))
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("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)
Runtime:addEventListener("enterFrame", function (event)

View File

@ -43,6 +43,7 @@ spine.RegionAttachment = require "spine-lua.attachments.RegionAttachment"
spine.MeshAttachment = require "spine-lua.attachments.MeshAttachment"
spine.VertexAttachment = require "spine-lua.attachments.VertexAttachment"
spine.PathAttachment = require "spine-lua.attachments.PathAttachment"
spine.PointAttachment = require "spine-lua.attachments.PointAttachment"
spine.Skeleton = require "spine-lua.Skeleton"
spine.Bone = require "spine-lua.Bone"
spine.Slot = require "spine-lua.Slot"
@ -86,6 +87,7 @@ spine.Skeleton.new = function(skeletonData, group)
self.drawingGroup = nil
self.premultipliedAlpha = false
self.batches = 0
self.tempColor = spine.Color.newWith(1, 1, 1, 1)
return self
end
@ -108,6 +110,8 @@ local function toCoronaBlendMode(blendMode)
end
end
local worldVertices = spine.utils.newNumberArray(10000 * 8)
function spine.Skeleton:updateWorldTransform()
spine.Skeleton.updateWorldTransform_super(self)
local premultipliedAlpha = self.premultipliedAlpha
@ -125,7 +129,7 @@ function spine.Skeleton:updateWorldTransform()
local groupVertices = {}
local groupIndices = {}
local groupUvs = {}
local color = nil
local color = self.tempColor
local lastColor = nil
local texture = nil
local lastTexture = nil
@ -134,19 +138,20 @@ function spine.Skeleton:updateWorldTransform()
for i,slot in ipairs(drawOrder) do
local attachment = slot.attachment
local vertices = nil
local numVertices = 0
local indices = nil
if attachment 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
texture = attachment.region.renderObject.texture
color = { vertices[5], vertices[6], vertices[7], vertices[8]}
blendMode = toCoronaBlendMode(slot.data.blendMode)
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
texture = attachment.region.renderObject.texture
color = { vertices[5], vertices[6], vertices[7], vertices[8] }
blendMode = toCoronaBlendMode(slot.data.blendMode)
end
@ -165,7 +170,7 @@ function spine.Skeleton:updateWorldTransform()
groupIndices = {}
end
self:batch(vertices, indices, groupVertices, groupUvs, groupIndices)
self:batch(vertices, numVertices, indices, groupVertices, groupUvs, groupIndices)
end
end
end
@ -175,22 +180,87 @@ function spine.Skeleton:updateWorldTransform()
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)
mesh = display.newMesh(drawingGroup, 0, 0, {
local mesh = display.newMesh(drawingGroup, 0, 0, {
mode = "indexed",
vertices = groupVertices,
uvs = groupUvs,
indices = groupIndices
})
mesh.fill = texture
mesh:setFillColor(color[1], color[2], color[3])
mesh.alpha = color[4]
mesh:setFillColor(color.r, color.g, color.b)
mesh.alpha = color.a
mesh.blendMode = blendMode
mesh:translate(mesh.path:getVertexOffset())
self.batches = self.batches + 1
end
function spine.Skeleton:batch(vertices, indices, groupVertices, groupUvs, groupIndices)
function spine.Skeleton:batch(vertices, numVertices, indices, groupVertices, groupUvs, groupIndices)
local numIndices = #indices
local i = 1
local indexStart = #groupIndices + 1
@ -204,16 +274,15 @@ function spine.Skeleton:batch(vertices, indices, groupVertices, groupUvs, groupI
end
i = 1
local numVertices = #vertices
local vertexStart = #groupVertices + 1
local vertexEnd = vertexStart + numVertices / 4
local vertexEnd = vertexStart + numVertices * 2
while vertexStart < vertexEnd do
groupVertices[vertexStart] = vertices[i]
groupVertices[vertexStart+1] = vertices[i+1]
groupUvs[vertexStart] = vertices[i+2]
groupUvs[vertexStart+1] = vertices[i+3]
vertexStart = vertexStart + 2
i = i + 8
i = i + 4
end
end

View File

@ -118,7 +118,8 @@ Animation.TimelineType = {
attachment = 4, color = 5, deform = 6,
event = 7, drawOrder = 8,
ikConstraint = 9, transformConstraint = 10,
pathConstraintPosition = 11, pathConstraintSpacing = 12, pathConstraintMix = 13
pathConstraintPosition = 11, pathConstraintSpacing = 12, pathConstraintMix = 13,
twoColor = 14
}
local TimelineType = Animation.TimelineType
local SHL_24 = 16777216
@ -562,6 +563,108 @@ function Animation.ColorTimeline.new (frameCount)
return self
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 = {}
function Animation.AttachmentTimeline.new (frameCount)
local self = {

View File

@ -35,6 +35,7 @@ local RegionAttachment = require "spine-lua.attachments.RegionAttachment"
local BoundingBoxAttachment = require "spine-lua.attachments.BoundingBoxAttachment"
local MeshAttachment = require "spine-lua.attachments.MeshAttachment"
local PathAttachment = require "spine-lua.attachments.PathAttachment"
local PointAttachment = require "spine-lua.attachments.PointAttachment"
local TextureAtlas = require "spine-lua.TextureAtlas"
local AtlasAttachmentLoader = {}
@ -79,4 +80,8 @@ function AtlasAttachmentLoader:newPathAttachment(skin, name)
return PathAttachment.new(name)
end
function AtlasAttachmentLoader:newPointAttachment(skin, name)
return PointAttachment.new(name)
end
return AtlasAttachmentLoader

View File

@ -33,6 +33,7 @@ local RegionAttachment = require "spine-lua.attachments.RegionAttachment"
local BoundingBoxAttachment = require "spine-lua.attachments.BoundingBoxAttachment"
local MeshAttachment = require "spine-lua.attachments.MeshAttachment"
local PathAttachment = require "spine-lua.attachments.PathAttachment"
local PointAttachment = require "spine-lua.attachments.PointAttachment"
local AttachmentLoader = {}
function AttachmentLoader.new ()
@ -58,6 +59,10 @@ function AttachmentLoader.new ()
return PathAttachment.new(name)
end
function self:newPointAttachment(skin, name)
return PointAttachment.new(name)
end
return self
end
return AttachmentLoader

View File

@ -240,45 +240,6 @@ function Bone:getWorldScaleY ()
return math_sqrt(self.b * self.b + self.d * self.d)
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 ()
local parent = self.parent
if parent == nil then
@ -344,4 +305,31 @@ function Bone:localToWorld (localCoords)
return localCoords
end
function Bone:worldToLocalRotation (worldRotation)
local sin = math_sin(math_rad(worldRotation))
local cos = math_cos(math_rad(worldRotation))
return math_deg(math_atan2(self.a * sin - self.c * cos, self.d * cos - self.b * sin))
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

View File

@ -117,13 +117,13 @@ function PathConstraint:update ()
local n = spacesCount - 1
while i < n do
local bone = bones[i + 1];
local length = bone.data.length
local x = length * bone.a
local y = length * bone.c
length = math_sqrt(x * x + y * y)
local setupLength = bone.data.length
local x = setupLength * bone.a
local y = setupLength * bone.c
local length = math_sqrt(x * x + y * y)
if scale then lengths[i + 1] = length end
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
else
local i = 1
@ -254,14 +254,14 @@ function PathConstraint:computeWorldPositions (path, spacesCount, tangents, perc
elseif p < 0 then
if prevCurve ~= PathConstraint.BEFORE then
prevCurve = PathConstraint.BEFORE
path:computeWorldVerticesWith(target, 2, 4, world, 0)
path:computeWorldVertices(target, 2, 4, world, 0, 2)
end
self:addBeforePosition(p, world, 0, out, o)
skip = true
elseif p > pathLength then
if prevCurve ~= PathConstraint.AFTER then
prevCurve = PathConstraint.AFTER
path:computeWorldVerticesWith(target, verticesLength - 6, 4, world, 0)
path:computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2)
end
self:addAfterPosition(p - pathLength, world, 0, out, o)
skip = true
@ -285,10 +285,10 @@ function PathConstraint:computeWorldPositions (path, spacesCount, tangents, perc
if curve ~= prevCurve then
prevCurve = curve
if closed and curve == curveCount then
path:computeWorldVerticesWith(target, verticesLength - 4, 4, world, 0)
path:computeWorldVerticesWith(target, 0, 4, world, 4)
path:computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2)
path:computeWorldVertices(target, 0, 4, world, 4, 2)
else
path:computeWorldVerticesWith(target, curve * 6 + 2, 8, world, 0)
path:computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2)
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))
@ -304,15 +304,15 @@ function PathConstraint:computeWorldPositions (path, spacesCount, tangents, perc
if closed then
verticesLength = verticesLength + 2
world = utils.setArraySize(self.world, verticesLength)
path:computeWorldVerticesWith(target, 2, verticesLength - 4, world, 0)
path:computeWorldVerticesWith(target, 0, 2, world, verticesLength - 4)
path:computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2)
path:computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2)
world[verticesLength - 2 + 1] = world[0 + 1]
world[verticesLength - 1 + 1] = world[1 + 1]
else
curveCount = curveCount - 1
verticesLength = verticesLength - 4;
world = utils.setArraySize(self.world, verticesLength)
path:computeWorldVerticesWith(target, 2, verticesLength, world, 0)
path:computeWorldVertices(target, 2, verticesLength, world, 0, 2)
end
-- Curve lengths.

View File

@ -206,7 +206,7 @@ function Skeleton:sortPathConstraint(constraint)
if self.data.defaultSkin and not (self.data.defaultSkin == skin) then
self:sortPathConstraintAttachment(self.data.defaultSkin, slotIndex, slotBone)
end
for ii,skin in ipairs(self.data.skins) do
for i,skin in ipairs(self.data.skins) do
self:sortPathConstraintAttachment(skin, slotIndex, slotBone)
end
@ -214,7 +214,7 @@ function Skeleton:sortPathConstraint(constraint)
if attachment.type == AttachmentType.path then self:sortPathConstraintAttachmentWith(attachment, slotBone) end
local constrained = constraint.bones
for ii,bone in ipairs(constrained) do
for i,bone in ipairs(constrained) do
self:sortBone(bone)
end
@ -233,8 +233,23 @@ function Skeleton:sortTransformConstraint(constraint)
self:sortBone(constraint.target)
local constrained = constraint.bones
for ii,bone in ipairs(constrained) do
self:sortBone(bone)
if constraint.data.local_ then
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
table_insert(self._updateCache, constraint)
@ -482,12 +497,16 @@ function Skeleton:getBounds(offset, size)
local maxX = -99999999
local maxY = -99999999
for i, slot in ipairs(drawOrder) do
local vertices = nil
local vertices = {}
local attachment = slot.attachment
if attachment and (attachment.type == AttachmentType.region or attachment.type == AttachmentType.mesh) then
vertices = attachment:updateWorldVertices(slot, false);
if attachment then
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
if vertices then
if #vertices > 0 then
local nn = #vertices
local ii = 1
while ii <= nn do
@ -497,7 +516,7 @@ function Skeleton:getBounds(offset, size)
minY = math_min(minY, y)
maxX = math_max(maxX, x)
maxY = math_max(maxY, y)
ii = ii + 8
ii = ii + 2
end
end
end

View File

@ -68,7 +68,7 @@ function SkeletonBounds:update (skeleton, updateAabb)
local polygon = {}
table_insert(polygons, polygon)
boundingBox:computeWorldVertices(slot, polygon)
boundingBox:computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2)
end
end

View File

@ -131,6 +131,15 @@ function SkeletonJson.new (attachmentLoader)
tonumber(color:sub(7, 8), 16) / 255)
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.blendMode = BlendMode[getValue(slotMap, "blend", "normal")]
@ -380,6 +389,23 @@ function SkeletonJson.new (attachmentLoader)
tonumber(color:sub(7, 8), 16) / 255)
end
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
error("Unknown attachment type: " .. type .. " (" .. name .. ")")

View File

@ -43,6 +43,7 @@ function Slot.new (data, bone)
data = data,
bone = bone,
color = Color.newWith(1, 1, 1, 1),
darkColor = nil,
attachment = nil,
attachmentTime = 0,
attachmentVertices = {},
@ -50,6 +51,8 @@ function Slot.new (data, bone)
}
setmetatable(self, Slot)
if data.darkColor then self.darkColor = Color.newWith(1, 1, 1, 1) end
self:setToSetupPose()
return self
@ -74,6 +77,7 @@ function Slot:setToSetupPose ()
local data = self.data
self.color:setFrom(data.color)
if self.darkColor then self.darkColor:setFrom(data.darkColor) end
local attachment = nil
if data.attachmentName then

View File

@ -46,6 +46,7 @@ function SlotData.new (index, name, boneData)
name = name,
boneData = boneData,
color = Color.newWith(1, 1, 1, 1),
darkColor = nil,
attachmentName = nil,
blendMode = BlendMode.normal
}

View File

@ -38,7 +38,9 @@ function TransformConstraintData.new (name)
bones = {},
target = nil,
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

View File

@ -33,6 +33,7 @@ local AttachmentType = {
boundingbox = 1,
mesh = 2,
linkedmesh = 3,
path = 4
path = 4,
point = 5
}
return AttachmentType

View File

@ -45,7 +45,7 @@ function MeshAttachment.new (name)
self.region = nil
self.path = nil
self.regionUVs = nil
self.worldVertices = nil
self.uvs = nil
self.triangles = nil
self.color = Color.newWith(1, 1, 1, 1)
self.hullLength = 0
@ -57,13 +57,6 @@ function MeshAttachment.new (name)
end
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 v = 0
local width = 0
@ -79,139 +72,28 @@ function MeshAttachment:updateUVs ()
width = self.region.u2 - u;
height = self.region.v2 - v;
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
local i = 0
local w = 2
while i < verticesLength do
self.worldVertices[w + 1] = u + regionUVs[i + 2] * width;
self.worldVertices[w + 2] = v + height - regionUVs[i + 1] * height;
local n = #uvs
while i < n do
uvs[i + 1] = u + regionUVs[i + 2] * width;
uvs[i + 2] = v + height - regionUVs[i + 1] * height;
i = i + 2
w = w + 8
end
else
local i = 0
local w = 2
while i < verticesLength do
self.worldVertices[w + 1] = u + regionUVs[i + 1] * width;
self.worldVertices[w + 2] = v + regionUVs[i + 2] * height;
local n = #uvs
while i < n do
uvs[i + 1] = u + regionUVs[i + 1] * width;
uvs[i + 2] = v + regionUVs[i + 2] * height;
i = i + 2
w = w + 8
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)
return self == sourceAttachment or (self.inheritDeform and self.parentMesh == sourceAttachment)
end
@ -224,7 +106,6 @@ function MeshAttachment:setParentMesh (parentMesh)
self.regionUVs = parentMesh.regionUVs
self.triangles = parentMesh.triangles
self.hullLength = parentMesh.hullLength
self.worldVerticesLength = parentMesh.worldVerticesLength
end
end

View 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

View File

@ -87,6 +87,51 @@ local RegionAttachment = {}
RegionAttachment.__index = RegionAttachment
setmetatable(RegionAttachment, { __index = Attachment })
RegionAttachment.OX1 = 1
RegionAttachment.OY1 = 2
RegionAttachment.OX2 = 3
RegionAttachment.OY2 = 4
RegionAttachment.OX3 = 5
RegionAttachment.OY3 = 6
RegionAttachment.OX4 = 7
RegionAttachment.OY4 = 8
RegionAttachment.X1 = 1
RegionAttachment.Y1 = 2
RegionAttachment.U1 = 3
RegionAttachment.V1 = 4
RegionAttachment.C1R = 5
RegionAttachment.C1G = 6
RegionAttachment.C1B = 7
RegionAttachment.C1A = 8
RegionAttachment.X2 = 9
RegionAttachment.Y2 = 10
RegionAttachment.U2 = 11
RegionAttachment.V2 = 12
RegionAttachment.C2R = 13
RegionAttachment.C2G = 14
RegionAttachment.C2B = 15
RegionAttachment.C2A = 16
RegionAttachment.X3 = 17
RegionAttachment.Y3 = 18
RegionAttachment.U3 = 19
RegionAttachment.V3 = 20
RegionAttachment.C3R = 21
RegionAttachment.C3G = 22
RegionAttachment.C3B = 23
RegionAttachment.C3A = 24
RegionAttachment.X4 = 25
RegionAttachment.Y4 = 26
RegionAttachment.U4 = 27
RegionAttachment.V4 = 28
RegionAttachment.C4R = 29
RegionAttachment.C4G = 30
RegionAttachment.C4B = 31
RegionAttachment.C4A = 32
function RegionAttachment.new (name)
if not name then error("name cannot be nil", 2) end
@ -103,36 +148,13 @@ function RegionAttachment.new (name)
self.rendererObject = nil
self.region = nil
self.offset = Utils.newNumberArray(8)
self.vertices = Utils.newNumberArray(8 * 4)
self.uvs = Utils.newNumberArray(8)
self.tempColor = Color.newWith(1, 1, 1, 1)
setmetatable(self, RegionAttachment)
return self
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 ()
local regionScaleX = self.width / self.region.originalWidth * self.scaleX
local regionScaleY = self.height / self.region.originalHeight * self.scaleY
@ -162,23 +184,32 @@ function RegionAttachment:updateOffset ()
offset[OY4] = localYCos + localX2Sin
end
function RegionAttachment:updateWorldVertices (slot, premultipliedAlpha)
local skeleton = slot.bone.skeleton
local skeletonColor = skeleton.color
local slotColor = slot.color
local regionColor = self.color
local alpha = skeletonColor.a * slotColor.a * regionColor.a
local multiplier = alpha
if premultipliedAlpha then multiplier = 1 end
local color = self.tempColor
color:set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
skeletonColor.g * slotColor.g * regionColor.g * multiplier,
skeletonColor.b * slotColor.b * regionColor.b * multiplier,
alpha)
function RegionAttachment:setRegion (region)
local uvs = self.uvs
if region.rotate then
uvs[3] = region.u
uvs[4] = region.v2
uvs[5] = region.u
uvs[6] = region.v
uvs[7] = region.u2
uvs[8] = region.v
uvs[1] = region.u2
uvs[2] = region.v2
else
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
local offset = self.offset
local bone = slot.bone
function RegionAttachment:computeWorldVertices (bone, worldVertices, offset, stride)
offset = offset + 1
local vertexOffset = self.offset
local x = bone.worldX
local y = bone.worldY
local a = bone.a
@ -188,43 +219,28 @@ function RegionAttachment:updateWorldVertices (slot, premultipliedAlpha)
local offsetX = 0
local offsetY = 0
offsetX = offset[OX1]
offsetY = offset[OY1]
vertices[X1] = offsetX * a + offsetY * b + x -- br
vertices[Y1] = offsetX * c + offsetY * d + y
vertices[C1R] = color.r
vertices[C1G] = color.g
vertices[C1B] = color.b
vertices[C1A] = color.a
offsetX = vertexOffset[OX1]
offsetY = vertexOffset[OY1]
worldVertices[offset] = offsetX * a + offsetY * b + x -- br
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
offset = offset + stride
offsetX = offset[OX2]
offsetY = offset[OY2]
vertices[X2] = offsetX * a + offsetY * b + x -- bl
vertices[Y2] = offsetX * c + offsetY * d + y
vertices[C2R] = color.r
vertices[C2G] = color.g
vertices[C2B] = color.b
vertices[C2A] = color.a
offsetX = vertexOffset[OX2]
offsetY = vertexOffset[OY2]
worldVertices[offset] = offsetX * a + offsetY * b + x -- bl
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
offset = offset + stride
offsetX = offset[OX3]
offsetY = offset[OY3]
vertices[X3] = offsetX * a + offsetY * b + x -- ul
vertices[Y3] = offsetX * c + offsetY * d + y
vertices[C3R] = color.r
vertices[C3G] = color.g
vertices[C3B] = color.b
vertices[C3A] = color.a
offsetX = vertexOffset[OX3]
offsetY = vertexOffset[OY3]
worldVertices[offset] = offsetX * a + offsetY * b + x -- ul
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
offset = offset + stride
offsetX = offset[OX4]
offsetY = offset[OY4]
vertices[X4] = offsetX * a + offsetY * b + x -- ur
vertices[Y4] = offsetX * c + offsetY * d + y
vertices[C4R] = color.r
vertices[C4G] = color.g
vertices[C4B] = color.b
vertices[C4A] = color.a
return vertices
offsetX = vertexOffset[OX4]
offsetY = vertexOffset[OY4]
worldVertices[offset] = offsetX * a + offsetY * b + x -- ur
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
end
return RegionAttachment

View File

@ -50,12 +50,8 @@ function VertexAttachment.new (name, attachmentType)
return self
end
function VertexAttachment:computeWorldVertices (slot, worldVertices)
self:computeWorldVerticesWith(slot, 0, self.worldVerticesLength, worldVertices, 0)
end
function VertexAttachment:computeWorldVerticesWith (slot, start, count, worldVertices, offset)
count = count + offset
function VertexAttachment:computeWorldVertices (slot, start, count, worldVertices, offset, stride)
count = offset + (count / 2) * stride
local skeleton = slot.bone.skeleton
local deformArray = slot.attachmentVertices
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 + 2] = vx * c + vy * d + y
v = v + 2
w = w + 2
w = w + stride
end
return
end
@ -112,7 +108,7 @@ function VertexAttachment:computeWorldVerticesWith (slot, start, count, worldVer
end
worldVertices[w + 1] = wx
worldVertices[w + 2] = wy
w = w + 2
w = w + stride
end
else
local deform = deformArray
@ -139,7 +135,7 @@ function VertexAttachment:computeWorldVerticesWith (slot, start, count, worldVer
end
worldVertices[w + 1] = wx
worldVertices[w + 2] = wy
w = w + 2
w = w + stride
end
end
end