Merge pull request #184 from argonui/faster-connectors
Optimize location connection drawing during drag operations
This commit is contained in:
commit
31006694b8
@ -184,6 +184,14 @@ function onObjectSearchEnd(object, playerColor)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Pass object enter container events to the PlayArea to clear vector lines from dragged cards.
|
||||||
|
-- This requires the try method as cards won't exist any more after they enter a deck, so the lines
|
||||||
|
-- can't be cleared.
|
||||||
|
function tryObjectEnterContainer(container, object)
|
||||||
|
playAreaAPI.tryObjectEnterContainer(container, object)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
function drawEncountercard(params)
|
function drawEncountercard(params)
|
||||||
local position = params[1]
|
local position = params[1]
|
||||||
local rotation = params[2]
|
local rotation = params[2]
|
||||||
|
@ -8,9 +8,12 @@ local DEBUG = false
|
|||||||
-- Location connection directional options
|
-- Location connection directional options
|
||||||
local BIDIRECTIONAL = 0
|
local BIDIRECTIONAL = 0
|
||||||
local ONE_WAY = 1
|
local ONE_WAY = 1
|
||||||
|
local INCOMING_ONE_WAY = 2
|
||||||
|
|
||||||
-- Connector draw parameters
|
-- Connector draw parameters
|
||||||
local CONNECTION_THICKNESS = 0.015
|
local CONNECTION_THICKNESS = 0.015
|
||||||
|
local DRAGGING_CONNECTION_THICKNESS = 0.15
|
||||||
|
local DRAGGING_CONNECTION_COLOR = { 0.8, 0.8, 0.8, 1 }
|
||||||
local CONNECTION_COLOR = { 0.4, 0.4, 0.4, 1 }
|
local CONNECTION_COLOR = { 0.4, 0.4, 0.4, 1 }
|
||||||
local DIRECTIONAL_ARROW_DISTANCE = 3.5
|
local DIRECTIONAL_ARROW_DISTANCE = 3.5
|
||||||
local ARROW_ARM_LENGTH = 0.9
|
local ARROW_ARM_LENGTH = 0.9
|
||||||
@ -90,7 +93,7 @@ end
|
|||||||
function onCollisionEnter(collisionInfo)
|
function onCollisionEnter(collisionInfo)
|
||||||
local obj = collisionInfo.collision_object
|
local obj = collisionInfo.collision_object
|
||||||
local objType = obj.name
|
local objType = obj.name
|
||||||
|
|
||||||
-- only continue for cards
|
-- only continue for cards
|
||||||
if not collisionEnabled or (objType ~= "Card" and objType ~= "CardCustom") then return end
|
if not collisionEnabled or (objType ~= "Card" and objType ~= "CardCustom") then return end
|
||||||
|
|
||||||
@ -99,7 +102,12 @@ function onCollisionEnter(collisionInfo)
|
|||||||
if shouldSpawnTokens(card) then
|
if shouldSpawnTokens(card) then
|
||||||
tokenManager.spawnForCard(card)
|
tokenManager.spawnForCard(card)
|
||||||
end
|
end
|
||||||
draggingGuids[card.getGUID()] = nil
|
-- If this card was being dragged, clear the dragging connections. A multi-drag/drop may send
|
||||||
|
-- the dropped card immediately into a deck, so this has to be done here
|
||||||
|
if draggingGuids[card.getGUID()] ~= nil then
|
||||||
|
card.setVectorLines(nil)
|
||||||
|
draggingGuids[card.getGUID()] = nil
|
||||||
|
end
|
||||||
maybeTrackLocation(card)
|
maybeTrackLocation(card)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -150,6 +158,11 @@ function onUpdate()
|
|||||||
if obj == nil or not isInPlayArea(obj) then
|
if obj == nil or not isInPlayArea(obj) then
|
||||||
draggingGuids[guid] = nil
|
draggingGuids[guid] = nil
|
||||||
needsConnectionRebuild = true
|
needsConnectionRebuild = true
|
||||||
|
-- If object still exists then it's been dragged outside the area and needs to clear the
|
||||||
|
-- lines attached to it
|
||||||
|
if obj ~= nil then
|
||||||
|
obj.setVectorLines(nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
-- Even if the last location left the play area, need one last draw to clear the lines
|
-- Even if the last location left the play area, need one last draw to clear the lines
|
||||||
needsConnectionDraw = true
|
needsConnectionDraw = true
|
||||||
@ -158,7 +171,7 @@ function onUpdate()
|
|||||||
rebuildConnectionList()
|
rebuildConnectionList()
|
||||||
end
|
end
|
||||||
if needsConnectionDraw then
|
if needsConnectionDraw then
|
||||||
drawConnections()
|
drawDraggingConnections()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -173,7 +186,7 @@ function maybeTrackLocation(card)
|
|||||||
if metadata.type == "Location" then
|
if metadata.type == "Location" then
|
||||||
locations[card.getGUID()] = metadata
|
locations[card.getGUID()] = metadata
|
||||||
rebuildConnectionList()
|
rebuildConnectionList()
|
||||||
drawConnections()
|
drawBaseConnections()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -189,14 +202,26 @@ function maybeUntrackLocation(card)
|
|||||||
if locations[card.getGUID()] ~= nil and not card.locked then
|
if locations[card.getGUID()] ~= nil and not card.locked then
|
||||||
locations[card.getGUID()] = nil
|
locations[card.getGUID()] = nil
|
||||||
rebuildConnectionList()
|
rebuildConnectionList()
|
||||||
drawConnections()
|
drawBaseConnections()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Global event handler, delegated from Global. Clears any connection lines from dragged cards
|
||||||
|
-- before they are destroyed by entering a deck. Removal of the card from the dragging list will
|
||||||
|
-- be handled during the next onUpdate() call.
|
||||||
|
function tryObjectEnterContainer(params)
|
||||||
|
for draggedGuid, _ in pairs(draggingGuids) do
|
||||||
|
local draggedObj = getObjectFromGUID(draggedGuid)
|
||||||
|
if draggedObj ~= nil then
|
||||||
|
draggedObj.setVectorLines(nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Builds a list of GUID to GUID connection information based on the currently tracked locations.
|
-- Builds a list of GUID to GUID connection information based on the currently tracked locations.
|
||||||
-- This will update the connection information and store it in the locationConnections data member,
|
-- This will update the connection information and store it in the locationConnections data member,
|
||||||
-- but does not draw those connections. This should often be followed by a call to
|
-- but does not draw those connections. This should often be followed by a call to
|
||||||
-- drawConnections()
|
-- drawBaseConnections()
|
||||||
function rebuildConnectionList()
|
function rebuildConnectionList()
|
||||||
if not showLocationLinks() then
|
if not showLocationLinks() then
|
||||||
locationConnections = { }
|
locationConnections = { }
|
||||||
@ -255,10 +280,15 @@ function buildConnection(cardId, iconCardList)
|
|||||||
for _, connectedGuid in ipairs(iconCardList[icon]) do
|
for _, connectedGuid in ipairs(iconCardList[icon]) do
|
||||||
-- If the reciprocal exists, convert it to BiDi, otherwise add as a one-way
|
-- If the reciprocal exists, convert it to BiDi, otherwise add as a one-way
|
||||||
if locationConnections[connectedGuid] ~= nil
|
if locationConnections[connectedGuid] ~= nil
|
||||||
and locationConnections[connectedGuid][card.getGUID()] ~= nil then
|
and locationConnections[connectedGuid][card.getGUID()] == ONE_WAY then
|
||||||
locationConnections[connectedGuid][card.getGUID()] = BIDIRECTIONAL
|
locationConnections[connectedGuid][card.getGUID()] = BIDIRECTIONAL
|
||||||
|
locationConnections[card.getGUID()][connectedGuid] = nil
|
||||||
else
|
else
|
||||||
|
if locationConnections[connectedGuid] == nil then
|
||||||
|
locationConnections[connectedGuid] = { }
|
||||||
|
end
|
||||||
locationConnections[card.getGUID()][connectedGuid] = ONE_WAY
|
locationConnections[card.getGUID()][connectedGuid] = ONE_WAY
|
||||||
|
locationConnections[connectedGuid][card.getGUID()] = INCOMING_ONE_WAY
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -282,8 +312,9 @@ function getLocationData(card)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Draws the lines for connections currently in locationConnections.
|
-- Draws the lines for connections currently in locationConnections but not in draggingGuids.
|
||||||
function drawConnections()
|
-- Constructed vectors will be set to the playmat
|
||||||
|
function drawBaseConnections()
|
||||||
if not showLocationLinks() then
|
if not showLocationLinks() then
|
||||||
locationConnections = { }
|
locationConnections = { }
|
||||||
return
|
return
|
||||||
@ -294,14 +325,16 @@ function drawConnections()
|
|||||||
-- Objects should reliably exist at this point, but since this can be called during onUpdate the
|
-- Objects should reliably exist at this point, but since this can be called during onUpdate the
|
||||||
-- object checks are conservative just to make sure.
|
-- object checks are conservative just to make sure.
|
||||||
local origin = getObjectFromGUID(originGuid)
|
local origin = getObjectFromGUID(originGuid)
|
||||||
if origin != nil then
|
if draggingGuids[originGuid] == nil and origin != nil then
|
||||||
for targetGuid, direction in pairs(targetGuids) do
|
for targetGuid, direction in pairs(targetGuids) do
|
||||||
local target = getObjectFromGUID(targetGuid)
|
local target = getObjectFromGUID(targetGuid)
|
||||||
if target != nil then
|
if draggingGuids[targetGuid] == nil and target != nil then
|
||||||
|
-- Since we process the full list, we're guaranteed to hit any ONE_WAY connections later
|
||||||
|
-- so we can ignore INCOMING_ONE_WAY
|
||||||
if direction == BIDIRECTIONAL then
|
if direction == BIDIRECTIONAL then
|
||||||
addBidirectionalVector(origin, target, cardConnectionLines)
|
addBidirectionalVector(origin, target, self, cardConnectionLines)
|
||||||
elseif direction == ONE_WAY then
|
elseif direction == ONE_WAY then
|
||||||
addOneWayVector(origin, target, cardConnectionLines)
|
addOneWayVector(origin, target, self, cardConnectionLines)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -310,22 +343,61 @@ function drawConnections()
|
|||||||
self.setVectorLines(cardConnectionLines)
|
self.setVectorLines(cardConnectionLines)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Draws the lines for cards which are currently being dragged.
|
||||||
|
function drawDraggingConnections()
|
||||||
|
if not showLocationLinks() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local cardConnectionLines = { }
|
||||||
|
local ownedVectors = { }
|
||||||
|
|
||||||
|
for originGuid, _ in pairs(draggingGuids) do
|
||||||
|
targetGuids = locationConnections[originGuid]
|
||||||
|
-- Objects should reliably exist at this point, but since this can be called during onUpdate the
|
||||||
|
-- object checks are conservative just to make sure.
|
||||||
|
local origin = getObjectFromGUID(originGuid)
|
||||||
|
if draggingGuids[originGuid] and origin != nil then
|
||||||
|
ownedVectors[originGuid] = { }
|
||||||
|
for targetGuid, direction in pairs(targetGuids) do
|
||||||
|
local target = getObjectFromGUID(targetGuid)
|
||||||
|
if target != nil then
|
||||||
|
if direction == BIDIRECTIONAL then
|
||||||
|
addBidirectionalVector(origin, target, origin, ownedVectors[originGuid])
|
||||||
|
elseif direction == ONE_WAY then
|
||||||
|
addOneWayVector(origin, target, origin, ownedVectors[originGuid])
|
||||||
|
elseif direction == INCOMING_ONE_WAY and not draggingGuids[targetGuid] then
|
||||||
|
addOneWayVector(target, origin, origin, ownedVectors[originGuid])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for ownerGuid, vectors in pairs(ownedVectors) do
|
||||||
|
local card = getObjectFromGUID(ownerGuid)
|
||||||
|
card.setVectorLines(vectors)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Draws a bidirectional location connection between the two cards, adding the lines to do so to the
|
-- Draws a bidirectional location connection between the two cards, adding the lines to do so to the
|
||||||
-- given lines list.
|
-- given lines list.
|
||||||
---@param card1 Object One of the card objects to connect
|
---@param card1 Object One of the card objects to connect
|
||||||
---@param card2 Object The other card object to connect
|
---@param card2 Object The other card object to connect
|
||||||
|
---@param vectorOwner Object The object which these lines will be set to. Used for relative
|
||||||
|
--- positioning and scaling, as well as highlighting connections during a drag operation
|
||||||
---@param lines Table List of vector line elements. Mutable, will be updated to add this connector
|
---@param lines Table List of vector line elements. Mutable, will be updated to add this connector
|
||||||
function addBidirectionalVector(card1, card2, lines)
|
function addBidirectionalVector(card1, card2, vectorOwner, lines)
|
||||||
local cardPos1 = card1.getPosition()
|
local cardPos1 = card1.getPosition()
|
||||||
local cardPos2 = card2.getPosition()
|
local cardPos2 = card2.getPosition()
|
||||||
cardPos1.y = CONNECTION_LINE_Y
|
cardPos1.y = CONNECTION_LINE_Y
|
||||||
cardPos2.y = CONNECTION_LINE_Y
|
cardPos2.y = CONNECTION_LINE_Y
|
||||||
local pos1 = self.positionToLocal(cardPos1)
|
|
||||||
local pos2 = self.positionToLocal(cardPos2)
|
local pos1 = vectorOwner.positionToLocal(cardPos1)
|
||||||
|
local pos2 = vectorOwner.positionToLocal(cardPos2)
|
||||||
|
|
||||||
table.insert(lines, {
|
table.insert(lines, {
|
||||||
points = { pos1, pos2 },
|
points = { pos1, pos2 },
|
||||||
color = CONNECTION_COLOR,
|
color = vectorOwner == self and CONNECTION_COLOR or DRAGGING_CONNECTION_COLOR,
|
||||||
thickness = CONNECTION_THICKNESS,
|
thickness = vectorOwner == self and CONNECTION_THICKNESS or DRAGGING_CONNECTION_THICKNESS,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -333,10 +405,12 @@ end
|
|||||||
-- given lines list. Arrows will point towards the target card.
|
-- given lines list. Arrows will point towards the target card.
|
||||||
---@param origin Object Origin card in the connection
|
---@param origin Object Origin card in the connection
|
||||||
---@param target Object Target card object to connect
|
---@param target Object Target card object to connect
|
||||||
|
---@param vectorOwner Object The object which these lines will be set to. Used for relative
|
||||||
|
--- positioning and scaling, as well as highlighting connections during a drag operation
|
||||||
---@param lines Table List of vector line elements. Mutable, will be updated to add this connector
|
---@param lines Table List of vector line elements. Mutable, will be updated to add this connector
|
||||||
function addOneWayVector(origin, target, lines)
|
function addOneWayVector(origin, target, vectorOwner, lines)
|
||||||
-- Start with the BiDi then add the arrow lines to it
|
-- Start with the BiDi then add the arrow lines to it
|
||||||
addBidirectionalVector(origin, target, lines)
|
addBidirectionalVector(origin, target, vectorOwner, lines)
|
||||||
local originPos = origin.getPosition()
|
local originPos = origin.getPosition()
|
||||||
local targetPos = target.getPosition()
|
local targetPos = target.getPosition()
|
||||||
originPos.y = CONNECTION_LINE_Y
|
originPos.y = CONNECTION_LINE_Y
|
||||||
@ -354,28 +428,30 @@ function addOneWayVector(origin, target, lines)
|
|||||||
local closeToTarget = Vector(targetPos):moveTowards(originPos, distanceFromCard - ARROW_ARM_LENGTH / 2)
|
local closeToTarget = Vector(targetPos):moveTowards(originPos, distanceFromCard - ARROW_ARM_LENGTH / 2)
|
||||||
|
|
||||||
if (originPos:distance(closeToOrigin) > originPos:distance(closeToTarget)) then
|
if (originPos:distance(closeToOrigin) > originPos:distance(closeToTarget)) then
|
||||||
addArrowLines(midpoint, originPos, lines)
|
addArrowLines(midpoint, originPos, vectorOwner, lines)
|
||||||
else
|
else
|
||||||
addArrowLines(closeToOrigin, originPos, lines)
|
addArrowLines(closeToOrigin, originPos, vectorOwner, lines)
|
||||||
addArrowLines(closeToTarget, originPos, lines)
|
addArrowLines(closeToTarget, originPos, vectorOwner, lines)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Draws an arrowhead at the given position.
|
-- Draws an arrowhead at the given position.
|
||||||
---@param arrowheadPosition Table Centerpoint of the arrowhead to draw (NOT the tip of the arrow)
|
---@param arrowheadPosition Table Centerpoint of the arrowhead to draw (NOT the tip of the arrow)
|
||||||
---@param originPos Table Origin point of the connection, used to position the arrow arms
|
---@param originPos Table Origin point of the connection, used to position the arrow arms
|
||||||
|
---@param vectorOwner Object The object which these lines will be set to. Used for relative
|
||||||
|
--- positioning and scaling, as well as highlighting connections during a drag operation
|
||||||
---@param lines Table List of vector line elements. Mutable, will be updated to add this arrow
|
---@param lines Table List of vector line elements. Mutable, will be updated to add this arrow
|
||||||
function addArrowLines(arrowheadPos, originPos, lines)
|
function addArrowLines(arrowheadPos, originPos, vectorOwner, lines)
|
||||||
local arrowArm1 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y", -1 * ARROW_ANGLE):add(arrowheadPos)
|
local arrowArm1 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y", -1 * ARROW_ANGLE):add(arrowheadPos)
|
||||||
local arrowArm2 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y", ARROW_ANGLE):add(arrowheadPos)
|
local arrowArm2 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y", ARROW_ANGLE):add(arrowheadPos)
|
||||||
|
|
||||||
local head = self.positionToLocal(arrowheadPos)
|
local head = vectorOwner.positionToLocal(arrowheadPos)
|
||||||
local arm1 = self.positionToLocal(arrowArm1)
|
local arm1 = vectorOwner.positionToLocal(arrowArm1)
|
||||||
local arm2 = self.positionToLocal(arrowArm2)
|
local arm2 = vectorOwner.positionToLocal(arrowArm2)
|
||||||
table.insert(lines, {
|
table.insert(lines, {
|
||||||
points = { arm1, head, arm2},
|
points = { arm1, head, arm2},
|
||||||
color = CONNECTION_COLOR,
|
color = vectorOwner == self and CONNECTION_COLOR or DRAGGING_CONNECTION_COLOR,
|
||||||
thickness = CONNECTION_THICKNESS
|
thickness = vectorOwner == self and CONNECTION_THICKNESS or DRAGGING_CONNECTION_THICKNESS,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -47,6 +47,13 @@ do
|
|||||||
PlayAreaApi.setLimitSnapsByType = function(matchCardTypes)
|
PlayAreaApi.setLimitSnapsByType = function(matchCardTypes)
|
||||||
getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes)
|
getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged
|
||||||
|
-- cards before they're destroyed by entering the container
|
||||||
|
PlayAreaApi.tryObjectEnterContainer = function(container, object)
|
||||||
|
getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer",
|
||||||
|
{ container = container, object = object })
|
||||||
|
end
|
||||||
|
|
||||||
return PlayAreaApi
|
return PlayAreaApi
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user