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 | |
27 | IMPLEMENT_STANDARD_RTTIEXT(AIS_MediaPlayer, AIS_InteractiveObject) |
28 | |
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) |
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 | //================================================================ |
48 | AIS_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 | //================================================================ |
68 | AIS_MediaPlayer::~AIS_MediaPlayer() |
69 | { |
70 | // stop threads |
71 | myFramePair.Nullify(); |
72 | } |
73 | |
74 | // ======================================================================= |
75 | // function : OpenInput |
76 | // purpose : |
77 | // ======================================================================= |
78 | void 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 | // ======================================================================= |
95 | bool 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 | // ======================================================================= |
137 | bool 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 | // ======================================================================= |
197 | void 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 | // ======================================================================= |
213 | void 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 | // ======================================================================= |
236 | void 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 | } |