KiCad PCB EDA Suite
track_ball.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015-2016 Mario Luzeiro <[email protected]>
5  * Copyright (C) 2015-2020 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 
31 #include "track_ball.h"
32 #include "trackball.h"
33 #include "../3d_math.h"
34 #include <wx/log.h>
35 
36 
37 TRACK_BALL::TRACK_BALL( float aInitialDistance ) :
38  CAMERA( aInitialDistance )
39 {
40  wxLogTrace( m_logTrace, wxT( "TRACK_BALL::TRACK_BALL" ) );
41 
42  memset( m_quat, 0, sizeof( m_quat ) );
43  memset( m_quat_t0, 0, sizeof( m_quat_t0 ) );
44  memset( m_quat_t1, 0, sizeof( m_quat_t1 ) );
45 
46  trackball( m_quat, 0.0, 0.0, 0.0, 0.0 );
47  trackball( m_quat_t0, 0.0, 0.0, 0.0, 0.0 );
48  trackball( m_quat_t1, 0.0, 0.0, 0.0, 0.0 );
49 }
50 
51 
52 void TRACK_BALL::Drag( const wxPoint& aNewMousePosition )
53 {
54  m_parametersChanged = true;
55 
56  double spin_quat[4];
57 
58  // "Pass the x and y coordinates of the last and current positions of
59  // the mouse, scaled so they are from (-1.0 ... 1.0)."
60  const float zoom = 1.0f;
61 
62  trackball( spin_quat, zoom * ( 2.0 * m_lastPosition.x - m_windowSize.x ) / m_windowSize.x,
63  zoom * ( m_windowSize.y - 2.0 * m_lastPosition.y ) / m_windowSize.y,
64  zoom * ( 2.0 * aNewMousePosition.x - m_windowSize.x ) / m_windowSize.x,
65  zoom * ( m_windowSize.y - 2.0 * aNewMousePosition.y ) / m_windowSize.y );
66 
67  add_quats( spin_quat, m_quat, m_quat );
68 
69  float rotationMatrix[4][4];
70 
71  build_rotmatrix( rotationMatrix, m_quat );
72 
73  m_rotationMatrix = glm::make_mat4( &rotationMatrix[0][0] );
74 
76 
77  updateFrustum();
78 }
79 
80 
81 void TRACK_BALL::SetLookAtPos( const SFVEC3F& aLookAtPos )
82 {
83  if( m_lookat_pos != aLookAtPos )
84  {
85  m_lookat_pos = aLookAtPos;
86 
88  updateFrustum();
89 
90  m_parametersChanged = true;
91  }
92 }
93 
94 
95 void TRACK_BALL::Pan( const wxPoint& aNewMousePosition )
96 {
97  m_parametersChanged = true;
98 
100  {
101  m_camera_pos.x -= m_frustum.nw *
102  ( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x;
103  m_camera_pos.y -= m_frustum.nh *
104  ( aNewMousePosition.y - m_lastPosition.y ) / m_windowSize.y;
105  }
106  else // PROJECTION_TYPE::PERSPECTIVE
107  {
108  // Unproject the coordinates using the precomputed frustum tangent (zoom level dependent)
109  const float panFactor = -m_camera_pos.z * m_frustum.tang * 2;
110  m_camera_pos.x -= panFactor * m_frustum.ratio *
111  ( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x;
112  m_camera_pos.y -= panFactor * ( aNewMousePosition.y - m_lastPosition.y ) / m_windowSize.y;
113  }
114 
116  updateFrustum();
117 }
118 
119 
120 void TRACK_BALL::Pan( const SFVEC3F& aDeltaOffsetInc )
121 {
122  m_parametersChanged = true;
123 
124  m_camera_pos += aDeltaOffsetInc;
125 
127  updateFrustum();
128 }
129 
130 
131 void TRACK_BALL::Pan_T1( const SFVEC3F& aDeltaOffsetInc )
132 {
133  m_camera_pos_t1 = m_camera_pos + aDeltaOffsetInc;
134 }
135 
136 
138 {
139  CAMERA::Reset();
140 
141  memset( m_quat, 0, sizeof( m_quat ) );
142  trackball( m_quat, 0.0, 0.0, 0.0, 0.0 );
143 }
144 
145 
147 {
149 
150  memset( m_quat_t1, 0, sizeof( m_quat_t1 ) );
151  trackball( m_quat_t1, 0.0, 0.0, 0.0, 0.0 );
152 }
153 
154 
156 {
158 
159  memcpy( m_quat_t0, m_quat, sizeof( m_quat ) );
160  memcpy( m_quat_t1, m_quat, sizeof( m_quat ) );
161 }
162 
163 
164 void TRACK_BALL::Interpolate( float t )
165 {
166  wxASSERT( t >= 0.0f );
167 
168  // Limit t o 1.0
169  t = ( t > 1.0f ) ? 1.0f : t;
170 
171  switch( m_interpolation_mode )
172  {
174  t = BezierBlend( t );
175  break;
176 
178  t = QuadricEasingInOut( t );
179  break;
180 
182  default:
183  break;
184  }
185 
186  const float t0 = 1.0f - t;
187 
188  m_quat[0] = m_quat_t0[0] * t0 + m_quat_t1[0] * t;
189  m_quat[1] = m_quat_t0[1] * t0 + m_quat_t1[1] * t;
190  m_quat[2] = m_quat_t0[2] * t0 + m_quat_t1[2] * t;
191  m_quat[3] = m_quat_t0[3] * t0 + m_quat_t1[3] * t;
192 
193  float rotationMatrix[4][4];
194 
195  build_rotmatrix( rotationMatrix, m_quat );
196 
197  m_rotationMatrix = glm::make_mat4( &rotationMatrix[0][0] );
198 
199  CAMERA::Interpolate( t );
200 }
double m_quat_t1[4]
Definition: track_ball.h:69
void build_rotmatrix(float m[4][4], double q[4])
Definition: trackball.cpp:306
void Interpolate(float t) override
It will update the matrix to interpolate between T0 and T1 values.
Definition: track_ball.cpp:164
bool m_parametersChanged
Set to true if any of the parameters in the camera was changed.
Definition: camera.h:335
float BezierBlend(float t)
Definition: 3d_math.h:179
void Reset_T1() override
Definition: track_ball.cpp:146
double m_quat_t0[4]
Definition: track_ball.h:68
float QuadricEasingInOut(float t)
Definition: 3d_math.h:163
virtual void Reset()
Reset the camera to initial state.
Definition: camera.cpp:71
float ratio
Definition: camera.h:59
void trackball(double q[4], double p1x, double p1y, double p2x, double p2y)
Definition: trackball.cpp:155
double m_quat[4]
quarternion of the trackball
Definition: track_ball.h:67
float nw
Definition: camera.h:60
float tang
Definition: camera.h:59
A class used to derive camera objects from.
Definition: camera.h:77
void SetT0_and_T1_current_T() override
This will set T0 and T1 with the current values.
Definition: track_ball.cpp:155
PROJECTION_TYPE m_projectionType
Definition: camera.h:292
wxPoint m_lastPosition
The last mouse position in the screen.
Definition: camera.h:284
void updateViewMatrix()
Definition: camera.cpp:139
virtual void Reset_T1()
Definition: camera.cpp:103
glm::mat4 m_rotationMatrix
Definition: camera.h:286
void Reset() override
Reset the camera to initial state.
Definition: track_ball.cpp:137
SFVEC2I m_windowSize
The window size that this camera is working.
Definition: camera.h:279
SFVEC3F m_camera_pos_t1
Definition: camera.h:306
SFVEC3F m_lookat_pos
Definition: camera.h:308
CAMERA_INTERPOLATION m_interpolation_mode
Definition: camera.h:317
SFVEC3F m_camera_pos
Definition: camera.h:304
void updateFrustum()
Definition: camera.cpp:265
void Pan(const wxPoint &aNewMousePosition) override
Definition: track_ball.cpp:95
void add_quats(double q1[4], double q2[4], double dest[4])
Definition: trackball.cpp:249
virtual void SetT0_and_T1_current_T()
This will set T0 and T1 with the current values.
Definition: camera.cpp:558
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
Definition: camera.h:344
CAMERA_FRUSTUM m_frustum
Definition: camera.h:294
virtual void Interpolate(float t)
It will update the matrix to interpolate between T0 and T1 values.
Definition: camera.cpp:572
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44
void Pan_T1(const SFVEC3F &aDeltaOffsetInc) override
Definition: track_ball.cpp:131
TRACK_BALL(float aInitialDistance)
Definition: track_ball.cpp:37
void SetLookAtPos(const SFVEC3F &aLookAtPos) override
Definition: track_ball.cpp:81
Declaration for a track ball camera.
float nh
Definition: camera.h:60
void Drag(const wxPoint &aNewMousePosition) override
Calculate a new mouse drag position.
Definition: track_ball.cpp:52