transform.h
1 /*************************************************************************/
2 /* transform.h */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* http://www.godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
9 /* */
10 /* Permission is hereby granted, free of charge, to any person obtaining */
11 /* a copy of this software and associated documentation files (the */
12 /* "Software"), to deal in the Software without restriction, including */
13 /* without limitation the rights to use, copy, modify, merge, publish, */
14 /* distribute, sublicense, and/or sell copies of the Software, and to */
15 /* permit persons to whom the Software is furnished to do so, subject to */
16 /* the following conditions: */
17 /* */
18 /* The above copyright notice and this permission notice shall be */
19 /* included in all copies or substantial portions of the Software. */
20 /* */
21 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
22 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
23 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
24 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
25 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
26 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
27 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
28 /*************************************************************************/
29 #ifndef TRANSFORM_H
30 #define TRANSFORM_H
31 
32 #include "matrix3.h"
33 #include "plane.h"
34 #include "aabb.h"
38 class Transform {
39 public:
40 
41  Matrix3 basis;
42  Vector3 origin;
43 
44  void invert();
45  Transform inverse() const;
46 
47  void affine_invert();
48  Transform affine_inverse() const;
49 
50  Transform rotated(const Vector3& p_axis,real_t p_phi) const;
51 
52  void rotate(const Vector3& p_axis,real_t p_phi);
53  void rotate_basis(const Vector3& p_axis,real_t p_phi);
54 
55  void set_look_at( const Vector3& p_eye, const Vector3& p_target, const Vector3& p_up );
56  Transform looking_at( const Vector3& p_target, const Vector3& p_up ) const;
57 
58  void scale(const Vector3& p_scale);
59  Transform scaled(const Vector3& p_scale) const;
60  void scale_basis(const Vector3& p_scale);
61  void translate( real_t p_tx, real_t p_ty, real_t p_tz );
62  void translate( const Vector3& p_translation );
63  Transform translated( const Vector3& p_translation ) const;
64 
65  const Matrix3& get_basis() const { return basis; }
66  void set_basis(const Matrix3& p_basis) { basis=p_basis; }
67 
68  const Vector3& get_origin() const { return origin; }
69  void set_origin(const Vector3& p_origin) { origin=p_origin; }
70 
71  void orthonormalize();
72  Transform orthonormalized() const;
73 
74  bool operator==(const Transform& p_transform) const;
75  bool operator!=(const Transform& p_transform) const;
76 
77  _FORCE_INLINE_ Vector3 xform(const Vector3& p_vector) const;
78  _FORCE_INLINE_ Vector3 xform_inv(const Vector3& p_vector) const;
79 
80  _FORCE_INLINE_ Plane xform(const Plane& p_plane) const;
81  _FORCE_INLINE_ Plane xform_inv(const Plane& p_plane) const;
82 
83  _FORCE_INLINE_ AABB xform(const AABB& p_aabb) const;
84  _FORCE_INLINE_ AABB xform_inv(const AABB& p_aabb) const;
85 
86  void operator*=(const Transform& p_transform);
87  Transform operator*(const Transform& p_transform) const;
88 
89  Transform interpolate_with(const Transform& p_transform, float p_c) const;
90 
91  _FORCE_INLINE_ Transform inverse_xform(const Transform& t) const {
92 
93  Vector3 v = t.origin - origin;
94  return Transform(basis.transpose_xform(t.basis),
95  basis.xform(v));
96  }
97 
98  void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz,real_t tx, real_t ty, real_t tz) {
99 
100  basis.elements[0][0]=xx;
101  basis.elements[0][1]=xy;
102  basis.elements[0][2]=xz;
103  basis.elements[1][0]=yx;
104  basis.elements[1][1]=yy;
105  basis.elements[1][2]=yz;
106  basis.elements[2][0]=zx;
107  basis.elements[2][1]=zy;
108  basis.elements[2][2]=zz;
109  origin.x=tx;
110  origin.y=ty;
111  origin.z=tz;
112  }
113 
114  operator String() const;
115 
116  Transform(const Matrix3& p_basis, const Vector3& p_origin=Vector3());
117  Transform() {}
118 
119 };
120 
121 
122 _FORCE_INLINE_ Vector3 Transform::xform(const Vector3& p_vector) const {
123 
124  return Vector3(
125  basis[0].dot(p_vector)+origin.x,
126  basis[1].dot(p_vector)+origin.y,
127  basis[2].dot(p_vector)+origin.z
128  );
129 }
130 _FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3& p_vector) const {
131 
132  Vector3 v = p_vector - origin;
133 
134  return Vector3(
135  (basis.elements[0][0]*v.x ) + ( basis.elements[1][0]*v.y ) + ( basis.elements[2][0]*v.z ),
136  (basis.elements[0][1]*v.x ) + ( basis.elements[1][1]*v.y ) + ( basis.elements[2][1]*v.z ),
137  (basis.elements[0][2]*v.x ) + ( basis.elements[1][2]*v.y ) + ( basis.elements[2][2]*v.z )
138  );
139 }
140 
141 _FORCE_INLINE_ Plane Transform::xform(const Plane& p_plane) const {
142 
143 
144  Vector3 point=p_plane.normal*p_plane.d;
145  Vector3 point_dir=point+p_plane.normal;
146  point=xform(point);
147  point_dir=xform(point_dir);
148 
149  Vector3 normal=point_dir-point;
150  normal.normalize();
151  real_t d=normal.dot(point);
152 
153  return Plane(normal,d);
154 
155 }
156 _FORCE_INLINE_ Plane Transform::xform_inv(const Plane& p_plane) const {
157 
158  Vector3 point=p_plane.normal*p_plane.d;
159  Vector3 point_dir=point+p_plane.normal;
160  xform_inv(point);
161  xform_inv(point_dir);
162 
163  Vector3 normal=point_dir-point;
164  normal.normalize();
165  real_t d=normal.dot(point);
166 
167  return Plane(normal,d);
168 
169 }
170 
171 _FORCE_INLINE_ AABB Transform::xform(const AABB& p_aabb) const {
172  /* define vertices */
173 #if 1
174  Vector3 x=basis.get_axis(0)*p_aabb.size.x;
175  Vector3 y=basis.get_axis(1)*p_aabb.size.y;
176  Vector3 z=basis.get_axis(2)*p_aabb.size.z;
177  Vector3 pos = xform( p_aabb.pos );
178 //could be even further optimized
179  AABB new_aabb;
180  new_aabb.pos=pos;
181  new_aabb.expand_to( pos+x );
182  new_aabb.expand_to( pos+y );
183  new_aabb.expand_to( pos+z );
184  new_aabb.expand_to( pos+x+y );
185  new_aabb.expand_to( pos+x+z );
186  new_aabb.expand_to( pos+y+z );
187  new_aabb.expand_to( pos+x+y+z );
188  return new_aabb;
189 #else
190 
191 
192  Vector3 vertices[8]={
193  Vector3(p_aabb.pos.x+p_aabb.size.x, p_aabb.pos.y+p_aabb.size.y, p_aabb.pos.z+p_aabb.size.z),
194  Vector3(p_aabb.pos.x+p_aabb.size.x, p_aabb.pos.y+p_aabb.size.y, p_aabb.pos.z),
195  Vector3(p_aabb.pos.x+p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
196  Vector3(p_aabb.pos.x+p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z),
197  Vector3(p_aabb.pos.x, p_aabb.pos.y+p_aabb.size.y, p_aabb.pos.z+p_aabb.size.z),
198  Vector3(p_aabb.pos.x, p_aabb.pos.y+p_aabb.size.y, p_aabb.pos.z),
199  Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
200  Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
201  };
202 
203 
204  AABB ret;
205 
206  ret.pos=xform(vertices[0]);
207 
208  for (int i=1;i<8;i++) {
209 
210  ret.expand_to( xform(vertices[i]) );
211  }
212 
213  return ret;
214 #endif
215 
216 }
217 _FORCE_INLINE_ AABB Transform::xform_inv(const AABB& p_aabb) const {
218 
219  /* define vertices */
220  Vector3 vertices[8]={
221  Vector3(p_aabb.pos.x+p_aabb.size.x, p_aabb.pos.y+p_aabb.size.y, p_aabb.pos.z+p_aabb.size.z),
222  Vector3(p_aabb.pos.x+p_aabb.size.x, p_aabb.pos.y+p_aabb.size.y, p_aabb.pos.z),
223  Vector3(p_aabb.pos.x+p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
224  Vector3(p_aabb.pos.x+p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z),
225  Vector3(p_aabb.pos.x, p_aabb.pos.y+p_aabb.size.y, p_aabb.pos.z+p_aabb.size.z),
226  Vector3(p_aabb.pos.x, p_aabb.pos.y+p_aabb.size.y, p_aabb.pos.z),
227  Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
228  Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
229  };
230 
231 
232  AABB ret;
233 
234  ret.pos=xform_inv(vertices[0]);
235 
236  for (int i=1;i<8;i++) {
237 
238  ret.expand_to( xform_inv(vertices[i]) );
239  }
240 
241  return ret;
242 
243 }
244 
245 #ifdef OPTIMIZED_TRANSFORM_IMPL_OVERRIDE
246 
247 #else
248 
250 
251  Transform transform;
252 
253  _FORCE_INLINE_ void invert() {transform.invert(); }
254  _FORCE_INLINE_ void affine_invert() {transform.affine_invert(); }
255  _FORCE_INLINE_ Vector3 xform(const Vector3& p_vec) const { return transform.xform(p_vec); };
256  _FORCE_INLINE_ Vector3 xform_inv(const Vector3& p_vec) const { return transform.xform_inv(p_vec); };
257  _FORCE_INLINE_ OptimizedTransform operator*(const OptimizedTransform& p_ot ) const { return OptimizedTransform( transform * p_ot.transform ) ; }
258  _FORCE_INLINE_ Transform get_transform() const { return transform; }
259  _FORCE_INLINE_ void set_transform(const Transform& p_transform) { transform=p_transform; }
260 
261  OptimizedTransform(const Transform& p_transform) {
262  transform=p_transform;
263  }
264 };
265 
266 #endif
267 
268 #endif
Definition: aabb.h:43
Definition: matrix3.h:38
Definition: vector3.h:38
Definition: transform.h:38
Definition: plane.h:35
Definition: transform.h:249
Definition: ustring.h:64