KiCad PCB EDA Suite
Loading...
Searching...
No Matches
3d_math.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) 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
25
26
27#include "3d_math.h"
28
29#include <glm/gtc/matrix_transform.hpp>
30#include <glm/gtc/quaternion.hpp>
31#include <cmath>
32
33
34glm::mat4 CalcModelMatrix( const SFVEC3F& aOffset, const SFVEC3F& aRotation, const SFVEC3F& aScale )
35{
36 glm::mat4 matrix( 1.0f );
37
38 matrix = glm::translate( matrix, aOffset );
39 matrix = glm::rotate( matrix, glm::radians( -aRotation.z ), { 0.0f, 0.0f, 1.0f } );
40 matrix = glm::rotate( matrix, glm::radians( -aRotation.y ), { 0.0f, 1.0f, 0.0f } );
41 matrix = glm::rotate( matrix, glm::radians( -aRotation.x ), { 1.0f, 0.0f, 0.0f } );
42
43 return glm::scale( matrix, aScale );
44}
45
46
47SFVEC3F CalcModelRotation( const glm::mat3& aRotation )
48{
49 // CalcModelMatrix() builds Rz( -rz ) * Ry( -ry ) * Rx( -rx ), so this is the standard
50 // ZYX decomposition run on the negated angles.
51 const float sinBeta = -aRotation[0][2];
52 const float beta = std::asin( glm::clamp( sinBeta, -1.0f, 1.0f ) );
53 const float cosBeta = std::cos( beta );
54 float alpha;
55 float gamma;
56
57 if( std::abs( cosBeta ) < 1e-6f )
58 {
59 // Gimbal lock leaves only the sum or difference of the outer angles observable.
60 alpha = 0.0f;
61 gamma = std::atan2( sinBeta * aRotation[2][1], aRotation[1][1] );
62 }
63 else
64 {
65 alpha = std::atan2( aRotation[1][2], aRotation[2][2] );
66 gamma = std::atan2( aRotation[0][1], aRotation[0][0] );
67 }
68
69 return SFVEC3F( -glm::degrees( alpha ), -glm::degrees( beta ), -glm::degrees( gamma ) );
70}
71
72
73SFVEC3F InterpolateModelRotation( const SFVEC3F& aStart, const SFVEC3F& aEnd, float aT )
74{
75 const SFVEC3F zero( 0.0f );
76 const SFVEC3F one( 1.0f );
77 const glm::quat start( glm::mat3( CalcModelMatrix( zero, aStart, one ) ) );
78 const glm::quat end( glm::mat3( CalcModelMatrix( zero, aEnd, one ) ) );
79
80 return CalcModelRotation( glm::mat3_cast( glm::slerp( start, end, glm::clamp( aT, 0.0f, 1.0f ) ) ) );
81}
SFVEC3F InterpolateModelRotation(const SFVEC3F &aStart, const SFVEC3F &aEnd, float aT)
Interpolate between two model orientations along the shortest arc.
Definition 3d_math.cpp:73
SFVEC3F CalcModelRotation(const glm::mat3 &aRotation)
Recover the FP_3DMODEL angles that CalcModelMatrix() would turn into aRotation.
Definition 3d_math.cpp:47
glm::mat4 CalcModelMatrix(const SFVEC3F &aOffset, const SFVEC3F &aRotation, const SFVEC3F &aScale)
Build the model-to-footprint transform used by rendering and picking.
Definition 3d_math.cpp:34
Defines math related functions.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:437
VECTOR2I end
glm::vec3 SFVEC3F
Definition xv3d_types.h:40