00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef NL_TRANSFORMABLE_H
00027 #define NL_TRANSFORMABLE_H
00028
00029 #include "nel/misc/types_nl.h"
00030 #include "nel/misc/matrix.h"
00031 #include "nel/misc/quat.h"
00032 #include "3d/animatable.h"
00033 #include "3d/animated_value.h"
00034 #include "3d/track.h"
00035
00036
00037 namespace NL3D
00038 {
00039
00040 class CChannelMixer;
00041
00042 using NLMISC::CMatrix;
00043 using NLMISC::CVector;
00044 using NLMISC::CQuat;
00045
00046
00054 class ITransformable : public IAnimatable
00055 {
00056 public:
00057
00058 enum TTransformMode
00059 {
00060 DirectMatrix=0,
00061 RotEuler,
00062 RotQuat,
00063
00064 TransformModeCount
00065 };
00066
00067
00068 public:
00069
00071 ITransformable();
00072 virtual ~ITransformable() {}
00073
00074
00076 const CMatrix &getMatrix() const {updateMatrix(); return _LocalMatrix;}
00077
00078
00082 bool compareMatrixDate(uint64 callerDate) const
00083 {
00084 return callerDate<_LocalMatrixDate || needCompute();
00085 }
00086
00087
00090 uint64 getMatrixDate() const
00091 {
00092 updateMatrix();
00093 return _LocalMatrixDate;
00094 }
00095
00096
00098
00099
00100 void setTransformMode(TTransformMode mode, CMatrix::TRotOrder ro= CMatrix::ZXY)
00101 {
00102 _Mode= mode;
00103 _RotOrder= ro;
00104
00105 touch(PosValue, OwnerBit);
00106 }
00108
00109
00111
00112
00114 void setPos(const CVector &pos)
00115 {
00116 nlassert(_Mode==RotEuler || _Mode==RotQuat);
00117 _Pos.Value= pos;
00118 touch(PosValue, OwnerBit);
00119 }
00121 void setPos(float x, float y, float z)
00122 {
00123 setPos(CVector(x,y,z));
00124 }
00126 void setRotEuler(const CVector &rot)
00127 {
00128 nlassert(_Mode==RotEuler);
00129 _RotEuler.Value= rot;
00130 touch(RotEulerValue, OwnerBit);
00131 }
00133 void setRotEuler(float rotX, float rotY, float rotZ)
00134 {
00135 setRotEuler(CVector(rotX, rotY, rotZ));
00136 }
00138 void setRotQuat(const CQuat &quat)
00139 {
00140 nlassert(_Mode==RotQuat);
00141 _RotQuat.Value= quat;
00142 touch(RotQuatValue, OwnerBit);
00143 }
00145 void setScale(const CVector &scale)
00146 {
00147 nlassert(_Mode==RotEuler || _Mode==RotQuat);
00148 _Scale.Value= scale;
00149 touch(ScaleValue, OwnerBit);
00150 }
00152 void setScale(float scaleX, float scaleY, float scaleZ)
00153 {
00154 setScale(CVector(scaleX, scaleY, scaleZ));
00155 }
00157 void setScale(float scale)
00158 {
00159 setScale(CVector(scale, scale, scale));
00160 }
00162 void setPivot(const CVector &pivot)
00163 {
00164 nlassert(_Mode==RotEuler || _Mode==RotQuat);
00165 _Pivot.Value= pivot;
00166 touch(PivotValue, OwnerBit);
00167 }
00169 void setPivot(float x, float y, float z)
00170 {
00171 setPivot(CVector(x, y, z));
00172 }
00174 void setMatrix(const CMatrix &mat)
00175 {
00176 nlassert(_Mode==DirectMatrix);
00177 _LocalMatrix= mat;
00178
00179 _LocalMatrixDate++;
00180 }
00181
00183
00184
00186
00187
00189 TTransformMode getTransformMode()
00190 {
00191 return _Mode;
00192 }
00194 CMatrix::TRotOrder getRotOrder()
00195 {
00196 return _RotOrder;
00197 }
00198
00200 void getPos(CVector &pos)
00201 {
00202 nlassert(_Mode==RotEuler || _Mode==RotQuat);
00203 pos= _Pos.Value;
00204 }
00206 void getRotEuler(CVector &rot)
00207 {
00208 nlassert(_Mode==RotEuler);
00209 rot= _RotEuler.Value;
00210 }
00212 void getRotQuat(CQuat &quat)
00213 {
00214 nlassert(_Mode==RotQuat);
00215 quat= _RotQuat.Value;
00216 }
00218 void getScale(CVector &scale)
00219 {
00220 nlassert(_Mode==RotEuler || _Mode==RotQuat);
00221 scale= _Scale.Value;
00222 }
00224 void getPivot(CVector &pivot)
00225 {
00226 nlassert(_Mode==RotEuler || _Mode==RotQuat);
00227 pivot= _Pivot.Value;
00228 }
00229
00231 CVector getPos()
00232 {
00233 nlassert(_Mode==RotEuler || _Mode==RotQuat);
00234 return _Pos.Value;
00235 }
00237 CVector getRotEuler()
00238 {
00239 nlassert(_Mode==RotEuler);
00240 return _RotEuler.Value;
00241 }
00243 CQuat getRotQuat()
00244 {
00245 nlassert(_Mode==RotQuat);
00246 return _RotQuat.Value;
00247 }
00249 CVector getScale()
00250 {
00251 nlassert(_Mode==RotEuler || _Mode==RotQuat);
00252 return _Scale.Value;
00253 }
00255 CVector getPivot()
00256 {
00257 nlassert(_Mode==RotEuler || _Mode==RotQuat);
00258 return _Pivot.Value;
00259 }
00261
00262
00264
00272 void lookAt (const CVector& eye, const CVector& target, float roll=0.f);
00273
00274
00275
00276
00278
00280
00281 {
00282 OwnerBit= IAnimatable::AnimValueLast,
00283 PosValue,
00284 RotEulerValue,
00285 RotQuatValue,
00286 ScaleValue,
00287 PivotValue,
00288 AnimValueLast
00289 };
00290
00292 virtual IAnimatedValue* getValue (uint valueId);
00293
00295 virtual const char *getValueName (uint valueId) const;
00296
00298 virtual ITrack* getDefaultTrack (uint valueId) =0;
00299
00301 virtual void registerToChannelMixer(CChannelMixer *chanMixer, const std::string &prefix) =0;
00302
00303
00304
00305
00306 static const char *getPosValueName ();
00307 static const char *getRotEulerValueName();
00308 static const char *getRotQuatValueName();
00309 static const char *getScaleValueName();
00310 static const char *getPivotValueName();
00311
00312
00313 private:
00314
00315 mutable CMatrix _LocalMatrix;
00316 TTransformMode _Mode;
00317 CMatrix::TRotOrder _RotOrder;
00318 mutable uint64 _LocalMatrixDate;
00319
00320
00321 CAnimatedValueVector _Pos;
00322 CAnimatedValueVector _RotEuler;
00323 CAnimatedValueQuat _RotQuat;
00324 CAnimatedValueVector _Scale;
00325 CAnimatedValueVector _Pivot;
00326
00327
00328 void clearTransformFlags() const;
00329
00330
00331 void updateMatrix() const;
00332
00334 bool needCompute() const
00335 {
00336 return _Mode!=DirectMatrix && isTouched(OwnerBit);
00337 }
00338
00339 };
00340
00341
00342 }
00343
00344
00345 #endif // NL_TRANSFORMABLE_H
00346
00347