mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 08:53:52 +00:00
Merge remote-tracking branch 'aesylwinn/editor_camera'
This commit is contained in:
commit
60509875e8
17 changed files with 1305 additions and 582 deletions
|
@ -86,11 +86,12 @@ opencs_units (view/widget
|
|||
opencs_units (view/render
|
||||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
||||
orbitcameramode
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/render
|
||||
lighting lightingday lightingnight
|
||||
lightingbright object cell terrainstorage tagbase cellarrow cellmarker cellborder
|
||||
lighting lightingday lightingnight lightingbright object cell terrainstorage tagbase
|
||||
cellarrow cellmarker cellborder cameracontroller
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (view/render
|
||||
|
|
|
@ -15,10 +15,16 @@
|
|||
CSMPrefs::DoubleSetting::DoubleSetting (Category *parent, Settings::Manager *values,
|
||||
QMutex *mutex, const std::string& key, const std::string& label, double default_)
|
||||
: Setting (parent, values, mutex, key, label),
|
||||
mMin (0), mMax (std::numeric_limits<double>::max()),
|
||||
mPrecision(2), mMin (0), mMax (std::numeric_limits<double>::max()),
|
||||
mDefault (default_)
|
||||
{}
|
||||
|
||||
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setPrecision(int precision)
|
||||
{
|
||||
mPrecision = precision;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setRange (double min, double max)
|
||||
{
|
||||
mMin = min;
|
||||
|
@ -49,6 +55,7 @@ std::pair<QWidget *, QWidget *> CSMPrefs::DoubleSetting::makeWidgets (QWidget *p
|
|||
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
|
||||
|
||||
QDoubleSpinBox *widget = new QDoubleSpinBox (parent);
|
||||
widget->setDecimals(mPrecision);
|
||||
widget->setRange (mMin, mMax);
|
||||
widget->setValue (mDefault);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace CSMPrefs
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
int mPrecision;
|
||||
double mMin;
|
||||
double mMax;
|
||||
std::string mTooltip;
|
||||
|
@ -20,6 +21,8 @@ namespace CSMPrefs
|
|||
QMutex *mutex, const std::string& key, const std::string& label,
|
||||
double default_);
|
||||
|
||||
DoubleSetting& setPrecision (int precision);
|
||||
|
||||
// defaults to [0, std::numeric_limits<double>::max()]
|
||||
DoubleSetting& setRange (double min, double max);
|
||||
|
||||
|
|
|
@ -172,6 +172,17 @@ void CSMPrefs::State::declare()
|
|||
inputButtons.add (left).add (cLeft).add (right).add (cRight).add (middle).add (cMiddle);
|
||||
declareEnum ("p-navi", "Primary Camera Navigation Button", left).addValues (inputButtons);
|
||||
declareEnum ("s-navi", "Secondary Camera Navigation Button", cLeft).addValues (inputButtons);
|
||||
declareDouble ("p-navi-free-sensitivity", "Free Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0);
|
||||
declareBool ("p-navi-free-invert", "Invert Free Camera Mouse Input", false);
|
||||
declareDouble ("p-navi-orbit-sensitivity", "Orbit Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0);
|
||||
declareBool ("p-navi-orbit-invert", "Invert Orbit Camera Mouse Input", false);
|
||||
declareDouble ("s-navi-sensitivity", "Secondary Camera Movement Sensitivity", 50.0).setRange(-1000.0, 1000.0);
|
||||
declareDouble ("navi-wheel-factor", "Camera Zoom Sensitivity", 8).setRange(-100.0, 100.0);
|
||||
declareDouble ("navi-free-lin-speed", "Free Camera Linear Speed", 1000.0).setRange(1.0, 10000.0);
|
||||
declareDouble ("navi-free-rot-speed", "Free Camera Rotational Speed", 3.14 / 2).setRange(0.001, 6.28);
|
||||
declareDouble ("navi-free-speed-mult", "Free Camera Speed Multiplier (from Modifier)", 8).setRange(0.001, 1000.0);
|
||||
declareDouble ("navi-orbit-rot-speed", "Orbital Camera Rotational Speed", 3.14 / 4).setRange(0.001, 6.28);
|
||||
declareDouble ("navi-orbit-speed-mult", "Orbital Camera Speed Multiplier (from Modifier)", 4).setRange(0.001, 1000.0);
|
||||
declareEnum ("p-edit", "Primary Editing Button", right).addValues (inputButtons);
|
||||
declareEnum ("s-edit", "Secondary Editing Button", cRight).addValues (inputButtons);
|
||||
declareEnum ("p-select", "Primary Selection Button", middle).addValues (inputButtons);
|
||||
|
|
628
apps/opencs/view/render/cameracontroller.cpp
Normal file
628
apps/opencs/view/render/cameracontroller.cpp
Normal file
|
@ -0,0 +1,628 @@
|
|||
#include "cameracontroller.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include <osg/BoundingBox>
|
||||
#include <osg/Camera>
|
||||
#include <osg/ComputeBoundsVisitor>
|
||||
#include <osg/Drawable>
|
||||
#include <osg/Group>
|
||||
#include <osg/Matrixd>
|
||||
#include <osg/Quat>
|
||||
|
||||
#include <osgUtil/LineSegmentIntersector>
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
|
||||
/*
|
||||
Camera Controller
|
||||
*/
|
||||
|
||||
const osg::Vec3d CameraController::WorldUp = osg::Vec3d(0, 0, 1);
|
||||
|
||||
const osg::Vec3d CameraController::LocalUp = osg::Vec3d(0, 1, 0);
|
||||
const osg::Vec3d CameraController::LocalLeft = osg::Vec3d(1, 0, 0);
|
||||
const osg::Vec3d CameraController::LocalForward = osg::Vec3d(0, 0, 1);
|
||||
|
||||
CameraController::CameraController()
|
||||
: mActive(false)
|
||||
, mInverted(false)
|
||||
, mCameraSensitivity(1/650.f)
|
||||
, mSecondaryMoveMult(50)
|
||||
, mWheelMoveMult(8)
|
||||
, mCamera(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CameraController::~CameraController()
|
||||
{
|
||||
}
|
||||
|
||||
bool CameraController::isActive() const
|
||||
{
|
||||
return mActive;
|
||||
}
|
||||
|
||||
osg::Camera* CameraController::getCamera() const
|
||||
{
|
||||
return mCamera;
|
||||
}
|
||||
|
||||
double CameraController::getCameraSensitivity() const
|
||||
{
|
||||
return mCameraSensitivity;
|
||||
}
|
||||
|
||||
bool CameraController::getInverted() const
|
||||
{
|
||||
return mInverted;
|
||||
}
|
||||
|
||||
double CameraController::getSecondaryMovementMultiplier() const
|
||||
{
|
||||
return mSecondaryMoveMult;
|
||||
}
|
||||
|
||||
double CameraController::getWheelMovementMultiplier() const
|
||||
{
|
||||
return mWheelMoveMult;
|
||||
}
|
||||
|
||||
void CameraController::setCamera(osg::Camera* camera)
|
||||
{
|
||||
mCamera = camera;
|
||||
mActive = (mCamera != NULL);
|
||||
|
||||
if (mActive)
|
||||
onActivate();
|
||||
}
|
||||
|
||||
void CameraController::setCameraSensitivity(double value)
|
||||
{
|
||||
mCameraSensitivity = value;
|
||||
}
|
||||
|
||||
void CameraController::setInverted(bool value)
|
||||
{
|
||||
mInverted = value;
|
||||
}
|
||||
|
||||
void CameraController::setSecondaryMovementMultiplier(double value)
|
||||
{
|
||||
mSecondaryMoveMult = value;
|
||||
}
|
||||
|
||||
void CameraController::setWheelMovementMultiplier(double value)
|
||||
{
|
||||
mWheelMoveMult = value;
|
||||
}
|
||||
|
||||
void CameraController::setup(osg::Group* root, unsigned int mask, const osg::Vec3d& up)
|
||||
{
|
||||
// Find World bounds
|
||||
osg::ComputeBoundsVisitor boundsVisitor;
|
||||
osg::BoundingBox& boundingBox = boundsVisitor.getBoundingBox();
|
||||
|
||||
boundsVisitor.setTraversalMask(mask);
|
||||
root->accept(boundsVisitor);
|
||||
|
||||
if (!boundingBox.valid())
|
||||
{
|
||||
// Try again without any mask
|
||||
boundsVisitor.reset();
|
||||
boundsVisitor.setTraversalMask(~0);
|
||||
root->accept(boundsVisitor);
|
||||
|
||||
// Last resort, set a default
|
||||
if (!boundingBox.valid())
|
||||
{
|
||||
boundingBox.set(-1, -1, -1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate a good starting position
|
||||
osg::Vec3d minBounds = boundingBox.corner(0) - boundingBox.center();
|
||||
osg::Vec3d maxBounds = boundingBox.corner(7) - boundingBox.center();
|
||||
|
||||
osg::Vec3d camOffset = up * maxBounds > 0 ? maxBounds : minBounds;
|
||||
camOffset *= 2;
|
||||
|
||||
osg::Vec3d eye = camOffset + boundingBox.center();
|
||||
osg::Vec3d center = boundingBox.center();
|
||||
|
||||
getCamera()->setViewMatrixAsLookAt(eye, center, up);
|
||||
}
|
||||
|
||||
/*
|
||||
Free Camera Controller
|
||||
*/
|
||||
|
||||
FreeCameraController::FreeCameraController()
|
||||
: mLockUpright(false)
|
||||
, mModified(false)
|
||||
, mFast(false)
|
||||
, mLeft(false)
|
||||
, mRight(false)
|
||||
, mForward(false)
|
||||
, mBackward(false)
|
||||
, mRollLeft(false)
|
||||
, mRollRight(false)
|
||||
, mUp(LocalUp)
|
||||
, mLinSpeed(1000)
|
||||
, mRotSpeed(osg::PI / 2)
|
||||
, mSpeedMult(8)
|
||||
{
|
||||
}
|
||||
|
||||
double FreeCameraController::getLinearSpeed() const
|
||||
{
|
||||
return mLinSpeed;
|
||||
}
|
||||
|
||||
double FreeCameraController::getRotationalSpeed() const
|
||||
{
|
||||
return mRotSpeed;
|
||||
}
|
||||
|
||||
double FreeCameraController::getSpeedMultiplier() const
|
||||
{
|
||||
return mSpeedMult;
|
||||
}
|
||||
|
||||
void FreeCameraController::setLinearSpeed(double value)
|
||||
{
|
||||
mLinSpeed = value;
|
||||
}
|
||||
|
||||
void FreeCameraController::setRotationalSpeed(double value)
|
||||
{
|
||||
mRotSpeed = value;
|
||||
}
|
||||
|
||||
void FreeCameraController::setSpeedMultiplier(double value)
|
||||
{
|
||||
mSpeedMult = value;
|
||||
}
|
||||
|
||||
void FreeCameraController::fixUpAxis(const osg::Vec3d& up)
|
||||
{
|
||||
mLockUpright = true;
|
||||
mUp = up;
|
||||
mModified = true;
|
||||
}
|
||||
|
||||
void FreeCameraController::unfixUpAxis()
|
||||
{
|
||||
mLockUpright = false;
|
||||
}
|
||||
|
||||
bool FreeCameraController::handleKeyEvent(QKeyEvent* event, bool pressed)
|
||||
{
|
||||
if (!isActive())
|
||||
return false;
|
||||
|
||||
if (event->key() == Qt::Key_Q)
|
||||
{
|
||||
mRollLeft = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_E)
|
||||
{
|
||||
mRollRight = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_A)
|
||||
{
|
||||
mLeft = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_D)
|
||||
{
|
||||
mRight = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_W)
|
||||
{
|
||||
mForward = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_S)
|
||||
{
|
||||
mBackward = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_Shift)
|
||||
{
|
||||
mFast = pressed;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FreeCameraController::handleMouseMoveEvent(std::string mode, int x, int y)
|
||||
{
|
||||
if (!isActive())
|
||||
return false;
|
||||
|
||||
if (mode == "p-navi")
|
||||
{
|
||||
double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0);
|
||||
yaw(x * scalar);
|
||||
pitch(y * scalar);
|
||||
}
|
||||
else if (mode == "s-navi")
|
||||
{
|
||||
osg::Vec3d movement;
|
||||
movement += LocalLeft * -x * getSecondaryMovementMultiplier();
|
||||
movement += LocalUp * y * getSecondaryMovementMultiplier();
|
||||
|
||||
translate(movement);
|
||||
}
|
||||
else if (mode == "t-navi")
|
||||
{
|
||||
translate(LocalForward * x * (mFast ? getWheelMovementMultiplier() : 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreeCameraController::update(double dt)
|
||||
{
|
||||
if (!isActive())
|
||||
return;
|
||||
|
||||
double linDist = mLinSpeed * dt;
|
||||
double rotDist = mRotSpeed * dt;
|
||||
|
||||
if (mFast)
|
||||
linDist *= mSpeedMult;
|
||||
|
||||
if (mLeft)
|
||||
translate(LocalLeft * linDist);
|
||||
if (mRight)
|
||||
translate(LocalLeft * -linDist);
|
||||
if (mForward)
|
||||
translate(LocalForward * linDist);
|
||||
if (mBackward)
|
||||
translate(LocalForward * -linDist);
|
||||
|
||||
if (!mLockUpright)
|
||||
{
|
||||
if (mRollLeft)
|
||||
roll(-rotDist);
|
||||
if (mRollRight)
|
||||
roll(rotDist);
|
||||
}
|
||||
else if(mModified)
|
||||
{
|
||||
stabilize();
|
||||
mModified = false;
|
||||
}
|
||||
|
||||
// Normalize the matrix to counter drift
|
||||
getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix());
|
||||
}
|
||||
|
||||
void FreeCameraController::yaw(double value)
|
||||
{
|
||||
getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalUp);
|
||||
mModified = true;
|
||||
}
|
||||
|
||||
void FreeCameraController::pitch(double value)
|
||||
{
|
||||
const double Constraint = osg::PI / 2 - 0.1;
|
||||
|
||||
if (mLockUpright)
|
||||
{
|
||||
osg::Vec3d eye, center, up;
|
||||
getCamera()->getViewMatrixAsLookAt(eye, center, up);
|
||||
|
||||
osg::Vec3d forward = center - eye;
|
||||
osg::Vec3d left = up ^ forward;
|
||||
|
||||
double pitchAngle = std::acos(up * mUp);
|
||||
if ((mUp ^ up) * left < 0)
|
||||
pitchAngle *= -1;
|
||||
|
||||
if (std::abs(pitchAngle + value) > Constraint)
|
||||
value = (pitchAngle > 0 ? 1 : -1) * Constraint - pitchAngle;
|
||||
}
|
||||
|
||||
getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalLeft);
|
||||
mModified = true;
|
||||
}
|
||||
|
||||
void FreeCameraController::roll(double value)
|
||||
{
|
||||
getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalForward);
|
||||
mModified = true;
|
||||
}
|
||||
|
||||
void FreeCameraController::translate(const osg::Vec3d& offset)
|
||||
{
|
||||
getCamera()->getViewMatrix() *= osg::Matrixd::translate(offset);
|
||||
mModified = true;
|
||||
}
|
||||
|
||||
void FreeCameraController::stabilize()
|
||||
{
|
||||
osg::Vec3d eye, center, up;
|
||||
getCamera()->getViewMatrixAsLookAt(eye, center, up);
|
||||
getCamera()->setViewMatrixAsLookAt(eye, center, mUp);
|
||||
}
|
||||
|
||||
/*
|
||||
Orbit Camera Controller
|
||||
*/
|
||||
|
||||
OrbitCameraController::OrbitCameraController()
|
||||
: mInitialized(false)
|
||||
, mFast(false)
|
||||
, mLeft(false)
|
||||
, mRight(false)
|
||||
, mUp(false)
|
||||
, mDown(false)
|
||||
, mRollLeft(false)
|
||||
, mRollRight(false)
|
||||
, mPickingMask(~0)
|
||||
, mCenter(0,0,0)
|
||||
, mDistance(0)
|
||||
, mOrbitSpeed(osg::PI / 4)
|
||||
, mOrbitSpeedMult(4)
|
||||
{
|
||||
}
|
||||
|
||||
osg::Vec3d OrbitCameraController::getCenter() const
|
||||
{
|
||||
return mCenter;
|
||||
}
|
||||
|
||||
double OrbitCameraController::getOrbitSpeed() const
|
||||
{
|
||||
return mOrbitSpeed;
|
||||
}
|
||||
|
||||
double OrbitCameraController::getOrbitSpeedMultiplier() const
|
||||
{
|
||||
return mOrbitSpeedMult;
|
||||
}
|
||||
|
||||
unsigned int OrbitCameraController::getPickingMask() const
|
||||
{
|
||||
return mPickingMask;
|
||||
}
|
||||
|
||||
void OrbitCameraController::setCenter(const osg::Vec3d& value)
|
||||
{
|
||||
osg::Vec3d eye, center, up;
|
||||
getCamera()->getViewMatrixAsLookAt(eye, center, up);
|
||||
|
||||
mCenter = value;
|
||||
mDistance = (eye - mCenter).length();
|
||||
|
||||
getCamera()->setViewMatrixAsLookAt(eye, mCenter, up);
|
||||
|
||||
mInitialized = true;
|
||||
}
|
||||
|
||||
void OrbitCameraController::setOrbitSpeed(double value)
|
||||
{
|
||||
mOrbitSpeed = value;
|
||||
}
|
||||
|
||||
void OrbitCameraController::setOrbitSpeedMultiplier(double value)
|
||||
{
|
||||
mOrbitSpeedMult = value;
|
||||
}
|
||||
|
||||
void OrbitCameraController::setPickingMask(unsigned int value)
|
||||
{
|
||||
mPickingMask = value;
|
||||
}
|
||||
|
||||
bool OrbitCameraController::handleKeyEvent(QKeyEvent* event, bool pressed)
|
||||
{
|
||||
if (!isActive())
|
||||
return false;
|
||||
|
||||
if (!mInitialized)
|
||||
initialize();
|
||||
|
||||
if (event->key() == Qt::Key_Q)
|
||||
{
|
||||
mRollLeft = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_E)
|
||||
{
|
||||
mRollRight = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_A)
|
||||
{
|
||||
mLeft = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_D)
|
||||
{
|
||||
mRight = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_W)
|
||||
{
|
||||
mUp = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_S)
|
||||
{
|
||||
mDown = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_Shift)
|
||||
{
|
||||
mFast = pressed;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OrbitCameraController::handleMouseMoveEvent(std::string mode, int x, int y)
|
||||
{
|
||||
if (!isActive())
|
||||
return false;
|
||||
|
||||
if (!mInitialized)
|
||||
initialize();
|
||||
|
||||
if (mode == "p-navi")
|
||||
{
|
||||
double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0);
|
||||
rotateHorizontal(x * scalar);
|
||||
rotateVertical(-y * scalar);
|
||||
}
|
||||
else if (mode == "s-navi")
|
||||
{
|
||||
osg::Vec3d movement;
|
||||
movement += LocalLeft * x * getSecondaryMovementMultiplier();
|
||||
movement += LocalUp * -y * getSecondaryMovementMultiplier();
|
||||
|
||||
translate(movement);
|
||||
}
|
||||
else if (mode == "t-navi")
|
||||
{
|
||||
zoom(-x * (mFast ? getWheelMovementMultiplier() : 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OrbitCameraController::update(double dt)
|
||||
{
|
||||
if (!isActive())
|
||||
return;
|
||||
|
||||
if (!mInitialized)
|
||||
initialize();
|
||||
|
||||
double rotDist = mOrbitSpeed * dt;
|
||||
|
||||
if (mFast)
|
||||
rotDist *= mOrbitSpeedMult;
|
||||
|
||||
if (mLeft)
|
||||
rotateHorizontal(-rotDist);
|
||||
if (mRight)
|
||||
rotateHorizontal(rotDist);
|
||||
if (mUp)
|
||||
rotateVertical(rotDist);
|
||||
if (mDown)
|
||||
rotateVertical(-rotDist);
|
||||
|
||||
if (mRollLeft)
|
||||
roll(-rotDist);
|
||||
if (mRollRight)
|
||||
roll(rotDist);
|
||||
|
||||
// Normalize the matrix to counter drift
|
||||
getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix());
|
||||
}
|
||||
|
||||
void OrbitCameraController::onActivate()
|
||||
{
|
||||
mInitialized = false;
|
||||
}
|
||||
|
||||
void OrbitCameraController::initialize()
|
||||
{
|
||||
static const int DefaultStartDistance = 10000.f;
|
||||
|
||||
// Try to intelligently pick focus object
|
||||
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (new osgUtil::LineSegmentIntersector(
|
||||
osgUtil::Intersector::PROJECTION, osg::Vec3d(0, 0, 0), LocalForward));
|
||||
|
||||
intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::LIMIT_NEAREST);
|
||||
osgUtil::IntersectionVisitor visitor(intersector);
|
||||
|
||||
visitor.setTraversalMask(mPickingMask);
|
||||
|
||||
getCamera()->accept(visitor);
|
||||
|
||||
osg::Vec3d eye, center, up;
|
||||
getCamera()->getViewMatrixAsLookAt(eye, center, up, DefaultStartDistance);
|
||||
|
||||
if (intersector->getIntersections().begin() != intersector->getIntersections().end())
|
||||
{
|
||||
mCenter = intersector->getIntersections().begin()->getWorldIntersectPoint();
|
||||
mDistance = (eye - mCenter).length();
|
||||
}
|
||||
else
|
||||
{
|
||||
mCenter = center;
|
||||
mDistance = DefaultStartDistance;
|
||||
}
|
||||
|
||||
mInitialized = true;
|
||||
}
|
||||
|
||||
void OrbitCameraController::rotateHorizontal(double value)
|
||||
{
|
||||
osg::Vec3d eye, center, up;
|
||||
getCamera()->getViewMatrixAsLookAt(eye, center, up);
|
||||
|
||||
osg::Quat rotation = osg::Quat(value, up);
|
||||
osg::Vec3d oldOffset = eye - mCenter;
|
||||
osg::Vec3d newOffset = rotation * oldOffset;
|
||||
|
||||
getCamera()->setViewMatrixAsLookAt(mCenter + newOffset, mCenter, up);
|
||||
}
|
||||
|
||||
void OrbitCameraController::rotateVertical(double value)
|
||||
{
|
||||
osg::Vec3d eye, center, up;
|
||||
getCamera()->getViewMatrixAsLookAt(eye, center, up);
|
||||
|
||||
osg::Vec3d forward = center - eye;
|
||||
osg::Quat rotation = osg::Quat(value, up ^ forward);
|
||||
osg::Vec3d oldOffset = eye - mCenter;
|
||||
osg::Vec3d newOffset = rotation * oldOffset;
|
||||
|
||||
getCamera()->setViewMatrixAsLookAt(mCenter + newOffset, mCenter, up);
|
||||
}
|
||||
|
||||
void OrbitCameraController::roll(double value)
|
||||
{
|
||||
getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalForward);
|
||||
}
|
||||
|
||||
void OrbitCameraController::translate(const osg::Vec3d& offset)
|
||||
{
|
||||
osg::Vec3d eye, center, up;
|
||||
getCamera()->getViewMatrixAsLookAt(eye, center, up);
|
||||
|
||||
osg::Vec3d newOffset = getCamera()->getViewMatrix().getRotate().inverse() * offset;
|
||||
mCenter += newOffset;
|
||||
eye += newOffset;
|
||||
|
||||
getCamera()->setViewMatrixAsLookAt(eye, mCenter, up);
|
||||
}
|
||||
|
||||
void OrbitCameraController::zoom(double value)
|
||||
{
|
||||
mDistance = std::max(10., mDistance + value);
|
||||
|
||||
osg::Vec3d eye, center, up;
|
||||
getCamera()->getViewMatrixAsLookAt(eye, center, up, 1.f);
|
||||
|
||||
osg::Vec3d offset = (eye - center) * mDistance;
|
||||
|
||||
getCamera()->setViewMatrixAsLookAt(mCenter + offset, mCenter, up);
|
||||
}
|
||||
}
|
152
apps/opencs/view/render/cameracontroller.hpp
Normal file
152
apps/opencs/view/render/cameracontroller.hpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
#ifndef OPENCS_VIEW_CAMERACONTROLLER_H
|
||||
#define OPENCS_VIEW_CAMERACONTROLLER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Vec3d>
|
||||
|
||||
class QKeyEvent;
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class Camera;
|
||||
class Group;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class CameraController
|
||||
{
|
||||
public:
|
||||
|
||||
static const osg::Vec3d WorldUp;
|
||||
|
||||
static const osg::Vec3d LocalUp;
|
||||
static const osg::Vec3d LocalLeft;
|
||||
static const osg::Vec3d LocalForward;
|
||||
|
||||
CameraController();
|
||||
virtual ~CameraController();
|
||||
|
||||
bool isActive() const;
|
||||
|
||||
osg::Camera* getCamera() const;
|
||||
double getCameraSensitivity() const;
|
||||
bool getInverted() const;
|
||||
double getSecondaryMovementMultiplier() const;
|
||||
double getWheelMovementMultiplier() const;
|
||||
|
||||
void setCamera(osg::Camera*);
|
||||
void setCameraSensitivity(double value);
|
||||
void setInverted(bool value);
|
||||
void setSecondaryMovementMultiplier(double value);
|
||||
void setWheelMovementMultiplier(double value);
|
||||
|
||||
// moves the camera to an intelligent position
|
||||
void setup(osg::Group* root, unsigned int mask, const osg::Vec3d& up);
|
||||
|
||||
virtual bool handleKeyEvent(QKeyEvent* event, bool pressed) = 0;
|
||||
virtual bool handleMouseMoveEvent(std::string mode, int x, int y) = 0;
|
||||
|
||||
virtual void update(double dt) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void onActivate(){}
|
||||
|
||||
private:
|
||||
|
||||
bool mActive, mInverted;
|
||||
double mCameraSensitivity;
|
||||
double mSecondaryMoveMult;
|
||||
double mWheelMoveMult;
|
||||
|
||||
osg::Camera* mCamera;
|
||||
};
|
||||
|
||||
class FreeCameraController : public CameraController
|
||||
{
|
||||
public:
|
||||
|
||||
FreeCameraController();
|
||||
|
||||
double getLinearSpeed() const;
|
||||
double getRotationalSpeed() const;
|
||||
double getSpeedMultiplier() const;
|
||||
|
||||
void setLinearSpeed(double value);
|
||||
void setRotationalSpeed(double value);
|
||||
void setSpeedMultiplier(double value);
|
||||
|
||||
void fixUpAxis(const osg::Vec3d& up);
|
||||
void unfixUpAxis();
|
||||
|
||||
bool handleKeyEvent(QKeyEvent* event, bool pressed);
|
||||
bool handleMouseMoveEvent(std::string mode, int x, int y);
|
||||
|
||||
void update(double dt);
|
||||
|
||||
private:
|
||||
|
||||
void yaw(double value);
|
||||
void pitch(double value);
|
||||
void roll(double value);
|
||||
void translate(const osg::Vec3d& offset);
|
||||
|
||||
void stabilize();
|
||||
|
||||
bool mLockUpright, mModified;
|
||||
bool mFast, mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight;
|
||||
osg::Vec3d mUp;
|
||||
|
||||
double mLinSpeed;
|
||||
double mRotSpeed;
|
||||
double mSpeedMult;
|
||||
};
|
||||
|
||||
class OrbitCameraController : public CameraController
|
||||
{
|
||||
public:
|
||||
|
||||
OrbitCameraController();
|
||||
|
||||
osg::Vec3d getCenter() const;
|
||||
double getOrbitSpeed() const;
|
||||
double getOrbitSpeedMultiplier() const;
|
||||
unsigned int getPickingMask() const;
|
||||
|
||||
void setCenter(const osg::Vec3d& center);
|
||||
void setOrbitSpeed(double value);
|
||||
void setOrbitSpeedMultiplier(double value);
|
||||
void setPickingMask(unsigned int value);
|
||||
|
||||
bool handleKeyEvent(QKeyEvent* event, bool pressed);
|
||||
bool handleMouseMoveEvent(std::string mode, int x, int y);
|
||||
|
||||
void update(double dt);
|
||||
|
||||
private:
|
||||
|
||||
void onActivate();
|
||||
|
||||
void initialize();
|
||||
|
||||
void rotateHorizontal(double value);
|
||||
void rotateVertical(double value);
|
||||
void roll(double value);
|
||||
void translate(const osg::Vec3d& offset);
|
||||
void zoom(double value);
|
||||
|
||||
bool mInitialized;
|
||||
bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight;
|
||||
unsigned int mPickingMask;
|
||||
osg::Vec3d mCenter;
|
||||
double mDistance;
|
||||
|
||||
double mOrbitSpeed;
|
||||
double mOrbitSpeedMult;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
37
apps/opencs/view/render/orbitcameramode.cpp
Normal file
37
apps/opencs/view/render/orbitcameramode.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include "orbitcameramode.hpp"
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
#include "worldspacewidget.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
OrbitCameraMode::OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip,
|
||||
QWidget* parent)
|
||||
: ModeButton(icon, tooltip, parent)
|
||||
, mWorldspaceWidget(worldspaceWidget)
|
||||
, mCenterOnSelection(0)
|
||||
{
|
||||
}
|
||||
|
||||
void OrbitCameraMode::activate(CSVWidget::SceneToolbar* toolbar)
|
||||
{
|
||||
mCenterOnSelection = new QAction("Center on selected object", this);
|
||||
connect(mCenterOnSelection, SIGNAL(triggered()), this, SLOT(centerSelection()));
|
||||
}
|
||||
|
||||
bool OrbitCameraMode::createContextMenu(QMenu* menu)
|
||||
{
|
||||
if (menu)
|
||||
{
|
||||
menu->addAction(mCenterOnSelection);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OrbitCameraMode::centerSelection()
|
||||
{
|
||||
mWorldspaceWidget->centerOrbitCameraOnSelection();
|
||||
}
|
||||
}
|
33
apps/opencs/view/render/orbitcameramode.hpp
Normal file
33
apps/opencs/view/render/orbitcameramode.hpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef CSV_RENDER_ORBITCAMERAPICKMODE_H
|
||||
#define CSV_RENDER_ORBITCAMERAPICKMODE_H
|
||||
|
||||
#include "../widget/modebutton.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class WorldspaceWidget;
|
||||
|
||||
class OrbitCameraMode : public CSVWidget::ModeButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip = "",
|
||||
QWidget* parent = 0);
|
||||
|
||||
virtual void activate(CSVWidget::SceneToolbar* toolbar);
|
||||
virtual bool createContextMenu(QMenu* menu);
|
||||
|
||||
private:
|
||||
|
||||
WorldspaceWidget* mWorldspaceWidget;
|
||||
QAction* mCenterOnSelection;
|
||||
|
||||
private slots:
|
||||
|
||||
void centerSelection();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -6,8 +6,6 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QApplication>
|
||||
|
||||
#include <osgGA/TrackballManipulator>
|
||||
|
||||
#include <components/esm/loadland.hpp>
|
||||
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
|
@ -23,7 +21,6 @@
|
|||
bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
||||
{
|
||||
bool modified = false;
|
||||
bool wasEmpty = mCells.empty();
|
||||
|
||||
const CSMWorld::IdCollection<CSMWorld::Cell>& cells = mDocument.getData().getCells();
|
||||
|
||||
|
@ -114,11 +111,6 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
|||
}
|
||||
}
|
||||
|
||||
/// \todo do not overwrite manipulator object
|
||||
/// \todo move code to useViewHint function
|
||||
if (modified && wasEmpty)
|
||||
mView->setCameraManipulator(new osgGA::TrackballManipulator);
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "previewwidget.hpp"
|
||||
|
||||
#include <osgGA/TrackballManipulator>
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
|
||||
|
@ -9,7 +7,7 @@ CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
|||
const std::string& id, bool referenceable, QWidget *parent)
|
||||
: SceneWidget (data.getResourceSystem(), parent), mData (data), mObject(data, mRootNode, id, referenceable)
|
||||
{
|
||||
mView->setCameraManipulator(new osgGA::TrackballManipulator);
|
||||
selectNavigationMode("orbit");
|
||||
|
||||
QAbstractItemModel *referenceables =
|
||||
mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables);
|
||||
|
|
|
@ -18,8 +18,11 @@
|
|||
|
||||
#include "../widget/scenetoolmode.hpp"
|
||||
|
||||
#include "../../model/prefs/state.hpp"
|
||||
|
||||
#include "lighting.hpp"
|
||||
#include "mask.hpp"
|
||||
#include "cameracontroller.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
|
@ -57,9 +60,6 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
|
|||
layout->addWidget(window->getGLWidget());
|
||||
setLayout(layout);
|
||||
|
||||
// Pass events through this widget first
|
||||
window->getGLWidget()->installEventFilter(this);
|
||||
|
||||
mView->getCamera()->setGraphicsContext(window);
|
||||
mView->getCamera()->setClearColor( osg::Vec4(0.2, 0.2, 0.6, 1.0) );
|
||||
mView->getCamera()->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );
|
||||
|
@ -100,26 +100,6 @@ void RenderWidget::setVisibilityMask(int mask)
|
|||
mView->getCamera()->setCullMask(mask | Mask_ParticleSystem | Mask_Lighting);
|
||||
}
|
||||
|
||||
bool RenderWidget::eventFilter(QObject* obj, QEvent* event)
|
||||
{
|
||||
// handle event in this widget, is there a better way to do this?
|
||||
if (event->type() == QEvent::MouseButtonPress)
|
||||
mousePressEvent(static_cast<QMouseEvent*>(event));
|
||||
if (event->type() == QEvent::MouseButtonRelease)
|
||||
mouseReleaseEvent(static_cast<QMouseEvent*>(event));
|
||||
if (event->type() == QEvent::MouseMove)
|
||||
mouseMoveEvent(static_cast<QMouseEvent*>(event));
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
keyPressEvent(static_cast<QKeyEvent*>(event));
|
||||
if (event->type() == QEvent::KeyRelease)
|
||||
keyReleaseEvent(static_cast<QKeyEvent*>(event));
|
||||
if (event->type() == QEvent::Wheel)
|
||||
wheelEvent(static_cast<QWheelEvent *>(event));
|
||||
|
||||
// Always pass the event on to GLWidget, i.e. to OSG event queue
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
osg::Camera *RenderWidget::getCamera()
|
||||
{
|
||||
return mView->getCamera();
|
||||
|
@ -159,19 +139,33 @@ CompositeViewer &CompositeViewer::get()
|
|||
|
||||
void CompositeViewer::update()
|
||||
{
|
||||
mSimulationTime += mFrameTimer.time_s();
|
||||
double dt = mFrameTimer.time_s();
|
||||
mFrameTimer.setStartTick();
|
||||
|
||||
emit simulationUpdated(dt);
|
||||
|
||||
mSimulationTime += dt;
|
||||
frame(mSimulationTime);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
|
||||
SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSystem, QWidget *parent, Qt::WindowFlags f)
|
||||
SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSystem, QWidget *parent, Qt::WindowFlags f,
|
||||
bool retrieveInput)
|
||||
: RenderWidget(parent, f)
|
||||
, mResourceSystem(resourceSystem)
|
||||
, mLighting(NULL)
|
||||
, mHasDefaultAmbient(false)
|
||||
, mPrevMouseX(0)
|
||||
, mPrevMouseY(0)
|
||||
, mFreeCamControl(new FreeCameraController())
|
||||
, mOrbitCamControl(new OrbitCameraController())
|
||||
, mCurrentCamControl(mFreeCamControl.get())
|
||||
, mCamPositionSet(false)
|
||||
{
|
||||
mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain);
|
||||
selectNavigationMode("free");
|
||||
|
||||
// we handle lighting manually
|
||||
mView->setLightingMode(osgViewer::View::NO_LIGHT);
|
||||
|
||||
|
@ -182,6 +176,18 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
|
|||
/// \todo make shortcut configurable
|
||||
QShortcut *focusToolbar = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut);
|
||||
connect (focusToolbar, SIGNAL (activated()), this, SIGNAL (focusToolbarRequest()));
|
||||
|
||||
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
|
||||
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
|
||||
|
||||
// TODO update this outside of the constructor where virtual methods can be used
|
||||
if (retrieveInput)
|
||||
{
|
||||
CSMPrefs::get()["3D Scene Input"].update();
|
||||
CSMPrefs::get()["Tooltips"].update();
|
||||
}
|
||||
|
||||
connect (&CompositeViewer::get(), SIGNAL (simulationUpdated(double)), this, SLOT (update(double)));
|
||||
}
|
||||
|
||||
SceneWidget::~SceneWidget()
|
||||
|
@ -261,4 +267,181 @@ void SceneWidget::setDefaultAmbient (const osg::Vec4f& colour)
|
|||
setAmbient(mLighting->getAmbientColour(&mDefaultAmbient));
|
||||
}
|
||||
|
||||
void SceneWidget::mousePressEvent (QMouseEvent *event)
|
||||
{
|
||||
mMouseMode = mapButton(event);
|
||||
|
||||
mPrevMouseX = event->x();
|
||||
mPrevMouseY = event->y();
|
||||
}
|
||||
|
||||
void SceneWidget::mouseReleaseEvent (QMouseEvent *event)
|
||||
{
|
||||
mMouseMode = "";
|
||||
}
|
||||
|
||||
void SceneWidget::mouseMoveEvent (QMouseEvent *event)
|
||||
{
|
||||
mCurrentCamControl->handleMouseMoveEvent(mMouseMode, event->x() - mPrevMouseX, event->y() - mPrevMouseY);
|
||||
|
||||
mPrevMouseX = event->x();
|
||||
mPrevMouseY = event->y();
|
||||
}
|
||||
|
||||
void SceneWidget::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
mCurrentCamControl->handleMouseMoveEvent("t-navi", event->delta(), 0);
|
||||
}
|
||||
|
||||
void SceneWidget::keyPressEvent (QKeyEvent *event)
|
||||
{
|
||||
mCurrentCamControl->handleKeyEvent(event, true);
|
||||
}
|
||||
|
||||
void SceneWidget::keyReleaseEvent (QKeyEvent *event)
|
||||
{
|
||||
mCurrentCamControl->handleKeyEvent(event, false);
|
||||
}
|
||||
|
||||
void SceneWidget::update(double dt)
|
||||
{
|
||||
if (mCamPositionSet)
|
||||
{
|
||||
mCurrentCamControl->update(dt);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentCamControl->setup(mRootNode, Mask_Reference | Mask_Terrain, CameraController::WorldUp);
|
||||
mCamPositionSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWidget::settingChanged (const CSMPrefs::Setting *setting)
|
||||
{
|
||||
if (*setting=="3D Scene Input/p-navi-free-sensitivity")
|
||||
{
|
||||
mFreeCamControl->setCameraSensitivity(setting->toDouble());
|
||||
}
|
||||
else if (*setting=="3D Scene Input/p-navi-orbit-sensitivity")
|
||||
{
|
||||
mOrbitCamControl->setCameraSensitivity(setting->toDouble());
|
||||
}
|
||||
else if (*setting=="3D Scene Input/p-navi-free-invert")
|
||||
{
|
||||
mFreeCamControl->setInverted(setting->isTrue());
|
||||
}
|
||||
else if (*setting=="3D Scene Input/p-navi-orbit-invert")
|
||||
{
|
||||
mOrbitCamControl->setInverted(setting->isTrue());
|
||||
}
|
||||
else if (*setting=="3D Scene Input/s-navi-sensitivity")
|
||||
{
|
||||
mFreeCamControl->setSecondaryMovementMultiplier(setting->toDouble());
|
||||
mOrbitCamControl->setSecondaryMovementMultiplier(setting->toDouble());
|
||||
}
|
||||
else if (*setting=="3D Scene Input/navi-wheel-factor")
|
||||
{
|
||||
mFreeCamControl->setWheelMovementMultiplier(setting->toDouble());
|
||||
mOrbitCamControl->setWheelMovementMultiplier(setting->toDouble());
|
||||
}
|
||||
else if (*setting=="3D Scene Input/navi-free-lin-speed")
|
||||
{
|
||||
mFreeCamControl->setLinearSpeed(setting->toDouble());
|
||||
}
|
||||
else if (*setting=="3D Scene Input/navi-free-rot-speed")
|
||||
{
|
||||
mFreeCamControl->setRotationalSpeed(setting->toDouble());
|
||||
}
|
||||
else if (*setting=="3D Scene Input/navi-free-speed-mult")
|
||||
{
|
||||
mFreeCamControl->setSpeedMultiplier(setting->toDouble());
|
||||
}
|
||||
else if (*setting=="3D Scene Input/navi-orbit-rot-speed")
|
||||
{
|
||||
mOrbitCamControl->setOrbitSpeed(setting->toDouble());
|
||||
}
|
||||
else if (*setting=="3D Scene Input/navi-orbit-speed-mult")
|
||||
{
|
||||
mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble());
|
||||
}
|
||||
else
|
||||
{
|
||||
storeMappingSetting(setting);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWidget::selectNavigationMode (const std::string& mode)
|
||||
{
|
||||
if (mode=="1st")
|
||||
{
|
||||
mCurrentCamControl->setCamera(NULL);
|
||||
mCurrentCamControl = mFreeCamControl.get();
|
||||
mCurrentCamControl->setCamera(getCamera());
|
||||
mFreeCamControl->fixUpAxis(CameraController::WorldUp);
|
||||
}
|
||||
else if (mode=="free")
|
||||
{
|
||||
mCurrentCamControl->setCamera(NULL);
|
||||
mCurrentCamControl = mFreeCamControl.get();
|
||||
mCurrentCamControl->setCamera(getCamera());
|
||||
mFreeCamControl->unfixUpAxis();
|
||||
}
|
||||
else if (mode=="orbit")
|
||||
{
|
||||
mCurrentCamControl->setCamera(NULL);
|
||||
mCurrentCamControl = mOrbitCamControl.get();
|
||||
mCurrentCamControl->setCamera(getCamera());
|
||||
}
|
||||
}
|
||||
|
||||
bool SceneWidget::storeMappingSetting (const CSMPrefs::Setting *setting)
|
||||
{
|
||||
if (setting->getParent()->getKey()!="3D Scene Input")
|
||||
return false;
|
||||
|
||||
static const char * const sMappingSettings[] =
|
||||
{
|
||||
"p-navi", "s-navi",
|
||||
0
|
||||
};
|
||||
|
||||
for (int i=0; sMappingSettings[i]; ++i)
|
||||
if (setting->getKey()==sMappingSettings[i])
|
||||
{
|
||||
QString value = QString::fromUtf8 (setting->toString().c_str());
|
||||
|
||||
Qt::MouseButton button = Qt::NoButton;
|
||||
|
||||
if (value.endsWith ("Left Mouse-Button"))
|
||||
button = Qt::LeftButton;
|
||||
else if (value.endsWith ("Right Mouse-Button"))
|
||||
button = Qt::RightButton;
|
||||
else if (value.endsWith ("Middle Mouse-Button"))
|
||||
button = Qt::MiddleButton;
|
||||
else
|
||||
return false;
|
||||
|
||||
bool ctrl = value.startsWith ("Ctrl-");
|
||||
|
||||
mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string SceneWidget::mapButton (QMouseEvent *event)
|
||||
{
|
||||
std::pair<Qt::MouseButton, bool> phyiscal (
|
||||
event->button(), event->modifiers() & Qt::ControlModifier);
|
||||
|
||||
std::map<std::pair<Qt::MouseButton, bool>, std::string>::const_iterator iter =
|
||||
mButtonMapping.find (phyiscal);
|
||||
|
||||
if (iter!=mButtonMapping.end())
|
||||
return iter->second;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef OPENCS_VIEW_SCENEWIDGET_H
|
||||
#define OPENCS_VIEW_SCENEWIDGET_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTimer>
|
||||
|
||||
|
@ -30,93 +33,135 @@ namespace CSVWidget
|
|||
class SceneToolbar;
|
||||
}
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class Setting;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class CameraController;
|
||||
class FreeCameraController;
|
||||
class OrbitCameraController;
|
||||
class Lighting;
|
||||
|
||||
class RenderWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||
virtual ~RenderWidget();
|
||||
public:
|
||||
RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||
virtual ~RenderWidget();
|
||||
|
||||
void flagAsModified();
|
||||
void flagAsModified();
|
||||
|
||||
void setVisibilityMask(int mask);
|
||||
void setVisibilityMask(int mask);
|
||||
|
||||
bool eventFilter(QObject *, QEvent *);
|
||||
osg::Camera *getCamera();
|
||||
|
||||
osg::Camera *getCamera();
|
||||
protected:
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<osgViewer::View> mView;
|
||||
|
||||
osg::ref_ptr<osgViewer::View> mView;
|
||||
osg::Group* mRootNode;
|
||||
|
||||
osg::Group* mRootNode;
|
||||
|
||||
QTimer mTimer;
|
||||
QTimer mTimer;
|
||||
};
|
||||
|
||||
// Extension of RenderWidget to support lighting mode selection & toolbar
|
||||
class SceneWidget : public RenderWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSystem, QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||
virtual ~SceneWidget();
|
||||
Q_OBJECT
|
||||
public:
|
||||
SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSystem, QWidget* parent = 0,
|
||||
Qt::WindowFlags f = 0, bool retrieveInput = true);
|
||||
virtual ~SceneWidget();
|
||||
|
||||
CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent);
|
||||
///< \attention The created tool is not added to the toolbar (via addTool). Doing that
|
||||
/// is the responsibility of the calling function.
|
||||
CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent);
|
||||
///< \attention The created tool is not added to the toolbar (via addTool). Doing that
|
||||
/// is the responsibility of the calling function.
|
||||
|
||||
void setDefaultAmbient (const osg::Vec4f& colour);
|
||||
///< \note The actual ambient colour may differ based on lighting settings.
|
||||
void setDefaultAmbient (const osg::Vec4f& colour);
|
||||
///< \note The actual ambient colour may differ based on lighting settings.
|
||||
|
||||
protected:
|
||||
void setLighting (Lighting *lighting);
|
||||
///< \attention The ownership of \a lighting is not transferred to *this.
|
||||
protected:
|
||||
void setLighting (Lighting *lighting);
|
||||
///< \attention The ownership of \a lighting is not transferred to *this.
|
||||
|
||||
void setAmbient(const osg::Vec4f& ambient);
|
||||
void setAmbient(const osg::Vec4f& ambient);
|
||||
|
||||
boost::shared_ptr<Resource::ResourceSystem> mResourceSystem;
|
||||
virtual void mousePressEvent (QMouseEvent *event);
|
||||
virtual void mouseReleaseEvent (QMouseEvent *event);
|
||||
virtual void mouseMoveEvent (QMouseEvent *event);
|
||||
virtual void wheelEvent (QWheelEvent *event);
|
||||
virtual void keyPressEvent (QKeyEvent *event);
|
||||
virtual void keyReleaseEvent (QKeyEvent *event);
|
||||
|
||||
Lighting* mLighting;
|
||||
/// \return Is \a key a button mapping setting? (ignored otherwise)
|
||||
virtual bool storeMappingSetting (const CSMPrefs::Setting *setting);
|
||||
|
||||
osg::Vec4f mDefaultAmbient;
|
||||
bool mHasDefaultAmbient;
|
||||
LightingDay mLightingDay;
|
||||
LightingNight mLightingNight;
|
||||
LightingBright mLightingBright;
|
||||
std::string mapButton (QMouseEvent *event);
|
||||
|
||||
private slots:
|
||||
boost::shared_ptr<Resource::ResourceSystem> mResourceSystem;
|
||||
|
||||
void selectLightingMode (const std::string& mode);
|
||||
Lighting* mLighting;
|
||||
|
||||
osg::Vec4f mDefaultAmbient;
|
||||
bool mHasDefaultAmbient;
|
||||
LightingDay mLightingDay;
|
||||
LightingNight mLightingNight;
|
||||
LightingBright mLightingBright;
|
||||
|
||||
int mPrevMouseX, mPrevMouseY;
|
||||
std::string mMouseMode;
|
||||
std::auto_ptr<FreeCameraController> mFreeCamControl;
|
||||
std::auto_ptr<OrbitCameraController> mOrbitCamControl;
|
||||
CameraController* mCurrentCamControl;
|
||||
|
||||
std::map<std::pair<Qt::MouseButton, bool>, std::string> mButtonMapping;
|
||||
|
||||
private:
|
||||
bool mCamPositionSet;
|
||||
|
||||
public slots:
|
||||
void update(double dt);
|
||||
|
||||
protected slots:
|
||||
|
||||
virtual void settingChanged (const CSMPrefs::Setting *setting);
|
||||
|
||||
void selectNavigationMode (const std::string& mode);
|
||||
|
||||
private slots:
|
||||
|
||||
void selectLightingMode (const std::string& mode);
|
||||
|
||||
signals:
|
||||
|
||||
void focusToolbarRequest();
|
||||
void focusToolbarRequest();
|
||||
};
|
||||
|
||||
|
||||
// There are rendering glitches when using multiple Viewer instances, work around using CompositeViewer with multiple views
|
||||
class CompositeViewer : public QObject, public osgViewer::CompositeViewer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CompositeViewer();
|
||||
Q_OBJECT
|
||||
public:
|
||||
CompositeViewer();
|
||||
|
||||
static CompositeViewer& get();
|
||||
static CompositeViewer& get();
|
||||
|
||||
QTimer mTimer;
|
||||
QTimer mTimer;
|
||||
|
||||
private:
|
||||
osg::Timer mFrameTimer;
|
||||
double mSimulationTime;
|
||||
private:
|
||||
osg::Timer mFrameTimer;
|
||||
double mSimulationTime;
|
||||
|
||||
public slots:
|
||||
void update();
|
||||
public slots:
|
||||
void update();
|
||||
|
||||
signals:
|
||||
void simulationUpdated(double dt);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
#include <osgGA/TrackballManipulator>
|
||||
|
||||
#include <QEvent>
|
||||
|
||||
#include <components/sceneutil/util.hpp>
|
||||
|
@ -50,8 +48,6 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string&
|
|||
update();
|
||||
|
||||
mCell.reset (new Cell (document.getData(), mRootNode, mCellId));
|
||||
|
||||
mView->setCameraManipulator(new osgGA::TrackballManipulator);
|
||||
}
|
||||
|
||||
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
|
||||
|
|
|
@ -12,9 +12,6 @@
|
|||
#include <QApplication>
|
||||
#include <QToolTip>
|
||||
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osgGA/FirstPersonManipulator>
|
||||
|
||||
#include <osgUtil/LineSegmentIntersector>
|
||||
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
@ -22,6 +19,8 @@
|
|||
|
||||
#include "../../model/prefs/state.hpp"
|
||||
|
||||
#include "../render/orbitcameramode.hpp"
|
||||
|
||||
#include "../widget/scenetoolmode.hpp"
|
||||
#include "../widget/scenetooltoggle2.hpp"
|
||||
#include "../widget/scenetoolrun.hpp"
|
||||
|
@ -30,9 +29,10 @@
|
|||
#include "mask.hpp"
|
||||
#include "editmode.hpp"
|
||||
#include "instancemode.hpp"
|
||||
#include "cameracontroller.hpp"
|
||||
|
||||
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
|
||||
: SceneWidget (document.getData().getResourceSystem(), parent), mSceneElements(0), mRun(0), mDocument(document),
|
||||
: SceneWidget (document.getData().getResourceSystem(), parent, 0, false), mSceneElements(0), mRun(0), mDocument(document),
|
||||
mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false), mDragX(0), mDragY(0), mDragFactor(0),
|
||||
mDragWheelFactor(0), mDragShiftFactor(0),
|
||||
mToolTipPos (-1, -1), mShowToolTips(false), mToolTipDelay(0)
|
||||
|
@ -67,13 +67,11 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
|
|||
connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||
this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||
|
||||
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
|
||||
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
|
||||
CSMPrefs::get()["3D Scene Input"].update();
|
||||
CSMPrefs::get()["Tooltips"].update();
|
||||
|
||||
mToolTipDelayTimer.setSingleShot (true);
|
||||
connect (&mToolTipDelayTimer, SIGNAL (timeout()), this, SLOT (showToolTip()));
|
||||
|
||||
CSMPrefs::get()["3D Scene Input"].update();
|
||||
CSMPrefs::get()["Tooltips"].update();
|
||||
}
|
||||
|
||||
CSVRender::WorldspaceWidget::~WorldspaceWidget ()
|
||||
|
@ -82,9 +80,6 @@ CSVRender::WorldspaceWidget::~WorldspaceWidget ()
|
|||
|
||||
void CSVRender::WorldspaceWidget::settingChanged (const CSMPrefs::Setting *setting)
|
||||
{
|
||||
if (storeMappingSetting (setting))
|
||||
return;
|
||||
|
||||
if (*setting=="3D Scene Input/drag-factor")
|
||||
mDragFactor = setting->toDouble();
|
||||
else if (*setting=="3D Scene Input/drag-wheel-factor")
|
||||
|
@ -95,23 +90,29 @@ void CSVRender::WorldspaceWidget::settingChanged (const CSMPrefs::Setting *setti
|
|||
mToolTipDelay = setting->toInt();
|
||||
else if (*setting=="Tooltips/scene")
|
||||
mShowToolTips = setting->isTrue();
|
||||
else
|
||||
SceneWidget::settingChanged(setting);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
|
||||
{
|
||||
if (mode=="1st")
|
||||
mView->setCameraManipulator(new osgGA::FirstPersonManipulator);
|
||||
else if (mode=="free")
|
||||
mView->setCameraManipulator(new osgGA::FirstPersonManipulator);
|
||||
else if (mode=="orbit")
|
||||
mView->setCameraManipulator(new osgGA::OrbitManipulator);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::useViewHint (const std::string& hint) {}
|
||||
|
||||
void CSVRender::WorldspaceWidget::selectDefaultNavigationMode()
|
||||
{
|
||||
mView->setCameraManipulator(new osgGA::FirstPersonManipulator);
|
||||
selectNavigationMode("1st");
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::centerOrbitCameraOnSelection()
|
||||
{
|
||||
std::vector<osg::ref_ptr<TagBase> > selection = getSelection(~0);
|
||||
|
||||
for (std::vector<osg::ref_ptr<TagBase> >::iterator it = selection.begin(); it!=selection.end(); ++it)
|
||||
{
|
||||
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag*> (it->get()))
|
||||
{
|
||||
mOrbitCamControl->setCenter(objectTag->mObject->getPosition().asVec3());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector (
|
||||
|
@ -138,15 +139,17 @@ CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector (
|
|||
"<li>Roll camera with Q and E keys</li>"
|
||||
"<li>Hold shift to speed up movement</li>"
|
||||
"</ul>");
|
||||
tool->addButton (":scenetoolbar/orbiting-camera", "orbit",
|
||||
"Orbiting Camera"
|
||||
"<ul><li>Always facing the centre point</li>"
|
||||
"<li>Rotate around the centre point via WASD or by moving the mouse while holding the left button</li>"
|
||||
"<li>Mouse wheel moves camera away or towards centre point but can not pass through it</li>"
|
||||
"<li>Roll camera with Q and E keys</li>"
|
||||
"<li>Strafing (also vertically) by holding the left mouse button and control (includes relocation of the centre point)</li>"
|
||||
"<li>Hold shift to speed up movement</li>"
|
||||
"</ul>");
|
||||
tool->addButton(
|
||||
new CSVRender::OrbitCameraMode(this, QIcon(":scenetoolbar/orbiting-camera"),
|
||||
"Orbiting Camera"
|
||||
"<ul><li>Always facing the centre point</li>"
|
||||
"<li>Rotate around the centre point via WASD or by moving the mouse while holding the left button</li>"
|
||||
"<li>Mouse wheel moves camera away or towards centre point but can not pass through it</li>"
|
||||
"<li>Roll camera with Q and E keys</li>"
|
||||
"<li>Strafing (also vertically) by holding the left mouse button and control (includes relocation of the centre point)</li>"
|
||||
"<li>Hold shift to speed up movement</li>"
|
||||
"</ul>", tool),
|
||||
"orbit");
|
||||
|
||||
connect (tool, SIGNAL (modeChanged (const std::string&)),
|
||||
this, SLOT (selectNavigationMode (const std::string&)));
|
||||
|
@ -418,40 +421,41 @@ void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent *event)
|
|||
|
||||
bool CSVRender::WorldspaceWidget::storeMappingSetting (const CSMPrefs::Setting *setting)
|
||||
{
|
||||
if (setting->getParent()->getKey()!="3D Scene Input")
|
||||
return false;
|
||||
|
||||
static const char * const sMappingSettings[] =
|
||||
{
|
||||
"p-navi", "s-navi",
|
||||
"p-edit", "s-edit",
|
||||
"p-select", "s-select",
|
||||
0
|
||||
};
|
||||
|
||||
for (int i=0; sMappingSettings[i]; ++i)
|
||||
if (setting->getKey()==sMappingSettings[i])
|
||||
if (setting->getParent()->getKey()=="3D Scene Input")
|
||||
{
|
||||
for (int i=0; sMappingSettings[i]; ++i)
|
||||
{
|
||||
QString value = QString::fromUtf8 (setting->toString().c_str());
|
||||
if (setting->getKey()==sMappingSettings[i])
|
||||
{
|
||||
QString value = QString::fromUtf8 (setting->toString().c_str());
|
||||
|
||||
Qt::MouseButton button = Qt::NoButton;
|
||||
Qt::MouseButton button = Qt::NoButton;
|
||||
|
||||
if (value.endsWith ("Left Mouse-Button"))
|
||||
button = Qt::LeftButton;
|
||||
else if (value.endsWith ("Right Mouse-Button"))
|
||||
button = Qt::RightButton;
|
||||
else if (value.endsWith ("Middle Mouse-Button"))
|
||||
button = Qt::MiddleButton;
|
||||
else
|
||||
return false;
|
||||
if (value.endsWith ("Left Mouse-Button"))
|
||||
button = Qt::LeftButton;
|
||||
else if (value.endsWith ("Right Mouse-Button"))
|
||||
button = Qt::RightButton;
|
||||
else if (value.endsWith ("Middle Mouse-Button"))
|
||||
button = Qt::MiddleButton;
|
||||
else
|
||||
return false;
|
||||
|
||||
bool ctrl = value.startsWith ("Ctrl-");
|
||||
bool ctrl = value.startsWith ("Ctrl-");
|
||||
|
||||
mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i];
|
||||
return true;
|
||||
mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return SceneWidget::storeMappingSetting(setting);
|
||||
}
|
||||
|
||||
osg::ref_ptr<CSVRender::TagBase> CSVRender::WorldspaceWidget::mousePick (const QPoint& localPos)
|
||||
|
@ -496,20 +500,6 @@ osg::ref_ptr<CSVRender::TagBase> CSVRender::WorldspaceWidget::mousePick (const Q
|
|||
return osg::ref_ptr<CSVRender::TagBase>();
|
||||
}
|
||||
|
||||
std::string CSVRender::WorldspaceWidget::mapButton (QMouseEvent *event)
|
||||
{
|
||||
std::pair<Qt::MouseButton, bool> phyiscal (
|
||||
event->button(), event->modifiers() & Qt::ControlModifier);
|
||||
|
||||
std::map<std::pair<Qt::MouseButton, bool>, std::string>::const_iterator iter =
|
||||
mButtonMapping.find (phyiscal);
|
||||
|
||||
if (iter!=mButtonMapping.end())
|
||||
return iter->second;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event)
|
||||
{
|
||||
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
|
||||
|
@ -615,50 +605,7 @@ void CSVRender::WorldspaceWidget::updateOverlay()
|
|||
|
||||
void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
|
||||
{
|
||||
if (!mDragging)
|
||||
{
|
||||
if (mDragMode.empty())
|
||||
{
|
||||
if (event->globalPos()!=mToolTipPos)
|
||||
{
|
||||
mToolTipPos = event->globalPos();
|
||||
|
||||
if (mShowToolTips)
|
||||
mToolTipDelayTimer.start (mToolTipDelay);
|
||||
}
|
||||
}
|
||||
else if (mDragMode=="p-navi" || mDragMode=="s-navi")
|
||||
{
|
||||
|
||||
}
|
||||
else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="p-select" || mDragMode=="s-select")
|
||||
{
|
||||
osg::ref_ptr<TagBase> tag = mousePick (event->pos());
|
||||
|
||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||
|
||||
if (mDragMode=="p-edit")
|
||||
mDragging = editMode.primaryEditStartDrag (tag);
|
||||
else if (mDragMode=="s-edit")
|
||||
mDragging = editMode.secondaryEditStartDrag (tag);
|
||||
else if (mDragMode=="p-select")
|
||||
mDragging = editMode.primarySelectStartDrag (tag);
|
||||
else if (mDragMode=="s-select")
|
||||
mDragging = editMode.secondarySelectStartDrag (tag);
|
||||
|
||||
if (mDragging)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
mDragX = event->localPos().x();
|
||||
mDragY = height() - event->localPos().y();
|
||||
#else
|
||||
mDragX = event->posF().x();
|
||||
mDragY = height() - event->posF().y();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (mDragging)
|
||||
{
|
||||
int diffX = event->x() - mDragX;
|
||||
int diffY = (height() - event->y()) - mDragY;
|
||||
|
@ -675,59 +622,84 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
|
|||
|
||||
editMode.drag (diffX, diffY, factor);
|
||||
}
|
||||
else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="p-select" || mDragMode=="s-select")
|
||||
{
|
||||
osg::ref_ptr<TagBase> tag = mousePick (event->pos());
|
||||
|
||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||
|
||||
if (mDragMode=="p-edit")
|
||||
mDragging = editMode.primaryEditStartDrag (tag);
|
||||
else if (mDragMode=="s-edit")
|
||||
mDragging = editMode.secondaryEditStartDrag (tag);
|
||||
else if (mDragMode=="p-select")
|
||||
mDragging = editMode.primarySelectStartDrag (tag);
|
||||
else if (mDragMode=="s-select")
|
||||
mDragging = editMode.secondarySelectStartDrag (tag);
|
||||
|
||||
if (mDragging)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
mDragX = event->localPos().x();
|
||||
mDragY = height() - event->localPos().y();
|
||||
#else
|
||||
mDragX = event->posF().x();
|
||||
mDragY = height() - event->posF().y();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (event->globalPos()!=mToolTipPos)
|
||||
{
|
||||
mToolTipPos = event->globalPos();
|
||||
|
||||
if (mShowToolTips)
|
||||
mToolTipDelayTimer.start (mToolTipDelay);
|
||||
}
|
||||
|
||||
SceneWidget::mouseMoveEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event)
|
||||
{
|
||||
std::string button = mapButton (event);
|
||||
|
||||
if (!mDragging)
|
||||
mDragMode = button;
|
||||
if (button=="p-edit" || button=="s-edit" ||
|
||||
button=="p-select" || button=="s-select")
|
||||
{
|
||||
if (!mDragging)
|
||||
mDragMode = button;
|
||||
}
|
||||
else
|
||||
SceneWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event)
|
||||
{
|
||||
std::string button = mapButton (event);
|
||||
mDragMode.clear();
|
||||
|
||||
if (mDragging)
|
||||
if (button=="p-edit" || button=="s-edit" ||
|
||||
button=="p-select" || button=="s-select")
|
||||
{
|
||||
if (mDragMode=="p-navi" || mDragMode=="s-navi")
|
||||
{
|
||||
|
||||
}
|
||||
else if (mDragMode=="p-edit" || mDragMode=="s-edit" ||
|
||||
mDragMode=="p-select" || mDragMode=="s-select")
|
||||
if (mDragging)
|
||||
{
|
||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||
|
||||
editMode.dragCompleted();
|
||||
mDragging = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (button=="p-navi" || button=="s-navi")
|
||||
{
|
||||
|
||||
}
|
||||
else if (button=="p-edit" || button=="s-edit" ||
|
||||
button=="p-select" || button=="s-select")
|
||||
else
|
||||
{
|
||||
osg::ref_ptr<TagBase> tag = mousePick (event->pos());
|
||||
|
||||
handleMouseClick (tag, button, event->modifiers() & Qt::ShiftModifier);
|
||||
}
|
||||
}
|
||||
|
||||
mDragMode.clear();
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event)
|
||||
{
|
||||
if(event->button() == Qt::RightButton)
|
||||
{
|
||||
//mMouse->mouseDoubleClickEvent(event);
|
||||
}
|
||||
else
|
||||
SceneWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
|
||||
|
@ -743,6 +715,8 @@ void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
|
|||
|
||||
editMode.dragWheel (event->delta(), factor);
|
||||
}
|
||||
else
|
||||
SceneWidget::wheelEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
|
||||
|
@ -752,7 +726,7 @@ void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
|
|||
abortDrag();
|
||||
}
|
||||
else
|
||||
RenderWidget::keyPressEvent(event);
|
||||
SceneWidget::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button, bool shift)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#ifndef OPENCS_VIEW_WORLDSPACEWIDGET_H
|
||||
#define OPENCS_VIEW_WORLDSPACEWIDGET_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <QTimer>
|
||||
|
@ -45,7 +43,6 @@ namespace CSVRender
|
|||
CSVWidget::SceneToolRun *mRun;
|
||||
CSMDoc::Document& mDocument;
|
||||
unsigned int mInteractionMask;
|
||||
std::map<std::pair<Qt::MouseButton, bool>, std::string> mButtonMapping;
|
||||
CSVWidget::SceneToolMode *mEditMode;
|
||||
bool mLocked;
|
||||
std::string mDragMode;
|
||||
|
@ -100,6 +97,8 @@ namespace CSVRender
|
|||
|
||||
void selectDefaultNavigationMode();
|
||||
|
||||
void centerOrbitCameraOnSelection();
|
||||
|
||||
static DropType getDropType(const std::vector<CSMWorld::UniversalId>& data);
|
||||
|
||||
virtual dropRequirments getDropRequirements(DropType type) const;
|
||||
|
@ -189,13 +188,17 @@ namespace CSVRender
|
|||
virtual void mouseMoveEvent (QMouseEvent *event);
|
||||
virtual void mousePressEvent (QMouseEvent *event);
|
||||
virtual void mouseReleaseEvent (QMouseEvent *event);
|
||||
virtual void mouseDoubleClickEvent (QMouseEvent *event);
|
||||
virtual void wheelEvent (QWheelEvent *event);
|
||||
virtual void keyPressEvent (QKeyEvent *event);
|
||||
|
||||
virtual void handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button,
|
||||
bool shift);
|
||||
|
||||
/// \return Is \a key a button mapping setting? (ignored otherwise)
|
||||
virtual bool storeMappingSetting (const CSMPrefs::Setting *setting);
|
||||
|
||||
virtual void settingChanged (const CSMPrefs::Setting *setting);
|
||||
|
||||
EditMode *getEditMode();
|
||||
|
||||
private:
|
||||
|
@ -206,21 +209,12 @@ namespace CSVRender
|
|||
|
||||
void dragMoveEvent(QDragMoveEvent *event);
|
||||
|
||||
/// \return Is \a key a button mapping setting? (ignored otherwise)
|
||||
bool storeMappingSetting (const CSMPrefs::Setting *setting);
|
||||
|
||||
osg::ref_ptr<TagBase> mousePick (const QPoint& localPos);
|
||||
|
||||
std::string mapButton (QMouseEvent *event);
|
||||
|
||||
virtual std::string getStartupInstruction() = 0;
|
||||
|
||||
private slots:
|
||||
|
||||
void settingChanged (const CSMPrefs::Setting *setting);
|
||||
|
||||
void selectNavigationMode (const std::string& mode);
|
||||
|
||||
virtual void referenceableDataChanged (const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight) = 0;
|
||||
|
||||
|
|
29
extern/osgQt/GraphicsWindowQt
vendored
29
extern/osgQt/GraphicsWindowQt
vendored
|
@ -56,32 +56,15 @@ class GLWidget : public QGLWidget
|
|||
|
||||
public:
|
||||
|
||||
GLWidget( QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false );
|
||||
GLWidget( QGLContext* context, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false );
|
||||
GLWidget( const QGLFormat& format, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false );
|
||||
GLWidget( QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0);
|
||||
GLWidget( QGLContext* context, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0);
|
||||
GLWidget( const QGLFormat& format, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0);
|
||||
virtual ~GLWidget();
|
||||
|
||||
inline void setGraphicsWindow( GraphicsWindowQt* gw ) { _gw = gw; }
|
||||
inline GraphicsWindowQt* getGraphicsWindow() { return _gw; }
|
||||
inline const GraphicsWindowQt* getGraphicsWindow() const { return _gw; }
|
||||
|
||||
inline bool getForwardKeyEvents() const { return _forwardKeyEvents; }
|
||||
virtual void setForwardKeyEvents( bool f ) { _forwardKeyEvents = f; }
|
||||
|
||||
inline bool getTouchEventsEnabled() const { return _touchEventsEnabled; }
|
||||
void setTouchEventsEnabled( bool e );
|
||||
|
||||
void setKeyboardModifiers( QInputEvent* event );
|
||||
|
||||
virtual void keyPressEvent( QKeyEvent* event );
|
||||
virtual void keyReleaseEvent( QKeyEvent* event );
|
||||
virtual void mousePressEvent( QMouseEvent* event );
|
||||
virtual void mouseReleaseEvent( QMouseEvent* event );
|
||||
virtual void mouseDoubleClickEvent( QMouseEvent* event );
|
||||
virtual void mouseMoveEvent( QMouseEvent* event );
|
||||
virtual void wheelEvent( QWheelEvent* event );
|
||||
virtual bool gestureEvent( QGestureEvent* event );
|
||||
|
||||
protected:
|
||||
|
||||
int getNumDeferredEvents()
|
||||
|
@ -114,9 +97,6 @@ protected:
|
|||
QQueue<QEvent::Type> _deferredEventQueue;
|
||||
QSet<QEvent::Type> _eventCompressor;
|
||||
|
||||
bool _touchEventsEnabled;
|
||||
|
||||
bool _forwardKeyEvents;
|
||||
qreal _devicePixelRatio;
|
||||
|
||||
virtual void resizeEvent( QResizeEvent* event );
|
||||
|
@ -164,9 +144,6 @@ public:
|
|||
virtual std::string getWindowName();
|
||||
virtual void useCursor( bool cursorOn );
|
||||
virtual void setCursor( MouseCursor cursor );
|
||||
inline bool getTouchEventsEnabled() const { return _widget->getTouchEventsEnabled(); }
|
||||
virtual void setTouchEventsEnabled( bool e ) { _widget->setTouchEventsEnabled(e); }
|
||||
|
||||
|
||||
virtual bool valid() const;
|
||||
virtual bool realizeImplementation();
|
||||
|
|
322
extern/osgQt/GraphicsWindowQt.cpp
vendored
322
extern/osgQt/GraphicsWindowQt.cpp
vendored
|
@ -26,98 +26,6 @@
|
|||
|
||||
using namespace osgQt;
|
||||
|
||||
|
||||
class QtKeyboardMap
|
||||
{
|
||||
|
||||
public:
|
||||
QtKeyboardMap()
|
||||
{
|
||||
mKeyMap[Qt::Key_Escape ] = osgGA::GUIEventAdapter::KEY_Escape;
|
||||
mKeyMap[Qt::Key_Delete ] = osgGA::GUIEventAdapter::KEY_Delete;
|
||||
mKeyMap[Qt::Key_Home ] = osgGA::GUIEventAdapter::KEY_Home;
|
||||
mKeyMap[Qt::Key_Enter ] = osgGA::GUIEventAdapter::KEY_KP_Enter;
|
||||
mKeyMap[Qt::Key_End ] = osgGA::GUIEventAdapter::KEY_End;
|
||||
mKeyMap[Qt::Key_Return ] = osgGA::GUIEventAdapter::KEY_Return;
|
||||
mKeyMap[Qt::Key_PageUp ] = osgGA::GUIEventAdapter::KEY_Page_Up;
|
||||
mKeyMap[Qt::Key_PageDown ] = osgGA::GUIEventAdapter::KEY_Page_Down;
|
||||
mKeyMap[Qt::Key_Left ] = osgGA::GUIEventAdapter::KEY_Left;
|
||||
mKeyMap[Qt::Key_Right ] = osgGA::GUIEventAdapter::KEY_Right;
|
||||
mKeyMap[Qt::Key_Up ] = osgGA::GUIEventAdapter::KEY_Up;
|
||||
mKeyMap[Qt::Key_Down ] = osgGA::GUIEventAdapter::KEY_Down;
|
||||
mKeyMap[Qt::Key_Backspace ] = osgGA::GUIEventAdapter::KEY_BackSpace;
|
||||
mKeyMap[Qt::Key_Tab ] = osgGA::GUIEventAdapter::KEY_Tab;
|
||||
mKeyMap[Qt::Key_Space ] = osgGA::GUIEventAdapter::KEY_Space;
|
||||
mKeyMap[Qt::Key_Delete ] = osgGA::GUIEventAdapter::KEY_Delete;
|
||||
mKeyMap[Qt::Key_Alt ] = osgGA::GUIEventAdapter::KEY_Alt_L;
|
||||
mKeyMap[Qt::Key_Shift ] = osgGA::GUIEventAdapter::KEY_Shift_L;
|
||||
mKeyMap[Qt::Key_Control ] = osgGA::GUIEventAdapter::KEY_Control_L;
|
||||
mKeyMap[Qt::Key_Meta ] = osgGA::GUIEventAdapter::KEY_Meta_L;
|
||||
|
||||
mKeyMap[Qt::Key_F1 ] = osgGA::GUIEventAdapter::KEY_F1;
|
||||
mKeyMap[Qt::Key_F2 ] = osgGA::GUIEventAdapter::KEY_F2;
|
||||
mKeyMap[Qt::Key_F3 ] = osgGA::GUIEventAdapter::KEY_F3;
|
||||
mKeyMap[Qt::Key_F4 ] = osgGA::GUIEventAdapter::KEY_F4;
|
||||
mKeyMap[Qt::Key_F5 ] = osgGA::GUIEventAdapter::KEY_F5;
|
||||
mKeyMap[Qt::Key_F6 ] = osgGA::GUIEventAdapter::KEY_F6;
|
||||
mKeyMap[Qt::Key_F7 ] = osgGA::GUIEventAdapter::KEY_F7;
|
||||
mKeyMap[Qt::Key_F8 ] = osgGA::GUIEventAdapter::KEY_F8;
|
||||
mKeyMap[Qt::Key_F9 ] = osgGA::GUIEventAdapter::KEY_F9;
|
||||
mKeyMap[Qt::Key_F10 ] = osgGA::GUIEventAdapter::KEY_F10;
|
||||
mKeyMap[Qt::Key_F11 ] = osgGA::GUIEventAdapter::KEY_F11;
|
||||
mKeyMap[Qt::Key_F12 ] = osgGA::GUIEventAdapter::KEY_F12;
|
||||
mKeyMap[Qt::Key_F13 ] = osgGA::GUIEventAdapter::KEY_F13;
|
||||
mKeyMap[Qt::Key_F14 ] = osgGA::GUIEventAdapter::KEY_F14;
|
||||
mKeyMap[Qt::Key_F15 ] = osgGA::GUIEventAdapter::KEY_F15;
|
||||
mKeyMap[Qt::Key_F16 ] = osgGA::GUIEventAdapter::KEY_F16;
|
||||
mKeyMap[Qt::Key_F17 ] = osgGA::GUIEventAdapter::KEY_F17;
|
||||
mKeyMap[Qt::Key_F18 ] = osgGA::GUIEventAdapter::KEY_F18;
|
||||
mKeyMap[Qt::Key_F19 ] = osgGA::GUIEventAdapter::KEY_F19;
|
||||
mKeyMap[Qt::Key_F20 ] = osgGA::GUIEventAdapter::KEY_F20;
|
||||
|
||||
mKeyMap[Qt::Key_hyphen ] = '-';
|
||||
mKeyMap[Qt::Key_Equal ] = '=';
|
||||
|
||||
mKeyMap[Qt::Key_division ] = osgGA::GUIEventAdapter::KEY_KP_Divide;
|
||||
mKeyMap[Qt::Key_multiply ] = osgGA::GUIEventAdapter::KEY_KP_Multiply;
|
||||
mKeyMap[Qt::Key_Minus ] = '-';
|
||||
mKeyMap[Qt::Key_Plus ] = '+';
|
||||
//mKeyMap[Qt::Key_H ] = osgGA::GUIEventAdapter::KEY_KP_Home;
|
||||
//mKeyMap[Qt::Key_ ] = osgGA::GUIEventAdapter::KEY_KP_Up;
|
||||
//mKeyMap[92 ] = osgGA::GUIEventAdapter::KEY_KP_Page_Up;
|
||||
//mKeyMap[86 ] = osgGA::GUIEventAdapter::KEY_KP_Left;
|
||||
//mKeyMap[87 ] = osgGA::GUIEventAdapter::KEY_KP_Begin;
|
||||
//mKeyMap[88 ] = osgGA::GUIEventAdapter::KEY_KP_Right;
|
||||
//mKeyMap[83 ] = osgGA::GUIEventAdapter::KEY_KP_End;
|
||||
//mKeyMap[84 ] = osgGA::GUIEventAdapter::KEY_KP_Down;
|
||||
//mKeyMap[85 ] = osgGA::GUIEventAdapter::KEY_KP_Page_Down;
|
||||
mKeyMap[Qt::Key_Insert ] = osgGA::GUIEventAdapter::KEY_KP_Insert;
|
||||
//mKeyMap[Qt::Key_Delete ] = osgGA::GUIEventAdapter::KEY_KP_Delete;
|
||||
}
|
||||
|
||||
~QtKeyboardMap()
|
||||
{
|
||||
}
|
||||
|
||||
int remapKey(QKeyEvent* event)
|
||||
{
|
||||
KeyMap::iterator itr = mKeyMap.find(event->key());
|
||||
if (itr == mKeyMap.end())
|
||||
{
|
||||
return int(*(event->text().toLatin1().data()));
|
||||
}
|
||||
else
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::map<unsigned int, int> KeyMap;
|
||||
KeyMap mKeyMap;
|
||||
};
|
||||
|
||||
static QtKeyboardMap s_QtKeyboardMap;
|
||||
|
||||
|
||||
/// The object responsible for the scene re-rendering.
|
||||
class HeartBeat : public QObject {
|
||||
public:
|
||||
|
@ -146,31 +54,20 @@ QPointer<HeartBeat> HeartBeat::heartBeat;
|
|||
#define GETDEVICEPIXELRATIO() devicePixelRatio()
|
||||
#endif
|
||||
|
||||
GLWidget::GLWidget( QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f, bool forwardKeyEvents )
|
||||
: QGLWidget(parent, shareWidget, f),
|
||||
_gw( NULL ),
|
||||
_touchEventsEnabled( false ),
|
||||
_forwardKeyEvents( forwardKeyEvents )
|
||||
GLWidget::GLWidget( QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f)
|
||||
: QGLWidget(parent, shareWidget, f), _gw( NULL )
|
||||
{
|
||||
_devicePixelRatio = GETDEVICEPIXELRATIO();
|
||||
}
|
||||
|
||||
GLWidget::GLWidget( QGLContext* context, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f,
|
||||
bool forwardKeyEvents )
|
||||
: QGLWidget(context, parent, shareWidget, f),
|
||||
_gw( NULL ),
|
||||
_touchEventsEnabled( false ),
|
||||
_forwardKeyEvents( forwardKeyEvents )
|
||||
GLWidget::GLWidget( QGLContext* context, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f)
|
||||
: QGLWidget(context, parent, shareWidget, f), _gw( NULL )
|
||||
{
|
||||
_devicePixelRatio = GETDEVICEPIXELRATIO();
|
||||
}
|
||||
|
||||
GLWidget::GLWidget( const QGLFormat& format, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f,
|
||||
bool forwardKeyEvents )
|
||||
: QGLWidget(format, parent, shareWidget, f),
|
||||
_gw( NULL ),
|
||||
_touchEventsEnabled( false ),
|
||||
_forwardKeyEvents( forwardKeyEvents )
|
||||
GLWidget::GLWidget( const QGLFormat& format, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f)
|
||||
: QGLWidget(format, parent, shareWidget, f), _gw( NULL )
|
||||
{
|
||||
_devicePixelRatio = GETDEVICEPIXELRATIO();
|
||||
}
|
||||
|
@ -186,25 +83,6 @@ GLWidget::~GLWidget()
|
|||
}
|
||||
}
|
||||
|
||||
void GLWidget::setTouchEventsEnabled(bool e)
|
||||
{
|
||||
#ifdef USE_GESTURES
|
||||
if (e==_touchEventsEnabled)
|
||||
return;
|
||||
|
||||
_touchEventsEnabled = e;
|
||||
|
||||
if (_touchEventsEnabled)
|
||||
{
|
||||
grabGesture(Qt::PinchGesture);
|
||||
}
|
||||
else
|
||||
{
|
||||
ungrabGesture(Qt::PinchGesture);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLWidget::processDeferredEvents()
|
||||
{
|
||||
QQueue<QEvent::Type> deferredEventQueueCopy;
|
||||
|
@ -224,10 +102,6 @@ void GLWidget::processDeferredEvents()
|
|||
|
||||
bool GLWidget::event( QEvent* event )
|
||||
{
|
||||
#ifdef USE_GESTURES
|
||||
if ( event->type()==QEvent::Gesture )
|
||||
return gestureEvent(static_cast<QGestureEvent*>(event));
|
||||
#endif
|
||||
|
||||
// QEvent::Hide
|
||||
//
|
||||
|
@ -274,16 +148,6 @@ bool GLWidget::event( QEvent* event )
|
|||
return QGLWidget::event( event );
|
||||
}
|
||||
|
||||
void GLWidget::setKeyboardModifiers( QInputEvent* event )
|
||||
{
|
||||
int modkey = event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier);
|
||||
unsigned int mask = 0;
|
||||
if ( modkey & Qt::ShiftModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
|
||||
if ( modkey & Qt::ControlModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_CTRL;
|
||||
if ( modkey & Qt::AltModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_ALT;
|
||||
_gw->getEventQueue()->getCurrentEventState()->setModKeyMask( mask );
|
||||
}
|
||||
|
||||
void GLWidget::resizeEvent( QResizeEvent* event )
|
||||
{
|
||||
const QSize& size = event->size();
|
||||
|
@ -309,178 +173,6 @@ void GLWidget::glDraw()
|
|||
_gw->requestRedraw();
|
||||
}
|
||||
|
||||
void GLWidget::keyPressEvent( QKeyEvent* event )
|
||||
{
|
||||
setKeyboardModifiers( event );
|
||||
int value = s_QtKeyboardMap.remapKey( event );
|
||||
_gw->getEventQueue()->keyPress( value );
|
||||
|
||||
// this passes the event to the regular Qt key event processing,
|
||||
// among others, it closes popup windows on ESC and forwards the event to the parent widgets
|
||||
if( _forwardKeyEvents )
|
||||
inherited::keyPressEvent( event );
|
||||
}
|
||||
|
||||
void GLWidget::keyReleaseEvent( QKeyEvent* event )
|
||||
{
|
||||
if( event->isAutoRepeat() )
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
else
|
||||
{
|
||||
setKeyboardModifiers( event );
|
||||
int value = s_QtKeyboardMap.remapKey( event );
|
||||
_gw->getEventQueue()->keyRelease( value );
|
||||
}
|
||||
|
||||
// this passes the event to the regular Qt key event processing,
|
||||
// among others, it closes popup windows on ESC and forwards the event to the parent widgets
|
||||
if( _forwardKeyEvents )
|
||||
inherited::keyReleaseEvent( event );
|
||||
}
|
||||
|
||||
void GLWidget::mousePressEvent( QMouseEvent* event )
|
||||
{
|
||||
int button = 0;
|
||||
switch ( event->button() )
|
||||
{
|
||||
case Qt::LeftButton: button = 1; break;
|
||||
case Qt::MidButton: button = 2; break;
|
||||
case Qt::RightButton: button = 3; break;
|
||||
case Qt::NoButton: button = 0; break;
|
||||
default: button = 0; break;
|
||||
}
|
||||
setKeyboardModifiers( event );
|
||||
_gw->getEventQueue()->mouseButtonPress( event->x()*_devicePixelRatio, event->y()*_devicePixelRatio, button );
|
||||
}
|
||||
|
||||
void GLWidget::mouseReleaseEvent( QMouseEvent* event )
|
||||
{
|
||||
int button = 0;
|
||||
switch ( event->button() )
|
||||
{
|
||||
case Qt::LeftButton: button = 1; break;
|
||||
case Qt::MidButton: button = 2; break;
|
||||
case Qt::RightButton: button = 3; break;
|
||||
case Qt::NoButton: button = 0; break;
|
||||
default: button = 0; break;
|
||||
}
|
||||
setKeyboardModifiers( event );
|
||||
_gw->getEventQueue()->mouseButtonRelease( event->x()*_devicePixelRatio, event->y()*_devicePixelRatio, button );
|
||||
}
|
||||
|
||||
void GLWidget::mouseDoubleClickEvent( QMouseEvent* event )
|
||||
{
|
||||
int button = 0;
|
||||
switch ( event->button() )
|
||||
{
|
||||
case Qt::LeftButton: button = 1; break;
|
||||
case Qt::MidButton: button = 2; break;
|
||||
case Qt::RightButton: button = 3; break;
|
||||
case Qt::NoButton: button = 0; break;
|
||||
default: button = 0; break;
|
||||
}
|
||||
setKeyboardModifiers( event );
|
||||
_gw->getEventQueue()->mouseDoubleButtonPress( event->x()*_devicePixelRatio, event->y()*_devicePixelRatio, button );
|
||||
}
|
||||
|
||||
void GLWidget::mouseMoveEvent( QMouseEvent* event )
|
||||
{
|
||||
setKeyboardModifiers( event );
|
||||
_gw->getEventQueue()->mouseMotion( event->x()*_devicePixelRatio, event->y()*_devicePixelRatio );
|
||||
}
|
||||
|
||||
void GLWidget::wheelEvent( QWheelEvent* event )
|
||||
{
|
||||
setKeyboardModifiers( event );
|
||||
_gw->getEventQueue()->mouseScroll(
|
||||
event->orientation() == Qt::Vertical ?
|
||||
(event->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN) :
|
||||
(event->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_LEFT : osgGA::GUIEventAdapter::SCROLL_RIGHT) );
|
||||
}
|
||||
|
||||
#ifdef USE_GESTURES
|
||||
static osgGA::GUIEventAdapter::TouchPhase translateQtGestureState( Qt::GestureState state )
|
||||
{
|
||||
osgGA::GUIEventAdapter::TouchPhase touchPhase;
|
||||
switch ( state )
|
||||
{
|
||||
case Qt::GestureStarted:
|
||||
touchPhase = osgGA::GUIEventAdapter::TOUCH_BEGAN;
|
||||
break;
|
||||
case Qt::GestureUpdated:
|
||||
touchPhase = osgGA::GUIEventAdapter::TOUCH_MOVED;
|
||||
break;
|
||||
case Qt::GestureFinished:
|
||||
case Qt::GestureCanceled:
|
||||
touchPhase = osgGA::GUIEventAdapter::TOUCH_ENDED;
|
||||
break;
|
||||
default:
|
||||
touchPhase = osgGA::GUIEventAdapter::TOUCH_UNKNOWN;
|
||||
};
|
||||
|
||||
return touchPhase;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool GLWidget::gestureEvent( QGestureEvent* qevent )
|
||||
{
|
||||
#ifndef USE_GESTURES
|
||||
return false;
|
||||
#else
|
||||
|
||||
bool accept = false;
|
||||
|
||||
if ( QPinchGesture* pinch = static_cast<QPinchGesture *>(qevent->gesture(Qt::PinchGesture) ) )
|
||||
{
|
||||
const QPointF qcenterf = pinch->centerPoint();
|
||||
const float angle = pinch->totalRotationAngle();
|
||||
const float scale = pinch->totalScaleFactor();
|
||||
|
||||
const QPoint pinchCenterQt = mapFromGlobal(qcenterf.toPoint());
|
||||
const osg::Vec2 pinchCenter( pinchCenterQt.x(), pinchCenterQt.y() );
|
||||
|
||||
//We don't have absolute positions of the two touches, only a scale and rotation
|
||||
//Hence we create pseudo-coordinates which are reasonable, and centered around the
|
||||
//real position
|
||||
const float radius = (width()+height())/4;
|
||||
const osg::Vec2 vector( scale*cos(angle)*radius, scale*sin(angle)*radius);
|
||||
const osg::Vec2 p0 = pinchCenter+vector;
|
||||
const osg::Vec2 p1 = pinchCenter-vector;
|
||||
|
||||
osg::ref_ptr<osgGA::GUIEventAdapter> event = 0;
|
||||
const osgGA::GUIEventAdapter::TouchPhase touchPhase = translateQtGestureState( pinch->state() );
|
||||
if ( touchPhase==osgGA::GUIEventAdapter::TOUCH_BEGAN )
|
||||
{
|
||||
event = _gw->getEventQueue()->touchBegan(0 , touchPhase, p0[0], p0[1] );
|
||||
}
|
||||
else if ( touchPhase==osgGA::GUIEventAdapter::TOUCH_MOVED )
|
||||
{
|
||||
event = _gw->getEventQueue()->touchMoved( 0, touchPhase, p0[0], p0[1] );
|
||||
}
|
||||
else
|
||||
{
|
||||
event = _gw->getEventQueue()->touchEnded( 0, touchPhase, p0[0], p0[1], 1 );
|
||||
}
|
||||
|
||||
if ( event )
|
||||
{
|
||||
event->addTouchPoint( 1, touchPhase, p1[0], p1[1] );
|
||||
accept = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( accept )
|
||||
qevent->accept();
|
||||
|
||||
return accept;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
GraphicsWindowQt::GraphicsWindowQt( osg::GraphicsContext::Traits* traits, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f )
|
||||
: _realized(false)
|
||||
{
|
||||
|
@ -1016,7 +708,7 @@ void HeartBeat::init( osgViewer::ViewerBase *viewer )
|
|||
}
|
||||
|
||||
|
||||
void HeartBeat::timerEvent( QTimerEvent */*event*/ )
|
||||
void HeartBeat::timerEvent( QTimerEvent * /*event*/ )
|
||||
{
|
||||
osg::ref_ptr< osgViewer::ViewerBase > viewer;
|
||||
if( !_viewer.lock( viewer ) )
|
||||
|
|
Loading…
Reference in a new issue