542 lines
17 KiB
Lua
542 lines
17 KiB
Lua
require 'math'
|
|
|
|
|
|
--[[
|
|
keypoints: sorted array of {x, y} pairs ('x' values should increase strongly monotonic!), e.g. { {0, 0.9}, {0.4, 0}, {0.6, 0.2}, {0.8, 1.0} }
|
|
pos: a position on the 'x' axis, e.g. 0.5
|
|
return: the value corresponding to 'pos' that was linear interpolated from the 'keypoints' line chain (e.g. 0.1 for the example input data)
|
|
--]]
|
|
function roadbookMapInterpolated(keypoints, pos)
|
|
local idx = 1
|
|
while ((idx + 1 < #keypoints) and (pos > keypoints[idx + 1][1])) do
|
|
idx = idx + 1
|
|
end
|
|
local secondidx = math.min(#keypoints, idx + 1)
|
|
local k0 = keypoints[idx][1]
|
|
local v0 = keypoints[idx][2]
|
|
local k1 = keypoints[secondidx][1]
|
|
local v1 = keypoints[secondidx][2]
|
|
local lpos = 0.0
|
|
if (k1 > k0) then
|
|
lpos = math.min(1.0, math.max(0.0, (pos - k0) / (k1 - k0)))
|
|
end
|
|
local result = v0 * (1.0 - lpos) + v1 * lpos
|
|
print(pos, " ", idx, " ", secondidx, " ", k0, " ", v0, " ", k1, " ", v1, " ", lpos, " ", result)
|
|
return result
|
|
end
|
|
|
|
--[[
|
|
state: the guidance state
|
|
return:
|
|
opacity: the opacity of the deviate content
|
|
--]]
|
|
function roadbookDeviateContentOpacity(state)
|
|
if state == ROADBOOK_GUIDANCE_STATE_DEVIATE then
|
|
return 1.0
|
|
else
|
|
return 0.0
|
|
end
|
|
end
|
|
|
|
function roadbookAsiaCcpOpacity(state)
|
|
if state == ROADBOOK_GUIDANCE_STATE_CALCULATION_ASIA
|
|
or state == ROADBOOK_GUIDANCE_STATE_INACTIVE_ASIA
|
|
or state == ROADBOOK_GUIDANCE_STATE_OFFROAD_ASIA then
|
|
return 1.0
|
|
else
|
|
return 0.0
|
|
end
|
|
end
|
|
|
|
--[[
|
|
state: the guidance state
|
|
enabled: roadbook is selected
|
|
mapVisible: whether a map screen (which can contain the flying window) is visible
|
|
return:
|
|
visibility: the visibility of the destination information (as a bool)
|
|
opacity: the visibility of the destination information (as either 1.0 or 0.0)
|
|
--]]
|
|
function roadbookDestinationVisibility(state, enabled, mapVisible)
|
|
local ret = (not mapVisible) and enabled and
|
|
(state == ROADBOOK_GUIDANCE_STATE_ACTIVE
|
|
or state == ROADBOOK_GUIDANCE_STATE_OFFROAD
|
|
or state == ROADBOOK_GUIDANCE_STATE_DEVIATE
|
|
or state == ROADBOOK_GUIDANCE_STATE_OFFROAD_ASIA)
|
|
if ret then
|
|
return true, 1.0
|
|
else
|
|
return false, 0.0
|
|
end
|
|
end
|
|
|
|
--[[
|
|
state: the guidance state
|
|
isEce: should contain true for ECE or US
|
|
enabled: roadbook is selected
|
|
bendDelay: a delay time for the bend (usually negative)
|
|
currentBend: current bend of bend animation
|
|
bendThreshold: bending threashold if the content will be visible
|
|
return:
|
|
bend: the bend value for the road
|
|
contentVisible: the visibility of the roadbook panels
|
|
detailedContentVisible: the visibility of the detailed content
|
|
laneguidingVisible: the visibility of the three LG rows and the separator
|
|
compassVisible: the visibility of the (non asia) compass
|
|
--]]
|
|
function roadbookGuidanceStateRelated(state, isEce, enabled, bendDelay, currentBend, bendThreshold)
|
|
local panelsVisible = (state == ROADBOOK_GUIDANCE_STATE_ACTIVE or state == ROADBOOK_GUIDANCE_STATE_DEVIATE)
|
|
local roadBend = bendDelay
|
|
if panelsVisible then
|
|
roadBend = 1.0
|
|
end
|
|
local detailedContentVisible = (panelsVisible or state == ROADBOOK_GUIDANCE_STATE_INACTIVE_ASIA)
|
|
-- TODO: will this lead to instantly vanishing lane guiding on state change??
|
|
local lgVisible = (state == ROADBOOK_GUIDANCE_STATE_ACTIVE)
|
|
local compassVisible = isEce
|
|
|
|
local contentVisible = enabled and panelsVisible and (currentBend > bendThreshold)
|
|
return roadBend, contentVisible, enabled and detailedContentVisible, enabled and lgVisible, enabled and compassVisible
|
|
end
|
|
|
|
--[[
|
|
opacity: opacity to be used when visible
|
|
visible: if false, the resulting opacity will be 0
|
|
return:
|
|
effectiveOpacity: Either input opacity or 0, depending on "visible"
|
|
--]]
|
|
function roadbookEffectiveOpacity(opacity, visible)
|
|
if visible then
|
|
return opacity
|
|
else
|
|
return 0
|
|
end
|
|
end
|
|
|
|
--[[
|
|
progress: the progress of the bargraph
|
|
assetSize: size of the bargraph asset
|
|
return:
|
|
position: vertical bottom position of the bar graph component
|
|
size: vertical size of the bar graph component
|
|
--]]
|
|
function roadbookBargraphPlacement(progress, assetSize)
|
|
-- always at least 9 px high, as the bottom + top images have that size
|
|
local size = 9 + ( (assetSize.z - 2*6 - 9) * (100.0 - progress) / 100.0 )
|
|
return assetSize.z - 6.0 - size , size
|
|
end
|
|
|
|
--[[
|
|
currentOpacity: The current opacity for the whole widget
|
|
contentOpacity: The animated opacity for the content
|
|
loadingOpacity: The animated opacity for the loading indicator
|
|
return:
|
|
contentOpacity: Calculated opacity for the content
|
|
loadingOpacity: Calculated opacity for the loading indicator
|
|
--]]
|
|
function calculatePanelContentOpacity(currentOpacity, contentOpacity, loadingOpacity)
|
|
return currentOpacity * contentOpacity, currentOpacity * loadingOpacity
|
|
end
|
|
|
|
--[[
|
|
trafficIconsVisibility: [0, 1] for the visibility of traffic icons and divider bar (causes other elements to be shifted)
|
|
opacity: the current opacity of the widget
|
|
maxTextLineWidth: the maximum width of the text widget
|
|
xStartWithOutTrafficIcons: x-offset without traffic icons displayed
|
|
xStartWithTrafficIcons: x-offset with traffic icons displayed
|
|
return:
|
|
textLineSize: layout related size vector of the icon text line and the service icons
|
|
doubleTextLineSize: layout related size vector of the two-lined text widget
|
|
iconTextPosition: layout related position vector of the icon text line and the two-lined text widget
|
|
serviceIconPosition: layout related position vector of the service icons
|
|
directionPosition: layout related position vector of the direction arrow
|
|
trafficElementsOpacity: opacity of traffic related content
|
|
--]]
|
|
function roadbookFrontContentLayout(trafficIconsVisibility, opacity, maxTextLineWidth, xStartWithOutTrafficIcons, xStartWithTrafficIcons)
|
|
-- TODO: shift direction position less? (only 35px?)
|
|
local xOffset = roadbookMapInterpolated({{0.0, xStartWithOutTrafficIcons}, {0.6, xStartWithTrafficIcons}}, trafficIconsVisibility);
|
|
local trafficOpa = roadbookMapInterpolated({{0.7, 0.0}, {1.0, 1.0}}, trafficIconsVisibility);
|
|
|
|
local textLineSize = {x=maxTextLineWidth - xOffset, y=0, z=40}
|
|
local doubleTextLineSize = {x=maxTextLineWidth - xOffset, y=0, z=90}
|
|
local iconTextPosition = {x=25 + xOffset, y=0, z=-52}
|
|
local serviceIconPosition = {x=25 + xOffset, y=0, z=-97}
|
|
local directionPosition = {x=35 + xOffset, y=0, z=-212}
|
|
local trafficElementsOpacity = opacity * trafficOpa
|
|
|
|
return textLineSize, doubleTextLineSize, iconTextPosition, serviceIconPosition, directionPosition, trafficElementsOpacity
|
|
end
|
|
|
|
--[[
|
|
return:
|
|
tunnelIconOpacity: the current opacity for the widgets in tunnel maneuver layout
|
|
barGraphPosition: the bar graph widget position (not in tunnels, only normal and Asia Branch)
|
|
distancePosition: the distance text position for the widgets in non-tunnel maneuver layout
|
|
--]]
|
|
function roadboookBlowupContentLayout(isTunnelLayout, opacity, distanceVerticalOffset, distanceHorizontalOffset, barGraphVerticalOffset, barGraphHorizontalOffset)
|
|
local tunnelIconOpacity = 0.0
|
|
local px = 332
|
|
local py = -438
|
|
local of = 1.9 -- shadow/outline x/y offset
|
|
if isTunnelLayout then
|
|
tunnelIconOpacity = opacity
|
|
px = 234
|
|
end
|
|
py = py + distanceVerticalOffset
|
|
local barGraphPosition = {x=px + 170 + barGraphHorizontalOffset, y=0, z=py + 63 + barGraphVerticalOffset}
|
|
return tunnelIconOpacity, barGraphPosition, {x=px + distanceHorizontalOffset, y=0, z=py}
|
|
end
|
|
|
|
--[[
|
|
size: the given size vector
|
|
return: a size vector where z is divided by 2
|
|
--]]
|
|
function roadbookTrafficSegmentSize(size)
|
|
return {x = size.x, y = size.y, z = size.z/2}
|
|
end
|
|
|
|
function roadbookDelayOpacity(delayTimeString, baseOpacity)
|
|
if delayTimeString == "" then
|
|
return 0.0
|
|
end
|
|
return baseOpacity
|
|
end
|
|
|
|
--[[
|
|
guidanceState: the guidance state
|
|
headlineContentVisible: is there any DTD/ETA/... info visible?
|
|
return:
|
|
opacity of the black headline background
|
|
sortOrder of the black headline background
|
|
--]]
|
|
function roadbookHeadlineBackground(guidanceState, headlineContentVisible)
|
|
if headlineContentVisible and (guidanceState == ROADBOOK_GUIDANCE_STATE_OFFROAD or
|
|
guidanceState == ROADBOOK_GUIDANCE_STATE_OFFROAD_ASIA) then
|
|
return 1.0, 0
|
|
elseif guidanceState == ROADBOOK_GUIDANCE_STATE_CALCULATION or
|
|
guidanceState == ROADBOOK_GUIDANCE_STATE_CALCULATION_ASIA then
|
|
return 1.0, 6
|
|
else
|
|
return 0.0, 0
|
|
end
|
|
end
|
|
|
|
--[[
|
|
guidanceState: the guidance state
|
|
return:
|
|
opacity of the "Calculating route..." text
|
|
--]]
|
|
function roadbookHeadlineCalculatingText(guidanceState)
|
|
if guidanceState == ROADBOOK_GUIDANCE_STATE_CALCULATION or
|
|
guidanceState == ROADBOOK_GUIDANCE_STATE_CALCULATION_ASIA then
|
|
return 1.0
|
|
else
|
|
return 0.0
|
|
end
|
|
end
|
|
|
|
function roadbookLabelsGuidanceState(guidingStep, isDoubleManeuver, parentOpacity)
|
|
opacityDirection = parentOpacity
|
|
opacityDtM = parentOpacity
|
|
opacityComingRoad = parentOpacity
|
|
opacityGS3 = parentOpacity
|
|
layerEnabled = false
|
|
opacityFrame = parentOpacity
|
|
opacityFrameDoubleManeuver = 0.0
|
|
|
|
if guidingStep == ROADBOOK_GS_3_1 or guidingStep == ROADBOOK_GS_3_2 then
|
|
opacityComingRoad = 0.0
|
|
opacityDtM = 0.0
|
|
opacityComingRoad = 0.0
|
|
opacityDirection = 0.0
|
|
opacityFrameDoubleManeuver = 0.0
|
|
layerEnabled = true
|
|
else
|
|
opacityGS3 = 0.0
|
|
if isDoubleManeuver == true then
|
|
opacityDirection = parentOpacity * 0.5
|
|
opacityDtM = 0.0
|
|
opacityComingRoad = 0.0
|
|
opacityFrameDoubleManeuver = parentOpacity
|
|
opacityFrame = 0.0
|
|
elseif guidingStep == ROADBOOK_GS_1 or guidingStep == ROADBOOK_GS_0 then
|
|
opacityComingRoad = 0.0
|
|
end
|
|
end
|
|
|
|
return opacityDirection, opacityDtM, opacityComingRoad, opacityFrame, opacityFrameDoubleManeuver, opacityGS3, layerEnabled
|
|
end
|
|
|
|
function roadbookLabelsGuidanceLaneGuidingState(guidingStep, parentOpacity, useCutoutFrame)
|
|
opacity = parentOpacity
|
|
opacityCutoutFrame = parentOpacity
|
|
|
|
if guidingStep == ROADBOOK_GS_1 then
|
|
opacityCutoutFrame = 0.0
|
|
end
|
|
|
|
if useCutoutFrame == true then
|
|
opacityNormalFrame = parentOpacity - opacityCutoutFrame
|
|
else
|
|
opacityNormalFrame = parentOpacity
|
|
end
|
|
|
|
|
|
return opacity, opacityNormalFrame, opacityCutoutFrame
|
|
end
|
|
|
|
|
|
function roadbookLabelsGuidanceStateSize(guidingStep, width, showComingRoad)
|
|
height = 103.0
|
|
|
|
if guidingStep == ROADBOOK_GS_1 or guidingStep == ROADBOOK_GS_0 then
|
|
height = 60.0
|
|
elseif guidingStep == ROADBOOK_GS_3_1 or guidingStep == ROADBOOK_GS_3_2 then
|
|
height = 232.0
|
|
if showComingRoad then
|
|
height = height + 45.0
|
|
end
|
|
end
|
|
|
|
return { x=width, y=0.0, z=height }
|
|
end
|
|
|
|
function roadbookCurrentLaneIndicatorPosition(laneIndicatorPosition, basePosition)
|
|
xValue = laneIndicatorPosition
|
|
return { x=basePosition.x + xValue, y=basePosition.y, z=basePosition.z }
|
|
end
|
|
|
|
function roadbookLabelsGuidanceLanePosition(laneCount, offset)
|
|
width = 4.0 + 8.0 - 1.0 + laneCount * ( 36.0 + 4.0 )
|
|
width = width + offset;
|
|
height = 0.0
|
|
return { x=width, y=0.0, z=height }
|
|
end
|
|
|
|
function roadbookLabelsGuidanceBackgroundOpacity(parentOpacity, guidingStep)
|
|
opacityGS1 = parentOpacity
|
|
opacityGS2 = parentOpacity
|
|
|
|
if guidingStep == ROADBOOK_GS_1 then
|
|
opacityGS2 = 0
|
|
else
|
|
opacityGS1 = 0
|
|
end
|
|
|
|
return opacityGS1, opacityGS2
|
|
end
|
|
|
|
--[[
|
|
numberOfLanes: number of available lanes
|
|
currentLaneIndex: the index of the current lane
|
|
return:
|
|
visibility of the current lane
|
|
position of the current lane
|
|
position of the current lane separator
|
|
position of the current lane sector
|
|
--]]
|
|
function roadbookLabelLaneProperties(numberOfLanes, currentLaneIndex, positionOffset)
|
|
pos = -40.0 * ( numberOfLanes - currentLaneIndex )
|
|
separatorPos = pos - 4.0
|
|
positionOffset.x = positionOffset.x + pos
|
|
visibility = 0.0
|
|
|
|
if numberOfLanes >= currentLaneIndex and numberOfLanes ~= 0 then
|
|
visibility = 1.0
|
|
end
|
|
|
|
return visibility, positionOffset, { x=separatorPos, y=0.0, z=0.0 }, { x=pos, y=0.0, z=8.0 }
|
|
end
|
|
|
|
function roadbookLabelsComingRoadFadeDelay( opacityTo )
|
|
if opacityTo > 0 then
|
|
return 500
|
|
end
|
|
|
|
return 1
|
|
end
|
|
|
|
function roadbookLabelsBarGraphFadeDelay( opacityTo )
|
|
delay = 1
|
|
|
|
if opacityTo > 0 then
|
|
delay = 500
|
|
end
|
|
|
|
return delay
|
|
end
|
|
|
|
function roadbookLabelsHighguidingFadeDuration( opacityTo, animDuration )
|
|
duration = 1
|
|
|
|
if opacityTo > 0 then
|
|
duration = animDuration
|
|
end
|
|
|
|
return duration
|
|
end
|
|
|
|
function roadbookLabelsHighguidingSize( size, showComingRoad )
|
|
size.x = size.x - 12.0
|
|
size.z = size.z - 11.0
|
|
|
|
if showComingRoad then
|
|
size.z = size.z - 45.0
|
|
end
|
|
|
|
if size.x < 0.0 then
|
|
size.x = 0.0
|
|
end
|
|
|
|
if size.z < 0.0 then
|
|
size.z = 0.0
|
|
end
|
|
|
|
return size
|
|
end
|
|
|
|
function roadbookLabelsComingRoadLineSizeScript( width )
|
|
spacerWidth = 10.0
|
|
sizeX = width - spacerWidth - spacerWidth -- start and end spacers
|
|
|
|
return { x=sizeX, y=0.0, z=41.0 }
|
|
end
|
|
|
|
function roadbookLabelsDistanceLineSizeScript( width )
|
|
spacerWidth = 10.0
|
|
iconWidth = 113.0
|
|
iconRightBorderTransparency = 45.0
|
|
sizeX = width - iconWidth + iconRightBorderTransparency - spacerWidth - spacerWidth - spacerWidth -- spacers at start and end and between icon/distance
|
|
|
|
return { x=sizeX, y=0.0, z=41.0 }
|
|
end
|
|
|
|
function roadbookLabelLaneGS2BackgroundOpacity( opacity, useCutoutFrame )
|
|
if useCutoutFrame == true then
|
|
return opacity
|
|
end
|
|
|
|
return 0.0
|
|
end
|
|
|
|
function roadbookLabelsLaneGuidingBackgroundSize( guidingStep, gs1Size, gs2Size, useCutoutFrame )
|
|
if guidingStep == 1 then
|
|
return gs1Size
|
|
end
|
|
|
|
if useCutoutFrame == true then
|
|
return gs1Size
|
|
end
|
|
|
|
return gs2Size
|
|
end
|
|
|
|
function roadbookLabelsComingRoadBackgroundSize( size )
|
|
if size.z > 42.0 then
|
|
size.z = 42.0
|
|
end
|
|
|
|
size.x = size.x - 12.0
|
|
|
|
if size.x < 0.0 then
|
|
size.x = 0.0
|
|
end
|
|
|
|
return size
|
|
end
|
|
|
|
function roadbookLabelsComingRoadLineSize( size )
|
|
if size.z > 47.0 then
|
|
size.z = 47.0
|
|
end
|
|
|
|
size.x = size.x - 20.0
|
|
|
|
if size.x < 0.0 then
|
|
size.x = 0.0
|
|
end
|
|
|
|
return size
|
|
end
|
|
|
|
function roadbookLabelsComingRoadPosition( size )
|
|
size.x = 0.0
|
|
size.z = size.z - 47.0
|
|
return size
|
|
end
|
|
|
|
function roadbookTextOutlinePositions( size )
|
|
return { x=-size, y=0.0, z=-size }, { x=-size, y=0.0, z=size }, { x=size, y=0.0, z=-size }, { x=size, y=0.0, z=size }
|
|
end
|
|
|
|
|
|
--[[
|
|
widgetTopOffset: the amount of pixels that the layer widget (height = 485) is shifted downwards, with 0 it being aligned with the top of the screen
|
|
widgetWidth: the size of the texture image widget
|
|
widgetHeight: see above
|
|
widgetExtraOffset: a vec3 that is subtracted from the widgetWidth/Height (i.e. can be used to expand/shrink the widget size)
|
|
return:
|
|
a (x,y, w,h) texture coordinate vector
|
|
--]]
|
|
function roadbookAssetLayerMaskTexCoords(widgetTopOffset, widgetWidth, widgetHeight, widgetExtraOffset)
|
|
local texWidth = 32
|
|
local texHeight = 96
|
|
local texCoordW = (widgetWidth - widgetExtraOffset.x) / texWidth
|
|
local texCoordH = (widgetHeight - widgetExtraOffset.z) / texHeight
|
|
local texCoordStartOffsetY = (55.0 - widgetTopOffset) / texHeight
|
|
return { x=0.0, y=texCoordStartOffsetY, z=texCoordW, w=texCoordH }
|
|
end
|
|
|
|
--[[
|
|
carHeading: heading of the car [0..1[
|
|
return:
|
|
rotation value [0..360[
|
|
--]]
|
|
function roadbookFlatCompassScalesRotation(carHeading)
|
|
return { x=0.0, y=carHeading*360.0, z=0.0 }
|
|
end
|
|
|
|
--[[
|
|
offset: current offset [0..1]
|
|
range: +- threashold
|
|
return:
|
|
mapped value from [0-range..1+range]
|
|
--]]
|
|
function roadbookMapAlphaMaskValue( offset, range )
|
|
return ( 1.0 + range * 2.0 ) * offset - range
|
|
end
|
|
|
|
--[[
|
|
panelPos: current panel position [0.0..5.0] (S_FUTURE, S_FAR, S_NEAR, S_FRONT, S_BLOWUP, S_BEHIND)
|
|
blowUp: current blowup value
|
|
return:
|
|
previewContentOpacity
|
|
previewTrafficContentOpacity
|
|
fullContentOpacity
|
|
--]]
|
|
function roadbookMapPanelPositionToOpacity( panelPos, blowUp, isDeviate )
|
|
local S_FUTURE = 0.0
|
|
local S_FAR = 1.0
|
|
local S_NEAR = 2.0
|
|
local S_NEAR_FRONT = 2.5
|
|
local S_FRONT = 3.0
|
|
local S_FRONT_BLOWUP = 3.5
|
|
local S_BLOWUP = 4.0
|
|
local S_BEHIND = 5.0
|
|
|
|
if isDeviate == true then
|
|
return 0.0, 0.0, 0.0
|
|
end
|
|
|
|
panelPos = panelPos + 1
|
|
|
|
local previewContentOpacity = roadbookMapInterpolated({{S_FUTURE, 0.0}, {S_FAR, 0.29}, {S_NEAR, 0.55}, {S_NEAR_FRONT, 0.0}}, panelPos)
|
|
local previewTrafficContentOpacity = roadbookMapInterpolated({{S_FUTURE, 0.0}, {S_FAR, 0.6}, {S_NEAR, 0.8}, {S_NEAR_FRONT, 0.0}}, panelPos)
|
|
local fullContentOpacity = roadbookMapInterpolated({{S_NEAR_FRONT, 0.0}, {S_FRONT, 1.0}, {S_FRONT_BLOWUP, 0.0}, {S_BEHIND, 0.0}}, panelPos)
|
|
|
|
local blowUpScale = roadbookMapInterpolated({{1.0, 1.0}, {2.0, 0.0}}, blowUp)
|
|
fullContentOpacity = fullContentOpacity * blowUpScale
|
|
|
|
return previewContentOpacity, previewTrafficContentOpacity, fullContentOpacity
|
|
end
|
|
|