0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / AIS / AIS_Animation.cxx
CommitLineData
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
19IMPLEMENT_STANDARD_RTTIEXT(AIS_Animation, Standard_Transient)
20
21//=============================================================================
22//function : Constructor
23//purpose :
24//=============================================================================
25AIS_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//=============================================================================
39AIS_Animation::~AIS_Animation()
40{
41 Clear();
42}
43
44//=============================================================================
45//function : Clear
46//purpose :
47//=============================================================================
48void AIS_Animation::Clear()
49{
50 myAnimations.Clear();
51 myOwnDuration = 0.0;
52}
53
54//=============================================================================
55//function : Add
56//purpose :
57//=============================================================================
58void 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//=============================================================================
82Handle(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//=============================================================================
98Standard_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//=============================================================================
116Standard_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//=============================================================================
135void 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//=============================================================================
151void 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//=============================================================================
164void 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 {
98e6c6d1 171 myTimer = new Media_Timer();
1beb58d7 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//=============================================================================
188Standard_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//=============================================================================
204void 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//=============================================================================
231void 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//=============================================================================
249void 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//=============================================================================
267Standard_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//=============================================================================
285void 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}