1 // Created by: Kirill GAVRILOV
2 // Copyright (c) 2019 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_MediaPlayer.hxx>
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>
27 IMPLEMENT_STANDARD_RTTIEXT(AIS_MediaPlayer, AIS_InteractiveObject)
29 //! Create an array of triangles defining a rectangle.
30 static Handle(Graphic3d_ArrayOfTriangles) createRectangleArray (const Graphic3d_Vec2i& theLower,
31 const Graphic3d_Vec2i& theUpper,
32 Graphic3d_ArrayFlags theFlags)
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);
44 //================================================================
45 // Function : AIS_MediaPlayer
47 //================================================================
48 AIS_MediaPlayer::AIS_MediaPlayer()
49 : myFramePair (new Graphic3d_MediaTextureSet()),
51 myToClosePlayer (false)
53 SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
54 SetZLayer (Graphic3d_ZLayerId_TopOSD);
55 SetInfiniteState (true);
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);
64 //================================================================
65 // Function : ~AIS_MediaPlayer
67 //================================================================
68 AIS_MediaPlayer::~AIS_MediaPlayer()
71 myFramePair.Nullify();
74 // =======================================================================
75 // function : OpenInput
77 // =======================================================================
78 void AIS_MediaPlayer::OpenInput (const TCollection_AsciiString& thePath,
79 Standard_Boolean theToWait)
81 if (myFramePair->PlayerContext().IsNull()
87 myFramePair->OpenInput (thePath, theToWait);
91 // =======================================================================
92 // function : PresentFrame
94 // =======================================================================
95 bool AIS_MediaPlayer::PresentFrame (const Graphic3d_Vec2i& theLeftCorner,
96 const Graphic3d_Vec2i& theMaxSize)
100 myToClosePlayer = false;
101 if (!HasInteractiveContext())
106 if (!myFramePair->PlayerContext().IsNull())
108 myFramePair->PlayerContext()->Pause();
111 Handle(AIS_InteractiveContext) aCtx = GetContext();
112 Handle(AIS_InteractiveObject) aThis = this;
113 aCtx->Remove (aThis, false);
114 aCtx->CurrentViewer()->Invalidate();
118 if (myFramePair->PlayerContext().IsNull())
123 bool toRedraw = myFramePair->SwapFrames();
124 toRedraw = updateSize (theLeftCorner, theMaxSize) || toRedraw;
127 myFrameAspect->SetShaderProgram (myFramePair->ShaderProgram());
128 SynchronizeAspects();
133 // =======================================================================
134 // function : updateSize
136 // =======================================================================
137 bool AIS_MediaPlayer::updateSize (const Graphic3d_Vec2i& theLeftCorner,
138 const Graphic3d_Vec2i& theMaxSize)
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)
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)
151 aNewSize.y() = int(double(aFrameSize.x()) / aFitAspect);
155 aNewSize.x() = int(double(aFrameSize.y()) * aFitAspect);
158 for (int aCoord = 0; aCoord < 2; ++aCoord)
160 if (aNewSize[aCoord] > theMaxSize[aCoord])
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);
168 aNewPos = theLeftCorner + theMaxSize / 2 - aNewSize / 2;
170 else if (myFrameSize.x() < 2
171 || myFrameSize.y() < 2)
173 aNewSize = theMaxSize;
176 if (myFrameSize == aNewSize
177 && myFrameBottomLeft == aNewPos)
182 myFrameSize = aNewSize;
183 myFrameBottomLeft = aNewPos;
184 if (HasInteractiveContext())
187 GetContext()->Redisplay (this, false);
188 GetContext()->CurrentViewer()->Invalidate();
193 // =======================================================================
194 // function : PlayPause
196 // =======================================================================
197 void AIS_MediaPlayer::PlayPause()
199 if (myFramePair->PlayerContext().IsNull())
204 Standard_Real aProgress = 0.0, aDuration = 0.0;
205 bool isPaused = false;
206 myFramePair->PlayerContext()->PlayPause (isPaused, aProgress, aDuration);
209 // =======================================================================
210 // function : Compute
212 // =======================================================================
213 void AIS_MediaPlayer::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
214 const Handle(Prs3d_Presentation)& thePrs,
215 const Standard_Integer theMode)
217 thePrs->SetInfiniteState (IsInfinite());
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);
232 // =======================================================================
233 // function : ComputeSelection
235 // =======================================================================
236 void AIS_MediaPlayer::ComputeSelection (const Handle(SelectMgr_Selection)& theSel,
237 const Standard_Integer theMode)
244 Handle(Graphic3d_ArrayOfTriangles) aTris = createRectangleArray (myFrameBottomLeft, myFrameBottomLeft + myFrameSize, Graphic3d_ArrayFlags_None);
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());