1beb58d7 |
1 | // Created by: Anastasia BORISOVA |
2 | // Copyright (c) 2016 OPEN CASCADE SAS |
3 | // |
4 | // This file is part of Open CASCADE Technology software library. |
5 | // |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
11 | // |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
14 | |
15 | #include <AIS_Animation.hxx> |
16 | |
17 | #include <Standard_Assert.hxx> |
18 | |
19 | IMPLEMENT_STANDARD_RTTIEXT(AIS_Animation, Standard_Transient) |
20 | |
21 | //============================================================================= |
22 | //function : Constructor |
23 | //purpose : |
24 | //============================================================================= |
25 | AIS_Animation::AIS_Animation (const TCollection_AsciiString& theAnimationName) |
26 | : myName (theAnimationName), |
27 | myState (AnimationState_Stopped), |
28 | myPtsStart (0.0), |
29 | myOwnDuration (0.0), |
30 | myChildrenDuration (0.0) |
31 | { |
32 | // |
33 | } |
34 | |
35 | //============================================================================= |
36 | //function : ~AIS_Animation |
37 | //purpose : |
38 | //============================================================================= |
39 | AIS_Animation::~AIS_Animation() |
40 | { |
41 | Clear(); |
42 | } |
43 | |
44 | //============================================================================= |
45 | //function : Clear |
46 | //purpose : |
47 | //============================================================================= |
48 | void AIS_Animation::Clear() |
49 | { |
50 | myAnimations.Clear(); |
51 | myOwnDuration = 0.0; |
52 | } |
53 | |
54 | //============================================================================= |
55 | //function : Add |
56 | //purpose : |
57 | //============================================================================= |
58 | void AIS_Animation::Add (const Handle(AIS_Animation)& theAnimation) |
59 | { |
60 | if (theAnimation.IsNull()) |
61 | { |
9775fa61 |
62 | throw Standard_ProgramError("AIS_Animation::Add() - attempt to add a NULL animation!"); |
1beb58d7 |
63 | } |
64 | |
65 | for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next()) |
66 | { |
67 | if (anIter.Value() == theAnimation) |
68 | { |
69 | UpdateTotalDuration(); |
70 | return; |
71 | } |
72 | } |
73 | |
74 | myAnimations.Append (theAnimation); |
75 | UpdateTotalDuration(); |
76 | } |
77 | |
78 | //============================================================================= |
79 | //function : Find |
80 | //purpose : |
81 | //============================================================================= |
82 | Handle(AIS_Animation) AIS_Animation::Find (const TCollection_AsciiString& theAnimationName) const |
83 | { |
84 | for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next()) |
85 | { |
86 | if (anIter.Value()->Name() == theAnimationName) |
87 | { |
88 | return anIter.Value(); |
89 | } |
90 | } |
91 | return Handle(AIS_Animation)(); |
92 | } |
93 | |
94 | //============================================================================= |
95 | //function : Remove |
96 | //purpose : |
97 | //============================================================================= |
98 | Standard_Boolean AIS_Animation::Remove (const Handle(AIS_Animation)& theAnimation) |
99 | { |
100 | for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next()) |
101 | { |
102 | if (anIter.Value() == theAnimation) |
103 | { |
104 | myAnimations.Remove (anIter); |
105 | UpdateTotalDuration(); |
106 | return Standard_True; |
107 | } |
108 | } |
109 | return Standard_False; |
110 | } |
111 | |
112 | //============================================================================= |
113 | //function : Replace |
114 | //purpose : |
115 | //============================================================================= |
116 | Standard_Boolean AIS_Animation::Replace (const Handle(AIS_Animation)& theAnimationOld, |
117 | const Handle(AIS_Animation)& theAnimationNew) |
118 | { |
119 | for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next()) |
120 | { |
121 | if (anIter.Value() == theAnimationOld) |
122 | { |
123 | anIter.ChangeValue() = theAnimationNew; |
124 | UpdateTotalDuration(); |
125 | return Standard_True; |
126 | } |
127 | } |
128 | return Standard_False; |
129 | } |
130 | |
131 | //============================================================================= |
132 | //function : CopyFrom |
133 | //purpose : |
134 | //============================================================================= |
135 | void AIS_Animation::CopyFrom (const Handle(AIS_Animation)& theOther) |
136 | { |
137 | myAnimations.Clear(); |
138 | for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (theOther->myAnimations); anIter.More(); anIter.Next()) |
139 | { |
140 | myAnimations.Append (anIter.Value()); |
141 | } |
142 | UpdateTotalDuration(); |
143 | myPtsStart = theOther->myPtsStart; |
144 | myOwnDuration = theOther->myOwnDuration; |
145 | } |
146 | |
147 | //============================================================================= |
148 | //function : UpdateTotalDuration |
149 | //purpose : |
150 | //============================================================================= |
151 | void AIS_Animation::UpdateTotalDuration() |
152 | { |
153 | myChildrenDuration = 0.0; |
154 | for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next()) |
155 | { |
156 | myChildrenDuration = Max (myChildrenDuration, anIter.Value()->StartPts() + anIter.Value()->Duration()); |
157 | } |
158 | } |
159 | |
160 | //============================================================================= |
161 | //function : StartTimer |
162 | //purpose : |
163 | //============================================================================= |
164 | void AIS_Animation::StartTimer (const Standard_Real theStartPts, |
165 | const Standard_Real thePlaySpeed, |
bf7b2ceb |
166 | const Standard_Boolean theToUpdate, |
167 | const Standard_Boolean theToStopTimer) |
1beb58d7 |
168 | { |
169 | if (myTimer.IsNull()) |
170 | { |
171 | myTimer = new AIS_AnimationTimer(); |
172 | } |
173 | myTimer->Stop(); |
174 | myTimer->Seek (theStartPts); |
175 | myTimer->SetPlaybackSpeed (thePlaySpeed); |
176 | Start (theToUpdate); |
bf7b2ceb |
177 | if (theToStopTimer) |
178 | { |
179 | myTimer->Stop(); |
180 | myTimer->Seek (theStartPts); |
181 | } |
1beb58d7 |
182 | } |
183 | |
184 | //============================================================================= |
185 | //function : UpdateTimer |
186 | //purpose : |
187 | //============================================================================= |
188 | Standard_Real AIS_Animation::UpdateTimer() |
189 | { |
190 | if (myTimer.IsNull()) |
191 | { |
9775fa61 |
192 | throw Standard_ProgramError("AIS_Animation::UpdateTimer() - timer was not created!"); |
1beb58d7 |
193 | } |
194 | |
195 | const Standard_Real anElapsedTime = myTimer->ElapsedTime(); |
196 | Update (anElapsedTime); |
197 | return anElapsedTime; |
198 | } |
199 | |
200 | //============================================================================= |
201 | //function : Start |
202 | //purpose : |
203 | //============================================================================= |
204 | void AIS_Animation::Start (const Standard_Boolean theToUpdate) |
205 | { |
206 | UpdateTotalDuration(); |
207 | myState = AnimationState_Started; |
208 | for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next()) |
209 | { |
210 | anIter.ChangeValue()->Start (Standard_False); |
211 | } |
212 | |
213 | if (theToUpdate) |
214 | { |
215 | const Standard_Real anElapsedTime = !myTimer.IsNull() |
216 | ? myTimer->ElapsedTime() |
217 | : 0.0; |
218 | Update (anElapsedTime); |
219 | } |
220 | |
221 | if (!myTimer.IsNull()) |
222 | { |
223 | myTimer->Start(); |
224 | } |
225 | } |
226 | |
227 | //============================================================================= |
228 | //function : Pause |
229 | //purpose : |
230 | //============================================================================= |
231 | void AIS_Animation::Pause() |
232 | { |
233 | myState = AnimationState_Paused; |
234 | if (!myTimer.IsNull()) |
235 | { |
236 | myTimer->Pause(); |
237 | } |
238 | |
239 | for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next()) |
240 | { |
241 | anIter.ChangeValue()->Stop(); |
242 | } |
243 | } |
244 | |
245 | //============================================================================= |
246 | //function : Stop |
247 | //purpose : |
248 | //============================================================================= |
249 | void AIS_Animation::Stop() |
250 | { |
251 | myState = AnimationState_Stopped; |
252 | if (!myTimer.IsNull()) |
253 | { |
254 | myTimer->Stop(); |
255 | } |
256 | |
257 | for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next()) |
258 | { |
259 | anIter.ChangeValue()->Stop(); |
260 | } |
261 | } |
262 | |
263 | //============================================================================= |
264 | //function : Update |
265 | //purpose : |
266 | //============================================================================= |
267 | Standard_Boolean AIS_Animation::Update (const Standard_Real thePts) |
268 | { |
269 | AIS_AnimationProgress aPosition; |
270 | aPosition.Pts = thePts; |
271 | aPosition.LocalPts = thePts - myPtsStart; |
272 | aPosition.LocalNormalized = HasOwnDuration() |
273 | ? (aPosition.LocalPts / myOwnDuration) |
274 | : 0.0; |
275 | aPosition.LocalNormalized = Max (0.0, aPosition.LocalNormalized); |
276 | aPosition.LocalNormalized = Min (1.0, aPosition.LocalNormalized); |
277 | updateWithChildren (aPosition); |
278 | return thePts < myPtsStart + Duration(); |
279 | } |
280 | |
281 | //============================================================================= |
282 | //function : updateWithChildren |
283 | //purpose : |
284 | //============================================================================= |
285 | void AIS_Animation::updateWithChildren (const AIS_AnimationProgress& thePosition) |
286 | { |
287 | if (thePosition.LocalPts < 0.0 |
288 | || IsStopped()) |
289 | { |
290 | return; |
291 | } |
292 | |
293 | for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next()) |
294 | { |
295 | const Handle(AIS_Animation)& anAnim = anIter.Value(); |
296 | AIS_AnimationProgress aPosition = thePosition; |
297 | aPosition.LocalPts = aPosition.LocalPts - anAnim->StartPts(); |
298 | aPosition.LocalNormalized = anAnim->HasOwnDuration() |
299 | ? (aPosition.LocalPts / anAnim->OwnDuration()) |
300 | : 0.0; |
301 | aPosition.LocalNormalized = Max (0.0, aPosition.LocalNormalized); |
302 | aPosition.LocalNormalized = Min (1.0, aPosition.LocalNormalized); |
303 | anAnim->updateWithChildren (aPosition); |
304 | } |
305 | |
306 | if (thePosition.LocalPts >= Duration()) |
307 | { |
308 | Stop(); |
309 | } |
310 | |
311 | update (thePosition); |
312 | } |