You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
5.4 KiB
C++

#pragma once
#include <osgGA/TrackballManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgViewer/GraphicsWindow>
#include <osg/ComputeBoundsVisitor>
#include <osgViewer/Viewer>
#include <windows.h>
//操作器切换管理器
class CXJManipulator : public osgGA::KeySwitchMatrixManipulator
{
public:
CXJManipulator()
{
m_mode = 1;
m_bEnable = true;
}
void SetMode(int mode){m_mode = mode;}
int GetMode(){return m_mode;}
void SetManipulatorEnable(bool enable) {m_bEnable = enable;}
private:
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
{
osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>( &us );
if(m_bEnable == true)
{
//if(m_mode == 0)
return osgGA::KeySwitchMatrixManipulator::handle(ea,us);
//else if(m_mode == 1)
//{
// if(ea.getEventType() == osgGA::GUIEventAdapter::SCROLL //滚轮
// ||(ea.getButtonMask() == 2 &&
// ea.getEventType() == osgGA::GUIEventAdapter::DRAG ||
// ea.getEventType() == osgGA::GUIEventAdapter::PUSH ||
// ea.getEventType() == osgGA::GUIEventAdapter::MOVE)
// )
// {
// return osgGA::KeySwitchMatrixManipulator::handle(ea,us);
// }
// else
// return true;
//}
}
return true;
}
private:
int m_mode;//0 的行为和KeySwitchMatrixManipulator一样 //1 只支持滚动进行放大缩小,不支持旋转
bool m_bEnable; //操作器是否失效
};
class CXJTrackballManipulator : public osgGA::TrackballManipulator
{
public:
CXJTrackballManipulator( int flags = DEFAULT_SETTINGS);
CXJTrackballManipulator(const CXJTrackballManipulator& tm,
const osg::CopyOp& copyOp = osg::CopyOp::SHALLOW_COPY );
META_Object( osgGA, CXJTrackballManipulator );
void setGraphicWindow(osgViewer::GraphicsWindow* pWin32) {m_window32 = pWin32;}
//void setHwnd(void* hwnd) {m_hWnd = hwnd;}
//设置绕轴旋转时的固定轴
void SetVerticeAxis(const osg::Vec3& axis) {m_localUp = axis;}
protected:
virtual bool handleFrame(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool handleMouseDrag(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool performMovement();
virtual bool handleMouseRelease(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool handleMouseWheel(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool handleKeyDown(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool handleKeyUp(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool performMovementLeftMouseButton(const double eventTimeDelta, const double dx, const double dy);
virtual bool performRotateMiddleMouseButton(const double eventTimeDelta, const double dx, const double dy);
virtual bool performPanMiddleMouseButton(const double eventTimeDelta, const double dx, const double dy);
virtual bool performMovementRightMouseButton(const double eventTimeDelta, const double dx, const double dy);
virtual void rotateTrackball( const float px0, const float py0,
const float px1, const float py1, const float scale );
virtual void rotateWithFixedVertical( const float dx, const float dy );
static void rotateYawPitch( osg::Quat& rotation, const double yaw, const double pitch,
const osg::Vec3d& localUp = osg::Vec3d( 0.,0.,0.) );
void zoomView(float x, float y, float dy);
/** Compute the home position.*/
virtual void computeHomePosition(const osg::Camera *camera = NULL, bool useBoundingBox = false)
{
if (getNode())
{
osg::BoundingSphere boundingSphere;
OSG_INFO<<" CameraManipulator::computeHomePosition("<<camera<<", "<<useBoundingBox<<")"<<std::endl;
if (useBoundingBox)
{
// compute bounding box
// (bounding box computes model center more precisely than bounding sphere)
osg::ComputeBoundsVisitor cbVisitor;
getNode()->accept(cbVisitor);
osg::BoundingBox &bb = cbVisitor.getBoundingBox();
if (bb.valid()) boundingSphere.expandBy(bb);
else boundingSphere = getNode()->getBound();
}
else
{
// compute bounding sphere
boundingSphere = getNode()->getBound();
}
/*OSG_INFO<<" boundingSphere.center() = ("<<boundingSphere.center()<<")"<<std::endl;
OSG_INFO<<" boundingSphere.radius() = "<<boundingSphere.radius()<<std::endl;*/
// set dist to default
double dist = 3.5f * boundingSphere.radius();
if (camera)
{
// try to compute dist from frustrum
double left,right,bottom,top,zNear,zFar;
if (camera->getProjectionMatrixAsFrustum(left,right,bottom,top,zNear,zFar))
{
double vertical2 = fabs(right - left) / zNear / 2.;
double horizontal2 = fabs(top - bottom) / zNear / 2.;
double dim = horizontal2 < vertical2 ? horizontal2 : vertical2;
double viewAngle = atan2(dim,1.);
dist = boundingSphere.radius() / sin(viewAngle);
}
else
{
// try to compute dist from ortho
if (camera->getProjectionMatrixAsOrtho(left,right,bottom,top,zNear,zFar))
{
dist = fabs(zFar - zNear) / 2.;
}
}
}
// set home position
/*setHomePosition(boundingSphere.center() + osg::Vec3d(0.0,-dist,0.0f),
boundingSphere.center(),
osg::Vec3d(0.0f,0.0f,1.0f),
_autoComputeHomePosition);*/
setHomePosition(osg::Vec3(0.0f, -20.0f, 0.0f),
osg::Vec3(0.0f, 0.0f, 0.0f),
osg::Vec3(0.0f, 0.0f, 1.0f));
}
}
private:
osg::Camera* m_masterCamera;
osg::Vec3 m_localUp;
osgViewer::GraphicsWindow* m_window32;
bool m_spaceDown;
//void* m_hWnd;
};