Пример #1
0
/*
============
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 );
}
Пример #2
0
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);
		}
	}
}
Пример #3
0
/*
=====================
idQuat::ToCQuat
=====================
*/
CQuat idQuat::ToCQuat( void ) const {
	if ( w < 0.0f ) {
		return CQuat( -x, -y, -z );
	}
	return CQuat( x, y, z );
}