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 &center, 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 &center, 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 &center, 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 &center, 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