Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / avmedia / source / opengl / oglwindow.cxx
blobae550ff37f84fd7714e45401db59c32e5e4104ee
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include "oglwindow.hxx"
11 #include <cppuhelper/supportsservice.hxx>
13 using namespace com::sun::star;
14 using namespace libgltf;
16 namespace avmedia { namespace ogl {
18 OGLWindow::OGLWindow( glTFHandle& rHandle, const rtl::Reference<OpenGLContext> &rContext, vcl::Window& rEventHandlerParent )
19 : m_rHandle( rHandle )
20 , m_xContext( rContext )
21 , m_rEventHandler( rEventHandlerParent )
22 , m_bVisible ( false )
23 , m_aLastMousePos(Point(0,0))
24 , m_bIsOrbitMode( false )
28 OGLWindow::~OGLWindow()
30 dispose();
33 void SAL_CALL OGLWindow::update()
35 m_xContext->makeCurrent();
36 int nRet = gltf_prepare_renderer(&m_rHandle);
37 if( nRet != 0 )
39 SAL_WARN("avmedia.opengl", "Error occurred while preparing for rendering! Error code: " << nRet);
40 return;
42 gltf_renderer(&m_rHandle);
43 gltf_complete_renderer(&m_rHandle);
44 m_xContext->swapBuffers();
47 sal_Bool SAL_CALL OGLWindow::setZoomLevel( css::media::ZoomLevel /*eZoomLevel*/ )
49 return false;
52 css::media::ZoomLevel SAL_CALL OGLWindow::getZoomLevel()
54 return media::ZoomLevel_ORIGINAL;
57 void SAL_CALL OGLWindow::setPointerType( sal_Int32 )
61 OUString SAL_CALL OGLWindow::getImplementationName()
63 return OUString("com.sun.star.comp.avmedia.Window_OpenGL");
66 sal_Bool SAL_CALL OGLWindow::supportsService( const OUString& rServiceName )
68 return cppu::supportsService(this, rServiceName);
71 uno::Sequence< OUString > SAL_CALL OGLWindow::getSupportedServiceNames()
73 return { "com.sun.star.media.Window_OpenGL" };
76 void SAL_CALL OGLWindow::dispose()
78 assert(m_rEventHandler.GetParent());
79 m_rEventHandler.GetParent()->RemoveEventListener( LINK(this, OGLWindow, FocusGrabber));
80 m_rEventHandler.RemoveEventListener( LINK(this, OGLWindow, CameraHandler));
83 void SAL_CALL OGLWindow::addEventListener( const uno::Reference< lang::XEventListener >& )
87 void SAL_CALL OGLWindow::removeEventListener( const uno::Reference< lang::XEventListener >& )
91 void SAL_CALL OGLWindow::setPosSize( sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int16 /*nFlags*/ )
93 if( m_rHandle.viewport.x != nX || m_rHandle.viewport.x != nY ||
94 m_rHandle.viewport.width != nWidth || m_rHandle.viewport.height != nHeight )
96 m_xContext->setWinSize(Size(nWidth,nHeight));
97 m_rHandle.viewport.x = nX;
98 m_rHandle.viewport.y = nY;
99 m_rHandle.viewport.width = nWidth;
100 m_rHandle.viewport.height = nHeight;
104 awt::Rectangle SAL_CALL OGLWindow::getPosSize()
106 return awt::Rectangle(m_rHandle.viewport.x, m_rHandle.viewport.y,
107 m_rHandle.viewport.width, m_rHandle.viewport.height);
110 void SAL_CALL OGLWindow::setVisible( sal_Bool bSet )
112 assert(m_rEventHandler.GetParent());
113 if( bSet && !m_bVisible )
115 m_rEventHandler.GetParent()->AddEventListener( LINK(this, OGLWindow, FocusGrabber));
116 m_rEventHandler.AddEventListener( LINK(this, OGLWindow, CameraHandler));
117 m_rEventHandler.GrabFocus();
119 else if( !bSet )
121 m_rEventHandler.GetParent()->RemoveEventListener( LINK(this, OGLWindow, FocusGrabber));
122 m_rEventHandler.RemoveEventListener( LINK(this, OGLWindow, CameraHandler));
124 m_bVisible = bSet;
127 void SAL_CALL OGLWindow::setEnable( sal_Bool )
131 void SAL_CALL OGLWindow::setFocus()
135 void SAL_CALL OGLWindow::addWindowListener( const uno::Reference< awt::XWindowListener >& )
139 void SAL_CALL OGLWindow::removeWindowListener( const uno::Reference< awt::XWindowListener >& )
143 void SAL_CALL OGLWindow::addFocusListener( const uno::Reference< awt::XFocusListener >& )
147 void SAL_CALL OGLWindow::removeFocusListener( const uno::Reference< awt::XFocusListener >& )
151 void SAL_CALL OGLWindow::addKeyListener( const uno::Reference< awt::XKeyListener >& )
155 void SAL_CALL OGLWindow::removeKeyListener( const uno::Reference< awt::XKeyListener >& )
159 void SAL_CALL OGLWindow::addMouseListener( const uno::Reference< awt::XMouseListener >& )
163 void SAL_CALL OGLWindow::removeMouseListener( const uno::Reference< awt::XMouseListener >& )
167 void SAL_CALL OGLWindow::addMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& )
171 void SAL_CALL OGLWindow::removeMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& )
175 void SAL_CALL OGLWindow::addPaintListener( const uno::Reference< awt::XPaintListener >& )
179 void SAL_CALL OGLWindow::removePaintListener( const uno::Reference< awt::XPaintListener >& )
183 IMPL_LINK(OGLWindow, FocusGrabber, VclWindowEvent&, rEvent, void)
185 if( rEvent.GetId() == VclEventId::WindowMouseMove )
187 MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rEvent.GetData());
188 if(pMouseEvt)
190 const Point& rMousePos = pMouseEvt->GetPosPixel();
191 const tools::Rectangle aWinRect(m_rEventHandler.GetPosPixel(),m_rEventHandler.GetSizePixel());
192 // Grab focus to the OpenGL window when mouse pointer is over it
193 if( aWinRect.IsInside(rMousePos) )
195 if ( !m_rEventHandler.HasFocus() )
197 m_rEventHandler.GrabFocus();
200 // Move focus to the document when mouse is not over the OpenGL window
201 else if ( m_rEventHandler.HasFocus() )
203 m_rEventHandler.GrabFocusToDocument();
209 IMPL_LINK(OGLWindow, CameraHandler, VclWindowEvent&, rEvent, void)
211 if( rEvent.GetId() == VclEventId::WindowKeyInput )
213 KeyEvent* pKeyEvt = static_cast<KeyEvent*>(rEvent.GetData());
214 if(pKeyEvt)
216 const sal_uInt16 nCode = pKeyEvt->GetKeyCode().GetCode();
217 if (nCode == KEY_Q || nCode == KEY_E ||
218 nCode == KEY_A || nCode == KEY_D ||
219 nCode == KEY_W || nCode == KEY_S )
221 // Calculate movement
222 glm::vec3 vMoveBy;
224 glm::vec3 vEye;
225 glm::vec3 vView;
226 glm::vec3 vUp;
227 gltf_get_camera_pos(&m_rHandle, &vEye,&vView,&vUp);
228 float fModelSize =(float)gltf_get_model_size(&m_rHandle);
230 glm::vec3 vMove = vView-vEye;
231 vMove = glm::normalize(vMove);
232 vMove *= 25.0f;
233 glm::vec3 vStrafe = glm::cross(vMove, vUp);
234 vStrafe = glm::normalize(vStrafe);
235 vStrafe *= 25.0f;
236 glm::vec3 vMup = vUp * 25.0f;
238 if( !m_bIsOrbitMode )
240 if(nCode == KEY_E)vMoveBy += vMup*(0.0005f*fModelSize);
241 if(nCode == KEY_Q)vMoveBy -= vMup*(0.0005f*fModelSize);
242 if(nCode == KEY_W)vMoveBy += vMove*(0.0005f*fModelSize);
243 if(nCode == KEY_S)vMoveBy -= vMove*(0.0005f*fModelSize);
244 if(nCode == KEY_A)vMoveBy -= vStrafe*(0.0005f*fModelSize);
245 if(nCode == KEY_D)vMoveBy += vStrafe*(0.0005f*fModelSize);
247 else
249 bool bZoomIn = false;
250 bool bZoomOut = false;
251 if(nCode == KEY_E)
253 vMoveBy += vMove*(0.0005f*fModelSize);
254 bZoomIn = true;
256 if(nCode == KEY_Q)
258 vMoveBy -= vMove*(0.0005f*fModelSize);
259 bZoomOut = true;
262 // Limit zooming in orbit mode
263 float fCameraDistFromModelGlobe = glm::length(vEye + vMoveBy - vView) - fModelSize / 2.0f;
264 if ((fCameraDistFromModelGlobe < 0.5 * fModelSize && bZoomIn ) ||
265 (fCameraDistFromModelGlobe > 2 * fModelSize && bZoomOut ))
267 vMoveBy = glm::vec3(0.0);
271 gltf_renderer_move_camera(&m_rHandle, vMoveBy.x, vMoveBy.y, vMoveBy.z, 0.0001);
273 if( m_bIsOrbitMode )
275 long nDeltaX = 0;
276 long nDeltaY = 0;
277 if (nCode == KEY_W)
279 nDeltaY -= 1;
281 if (nCode == KEY_S)
283 nDeltaY += 1;
285 if (nCode == KEY_A)
287 nDeltaX -= 1;
289 if (nCode == KEY_D)
291 nDeltaX += 1;
293 float fSensitivity = 50.0;
294 gltf_renderer_rotate_model(&m_rHandle, nDeltaX*fSensitivity, nDeltaY*fSensitivity, 0.0);
297 else if(nCode == KEY_M)
299 if(m_bIsOrbitMode)
301 gltf_orbit_mode_stop(&m_rHandle);
302 m_bIsOrbitMode = false;
304 else
306 gltf_orbit_mode_start(&m_rHandle);
307 m_bIsOrbitMode = true;
310 else if(nCode == KEY_F)
312 gltf_render_FPS_enable(&m_rHandle);
316 else if( rEvent.GetId() == VclEventId::WindowMouseButtonDown )
318 MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rEvent.GetData());
319 if(pMouseEvt && pMouseEvt->IsLeft() && pMouseEvt->GetClicks() == 1)
321 m_aLastMousePos = pMouseEvt->GetPosPixel();
324 else if( rEvent.GetId() == VclEventId::WindowMouseMove )
326 if ( !m_rEventHandler.HasFocus() )
328 m_rEventHandler.GrabFocus();
330 MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rEvent.GetData());
331 if(pMouseEvt && pMouseEvt->IsLeft() && m_aLastMousePos != Point(0,0))
333 const Point& aCurPos = pMouseEvt->GetPosPixel();
334 float fSensitivity = std::min(m_rHandle.viewport.width, m_rHandle.viewport.height);
335 if (fSensitivity == 0.0)
336 fSensitivity = 1.0;
337 else
338 fSensitivity = 540.0 / fSensitivity;
341 long nDeltaX = m_aLastMousePos.X()-aCurPos.X();
342 long nDeltaY = m_aLastMousePos.Y()-aCurPos.Y();
343 if( m_bIsOrbitMode )
345 fSensitivity *= 5;
346 gltf_renderer_rotate_model(&m_rHandle, (float)nDeltaX*fSensitivity, (float)nDeltaY*fSensitivity, 0.0);
348 else
350 // Filter out too small deltas to avoid rewrite rotation parameter with 0
351 // before rotation is done
352 if( nDeltaX != 0 || nDeltaY != 0 )
353 gltf_renderer_rotate_camera(&m_rHandle, (float)nDeltaX*fSensitivity, (float)nDeltaY*fSensitivity, 0.0);
355 m_aLastMousePos = aCurPos;
358 else if( rEvent.GetId() == VclEventId::WindowMouseButtonUp )
360 MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rEvent.GetData());
361 if(pMouseEvt && pMouseEvt->IsLeft() && pMouseEvt->GetClicks() == 1)
363 m_aLastMousePos = Point(0,0);
368 } // namespace ogl
369 } // namespace avmedia
371 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */