0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / AIS / AIS_MediaPlayer.cxx
CommitLineData
98e6c6d1 1// Created by: Kirill GAVRILOV
2// Copyright (c) 2019 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_MediaPlayer.hxx>
16
17#include <AIS_InteractiveContext.hxx>
18#include <Media_PlayerContext.hxx>
19#include <Message.hxx>
20#include <Message_Messenger.hxx>
21#include <Graphic3d_ArrayOfTriangles.hxx>
22#include <Graphic3d_MediaTexture.hxx>
23#include <SelectMgr_EntityOwner.hxx>
24#include <Select3D_SensitivePrimitiveArray.hxx>
25#include <V3d_Viewer.hxx>
26
27IMPLEMENT_STANDARD_RTTIEXT(AIS_MediaPlayer, AIS_InteractiveObject)
28
29//! Create an array of triangles defining a rectangle.
30static Handle(Graphic3d_ArrayOfTriangles) createRectangleArray (const Graphic3d_Vec2i& theLower,
31 const Graphic3d_Vec2i& theUpper,
32 Graphic3d_ArrayFlags theFlags)
33{
34 Handle(Graphic3d_ArrayOfTriangles) aRectTris = new Graphic3d_ArrayOfTriangles (4, 6, theFlags);
35 aRectTris->AddVertex (gp_Pnt (theLower.x(), theLower.y(), 0.0), gp_Pnt2d (0.0, 1.0));
36 aRectTris->AddVertex (gp_Pnt (theLower.x(), theUpper.y(), 0.0), gp_Pnt2d (0.0, 0.0));
37 aRectTris->AddVertex (gp_Pnt (theUpper.x(), theUpper.y(), 0.0), gp_Pnt2d (1.0, 0.0));
38 aRectTris->AddVertex (gp_Pnt (theUpper.x(), theLower.y(), 0.0), gp_Pnt2d (1.0, 1.0));
39 aRectTris->AddEdges (1, 2, 3);
40 aRectTris->AddEdges (1, 3, 4);
41 return aRectTris;
42}
43
44//================================================================
45// Function : AIS_MediaPlayer
46// Purpose :
47//================================================================
48AIS_MediaPlayer::AIS_MediaPlayer()
49: myFramePair (new Graphic3d_MediaTextureSet()),
50 myFrameSize (1, 1),
51 myToClosePlayer (false)
52{
53 SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
54 SetZLayer (Graphic3d_ZLayerId_TopOSD);
55 SetInfiniteState (true);
56
57 Graphic3d_MaterialAspect aMat;
58 myFrameAspect = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID, Quantity_NOC_WHITE, Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0f, aMat, aMat);
59 myFrameAspect->SetShadingModel (Graphic3d_TOSM_UNLIT);
60 myFrameAspect->SetTextureMapOn (true);
61 myFrameAspect->SetTextureSet (myFramePair);
62}
63
64//================================================================
65// Function : ~AIS_MediaPlayer
66// Purpose :
67//================================================================
68AIS_MediaPlayer::~AIS_MediaPlayer()
69{
70 // stop threads
71 myFramePair.Nullify();
72}
73
74// =======================================================================
75// function : OpenInput
76// purpose :
77// =======================================================================
78void AIS_MediaPlayer::OpenInput (const TCollection_AsciiString& thePath,
79 Standard_Boolean theToWait)
80{
81 if (myFramePair->PlayerContext().IsNull()
82 && thePath.IsEmpty())
83 {
84 return;
85 }
86
87 myFramePair->OpenInput (thePath, theToWait);
88 SynchronizeAspects();
89}
90
91// =======================================================================
92// function : PresentFrame
93// purpose :
94// =======================================================================
95bool AIS_MediaPlayer::PresentFrame (const Graphic3d_Vec2i& theLeftCorner,
96 const Graphic3d_Vec2i& theMaxSize)
97{
98 if (myToClosePlayer)
99 {
100 myToClosePlayer = false;
101 if (!HasInteractiveContext())
102 {
103 return false;
104 }
105
106 if (!myFramePair->PlayerContext().IsNull())
107 {
108 myFramePair->PlayerContext()->Pause();
109 }
110
111 Handle(AIS_InteractiveContext) aCtx = GetContext();
112 Handle(AIS_InteractiveObject) aThis = this;
113 aCtx->Remove (aThis, false);
114 aCtx->CurrentViewer()->Invalidate();
115 return true;
116 }
117
118 if (myFramePair->PlayerContext().IsNull())
119 {
120 return false;
121 }
122
123 bool toRedraw = myFramePair->SwapFrames();
124 toRedraw = updateSize (theLeftCorner, theMaxSize) || toRedraw;
125 if (toRedraw)
126 {
127 myFrameAspect->SetShaderProgram (myFramePair->ShaderProgram());
128 SynchronizeAspects();
129 }
130 return toRedraw;
131}
132
133// =======================================================================
134// function : updateSize
135// purpose :
136// =======================================================================
137bool AIS_MediaPlayer::updateSize (const Graphic3d_Vec2i& theLeftCorner,
138 const Graphic3d_Vec2i& theMaxSize)
139{
140 const Graphic3d_Vec2i aFrameSize = myFramePair->FrameSize();
141 Graphic3d_Vec2i aNewPos = theLeftCorner;
142 Graphic3d_Vec2i aNewSize = myFrameSize;
143 if (aFrameSize.x() > 0
144 && aFrameSize.y() > 0)
145 {
146 const double anAspect = double(theMaxSize.x()) / double(theMaxSize.y());
147 const double aFitAspect = double(aFrameSize.x()) / double(aFrameSize.y());
148 aNewSize = aFrameSize;
149 if (aFitAspect >= anAspect)
150 {
151 aNewSize.y() = int(double(aFrameSize.x()) / aFitAspect);
152 }
153 else
154 {
155 aNewSize.x() = int(double(aFrameSize.y()) * aFitAspect);
156 }
157
158 for (int aCoord = 0; aCoord < 2; ++aCoord)
159 {
160 if (aNewSize[aCoord] > theMaxSize[aCoord])
161 {
162 const double aScale = double(theMaxSize[aCoord]) / double(aNewSize[aCoord]);
163 aNewSize.x() = int(double(aNewSize.x()) * aScale);
164 aNewSize.y() = int(double(aNewSize.y()) * aScale);
165 }
166 }
167
168 aNewPos = theLeftCorner + theMaxSize / 2 - aNewSize / 2;
169 }
170 else if (myFrameSize.x() < 2
171 || myFrameSize.y() < 2)
172 {
173 aNewSize = theMaxSize;
174 }
175
176 if (myFrameSize == aNewSize
177 && myFrameBottomLeft == aNewPos)
178 {
179 return false;
180 }
181
182 myFrameSize = aNewSize;
183 myFrameBottomLeft = aNewPos;
184 if (HasInteractiveContext())
185 {
186 SetToUpdate();
187 GetContext()->Redisplay (this, false);
188 GetContext()->CurrentViewer()->Invalidate();
189 }
190 return true;
191}
192
193// =======================================================================
194// function : PlayPause
195// purpose :
196// =======================================================================
197void AIS_MediaPlayer::PlayPause()
198{
199 if (myFramePair->PlayerContext().IsNull())
200 {
201 return;
202 }
203
204 Standard_Real aProgress = 0.0, aDuration = 0.0;
205 bool isPaused = false;
206 myFramePair->PlayerContext()->PlayPause (isPaused, aProgress, aDuration);
207}
208
209// =======================================================================
210// function : Compute
211// purpose :
212// =======================================================================
213void AIS_MediaPlayer::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
214 const Handle(Prs3d_Presentation)& thePrs,
215 const Standard_Integer theMode)
216{
217 thePrs->SetInfiniteState (IsInfinite());
218 if (theMode != 0)
219 {
220 return;
221 }
222
223 // main frame
224 {
225 Handle(Graphic3d_ArrayOfTriangles) aTris = createRectangleArray (myFrameBottomLeft, myFrameBottomLeft + myFrameSize, Graphic3d_ArrayFlags_VertexTexel);
226 Handle(Graphic3d_Group) aMainGroup = thePrs->NewGroup();
227 aMainGroup->SetGroupPrimitivesAspect (myFrameAspect);
228 aMainGroup->AddPrimitiveArray (aTris);
229 }
230}
231
232// =======================================================================
233// function : ComputeSelection
234// purpose :
235// =======================================================================
236void AIS_MediaPlayer::ComputeSelection (const Handle(SelectMgr_Selection)& theSel,
237 const Standard_Integer theMode)
238{
239 if (theMode != 0)
240 {
241 return;
242 }
243
244 Handle(Graphic3d_ArrayOfTriangles) aTris = createRectangleArray (myFrameBottomLeft, myFrameBottomLeft + myFrameSize, Graphic3d_ArrayFlags_None);
245
246 Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this, 5);
247 Handle(Select3D_SensitivePrimitiveArray) aSens = new Select3D_SensitivePrimitiveArray (anOwner);
248 aSens->InitTriangulation (aTris->Attributes(), aTris->Indices(), TopLoc_Location());
249 theSel->Add (aSens);
250}