You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

333 lines
9.4 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
  5. * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. /**
  25. * @file ccamera.h
  26. * @brief Define an abstract camera
  27. */
  28. #ifndef CCAMERA_H
  29. #define CCAMERA_H
  30. #include "../3d_rendering/3d_render_raytracing/ray.h"
  31. #include <wx/gdicmn.h> // for wxSize
  32. #include <vector>
  33. enum PROJECTION_TYPE
  34. {
  35. PROJECTION_ORTHO,
  36. PROJECTION_PERSPECTIVE
  37. };
  38. /**
  39. * Frustum structure
  40. * Frustum is a implementation based on a tutorial by
  41. * http://www.lighthouse3d.com/tutorials/view-frustum-culling/
  42. */
  43. struct FRUSTUM
  44. {
  45. SFVEC3F nc;
  46. SFVEC3F fc;
  47. SFVEC3F ntl; ///< Near Top Left
  48. SFVEC3F ntr; ///< Near Top Right
  49. SFVEC3F nbl; ///< Near Bottom Left
  50. SFVEC3F nbr; ///< Near Bottom Right
  51. SFVEC3F ftl; ///< Far Top Left
  52. SFVEC3F ftr; ///< Far Top Right
  53. SFVEC3F fbl; ///< Far Bottom Left
  54. SFVEC3F fbr; ///< Far Bottom Right
  55. float nearD, farD, ratio, angle, tang;
  56. float nw, nh, fw, fh;
  57. };
  58. enum CAMERA_INTERPOLATION
  59. {
  60. INTERPOLATION_LINEAR,
  61. INTERPOLATION_EASING_IN_OUT, // Quadratic
  62. INTERPOLATION_BEZIER,
  63. };
  64. /**
  65. * Class CCAMERA
  66. * is a virtual class used to derive CCAMERA objects from.
  67. *
  68. * It must be derived to other classes to implement a real camera object.
  69. */
  70. class CCAMERA
  71. {
  72. public:
  73. /**
  74. * @brief CCAMERA initialize a camera
  75. * @param aRangeScale: it will be expected that the board will have a
  76. * -aRangeScale/2 to +aRangeScale/2
  77. * it will initialize the initial Z position with aRangeScale
  78. */
  79. explicit CCAMERA( float aRangeScale );
  80. /**
  81. * Function GetRotationMatrix
  82. * Get the rotation matrix to be applied in a transformation camera
  83. * @return the rotation matrix of the camera
  84. */
  85. const glm::mat4 GetRotationMatrix() const;
  86. const glm::mat4 &GetViewMatrix() const;
  87. const glm::mat4 &GetViewMatrix_Inv() const;
  88. const glm::mat4 &GetProjectionMatrix() const;
  89. const glm::mat4 &GetProjectionMatrixInv() const;
  90. const SFVEC3F &GetRight() const { return m_right; }
  91. const SFVEC3F &GetUp() const { return m_up; }
  92. const SFVEC3F &GetDir() const { return m_dir; }
  93. const SFVEC3F &GetPos() const { return m_pos; }
  94. const SFVEC2F &GetFocalLen() const { return m_focalLen; }
  95. float GetNear() const { return m_frustum.nearD; }
  96. float GetFar() const { return m_frustum.farD; }
  97. void SetBoardLookAtPos( const SFVEC3F &aBoardPos ) {
  98. if( m_board_lookat_pos_init != aBoardPos )
  99. {
  100. m_board_lookat_pos_init = aBoardPos;
  101. SetLookAtPos( aBoardPos );
  102. }
  103. }
  104. virtual void SetLookAtPos( const SFVEC3F &aLookAtPos ) = 0;
  105. void SetLookAtPos_T1( const SFVEC3F &aLookAtPos ) {
  106. m_lookat_pos_t1 = aLookAtPos;
  107. }
  108. const SFVEC3F &GetLookAtPos_T1() const { return m_lookat_pos_t1; }
  109. const SFVEC3F &GetCameraPos() const { return m_camera_pos; }
  110. /**
  111. * Calculate a new mouse drag position
  112. */
  113. virtual void Drag( const wxPoint &aNewMousePosition ) = 0;
  114. virtual void Pan( const wxPoint &aNewMousePosition ) = 0;
  115. virtual void Pan( const SFVEC3F &aDeltaOffsetInc ) = 0;
  116. virtual void Pan_T1( const SFVEC3F &aDeltaOffsetInc ) = 0;
  117. /**
  118. * Reset the camera to initial state
  119. */
  120. virtual void Reset();
  121. virtual void Reset_T1();
  122. void ResetXYpos();
  123. void ResetXYpos_T1();
  124. /**
  125. * It updates the current mouse position without make any new recalculations
  126. * on camera.
  127. */
  128. void SetCurMousePosition( const wxPoint &aPosition );
  129. void SetProjection( PROJECTION_TYPE aProjectionType );
  130. void ToggleProjection();
  131. /**
  132. * @brief SetCurWindowSize - update the windows size of the camera
  133. * @param aSize
  134. * @return true if the windows size changed since last time
  135. */
  136. bool SetCurWindowSize( const wxSize &aSize );
  137. void ZoomReset();
  138. bool Zoom( float aFactor );
  139. bool Zoom_T1( float aFactor );
  140. float ZoomGet() const ;
  141. void RotateX( float aAngleInRadians );
  142. void RotateY( float aAngleInRadians );
  143. void RotateZ( float aAngleInRadians );
  144. void RotateX_T1( float aAngleInRadians );
  145. void RotateY_T1( float aAngleInRadians );
  146. void RotateZ_T1( float aAngleInRadians );
  147. /**
  148. * @brief SetT0_and_T1_current_T - This will set T0 and T1 with the current values
  149. */
  150. virtual void SetT0_and_T1_current_T();
  151. /**
  152. * @brief Interpolate - It will update the matrix to interpolate between T0 and T1 values
  153. * @param t the interpolation time, between 0.0f and 1.0f (it will clamp if >1)
  154. */
  155. virtual void Interpolate( float t );
  156. void SetInterpolateMode( CAMERA_INTERPOLATION aInterpolateMode )
  157. {
  158. m_interpolation_mode = aInterpolateMode;
  159. }
  160. /**
  161. * Function ParametersChanged
  162. * @return true if some of the parameters in camera was changed,
  163. * it will reset the flag
  164. */
  165. bool ParametersChanged();
  166. /**
  167. * Function ParametersChangedQuery
  168. * @return true if some of the parameters in camera was changed,
  169. * it will NOT reset the flag
  170. */
  171. bool ParametersChangedQuery() const { return m_parametersChanged; }
  172. /**
  173. * @brief MakeRay - Make a ray based on a windows screen position
  174. * @param aWindowPos: the windows buffer position
  175. * @param aOutOrigin: out origin position of the ray
  176. * @param aOutDirection: out direction
  177. */
  178. void MakeRay( const SFVEC2I &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const;
  179. /**
  180. * @brief MakeRay - Make a ray based on a windows screen position, it will interpolate based on the float aWindowPos
  181. * @param aWindowPos: the windows buffer position (float value)
  182. * @param aOutOrigin: out origin position of the ray
  183. * @param aOutDirection: out direction
  184. */
  185. void MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const;
  186. /**
  187. * @brief MakeRayAtCurrrentMousePosition - Make a ray based on the latest mouse position
  188. * @param aOutOrigin: out origin position of the ray
  189. * @param aOutDirection: out direction
  190. */
  191. void MakeRayAtCurrrentMousePosition( SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const;
  192. protected:
  193. void rebuildProjection();
  194. void updateFrustum();
  195. void updateViewMatrix();
  196. void updateRotationMatrix();
  197. /**
  198. * @brief m_range_scale - the nominal range expected to be used in the camera.
  199. * It will be used to initialize the Z position
  200. */
  201. float m_range_scale;
  202. /**
  203. * 3D zoom value (Min 0.0 ... Max 1.0)
  204. */
  205. float m_zoom;
  206. float m_zoom_t0;
  207. float m_zoom_t1;
  208. /**
  209. * The window size that this camera is working.
  210. */
  211. SFVEC2I m_windowSize;
  212. /**
  213. * The last mouse position in the screen
  214. */
  215. wxPoint m_lastPosition;
  216. glm::mat4 m_rotationMatrix;
  217. glm::mat4 m_rotationMatrixAux;
  218. glm::mat4 m_viewMatrix;
  219. glm::mat4 m_viewMatrixInverse;
  220. glm::mat4 m_projectionMatrix;
  221. glm::mat4 m_projectionMatrixInv;
  222. PROJECTION_TYPE m_projectionType;
  223. FRUSTUM m_frustum;
  224. SFVEC3F m_right;
  225. SFVEC3F m_up;
  226. SFVEC3F m_dir;
  227. SFVEC3F m_pos;
  228. SFVEC2F m_focalLen;
  229. SFVEC3F m_camera_pos_init;
  230. SFVEC3F m_camera_pos;
  231. SFVEC3F m_camera_pos_t0;
  232. SFVEC3F m_camera_pos_t1;
  233. SFVEC3F m_lookat_pos;
  234. SFVEC3F m_lookat_pos_t0;
  235. SFVEC3F m_lookat_pos_t1;
  236. SFVEC3F m_board_lookat_pos_init; ///< Default boardlookat position (the board center)
  237. SFVEC3F m_rotate_aux; ///< Stores the rotation angle auxiliar
  238. SFVEC3F m_rotate_aux_t0;
  239. SFVEC3F m_rotate_aux_t1;
  240. CAMERA_INTERPOLATION m_interpolation_mode;
  241. /**
  242. * Precalc values array used to calc ray for each pixel
  243. * (constant for the same window size)
  244. */
  245. std::vector< float > m_scr_nX;
  246. std::vector< float > m_scr_nY;
  247. /**
  248. * Precalc values array used to calc ray for each pixel,
  249. * for X and Y axis of each new camera position
  250. */
  251. std::vector< SFVEC3F > m_right_nX;
  252. std::vector< SFVEC3F > m_up_nY;
  253. /**
  254. * Set to true if any of the parameters in the camera was changed
  255. */
  256. bool m_parametersChanged;
  257. /**
  258. * Trace mask used to enable or disable the trace output of this class.
  259. * The debug output can be turned on by setting the WXTRACE environment variable to
  260. * "KI_TRACE_CCAMERA". See the wxWidgets documentation on wxLogTrace for
  261. * more information.
  262. */
  263. static const wxChar *m_logTrace;
  264. };
  265. #endif // CCAMERA_H