23 | function Ropes.initSpecialization() |
24 | local schema = Vehicle.xmlSchema |
25 | schema:setXMLSpecializationType("Ropes") |
26 | |
27 | schema:register(XMLValueType.NODE_INDEX, "vehicle.ropes.rope(?)#baseNode", "Base node") |
28 | schema:register(XMLValueType.NODE_INDEX, "vehicle.ropes.rope(?)#targetNode", "Target node") |
29 | schema:register(XMLValueType.VECTOR_4, "vehicle.ropes.rope(?)#baseParameters", "Base parameters") |
30 | schema:register(XMLValueType.VECTOR_4, "vehicle.ropes.rope(?)#targetParameters", "Target parameters") |
31 | |
32 | schema:register(XMLValueType.NODE_INDEX, "vehicle.ropes.rope(?).baseParameterAdjuster(?)#node", "Adjuster node") |
33 | schema:register(XMLValueType.INT, "vehicle.ropes.rope(?).baseParameterAdjuster(?)#rotationAxis", "Rotation axis") |
34 | schema:register(XMLValueType.VECTOR_ROT_2, "vehicle.ropes.rope(?).baseParameterAdjuster(?)#rotationRange", "Rotation range") |
35 | schema:register(XMLValueType.INT, "vehicle.ropes.rope(?).baseParameterAdjuster(?)#translationAxis", "Translation axis") |
36 | schema:register(XMLValueType.VECTOR_2, "vehicle.ropes.rope(?).baseParameterAdjuster(?)#translationRange", "Translation range") |
37 | schema:register(XMLValueType.VECTOR_4, "vehicle.ropes.rope(?).baseParameterAdjuster(?)#minTargetParameters", "Min. target parameters") |
38 | schema:register(XMLValueType.VECTOR_4, "vehicle.ropes.rope(?).baseParameterAdjuster(?)#maxTargetParameters", "Max. target parameters") |
39 | |
40 | schema:register(XMLValueType.NODE_INDEX, "vehicle.ropes.rope(?).targetParameterAdjuster(?)#node", "Adjuster node") |
41 | schema:register(XMLValueType.INT, "vehicle.ropes.rope(?).targetParameterAdjuster(?)#rotationAxis", "Rotation axis") |
42 | schema:register(XMLValueType.VECTOR_ROT_2, "vehicle.ropes.rope(?).targetParameterAdjuster(?)#rotationRange", "Rotation range") |
43 | schema:register(XMLValueType.INT, "vehicle.ropes.rope(?).targetParameterAdjuster(?)#translationAxis", "Translation axis") |
44 | schema:register(XMLValueType.VECTOR_2, "vehicle.ropes.rope(?).targetParameterAdjuster(?)#translationRange", "Translation range") |
45 | schema:register(XMLValueType.VECTOR_4, "vehicle.ropes.rope(?).targetParameterAdjuster(?)#minTargetParameters", "Min. target parameters") |
46 | schema:register(XMLValueType.VECTOR_4, "vehicle.ropes.rope(?).targetParameterAdjuster(?)#maxTargetParameters", "Max. target parameters") |
47 | |
48 | schema:setXMLSpecializationType() |
49 | end |
154 | function Ropes:loadAdjusterNode(adjusterNode, xmlFile, key) |
155 | XMLUtil.checkDeprecatedXMLElements(xmlFile, key .. "#index", key .. "#node") --FS17 to FS19 |
156 | |
157 | local node = xmlFile:getValue(key .. "#node", nil, self.components, self.i3dMappings) |
158 | if node ~= nil then |
159 | adjusterNode.node = node |
160 | |
161 | adjusterNode.rotationAxis = xmlFile:getValue(key .. "#rotationAxis", 1) |
162 | adjusterNode.rotationRange = xmlFile:getValue(key .. "#rotationRange", nil, true) |
163 | |
164 | adjusterNode.translationAxis = xmlFile:getValue(key .. "#translationAxis", 1) |
165 | adjusterNode.translationRange = xmlFile:getValue(key .. "#translationRange", nil, true) |
166 | |
167 | adjusterNode.minTargetParameters = xmlFile:getValue(key .. "#minTargetParameters", nil, true) |
168 | if adjusterNode.minTargetParameters == nil then |
169 | Logging.xmlWarning(self.xmlFile, "Missing minTargetParameters attribute in '%s'", key) |
170 | return false |
171 | end |
172 | |
173 | adjusterNode.maxTargetParameters = xmlFile:getValue(key .. "#maxTargetParameters", nil, true) |
174 | if adjusterNode.maxTargetParameters == nil then |
175 | Logging.xmlWarning(self.xmlFile, "Missing maxTargetParameters attribute in '%s'", key) |
176 | return false |
177 | end |
178 | |
179 | return true |
180 | else |
181 | Logging.xmlWarning(self.xmlFile, "Missing node attribute in '%s'", key) |
182 | end |
183 | |
184 | return false |
185 | end |
70 | function Ropes:onLoad(savegame) |
71 | local spec = self.spec_ropes |
72 | |
73 | if self.isClient then |
74 | spec.ropes = {} |
75 | local i = 0 |
76 | while true do |
77 | local key = string.format("vehicle.ropes.rope(%d)", i) |
78 | if not self.xmlFile:hasProperty(key) then |
79 | break |
80 | end |
81 | |
82 | local entry = {} |
83 | entry.baseNode = self.xmlFile:getValue(key .. "#baseNode", nil, self.components, self.i3dMappings) |
84 | entry.targetNode = self.xmlFile:getValue(key .. "#targetNode", nil, self.components, self.i3dMappings) |
85 | entry.baseParameters = self.xmlFile:getValue(key .. "#baseParameters", nil, true) |
86 | entry.targetParameters = self.xmlFile:getValue(key .. "#targetParameters", nil, true) |
87 | |
88 | setShaderParameter(entry.baseNode, "cv0", entry.baseParameters[1], entry.baseParameters[2], entry.baseParameters[3], entry.baseParameters[4], false) |
89 | setShaderParameter(entry.baseNode, "cv1", 0, 0, 0, 0, false) |
90 | local x,y,z = localToLocal(entry.targetNode, entry.baseNode, entry.targetParameters[1], entry.targetParameters[2], entry.targetParameters[3]) |
91 | setShaderParameter(entry.baseNode, "cv3", x, y, z, 0, false) |
92 | |
93 | entry.baseParameterAdjusters = {} |
94 | local j = 0 |
95 | while true do |
96 | local adjusterKey = string.format("%s.baseParameterAdjuster(%d)", key, j) |
97 | if not self.xmlFile:hasProperty(adjusterKey) then |
98 | break |
99 | end |
100 | |
101 | local adjusterNode = {} |
102 | if self:loadAdjusterNode(adjusterNode, self.xmlFile, adjusterKey)then |
103 | table.insert(entry.baseParameterAdjusters, adjusterNode) |
104 | end |
105 | |
106 | j = j + 1 |
107 | end |
108 | |
109 | entry.targetParameterAdjusters = {} |
110 | j = 0 |
111 | while true do |
112 | local adjusterKey = string.format("%s.targetParameterAdjuster(%d)", key, j) |
113 | if not self.xmlFile:hasProperty(adjusterKey) then |
114 | break |
115 | end |
116 | |
117 | local adjusterNode = {} |
118 | if self:loadAdjusterNode(adjusterNode, self.xmlFile, adjusterKey)then |
119 | table.insert(entry.targetParameterAdjusters, adjusterNode) |
120 | end |
121 | |
122 | j = j + 1 |
123 | end |
124 | |
125 | table.insert(spec.ropes, entry) |
126 | i = i + 1 |
127 | end |
128 | end |
129 | |
130 | if not self.isClient or #spec.ropes == 0 then |
131 | SpecializationUtil.removeEventListener(self, "onLoadFinished", Ropes) |
132 | SpecializationUtil.removeEventListener(self, "onUpdate", Ropes) |
133 | end |
134 | end |
207 | function Ropes:updateAdjusterNodes(adjusterNodes) |
208 | local xRet, yRet, zRet = 0, 0, 0 |
209 | for _, adjusterNode in pairs(adjusterNodes) do |
210 | if adjusterNode.rotationAxis ~= nil and adjusterNode.rotationRange ~= nil then |
211 | local rotations = { getRotation(adjusterNode.node) } |
212 | local rot = rotations[adjusterNode.rotationAxis] |
213 | local alpha = math.max(0, math.min(1, (rot - adjusterNode.rotationRange[1]) / (adjusterNode.rotationRange[2] - adjusterNode.rotationRange[1]) )) |
214 | local x, y, z = MathUtil.vector3ArrayLerp(adjusterNode.minTargetParameters, adjusterNode.maxTargetParameters, alpha) |
215 | xRet, yRet, zRet = xRet+x, yRet+y, zRet+z |
216 | elseif adjusterNode.translationAxis ~= nil and adjusterNode.translationRange ~= nil then |
217 | local translations = { getTranslation(adjusterNode.node) } |
218 | local trans = translations[adjusterNode.translationAxis] |
219 | local alpha = math.max(0, math.min(1, (trans - adjusterNode.translationRange[1]) / (adjusterNode.translationRange[2] - adjusterNode.translationRange[1]) )) |
220 | local x, y, z = MathUtil.vector3ArrayLerp(adjusterNode.minTargetParameters, adjusterNode.maxTargetParameters, alpha) |
221 | xRet, yRet, zRet = xRet+x, yRet+y, zRet+z |
222 | end |
223 | end |
224 | |
225 | return xRet, yRet, zRet |
226 | end |
189 | function Ropes:updateRopes(dt) |
190 | local spec = self.spec_ropes |
191 | for _, rope in pairs(spec.ropes) do |
192 | local x, y, z = self:updateAdjusterNodes(rope.baseParameterAdjusters) |
193 | setShaderParameter(rope.baseNode, "cv0", rope.baseParameters[1]+x, rope.baseParameters[2]+y, rope.baseParameters[3]+z, 0, false) |
194 | |
195 | x, y, z = localToLocal(rope.targetNode, rope.baseNode, 0, 0, 0) |
196 | setShaderParameter(rope.baseNode, "cv2", 0, 0, 0, 0, false) |
197 | setShaderParameter(rope.baseNode, "cv3", x, y, z, 0, false) |
198 | |
199 | x, y, z = self:updateAdjusterNodes(rope.targetParameterAdjusters) |
200 | x, y, z = localToLocal(rope.targetNode, rope.baseNode, rope.targetParameters[1]+x, rope.targetParameters[2]+y, rope.targetParameters[3]+z) |
201 | setShaderParameter(rope.baseNode, "cv4", x,y,z,0, false) |
202 | end |
203 | end |