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 The 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, see <https://www.gnu.org/licenses/>.
19 */
20
26
27#include "track_ball.h"
28#include "trackball.h"
29#include "../3d_math.h"
30#include <wx/log.h>
31
32#include <glm/gtc/quaternion.hpp>
33
34// stdlib
35#include <algorithm>
36
37
38TRACK_BALL::TRACK_BALL( float aInitialDistance ) : CAMERA( aInitialDistance )
39{
40 wxLogTrace( m_logTrace, wxT( "TRACK_BALL::TRACK_BALL" ) );
41 initQuat();
42}
43
44
45TRACK_BALL::TRACK_BALL( SFVEC3F aInitPos, SFVEC3F aLookat, PROJECTION_TYPE aProjectionType ) :
46 CAMERA( aInitPos, aLookat, aProjectionType )
47{
48 wxLogTrace( m_logTrace, wxT( "TRACK_BALL::TRACK_BALL" ) );
49 initQuat();
50}
51
52
54{
55 memset( m_quat_t0, 0, sizeof( m_quat_t0 ) );
56 memset( m_quat_t1, 0, sizeof( m_quat_t1 ) );
57
58 trackball( m_quat_t0, 0.0, 0.0, 0.0, 0.0 );
59 trackball( m_quat_t1, 0.0, 0.0, 0.0, 0.0 );
60}
61
62
63void TRACK_BALL::Drag( const wxPoint& aNewMousePosition )
64{
66
67 double spin_quat[4];
68
69 // "Pass the x and y coordinates of the last and current positions of
70 // the mouse, scaled so they are from (-1.0 ... 1.0)."
71 const float zoom = 1.0f;
72
73 trackball( spin_quat, zoom * ( 2.0 * m_lastPosition.x - m_windowSize.x ) / m_windowSize.x,
74 zoom * ( m_windowSize.y - 2.0 * m_lastPosition.y ) / m_windowSize.y,
75 zoom * ( 2.0 * aNewMousePosition.x - m_windowSize.x ) / m_windowSize.x,
76 zoom * ( m_windowSize.y - 2.0 * aNewMousePosition.y ) / m_windowSize.y );
77
78 float spin_matrix[4][4];
79 build_rotmatrix( spin_matrix, spin_quat );
80 m_rotationMatrix = glm::make_mat4( &spin_matrix[0][0] ) * m_rotationMatrix;
81
83
85}
86
87void TRACK_BALL::Pan( const wxPoint& aNewMousePosition )
88{
90
92 {
93 m_camera_pos.x -= m_frustum.nw *
94 ( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x;
95 m_camera_pos.y -= m_frustum.nh *
96 ( aNewMousePosition.y - m_lastPosition.y ) / m_windowSize.y;
97 }
98 else // PROJECTION_TYPE::PERSPECTIVE
99 {
100 // Unproject the coordinates using the precomputed frustum tangent (zoom level dependent)
101 const float panFactor = -m_camera_pos.z * m_frustum.tang * 2;
102 m_camera_pos.x -= panFactor * m_frustum.ratio *
103 ( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x;
104 m_camera_pos.y -= panFactor * ( aNewMousePosition.y - m_lastPosition.y ) / m_windowSize.y;
105 }
106
109}
110
111void TRACK_BALL::Pan( const SFVEC3F& aDeltaOffsetInc )
112{
113 m_parametersChanged = true;
114
115 m_camera_pos += aDeltaOffsetInc;
116
119}
120
121void TRACK_BALL::Pan_T1( const SFVEC3F& aDeltaOffsetInc )
122{
123 m_camera_pos_t1 = m_camera_pos + aDeltaOffsetInc;
124}
125
127{
129
130 memset( m_quat_t1, 0, sizeof( m_quat_t1 ) );
131 trackball( m_quat_t1, 0.0, 0.0, 0.0, 0.0 );
132}
133
135{
137
138 double quat[4];
139
140 // Charge the quaternions with the current rotation matrix to allow dual input.
141 std::copy_n( glm::value_ptr( glm::conjugate( glm::quat_cast( m_rotationMatrix ) ) ),
142 sizeof( quat ) / sizeof( quat[0] ), quat );
143
144 memcpy( m_quat_t0, quat, sizeof( quat ) );
145 memcpy( m_quat_t1, quat, sizeof( quat ) );
146}
147
149{
150 wxASSERT( t >= 0.0f );
151
152 // Limit t o 1.0
153 t = ( t > 1.0f ) ? 1.0f : t;
154
155 switch( m_interpolation_mode )
156 {
158 t = BezierBlend( t );
159 break;
160
162 t = QuadricEasingInOut( t );
163 break;
164
166 default:
167 break;
168 }
169
170 glm::quat q0( (float) m_quat_t0[3], (float) m_quat_t0[0], (float) m_quat_t0[1], (float) m_quat_t0[2] );
171 glm::quat q1( (float) m_quat_t1[3], (float) m_quat_t1[0], (float) m_quat_t1[1], (float) m_quat_t1[2] );
172
173 if( glm::dot( q0, q1 ) < 0.0f )
174 q1 = -q1;
175
176 const glm::quat q = glm::normalize( glm::slerp( q0, q1, t ) );
177
178 m_rotationMatrix = glm::mat4_cast( glm::conjugate( q ) );
179
181}
Defines math related functions.
float BezierBlend(float t)
Definition 3d_math.h:175
float QuadricEasingInOut(float t)
Definition 3d_math.h:159
PROJECTION_TYPE
Definition camera.h:36
bool m_parametersChanged
Set to true if any of the parameters in the camera was changed.
Definition camera.h:387
CAMERA_INTERPOLATION m_interpolation_mode
Definition camera.h:369
wxPoint m_lastPosition
The last mouse position in the screen.
Definition camera.h:336
virtual void Reset_T1()
Definition camera.cpp:157
virtual void Interpolate(float t)
It will update the matrix to interpolate between T0 and T1 values.
Definition camera.cpp:708
CAMERA(float aInitialDistance)
Initialize a camera.
Definition camera.cpp:50
CAMERA_FRUSTUM m_frustum
Definition camera.h:346
void updateFrustum()
Definition camera.cpp:345
virtual void SetT0_and_T1_current_T()
This will set T0 and T1 with the current values.
Definition camera.cpp:694
SFVEC3F m_camera_pos
Definition camera.h:356
PROJECTION_TYPE m_projectionType
Definition camera.h:344
SFVEC2I m_windowSize
The window size that this camera is working.
Definition camera.h:331
void updateViewMatrix()
Definition camera.cpp:208
glm::mat4 m_rotationMatrix
Definition camera.h:338
SFVEC3F m_camera_pos_t1
Definition camera.h:358
void initQuat()
void Pan_T1(const SFVEC3F &aDeltaOffsetInc) override
void SetT0_and_T1_current_T() override
This will set T0 and T1 with the current values.
void Interpolate(float t) override
It will update the matrix to interpolate between T0 and T1 values.
TRACK_BALL(float aInitialDistance)
void Pan(const wxPoint &aNewMousePosition) override
void Reset_T1() override
double m_quat_t1[4]
Definition track_ball.h:63
double m_quat_t0[4]
interpolate quaternions of the trackball
Definition track_ball.h:62
void Drag(const wxPoint &aNewMousePosition) override
Calculate a new mouse drag position.
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
Definition camera.h:396
Declaration for a track ball camera.
void build_rotmatrix(float m[4][4], double q[4])
void trackball(double q[4], double p1x, double p1y, double p2x, double p2y)
glm::vec3 SFVEC3F
Definition xv3d_types.h:40