35 | function AnimatedVehicle:load(savegame) |
36 | |
37 | self.playAnimation = SpecializationUtil.callSpecializationsFunction("playAnimation"); |
38 | self.stopAnimation = SpecializationUtil.callSpecializationsFunction("stopAnimation"); |
39 | self.setRealAnimationTime = SpecializationUtil.callSpecializationsFunction("setRealAnimationTime"); |
40 | self.setAnimationTime = SpecializationUtil.callSpecializationsFunction("setAnimationTime"); |
41 | self.setAnimationStopTime = SpecializationUtil.callSpecializationsFunction("setAnimationStopTime"); |
42 | self.setAnimationSpeed = SpecializationUtil.callSpecializationsFunction("setAnimationSpeed"); |
43 | self.getIsAnimationPlaying = AnimatedVehicle.getIsAnimationPlaying; |
44 | self.getRealAnimationTime = AnimatedVehicle.getRealAnimationTime; |
45 | self.getAnimationTime = AnimatedVehicle.getAnimationTime; |
46 | self.getAnimationDuration = AnimatedVehicle.getAnimationDuration; |
47 | |
48 | self.resetAnimationValues = AnimatedVehicle.resetAnimationValues; |
49 | self.resetAnimationPartValues = AnimatedVehicle.resetAnimationPartValues; |
50 | self.getIsSpeedRotatingPartActive = Utils.overwrittenFunction(self.getIsSpeedRotatingPartActive, AnimatedVehicle.getIsSpeedRotatingPartActive); |
51 | self.getIsWorkAreaActive = Utils.overwrittenFunction(self.getIsWorkAreaActive, AnimatedVehicle.getIsWorkAreaActive); |
52 | |
53 | self.animations = {}; |
54 | |
55 | local i=0; |
56 | while true do |
57 | local key = string.format("vehicle.animations.animation(%d)", i); |
58 | if not hasXMLProperty(self.xmlFile, key) then |
59 | break; |
60 | end; |
61 | |
62 | local name = getXMLString(self.xmlFile, key.."#name"); |
63 | if name ~= nil then |
64 | local animation = {}; |
65 | animation.name = name; |
66 | animation.parts = {}; |
67 | animation.currentTime = 0; |
68 | animation.currentSpeed = 1; |
69 | animation.looping = Utils.getNoNil(getXMLBool(self.xmlFile, key .. "#looping"), false); |
70 | |
71 | local partI = 0; |
72 | while true do |
73 | local partKey = key..string.format(".part(%d)", partI); |
74 | if not hasXMLProperty(self.xmlFile, partKey) then |
75 | break; |
76 | end; |
77 | |
78 | local node = Utils.indexToObject(self.components, getXMLString(self.xmlFile, partKey.."#node")); |
79 | local startTime = getXMLFloat(self.xmlFile, partKey.."#startTime"); |
80 | local duration = getXMLFloat(self.xmlFile, partKey.."#duration"); |
81 | local endTime = getXMLFloat(self.xmlFile, partKey.."#endTime"); |
82 | local direction = Utils.sign(Utils.getNoNil(getXMLInt(self.xmlFile, partKey.."#direction"), 0)); |
83 | local startRot = Utils.getRadiansFromString(getXMLString(self.xmlFile, partKey.."#startRot"), 3); |
84 | local endRot = Utils.getRadiansFromString(getXMLString(self.xmlFile, partKey.."#endRot"), 3); |
85 | local startTrans = Utils.getVectorNFromString(getXMLString(self.xmlFile, partKey.."#startTrans"), 3); |
86 | local endTrans = Utils.getVectorNFromString(getXMLString(self.xmlFile, partKey.."#endTrans"), 3); |
87 | local startScale = Utils.getVectorNFromString(getXMLString(self.xmlFile, partKey.."#startScale"), 3); |
88 | local endScale = Utils.getVectorNFromString(getXMLString(self.xmlFile, partKey.."#endScale"), 3); |
89 | local visibility = getXMLBool(self.xmlFile, partKey.."#visibility"); |
90 | local componentJointIndex = getXMLInt(self.xmlFile, partKey.."#componentJointIndex"); |
91 | local componentJoint; |
92 | if componentJointIndex ~= nil then |
93 | componentJoint = self.componentJoints[componentJointIndex+1]; |
94 | end |
95 | local startRotLimit = Utils.getRadiansFromString(getXMLString(self.xmlFile, partKey.."#startRotLimit"), 3); |
96 | local startRotMinLimit = Utils.getRadiansFromString(getXMLString(self.xmlFile, partKey.."#startRotMinLimit"), 3); |
97 | local startRotMaxLimit = Utils.getRadiansFromString(getXMLString(self.xmlFile, partKey.."#startRotMaxLimit"), 3); |
98 | if startRotLimit ~= nil then |
99 | startRotMinLimit = {}; |
100 | startRotMaxLimit = {}; |
101 | for i=1,3 do |
102 | startRotMinLimit[i] = -startRotLimit[i]; |
103 | startRotMaxLimit[i] = startRotLimit[i]; |
104 | end |
105 | end |
106 | local endRotLimit = Utils.getRadiansFromString(getXMLString(self.xmlFile, partKey.."#endRotLimit"), 3); |
107 | local endRotMinLimit = Utils.getRadiansFromString(getXMLString(self.xmlFile, partKey.."#endRotMinLimit"), 3); |
108 | local endRotMaxLimit = Utils.getRadiansFromString(getXMLString(self.xmlFile, partKey.."#endRotMaxLimit"), 3); |
109 | if endRotLimit ~= nil then |
110 | endRotMinLimit = {}; |
111 | endRotMaxLimit = {}; |
112 | for i=1,3 do |
113 | endRotMinLimit[i] = -endRotLimit[i]; |
114 | endRotMaxLimit[i] = endRotLimit[i]; |
115 | end |
116 | end |
117 | |
118 | local startTransLimit = Utils.getVectorNFromString(getXMLString(self.xmlFile, partKey.."#startTransLimit"), 3); |
119 | local startTransMinLimit = Utils.getVectorNFromString(getXMLString(self.xmlFile, partKey.."#startTransMinLimit"), 3); |
120 | local startTransMaxLimit = Utils.getVectorNFromString(getXMLString(self.xmlFile, partKey.."#startTransMaxLimit"), 3); |
121 | if startTransLimit ~= nil then |
122 | startTransMinLimit = {}; |
123 | startTransMaxLimit = {}; |
124 | for i=1,3 do |
125 | startTransMinLimit[i] = -startTransLimit[i]; |
126 | startTransMaxLimit[i] = startTransLimit[i]; |
127 | end |
128 | end |
129 | local endTransLimit = Utils.getVectorNFromString(getXMLString(self.xmlFile, partKey.."#endTransLimit"), 3); |
130 | local endTransMinLimit = Utils.getVectorNFromString(getXMLString(self.xmlFile, partKey.."#endTransMinLimit"), 3); |
131 | local endTransMaxLimit = Utils.getVectorNFromString(getXMLString(self.xmlFile, partKey.."#endTransMaxLimit"), 3); |
132 | if endTransLimit ~= nil then |
133 | endTransMinLimit = {}; |
134 | endTransMaxLimit = {}; |
135 | for i=1,3 do |
136 | endTransMinLimit[i] = -endTransLimit[i]; |
137 | endTransMaxLimit[i] = endTransLimit[i]; |
138 | end |
139 | end |
140 | |
141 | local shaderParameter = getXMLString(self.xmlFile, partKey.."#shaderParameter"); |
142 | local shaderStartValues = Utils.getVectorNFromString(getXMLString(self.xmlFile, partKey.."#shaderStartValues"), 4); |
143 | local shaderEndValues = Utils.getVectorNFromString(getXMLString(self.xmlFile, partKey.."#shaderEndValues"), 4); |
144 | |
145 | if startTime ~= nil and (duration ~= nil or endTime ~= nil) and |
146 | ( (node ~= nil and (endRot ~= nil or endTrans ~= nil or endScale ~= nil or visibility ~= nil)) or |
147 | (componentJoint ~= nil and ((endRotMinLimit ~= nil and endRotMaxLimit ~= nil) or (endTransMinLimit ~= nil and endTransMaxLimit ~= nil))) or |
148 | (node ~= nil and shaderParameter ~= nil and (shaderStartValues ~= nil and shaderEndValues ~= nil)) |
149 | ) |
150 | then |
151 | if endTime ~= nil then |
152 | duration = endTime - startTime; |
153 | end; |
154 | local part = {}; |
155 | part.node = node; |
156 | part.startTime = startTime*1000; |
157 | part.duration = duration*1000; |
158 | part.direction = direction; |
159 | if node ~= nil then |
160 | if endRot ~= nil then |
161 | part.startRot = startRot; |
162 | part.endRot = endRot; |
163 | end; |
164 | if endTrans ~= nil then |
165 | part.startTrans = startTrans; |
166 | part.endTrans = endTrans; |
167 | end; |
168 | if endScale ~= nil then |
169 | part.startScale = startScale; |
170 | part.endScale = endScale; |
171 | end; |
172 | |
173 | if shaderParameter ~= nil and shaderEndValues ~= nil and shaderStartValues ~= nil then |
174 | part.shaderParameter = shaderParameter; |
175 | part.shaderStartValues = shaderStartValues; |
176 | part.shaderEndValues = shaderEndValues; |
177 | end |
178 | |
179 | part.visibility = visibility; |
180 | end |
181 | if self.isServer then |
182 | if componentJoint ~= nil then |
183 | if endRotMinLimit ~= nil then |
184 | part.componentJoint = componentJoint; |
185 | part.startRotMinLimit = startRotMinLimit; |
186 | part.startRotMaxLimit = startRotMaxLimit; |
187 | part.endRotMinLimit = endRotMinLimit; |
188 | part.endRotMaxLimit = endRotMaxLimit; |
189 | end |
190 | if endTransMinLimit ~= nil then |
191 | part.componentJoint = componentJoint; |
192 | part.startTransMinLimit = startTransMinLimit; |
193 | part.startTransMaxLimit = startTransMaxLimit; |
194 | part.endTransMinLimit = endTransMinLimit; |
195 | part.endTransMaxLimit = endTransMaxLimit; |
196 | end |
197 | end |
198 | end |
199 | table.insert(animation.parts, part); |
200 | end; |
201 | partI = partI + 1; |
202 | end; |
203 | |
204 | -- sort parts by start/end time |
205 | animation.partsReverse = {}; |
206 | for _, part in ipairs(animation.parts) do |
207 | table.insert(animation.partsReverse, part); |
208 | end; |
209 | table.sort(animation.parts, AnimatedVehicle.animPartSorter); |
210 | table.sort(animation.partsReverse, AnimatedVehicle.animPartSorterReverse); |
211 | |
212 | AnimatedVehicle.initializeParts(self, animation); |
213 | |
214 | animation.currentPartIndex = 1; |
215 | animation.duration = 0; |
216 | for _, part in ipairs(animation.parts) do |
217 | animation.duration = math.max(animation.duration, part.startTime + part.duration); |
218 | end; |
219 | |
220 | self.animations[name] = animation; |
221 | end; |
222 | |
223 | i = i+1; |
224 | end; |
225 | |
226 | self.activeAnimations = {}; |
227 | end; |
232 | function AnimatedVehicle.initializeParts(self, animation) |
233 | local numParts = table.getn(animation.parts); |
234 | |
235 | for i=1, numParts do |
236 | local part = animation.parts[i]; |
237 | |
238 | -- find the next rot part |
239 | if part.endRot ~= nil then |
240 | for j=i+1, numParts do |
241 | local part2 = animation.parts[j]; |
242 | if part.node == part2.node and part2.endRot ~= nil then |
243 | if part.startTime + part.duration > part2.startTime+0.001 then |
244 | print("Warning: overlapping rotation parts for node "..getName(part.node).." in " .. animation.name.. " "..self.configFileName); |
245 | end |
246 | part.nextRotPart = part2; |
247 | part2.prevRotPart = part; |
248 | if part2.startRot == nil then |
249 | part2.startRot = {part.endRot[1], part.endRot[2], part.endRot[3]}; |
250 | end |
251 | break; |
252 | end |
253 | end |
254 | end |
255 | |
256 | -- find the next trans part |
257 | if part.endTrans ~= nil then |
258 | for j=i+1, numParts do |
259 | local part2 = animation.parts[j]; |
260 | if part.node == part2.node and part2.endTrans ~= nil then |
261 | if part.startTime + part.duration > part2.startTime+0.001 then |
262 | print("Warning: overlapping translation parts for node "..getName(part.node).." in " .. animation.name.. " "..self.configFileName); |
263 | end |
264 | part.nextTransPart = part2; |
265 | part2.prevTransPart = part; |
266 | if part2.startTrans == nil then |
267 | part2.startTrans = {part.endTrans[1], part.endTrans[2], part.endTrans[3]}; |
268 | end |
269 | break; |
270 | end |
271 | end |
272 | end |
273 | |
274 | -- find the next scale part |
275 | if part.endScale ~= nil then |
276 | for j=i+1, numParts do |
277 | local part2 = animation.parts[j]; |
278 | if part.node == part2.node and part2.endScale ~= nil then |
279 | if part.startTime + part.duration > part2.startTime+0.001 then |
280 | print("Warning: overlapping scale parts for node "..getName(part.node).." in " .. animation.name.. " "..self.configFileName); |
281 | end |
282 | part.nextScalePart = part2; |
283 | part2.prevScalePart = part; |
284 | if part2.startScale == nil then |
285 | part2.startScale = {part.endScale[1], part.endScale[2], part.endScale[3]}; |
286 | end |
287 | break; |
288 | end |
289 | end |
290 | end |
291 | |
292 | -- find the next shader part |
293 | if part.shaderEndValues ~= nil then |
294 | for j=i+1, numParts do |
295 | local part2 = animation.parts[j]; |
296 | if part.node == part2.node and part2.shaderEndValues ~= nil then |
297 | if part.startTime + part.duration > part2.startTime+0.001 then |
298 | print("Warning: overlapping shaderParameter parts for node "..getName(part.node).." in " .. animation.name.. " "..self.configFileName); |
299 | end |
300 | part.nextShaderPart = part2; |
301 | part2.prevShaderPart = part; |
302 | if part2.shaderStartValues == nil then |
303 | part2.shaderStartValues = {part.shaderEndValues[1], part.shaderEndValues[2], part.shaderEndValues[3], part.shaderEndValues[4]}; |
304 | end |
305 | break; |
306 | end |
307 | end |
308 | end |
309 | |
310 | if self.isServer then |
311 | -- find the next joint rot limit part |
312 | if part.endRotMinLimit ~= nil then |
313 | for j=i+1, numParts do |
314 | local part2 = animation.parts[j]; |
315 | if part.componentJoint == part2.componentJoint and (part2.endRotMinLimit ~= nil and part2.endRotMaxLimit ~= nil) then |
316 | if part.startTime + part.duration > part2.startTime+0.001 then |
317 | print("Warning: overlapping joint rot limit parts for component joint "..getName(part.componentJoint.jointNode).." in " .. animation.name.. " "..self.configFileName); |
318 | end |
319 | part.nextRotLimitPart = part2; |
320 | part2.prevRotLimitPart = part; |
321 | if part2.startRotMinLimit == nil then |
322 | part2.startRotMinLimit = {part.endRotMinLimit[1], part.endRotMinLimit[2], part.endRotMinLimit[3]}; |
323 | end |
324 | if part2.startRotMaxLimit == nil then |
325 | part2.startRotMaxLimit = {part.endRotMaxLimit[1], part.endRotMaxLimit[2], part.endRotMaxLimit[3]}; |
326 | end |
327 | break; |
328 | end |
329 | end |
330 | end |
331 | |
332 | -- find the next joint trans limit part |
333 | if part.endTransMinLimit ~= nil then |
334 | for j=i+1, numParts do |
335 | local part2 = animation.parts[j]; |
336 | if part.componentJoint == part2.componentJoint and (part2.endTransMinLimit ~= nil and part2.endTransMaxLimit ~= nil) then |
337 | if part.startTime + part.duration > part2.startTime+0.001 then |
338 | print("Warning: overlapping joint trans limit parts for component joint "..getName(part.componentJoint.jointNode).." in " .. animation.name.. " "..self.configFileName); |
339 | end |
340 | part.nextTransLimitPart = part2; |
341 | part2.prevTransLimitPart = part; |
342 | if part2.startTransMinLimit == nil then |
343 | part2.startTransMinLimit = {part.endTransMinLimit[1], part.endTransMinLimit[2], part.endTransMinLimit[3]}; |
344 | end |
345 | if part2.startTransMaxLimit == nil then |
346 | part2.startTransMaxLimit = {part.endTransMaxLimit[1], part.endTransMaxLimit[2], part.endTransMaxLimit[3]}; |
347 | end |
348 | break; |
349 | end |
350 | end |
351 | end |
352 | end |
353 | end |
354 | |
355 | -- default start values to the value stored in the i3d (if not set by the end value of the previous part) |
356 | for i=1, numParts do |
357 | local part = animation.parts[i]; |
358 | if part.endRot ~= nil and part.startRot == nil then |
359 | local x,y,z = getRotation(part.node); |
360 | part.startRot = {x,y,z}; |
361 | end |
362 | if part.endTrans ~= nil and part.startTrans == nil then |
363 | local x,y,z = getTranslation(part.node); |
364 | part.startTrans = {x,y,z}; |
365 | end; |
366 | if part.endScale ~= nil and part.startScale == nil then |
367 | local x,y,z = getScale(part.node); |
368 | part.startScale = {x,y,z}; |
369 | end; |
370 | if self.isServer then |
371 | if part.endRotMinLimit ~= nil and part.startRotMinLimit == nil then |
372 | local rotLimit = part.componentJoint.rotMinLimit; |
373 | part.startRotMinLimit = {rotLimit[1], rotLimit[2], rotLimit[3]}; |
374 | end |
375 | if part.endRotMaxLimit ~= nil and part.startRotMaxLimit == nil then |
376 | local rotLimit = part.componentJoint.rotLimit; |
377 | part.startRotMaxLimit = {rotLimit[1], rotLimit[2], rotLimit[3]}; |
378 | end |
379 | if part.endTransMinLimit ~= nil and part.startTransMinLimit == nil then |
380 | local transLimit = part.componentJoint.transMinLimit; |
381 | part.startTransMinLimit = {transLimit[1], transLimit[2], transLimit[3]}; |
382 | end |
383 | if part.endTransMaxLimit ~= nil and part.startTransMaxLimit == nil then |
384 | local transLimit = part.componentJoint.transLimit; |
385 | part.startTransMaxLimit = {transLimit[1], transLimit[2], transLimit[3]}; |
386 | end |
387 | end |
388 | end |
389 | end |
912 | function AnimatedVehicle.updateAnimation(self, anim, dtToUse, stopAnim) |
913 | local name = anim.name; |
914 | |
915 | local numParts = table.getn(anim.parts) |
916 | local parts = anim.parts; |
917 | if anim.currentSpeed < 0 then |
918 | parts = anim.partsReverse; |
919 | end; |
920 | |
921 | if dtToUse > 0 then |
922 | local hasChanged = false; |
923 | local nothingToChangeYet = false; |
924 | for partI=anim.currentPartIndex, numParts do |
925 | local part = parts[partI]; |
926 | |
927 | if part.direction == 0 or ((part.direction > 0) == (anim.currentSpeed >= 0)) then |
928 | local durationToEnd = AnimatedVehicle.getDurationToEndOfPart(part, anim); |
929 | |
930 | -- is this part not playing yet? |
931 | if durationToEnd > part.duration then |
932 | nothingToChangeYet = true; |
933 | break; |
934 | end |
935 | |
936 | durationToEnd = durationToEnd+dtToUse; |
937 | |
938 | local hasPartChanged = false; |
939 | -- update the part |
940 | if part.startRot ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(part.nextRotPart, part.prevRotPart, anim, true)) then |
941 | local destRot = part.endRot; |
942 | if anim.currentSpeed < 0 then |
943 | destRot = part.startRot; |
944 | end; |
945 | if part.curRot == nil then |
946 | local x,y,z = getRotation(part.node); |
947 | part.curRot = {x,y,z}; |
948 | local invDuration = 1.0/math.max(durationToEnd, 0.001); |
949 | part.speedRot = {(destRot[1]-x)*invDuration, (destRot[2]-y)*invDuration, (destRot[3]-z)*invDuration}; |
950 | end; |
951 | if AnimatedVehicle.setMovedLimitedValues3(part.curRot, destRot, part.speedRot, dtToUse) then |
952 | setRotation(part.node, part.curRot[1], part.curRot[2], part.curRot[3]); |
953 | hasPartChanged = true; |
954 | end; |
955 | end; |
956 | if part.startTrans ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(part.nextTransPart, part.prevTransPart, anim, true)) then |
957 | local destTrans = part.endTrans; |
958 | if anim.currentSpeed < 0 then |
959 | destTrans = part.startTrans; |
960 | end; |
961 | if part.curTrans == nil then |
962 | local x,y,z = getTranslation(part.node); |
963 | part.curTrans = {x,y,z}; |
964 | local invDuration = 1.0/math.max(durationToEnd, 0.001); |
965 | part.speedTrans = {(destTrans[1]-x)*invDuration, (destTrans[2]-y)*invDuration, (destTrans[3]-z)*invDuration}; |
966 | end; |
967 | if AnimatedVehicle.setMovedLimitedValues3(part.curTrans, destTrans, part.speedTrans, dtToUse) then |
968 | setTranslation(part.node, part.curTrans[1], part.curTrans[2], part.curTrans[3]); |
969 | hasPartChanged = true; |
970 | end; |
971 | end; |
972 | if part.startScale ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(part.nextScalePart, part.prevScalePart, anim, true)) then |
973 | local destScale = part.endScale; |
974 | if anim.currentSpeed < 0 then |
975 | destScale = part.startScale; |
976 | end; |
977 | if part.curScale == nil then |
978 | local x,y,z = getScale(part.node); |
979 | part.curScale = {x,y,z}; |
980 | local invDuration = 1.0/math.max(durationToEnd, 0.001); |
981 | part.speedScale = {(destScale[1]-x)*invDuration, (destScale[2]-y)*invDuration, (destScale[3]-z)*invDuration}; |
982 | end; |
983 | if AnimatedVehicle.setMovedLimitedValues3(part.curScale, destScale, part.speedScale, dtToUse) then |
984 | setScale(part.node, part.curScale[1], part.curScale[2], part.curScale[3]); |
985 | hasPartChanged = true; |
986 | end; |
987 | end; |
988 | if part.shaderParameter ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(part.nextShaderPart, part.prevShaderPart, anim, true)) then |
989 | local destValues = part.shaderEndValues; |
990 | if anim.currentSpeed < 0 then |
991 | destValues = part.shaderStartValues; |
992 | end |
993 | if part.shaderCurValues == nil then |
994 | local x,y,z,w = getShaderParameter(part.node, part.shaderParameter); |
995 | part.shaderCurValues = {x,y,z,w}; |
996 | local invDuration = 1.0 / math.max(durationToEnd, 0.001); |
997 | part.speedShader = {(destValues[1]-x)*invDuration, (destValues[2]-y)*invDuration, (destValues[3]-z)*invDuration, (destValues[4]-w)*invDuration}; |
998 | end |
999 | if AnimatedVehicle.setMovedLimitedValues4(part.shaderCurValues, destValues, part.speedShader, dtToUse) then |
1000 | setShaderParameter(part.node, part.shaderParameter, part.shaderCurValues[1], part.shaderCurValues[2], part.shaderCurValues[3], part.shaderCurValues[4], false); |
1001 | hasPartChanged = true; |
1002 | end |
1003 | end |
1004 | if part.visibility ~= nil then |
1005 | if part.curVisibility == nil then |
1006 | part.curVisibility = getVisibility(part.node); |
1007 | end; |
1008 | if part.visibility ~= part.curVisibility then |
1009 | part.curVisibility = part.visibility; |
1010 | setVisibility(part.node, part.visibility); |
1011 | hasPartChanged = true; |
1012 | end; |
1013 | end; |
1014 | |
1015 | if self.isServer then |
1016 | if part.startRotMinLimit ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(part.nextRotLimitPart, part.prevRotLimitPart, anim, true)) then |
1017 | local destRotMinLimit = part.endRotMinLimit; |
1018 | local destRotMaxLimit = part.endRotMaxLimit; |
1019 | if anim.currentSpeed < 0 then |
1020 | destRotMinLimit = part.startRotMinLimit; |
1021 | destRotMaxLimit = part.startRotMaxLimit; |
1022 | end; |
1023 | if part.curRotMinLimit == nil then |
1024 | local x,y,z = unpack(part.componentJoint.rotMinLimit); |
1025 | part.curRotMinLimit = {x,y,z}; |
1026 | local invDuration = 1.0/math.max(durationToEnd, 0.001); |
1027 | part.speedRotMinLimit = {(destRotMinLimit[1]-x)*invDuration, (destRotMinLimit[2]-y)*invDuration, (destRotMinLimit[3]-z)*invDuration}; |
1028 | end; |
1029 | if part.curRotMaxLimit == nil then |
1030 | local x,y,z = unpack(part.componentJoint.rotLimit); |
1031 | part.curRotMaxLimit = {x,y,z}; |
1032 | local invDuration = 1.0/math.max(durationToEnd, 0.001); |
1033 | part.speedRotMaxLimit = {(destRotMaxLimit[1]-x)*invDuration, (destRotMaxLimit[2]-y)*invDuration, (destRotMaxLimit[3]-z)*invDuration}; |
1034 | end; |
1035 | for i=1, 3 do |
1036 | local newRotMinLimit = AnimatedVehicle.getMovedLimitedValue(part.curRotMinLimit[i], destRotMinLimit[i], part.speedRotMinLimit[i], dtToUse); |
1037 | local newRotMaxLimit = AnimatedVehicle.getMovedLimitedValue(part.curRotMaxLimit[i], destRotMaxLimit[i], part.speedRotMaxLimit[i], dtToUse); |
1038 | if newRotMinLimit ~= part.curRotMinLimit[i] or newRotMaxLimit ~= part.curRotMaxLimit[i] then |
1039 | part.curRotMinLimit[i] = newRotMinLimit; |
1040 | part.curRotMaxLimit[i] = newRotMaxLimit; |
1041 | self:setComponentJointRotLimit(part.componentJoint, i, newRotMinLimit, newRotMaxLimit); |
1042 | hasPartChanged = true; |
1043 | end |
1044 | end; |
1045 | end; |
1046 | if part.startTransMinLimit ~= nil and (durationToEnd > 0 or AnimatedVehicle.getNextPartIsPlaying(part.nextTransLimitPart, part.prevTransLimitPart, anim, true)) then |
1047 | local destTransMinLimit = part.endTransMinLimit; |
1048 | local destTransMaxLimit = part.endTransMaxLimit; |
1049 | if anim.currentSpeed < 0 then |
1050 | destTransMinLimit = part.startTransMinLimit; |
1051 | destTransMaxLimit = part.startTransMaxLimit; |
1052 | end; |
1053 | if part.curTransMinLimit == nil then |
1054 | local x,y,z = unpack(part.componentJoint.transMinLimit); |
1055 | part.curTransMinLimit = {x,y,z}; |
1056 | local invDuration = 1.0/math.max(durationToEnd, 0.001); |
1057 | part.speedTransMinLimit = {(destTransMinLimit[1]-x)*invDuration, (destTransMinLimit[2]-y)*invDuration, (destTransMinLimit[3]-z)*invDuration}; |
1058 | end; |
1059 | if part.curTransMaxLimit == nil then |
1060 | local x,y,z = unpack(part.componentJoint.transLimit); |
1061 | part.curTransMaxLimit = {x,y,z}; |
1062 | local invDuration = 1.0/math.max(durationToEnd, 0.001); |
1063 | part.speedTransMaxLimit = {(destTransMaxLimit[1]-x)*invDuration, (destTransMaxLimit[2]-y)*invDuration, (destTransMaxLimit[3]-z)*invDuration}; |
1064 | end; |
1065 | for i=1, 3 do |
1066 | local newTransMinLimit = AnimatedVehicle.getMovedLimitedValue(part.curTransMinLimit[i], destTransMinLimit[i], part.speedTransMinLimit[i], dtToUse); |
1067 | local newTransMaxLimit = AnimatedVehicle.getMovedLimitedValue(part.curTransMaxLimit[i], destTransMaxLimit[i], part.speedTransMaxLimit[i], dtToUse); |
1068 | if newTransMinLimit ~= part.curTransMinLimit[i] or newTransMaxLimit ~= part.curTransMaxLimit[i] then |
1069 | part.curTransMinLimit[i] = newTransMinLimit; |
1070 | part.curTransMaxLimit[i] = newTransMaxLimit; |
1071 | self:setComponentJointTransLimit(part.componentJoint, i, newTransMinLimit, newTransMaxLimit); |
1072 | hasPartChanged = true; |
1073 | end |
1074 | end |
1075 | end |
1076 | end |
1077 | |
1078 | if hasPartChanged then |
1079 | if self.setMovingToolDirty ~= nil then |
1080 | self:setMovingToolDirty(part.node); |
1081 | end |
1082 | hasChanged = true; |
1083 | end |
1084 | end |
1085 | |
1086 | if partI == anim.currentPartIndex then |
1087 | -- is this part finished? |
1088 | if (anim.currentSpeed > 0 and part.startTime + part.duration < anim.currentTime) or |
1089 | (anim.currentSpeed <= 0 and part.startTime > anim.currentTime) |
1090 | then |
1091 | self:resetAnimationPartValues(part); |
1092 | --print("finished: "..anim.currentPartIndex); |
1093 | anim.currentPartIndex = anim.currentPartIndex+1; |
1094 | end |
1095 | end |
1096 | end; |
1097 | if not nothingToChangeYet and not hasChanged and anim.currentPartIndex >= numParts then |
1098 | -- end the animation |
1099 | if anim.currentSpeed > 0 then |
1100 | anim.currentTime = anim.duration; |
1101 | else |
1102 | anim.currentTime = 0; |
1103 | end |
1104 | stopAnim = true; |
1105 | end; |
1106 | end; |
1107 | if stopAnim or anim.currentPartIndex > numParts or anim.currentPartIndex < 1 then |
1108 | if not stopAnim then |
1109 | if anim.currentSpeed > 0 then |
1110 | anim.currentTime = anim.duration; |
1111 | else |
1112 | anim.currentTime = 0; |
1113 | end |
1114 | end |
1115 | anim.currentTime = math.min(math.max(anim.currentTime, 0), anim.duration); |
1116 | anim.stopTime = nil; |
1117 | self.activeAnimations[name] = nil; |
1118 | |
1119 | if anim.looping then |
1120 | -- restart animation |
1121 | self:setAnimationTime(anim.name, math.abs((anim.duration-anim.currentTime) - 1), true); |
1122 | self:playAnimation(anim.name, anim.currentSpeed, nil, true); |
1123 | end; |
1124 | end; |
1125 | end; |