Honeycomb  0.1
Component-Model Framework
Transform.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
5 #include "Honey/Math/Alge/Quat.h"
6 
7 namespace honey
8 {
9 
11 
40 template<class Real>
41 class Transform_
42 {
43 protected:
44  typedef Vec<2,Real> Vec2;
45  typedef Vec<3,Real> Vec3;
46  typedef Vec<4,Real> Vec4;
48  typedef Quat_<Real> Quat;
49 
50 public:
53 
55  Transform_( const Vec3& trans, const Quat& rot = Quat::identity,
56  const Vec3& scale = Vec3::one, const Quat& skew = Quat::identity)
57  { fromTrs(trans, rot, scale, skew); }
58 
60  explicit Transform_(const Matrix4& mat) { fromMatrix(mat); }
61 
63 
66  {
67  resetTrans();
68  resetRot();
69  resetScale();
70  return *this;
71  }
72 
74  Transform_& fromTrs( const Vec3& trans, const Quat& rot = Quat::identity,
75  const Vec3& scale = Vec3::one, const Quat& skew = Quat::identity)
76  {
77  setTrans(trans);
78  setRot(rot);
79  setScale(scale, skew);
80  return *this;
81  }
82 
84  Transform_& fromMatrix(const Matrix4& mat)
85  {
86  mat.decompose(_trans, _rot, _scale, _skew);
87  return fromTrs(_trans, _rot, _scale, _skew);
88  }
89 
91  {
92  _trans = rhs._trans;
93  _rot = rhs._rot;
94  _scale = rhs._scale;
95  _skew = rhs._skew;
96  _bTrans = rhs._bTrans;
97  _bRot = rhs._bRot;
98  _bScale = rhs._bScale;
99  _bUniformScale = rhs._bUniformScale;
100  _bSkew = rhs._bSkew;
101  onTmChange();
102  return *this;
103  }
104 
105  Transform_ operator*(const Transform_& tm) const;
106 
107  Vec3 operator*(const Vec3& v) const
108  {
109  Vec3 ret = v;
110  if (_bScale)
111  ret = _bSkew ? _skew * (_skew.inverse()*ret).elemMul(_scale) : ret.elemMul(_scale);
112  if (_bRot)
113  ret = _rot * ret;
114  ret += _trans;
115  return ret;
116  }
117 
118  Vec4 operator*(const Vec4& v) const { return Vec4(operator*(Vec3(v)), v.w); }
119  Vec2 operator*(const Vec2& v) const { return Vec2(operator*(Vec3(v))); }
120 
121  Transform_& operator*=(const Transform_& tm) { return *this = operator*(tm); }
122 
124  Vec3 mulRotScale(const Vec3& v) const
125  {
126  Vec3 ret = v;
127  if (_bScale)
128  ret = _bSkew ? _skew * (_skew.inverse()*ret).elemMul(_scale) : ret.elemMul(_scale);
129  if (_bRot)
130  ret = _rot * ret;
131  return ret;
132  }
133 
134  bool operator == (const Transform_& rhs) const { return _trans == rhs._trans && _rot == rhs._rot && _scale == rhs._scale; }
135  bool operator != (const Transform_& rhs) const { return !operator==(rhs); }
136 
137  Transform_ inverse() const;
138 
139  void resetTrans() { setTrans(Vec3::zero); }
141  void resetScale() { setScale(Vec3::one); }
142 
143  void setTrans(const Vec3& trans)
144  {
145  _trans = trans;
146  _bTrans = _trans != Vec3::zero;
147  onTmChange();
148  }
149 
150  const Vec3& getTrans() const { return _trans; }
151 
152  void setRot(const Quat& rot)
153  {
154  _rot = rot;
155  _bRot = _rot != Quat::identity;
156  onTmChange();
157  }
158 
159  const Quat& getRot() const { return _rot; }
160 
161  void setScale(const Vec3& scale, const Quat& skew = Quat::identity)
162  {
163  _skew = skew;
164  _bSkew = _skew != Quat::identity;
165  _scale = scale;
166  _bScale = _scale != Vec3::one || _bSkew;
167  _bUniformScale = _scale.x == _scale.y && _scale.x == _scale.z && !_bSkew;
168  onTmChange();
169  }
170 
171  void setScale(Real f) { setScale(Vec3(f)); }
172 
173  const Vec3& getScale() const { return _scale; }
174  const Quat& getSkew() const { return _skew; }
175 
178  {
179  if (trans) trans = _trans;
180  if (rot) rot = _rot;
181  if (scale) scale = _scale;
182  if (skew) skew = _skew;
183  }
184 
186  Transform_& translate(const Vec3& v) { Transform_ tm; tm.setTrans(v); return *this = tm * *this; }
188  Transform_& preTranslate(const Vec3& v) { Transform_ tm; tm.setTrans(v); return operator*=(tm); }
189 
191  Transform_& rotate(const Quat& q) { Transform_ tm; tm.setRot(q); return *this = tm * *this; }
193  Transform_& preRotate(const Quat& q) { Transform_ tm; tm.setRot(q); return operator*=(tm); }
194 
196  Transform_& scale(const Vec3& v, const Quat& skew = Quat::identity) { Transform_ tm; tm.setScale(v, skew); return *this = tm * *this; }
198  Transform_& scale(Real f) { return scale(Vec3(f)); }
199 
201  Transform_& preScale(const Vec3& v, const Quat& skew = Quat::identity) { Transform_ tm; tm.setScale(v, skew); return operator*=(tm); }
203  Transform_& preScale(Real f) { return preScale(Vec3(f)); }
204 
205  bool isIdentity() const { return !_bTrans && !_bRot && !_bScale; }
206  bool hasTrans() const { return _bTrans; }
207  bool hasRot() const { return _bRot; }
208  bool hasScale() const { return _bScale; }
209  bool hasUniformScale() const { return _bUniformScale; }
210  bool hasSkew() const { return _bSkew; }
211 
212  friend ostream& operator<<(ostream& os, const Transform_& tm)
213  {
214  return os << "{ " << "trans: " << tm._trans << ", rot: " << tm._rot
215  << ", scale: " << tm._scale << ", skew: " << tm._skew << " }";
216  }
217 
218 protected:
219  virtual void onTmChange() {}
220 
221 private:
224 
225  Vec3 _trans;
226  Quat _rot;
227  Vec3 _scale;
228  Quat _skew;
229 
230  bool _bTrans;
231  bool _bRot;
232  bool _bScale;
233  bool _bUniformScale;
234  bool _bSkew;
235 
236 public:
237  static const Transform_ identity;
238 };
239 
240 template<class Real> const Transform_<Real> Transform_<Real>::identity;
241 
245 
246 extern template class Transform_<Float>;
247 extern template class Transform_<Double>;
248 
249 }
(m x n)-dimensional matrix
Definition: Matrix.h:24
const Quat & getSkew() const
Definition: Transform.h:174
bool hasRot() const
Definition: Transform.h:207
void resetTrans()
Definition: Transform.h:139
static optnull_t optnull
Null optional, use to reset an optional to an uninitialized state or test for initialization.
Definition: Optional.h:12
const Vec3 & getScale() const
Definition: Transform.h:173
bool hasUniformScale() const
Definition: Transform.h:209
~Transform_()
Definition: Transform.h:62
bool operator==(const Transform_ &rhs) const
Definition: Transform.h:134
Transform_< Double > Transform_d
Definition: Transform.h:244
Transform_()
Init to identity.
Definition: Transform.h:52
friend ostream & operator<<(ostream &os, const Transform_ &tm)
Definition: Transform.h:212
Transform_ & preScale(const Vec3 &v, const Quat &skew=Quat::identity)
Make a tm that does a scale first, then performs this transform. ie. this * S.
Definition: Transform.h:201
Transform_< Float > Transform_f
Definition: Transform.h:243
Vec3 operator*(const Vec3 &v) const
Definition: Transform.h:107
Transform_ & fromTrs(const Vec3 &trans, const Quat &rot=Quat::identity, const Vec3 &scale=Vec3::one, const Quat &skew=Quat::identity)
Init from TRS components.
Definition: Transform.h:74
Transform_ & translate(const Vec3 &v)
Make a tm that performs this transform first, then does a translation. ie. T * this.
Definition: Transform.h:186
void setTrans(const Vec3 &trans)
Definition: Transform.h:143
bool operator!=(const Transform_ &rhs) const
Definition: Transform.h:135
Vec3 mulRotScale(const Vec3 &v) const
Transform by just rotation and scale/skew components (no translation)
Definition: Transform.h:124
Transform_(const Vec3 &trans, const Quat &rot=Quat::identity, const Vec3 &scale=Vec3::one, const Quat &skew=Quat::identity)
Construct from TRS components.
Definition: Transform.h:55
MatrixS elemMul(const MatrixBase< T > &rhs) const
Multiply each element with its corresponding element in rhs. Returns a new matrix with the results...
Definition: Base.h:199
const Quat & getRot() const
Definition: Transform.h:159
Vec2 operator*(const Vec2 &v) const
Definition: Transform.h:119
virtual void onTmChange()
Definition: Transform.h:219
Transform_ & preRotate(const Quat &q)
Make a tm that does a rotation first, then performs this transform. ie. this * R. ...
Definition: Transform.h:193
Quat_ inverse() const
Assumes that quaternion is unit length, same as conjugate()
Definition: Quat.h:191
Transform_ & preTranslate(const Vec3 &v)
Make a tm that does a translation first, then performs this transform. ie. this * T...
Definition: Transform.h:188
Transform_ & rotate(const Quat &q)
Make a tm that performs this transform first, then does a rotation. ie. R * this. ...
Definition: Transform.h:191
void setRot(const Quat &rot)
Definition: Transform.h:152
bool hasSkew() const
Definition: Transform.h:210
static const Quat_ identity
Definition: Quat.h:347
void resetRot()
Definition: Transform.h:140
Transform_ & scale(Real f)
Uniform scale.
Definition: Transform.h:198
float Real
Real number type. See Real_ for real number operations and constants.
Definition: Real.h:21
Use to differentiate an overloaded function by type. Accepts dummy parameter default value: func(tag<...
Definition: Meta.h:39
Transform_ & preScale(Real f)
Uniform prescale.
Definition: Transform.h:203
Enables any type to be optional so it can exist in an uninitialized null state.
Definition: Optional.h:52
bool hasTrans() const
Definition: Transform.h:206
Vec< 2, Real > Vec2
Definition: Transform.h:44
void setScale(const Vec3 &scale, const Quat &skew=Quat::identity)
Definition: Transform.h:161
Transform_(const Matrix4 &mat)
Construct from matrix. Matrix will be decomposed, an expensive operation.
Definition: Transform.h:60
void getTrs(optional< Vec3 & > trans=optnull, optional< Quat & > rot=optnull, optional< Vec3 & > scale=optnull, optional< Quat & > skew=optnull) const
Definition: Transform.h:176
void resetScale()
Definition: Transform.h:141
bool isIdentity() const
Definition: Transform.h:205
const Vec3 & getTrans() const
Definition: Transform.h:150
Transform_ & fromIdentity()
Init to identity.
Definition: Transform.h:65
Transform_ inverse() const
Definition: Transform.cpp:9
static const Transform_ identity
Definition: Transform.h:237
Vec< 3, Real > Vec3
Definition: Transform.h:45
Transform_ & scale(const Vec3 &v, const Quat &skew=Quat::identity)
Make a tm that performs this transform first, then does a scale. ie. S * this.
Definition: Transform.h:196
Vec< 4, Real > Vec4
Definition: Transform.h:46
bool hasScale() const
Definition: Transform.h:208
void setScale(Real f)
Definition: Transform.h:171
Vec4 operator*(const Vec4 &v) const
Definition: Transform.h:118
Transform_< Real > Transform
Definition: Transform.h:242
Transform_ & fromMatrix(const Matrix4 &mat)
Init from matrix. Matrix will be decomposed, an expensive operation.
Definition: Transform.h:84
Quat_< Real > Quat
Definition: Transform.h:48
Global Honeycomb namespace.
A 3D linear transform from TRS components (translation, rotation, and scale/skew) ...
Definition: Matrix4.h:11
Matrix< 4, 4, Real > Matrix4
Definition: Transform.h:47
Transform_ operator*(const Transform_ &tm) const
Definition: Transform.cpp:36
Transform_ & operator*=(const Transform_ &tm)
Definition: Transform.h:121
Transform_ & operator=(const Transform_ &rhs)
Definition: Transform.h:90