KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2024 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#include <glm/gtc/quaternion.hpp>
37
38// stdlib
39#include <algorithm>
40
41
42TRACK_BALL::TRACK_BALL( float aInitialDistance ) : CAMERA( aInitialDistance )
43{
44 wxLogTrace( m_logTrace, wxT( "TRACK_BALL::TRACK_BALL" ) );
45 initQuat();
46}
47
48
49TRACK_BALL::TRACK_BALL( SFVEC3F aInitPos, SFVEC3F aLookat, PROJECTION_TYPE aProjectionType ) :
50 CAMERA( aInitPos, aLookat, aProjectionType )
51{
52 wxLogTrace( m_logTrace, wxT( "TRACK_BALL::TRACK_BALL" ) );
53 initQuat();
54}
55
56
58{
59 memset( m_quat_t0, 0, sizeof( m_quat_t0 ) );
60 memset( m_quat_t1, 0, sizeof( m_quat_t1 ) );
61
62 trackball( m_quat_t0, 0.0, 0.0, 0.0, 0.0 );
63 trackball( m_quat_t1, 0.0, 0.0, 0.0, 0.0 );
64}
65
66
67void TRACK_BALL::Drag( const wxPoint& aNewMousePosition )
68{
70
71 double spin_quat[4];
72
73 // "Pass the x and y coordinates of the last and current positions of
74 // the mouse, scaled so they are from (-1.0 ... 1.0)."
75 const float zoom = 1.0f;
76
77 trackball( spin_quat, zoom * ( 2.0 * m_lastPosition.x - m_windowSize.x ) / m_windowSize.x,
78 zoom * ( m_windowSize.y - 2.0 * m_lastPosition.y ) / m_windowSize.y,
79 zoom * ( 2.0 * aNewMousePosition.x - m_windowSize.x ) / m_windowSize.x,
80 zoom * ( m_windowSize.y - 2.0 * aNewMousePosition.y ) / m_windowSize.y );
81
82 float spin_matrix[4][4];
83 build_rotmatrix( spin_matrix, spin_quat );
84 m_rotationMatrix = glm::make_mat4( &spin_matrix[0][0] ) * m_rotationMatrix;
85
87
89}
90
91void TRACK_BALL::Pan( const wxPoint& aNewMousePosition )
92{
94
95 if( m_projectionType == PROJECTION_TYPE::ORTHO )
96 {
98 ( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x;
100 ( aNewMousePosition.y - m_lastPosition.y ) / m_windowSize.y;
101 }
102 else // PROJECTION_TYPE::PERSPECTIVE
103 {
104 // Unproject the coordinates using the precomputed frustum tangent (zoom level dependent)
105 const float panFactor = -m_camera_pos.z * m_frustum.tang * 2;
106 m_camera_pos.x -= panFactor * m_frustum.ratio *
107 ( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x;
108 m_camera_pos.y -= panFactor * ( aNewMousePosition.y - m_lastPosition.y ) / m_windowSize.y;
109 }
110
113}
114
115void TRACK_BALL::Pan( const SFVEC3F& aDeltaOffsetInc )
116{
117 m_parametersChanged = true;
118
119 m_camera_pos += aDeltaOffsetInc;
120
123}
124
125void TRACK_BALL::Pan_T1( const SFVEC3F& aDeltaOffsetInc )
126{
127 m_camera_pos_t1 = m_camera_pos + aDeltaOffsetInc;
128}
129
131{
133
134 memset( m_quat_t1, 0, sizeof( m_quat_t1 ) );
135 trackball( m_quat_t1, 0.0, 0.0, 0.0, 0.0 );
136}
137
139{
141
142 double quat[4];
143
144 // Charge the quaternions with the current rotation matrix to allow dual input.
145 std::copy_n( glm::value_ptr( glm::conjugate( glm::quat_cast( m_rotationMatrix ) ) ),
146 sizeof( quat ) / sizeof( quat[0] ), quat );
147
148 memcpy( m_quat_t0, quat, sizeof( quat ) );
149 memcpy( m_quat_t1, quat, sizeof( quat ) );
150}
151
153{
154 wxASSERT( t >= 0.0f );
155
156 // Limit t o 1.0
157 t = ( t > 1.0f ) ? 1.0f : t;
158
159 switch( m_interpolation_mode )
160 {
161 case CAMERA_INTERPOLATION::BEZIER:
162 t = BezierBlend( t );
163 break;
164
165 case CAMERA_INTERPOLATION::EASING_IN_OUT:
166 t = QuadricEasingInOut( t );
167 break;
168
169 case CAMERA_INTERPOLATION::LINEAR:
170 default:
171 break;
172 }
173
174 const float t0 = 1.0f - t;
175 double quat[4];
176 quat[0] = m_quat_t0[0] * t0 + m_quat_t1[0] * t;
177 quat[1] = m_quat_t0[1] * t0 + m_quat_t1[1] * t;
178 quat[2] = m_quat_t0[2] * t0 + m_quat_t1[2] * t;
179 quat[3] = m_quat_t0[3] * t0 + m_quat_t1[3] * t;
180
181 float rotationMatrix[4][4];
182
183 build_rotmatrix( rotationMatrix, quat );
184
185 m_rotationMatrix = glm::make_mat4( &rotationMatrix[0][0] );
186
188}
float BezierBlend(float t)
Definition: 3d_math.h:179
float QuadricEasingInOut(float t)
Definition: 3d_math.h:163
PROJECTION_TYPE
Definition: camera.h:40
A class used to derive camera objects from.
Definition: camera.h:103
bool m_parametersChanged
Set to true if any of the parameters in the camera was changed.
Definition: camera.h:391
CAMERA_INTERPOLATION m_interpolation_mode
Definition: camera.h:373
wxPoint m_lastPosition
The last mouse position in the screen.
Definition: camera.h:340
virtual void Reset_T1()
Definition: camera.cpp:161
virtual void Interpolate(float t)
It will update the matrix to interpolate between T0 and T1 values.
Definition: camera.cpp:711
CAMERA_FRUSTUM m_frustum
Definition: camera.h:350
void updateFrustum()
Definition: camera.cpp:348
virtual void SetT0_and_T1_current_T()
This will set T0 and T1 with the current values.
Definition: camera.cpp:697
SFVEC3F m_camera_pos
Definition: camera.h:360
PROJECTION_TYPE m_projectionType
Definition: camera.h:348
SFVEC2I m_windowSize
The window size that this camera is working.
Definition: camera.h:335
void updateViewMatrix()
Definition: camera.cpp:212
glm::mat4 m_rotationMatrix
Definition: camera.h:342
SFVEC3F m_camera_pos_t1
Definition: camera.h:362
void initQuat()
Definition: track_ball.cpp:57
void Pan_T1(const SFVEC3F &aDeltaOffsetInc) override
Definition: track_ball.cpp:125
void SetT0_and_T1_current_T() override
This will set T0 and T1 with the current values.
Definition: track_ball.cpp:138
void Interpolate(float t) override
It will update the matrix to interpolate between T0 and T1 values.
Definition: track_ball.cpp:152
TRACK_BALL(float aInitialDistance)
Definition: track_ball.cpp:42
void Pan(const wxPoint &aNewMousePosition) override
Definition: track_ball.cpp:91
void Reset_T1() override
Definition: track_ball.cpp:130
double m_quat_t1[4]
Definition: track_ball.h:67
double m_quat_t0[4]
interpolate quaternions of the trackball
Definition: track_ball.h:66
void Drag(const wxPoint &aNewMousePosition) override
Calculate a new mouse drag position.
Definition: track_ball.cpp:67
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
Definition: camera.h:400
float ratio
Definition: camera.h:61
float nh
Definition: camera.h:62
float nw
Definition: camera.h:62
float tang
Definition: camera.h:61
Declaration for a track ball camera.
void build_rotmatrix(float m[4][4], double q[4])
Definition: trackball.cpp:306
void trackball(double q[4], double p1x, double p1y, double p2x, double p2y)
Definition: trackball.cpp:155
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44