1 /*
2 This file is a part of the RepSnapper project.
3 Copyright (C) 2010 Kulitorum
4 Copyright (C) 2012 martin.dieringer@gmx.de
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "transform3d.h"
22
23
24
Transform3D()25 Transform3D::Transform3D()
26 {
27 identity();
28 }
29
update_transform()30 void Transform3D::update_transform() {
31 transform = Matrix4d::IDENTITY;
32 // scale the unrotated object
33 for (uint i = 0; i < 3; i++)
34 transform(i,i) *= xyz_scale(i);
35 transform *= m_transform;
36
37 // for (uint i = 0; i < 3; i++)
38 // transform(3,i) = 0;
39 // translate
40 for (uint i = 0; i < 3; i++)
41 transform(3,i) = m_transform(3,i);
42 }
43
44
identity()45 void Transform3D::identity()
46 {
47 m_transform = Matrix4d::IDENTITY;
48 xyz_scale = Vector3d(1,1,1);
49 update_transform();
50 }
51
getFloatTransform() const52 Matrix4f Transform3D::getFloatTransform() const
53 {
54 return (Matrix4f) transform;
55 }
setTransform(const Matrix4f & matr)56 void Transform3D::setTransform(const Matrix4f &matr)
57 {
58 m_transform = (Matrix4d) matr;
59 update_transform();
60 }
61
getTranslation() const62 Vector3d Transform3D::getTranslation() const
63 {
64 Vector3d p;
65 m_transform.get_translation(p);
66 return p;
67 }
68
move(const Vector3d & delta)69 void Transform3D::move(const Vector3d &delta)
70 {
71 Vector3d trans = getTranslation();
72 m_transform.set_translation(trans + delta * transform(3,3)); // unscale delta
73 update_transform();
74 }
75
scale(double x)76 void Transform3D::scale(double x)
77 {
78 if (x==0) return;
79 m_transform[3][3] = 1/x;
80 update_transform();
81 }
82
scale_x(double x)83 void Transform3D::scale_x(double x)
84 {
85 xyz_scale(0) = x;
86 update_transform();
87 }
scale_y(double x)88 void Transform3D::scale_y(double x)
89 {
90 xyz_scale(1) = x;
91 update_transform();
92 }
scale_z(double x)93 void Transform3D::scale_z(double x)
94 {
95 xyz_scale(2) = x;
96 update_transform();
97 }
98
rotate_to(const Vector3d & center,const Vector3d & axis,double angle)99 void Transform3D::rotate_to(const Vector3d ¢er, const Vector3d &axis, double angle)
100 {
101 // save translation & scale
102 const Vector3d trans = getTranslation();
103 const double scale = m_transform(3,3);
104 // rotate only
105 Matrix4d rot;
106 Vector3d naxis = axis; naxis.normalize();
107 m_transform.rotate(angle, naxis); // this creates the matrix!
108 //cerr << m_transform << endl;
109 m_transform.set_translation(trans);
110 m_transform(3,3) = scale;
111 update_transform();
112 }
113
rotate(const Vector3d & axis,double angle)114 void Transform3D::rotate(const Vector3d &axis, double angle)
115 {
116 rotate(Vector3d::ZERO, axis, angle);
117 }
rotate(const Vector3d & center,const Vector3d & axis,double angle)118 void Transform3D::rotate(const Vector3d ¢er, const Vector3d &axis, double angle)
119 {
120 // save translation
121 const Vector3d trans = getTranslation();
122 // rotate only
123 Vector3d naxis = axis; naxis.normalize();
124 Matrix4d rot;
125 rot.rotate(angle, naxis); // this creates the matrix!
126 m_transform = rot * m_transform ;
127 //cerr << angle << axis << m_transform << endl;
128 // rotate center and translation
129 Vector3d rotcenter = rot * center;
130 Vector3d rottrans = rot * trans;
131 m_transform.set_translation((center-rotcenter)*m_transform[3][3] + rottrans);
132 update_transform();
133 }
134
135
136 //not used
rotate(const Vector3d & center,double x,double y,double z)137 void Transform3D::rotate(const Vector3d ¢er, double x, double y, double z)
138 {
139 cerr << "Transform3D::rotate has no effect " << x << y << z << endl;
140 }
141
rotate_to(const Vector3d & center,double x,double y,double z)142 void Transform3D::rotate_to(const Vector3d ¢er, double x, double y, double z)
143 {
144 const Vector3d trans = getTranslation();
145 rotate_to (center, Vector3d(1.,0.,0.), x);
146 rotate (center, Vector3d(0.,1.,0.), y);
147 rotate (center, Vector3d(0.,0.,1.), z);
148 m_transform.set_translation(trans);
149 update_transform();
150 }
151
getRotX() const152 double Transform3D::getRotX() const
153 {
154 return atan2(m_transform(2,1), m_transform(2,2));
155 }
getRotY() const156 double Transform3D::getRotY() const
157 {
158 return -asin(m_transform(2,0));
159 }
getRotZ() const160 double Transform3D::getRotZ() const
161 {
162 return atan2(m_transform(1,0), m_transform(0,0));
163 }
164
165
getInverse() const166 Matrix4d Transform3D::getInverse() const
167 {
168 Matrix4d im;
169 m_transform.inverse(im);
170 return im;
171 }
172
173