00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "3d/transformable.h"
00029 #include "3d/channel_mixer.h"
00030
00031
00032 namespace NL3D
00033 {
00034
00035
00036
00037 ITransformable::ITransformable()
00038 {
00039
00040 IAnimatable::resize (AnimValueLast);
00041
00042
00043
00044
00045 _Mode= RotQuat;
00046
00047 _Pos.Value= CVector::Null;
00048 _RotEuler.Value= CVector::Null;
00049 _RotQuat.Value= CQuat::Identity;
00050 _Scale.Value= CVector(1,1,1);
00051 _Pivot.Value= CVector::Null;
00052
00053 _LocalMatrixDate= 0;
00054 }
00055
00056
00057
00058 IAnimatedValue* ITransformable::getValue (uint valueId)
00059 {
00060
00061 switch (valueId)
00062 {
00063 case PosValue: return &_Pos;
00064 case RotEulerValue: return &_RotEuler;
00065 case RotQuatValue: return &_RotQuat;
00066 case ScaleValue: return &_Scale;
00067 case PivotValue: return &_Pivot;
00068 }
00069
00070
00071 nlstop;
00072
00073
00074 return NULL;
00075 }
00076
00077 const char *ITransformable::getValueName (uint valueId) const
00078 {
00079
00080 switch (valueId)
00081 {
00082 case PosValue: return getPosValueName ();
00083 case RotEulerValue: return getRotEulerValueName();
00084 case RotQuatValue: return getRotQuatValueName();
00085 case ScaleValue: return getScaleValueName();
00086 case PivotValue: return getPivotValueName();
00087 }
00088
00089
00090 nlstop;
00091
00092
00093 return "";
00094 }
00095
00096
00097 const char *ITransformable::getPosValueName ()
00098 {
00099 return "pos";
00100 }
00101
00102 const char *ITransformable::getRotEulerValueName()
00103 {
00104 return "roteuler";
00105 }
00106
00107 const char *ITransformable::getRotQuatValueName()
00108 {
00109 return "rotquat";
00110 }
00111
00112 const char *ITransformable::getScaleValueName()
00113 {
00114 return "scale";
00115 }
00116
00117 const char *ITransformable::getPivotValueName()
00118 {
00119 return "pivot";
00120 }
00121
00122
00123
00124 void ITransformable::clearTransformFlags() const
00125 {
00126 ITransformable *self= const_cast<ITransformable*>(this);
00127
00128
00129 self->clearFlag(PosValue);
00130 self->clearFlag(RotEulerValue);
00131 self->clearFlag(RotQuatValue);
00132 self->clearFlag(ScaleValue);
00133 self->clearFlag(PivotValue);
00134
00135
00136 self->clearFlag(OwnerBit);
00137 }
00138
00139
00140
00141 void ITransformable::updateMatrix() const
00142 {
00143
00144 if(needCompute())
00145 {
00146 clearTransformFlags();
00147
00148 _LocalMatrixDate++;
00149
00150
00151 _LocalMatrix.identity();
00152
00153
00154
00155 _LocalMatrix.translate(_Pos.Value+_Pivot.Value);
00156
00157
00158 if(_Mode==RotEuler)
00159 _LocalMatrix.rotate(_RotEuler.Value, _RotOrder);
00160 else
00161 _LocalMatrix.rotate(_RotQuat.Value);
00162 _LocalMatrix.scale(_Scale.Value);
00163 _LocalMatrix.translate(-_Pivot.Value);
00164 }
00165 }
00166
00167
00168
00169 void ITransformable::lookAt (const CVector& eye, const CVector& target, float roll)
00170 {
00171 nlassert(_Mode==RotQuat || _Mode==DirectMatrix);
00172
00173
00174 CMatrix rollMT;
00175 rollMT.identity();
00176 if (roll!=0.f)
00177 rollMT.rotateY (roll);
00178
00179
00180 CVector j=target;
00181 j-=eye;
00182 j.normalize();
00183 CVector i=j^CVector (0,0,1.f);
00184 CVector k=i^j;
00185 k.normalize();
00186 i=j^k;
00187 i.normalize();
00188
00189
00190 CMatrix targetMT;
00191 targetMT.identity();
00192 targetMT.setRot (i, j, k);
00193 targetMT.setPos (eye);
00194
00195
00196 targetMT*=rollMT;
00197
00198
00199 if(_Mode==DirectMatrix)
00200 setMatrix (targetMT);
00201 else
00202 {
00203
00204 setScale(CVector(1,1,1));
00205 setPivot(CVector::Null);
00206 setPos(targetMT.getPos());
00207 setRotQuat(targetMT.getRot());
00208 }
00209 }
00210
00211
00212
00213 }