ESO Lua File v100015

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
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: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 = (2 * math.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:AddNode(node)
    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 % (2 * math.pi)
    self.rootNode:SetRotation(self.currentAngle)
end
function ZO_SceneNodeRing:GetNodeAtAngle(radians)
    radians = (radians - self.rootNode:GetRotation()) % (2 * math.pi)
    local closestNode
    local closestDistance
    for _, node in ipairs(self.ringNodes) do
        local nodeAngle = node:GetRotation()
        local distance = zo_abs(nodeAngle - radians)
        if distance > math.pi then
            distance = 2 * math.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: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