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++
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;
|
|
};
|
|
|