Merge remote-tracking branch 'aesylwinn/editor_camera'

openmw-39
Marc Zinnschlag 9 years ago
commit 60509875e8

@ -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);

@ -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);
}
}

@ -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

@ -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();
}
}

@ -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
public:
RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
virtual ~RenderWidget();
Q_OBJECT
void flagAsModified();
public:
RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
virtual ~RenderWidget();
void setVisibilityMask(int mask);
void flagAsModified();
bool eventFilter(QObject *, QEvent *);
void setVisibilityMask(int mask);
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.
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.
void setAmbient(const osg::Vec4f& ambient);
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.
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);
void setDefaultAmbient (const osg::Vec4f& colour);
///< \note The actual ambient colour may differ based on lighting settings.
/// \return Is \a key a button mapping setting? (ignored otherwise)
virtual bool storeMappingSetting (const CSMPrefs::Setting *setting);
protected:
void setLighting (Lighting *lighting);
///< \attention The ownership of \a lighting is not transferred to *this.
std::string mapButton (QMouseEvent *event);
void setAmbient(const osg::Vec4f& ambient);
boost::shared_ptr<Resource::ResourceSystem> mResourceSystem;
boost::shared_ptr<Resource::ResourceSystem> mResourceSystem;
Lighting* mLighting;
Lighting* mLighting;
osg::Vec4f mDefaultAmbient;
bool mHasDefaultAmbient;
LightingDay mLightingDay;
LightingNight mLightingNight;
LightingBright mLightingBright;
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;
private slots:
std::map<std::pair<Qt::MouseButton, bool>, std::string> mButtonMapping;
void selectLightingMode (const std::string& mode);
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;

@ -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();

@ -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…
Cancel
Save