1 // Created by: Anastasia BORISOVA
2 // Copyright (c) 2016 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <AIS_Animation.hxx>
17 #include <Standard_Assert.hxx>
19 IMPLEMENT_STANDARD_RTTIEXT(AIS_Animation, Standard_Transient)
21 //=============================================================================
22 //function : Constructor
24 //=============================================================================
25 AIS_Animation::AIS_Animation (const TCollection_AsciiString& theAnimationName)
26 : myName (theAnimationName),
27 myState (AnimationState_Stopped),
30 myChildrenDuration (0.0)
35 //=============================================================================
36 //function : ~AIS_Animation
38 //=============================================================================
39 AIS_Animation::~AIS_Animation()
44 //=============================================================================
47 //=============================================================================
48 void AIS_Animation::Clear()
54 //=============================================================================
57 //=============================================================================
58 void AIS_Animation::Add (const Handle(AIS_Animation)& theAnimation)
60 if (theAnimation.IsNull())
62 throw Standard_ProgramError("AIS_Animation::Add() - attempt to add a NULL animation!");
65 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
67 if (anIter.Value() == theAnimation)
69 UpdateTotalDuration();
74 myAnimations.Append (theAnimation);
75 UpdateTotalDuration();
78 //=============================================================================
81 //=============================================================================
82 Handle(AIS_Animation) AIS_Animation::Find (const TCollection_AsciiString& theAnimationName) const
84 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
86 if (anIter.Value()->Name() == theAnimationName)
88 return anIter.Value();
91 return Handle(AIS_Animation)();
94 //=============================================================================
97 //=============================================================================
98 Standard_Boolean AIS_Animation::Remove (const Handle(AIS_Animation)& theAnimation)
100 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
102 if (anIter.Value() == theAnimation)
104 myAnimations.Remove (anIter);
105 UpdateTotalDuration();
106 return Standard_True;
109 return Standard_False;
112 //=============================================================================
115 //=============================================================================
116 Standard_Boolean AIS_Animation::Replace (const Handle(AIS_Animation)& theAnimationOld,
117 const Handle(AIS_Animation)& theAnimationNew)
119 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
121 if (anIter.Value() == theAnimationOld)
123 anIter.ChangeValue() = theAnimationNew;
124 UpdateTotalDuration();
125 return Standard_True;
128 return Standard_False;
131 //=============================================================================
132 //function : CopyFrom
134 //=============================================================================
135 void AIS_Animation::CopyFrom (const Handle(AIS_Animation)& theOther)
137 myAnimations.Clear();
138 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (theOther->myAnimations); anIter.More(); anIter.Next())
140 myAnimations.Append (anIter.Value());
142 UpdateTotalDuration();
143 myPtsStart = theOther->myPtsStart;
144 myOwnDuration = theOther->myOwnDuration;
147 //=============================================================================
148 //function : UpdateTotalDuration
150 //=============================================================================
151 void AIS_Animation::UpdateTotalDuration()
153 myChildrenDuration = 0.0;
154 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
156 myChildrenDuration = Max (myChildrenDuration, anIter.Value()->StartPts() + anIter.Value()->Duration());
160 //=============================================================================
161 //function : StartTimer
163 //=============================================================================
164 void AIS_Animation::StartTimer (const Standard_Real theStartPts,
165 const Standard_Real thePlaySpeed,
166 const Standard_Boolean theToUpdate,
167 const Standard_Boolean theToStopTimer)
169 if (myTimer.IsNull())
171 myTimer = new AIS_AnimationTimer();
174 myTimer->Seek (theStartPts);
175 myTimer->SetPlaybackSpeed (thePlaySpeed);
180 myTimer->Seek (theStartPts);
184 //=============================================================================
185 //function : UpdateTimer
187 //=============================================================================
188 Standard_Real AIS_Animation::UpdateTimer()
190 if (myTimer.IsNull())
192 throw Standard_ProgramError("AIS_Animation::UpdateTimer() - timer was not created!");
195 const Standard_Real anElapsedTime = myTimer->ElapsedTime();
196 Update (anElapsedTime);
197 return anElapsedTime;
200 //=============================================================================
203 //=============================================================================
204 void AIS_Animation::Start (const Standard_Boolean theToUpdate)
206 UpdateTotalDuration();
207 myState = AnimationState_Started;
208 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
210 anIter.ChangeValue()->Start (Standard_False);
215 const Standard_Real anElapsedTime = !myTimer.IsNull()
216 ? myTimer->ElapsedTime()
218 Update (anElapsedTime);
221 if (!myTimer.IsNull())
227 //=============================================================================
230 //=============================================================================
231 void AIS_Animation::Pause()
233 myState = AnimationState_Paused;
234 if (!myTimer.IsNull())
239 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
241 anIter.ChangeValue()->Stop();
245 //=============================================================================
248 //=============================================================================
249 void AIS_Animation::Stop()
251 myState = AnimationState_Stopped;
252 if (!myTimer.IsNull())
257 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
259 anIter.ChangeValue()->Stop();
263 //=============================================================================
266 //=============================================================================
267 Standard_Boolean AIS_Animation::Update (const Standard_Real thePts)
269 AIS_AnimationProgress aPosition;
270 aPosition.Pts = thePts;
271 aPosition.LocalPts = thePts - myPtsStart;
272 aPosition.LocalNormalized = HasOwnDuration()
273 ? (aPosition.LocalPts / myOwnDuration)
275 aPosition.LocalNormalized = Max (0.0, aPosition.LocalNormalized);
276 aPosition.LocalNormalized = Min (1.0, aPosition.LocalNormalized);
277 updateWithChildren (aPosition);
278 return thePts < myPtsStart + Duration();
281 //=============================================================================
282 //function : updateWithChildren
284 //=============================================================================
285 void AIS_Animation::updateWithChildren (const AIS_AnimationProgress& thePosition)
287 if (thePosition.LocalPts < 0.0
293 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
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())
301 aPosition.LocalNormalized = Max (0.0, aPosition.LocalNormalized);
302 aPosition.LocalNormalized = Min (1.0, aPosition.LocalNormalized);
303 anAnim->updateWithChildren (aPosition);
306 if (thePosition.LocalPts >= Duration())
311 update (thePosition);