Merge branch 'main/rendor-staging' into fixes
[ryzomcore.git] / nel / src / 3d / transformable.cpp
blob30ef19e36ebee0a53d5ad60e45e540082b27332d
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "std3d.h"
19 #include "nel/3d/transformable.h"
20 #include "nel/3d/channel_mixer.h"
22 #ifdef DEBUG_NEW
23 #define new DEBUG_NEW
24 #endif
26 namespace NL3D
30 // ***************************************************************************
31 ITransformable::ITransformable()
33 // Set number of animated values.
34 IAnimatable::resize (AnimValueLast);
36 // Deriver note: just copy this line in each ctor.
38 // Init default values.
39 _Mode= RotQuat;
40 // matrix init to identity.
41 _Pos.Value= CVector::Null;
42 _RotEuler.Value= CVector::Null;
43 _RotQuat.Value= CQuat::Identity;
44 _Scale.Value= CVector(1,1,1);
45 _Pivot.Value= CVector::Null;
47 _LocalMatrixDate= 0;
51 // ***************************************************************************
52 IAnimatedValue* ITransformable::getValue (uint valueId)
54 // what value ?
55 switch (valueId)
57 case PosValue: return &_Pos;
58 case RotEulerValue: return &_RotEuler;
59 case RotQuatValue: return &_RotQuat;
60 case ScaleValue: return &_Scale;
61 case PivotValue: return &_Pivot;
64 // No, only ITrnasformable values!
65 nlstop;
66 // Deriver note: else call BaseClass::getValue(valueId);
68 return NULL;
70 // ***************************************************************************
71 const char *ITransformable::getValueName (uint valueId) const
73 // what value ?
74 switch (valueId)
76 case PosValue: return getPosValueName ();
77 case RotEulerValue: return getRotEulerValueName();
78 case RotQuatValue: return getRotQuatValueName();
79 case ScaleValue: return getScaleValueName();
80 case PivotValue: return getPivotValueName();
83 // No, only ITrnasformable values!
84 nlstop;
85 // Deriver note: else call BaseClass::getValueName(valueId);
87 return "";
90 // ***************************************************************************
91 const char *ITransformable::getPosValueName ()
93 return "pos";
95 // ***************************************************************************
96 const char *ITransformable::getRotEulerValueName()
98 return "roteuler";
100 // ***************************************************************************
101 const char *ITransformable::getRotQuatValueName()
103 return "rotquat";
105 // ***************************************************************************
106 const char *ITransformable::getScaleValueName()
108 return "scale";
110 // ***************************************************************************
111 const char *ITransformable::getPivotValueName()
113 return "pivot";
117 // ***************************************************************************
118 void ITransformable::clearTransformFlags() const
120 ITransformable *self= const_cast<ITransformable*>(this);
122 // clear my falgs.
123 self->clearFlag(PosValue);
124 self->clearFlag(RotEulerValue);
125 self->clearFlag(RotQuatValue);
126 self->clearFlag(ScaleValue);
127 self->clearFlag(PivotValue);
129 // We are OK!
130 self->clearFlag(OwnerBit);
134 // ***************************************************************************
135 void ITransformable::updateMatrix() const
137 // should we update?
138 if(needCompute())
140 clearTransformFlags();
141 // update scale date (so sons are informed of change).
142 _LocalMatrixDate++;
144 // update the matrix.
145 _LocalMatrix.identity();
147 // father scale will be herited.
148 // T*P
149 _LocalMatrix.translate(_Pos.Value+_Pivot.Value);
151 // R*S*P-1.
152 if(_Mode==RotEuler)
153 _LocalMatrix.rotate(_RotEuler.Value, _RotOrder);
154 else
155 _LocalMatrix.rotate(_RotQuat.Value);
156 _LocalMatrix.scale(_Scale.Value);
157 _LocalMatrix.translate(-_Pivot.Value);
162 // ***************************************************************************
163 void ITransformable::lookAt (const CVector& eye, const CVector& target, float roll)
165 nlassert(_Mode==RotQuat || _Mode==DirectMatrix);
167 // Roll matrix
168 CMatrix rollMT;
169 rollMT.identity();
170 if (roll!=0.f)
171 rollMT.rotateY (roll);
173 // Make the target base
174 CVector j=target;
175 j-=eye;
176 j.normalize();
177 CVector i=j^CVector (0,0,1.f);
178 CVector k=i^j;
179 k.normalize();
180 i=j^k;
181 i.normalize();
183 // Make the target matrix
184 CMatrix targetMT;
185 targetMT.identity();
186 targetMT.setRot (i, j, k);
187 targetMT.setPos (eye);
189 // Compose matrix
190 targetMT*=rollMT;
192 // Set the matrix
193 if(_Mode==DirectMatrix)
194 setMatrix (targetMT);
195 else
197 // transfrom to quaternion mode.
198 setScale(CVector(1,1,1));
199 setPivot(CVector::Null);
200 setPos(targetMT.getPos());
201 setRotQuat(targetMT.getRot());
207 } // NL3D