/* ============ Matrix3::ToCQuat ============ */ CQuat Matrix3::ToCQuat( void ) const { idQuat q = ToQuat(); if ( q.w < 0.0f ) { return CQuat( -q.x, -q.y, -q.z ); } return CQuat( q.x, q.y, q.z ); }
void CEvent3dMouseListener::operator ()(const CEvent& event) { CEventMouse* mouseEvent=(CEventMouse*)&event; if (event==EventMouseMoveId) { bool bRotate=false; bool bTranslateXY=false; bool bTranslateZ=false; bool bZoom=false; // Rotate Axis CVector axis; if (_MouseMode==nelStyle) { bRotate=(mouseEvent->Button==(ctrlButton|rightButton)); bTranslateXY=(mouseEvent->Button==(ctrlButton|leftButton)); bTranslateZ=(mouseEvent->Button==(ctrlButton|shiftButton|leftButton)); bZoom=(mouseEvent->Button==(altButton|leftButton)); axis=_HotSpot; } else if (_MouseMode==edit3d) { bRotate=(mouseEvent->Button==(altButton|middleButton)) || (mouseEvent->Button==(altButton|leftButton)); bTranslateXY=(mouseEvent->Button==(ctrlButton|leftButton)) || (mouseEvent->Button==middleButton); bTranslateZ=(mouseEvent->Button==(ctrlButton|shiftButton|leftButton)) || (mouseEvent->Button==(ctrlButton|middleButton)); bZoom=(mouseEvent->Button==(shiftButton|leftButton)) || (mouseEvent->Button==(ctrlButton|altButton|middleButton)); axis=_HotSpot; } else // if (_MouseMode==firstPerson) { bRotate=(mouseEvent->Button&leftButton)!=0; bTranslateXY=false; bTranslateZ=false; bZoom=false; axis=_Matrix.getPos(); } if (bRotate) { if (!_EnableModelMatrixEdition) { // First in the hotSpot CMatrix comeFromHotSpot=_Matrix; comeFromHotSpot.setPos (axis); // Then turn along the Z axis with X mouse CMatrix turnZ; turnZ.identity(); turnZ.rotateZ ((float) Pi*2.f*(_X-mouseEvent->X)); // Then turn along the X axis with Y mouse CMatrix turnX; turnX.identity(); turnX.rotateX ((float) Pi*2.f*(mouseEvent->Y-_Y)); // Then come back from hotspot CMatrix goToHotSpot=comeFromHotSpot; goToHotSpot.invert(); // Make the matrix CMatrix negPivot, Pivot; negPivot.identity(); negPivot.setPos (-axis); Pivot.identity(); Pivot.setPos (axis); // Make this transformation \\// //_Matrix=Pivot*turnZ*negPivot*comeFromHotSpot*turnX*goToHotSpot*_Matrix; Pivot*=turnZ; Pivot*=negPivot; Pivot*=comeFromHotSpot; Pivot*=turnX; Pivot*=goToHotSpot; Pivot*=_Matrix; _Matrix=Pivot; // Normalize, too much transformation could give an ugly matrix.. _Matrix.normalize (CMatrix::XYZ); } else { CVector pos = _ModelMatrix.getPos() ; NLMISC::CQuat r ; switch (_CurrentModelRotationAxis) { case xAxis : r = CQuat(CAngleAxis(_ModelMatrix.getI(), (float) Pi*2.f*(_X-mouseEvent->X))) ; break ; case yAxis : r = CQuat(CAngleAxis(_ModelMatrix.getJ(), (float) Pi*2.f*(_X-mouseEvent->X))) ; break ; case zAxis : r = CQuat(CAngleAxis(_ModelMatrix.getK(), (float) Pi*2.f*(_X-mouseEvent->X))) ; break ; } ; CMatrix rm ; rm.rotate(r) ; _ModelMatrix = rm * _ModelMatrix ; _ModelMatrix.setPos(pos) ; _ModelMatrix.normalize (CMatrix::XYZ); } } if (bTranslateXY||bTranslateZ||bZoom) { // Move in plane CPlane plane; // For precision problem, do all the compute local to the hotspot/model. CVector decal; // Plane of the hotspot if (! _EnableModelMatrixEdition) { decal= axis; } else { decal= _ModelMatrix.getPos(); } // Choose plane to move on if (bTranslateXY && _TranslateXYInWorld) { plane.make (CVector::K, CVector::Null); } else { plane.make (_Matrix.getJ(), CVector::Null); } // Get ray from mouse point CMatrix localViewMatrix= _Matrix; localViewMatrix.setPos(_Matrix.getPos() - decal); CVector localPoint1, localPoint2; CVector pos, dir; _Viewport.getRayWithPoint (_X, _Y, pos, dir, localViewMatrix, _Frustrum); localPoint1=plane.intersect (pos, pos+dir); _Viewport.getRayWithPoint (mouseEvent->X, mouseEvent->Y, pos, dir, localViewMatrix, _Frustrum); localPoint2=plane.intersect (pos, pos+dir); // Move the camera if (bTranslateXY) { if (! _EnableModelMatrixEdition) { _Matrix.setPos(_Matrix.getPos()+localPoint1-localPoint2); } else { CVector dir = - localPoint1 + localPoint2 ; // transform the translation as needed. dir= _ModelMatrixTransformMove * dir; truncateVect(dir) ; _ModelMatrix.setPos(_ModelMatrix.getPos()+dir); } } else if (bTranslateZ) { CVector vect=localPoint1-localPoint2; if (! _EnableModelMatrixEdition) { _Matrix.setPos(_Matrix.getPos()+_Matrix.getK()*(vect.x+vect.y+vect.z)); } else { CVector dir = _Matrix.getK()*(vect.x+vect.y+vect.z) ; // transform the translation as needed. dir= _ModelMatrixTransformMove * dir; truncateVect(dir) ; _ModelMatrix.setPos(_ModelMatrix.getPos()+dir); } } else if (bZoom) { CVector vect=localPoint1-localPoint2; CVector direc=axis-_Matrix.getPos(); direc.normalize(); if (! _EnableModelMatrixEdition) { _Matrix.setPos(_Matrix.getPos()+direc*(vect.x+vect.y+vect.z)); } else { // transform the translation as needed. direc= _ModelMatrixTransformMove * direc; direc.normalize(); _ModelMatrix.setPos(_ModelMatrix.getPos()+direc*(vect.x+vect.y+vect.z)); } } } // Update mouse position _X=mouseEvent->X; _Y=mouseEvent->Y; } else if (event==EventMouseDownId) { // Update mouse position _X=mouseEvent->X; _Y=mouseEvent->Y; } else if (event==EventMouseUpId) { // Update mouse position _X=mouseEvent->X; _Y=mouseEvent->Y; } else if (event==EventMouseWheelId) { // Zoom.. CEventMouseWheel* mouseEvent=(CEventMouseWheel*)&event; CVector direc=_HotSpot-_Matrix.getPos(); if (! _EnableModelMatrixEdition) { _Matrix.setPos(_Matrix.getPos()+direc*(mouseEvent->Direction?0.1f:-0.1f)); } else { CVector dir = direc*(mouseEvent->Direction?0.1f:-0.1f) ; // transform the translation as needed. dir= _ModelMatrixTransformMove * dir; truncateVect(dir) ; _ModelMatrix.setPos(_ModelMatrix.getPos() + dir); } } }
/* ===================== idQuat::ToCQuat ===================== */ CQuat idQuat::ToCQuat( void ) const { if ( w < 0.0f ) { return CQuat( -x, -y, -z ); } return CQuat( x, y, z ); }