0027764: Visualization - add functionality for animation of 3D camera and interactive...
[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 {
62 Standard_ProgramError::Raise ("AIS_Animation::Add() - attempt to add a NULL animation!");
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,
166 const Standard_Boolean theToUpdate)
167{
168 if (myTimer.IsNull())
169 {
170 myTimer = new AIS_AnimationTimer();
171 }
172 myTimer->Stop();
173 myTimer->Seek (theStartPts);
174 myTimer->SetPlaybackSpeed (thePlaySpeed);
175 Start (theToUpdate);
176}
177
178//=============================================================================
179//function : UpdateTimer
180//purpose :
181//=============================================================================
182Standard_Real AIS_Animation::UpdateTimer()
183{
184 if (myTimer.IsNull())
185 {
186 Standard_ProgramError::Raise ("AIS_Animation::UpdateTimer() - timer was not created!");
187 }
188
189 const Standard_Real anElapsedTime = myTimer->ElapsedTime();
190 Update (anElapsedTime);
191 return anElapsedTime;
192}
193
194//=============================================================================
195//function : Start
196//purpose :
197//=============================================================================
198void AIS_Animation::Start (const Standard_Boolean theToUpdate)
199{
200 UpdateTotalDuration();
201 myState = AnimationState_Started;
202 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
203 {
204 anIter.ChangeValue()->Start (Standard_False);
205 }
206
207 if (theToUpdate)
208 {
209 const Standard_Real anElapsedTime = !myTimer.IsNull()
210 ? myTimer->ElapsedTime()
211 : 0.0;
212 Update (anElapsedTime);
213 }
214
215 if (!myTimer.IsNull())
216 {
217 myTimer->Start();
218 }
219}
220
221//=============================================================================
222//function : Pause
223//purpose :
224//=============================================================================
225void AIS_Animation::Pause()
226{
227 myState = AnimationState_Paused;
228 if (!myTimer.IsNull())
229 {
230 myTimer->Pause();
231 }
232
233 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
234 {
235 anIter.ChangeValue()->Stop();
236 }
237}
238
239//=============================================================================
240//function : Stop
241//purpose :
242//=============================================================================
243void AIS_Animation::Stop()
244{
245 myState = AnimationState_Stopped;
246 if (!myTimer.IsNull())
247 {
248 myTimer->Stop();
249 }
250
251 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
252 {
253 anIter.ChangeValue()->Stop();
254 }
255}
256
257//=============================================================================
258//function : Update
259//purpose :
260//=============================================================================
261Standard_Boolean AIS_Animation::Update (const Standard_Real thePts)
262{
263 AIS_AnimationProgress aPosition;
264 aPosition.Pts = thePts;
265 aPosition.LocalPts = thePts - myPtsStart;
266 aPosition.LocalNormalized = HasOwnDuration()
267 ? (aPosition.LocalPts / myOwnDuration)
268 : 0.0;
269 aPosition.LocalNormalized = Max (0.0, aPosition.LocalNormalized);
270 aPosition.LocalNormalized = Min (1.0, aPosition.LocalNormalized);
271 updateWithChildren (aPosition);
272 return thePts < myPtsStart + Duration();
273}
274
275//=============================================================================
276//function : updateWithChildren
277//purpose :
278//=============================================================================
279void AIS_Animation::updateWithChildren (const AIS_AnimationProgress& thePosition)
280{
281 if (thePosition.LocalPts < 0.0
282 || IsStopped())
283 {
284 return;
285 }
286
287 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
288 {
289 const Handle(AIS_Animation)& anAnim = anIter.Value();
290 AIS_AnimationProgress aPosition = thePosition;
291 aPosition.LocalPts = aPosition.LocalPts - anAnim->StartPts();
292 aPosition.LocalNormalized = anAnim->HasOwnDuration()
293 ? (aPosition.LocalPts / anAnim->OwnDuration())
294 : 0.0;
295 aPosition.LocalNormalized = Max (0.0, aPosition.LocalNormalized);
296 aPosition.LocalNormalized = Min (1.0, aPosition.LocalNormalized);
297 anAnim->updateWithChildren (aPosition);
298 }
299
300 if (thePosition.LocalPts >= Duration())
301 {
302 Stop();
303 }
304
305 update (thePosition);
306}