Back to Home

ESO Lua File v101039

libraries/zo_scenenodering/zo_scenenodering.lua

[◄ back to folders ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
ZO_SceneNodeRing = ZO_Object:Subclass()
function ZO_SceneNodeRing:New(...)
    local object = ZO_Object.New(self)
    object:Initialize(...)
    return object
end
function ZO_SceneNodeRing:Initialize(rootNode)
    self.rootNode = rootNode
    self.sceneGraph = rootNode:GetSceneGraph()
    self.angularVelocity = 0
    self.currentAngle = 0
    self.nodePositionsDirty = false
    self.ringNodes = {}
end
function ZO_SceneNodeRing:SetRadius(radius)
    if radius ~= self.radius then
        self.radius = radius
        self.nodePositionsDirty = true
    end
end
function ZO_SceneNodeRing:GetNodePadding(node)
    return node.ringPadding
end
function ZO_SceneNodeRing:SetNodePadding(node, radians)
    if radians ~= node.ringPadding then
        node.ringPadding = radians
        self.nodePositionsDirty = true
    end
end
function ZO_SceneNodeRing:SetAllNodesPadding(radians)
    for i, node in ipairs(self.ringNodes) do
        node.ringPadding = radians
    end
    self.nodePositionsDirty = true
end
function ZO_SceneNodeRing:RefreshNodePositions()
    if self.nodePositionsDirty then
        self.nodePositionsDirty = false
        local totalPadding = 0
        for i, node in ipairs(self.ringNodes) do
            totalPadding = totalPadding + node.ringPadding
        end
        --padding is on both side of a node
        totalPadding = totalPadding * 2
        local nodeArcSize = (ZO_TWO_PI - totalPadding) / #self.ringNodes
        local currentAngle = 0
        for i, node in ipairs(self.ringNodes) do
            local nextNodeIndex = i % #self.ringNodes + 1
            local nextNode = self.ringNodes[nextNodeIndex]
            node:SetX(self.radius)
            node:SetRotation(-currentAngle)
            currentAngle = currentAngle + nodeArcSize + node.ringPadding + nextNode.ringPadding
        end
    end
end
function ZO_SceneNodeRing:ClearNodes()
    for _, node in ipairs(self.ringNodes) do
        self.sceneGraph:RemoveNode(node)
    end
end
function ZO_SceneNodeRing:AddNode(node)
    node:SetParent(self.rootNode)
    node.ringPadding = 0
    table.insert(self.ringNodes, node)
    self.nodePositionsDirty = true
end
function ZO_SceneNodeRing:SetAngularVelocity(radiansPerSecond)
    self.angularVelocity = radiansPerSecond
end
function ZO_SceneNodeRing:GetAngle()
    return self.currentAngle
end
function ZO_SceneNodeRing:SetAngle(angle)
    self.currentAngle = angle % ZO_TWO_PI
    self.rootNode:SetRotation(self.currentAngle)
end
function ZO_SceneNodeRing:GetNodeAtAngle(radians)
    radians = (radians - self.rootNode:GetRotation()) % ZO_TWO_PI
    local closestNode
    local closestDistance
    for _, node in ipairs(self.ringNodes) do
        local nodeAngle = node:GetRotation()
        local distance = zo_abs(nodeAngle - radians)
        if distance > ZO_PI then
            distance = ZO_TWO_PI - distance
        end
        if not closestNode or distance < closestDistance then
            closestNode = node
            closestDistance = distance
        end
    end
    return closestNode
end
function ZO_SceneNodeRing:GetNextNode(node)
    for i, currentNode in ipairs(self.ringNodes) do
        if currentNode == node then
            return self.ringNodes[i % #self.ringNodes + 1]
        end
    end
end
function ZO_SceneNodeRing:GetPreviousNode(node)
    for i, currentNode in ipairs(self.ringNodes) do
        if currentNode == node then
            local prevIndex = i - 1
            if prevIndex == 0 then
                prevIndex = #self.ringNodes
            end
            return self.ringNodes[prevIndex]
        end
    end
end
function ZO_SceneNodeRing:NodeIterator(filterFunctions)
    return ZO_FilteredNumericallyIndexedTableIterator(self.ringNodes, filterFunctions)
end
function ZO_SceneNodeRing:GetAngularVelocity()
    return self.angularVelocity
end
function ZO_SceneNodeRing:Update(delta)
    if not self.sceneGraph:IsHidden() then
        self:RefreshNodePositions()
        self.currentAngle = self.currentAngle + self.angularVelocity * delta
        self.rootNode:SetRotation(self.currentAngle)
    end
end