262 | function FoliageBending:initializeAnimationPart(superFunc, animation, part, i, numParts) |
263 | |
264 | superFunc(self, animation, part, i, numParts) |
265 | |
266 | local initializeParts = function(startName, endName, nextPartName, prevPartName) |
267 | if part[endName] ~= nil then |
268 | for j=i+1, numParts do |
269 | local part2 = animation.parts[j] |
270 | if part.node == part2.node and part2[endName] ~= nil then |
271 | if part.direction == part2.direction and part.startTime + part.duration > part2[startName]+0.001 then |
272 | g_logManager:xmlWarning(self.configFileName, "Overlapping foliagebending parts for node '%s' in animation '%s'", getName(part.node), animation.name) |
273 | end |
274 | part[nextPartName] = part2 |
275 | part2[prevPartName] = part |
276 | if part2[startName] == nil then |
277 | part2[startName] = part[endName] |
278 | end |
279 | break |
280 | end |
281 | end |
282 | end |
283 | end |
284 | |
285 | initializeParts("startMinX", "endMinX", "nextMinXPart", "prevMinXPart") |
286 | initializeParts("startMaxX", "endMaxX", "nextMaxXPart", "prevMaxXPart") |
287 | initializeParts("startMinZ", "endMinZ", "nextMinZPart", "prevMinZPart") |
288 | initializeParts("startMaxZ", "endMaxZ", "nextMaxZPart", "prevMaxZPart") |
289 | initializeParts("startYOffset", "endYOffset", "nextYOffsetPart", "prevYOffsetPart") |
290 | end |
214 | function FoliageBending:loadAnimationPart(superFunc, xmlFile, partKey, part) |
215 | if not superFunc(self, xmlFile, partKey, part) then |
216 | return false |
217 | end |
218 | |
219 | local foliageBendingIndex = getXMLInt(xmlFile, partKey.."#foliageBendingIndex") |
220 | local startMinX = getXMLFloat(xmlFile, partKey.."#startMinX") |
221 | local endMinX = getXMLFloat(xmlFile, partKey.."#endMinX") |
222 | local startMaxX = getXMLFloat(xmlFile, partKey.."#startMaxX") |
223 | local endMaxX = getXMLFloat(xmlFile, partKey.."#endMaxX") |
224 | |
225 | local startMinZ = getXMLFloat(xmlFile, partKey.."#startMinZ") |
226 | local endMinZ = getXMLFloat(xmlFile, partKey.."#endMinZ") |
227 | local startMaxZ = getXMLFloat(xmlFile, partKey.."#startMaxZ") |
228 | local endMaxZ = getXMLFloat(xmlFile, partKey.."#endMaxZ") |
229 | |
230 | local startYOffset = getXMLFloat(xmlFile, partKey.."#startYOffset") |
231 | local endYOffset = getXMLFloat(xmlFile, partKey.."#endYOffset") |
232 | |
233 | if foliageBendingIndex ~= nil then |
234 | part.foliageBendingIndex = foliageBendingIndex |
235 | if startMinX ~= nil then |
236 | part.startMinX = startMinX |
237 | part.endMinX = endMinX |
238 | end |
239 | if startMaxX ~= nil then |
240 | part.startMaxX = startMaxX |
241 | part.endMaxX = endMaxX |
242 | end |
243 | if startMinZ ~= nil then |
244 | part.startMinZ = startMinZ |
245 | part.endMinZ = endMinZ |
246 | end |
247 | if startMaxZ ~= nil then |
248 | part.startMaxZ = startMaxZ |
249 | part.endMaxZ = endMaxZ |
250 | end |
251 | if startYOffset ~= nil then |
252 | part.startYOffset = startYOffset |
253 | part.endYOffset = endYOffset |
254 | end |
255 | end |
256 | |
257 | return true |
258 | end |
105 | function FoliageBending:loadBendingNodeFromXML(xmlFile, key, bendingNode) |
106 | local node = I3DUtil.indexToObject(self.components, getXMLString(xmlFile, key.."#node"), self.i3dMappings) |
107 | if node == nil then |
108 | node = self.rootNode |
109 | end |
110 | |
111 | bendingNode.node = node |
112 | bendingNode.key = key |
113 | bendingNode.minX = getXMLFloat(xmlFile, key.."#minX") or -1 |
114 | bendingNode.maxX = getXMLFloat(xmlFile, key.."#maxX") or 1 |
115 | bendingNode.minZ = getXMLFloat(xmlFile, key.."#minZ") or -1 |
116 | bendingNode.maxZ = getXMLFloat(xmlFile, key.."#maxZ") or 1 |
117 | bendingNode.yOffset = getXMLFloat(xmlFile, key.."#yOffset") or 0 |
118 | |
119 | return true |
120 | end |
124 | function FoliageBending:loadBendingNodeModifierFromXML(xmlFile, key) |
125 | local modifier = {} |
126 | |
127 | modifier.index = getXMLInt(xmlFile, key.."#index") |
128 | if modifier.index == nil then |
129 | g_logManager:xmlWarning(self.configFileName, "Missing bending node index for bending modifier '%s'", key) |
130 | return |
131 | end |
132 | modifier.minX = getXMLFloat(xmlFile, key.."#minX") |
133 | modifier.maxX = getXMLFloat(xmlFile, key.."#maxX") |
134 | modifier.minZ = getXMLFloat(xmlFile, key.."#minZ") |
135 | modifier.maxZ = getXMLFloat(xmlFile, key.."#maxZ") |
136 | modifier.yOffset = getXMLFloat(xmlFile, key.."#yOffset") |
137 | |
138 | local spec = self.spec_foliageBending |
139 | if spec.bendingModifiers == nil then |
140 | spec.bendingModifiers = {} |
141 | end |
142 | |
143 | table.insert(spec.bendingModifiers, modifier) |
144 | end |
53 | function FoliageBending:onLoad(savegame) |
54 | local spec = self.spec_foliageBending |
55 | |
56 | spec.bendingNodes = {} |
57 | local i = 0 |
58 | while true do |
59 | local key = string.format("vehicle.foliageBending.bendingNode(%d)", i) |
60 | if not hasXMLProperty(self.xmlFile, key) then |
61 | break |
62 | end |
63 | |
64 | local bendingNode = {} |
65 | if self:loadBendingNodeFromXML(self.xmlFile, key, bendingNode) then |
66 | table.insert(spec.bendingNodes, bendingNode) |
67 | bendingNode.index = #spec.bendingNodes |
68 | end |
69 | |
70 | i = i + 1 |
71 | end |
72 | end |
76 | function FoliageBending:onPostLoad(savegame) |
77 | local spec = self.spec_foliageBending |
78 | if spec.bendingModifiers ~= nil then |
79 | for _, modifier in ipairs(spec.bendingModifiers) do |
80 | local index = modifier.index |
81 | local bendingNode = spec.bendingNodes[index] |
82 | if bendingNode ~= nil then |
83 | bendingNode.minX = math.min(bendingNode.minX, modifier.minX or bendingNode.minX) |
84 | bendingNode.maxX = math.max(bendingNode.maxX, modifier.maxX or bendingNode.maxX) |
85 | bendingNode.minZ = math.min(bendingNode.minZ, modifier.minZ or bendingNode.minZ) |
86 | bendingNode.maxZ = math.max(bendingNode.maxZ, modifier.maxZ or bendingNode.maxZ) |
87 | bendingNode.yOffset = math.max(bendingNode.yOffset, modifier.yOffset or bendingNode.yOffset) |
88 | else |
89 | g_logManager:xmlWarning(self.configFileName, "Undefined bendingNode index '%d' for bending modifier '%s'!", index, modifier.key) |
90 | end |
91 | end |
92 | |
93 | spec.bendingModifiers = nil |
94 | end |
95 | end |
294 | function FoliageBending:postInitializeAnimationPart(superFunc, animation, part, i, numParts) |
295 | |
296 | superFunc(self, animation, part, i, numParts) |
297 | |
298 | if part.foliageBendingIndex ~= nil then |
299 | local defaultMinX = part.endMinX or 0 |
300 | local defaultMaxX = part.endMaxX or 0 |
301 | local defaultMinZ = part.endMinZ or 0 |
302 | local defaultMaxZ = part.endMaxZ or 0 |
303 | local defaultYOffset = part.endYOffset or 0 |
304 | local bendingNode = self:getFoliageBendingNodeByIndex(part.foliageBendingIndex) |
305 | |
306 | if bendingNode ~= nil then |
307 | defaultMinX = bendingNode.minX |
308 | defaultMaxX = bendingNode.maxX |
309 | defaultMinZ = bendingNode.minZ |
310 | defaultMaxZ = bendingNode.maxZ |
311 | defaultYOffset = bendingNode.yOffset |
312 | end |
313 | |
314 | if part.endMinX ~= nil and part.startMinX == nil then |
315 | part.startMinX = defaultMinX |
316 | end |
317 | if part.endMaxX ~= nil and part.startMaxX == nil then |
318 | part.startMaxX = defaultMaxX |
319 | end |
320 | if part.endMinZ ~= nil and part.startMinZ == nil then |
321 | part.startMinZ = defaultMinZ |
322 | end |
323 | if part.endMaxZ ~= nil and part.startMaxZ == nil then |
324 | part.startMaxZ = defaultMaxZ |
325 | end |
326 | if part.endYOffset ~= nil and part.startYOffset == nil then |
327 | part.startYOffset = defaultYOffset |
328 | end |
329 | end |
330 | end |
42 | function FoliageBending.registerEventListeners(vehicleType) |
43 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", FoliageBending) |
44 | SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", FoliageBending) |
45 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", FoliageBending) |
46 | SpecializationUtil.registerEventListener(vehicleType, "onActivate", FoliageBending) |
47 | SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", FoliageBending) |
48 | SpecializationUtil.registerEventListener(vehicleType, "onFinishedWheelLoading", FoliageBending) |
49 | end |
21 | function FoliageBending.registerFunctions(vehicleType) |
22 | SpecializationUtil.registerFunction(vehicleType, "loadBendingNodeFromXML", FoliageBending.loadBendingNodeFromXML) |
23 | SpecializationUtil.registerFunction(vehicleType, "loadBendingNodeModifierFromXML", FoliageBending.loadBendingNodeModifierFromXML) |
24 | SpecializationUtil.registerFunction(vehicleType, "activateBendingNodes", FoliageBending.activateBendingNodes) |
25 | SpecializationUtil.registerFunction(vehicleType, "deactivateBendingNodes", FoliageBending.deactivateBendingNodes) |
26 | SpecializationUtil.registerFunction(vehicleType, "getFoliageBendingNodeByIndex", FoliageBending.getFoliageBendingNodeByIndex) |
27 | SpecializationUtil.registerFunction(vehicleType, "updateFoliageBendingAttributes", FoliageBending.updateFoliageBendingAttributes) |
28 | end |
32 | function FoliageBending.registerOverwrittenFunctions(vehicleType) |
33 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadAnimationPart", FoliageBending.loadAnimationPart) |
34 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "initializeAnimationPart", FoliageBending.initializeAnimationPart) |
35 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "postInitializeAnimationPart", FoliageBending.postInitializeAnimationPart) |
36 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "updateAnimationPart", FoliageBending.updateAnimationPart) |
37 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "resetAnimationPartValues", FoliageBending.resetAnimationPartValues) |
38 | end |
334 | function FoliageBending:updateAnimationPart(superFunc, animation, part, durationToEnd, dtToUse, realDt) |
335 | local hasPartChanged = superFunc(self, animation, part, durationToEnd, dtToUse, realDt) |
336 | |
337 | if part.foliageBendingIndex ~= nil then |
338 | local updatePart = function(currentName, startName, endName, nextPartName, prevPartName) |
339 | if part[startName] ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(part[nextPartName], part[prevPartName], animation, true)) then |
340 | local destFactor = part[endName] |
341 | if animation.currentSpeed < 0 then |
342 | destFactor = part[startName] |
343 | end |
344 | if part.foliageBendingNode == nil then |
345 | local foliageBendingNode = self:getFoliageBendingNodeByIndex(part.foliageBendingIndex) |
346 | if foliageBendingNode == nil then |
347 | g_logManager:xmlWarning(self.configFileName, "Could not update foliage bending node. No bending node defined for node '%s'!", getName(part.node)) |
348 | part[startName] = nil |
349 | part.foliageBendingIndex = nil |
350 | return hasPartChanged |
351 | end |
352 | |
353 | part.foliageBendingNode = foliageBendingNode |
354 | local invDuration = 1.0/math.max(durationToEnd, 0.001) |
355 | part.speedFoliageBending = (destFactor-foliageBendingNode[currentName])*invDuration |
356 | end |
357 | |
358 | local newValue = AnimatedVehicle.getMovedLimitedValue(part.foliageBendingNode[currentName], destFactor, part.speedFoliageBending, dtToUse) |
359 | if newValue then |
360 | part.foliageBendingNode[currentName] = newValue |
361 | hasPartChanged = true |
362 | end |
363 | end |
364 | end |
365 | |
366 | updatePart("minX", "startMinX", "endMinX", "nextMinXPart", "prevMinXPart") |
367 | updatePart("maxX", "startMaxX", "endMaxX", "nextMaxXPart", "prevMaxXPart") |
368 | updatePart("minZ", "startMinZ", "endMinZ", "nextMinZPart", "prevMinZPart") |
369 | updatePart("maxZ", "startMaxZ", "endMaxZ", "nextMaxZPart", "prevMaxZPart") |
370 | updatePart("yOffset", "startYOffset", "endYOffset", "nextYOffsetPart", "prevYOffsetPart") |
371 | |
372 | self:updateFoliageBendingAttributes(part.foliageBendingIndex) |
373 | end |
374 | |
375 | return hasPartChanged |
376 | end |