Sprache Deutsch Language English

Script Dokumentation LS 2015 - AnimatedVehicle (Patch 1.3)

Script Dokumentation Übersicht

scripts/vehicles/specializations/AnimatedVehicle.lua

Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
1--
2-- AnimatedVehicle
3-- Class for all AnimatedVehicles
4--
5-- @author Stefan Geiger
6-- @date 16/10/09
7--
8-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.
9
10source("dataS/scripts/vehicles/specializations/AnimatedVehicleStartEvent.lua");
11source("dataS/scripts/vehicles/specializations/AnimatedVehicleStopEvent.lua");
12AnimatedVehicle = {};
13
14function AnimatedVehicle.prerequisitesPresent(specializations)
15 return true;
16end;
17
18function AnimatedVehicle:preLoad(xmlFile)
19 self.loadSpeedRotatingPartFromXML = Utils.overwrittenFunction(self.loadSpeedRotatingPartFromXML, AnimatedVehicle.loadSpeedRotatingPartFromXML);
20 self.loadWorkAreaFromXML = Utils.overwrittenFunction(self.loadWorkAreaFromXML, AnimatedVehicle.loadWorkAreaFromXML);
21end
22
23function AnimatedVehicle:load(xmlFile)
24
25 self.playAnimation = SpecializationUtil.callSpecializationsFunction("playAnimation");
26 self.stopAnimation = SpecializationUtil.callSpecializationsFunction("stopAnimation");
27 self.getIsAnimationPlaying = AnimatedVehicle.getIsAnimationPlaying;
28 self.getRealAnimationTime = AnimatedVehicle.getRealAnimationTime;
29 self.setRealAnimationTime = SpecializationUtil.callSpecializationsFunction("setRealAnimationTime");
30 self.getAnimationTime = AnimatedVehicle.getAnimationTime;
31 self.getAnimationDuration = AnimatedVehicle.getAnimationDuration;
32 self.setAnimationTime = SpecializationUtil.callSpecializationsFunction("setAnimationTime");
33 self.setAnimationStopTime = SpecializationUtil.callSpecializationsFunction("setAnimationStopTime");
34 self.setAnimationSpeed = SpecializationUtil.callSpecializationsFunction("setAnimationSpeed");
35 self.resetAnimationValues = AnimatedVehicle.resetAnimationValues;
36 self.resetAnimationPartValues = AnimatedVehicle.resetAnimationPartValues;
37 self.getIsSpeedRotatingPartActive = Utils.overwrittenFunction(self.getIsSpeedRotatingPartActive, AnimatedVehicle.getIsSpeedRotatingPartActive);
38 self.getIsWorkAreaActive = Utils.overwrittenFunction(self.getIsWorkAreaActive, AnimatedVehicle.getIsWorkAreaActive);
39
40 self.animations = {};
41
42 local i=0;
43 while true do
44 local key = string.format("vehicle.animations.animation(%d)", i);
45 if not hasXMLProperty(xmlFile, key) then
46 break;
47 end;
48
49 local name = getXMLString(xmlFile, key.."#name");
50 if name ~= nil then
51 local animation = {};
52 animation.name = name;
53 animation.parts = {};
54 animation.currentTime = 0;
55 animation.currentSpeed = 1;
56 animation.looping = Utils.getNoNil(getXMLBool(xmlFile, key .. "#looping"), false);
57
58 local partI = 0;
59 while true do
60 local partKey = key..string.format(".part(%d)", partI);
61 if not hasXMLProperty(xmlFile, partKey) then
62 break;
63 end;
64
65 local node = Utils.indexToObject(self.components, getXMLString(xmlFile, partKey.."#node"));
66 local startTime = getXMLFloat(xmlFile, partKey.."#startTime");
67 local duration = getXMLFloat(xmlFile, partKey.."#duration");
68 local endTime = getXMLFloat(xmlFile, partKey.."#endTime");
69 local direction = Utils.sign(Utils.getNoNil(getXMLInt(xmlFile, partKey.."#direction"), 0));
70 local startRot = Utils.getRadiansFromString(getXMLString(xmlFile, partKey.."#startRot"), 3);
71 local endRot = Utils.getRadiansFromString(getXMLString(xmlFile, partKey.."#endRot"), 3);
72 local startTrans = Utils.getVectorNFromString(getXMLString(xmlFile, partKey.."#startTrans"), 3);
73 local endTrans = Utils.getVectorNFromString(getXMLString(xmlFile, partKey.."#endTrans"), 3);
74 local startScale = Utils.getVectorNFromString(getXMLString(xmlFile, partKey.."#startScale"), 3);
75 local endScale = Utils.getVectorNFromString(getXMLString(xmlFile, partKey.."#endScale"), 3);
76 local visibility = getXMLBool(xmlFile, partKey.."#visibility");
77 local componentJointIndex = getXMLInt(xmlFile, partKey.."#componentJointIndex");
78 local componentJoint;
79 if componentJointIndex ~= nil then
80 componentJoint = self.componentJoints[componentJointIndex+1];
81 end
82 local startRotLimit = Utils.getRadiansFromString(getXMLString(xmlFile, partKey.."#startRotLimit"), 3);
83 local endRotLimit = Utils.getRadiansFromString(getXMLString(xmlFile, partKey.."#endRotLimit"), 3);
84 local startTransLimit = Utils.getVectorNFromString(getXMLString(xmlFile, partKey.."#startTransLimit"), 3);
85 local endTransLimit = Utils.getVectorNFromString(getXMLString(xmlFile, partKey.."#endTransLimit"), 3);
86
87 if startTime ~= nil and (duration ~= nil or endTime ~= nil) and
88 ( (node ~= nil and (endRot ~= nil or endTrans ~= nil or endScale ~= nil or visibility ~= nil)) or
89 (componentJoint ~= nil and (endRotLimit ~= nil or endTransLimit ~= nil)))
90 then
91 if endTime ~= nil then
92 duration = endTime - startTime;
93 end;
94 local part = {};
95 part.node = node;
96 part.startTime = startTime*1000;
97 part.duration = duration*1000;
98 part.direction = direction;
99 if node ~= nil then
100 if endRot ~= nil then
101 part.startRot = startRot;
102 part.endRot = endRot;
103 end;
104 if endTrans ~= nil then
105 part.startTrans = startTrans;
106 part.endTrans = endTrans;
107 end;
108 if endScale ~= nil then
109 part.startScale = startScale;
110 part.endScale = endScale;
111 end;
112
113 part.visibility = visibility;
114 end
115 if self.isServer then
116 if componentJoint ~= nil then
117 if endRotLimit ~= nil then
118 part.componentJoint = componentJoint;
119 part.startRotLimit = startRotLimit;
120 part.endRotLimit = endRotLimit;
121 end
122 if endTransLimit ~= nil then
123 part.componentJoint = componentJoint;
124 part.startTransLimit = startTransLimit;
125 part.endTransLimit = endTransLimit;
126 end
127 end
128 end
129 table.insert(animation.parts, part);
130 end;
131 partI = partI + 1;
132 end;
133
134 -- sort parts by start/end time
135 animation.partsReverse = {};
136 for _, part in ipairs(animation.parts) do
137 table.insert(animation.partsReverse, part);
138 end;
139 table.sort(animation.parts, AnimatedVehicle.animPartSorter);
140 table.sort(animation.partsReverse, AnimatedVehicle.animPartSorterReverse);
141
142 AnimatedVehicle.initializeParts(self, animation);
143
144 animation.currentPartIndex = 1;
145 animation.duration = 0;
146 for _, part in ipairs(animation.parts) do
147 animation.duration = math.max(animation.duration, part.startTime + part.duration);
148 end;
149
150 self.animations[name] = animation;
151 end;
152
153 i = i+1;
154 end;
155
156 self.activeAnimations = {};
157end;
158
159function AnimatedVehicle.initializeParts(self, animation)
160 local numParts = table.getn(animation.parts);
161
162 for i=1, numParts do
163 local part = animation.parts[i];
164
165 -- find the next rot part
166 if part.endRot ~= nil then
167 for j=i+1, numParts do
168 local part2 = animation.parts[j];
169 if part.node == part2.node and part2.endRot ~= nil then
170 if part.startTime + part.duration > part2.startTime+0.001 then
171 print("Warning: overlapping rotation parts for node "..getName(part.node).." in " .. animation.name.. " "..self.configFileName);
172 end
173 part.nextRotPart = part2;
174 part2.prevRotPart = part;
175 if part2.startRot == nil then
176 part2.startRot = {part.endRot[1], part.endRot[2], part.endRot[3]};
177 end
178 break;
179 end
180 end
181 end
182
183 -- find the next trans part
184 if part.endTrans ~= nil then
185 for j=i+1, numParts do
186 local part2 = animation.parts[j];
187 if part.node == part2.node and part2.endTrans ~= nil then
188 if part.startTime + part.duration > part2.startTime+0.001 then
189 print("Warning: overlapping translation parts for node "..getName(part.node).." in " .. animation.name.. " "..self.configFileName);
190 end
191 part.nextTransPart = part2;
192 part2.prevTransPart = part;
193 if part2.startTrans == nil then
194 part2.startTrans = {part.endTrans[1], part.endTrans[2], part.endTrans[3]};
195 end
196 break;
197 end
198 end
199 end
200
201 -- find the next scale part
202 if part.endScale ~= nil then
203 for j=i+1, numParts do
204 local part2 = animation.parts[j];
205 if part.node == part2.node and part2.endScale ~= nil then
206 if part.startTime + part.duration > part2.startTime+0.001 then
207 print("Warning: overlapping scale parts for node "..getName(part.node).." in " .. animation.name.. " "..self.configFileName);
208 end
209 part.nextScalePart = part2;
210 part2.prevScalePart = part;
211 if part2.startScale == nil then
212 part2.startScale = {part.endScale[1], part.endScale[2], part.endScale[3]};
213 end
214 break;
215 end
216 end
217 end
218
219 if self.isServer then
220 -- find the next joint rot limit part
221 if part.endRotLimit ~= nil then
222 for j=i+1, numParts do
223 local part2 = animation.parts[j];
224 if part.componentJoint == part2.componentJoint and part2.endRotLimit ~= nil then
225 if part.startTime + part.duration > part2.startTime+0.001 then
226 print("Warning: overlapping joint rot limit parts for component joint "..getName(part.componentJoint.jointNode).." in " .. animation.name.. " "..self.configFileName);
227 end
228 part.nextRotLimitPart = part2;
229 part2.prevRotLimitPart = part;
230 if part2.startRotLimit == nil then
231 part2.startRotLimit = {part.endRotLimit[1], part.endRotLimit[2], part.endRotLimit[3]};
232 end
233 break;
234 end
235 end
236 end
237
238 -- find the next joint trans limit part
239 if part.endTransLimit ~= nil then
240 for j=i+1, numParts do
241 local part2 = animation.parts[j];
242 if part.componentJoint == part2.componentJoint and part2.endTransLimit ~= nil then
243 if part.startTime + part.duration > part2.startTime+0.001 then
244 print("Warning: overlapping joint trans limit parts for component joint "..getName(part.componentJoint.jointNode).." in " .. animation.name.. " "..self.configFileName);
245 end
246 part.nextTransLimitPart = part2;
247 part2.prevTransLimitPart = part;
248 if part2.startTransLimit == nil then
249 part2.startTransLimit = {part.endTransLimit[1], part.endTransLimit[2], part.endTransLimit[3]};
250 end
251 break;
252 end
253 end
254 end
255 end
256 end
257
258 -- default start values to the value stored in the i3d (if not set by the end value of the previous part)
259 for i=1, numParts do
260 local part = animation.parts[i];
261 if part.endRot ~= nil and part.startRot == nil then
262 local x,y,z = getRotation(part.node);
263 part.startRot = {x,y,z};
264 end
265 if part.endTrans ~= nil and part.startTrans == nil then
266 local x,y,z = getTranslation(part.node);
267 part.startTrans = {x,y,z};
268 end;
269 if part.endScale ~= nil and part.startScale == nil then
270 local x,y,z = getScale(part.node);
271 part.startScale = {x,y,z};
272 end;
273 if self.isServer then
274 if part.endRotLimit ~= nil and part.startRotLimit == nil then
275 local rotLimit = part.componentJoint.rotLimit;
276 part.startRotLimit = {rotLimit[1], rotLimit[2], rotLimit[3]};
277 end
278 if part.endTransLimit ~= nil and part.startTransLimit == nil then
279 local transLimit = part.componentJoint.transLimit;
280 part.startTransLimit = {transLimit[1], transLimit[2], transLimit[3]};
281 end
282 end
283 end
284end
285
286function AnimatedVehicle:delete()
287
288end;
289
290
291function AnimatedVehicle:readStream(streamId, connection)
292 -- TODO
293end;
294
295function AnimatedVehicle:writeStream(streamId, connection)
296 -- TODO
297end;
298
299function AnimatedVehicle:readUpdateStream(streamId, timestamp, connection)
300 --[[if connection.isServer then
301 local x=streamReadFloat32(streamId);
302 local y=streamReadFloat32(streamId);
303 local z=streamReadFloat32(streamId);
304 local xrot=streamReadFloat32(streamId);
305 local yrot=streamReadFloat32(streamId);
306 local zrot=streamReadFloat32(streamId);
307 AnimatedVehicle.setAnimPos(self, animTime);
308 end;]]
309end;
310
311function AnimatedVehicle:writeUpdateStream(streamId, connection, dirtyMask)
312 --[[if not connection.isServer then
313 streamWriteFloat32(streamId, self.foldAnimTime);
314 end;]]
315end;
316
317function AnimatedVehicle:mouseEvent(posX, posY, isDown, isUp, button)
318end;
319
320function AnimatedVehicle:keyEvent(unicode, sym, modifier, isDown)
321end;
322
323function AnimatedVehicle:update(dt)
324 AnimatedVehicle.updateAnimations(self, dt)
325end;
326
327function AnimatedVehicle:updateTick(dt)
328 -- TODO
329end;
330
331function AnimatedVehicle:draw()
332end;
333
334function AnimatedVehicle:onDetach()
335end;
336
337function AnimatedVehicle:onLeave()
338end;
339
340function AnimatedVehicle:onDeactivate()
341end;
342
343function AnimatedVehicle:onDeactivateSounds()
344end;
345
346function AnimatedVehicle:playAnimation(name, speed, animTime, noEventSend)
347 local animation = self.animations[name];
348 if animation ~= nil then
349 if speed == nil then
350 speed = animation.currentSpeed;
351 end;
352 if animTime == nil then
353 if self:getIsAnimationPlaying(name) then
354 animTime = self:getAnimationTime(name);
355 elseif speed > 0 then
356 animTime = 0;
357 else
358 animTime = 1;
359 end;
360 end;
361 if noEventSend == nil or noEventSend == false then
362 if g_server ~= nil then
363 g_server:broadcastEvent(AnimatedVehicleStartEvent:new(self, name, speed, animTime), nil, nil, self);
364 else
365 g_client:getServerConnection():sendEvent(AnimatedVehicleStartEvent:new(self, name, speed, animTime));
366 end;
367 end;
368
369 self.activeAnimations[name] = animation;
370 animation.currentSpeed = speed;
371 animation.currentTime = animTime*animation.duration;
372 self:resetAnimationValues(animation);
373 end;
374end;
375
376function AnimatedVehicle:stopAnimation(name, noEventSend)
377 if noEventSend == nil or noEventSend == false then
378 if g_server ~= nil then
379 g_server:broadcastEvent(AnimatedVehicleStopEvent:new(self, name), nil, nil, self);
380 else
381 g_client:getServerConnection():sendEvent(AnimatedVehicleStopEvent:new(self, name));
382 end;
383 end
384 local animation = self.animations[name];
385 if animation ~= nil then
386 animation.stopTime = nil;
387 end;
388 self.activeAnimations[name] = nil;
389end;
390
391function AnimatedVehicle:getIsAnimationPlaying(name)
392 return self.activeAnimations[name] ~= nil;
393end;
394
395function AnimatedVehicle:getRealAnimationTime(name)
396 local animation = self.animations[name];
397 if animation ~= nil then
398 return animation.currentTime;
399 end;
400 return 0;
401end;
402
403function AnimatedVehicle:setRealAnimationTime(name, animTime, update)
404 local animation = self.animations[name];
405 if animation ~= nil then
406 if update == nil or update then
407 local currentSpeed = animation.currentSpeed;
408 animation.currentSpeed = 1;
409 if animation.currentTime > animTime then
410 animation.currentSpeed = -1;
411 end;
412
413 self:resetAnimationValues(animation);
414
415 local dtToUse, _ = AnimatedVehicle.updateAnimationCurrentTime(self, animation, 99999999, animTime);
416 AnimatedVehicle.updateAnimation(self, animation, dtToUse, false);
417 animation.currentSpeed = currentSpeed;
418 else
419 animation.currentTime = animTime;
420 end
421 end;
422end;
423
424function AnimatedVehicle:getAnimationTime(name)
425 local animation = self.animations[name];
426 if animation ~= nil then
427 return animation.currentTime/animation.duration;
428 end;
429 return 0;
430end;
431
432function AnimatedVehicle:setAnimationTime(name, animTime, update)
433 local animation = self.animations[name];
434 if animation ~= nil then
435 self:setRealAnimationTime(name, animTime*animation.duration, update);
436 end;
437end;
438
439function AnimatedVehicle:getAnimationDuration(name)
440 local animation = self.animations[name];
441 if animation ~= nil then
442 return animation.duration;
443 end;
444 return 1;
445end;
446
447function AnimatedVehicle:setAnimationSpeed(name, speed)
448 local animation = self.animations[name];
449 if animation ~= nil then
450 local speedReversed = false;
451 if (animation.currentSpeed > 0) ~= (speed > 0) then
452 speedReversed = true;
453 end;
454 animation.currentSpeed = speed;
455 if self:getIsAnimationPlaying(name) and speedReversed then
456 self:resetAnimationValues(animation);
457 end;
458 end;
459end;
460
461function AnimatedVehicle:setAnimationStopTime(name, stopTime)
462 local animation = self.animations[name];
463 if animation ~= nil then
464 animation.stopTime = stopTime*animation.duration;
465 end;
466end;
467
468function AnimatedVehicle:resetAnimationValues(animation)
469 AnimatedVehicle.findCurrentPartIndex(animation);
470 for _, part in ipairs(animation.parts) do
471 self:resetAnimationPartValues(part);
472 end;
473end
474
475function AnimatedVehicle:resetAnimationPartValues(part)
476 part.curRot = nil;
477 part.speedRot = nil;
478 part.curTrans = nil;
479 part.speedTrans = nil;
480 part.curScale = nil;
481 part.speedScale = nil;
482 part.curVisibility = nil;
483 part.curRotLimit = nil;
484 part.speedRotLimit = nil;
485 part.curTransLimit = nil;
486 part.speedTransLimit = nil;
487end;
488
489function AnimatedVehicle:loadSpeedRotatingPartFromXML(superFunc, speedRotatingPart, xmlFile, key)
490 if superFunc ~= nil then
491 if not superFunc(self, speedRotatingPart, xmlFile, key) then
492 return false;
493 end
494 end
495
496 speedRotatingPart.animName = getXMLString(xmlFile, key.."#animName");
497 speedRotatingPart.animOuterRange = Utils.getNoNil(getXMLFloat(xmlFile, key.."#animOuterRange"), false);
498 speedRotatingPart.animMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, key.."#animMinLimit"), 0);
499 speedRotatingPart.animMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, key.."#animMaxLimit"), 1);
500 return true;
501end
502
503function AnimatedVehicle:getIsSpeedRotatingPartActive(superFunc, speedRotatingPart)
504 if speedRotatingPart.animName ~= nil then
505 local animTime = self:getAnimationTime(speedRotatingPart.animName);
506 if speedRotatingPart.animOuterRange then
507 if animTime > speedRotatingPart.animMinLimit or animTime < speedRotatingPart.animMaxLimit then
508 return false;
509 end
510 else
511 if animTime > speedRotatingPart.animMaxLimit or animTime < speedRotatingPart.animMinLimit then
512 return false;
513 end
514 end;
515 end;
516
517 if superFunc ~= nil then
518 return superFunc(self, speedRotatingPart);
519 end
520 return true;
521end;
522
523function AnimatedVehicle:loadWorkAreaFromXML(superFunc, workArea, xmlFile, key)
524 workArea.animName = getXMLString(xmlFile, key.."#animName");
525 workArea.animMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, key.."#animMinLimit"), 0);
526 workArea.animMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, key.."#animMaxLimit"), 1);
527
528 if superFunc ~= nil then
529 return superFunc(self, workArea, xmlFile, key);
530 end;
531 return true;
532end;
533
534function AnimatedVehicle:getIsWorkAreaActive(superFunc, workArea)
535 if workArea.animName ~= nil then
536 local animTime = self:getAnimationTime(workArea.animName);
537 if animTime > workArea.animMaxLimit or animTime < workArea.animMinLimit then
538 return false;
539 end
540 end;
541
542 if superFunc ~= nil then
543 return superFunc(self, workArea);
544 end
545 return true;
546end;
547
548function AnimatedVehicle.animPartSorter(a, b)
549 if a.startTime < b.startTime then
550 return true;
551 elseif a.startTime == b.startTime then
552 return a.duration < b.duration;
553 end;
554 return false;
555end;
556
557function AnimatedVehicle.animPartSorterReverse(a, b)
558 local endTimeA = a.startTime+a.duration;
559 local endTimeB = b.startTime+b.duration;
560 if endTimeA > endTimeB then
561 return true;
562 elseif endTimeA == endTimeB then
563 return a.startTime > b.startTime;
564 end;
565 return false;
566end;
567
568function AnimatedVehicle.getMovedLimitedValue(currentValue, destValue, speed, dt)
569 local limitF = math.min;
570 -- we are moving towards -inf, we need to check for the maximum
571 if destValue < currentValue then
572 limitF = math.max;
573 elseif destValue == currentValue then
574 return currentValue;
575 end;
576 local ret = limitF(currentValue + speed * dt, destValue);
577 return ret;
578end;
579
580function AnimatedVehicle.setMovedLimitedValues3(currentValues, destValues, speeds, dt)
581
582 local hasChanged = false;
583 for i=1, 3 do
584 local newValue = AnimatedVehicle.getMovedLimitedValue(currentValues[i], destValues[i], speeds[i], dt);
585 if currentValues[i] ~= newValue then
586 hasChanged = true;
587 currentValues[i] = newValue;
588 end;
589 end;
590 return hasChanged;
591end;
592
593function AnimatedVehicle.findCurrentPartIndex(animation)
594 if animation.currentSpeed > 0 then
595 -- find the first part that is being played at the current time
596 animation.currentPartIndex = table.getn(animation.parts)+1;
597 for i, part in ipairs(animation.parts) do
598 if part.startTime+part.duration >= animation.currentTime then
599 animation.currentPartIndex = i;
600 break;
601 end;
602 end;
603 else
604 -- find the last part that is being played at the current time (the first in partsReverse)
605 animation.currentPartIndex = table.getn(animation.partsReverse)+1;
606 for i, part in ipairs(animation.partsReverse) do
607 if part.startTime <= animation.currentTime then
608 animation.currentPartIndex = i;
609 break;
610 end;
611 end;
612 end;
613end;
614
615function AnimatedVehicle.getDurationToEndOfPart(part, anim)
616 if anim.currentSpeed > 0 then
617 return part.startTime+part.duration - anim.currentTime;
618 else
619 return anim.currentTime - part.startTime;
620 end
621end
622
623function AnimatedVehicle.getNextPartIsPlaying(nextPart, prevPart, anim, default)
624 if anim.currentSpeed > 0 then
625 if nextPart ~= nil then
626 return nextPart.startTime > anim.currentTime;
627 end
628 else
629 if prevPart ~= nil then
630 return prevPart.startTime + prevPart.duration < anim.currentTime;
631 end
632 end
633 return default;
634end
635
636function AnimatedVehicle.updateAnimations(self, dt)
637 for _, anim in pairs(self.activeAnimations) do
638 local dtToUse, stopAnim = AnimatedVehicle.updateAnimationCurrentTime(self, anim, dt, anim.stopTime);
639 AnimatedVehicle.updateAnimation(self, anim, dtToUse, stopAnim);
640 end
641end
642
643function AnimatedVehicle.updateAnimationByName(self, animName, dt)
644 local anim = self.animations[animName];
645 if anim ~= nil then
646 local dtToUse, stopAnim = AnimatedVehicle.updateAnimationCurrentTime(self, anim, dt, anim.stopTime);
647 AnimatedVehicle.updateAnimation(self, anim, dtToUse, stopAnim);
648 end
649end
650
651function AnimatedVehicle.updateAnimationCurrentTime(self, anim, dt, stopTime)
652 anim.currentTime = anim.currentTime + dt*anim.currentSpeed;
653
654 local absSpeed = math.abs(anim.currentSpeed);
655 local dtToUse = dt*absSpeed;
656 local stopAnim = false;
657 if stopTime ~= nil then
658 if anim.currentSpeed > 0 then
659 if stopTime <= anim.currentTime then
660 dtToUse = dtToUse-(anim.currentTime-stopTime);
661 anim.currentTime = stopTime;
662 stopAnim = true;
663 end;
664 else
665 if stopTime >= anim.currentTime then
666 dtToUse = dtToUse-(stopTime-anim.currentTime);
667 anim.currentTime = stopTime;
668 stopAnim = true;
669 end;
670 end;
671 end;
672 return dtToUse, stopAnim;
673end
674
675function AnimatedVehicle.updateAnimation(self, anim, dtToUse, stopAnim)
676 local name = anim.name;
677
678 local numParts = table.getn(anim.parts)
679 local parts = anim.parts;
680 if anim.currentSpeed < 0 then
681 parts = anim.partsReverse;
682 end;
683
684 if dtToUse > 0 then
685 local hasChanged = false;
686 local nothingToChangeYet = false;
687 for partI=anim.currentPartIndex, numParts do
688 local part = parts[partI];
689
690 if part.direction == 0 or ((part.direction > 0) == (anim.currentSpeed >= 0)) then
691 local durationToEnd = AnimatedVehicle.getDurationToEndOfPart(part, anim);
692
693 -- is this part not playing yet?
694 if durationToEnd > part.duration then
695 nothingToChangeYet = true;
696 break;
697 end
698
699 durationToEnd = durationToEnd+dtToUse;
700
701 local hasPartChanged = false;
702 -- update the part
703 if part.startRot ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(part.nextRotPart, part.prevRotPart, anim, true)) then
704 local destRot = part.endRot;
705 if anim.currentSpeed < 0 then
706 destRot = part.startRot;
707 end;
708 if part.curRot == nil then
709 local x,y,z = getRotation(part.node);
710 part.curRot = {x,y,z};
711 local invDuration = 1.0/math.max(durationToEnd, 0.001);
712 part.speedRot = {(destRot[1]-x)*invDuration, (destRot[2]-y)*invDuration, (destRot[3]-z)*invDuration};
713 end;
714 if AnimatedVehicle.setMovedLimitedValues3(part.curRot, destRot, part.speedRot, dtToUse) then
715 setRotation(part.node, part.curRot[1], part.curRot[2], part.curRot[3]);
716 hasPartChanged = true;
717 end;
718 end;
719 if part.startTrans ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(part.nextTransPart, part.prevTransPart, anim, true)) then
720 local destTrans = part.endTrans;
721 if anim.currentSpeed < 0 then
722 destTrans = part.startTrans;
723 end;
724 if part.curTrans == nil then
725 local x,y,z = getTranslation(part.node);
726 part.curTrans = {x,y,z};
727 local invDuration = 1.0/math.max(durationToEnd, 0.001);
728 part.speedTrans = {(destTrans[1]-x)*invDuration, (destTrans[2]-y)*invDuration, (destTrans[3]-z)*invDuration};
729 end;
730 if AnimatedVehicle.setMovedLimitedValues3(part.curTrans, destTrans, part.speedTrans, dtToUse) then
731 setTranslation(part.node, part.curTrans[1], part.curTrans[2], part.curTrans[3]);
732 hasPartChanged = true;
733 end;
734 end;
735 if part.startScale ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(part.nextScalePart, part.prevScalePart, anim, true)) then
736 local destScale = part.endScale;
737 if anim.currentSpeed < 0 then
738 destScale = part.startScale;
739 end;
740 if part.curScale == nil then
741 local x,y,z = getScale(part.node);
742 part.curScale = {x,y,z};
743 local invDuration = 1.0/math.max(durationToEnd, 0.001);
744 part.speedScale = {(destScale[1]-x)*invDuration, (destScale[2]-y)*invDuration, (destScale[3]-z)*invDuration};
745 end;
746 if AnimatedVehicle.setMovedLimitedValues3(part.curScale, destScale, part.speedScale, dtToUse) then
747 setScale(part.node, part.curScale[1], part.curScale[2], part.curScale[3]);
748 hasPartChanged = true;
749 end;
750 end;
751 if part.visibility ~= nil then
752 if part.curVisibility == nil then
753 part.curVisibility = getVisibility(part.node);
754 end;
755 if part.visibility ~= part.curVisibility then
756 part.curVisibility = part.visibility;
757 setVisibility(part.node, part.visibility);
758 hasPartChanged = true;
759 end;
760 end;
761
762 if self.isServer then
763 if part.startRotLimit ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(part.nextRotLimitPart, part.prevRotLimitPart, anim, true)) then
764 local destRotLimit = part.endRotLimit;
765 if anim.currentSpeed < 0 then
766 destRotLimit = part.startRotLimit;
767 end;
768 if part.curRotLimit == nil then
769 local x,y,z = unpack(part.componentJoint.rotLimit);
770 part.curRotLimit = {x,y,z};
771 local invDuration = 1.0/math.max(durationToEnd, 0.001);
772 part.speedRotLimit = {(destRotLimit[1]-x)*invDuration, (destRotLimit[2]-y)*invDuration, (destRotLimit[3]-z)*invDuration};
773 end;
774 for i=1, 3 do
775 local newRotLimit = AnimatedVehicle.getMovedLimitedValue(part.curRotLimit[i], destRotLimit[i], part.speedRotLimit[i], dtToUse);
776 if newRotLimit ~= part.curRotLimit[i] then
777 part.curRotLimit[i] = newRotLimit;
778 self:setComponentJointRotLimit(part.componentJoint, i, -newRotLimit, newRotLimit);
779 hasPartChanged = true;
780 end
781 end;
782 end;
783 if part.startTransLimit ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(part.nextTransLimitPart, part.prevTransLimitPart, anim, true)) then
784 local destTransLimit = part.endTransLimit;
785 if anim.currentSpeed < 0 then
786 destTransLimit = part.startTransLimit;
787 end;
788 if part.curTransLimit == nil then
789 local x,y,z = unpack(part.componentJoint.transLimit);
790 part.curTransLimit = {x,y,z};
791 local invDuration = 1.0/math.max(durationToEnd, 0.001);
792 part.speedTransLimit = {(destTransLimit[1]-x)*invDuration, (destTransLimit[2]-y)*invDuration, (destTransLimit[3]-z)*invDuration};
793 end;
794 for i=1, 3 do
795 local newTransLimit = AnimatedVehicle.getMovedLimitedValue(part.curTransLimit[i], destTransLimit[i], part.speedTransLimit[i], dtToUse);
796 if newRotLimit ~= part.curTransLimit[i] then
797 part.curTransLimit[i] = newTransLimit;
798 self:setComponentJointTransLimit(part.componentJoint, i, -newTransLimit, newTransLimit);
799 hasPartChanged = true;
800 end
801 end
802 end
803 end
804
805 if hasPartChanged then
806 if self.setMovingToolDirty ~= nil then
807 self:setMovingToolDirty(part.node);
808 end
809 hasChanged = true;
810 end
811 end
812
813 if partI == anim.currentPartIndex then
814 -- is this part finished?
815 if (anim.currentSpeed > 0 and part.startTime + part.duration < anim.currentTime) or
816 (anim.currentSpeed <= 0 and part.startTime > anim.currentTime)
817 then
818 self:resetAnimationPartValues(part);
819 --print("finished: "..anim.currentPartIndex);
820 anim.currentPartIndex = anim.currentPartIndex+1;
821 end
822 end
823 end;
824 if not nothingToChangeYet and not hasChanged and anim.currentPartIndex >= numParts then
825 -- end the animation
826 if anim.currentSpeed > 0 then
827 anim.currentTime = anim.duration;
828 else
829 anim.currentTime = 0;
830 end
831 stopAnim = true;
832 end;
833 end;
834 if stopAnim or anim.currentPartIndex > numParts or anim.currentPartIndex < 1 then
835 if not stopAnim then
836 if anim.currentSpeed > 0 then
837 anim.currentTime = anim.duration;
838 else
839 anim.currentTime = 0;
840 end
841 end
842 anim.currentTime = math.min(math.max(anim.currentTime, 0), anim.duration);
843 anim.stopTime = nil;
844 self.activeAnimations[name] = nil;
845
846 if anim.looping then
847 -- restart animation
848 self:setAnimationTime(anim.name, math.abs((anim.duration-anim.currentTime) - 1), true);
849 self:playAnimation(anim.name, anim.currentSpeed, nil, true);
850 end;
851 end;
852end;
Copyright (c) 2008-2015 GIANTS Software GmbH, Confidential, All Rights Reserved.
This document is to be published solely by ls-mods.de
Script Dokumentation Übersicht