mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[lua] Fixed SkeletonClipping. [corona] Refactored rendering, should be a bit faster as it avoids a bunch of copies. Fixed RegionAttachment to be in alignement with reference implementation
This commit is contained in:
parent
1fafbd0cb7
commit
8123422f33
@ -77,12 +77,12 @@ end
|
|||||||
|
|
||||||
-- table.insert(skeletons, loadSkeleton("test.atlas", "test.json", 240, 300, 0.4, "animation"))
|
-- table.insert(skeletons, loadSkeleton("test.atlas", "test.json", 240, 300, 0.4, "animation"))
|
||||||
table.insert(skeletons, loadSkeleton("coin.atlas", "coin.json", 240, 300, 0.4, "rotate"))
|
table.insert(skeletons, loadSkeleton("coin.atlas", "coin.json", 240, 300, 0.4, "rotate"))
|
||||||
--[[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"))
|
||||||
table.insert(skeletons, loadSkeleton("stretchyman.atlas", "stretchyman.json", 40, 300, 0.5, "sneak"))
|
table.insert(skeletons, loadSkeleton("stretchyman.atlas", "stretchyman.json", 40, 300, 0.5, "sneak"))
|
||||||
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 triangulator = spine.Triangulator.new()
|
local triangulator = spine.Triangulator.new()
|
||||||
local polygon = { 411, 219, 199, 230, 161, 362, 534, 407, 346, 305, 596, 265 }
|
local polygon = { 411, 219, 199, 230, 161, 362, 534, 407, 346, 305, 596, 265 }
|
||||||
@ -90,6 +90,12 @@ local indices = triangulator:triangulate(polygon)
|
|||||||
print(indices)
|
print(indices)
|
||||||
print(triangulator:decompose(polygon, indices))
|
print(triangulator:decompose(polygon, indices))
|
||||||
|
|
||||||
|
local skeletonClipping = spine.SkeletonClipping.new()
|
||||||
|
local polygon2 = {0, 0, 100, 0, 100, 100, 0, 100 }
|
||||||
|
skeletonClipping:makeClockwise(polygon2)
|
||||||
|
print(polygon2)
|
||||||
|
|
||||||
|
|
||||||
local bounds = spine.SkeletonBounds.new()
|
local bounds = spine.SkeletonBounds.new()
|
||||||
skeletons[1].skeleton:updateWorldTransform()
|
skeletons[1].skeleton:updateWorldTransform()
|
||||||
bounds:update(skeletons[1].skeleton, true)
|
bounds:update(skeletons[1].skeleton, true)
|
||||||
@ -110,7 +116,7 @@ Runtime:addEventListener("enterFrame", function (event)
|
|||||||
state = skeletons[activeSkeleton].state
|
state = skeletons[activeSkeleton].state
|
||||||
|
|
||||||
state:update(delta)
|
state:update(delta)
|
||||||
-- state:apply(skeleton)
|
state:apply(skeleton)
|
||||||
skeleton:updateWorldTransform()
|
skeleton:updateWorldTransform()
|
||||||
|
|
||||||
-- uncomment if you want to know how many batches a skeleton renders to
|
-- uncomment if you want to know how many batches a skeleton renders to
|
||||||
@ -120,7 +126,7 @@ end)
|
|||||||
Runtime:addEventListener("key", function(event)
|
Runtime:addEventListener("key", function(event)
|
||||||
if activeSkeleton == 2 and event.phase == "down" then
|
if activeSkeleton == 2 and event.phase == "down" then
|
||||||
state = skeletons[activeSkeleton].state
|
state = skeletons[activeSkeleton].state
|
||||||
state:setAnimationByName(0, "Jump", false)
|
state:setAnimationByName(0, "jump", false)
|
||||||
state:addAnimationByName(0, "walk", true, 0)
|
state:addAnimationByName(0, "walk", true, 0)
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
|
|||||||
@ -92,6 +92,7 @@ spine.Skeleton.new = function(skeletonData, group)
|
|||||||
self.batches = 0
|
self.batches = 0
|
||||||
self.tempColor = spine.Color.newWith(1, 1, 1, 1)
|
self.tempColor = spine.Color.newWith(1, 1, 1, 1)
|
||||||
self.tempColor2 = spine.Color.newWith(-1, 1, 1, 1)
|
self.tempColor2 = spine.Color.newWith(-1, 1, 1, 1)
|
||||||
|
self.clipper = spine.SkeletonClipping.new()
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -140,25 +141,49 @@ function spine.Skeleton:updateWorldTransform()
|
|||||||
local lastTexture = nil
|
local lastTexture = nil
|
||||||
local blendMode = nil
|
local blendMode = nil
|
||||||
local lastBlendMode = nil
|
local lastBlendMode = nil
|
||||||
|
local renderable = {
|
||||||
|
vertices = nil,
|
||||||
|
uvs = nil
|
||||||
|
}
|
||||||
|
|
||||||
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 uvs = nil
|
||||||
local numVertices = 0
|
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
|
||||||
numVertices = 4
|
numVertices = 4
|
||||||
vertices = self:computeRegionVertices(slot, attachment, premultipliedAlpha, color)
|
vertices = worldVertices
|
||||||
|
attachment:computeWorldVertices(slot.bone, vertices, 0, 2)
|
||||||
|
uvs = attachment.uvs
|
||||||
indices = QUAD_TRIANGLES
|
indices = QUAD_TRIANGLES
|
||||||
texture = attachment.region.renderObject.texture
|
texture = attachment.region.renderObject.texture
|
||||||
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
||||||
elseif attachment.type == spine.AttachmentType.mesh then
|
elseif attachment.type == spine.AttachmentType.mesh then
|
||||||
numVertices = attachment.worldVerticesLength / 2
|
numVertices = attachment.worldVerticesLength / 2
|
||||||
vertices = self:computeMeshVertices(slot, attachment, premultipliedAlpha, color)
|
vertices = worldVertices
|
||||||
|
attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2)
|
||||||
|
uvs = attachment.uvs
|
||||||
indices = attachment.triangles
|
indices = attachment.triangles
|
||||||
texture = attachment.region.renderObject.texture
|
texture = attachment.region.renderObject.texture
|
||||||
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
||||||
|
elseif attachment.type == spine.AttachmentType.clipping then
|
||||||
|
self.clipper:clipStart(slot, attachment)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local skeleton = slot.bone.skeleton
|
||||||
|
local skeletonColor = skeleton.color
|
||||||
|
local slotColor = slot.color
|
||||||
|
local attachmentColor = attachment.color
|
||||||
|
local alpha = skeletonColor.a * slotColor.a * attachmentColor.a
|
||||||
|
local multiplier = alpha
|
||||||
|
if premultipliedAlpha then multiplier = 1 end
|
||||||
|
color:set(skeletonColor.r * slotColor.r * attachmentColor.r * multiplier,
|
||||||
|
skeletonColor.g * slotColor.g * attachmentColor.g * multiplier,
|
||||||
|
skeletonColor.b * slotColor.b * attachmentColor.b * multiplier,
|
||||||
|
alpha)
|
||||||
|
|
||||||
if texture and vertices and indices then
|
if texture and vertices and indices then
|
||||||
if not lastTexture then lastTexture = texture end
|
if not lastTexture then lastTexture = texture end
|
||||||
@ -174,80 +199,27 @@ function spine.Skeleton:updateWorldTransform()
|
|||||||
groupUvs = {}
|
groupUvs = {}
|
||||||
groupIndices = {}
|
groupIndices = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.clipper:isClipping() then
|
||||||
|
self.clipper:clipTriangles(vertices, uvs, indices, #indices)
|
||||||
|
vertices = self.clipper.clippedVertices
|
||||||
|
numVertices = #vertices / 2
|
||||||
|
uvs = self.clipper.clippedUVs
|
||||||
|
indices = self.clipper.clippedTriangles
|
||||||
|
end
|
||||||
|
|
||||||
self:batch(vertices, numVertices, indices, groupVertices, groupUvs, groupIndices)
|
self:batch(vertices, uvs, numVertices, indices, groupVertices, groupUvs, groupIndices)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.clipper:clipEnd(slot)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if #groupVertices > 0 then
|
if #groupVertices > 0 then
|
||||||
self:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup)
|
self:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup)
|
||||||
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
|
self.clipper:clipEnd2()
|
||||||
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
|
end
|
||||||
|
|
||||||
function spine.Skeleton:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup)
|
function spine.Skeleton:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup)
|
||||||
@ -265,7 +237,7 @@ function spine.Skeleton:flush(groupVertices, groupUvs, groupIndices, texture, co
|
|||||||
self.batches = self.batches + 1
|
self.batches = self.batches + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
function spine.Skeleton:batch(vertices, numVertices, indices, groupVertices, groupUvs, groupIndices)
|
function spine.Skeleton:batch(vertices, uvs, 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
|
||||||
@ -284,10 +256,10 @@ function spine.Skeleton:batch(vertices, numVertices, indices, groupVertices, gro
|
|||||||
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] = uvs[i]
|
||||||
groupUvs[vertexStart+1] = vertices[i+3]
|
groupUvs[vertexStart+1] = uvs[i+1]
|
||||||
vertexStart = vertexStart + 2
|
vertexStart = vertexStart + 2
|
||||||
i = i + 4
|
i = i + 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -289,5 +289,9 @@ class Triangulator {
|
|||||||
|
|
||||||
Array<FloatArray> polys = triangulator.decompose(polygon, triangles);
|
Array<FloatArray> polys = triangulator.decompose(polygon, triangles);
|
||||||
System.out.println(polys);
|
System.out.println(polys);
|
||||||
|
|
||||||
|
FloatArray poly2 = new FloatArray(new float[] {0, 0, 100, 0, 100, 100, 0, 100 });
|
||||||
|
SkeletonClipping.makeClockwise(poly2);
|
||||||
|
System.out.println(poly2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,7 @@
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
local utils = require "spine-lua.utils"
|
local utils = require "spine-lua.utils"
|
||||||
|
local Triangulator = require "spine-lua.Triangulator"
|
||||||
|
|
||||||
local setmetatable = setmetatable
|
local setmetatable = setmetatable
|
||||||
local math_min = math.min
|
local math_min = math.min
|
||||||
@ -42,15 +43,306 @@ SkeletonClipping.__index = SkeletonClipping
|
|||||||
|
|
||||||
function SkeletonClipping.new ()
|
function SkeletonClipping.new ()
|
||||||
local self = {
|
local self = {
|
||||||
convexPolygons = {},
|
triangulator = Triangulator.new(),
|
||||||
convexPolygonsIndices = {},
|
clippingPolygon = {},
|
||||||
indicesArray = {},
|
clipOutput = {},
|
||||||
isConcaveArray = {},
|
clippedVertices = {},
|
||||||
triangles = {}
|
clippedUVs = {},
|
||||||
|
clippedTriangles = {},
|
||||||
|
clipAttachment = nil
|
||||||
}
|
}
|
||||||
setmetatable(self, SkeletonClipping)
|
setmetatable(self, SkeletonClipping)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
return Triangulator
|
function SkeletonClipping:clipStart(slot, clip)
|
||||||
|
if self.clipAttachment then return 0 end
|
||||||
|
self.clipAttachment = clip
|
||||||
|
|
||||||
|
local n = clip.worldVerticesLength
|
||||||
|
self.clippingPolygon = {}
|
||||||
|
local vertices = self.clippingPolygon
|
||||||
|
clip:computeWorldVertices(slot, 0, n, vertices, 0, 2)
|
||||||
|
self:makeClockwise(self.clippingPolygon)
|
||||||
|
self.clippingPolygons = self.triangulator:decompose(self.clippingPolygon, self.triangulator:triangulate(self.clippingPolygon))
|
||||||
|
for i,polygon in ipairs(self.clippingPolygons) do
|
||||||
|
self:makeClockwise(polygon)
|
||||||
|
table_insert(polygon, polygon[1])
|
||||||
|
table_insert(polygon, polygon[2])
|
||||||
|
end
|
||||||
|
return #self.clippingPolygons
|
||||||
|
end
|
||||||
|
|
||||||
|
function SkeletonClipping:clipEnd(slot)
|
||||||
|
if self.clipAttachment and self.clipAttachment.endSlot == slot then self:clipEnd2() end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SkeletonClipping:clipEnd2()
|
||||||
|
if self.clipAttachment == nil then return end
|
||||||
|
self.clipAttachment = nil
|
||||||
|
self.clippingPolygons = nil
|
||||||
|
self.clippedVertices = {}
|
||||||
|
self.clippedUVs = {}
|
||||||
|
self.clippedTriangles = {}
|
||||||
|
self.clippingPolygon = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
function SkeletonClipping:isClipping()
|
||||||
|
return self.clipAttachment ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function SkeletonClipping:clipTriangles(vertices, uvs, triangles, trianglesLength)
|
||||||
|
self.clippedVertices = {}
|
||||||
|
self.clippedUVs = {}
|
||||||
|
self.clippedTriangles = {}
|
||||||
|
local clippedVertices = self.clippedVertices
|
||||||
|
local clippedUVs = self.clippedUVs
|
||||||
|
local clippedTriangles = self.clippedTriangles
|
||||||
|
local polygons = self.clippingPolygons
|
||||||
|
local polygonsCount = #self.clippingPolygons
|
||||||
|
|
||||||
|
local index = 1
|
||||||
|
|
||||||
|
local i = 1
|
||||||
|
while i <= trianglesLength do
|
||||||
|
local vertexOffset = (triangles[i] - 1) * 2 + 1
|
||||||
|
local x1 = vertices[vertexOffset]
|
||||||
|
local y1 = vertices[vertexOffset + 1]
|
||||||
|
local u1 = uvs[vertexOffset]
|
||||||
|
local v1 = uvs[vertexOffset + 1]
|
||||||
|
|
||||||
|
vertexOffset = (triangles[i + 1] - 1) * 2 + 1
|
||||||
|
local x2 = vertices[vertexOffset]
|
||||||
|
local y2 = vertices[vertexOffset + 1]
|
||||||
|
local u2 = uvs[vertexOffset]
|
||||||
|
local v2 = uvs[vertexOffset + 1]
|
||||||
|
|
||||||
|
vertexOffset = (triangles[i + 2] - 1) * 2 + 1;
|
||||||
|
local x3 = vertices[vertexOffset]
|
||||||
|
local y3 = vertices[vertexOffset + 1]
|
||||||
|
local u3 = uvs[vertexOffset]
|
||||||
|
local v3 = uvs[vertexOffset + 1]
|
||||||
|
|
||||||
|
local p = 1
|
||||||
|
while p <= polygonsCount do
|
||||||
|
local s = #clippedVertices + 1
|
||||||
|
local clipOutput = {}
|
||||||
|
if (self:clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) then
|
||||||
|
local clipOutputLength = #clipOutput
|
||||||
|
if (clipOutputLength > 0) then
|
||||||
|
local d0 = y2 - y3
|
||||||
|
local d1 = x3 - x2
|
||||||
|
local d2 = x1 - x3
|
||||||
|
local d4 = y3 - y1
|
||||||
|
local d = 1 / (d0 * d2 + d1 * (y1 - y3));
|
||||||
|
|
||||||
|
local clipOutputCount = clipOutputLength / 2
|
||||||
|
local clipOutputItems = clipOutput
|
||||||
|
local clippedVerticesItems = clippedVertices
|
||||||
|
local clippedUVsItems = clippedUVs
|
||||||
|
local ii = 1
|
||||||
|
while ii <= clipOutputLength do
|
||||||
|
local x = clipOutputItems[ii]
|
||||||
|
local y = clipOutputItems[ii + 1]
|
||||||
|
clippedVerticesItems[s] = x
|
||||||
|
clippedVerticesItems[s + 1] = y
|
||||||
|
local c0 = x - x3
|
||||||
|
local c1 = y - y3
|
||||||
|
local a = (d0 * c0 + d1 * c1) * d
|
||||||
|
local b = (d4 * c0 + d2 * c1) * d
|
||||||
|
local c = 1 - a - b
|
||||||
|
clippedUVsItems[s] = u1 * a + u2 * b + u3 * c
|
||||||
|
clippedUVsItems[s + 1] = v1 * a + v2 * b + v3 * c
|
||||||
|
s = s + 2
|
||||||
|
ii = ii + 2
|
||||||
|
end
|
||||||
|
|
||||||
|
s = #clippedTriangles + 1
|
||||||
|
local clippedTrianglesItems = clippedTriangles
|
||||||
|
clipOutputCount = clipOutputCount - 1
|
||||||
|
ii = 1
|
||||||
|
while ii < clipOutputCount do
|
||||||
|
clippedTrianglesItems[s] = index
|
||||||
|
clippedTrianglesItems[s + 1] = index + ii
|
||||||
|
clippedTrianglesItems[s + 2] = index + ii + 1
|
||||||
|
s = s + 3
|
||||||
|
ii = ii + 1
|
||||||
|
end
|
||||||
|
index = index + clipOutputCount + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local clippedVerticesItems = clippedVertices
|
||||||
|
local clippedUVsItems = clippedUVs
|
||||||
|
clippedVerticesItems[s] = x1
|
||||||
|
clippedVerticesItems[s + 1] = y1
|
||||||
|
clippedVerticesItems[s + 2] = x2
|
||||||
|
clippedVerticesItems[s + 3] = y2
|
||||||
|
clippedVerticesItems[s + 4] = x3
|
||||||
|
clippedVerticesItems[s + 5] = y3
|
||||||
|
|
||||||
|
clippedUVsItems[s] = u1
|
||||||
|
clippedUVsItems[s + 1] = v1
|
||||||
|
clippedUVsItems[s + 2] = u2
|
||||||
|
clippedUVsItems[s + 3] = v2
|
||||||
|
clippedUVsItems[s + 4] = u3
|
||||||
|
clippedUVsItems[s + 5] = v3
|
||||||
|
|
||||||
|
s = #clippedTriangles + 1
|
||||||
|
local clippedTrianglesItems = clippedTriangles
|
||||||
|
clippedTrianglesItems[s] = index
|
||||||
|
clippedTrianglesItems[s + 1] = index + 1
|
||||||
|
clippedTrianglesItems[s + 2] = index + 2
|
||||||
|
index = index + 3;
|
||||||
|
break
|
||||||
|
end
|
||||||
|
p = p + 1
|
||||||
|
end
|
||||||
|
i = i + 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SkeletonClipping:clip(x1, y1, x2, y2, x3, y3, clippingArea, output)
|
||||||
|
local originalOutput = output
|
||||||
|
local clipped = false
|
||||||
|
local scratch = {}
|
||||||
|
|
||||||
|
-- Avoid copy at the end.
|
||||||
|
local input = nil
|
||||||
|
if #clippingArea % 4 >= 2 then
|
||||||
|
input = output
|
||||||
|
output = scratch
|
||||||
|
else
|
||||||
|
input = scratch
|
||||||
|
end
|
||||||
|
|
||||||
|
table_insert(input, x1)
|
||||||
|
table_insert(input, y1)
|
||||||
|
table_insert(input, x2)
|
||||||
|
table_insert(input, y2)
|
||||||
|
table_insert(input, x3)
|
||||||
|
table_insert(input, y3)
|
||||||
|
table_insert(input, x1)
|
||||||
|
table_insert(input, y1)
|
||||||
|
|
||||||
|
local clippingVertices = clippingArea
|
||||||
|
local clippingVerticesLast = #clippingArea - 4 + 1
|
||||||
|
local i = 1
|
||||||
|
while true do
|
||||||
|
local edgeX = clippingVertices[i]
|
||||||
|
local edgeY = clippingVertices[i + 1]
|
||||||
|
local edgeX2 = clippingVertices[i + 2]
|
||||||
|
local edgeY2 = clippingVertices[i + 3]
|
||||||
|
local deltaX = edgeX - edgeX2
|
||||||
|
local deltaY = edgeY - edgeY2
|
||||||
|
|
||||||
|
local inputVertices = input
|
||||||
|
local inputVerticesLength = #input - 2
|
||||||
|
local outputStart = #output
|
||||||
|
local ii = 1
|
||||||
|
while ii <= inputVerticesLength do
|
||||||
|
local inputX = inputVertices[ii]
|
||||||
|
local inputY = inputVertices[ii + 1]
|
||||||
|
local inputX2 = inputVertices[ii + 2]
|
||||||
|
local inputY2 = inputVertices[ii + 3]
|
||||||
|
local side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0
|
||||||
|
local continue = false;
|
||||||
|
if deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0 then
|
||||||
|
if side2 then -- v1 inside, v2 inside
|
||||||
|
table_insert(output, inputX2)
|
||||||
|
table_insert(output, inputY2)
|
||||||
|
continue = true
|
||||||
|
else
|
||||||
|
-- v1 inside, v2 outside
|
||||||
|
local c0 = inputY2 - inputY
|
||||||
|
local c2 = inputX2 - inputX
|
||||||
|
local ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY))
|
||||||
|
table_insert(output, edgeX + (edgeX2 - edgeX) * ua)
|
||||||
|
table_insert(output, edgeY + (edgeY2 - edgeY) * ua)
|
||||||
|
end
|
||||||
|
elseif side2 then -- v1 outside, v2 inside
|
||||||
|
local c0 = inputY2 - inputY
|
||||||
|
local c2 = inputX2 - inputX
|
||||||
|
local ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY))
|
||||||
|
table_insert(output, edgeX + (edgeX2 - edgeX) * ua)
|
||||||
|
table_insert(output, edgeY + (edgeY2 - edgeY) * ua)
|
||||||
|
table_insert(output, inputX2)
|
||||||
|
table_insert(output, inputY2)
|
||||||
|
end
|
||||||
|
if not continue then clipped = true end
|
||||||
|
ii = ii + 2
|
||||||
|
end
|
||||||
|
|
||||||
|
if outputStart == #output then -- All edges outside.
|
||||||
|
for i, v in ipairs(originalOutput) do
|
||||||
|
originalOutput[i] = nil
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
table_insert(output, output[1])
|
||||||
|
table_insert(output, output[2])
|
||||||
|
|
||||||
|
if (i == clippingVerticesLast) then break end
|
||||||
|
local temp = output
|
||||||
|
output = input
|
||||||
|
for i, v in ipairs(output) do
|
||||||
|
output[i] = nil
|
||||||
|
end
|
||||||
|
input = temp
|
||||||
|
i = i + 2
|
||||||
|
end
|
||||||
|
|
||||||
|
if originalOutput ~= output then
|
||||||
|
for i, v in ipairs(originalOutput) do
|
||||||
|
originalOutput[i] = nil
|
||||||
|
end
|
||||||
|
i = 1
|
||||||
|
local n = #output - 2
|
||||||
|
while i <= n do
|
||||||
|
originalOutput[i] = output[i]
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
utils.setArraySize(originalOutput, #originalOutput - 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
return clipped
|
||||||
|
end
|
||||||
|
|
||||||
|
function SkeletonClipping:makeClockwise(polygon)
|
||||||
|
local vertices = polygon
|
||||||
|
local verticesLength = #polygon
|
||||||
|
local area = vertices[verticesLength - 2 + 1] * vertices[1 + 1] - vertices[0 + 1] * vertices[verticesLength - 1 + 1]
|
||||||
|
local p1x
|
||||||
|
local p1y
|
||||||
|
local p2x
|
||||||
|
local p2y
|
||||||
|
local i = 1
|
||||||
|
local n = verticesLength - 3 + 1
|
||||||
|
while i <= n do
|
||||||
|
p1x = vertices[i]
|
||||||
|
p1y = vertices[i + 1]
|
||||||
|
p2x = vertices[i + 2]
|
||||||
|
p2y = vertices[i + 3]
|
||||||
|
area = area + p1x * p2y - p2x * p1y
|
||||||
|
i = i + 2
|
||||||
|
end
|
||||||
|
if (area < 0) then return end
|
||||||
|
|
||||||
|
i = 1
|
||||||
|
local lastX = verticesLength - 2 + 1
|
||||||
|
n = verticesLength / 2
|
||||||
|
while i <= n do
|
||||||
|
local x = vertices[i]
|
||||||
|
local y = vertices[i + 1]
|
||||||
|
local other = lastX - i + 1
|
||||||
|
vertices[i] = vertices[other]
|
||||||
|
vertices[i + 1] = vertices[other + 1]
|
||||||
|
vertices[other] = x
|
||||||
|
vertices[other + 1] = y
|
||||||
|
i = i + 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return SkeletonClipping
|
||||||
|
|||||||
@ -187,6 +187,15 @@ end
|
|||||||
function RegionAttachment:setRegion (region)
|
function RegionAttachment:setRegion (region)
|
||||||
local uvs = self.uvs
|
local uvs = self.uvs
|
||||||
if region.rotate then
|
if region.rotate then
|
||||||
|
uvs[5] = region.u
|
||||||
|
uvs[6] = region.v2
|
||||||
|
uvs[7] = region.u
|
||||||
|
uvs[8] = region.v
|
||||||
|
uvs[1] = region.u2
|
||||||
|
uvs[2] = region.v
|
||||||
|
uvs[3] = region.u2
|
||||||
|
uvs[4] = region.v2
|
||||||
|
else
|
||||||
uvs[3] = region.u
|
uvs[3] = region.u
|
||||||
uvs[4] = region.v2
|
uvs[4] = region.v2
|
||||||
uvs[5] = region.u
|
uvs[5] = region.u
|
||||||
@ -195,15 +204,6 @@ function RegionAttachment:setRegion (region)
|
|||||||
uvs[8] = region.v
|
uvs[8] = region.v
|
||||||
uvs[1] = region.u2
|
uvs[1] = region.u2
|
||||||
uvs[2] = region.v2
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -219,26 +219,26 @@ function RegionAttachment:computeWorldVertices (bone, worldVertices, offset, str
|
|||||||
local offsetX = 0
|
local offsetX = 0
|
||||||
local offsetY = 0
|
local offsetY = 0
|
||||||
|
|
||||||
offsetX = vertexOffset[OX1]
|
offsetX = vertexOffset[7]
|
||||||
offsetY = vertexOffset[OY1]
|
offsetY = vertexOffset[8]
|
||||||
worldVertices[offset] = offsetX * a + offsetY * b + x -- br
|
worldVertices[offset] = offsetX * a + offsetY * b + x -- br
|
||||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||||
offset = offset + stride
|
offset = offset + stride
|
||||||
|
|
||||||
offsetX = vertexOffset[OX2]
|
offsetX = vertexOffset[1]
|
||||||
offsetY = vertexOffset[OY2]
|
offsetY = vertexOffset[2]
|
||||||
worldVertices[offset] = offsetX * a + offsetY * b + x -- bl
|
worldVertices[offset] = offsetX * a + offsetY * b + x -- bl
|
||||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||||
offset = offset + stride
|
offset = offset + stride
|
||||||
|
|
||||||
offsetX = vertexOffset[OX3]
|
offsetX = vertexOffset[3]
|
||||||
offsetY = vertexOffset[OY3]
|
offsetY = vertexOffset[4]
|
||||||
worldVertices[offset] = offsetX * a + offsetY * b + x -- ul
|
worldVertices[offset] = offsetX * a + offsetY * b + x -- ul
|
||||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||||
offset = offset + stride
|
offset = offset + stride
|
||||||
|
|
||||||
offsetX = vertexOffset[OX4]
|
offsetX = vertexOffset[5]
|
||||||
offsetY = vertexOffset[OY4]
|
offsetY = vertexOffset[6]
|
||||||
worldVertices[offset] = offsetX * a + offsetY * b + x -- ur
|
worldVertices[offset] = offsetX * a + offsetY * b + x -- ur
|
||||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
worldVertices[offset + 1] = offsetX * c + offsetY * d + y
|
||||||
end
|
end
|
||||||
|
|||||||
@ -108,7 +108,12 @@ function utils.setArraySize (array, size)
|
|||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
array[size + 1] = nil -- dirty trick to appease # without realloc
|
local originalSize = #array
|
||||||
|
local i = originalSize
|
||||||
|
while i > size do
|
||||||
|
array[i] = nil -- dirty trick to appease # without realloc
|
||||||
|
i = i - 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return array
|
return array
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user