DYTSrouce/src/viewer/CameraControlManipulator.h
2025-01-04 12:12:51 +08:00

277 lines
7.5 KiB
C++

#pragma once
#include <osgGA/CameraManipulator>
#include <osg/Quat>
#include <osg/ObserverNodePath>
#include <osg/Vec3d>
#include <osg/Quat>
#include <QMap>
#include <osg/AnimationPath>
#include <QString>
struct EyeViewport {
double time;
osg::Quat rotation;
osg::Vec3d eye;
QString strTxt;
QString strAudio;
bool bUsed;
EyeViewport() {
time = 0.0;
bUsed = false;
strTxt = "";
strAudio = "";
}
};
class CameraControlManipulator : public osgGA::CameraManipulator {
public:
CameraControlManipulator();
//-------------------------------------------------------------------------------------------------
virtual const char* className() const {
return "CameraControl";
}
/** set the position of the matrix manipulator using a 4x4 Matrix.*/
virtual void setByMatrix(const osg::Matrixd& matrix);
/** set the position of the matrix manipulator using a 4x4 Matrix.*/
virtual void setByInverseMatrix(const osg::Matrixd& matrix) {
setByMatrix(osg::Matrixd::inverse(matrix));
}
/** Get the position of the manipulator as 4x4 Matrix.*/
virtual osg::Matrixd getMatrix() const;
/** Get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
virtual osg::Matrixd getInverseMatrix() const;
/** Start/restart the manipulator.*/
virtual void init(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
//----------------------------------------------------------------------------------------------------------
void setTrackNodePath(const osg::NodePath& nodePath);
void setTrackNodePath(const osg::ObserverNodePath& nodePath) {
_trackNodePath = nodePath;
}
osg::ObserverNodePath& getTrackNodePath() {
return _trackNodePath;
}
void setTrackNode(osg::Node* node);
osg::Node* getTrackNode() {
osg::NodePath nodePath;
return _trackNodePath.getNodePath(nodePath) && !nodePath.empty() ? nodePath.back() : 0;
}
const osg::Node* getTrackNode() const {
osg::NodePath nodePath;
return _trackNodePath.getNodePath(nodePath) && !nodePath.empty() ? nodePath.back() : 0;
}
enum TrackerMode {
NODE_CENTER,
NODE_CENTER_AND_AZIM,
NODE_CENTER_AND_ROTATION
};
void setTrackerMode(TrackerMode mode);
TrackerMode getTrackerMode() const {
return _trackerMode;
}
enum ManipulatorMode {
Camera_ManipulatorMode,
Tracker_ManipulatorMode,
Roam_ManipulatorMode,
Model_ManipulatorMode
};
void setManipulatorMode(ManipulatorMode mode);
ManipulatorMode getManipulatorMode() const {
return _manipulatorMode;
}
enum ProjMode {
Proj_Perspective,
Proj_Ortho
};
void setProjMode(ProjMode mode) {
_projMode = mode;
}
ProjMode getProjMode() {
return _projMode;
}
void setDistance(float distance);
float getDistance() const {
return _distance;
}
void setCameraPos(osg::Vec3d pos);
void setCameraDeltaPos(osg::Vec3d pos);
void setCameraIniRot(double yaw, double pitch, double roll, bool bOgl = false);
void setCameraIniRot(osg::Quat quat);
void setRoamCamera(const osg::Vec3& eye, const osg::Vec3& center, const osg::Vec3& up);
virtual void setMinimumDistance(float minimumDistance) {
_minimumDistance = minimumDistance;
}
float getMinimumDistance() const {
return _minimumDistance;
}
void setVerticalAxisFixed(bool value);
void SetCameraSenario(EyeViewport eyeViewport);
protected:
~CameraControlManipulator(void);
void computeNodeWorldToLocal(osg::Matrixd& worldToLocal) const;
void computeNodeLocalToWorld(osg::Matrixd& localToWorld) const;
void computeNodeCenterAndRotation(osg::Vec3d& center, osg::Quat& rotation) const;
/** Reset the internal GUIEvent stack.*/
void flushMouseEventStack();
/** Add the current mouse GUIEvent to internal stack.*/
void addMouseEvent(const osgGA::GUIEventAdapter& ea);
/** For the give mouse movement calculate the movement of the camera.
Return true is camera has moved and a redraw is required.*/
bool calcMovement();
/** Check the speed at which the mouse is moving.
If speed is below a threshold then return false, otherwise return true.*/
bool isMouseMoving();
//---------------------------------------------------------
void trackball(osg::Vec3& axis, double& angle, double p1x, double p1y, double p2x, double p2y);
double tb_project_to_sphere(double r, double x, double y);
//--------------------------------------------------------
virtual bool handleFrame(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool handleResize(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool handleMouseMove(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool handleMouseDrag(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool handleMousePush(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool handleMouseRelease(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 handleMouseWheel(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
virtual bool handleMouseDeltaMovement(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
bool getVerticalAxisFixed() const;
void fixVerticalAxis(osg::Vec3d& eye, osg::Quat& rotation, bool disallowFlipOver);
void fixVerticalAxis(osg::Quat& rotation, const osg::Vec3d& localUp, bool disallowFlipOver);
/** Set the 'allow throw' flag. Releasing the mouse button while moving the camera results in a throw. */
void setAllowThrow(bool allowThrow) {
_allowThrow = allowThrow;
}
/** Returns true if the camera can be thrown, false otherwise. This defaults to true. */
bool getAllowThrow() const {
return _allowThrow;
}
void rotateYawPitch(osg::Quat& rotation, const double yaw, const double pitch,
const osg::Vec3d& localUp);
float getThrowScale(const double eventTimeDelta) const;
void panModel(const float dx, const float dy, const float dz = 0.0);
void zoomModel(const float dy, bool pushForwardIfNeeded);
protected:
osg::Vec3d _eye;
osg::ObserverNodePath _trackNodePath;
TrackerMode _trackerMode;
ManipulatorMode _manipulatorMode;
ProjMode _projMode;
osg::Quat _nodeRotation;
osg::Quat _rotation;
float _distance;
osg::Vec3d _center;
double _trackballSize{ 0.0 };
double _wheelZoomFactor{ 0.0 };
bool _verticalAxisFixed{ false };
double _minimumDistance;
// Internal event stack comprising last two mouse events.
osg::ref_ptr<const osgGA::GUIEventAdapter> _ga_t1;
osg::ref_ptr<const osgGA::GUIEventAdapter> _ga_t0;
double _yawDegIni;
double _pitchDegIni;
double _rollDegIni;
double _yawDegTemp;
double _pitchDegTemp;
double _rollDegTemp;
osg::Vec3 _cameraHPR;
double _adjustValue;
bool _allowThrow;
bool _thrown;
float _zoomDelta;
bool _isMove;
double _moveFactor;
double _rotFactor;
double _delta_frame_time;
double _last_frame_time;
bool _isEyeAnimation;
double _time_Animation;
double _curr_time_Animation;
osg::AnimationPath::ControlPoint _firstCP_Animation;
osg::AnimationPath::ControlPoint _secondCP_Animation;
osg::Vec3d _cameraDelta;
osg::ref_ptr<osgGA::GUIEventAdapter::TouchData> _lastTouchData;
bool _bKeyDownUp;
bool _bKeyDownDown;
bool _bKeyDownLeft;
bool _bKeyDownRight;
};