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