#include <target_anim_ctrl.h>
Inheritance diagram for NL3D::CTargetAnimCtrl:
Nevrax France
Definition at line 48 of file target_anim_ctrl.h.
Public Types | |
enum | TMode { TargetMode = 0, DirectionMode, NumMode } |
Public Member Functions | |
CTargetAnimCtrl () | |
Constructor. | |
virtual void | execute (CSkeletonModel *model, CBone *bone) |
Called at compute() time. | |
virtual | ~CTargetAnimCtrl () |
Data Fields | |
TMode | Mode |
Target controled or direction controled. Default to DirectionMode. | |
Target and Direction specific | |
CQuat | CurrentWorldDirection |
For DirectionMode, the WorldRotation to apply to the bone. NB: modified in execute() if TargetMode. | |
CVector | EyePos |
For TargetMode only, the Pos of eyes relative to the bone controlled. Default to (0,0,0). | |
CVector | WorldTarget |
For TargetMode, the world Position of the target. | |
Common | |
CQuat | DefaultWorldDirection |
This give The World Orientation when the Mesh is in bind Pos (default to "LookBack"). | |
bool | Enabled |
float | MaxAngle |
The Maximum angle of rotation that can be performed between the Default Direction and Current Direction. Default to Pi/3. | |
float | MaxAngularVelocity |
The Maximum Angular Velocity the ctrl can perform. Default to 2*Pi per second. | |
Private Member Functions | |
CQuat | getCurrentLSRotationFromBone (CSkeletonModel *model, CBone *bone) |
Private Attributes | |
bool | _EnableToDisableTransition |
bool | _LastEnabled |
This tells that a Enable/Disable transition is in progress. | |
CQuat | _LastLSRotation |
The last rotation computed (in LocalSkeleton Space). Used to smooth transition. |
|
Definition at line 52 of file target_anim_ctrl.h.
00052 {TargetMode=0, DirectionMode, NumMode}; |
|
Constructor.
Definition at line 40 of file target_anim_ctrl.cpp. References _EnableToDisableTransition, _LastEnabled, DefaultWorldDirection, DirectionMode, Enabled, EyePos, MaxAngle, MaxAngularVelocity, Mode, NLMISC::Pi, NLMISC::CQuatT< float >::set(), and WorldTarget.
00041 { 00042 Mode= DirectionMode; 00043 WorldTarget= CVector::Null; 00044 EyePos= CVector::Null; 00045 // Default Direction to "LookBack". 00046 DefaultWorldDirection.set(0,0,1,0); 00047 MaxAngle= (float)Pi/3; 00048 MaxAngularVelocity= (float)(2*Pi); 00049 Enabled= true; 00050 _EnableToDisableTransition= false; 00051 _LastEnabled= true; 00052 } |
|
Definition at line 56 of file target_anim_ctrl.cpp.
00057 { 00058 } |
|
Called at compute() time.
Implements NL3D::IAnimCtrl. Definition at line 62 of file target_anim_ctrl.cpp. References _EnableToDisableTransition, _LastEnabled, _LastLSRotation, NLMISC::CAngleAxis::Angle, NL3D::CSkeletonModel::Bones, NLMISC::clamp(), NL3D::CBone::compute(), NLMISC::CQuatT< float >::conjugate(), CurrentWorldDirection, DefaultWorldDirection, Enabled, EyePos, NLMISC::CQuatT< float >::getAngle(), NLMISC::CQuatT< float >::getAngleAxis(), NL3D::CBone::getBoneBase(), getCurrentLSRotationFromBone(), NL3D::CScene::getEllapsedTime(), NL3D::CBone::getFatherId(), NL3D::CBone::getLocalSkeletonMatrix(), NL3D::CTransform::getOwnerScene(), NLMISC::CMatrix::getRot(), NL3D::ITransformable::getTransformMode(), NL3D::CTransform::getWorldMatrix(), NL3D::CBone::getWorldMatrix(), NL3D::CBoneBase::InvBindPos, NLMISC::CQuatT< float >::makeClosest(), MaxAngle, MaxAngularVelocity, Mode, NLMISC::CMatrix::normalize(), NLMISC::CVector::normed(), NLMISC::CQuatT< float >::setAngleAxis(), NLMISC::CMatrix::setRot(), NL3D::ITransformable::setRotQuat(), and WorldTarget.
00063 { 00064 // no op if req not met 00065 if(!bone || !model || bone->getTransformMode()!=ITransformable::RotQuat) 00066 return; 00067 00068 // If the user changed the Enabled state, must do a transition. 00069 if(_LastEnabled!=Enabled) 00070 { 00071 _LastEnabled= Enabled; 00072 // if re-enable the control while completely disabled before 00073 if(Enabled && !_EnableToDisableTransition) 00074 { 00075 // set the LastLSRotation so that it match the current anim ones. 00076 _LastLSRotation= getCurrentLSRotationFromBone(model, bone); 00077 } 00078 // if disable the ctrl, then do a transition first 00079 if(!Enabled) 00080 { 00081 _EnableToDisableTransition= true; 00082 } 00083 } 00084 00085 // If not enabled, and not in transition, no op. 00086 if( !Enabled && !_EnableToDisableTransition) 00087 return; 00088 00089 // If Target mode, compute CurrentWorldDirection 00090 // *********** 00091 // NB: does need to compute direction if disabled (even if in transition) 00092 if(Mode==TargetMode && Enabled) 00093 { 00094 // get the eye pos in world. 00095 CVector worldEye= bone->getWorldMatrix()*EyePos; 00096 // get the world dir 00097 CVector worldDir= (WorldTarget - worldEye).normed(); 00098 // get the associated quat 00099 CMatrix mat; 00100 mat.setRot(CVector::I, worldDir, CVector::K); 00101 mat.normalize(CMatrix::YZX); 00102 CurrentWorldDirection= mat.getRot(); 00103 } 00104 00105 00106 // compute rotation to apply In LocalSkeleton Space 00107 // *********** 00108 CQuat currentLSRotation; 00109 00110 /* Get the Skeleton default WorldMatrix (bind pos). used later 00111 TRICK: to get the default Skeleton WorldMatrix, get it from Bone[0] (ie "Bip01") 00112 We cannot use the Default Pos/Rot of the skeleton model because of export bug (not exported...) 00113 So, since Bip01 as no Local Rot (yes, its true, exporter report all Bip01 rots on Skeleton), 00114 we are sure that Bip01 BindPos is the default Skeleton World Matrix. 00115 */ 00116 CQuat rootInvBP= model->Bones[0].getBoneBase().InvBindPos.getRot(); 00117 00118 // If ctrl not enabled, take the LSRotation from the animation 00119 if(!Enabled) 00120 { 00121 currentLSRotation= getCurrentLSRotationFromBone(model, bone); 00122 } 00123 else 00124 { 00125 // Get the wanted direction in LocalSkeleton Space. 00126 CQuat currentLSDirection; 00127 00128 // Get the current wanted WorldDirection into LocalSkeleton space (hence using current skeleton WorldMatrix). 00129 CMatrix toLSSpace= model->getWorldMatrix(); 00130 currentLSDirection= toLSSpace.getRot().conjugate() * CurrentWorldDirection; 00131 00132 // Get the default WorldDirection into LocalSkeleton space (hence using default skeleton WorldMatrix). 00133 CQuat defaultLSDirection= rootInvBP * DefaultWorldDirection; 00134 00135 /* get the rotation to apply to the bone when it is in bind Pos. If this quat is identity, 00136 then the bone will be in default (or bind) pos. 00137 It is in essence the "rotation to apply to defaultDirection in LS space, in order to get 00138 the wanted current direction in LS space". 00139 The makeClosest() is here just to ensure that the resulting angle<Pi (for clamp direction later) 00140 */ 00141 currentLSDirection.makeClosest(defaultLSDirection); 00142 currentLSRotation= currentLSDirection * defaultLSDirection.conjugate(); 00143 } 00144 00145 00146 // Clamp direction, and smooth direction changes. 00147 // *********** 00148 // if not enabled, then LSRotation comes from the animation => do not clamp 00149 if(Enabled) 00150 { 00151 // to AngleAxis. 00152 CAngleAxis angleAxis= currentLSRotation.getAngleAxis(); 00153 // Clamp the angle 00154 clamp(angleAxis.Angle, -MaxAngle, MaxAngle); 00155 // back To Quat. 00156 currentLSRotation.setAngleAxis(angleAxis); 00157 } 00158 00159 // get the dt of the scene. 00160 CScene *scene= model->getOwnerScene(); 00161 float sceneDt= scene->getEllapsedTime(); 00162 float maxDeltaAngle= MaxAngularVelocity*sceneDt; 00163 // get the quat that change from LastRotation to CurrentRotation 00164 CQuat rotMod= _LastLSRotation.conjugate() * currentLSRotation; 00165 // compute how many rotation we are allowed to do. 00166 float rotModAngle= (float)fabs(rotMod.getAngle()); 00167 bool rotSpeedClamped= false; 00168 if(rotModAngle) 00169 { 00170 float factor= (float)fabs(maxDeltaAngle) / rotModAngle; 00171 // If cannot do all the rotation this frame 00172 if(factor<1) 00173 { 00174 // then slerp between last and current rotation 00175 currentLSRotation.makeClosest(_LastLSRotation); 00176 currentLSRotation= CQuat::slerp(_LastLSRotation, currentLSRotation, factor); 00177 rotSpeedClamped= true; 00178 } 00179 } 00180 00181 // if the rotation has not been clamped for speed consideration, and if !Enabed, it's mean we have ended 00182 // the transition => no more compute next time 00183 if(!Enabled && !rotSpeedClamped) 00184 _EnableToDisableTransition= false; 00185 00186 // bkup last rotation 00187 _LastLSRotation= currentLSRotation; 00188 00189 // Apply the weighted Rotation to the bone 00190 // *********** 00191 // Get the bone Bind Pos in LocalSkeleton space (hence using Default Skeleton WorldMatrix) 00192 CQuat boneBindPosInWorld= bone->getBoneBase().InvBindPos.getRot().conjugate(); 00193 CQuat boneBindPosInLS= rootInvBP * boneBindPosInWorld; 00194 // rotate it to match our wanted direction. 00195 boneBindPosInLS= currentLSRotation * boneBindPosInLS; 00196 00197 // get it in bone local space. 00198 // get the Bone Parent LocalSkeletonMatrix 00199 CBone *boneParent= bone->getFatherId()==-1? NULL : &model->Bones[bone->getFatherId()]; 00200 CQuat currentLocalQuat; 00201 if(!boneParent) 00202 currentLocalQuat= boneBindPosInLS; 00203 else 00204 { 00205 // compute the rotation to apply, in local space 00206 CQuat qp= boneParent->getLocalSkeletonMatrix().getRot(); 00207 currentLocalQuat= qp.conjugate() * boneBindPosInLS; 00208 } 00209 00210 // set the new LocalRotQuat 00211 bone->setRotQuat(currentLocalQuat); 00212 // and recompute the bone (but without AnimCtrl of course :) ) 00213 bone->compute(boneParent, model->getWorldMatrix(), NULL); 00214 00215 } |
|
Definition at line 219 of file target_anim_ctrl.cpp. References NL3D::CSkeletonModel::Bones, NLMISC::CQuatT< float >::conjugate(), NL3D::CBone::getBoneBase(), NL3D::CBone::getLocalSkeletonMatrix(), NLMISC::CMatrix::getRot(), NL3D::CBoneBase::InvBindPos, and NLMISC::CQuatT< float >::makeClosest(). Referenced by execute().
00220 { 00221 // get the current rotation matrix (qmat) of this bone, in LS space 00222 CQuat currentLSRot= bone->getLocalSkeletonMatrix().getRot(); 00223 00224 // get the default bindPos (qb) rotation of this bone, in LS space. 00225 CQuat boneBindPosInWorld= bone->getBoneBase().InvBindPos.getRot().conjugate(); 00226 CQuat rootInvBP= model->Bones[0].getBoneBase().InvBindPos.getRot(); 00227 CQuat boneBindPosInLS= rootInvBP * boneBindPosInWorld; 00228 00229 // The rotation (qrot) is computed such that qmat= qrot * qb 00230 currentLSRot.makeClosest(boneBindPosInLS); 00231 return currentLSRot * boneBindPosInLS.conjugate(); 00232 } |
|
Definition at line 99 of file target_anim_ctrl.h. Referenced by CTargetAnimCtrl(), and execute(). |
|
This tells that a Enable/Disable transition is in progress.
Definition at line 98 of file target_anim_ctrl.h. Referenced by CTargetAnimCtrl(), and execute(). |
|
The last rotation computed (in LocalSkeleton Space). Used to smooth transition.
Definition at line 95 of file target_anim_ctrl.h. Referenced by execute(). |
|
For DirectionMode, the WorldRotation to apply to the bone. NB: modified in execute() if TargetMode.
Definition at line 65 of file target_anim_ctrl.h. Referenced by execute(). |
|
This give The World Orientation when the Mesh is in bind Pos (default to "LookBack").
Definition at line 75 of file target_anim_ctrl.h. Referenced by CTargetAnimCtrl(), and execute(). |
|
This enable or disable the ctrl. When disabled or enabled, the ctrl ensure that the movement does not "pop", respecting MaxAngularVelocity. Default to true. Definition at line 73 of file target_anim_ctrl.h. Referenced by CTargetAnimCtrl(), and execute(). |
|
For TargetMode only, the Pos of eyes relative to the bone controlled. Default to (0,0,0).
Definition at line 63 of file target_anim_ctrl.h. Referenced by CTargetAnimCtrl(), and execute(). |
|
The Maximum angle of rotation that can be performed between the Default Direction and Current Direction. Default to Pi/3.
Definition at line 77 of file target_anim_ctrl.h. Referenced by CTargetAnimCtrl(), and execute(). |
|
The Maximum Angular Velocity the ctrl can perform. Default to 2*Pi per second.
Definition at line 79 of file target_anim_ctrl.h. Referenced by CTargetAnimCtrl(), and execute(). |
|
Target controled or direction controled. Default to DirectionMode.
Definition at line 56 of file target_anim_ctrl.h. Referenced by CTargetAnimCtrl(), and execute(). |
|
For TargetMode, the world Position of the target.
Definition at line 61 of file target_anim_ctrl.h. Referenced by CTargetAnimCtrl(), and execute(). |