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/event_mouse_listener.h"
00029 #include "nel/misc/event_server.h"
00030 #include "3d/camera.h"
00031 #include "nel/misc/time_nl.h"
00032 #include "nel/misc/quat.h"
00033
00034 using namespace NLMISC;
00035
00036 namespace NL3D
00037 {
00038
00039
00040 CEvent3dMouseListener::CEvent3dMouseListener() : _CurrentModelRotationAxis(zAxis)
00041 ,_XModelTranslateEnabled(true)
00042 ,_YModelTranslateEnabled(true)
00043 ,_ZModelTranslateEnabled(true)
00044 {
00045 _Matrix.identity();
00046 _ModelMatrix.identity() ;
00047 _EnableModelMatrixEdition = false ;
00048 _HotSpot.set (0,0,0);
00049 _Viewport.initFullScreen();
00050 _Frustrum.init (2.f, 2.f, -1.f, 1.f);
00051 _MouseMode=nelStyle;
00052 setSpeed (10.f);
00053 _LastTime=CTime::getLocalTime ();
00054 _TranslateXYInWorld= false;
00055 }
00056
00057
00058
00059 void CEvent3dMouseListener::enableModelTranslationAxis(TAxis axis, bool enabled)
00060 {
00061 switch (axis)
00062 {
00063 case xAxis: _XModelTranslateEnabled = enabled ; break ;
00064 case yAxis: _YModelTranslateEnabled = enabled ; break ;
00065 case zAxis: _ZModelTranslateEnabled = enabled ; break ;
00066 }
00067 }
00068
00069 bool CEvent3dMouseListener::isModelTranslationEnabled(TAxis axis)
00070 {
00071 switch (axis)
00072 {
00073 case xAxis: return _XModelTranslateEnabled ; break ;
00074 case yAxis: return _YModelTranslateEnabled ; break ;
00075 case zAxis: return _ZModelTranslateEnabled ; break ;
00076 default: return false ; break ;
00077 }
00078 }
00079
00080
00081 void CEvent3dMouseListener::truncateVect(CVector &v)
00082 {
00083 if (!_XModelTranslateEnabled) v.x = 0.f ;
00084 if (!_YModelTranslateEnabled) v.y = 0.f ;
00085 if (!_ZModelTranslateEnabled) v.z = 0.f ;
00086 }
00087
00088
00089 void CEvent3dMouseListener::operator ()(const CEvent& event)
00090 {
00091 CEventMouse* mouseEvent=(CEventMouse*)&event;
00092 if (event==EventMouseMoveId)
00093 {
00094 bool bRotate=false;
00095 bool bTranslateXY=false;
00096 bool bTranslateZ=false;
00097 bool bZoom=false;
00098
00099
00100
00101 CVector axis;
00102
00103 if (_MouseMode==nelStyle)
00104 {
00105 bRotate=(mouseEvent->Button==(ctrlButton|rightButton));
00106 bTranslateXY=(mouseEvent->Button==(ctrlButton|leftButton));
00107 bTranslateZ=(mouseEvent->Button==(ctrlButton|shiftButton|leftButton));
00108 bZoom=(mouseEvent->Button==(altButton|leftButton));
00109 axis=_HotSpot;
00110 }
00111 else if (_MouseMode==edit3d)
00112 {
00113 bRotate=(mouseEvent->Button==(altButton|middleButton)) || (mouseEvent->Button==(altButton|leftButton));
00114 bTranslateXY=(mouseEvent->Button==(ctrlButton|leftButton)) || (mouseEvent->Button==middleButton);
00115 bTranslateZ=(mouseEvent->Button==(ctrlButton|shiftButton|leftButton)) || (mouseEvent->Button==(ctrlButton|middleButton));
00116 bZoom=(mouseEvent->Button==(shiftButton|leftButton)) || (mouseEvent->Button==(ctrlButton|altButton|middleButton));
00117 axis=_HotSpot;
00118 }
00119 else
00120 {
00121 bRotate=(mouseEvent->Button&leftButton)!=0;
00122 bTranslateXY=false;
00123 bTranslateZ=false;
00124 bZoom=false;
00125 axis=_Matrix.getPos();
00126 }
00127
00128 if (bRotate)
00129 {
00130 if (!_EnableModelMatrixEdition)
00131 {
00132
00133 CMatrix comeFromHotSpot=_Matrix;
00134 comeFromHotSpot.setPos (axis);
00135
00136
00137 CMatrix turnZ;
00138 turnZ.identity();
00139 turnZ.rotateZ ((float) Pi*2.f*(_X-mouseEvent->X));
00140
00141
00142 CMatrix turnX;
00143 turnX.identity();
00144 turnX.rotateX ((float) Pi*2.f*(mouseEvent->Y-_Y));
00145
00146
00147 CMatrix goToHotSpot=comeFromHotSpot;
00148 goToHotSpot.invert();
00149
00150
00151 CMatrix negPivot, Pivot;
00152 negPivot.identity();
00153 negPivot.setPos (-axis);
00154 Pivot.identity();
00155 Pivot.setPos (axis);
00156
00157
00158
00159 Pivot*=turnZ;
00160 Pivot*=negPivot;
00161 Pivot*=comeFromHotSpot;
00162 Pivot*=turnX;
00163 Pivot*=goToHotSpot;
00164
00165
00166 Pivot*=_Matrix;
00167 _Matrix=Pivot;
00168
00169 _Matrix.normalize (CMatrix::XYZ);
00170
00171 }
00172 else
00173 {
00174 CVector pos = _ModelMatrix.getPos() ;
00175 NLMISC::CQuat r ;
00176 switch (_CurrentModelRotationAxis)
00177 {
00178 case xAxis : r = CQuat(CAngleAxis(_ModelMatrix.getI(), (float) Pi*2.f*(_X-mouseEvent->X))) ; break ;
00179 case yAxis : r = CQuat(CAngleAxis(_ModelMatrix.getJ(), (float) Pi*2.f*(_X-mouseEvent->X))) ; break ;
00180 case zAxis : r = CQuat(CAngleAxis(_ModelMatrix.getK(), (float) Pi*2.f*(_X-mouseEvent->X))) ; break ;
00181 } ;
00182
00183
00184 CMatrix rm ;
00185 rm.rotate(r) ;
00186
00187 _ModelMatrix = rm * _ModelMatrix ;
00188 _ModelMatrix.setPos(pos) ;
00189
00190 _ModelMatrix.normalize (CMatrix::XYZ);
00191 }
00192 }
00193
00194
00195 if (bTranslateXY||bTranslateZ||bZoom)
00196 {
00197
00198
00199 CPlane plane;
00200
00201
00202 CVector decal;
00203
00204
00205 if (! _EnableModelMatrixEdition)
00206 {
00207 decal= axis;
00208 }
00209 else
00210 {
00211 decal= _ModelMatrix.getPos();
00212 }
00213
00214 if (bTranslateXY && _TranslateXYInWorld)
00215 {
00216 plane.make (CVector::K, CVector::Null);
00217 }
00218 else
00219 {
00220 plane.make (_Matrix.getJ(), CVector::Null);
00221 }
00222
00223
00224
00225 CMatrix localViewMatrix= _Matrix;
00226 localViewMatrix.setPos(_Matrix.getPos() - decal);
00227 CVector localPoint1, localPoint2;
00228 CVector pos, dir;
00229 _Viewport.getRayWithPoint (_X, _Y, pos, dir, localViewMatrix, _Frustrum);
00230 localPoint1=plane.intersect (pos, pos+dir);
00231 _Viewport.getRayWithPoint (mouseEvent->X, mouseEvent->Y, pos, dir, localViewMatrix, _Frustrum);
00232 localPoint2=plane.intersect (pos, pos+dir);
00233
00234
00235 if (bTranslateXY)
00236 {
00237 if (! _EnableModelMatrixEdition)
00238 {
00239 _Matrix.setPos(_Matrix.getPos()+localPoint1-localPoint2);
00240 }
00241 else
00242 {
00243 CVector dir = - localPoint1 + localPoint2 ;
00244
00245 dir= _ModelMatrixTransformMove * dir;
00246 truncateVect(dir) ;
00247 _ModelMatrix.setPos(_ModelMatrix.getPos()+dir);
00248 }
00249 }
00250 else if (bTranslateZ)
00251 {
00252 CVector vect=localPoint1-localPoint2;
00253 if (! _EnableModelMatrixEdition)
00254 {
00255 _Matrix.setPos(_Matrix.getPos()+_Matrix.getK()*(vect.x+vect.y+vect.z));
00256 }
00257 else
00258 {
00259 CVector dir = _Matrix.getK()*(vect.x+vect.y+vect.z) ;
00260
00261 dir= _ModelMatrixTransformMove * dir;
00262 truncateVect(dir) ;
00263 _ModelMatrix.setPos(_ModelMatrix.getPos()+dir);
00264 }
00265 }
00266 else if (bZoom)
00267 {
00268 CVector vect=localPoint1-localPoint2;
00269 CVector direc=axis-_Matrix.getPos();
00270 direc.normalize();
00271 if (! _EnableModelMatrixEdition)
00272 {
00273 _Matrix.setPos(_Matrix.getPos()+direc*(vect.x+vect.y+vect.z));
00274 }
00275 else
00276 {
00277
00278 direc= _ModelMatrixTransformMove * direc;
00279 direc.normalize();
00280 _ModelMatrix.setPos(_ModelMatrix.getPos()+direc*(vect.x+vect.y+vect.z));
00281 }
00282 }
00283 }
00284
00285
00286
00287 _X=mouseEvent->X;
00288 _Y=mouseEvent->Y;
00289 }
00290 else if (event==EventMouseDownId)
00291 {
00292
00293 _X=mouseEvent->X;
00294 _Y=mouseEvent->Y;
00295 }
00296 else if (event==EventMouseUpId)
00297 {
00298
00299 _X=mouseEvent->X;
00300 _Y=mouseEvent->Y;
00301 }
00302 else if (event==EventMouseWheelId)
00303 {
00304
00305 CEventMouseWheel* mouseEvent=(CEventMouseWheel*)&event;
00306
00307 CVector direc=_HotSpot-_Matrix.getPos();
00308 if (! _EnableModelMatrixEdition)
00309 {
00310 _Matrix.setPos(_Matrix.getPos()+direc*(mouseEvent->Direction?0.1f:-0.1f));
00311 }
00312 else
00313 {
00314 CVector dir = direc*(mouseEvent->Direction?0.1f:-0.1f) ;
00315
00316 dir= _ModelMatrixTransformMove * dir;
00317 truncateVect(dir) ;
00318 _ModelMatrix.setPos(_ModelMatrix.getPos() + dir);
00319 }
00320 }
00321 }
00322
00323 void CEvent3dMouseListener::addToServer (CEventServer& server)
00324 {
00325 server.addListener (EventMouseMoveId, this);
00326 server.addListener (EventMouseDownId, this);
00327 server.addListener (EventMouseUpId, this);
00328 server.addListener (EventMouseWheelId, this);
00329 _AsyncListener.addToServer (server);
00330 }
00331
00332 void CEvent3dMouseListener::removeFromServer (CEventServer& server)
00333 {
00334 server.removeListener (EventMouseMoveId, this);
00335 server.removeListener (EventMouseDownId, this);
00336 server.removeListener (EventMouseUpId, this);
00337 server.removeListener (EventMouseWheelId, this);
00338 _AsyncListener.removeFromServer (server);
00339 }
00340
00341 const NLMISC::CMatrix& CEvent3dMouseListener::getViewMatrix ()
00342 {
00343
00344 if (_MouseMode==firstPerson)
00345 {
00346
00347 CVector dir (0,0,0);
00348 bool find=false;
00349
00350
00351 if (_AsyncListener.isKeyDown (KeyUP))
00352 {
00353 dir+=CVector (0, 1, 0);
00354 find=true;
00355 }
00356 if (_AsyncListener.isKeyDown (KeyDOWN))
00357 {
00358 dir+=CVector (0, -1, 0);
00359 find=true;
00360 }
00361 if (_AsyncListener.isKeyDown (KeyRIGHT))
00362 {
00363 dir+=CVector (1, 0, 0);
00364 find=true;
00365 }
00366 if (_AsyncListener.isKeyDown (KeyLEFT))
00367 {
00368 dir+=CVector (-1, 0, 0);
00369 find=true;
00370 }
00371 if (_AsyncListener.isKeyDown (KeyNEXT))
00372 {
00373 dir+=CVector (0, 0, -1);
00374 find=true;
00375 }
00376 if (_AsyncListener.isKeyDown (KeyPRIOR))
00377 {
00378 dir+=CVector (0, 0, 1);
00379 find=true;
00380 }
00381
00382
00383 if (find)
00384 {
00385
00386 uint32 milli=(uint32)(CTime::getLocalTime ()-_LastTime);
00387
00388
00389 float dPos=_Speed*(float)milli/1000.f;
00390
00391
00392 dir.normalize ();
00393 dir*=dPos;
00394
00395
00396 dir=_Matrix.mulVector (dir);
00397
00398
00399 _Matrix.setPos (_Matrix.getPos ()+dir);
00400 }
00401 }
00402
00403
00404 _LastTime=CTime::getLocalTime ();
00405
00406
00407
00408 return _Matrix;
00409 }
00410
00411
00412 void CEvent3dMouseListener::enableTranslateXYInWorld(bool enabled)
00413 {
00414 _TranslateXYInWorld= enabled;
00415 }
00416
00417 void CEvent3dMouseListener::setModelMatrixTransformMove(const NLMISC::CMatrix& transModelMove)
00418 {
00419 _ModelMatrixTransformMove= transModelMove;
00420 }
00421
00422 void CEvent3dMouseListener::getModelMatrixTransformMove(NLMISC::CMatrix& transModelMove) const
00423 {
00424 transModelMove= _ModelMatrixTransformMove;
00425 }
00426
00427
00428 };