117 | function AnimationValueFloat:init(index, numParts) |
118 | for j=index+1, numParts do |
119 | local part2 = self.animation.parts[j] |
120 | if self.part.direction == part2.direction then |
121 | local animationValue2 |
122 | for secondIndex=1, #part2.animationValues do |
123 | local secondAnimValue = part2.animationValues[secondIndex] |
124 | if secondAnimValue.endName == self.endName then |
125 | local allowed = true |
126 | for paramIndex=1, #self.compareParams do |
127 | local param = self.compareParams[paramIndex] |
128 | if secondAnimValue[param] ~= self[param] then |
129 | allowed = false |
130 | end |
131 | end |
132 | |
133 | if allowed then |
134 | animationValue2 = secondAnimValue |
135 | end |
136 | end |
137 | end |
138 | |
139 | if animationValue2 ~= nil then |
140 | if self.part.startTime + self.part.duration > part2.startTime+0.001 then |
141 | Logging.xmlWarning(self.xmlFile, "Overlapping %s parts for '%s' in animation '%s'", self.name, self.warningInfo, self.animation.name) |
142 | end |
143 | |
144 | self.nextPart = animationValue2.part |
145 | animationValue2.prevPart = self.part |
146 | if animationValue2.startValue == nil then |
147 | animationValue2.startValue = {unpack(self.endValue)} |
148 | end |
149 | |
150 | break |
151 | end |
152 | end |
153 | end |
154 | end |
176 | function AnimationValueFloat:initValues(targetValue, durationToEnd, fixedTimeUpdate, ...) |
177 | self.curValue = self.curValue or self.oldCurValues |
178 | |
179 | local numValues = select("#", ...) |
180 | for i = 1, numValues do |
181 | self.curValue[i] = select(i, ...) |
182 | end |
183 | |
184 | local invDuration = 1.0 / math.max(durationToEnd, 0.001) |
185 | |
186 | self.speed = {} |
187 | for i=1, #self.curValue do |
188 | self.speed[i] = (targetValue[i]-self.curValue[i])*invDuration |
189 | |
190 | self.curStartValue[i] = self.curValue[i] |
191 | self.curRealValue[i] = self.curValue[i] |
192 | end |
193 | |
194 | if fixedTimeUpdate == true then |
195 | -- for fixed time updates (e.g. setAnimationTime) we use directly start and end values instead |
196 | -- of interpolating from the current position to the target as we normally do |
197 | -- this helps us to set the spline tangent type values correctly |
198 | if self.animation.currentSpeed < 0 then |
199 | for i=1, numValues do |
200 | self.curStartValue[i] = self.endValue[i] |
201 | end |
202 | else |
203 | for i=1, numValues do |
204 | self.curStartValue[i] = self.startValue[i] |
205 | end |
206 | end |
207 | end |
208 | |
209 | self.curTargetValue = targetValue |
210 | |
211 | return self.initialUpdate |
212 | end |
51 | function AnimationValueFloat:load(xmlFile, key) |
52 | if self.startName ~= "" then |
53 | self.startValue = xmlFile:getValue(key .. "#" .. self.startName, nil, true) |
54 | |
55 | if type(self.startValue) == "number" then |
56 | self.startValue = {self.startValue} |
57 | elseif type(self.startValue) == "boolean" then |
58 | self.startValue = {self.startValue and 1 or 0} |
59 | end |
60 | end |
61 | |
62 | if self.endName ~= "" then |
63 | self.endValue = xmlFile:getValue(key .. "#" .. self.endName, nil, true) |
64 | |
65 | if type(self.endValue) == "number" then |
66 | self.endValue = {self.endValue} |
67 | elseif type(self.endValue) == "boolean" then |
68 | self.endValue = {self.endValue and 1 or 0} |
69 | end |
70 | end |
71 | |
72 | if self.endValue ~= nil or self.endName == "" then |
73 | self.warningInfo = key |
74 | self.xmlFile = xmlFile |
75 | |
76 | local success = self:extraLoad(xmlFile, key) |
77 | |
78 | if success then |
79 | local tangentTypeStr = xmlFile:getValue(key .. "#tangentType", "linear") |
80 | tangentTypeStr = "TANGENT_TYPE_" .. tangentTypeStr:upper() |
81 | if AnimationValueFloat[tangentTypeStr] ~= nil then |
82 | self.tangentType = AnimationValueFloat[tangentTypeStr] |
83 | else |
84 | self.tangentType = AnimationValueFloat.TANGENT_TYPE_LINEAR |
85 | end |
86 | |
87 | self.curStartValue = {} |
88 | self.curRealValue = {} |
89 | for i=1, #(self.startValue or self.endValue) do |
90 | self.curStartValue[i] = 0 |
91 | self.curRealValue[i] = 0 |
92 | end |
93 | |
94 | return true |
95 | end |
96 | end |
97 | |
98 | return false |
99 | end |
20 | function AnimationValueFloat.new(vehicle, animation, part, startName, endName, name, initialUpdate, get, set, extraLoad, customMt) |
21 | local self = setmetatable({}, customMt or AnimationValueFloat_mt) |
22 | |
23 | self.vehicle = vehicle |
24 | self.animation = animation |
25 | self.part = part |
26 | |
27 | self.startName = startName |
28 | self.endName = endName |
29 | self.name = name |
30 | |
31 | self.initialUpdate = initialUpdate |
32 | |
33 | self.get = get |
34 | self.set = set |
35 | self.extraLoad = extraLoad |
36 | |
37 | self.warningInfo = self.name |
38 | self.compareParams = {} |
39 | |
40 | self.oldCurValues = {} |
41 | self.oldSpeed = {} |
42 | |
43 | self.curValue = nil |
44 | self.speed = nil |
45 | |
46 | return self |
47 | end |
220 | function AnimationValueFloat:update(durationToEnd, dtToUse, realDt, fixedTimeUpdate) |
221 | if self.startValue ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(self.nextPart, self.prevPart, self.animation, true)) then |
222 | local targetValue = self.endValue |
223 | if self.animation.currentSpeed < 0 then |
224 | targetValue = self.startValue |
225 | end |
226 | |
227 | local forceUpdate = false |
228 | if self.curValue == nil then |
229 | forceUpdate = self:initValues(targetValue, durationToEnd, fixedTimeUpdate, self:get()) |
230 | end |
231 | |
232 | if AnimatedVehicle.setMovedLimitedValuesN(#self.curValue, self.curValue, targetValue, self.speed, realDt) or forceUpdate then |
233 | if self.tangentType == AnimationValueFloat.TANGENT_TYPE_LINEAR then |
234 | self:set(unpack(self.curValue)) |
235 | elseif self.tangentType == AnimationValueFloat.TANGENT_TYPE_SPLINE then |
236 | for i=1, #self.curValue do |
237 | local alpha = (self.curValue[i] - self.curStartValue[i]) / (self.curTargetValue[i] - self.curStartValue[i]) |
238 | if fixedTimeUpdate == true then |
239 | alpha = 1 - MathUtil.clamp((durationToEnd - realDt) / self.part.duration, 0, 1) |
240 | end |
241 | |
242 | if alpha >= 0 and alpha <= 1 then |
243 | self.curRealValue[i] = getSplineAlpha(alpha) * (self.curTargetValue[i] - self.curStartValue[i]) + self.curStartValue[i] |
244 | else |
245 | self.curRealValue[i] = self.curValue[i] |
246 | end |
247 | end |
248 | |
249 | self:set(unpack(self.curRealValue)) |
250 | elseif self.tangentType == AnimationValueFloat.TANGENT_TYPE_STEP then |
251 | for i=1, #self.curValue do |
252 | local alpha = (self.curValue[i] - self.curStartValue[i]) / (self.curTargetValue[i] - self.curStartValue[i]) |
253 | if alpha >= 1 then |
254 | self.curRealValue[i] = self.curValue[i] |
255 | else |
256 | self.curRealValue[i] = self.curStartValue[i] |
257 | end |
258 | end |
259 | |
260 | self:set(unpack(self.curRealValue)) |
261 | end |
262 | |
263 | return true |
264 | end |
265 | end |
266 | |
267 | return false |
268 | end |