Refactor edit mode. Remove essentially duplicate function.

pull/1/head
Aesylwinn 9 years ago
parent 13c2161b27
commit ae0d2c3b9c

@ -37,29 +37,29 @@ void CSVRender::EditMode::primarySelectPressed (const WorldspaceHitResult& hit)
void CSVRender::EditMode::secondarySelectPressed (const WorldspaceHitResult& hit) {}
bool CSVRender::EditMode::primaryEditStartDrag (const WorldspaceHitResult& hit)
bool CSVRender::EditMode::primaryEditStartDrag (const QPoint& pos)
{
return false;
}
bool CSVRender::EditMode::secondaryEditStartDrag (const WorldspaceHitResult& hit)
bool CSVRender::EditMode::secondaryEditStartDrag (const QPoint& pos)
{
return false;
}
bool CSVRender::EditMode::primarySelectStartDrag (const WorldspaceHitResult& hit)
bool CSVRender::EditMode::primarySelectStartDrag (const QPoint& pos)
{
return false;
}
bool CSVRender::EditMode::secondarySelectStartDrag (const WorldspaceHitResult& hit)
bool CSVRender::EditMode::secondarySelectStartDrag (const QPoint& pos)
{
return false;
}
void CSVRender::EditMode::drag (int diffX, int diffY, double speedFactor) {}
void CSVRender::EditMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor) {}
void CSVRender::EditMode::dragCompleted(const WorldspaceHitResult& hit) {}
void CSVRender::EditMode::dragCompleted(const QPoint& pos) {}
void CSVRender::EditMode::dragAborted() {}
@ -67,7 +67,7 @@ void CSVRender::EditMode::dragWheel (int diff, double speedFactor) {}
void CSVRender::EditMode::dragEnterEvent (QDragEnterEvent *event) {}
void CSVRender::EditMode::dropEvent (QDropEvent* event) {}
void CSVRender::EditMode::dropEvent (QDropEvent *event) {}
void CSVRender::EditMode::dragMoveEvent (QDragMoveEvent *event) {}

@ -8,6 +8,7 @@
class QDragEnterEvent;
class QDropEvent;
class QDragMoveEvent;
class QPoint;
namespace CSVRender
{
@ -53,28 +54,28 @@ namespace CSVRender
/// Default-implementation: ignore and return false
///
/// \return Drag accepted?
virtual bool primaryEditStartDrag (const WorldspaceHitResult& hit);
virtual bool primaryEditStartDrag (const QPoint& pos);
/// Default-implementation: ignore and return false
///
/// \return Drag accepted?
virtual bool secondaryEditStartDrag (const WorldspaceHitResult& hit);
virtual bool secondaryEditStartDrag (const QPoint& pos);
/// Default-implementation: ignore and return false
///
/// \return Drag accepted?
virtual bool primarySelectStartDrag (const WorldspaceHitResult& hit);
virtual bool primarySelectStartDrag (const QPoint& pos);
/// Default-implementation: ignore and return false
///
/// \return Drag accepted?
virtual bool secondarySelectStartDrag (const WorldspaceHitResult& hit);
virtual bool secondarySelectStartDrag (const QPoint& pos);
/// Default-implementation: ignored
virtual void drag (int diffX, int diffY, double speedFactor);
virtual void drag (const QPoint& pos, int diffX, int diffY, double speedFactor);
/// Default-implementation: ignored
virtual void dragCompleted(const WorldspaceHitResult& hit);
virtual void dragCompleted(const QPoint& pos);
/// Default-implementation: ignored
///
@ -89,7 +90,7 @@ namespace CSVRender
virtual void dragEnterEvent (QDragEnterEvent *event);
/// Default-implementation: ignored
virtual void dropEvent (QDropEvent* event);
virtual void dropEvent (QDropEvent *event);
/// Default-implementation: ignored
virtual void dragMoveEvent (QDragMoveEvent *event);

@ -2,6 +2,7 @@
#include "instancemode.hpp"
#include <QDragEnterEvent>
#include <QPoint>
#include "../../model/prefs/state.hpp"
@ -145,11 +146,12 @@ void CSVRender::InstanceMode::secondarySelectPressed (const WorldspaceHitResult&
}
}
bool CSVRender::InstanceMode::primaryEditStartDrag (const WorldspaceHitResult& hit)
bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos)
{
if (mDragMode!=DragMode_None || mLocked)
return false;
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask());
if (hit.tag && CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
{
getWorldspaceWidget().clearSelection (Mask_Reference);
@ -189,7 +191,7 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const WorldspaceHitResult& h
return true;
}
bool CSVRender::InstanceMode::secondaryEditStartDrag (const WorldspaceHitResult& hit)
bool CSVRender::InstanceMode::secondaryEditStartDrag (const QPoint& pos)
{
if (mLocked)
return false;
@ -197,7 +199,7 @@ bool CSVRender::InstanceMode::secondaryEditStartDrag (const WorldspaceHitResult&
return false;
}
void CSVRender::InstanceMode::drag (int diffX, int diffY, double speedFactor)
void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor)
{
osg::Vec3f eye;
osg::Vec3f centre;
@ -244,7 +246,7 @@ void CSVRender::InstanceMode::drag (int diffX, int diffY, double speedFactor)
}
}
void CSVRender::InstanceMode::dragCompleted(const WorldspaceHitResult& hit)
void CSVRender::InstanceMode::dragCompleted(const QPoint& pos)
{
std::vector<osg::ref_ptr<TagBase> > selection =
getWorldspaceWidget().getEdited (Mask_Reference);
@ -333,9 +335,9 @@ void CSVRender::InstanceMode::dropEvent (QDropEvent* event)
if (!mime->fromDocument (document))
return;
osg::Vec3f insertPoint = getWorldspaceWidget().getIntersectionPoint (event->pos());
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (event->pos(), getWorldspaceWidget().getInteractionMask());
std::string cellId = getWorldspaceWidget().getCellId (insertPoint);
std::string cellId = getWorldspaceWidget().getCellId (hit.worldPos);
CSMWorld::IdTree& cellTable = dynamic_cast<CSMWorld::IdTree&> (
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
@ -412,11 +414,11 @@ void CSVRender::InstanceMode::dropEvent (QDropEvent* event)
createCommand->addValue (referencesTable.findColumnIndex (
CSMWorld::Columns::ColumnId_Cell), QString::fromUtf8 (cellId.c_str()));
createCommand->addValue (referencesTable.findColumnIndex (
CSMWorld::Columns::ColumnId_PositionXPos), insertPoint.x());
CSMWorld::Columns::ColumnId_PositionXPos), hit.worldPos.x());
createCommand->addValue (referencesTable.findColumnIndex (
CSMWorld::Columns::ColumnId_PositionYPos), insertPoint.y());
CSMWorld::Columns::ColumnId_PositionYPos), hit.worldPos.y());
createCommand->addValue (referencesTable.findColumnIndex (
CSMWorld::Columns::ColumnId_PositionZPos), insertPoint.z());
CSMWorld::Columns::ColumnId_PositionZPos), hit.worldPos.z());
createCommand->addValue (referencesTable.findColumnIndex (
CSMWorld::Columns::ColumnId_ReferenceableId),
QString::fromUtf8 (iter->getId().c_str()));

@ -49,13 +49,13 @@ namespace CSVRender
virtual void secondarySelectPressed (const WorldspaceHitResult& hit);
virtual bool primaryEditStartDrag (const WorldspaceHitResult& hit);
virtual bool primaryEditStartDrag (const QPoint& pos);
virtual bool secondaryEditStartDrag (const WorldspaceHitResult& hit);
virtual bool secondaryEditStartDrag (const QPoint& pos);
virtual void drag (int diffX, int diffY, double speedFactor);
virtual void drag (const QPoint& pos, int diffX, int diffY, double speedFactor);
virtual void dragCompleted(const WorldspaceHitResult& hit);
virtual void dragCompleted(const QPoint& pos);
/// \note dragAborted will not be called, if the drag is aborted via changing
/// editing mode
@ -65,7 +65,7 @@ namespace CSVRender
virtual void dragEnterEvent (QDragEnterEvent *event);
virtual void dropEvent (QDropEvent* event);
virtual void dropEvent (QDropEvent *event);
virtual int getSubMode() const;

@ -1,6 +1,7 @@
#include "pathgridmode.hpp"
#include <QMenu>
#include <QPoint>
#include <components/sceneutil/pathgridutil.hpp>
@ -69,27 +70,8 @@ namespace CSVRender
void PathgridMode::primaryEditPressed(const WorldspaceHitResult& hitResult)
{
// Determine placement
osg::Vec3d position;
if (hitResult.hit)
{
position = hitResult.worldPos;
}
else
{
const double DefaultDistance = 500.f;
osg::Vec3d eye, center, up, offset;
getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt (eye, center, up);
osg::Vec3d direction = center - eye;
direction.normalize();
position = eye + direction * DefaultDistance;
}
// Get pathgrid cell
Cell* cell = getWorldspaceWidget().getCell (position);
Cell* cell = getWorldspaceWidget().getCell (hitResult.worldPos);
if (cell)
{
// Add node
@ -97,7 +79,7 @@ namespace CSVRender
QString description = "Connect node to selected nodes";
CSMWorld::CommandMacro macro(undoStack, description);
cell->getPathgrid()->applyPoint(macro, position);
cell->getPathgrid()->applyPoint(macro, hitResult.worldPos);
}
}
@ -158,7 +140,7 @@ namespace CSVRender
getWorldspaceWidget().clearSelection(Mask_Pathgrid);
}
bool PathgridMode::primaryEditStartDrag(const WorldspaceHitResult& hit)
bool PathgridMode::primaryEditStartDrag(const QPoint& pos)
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
@ -170,8 +152,9 @@ namespace CSVRender
return true;
}
bool PathgridMode::secondaryEditStartDrag(const WorldspaceHitResult& hit)
bool PathgridMode::secondaryEditStartDrag(const QPoint& pos)
{
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask());
if (hit.tag)
{
if (PathgridTag* tag = dynamic_cast<PathgridTag*>(hit.tag.get()))
@ -187,7 +170,7 @@ namespace CSVRender
return true;
}
void PathgridMode::drag(int diffX, int diffY, double speedFactor)
void PathgridMode::drag(const QPoint& pos, int diffX, int diffY, double speedFactor)
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
@ -212,7 +195,7 @@ namespace CSVRender
}
}
void PathgridMode::dragCompleted(const WorldspaceHitResult& hit)
void PathgridMode::dragCompleted(const QPoint& pos)
{
if (mDragMode == DragMode_Move)
{
@ -231,6 +214,8 @@ namespace CSVRender
}
else if (mDragMode == DragMode_Edge)
{
WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask());
if (hit.tag)
{
if (PathgridTag* tag = dynamic_cast<PathgridTag*>(hit.tag.get()))

@ -27,13 +27,13 @@ namespace CSVRender
virtual void secondarySelectPressed(const WorldspaceHitResult& hit);
virtual bool primaryEditStartDrag (const WorldspaceHitResult& hit);
virtual bool primaryEditStartDrag (const QPoint& pos);
virtual bool secondaryEditStartDrag (const WorldspaceHitResult& hit);
virtual bool secondaryEditStartDrag (const QPoint& pos);
virtual void drag (int diffX, int diffY, double speedFactor);
virtual void drag (const QPoint& pos, int diffX, int diffY, double speedFactor);
virtual void dragCompleted(const WorldspaceHitResult& hit);
virtual void dragCompleted(const QPoint& pos);
/// \note dragAborted will not be called, if the drag is aborted via changing
/// editing mode

@ -326,39 +326,64 @@ CSMDoc::Document& CSVRender::WorldspaceWidget::getDocument()
return mDocument;
}
osg::Vec3f CSVRender::WorldspaceWidget::getIntersectionPoint (const QPoint& localPos,
unsigned int interactionMask, bool ignoreHidden) const
CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPoint& localPos,
unsigned int interactionMask) const
{
// (0,0) is considered the lower left corner of an OpenGL window
int x = localPos.x();
int y = height() - localPos.y();
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (
new osgUtil::LineSegmentIntersector (osgUtil::Intersector::WINDOW, x, y));
// Get intersection
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (new osgUtil::LineSegmentIntersector(
osgUtil::Intersector::WINDOW, x, y));
intersector->setIntersectionLimit (osgUtil::LineSegmentIntersector::NO_LIMIT);
osgUtil::IntersectionVisitor visitor (intersector);
unsigned int mask = interactionMask;
if (ignoreHidden)
mask &= getVisibilityMask();
intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT);
osgUtil::IntersectionVisitor visitor(intersector);
visitor.setTraversalMask (mask);
visitor.setTraversalMask(interactionMask);
mView->getCamera()->accept (visitor);
mView->getCamera()->accept(visitor);
for (osgUtil::LineSegmentIntersector::Intersections::iterator iter = intersector->getIntersections().begin();
iter!=intersector->getIntersections().end(); ++iter)
// Get relevant data
for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin();
it != intersector->getIntersections().end(); ++it)
{
osgUtil::LineSegmentIntersector::Intersection intersection = *it;
// reject back-facing polygons
osg::Vec3f normal = osg::Matrix::transform3x3 (
iter->getWorldIntersectNormal(), mView->getCamera()->getViewMatrix());
osg::Vec3f normal = intersection.getWorldIntersectNormal();
normal = osg::Matrix::transform3x3(normal, mView->getCamera()->getViewMatrix());
if (normal.z() < 0)
continue;
if (normal.z()>=0)
return iter->getWorldIntersectPoint();
for (std::vector<osg::Node*>::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it)
{
osg::Node* node = *it;
if (osg::ref_ptr<CSVRender::TagBase> tag = dynamic_cast<CSVRender::TagBase *>(node->getUserData()))
{
WorldspaceHitResult hit = { true, tag, 0, 0, 0, intersection.getWorldIntersectPoint() };
if (intersection.indexList.size() >= 3)
{
hit.index0 = intersection.indexList[0];
hit.index1 = intersection.indexList[1];
hit.index2 = intersection.indexList[2];
}
return hit;
}
}
// Something untagged, probably terrain
WorldspaceHitResult hit = { true, 0, 0, 0, 0, intersection.getWorldIntersectPoint() };
if (intersection.indexList.size() >= 3)
{
hit.index0 = intersection.indexList[0];
hit.index1 = intersection.indexList[1];
hit.index2 = intersection.indexList[2];
}
return hit;
}
// Default placement
osg::Matrixd matrix;
matrix.preMult (mView->getCamera()->getViewport()->computeWindowMatrix());
matrix.preMult (mView->getCamera()->getProjectionMatrix());
@ -368,10 +393,12 @@ osg::Vec3f CSVRender::WorldspaceWidget::getIntersectionPoint (const QPoint& loca
osg::Vec3d start = matrix.preMult (intersector->getStart());
osg::Vec3d end = matrix.preMult (intersector->getEnd());
osg::Vec3d direction = end-start;
osg::Vec3d direction = end - start;
direction.normalize();
direction *= CSMPrefs::get()["Scene Drops"]["distance"].toInt();
return start + direction * CSMPrefs::get()["Scene Drops"]["distance"].toInt();
WorldspaceHitResult hit = { false, 0, 0, 0, 0, start + direction };
return hit;
}
void CSVRender::WorldspaceWidget::abortDrag()
@ -465,63 +492,6 @@ bool CSVRender::WorldspaceWidget::storeMappingSetting (const CSMPrefs::Setting *
return SceneWidget::storeMappingSetting(setting);
}
CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPoint& localPos)
{
// (0,0) is considered the lower left corner of an OpenGL window
int x = localPos.x();
int y = height() - localPos.y();
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y));
intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT);
osgUtil::IntersectionVisitor visitor(intersector);
visitor.setTraversalMask(getInteractionMask());
mView->getCamera()->accept(visitor);
for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin();
it != intersector->getIntersections().end(); ++it)
{
osgUtil::LineSegmentIntersector::Intersection intersection = *it;
// reject back-facing polygons
osg::Vec3f normal = intersection.getWorldIntersectNormal();
normal = osg::Matrix::transform3x3(normal, mView->getCamera()->getViewMatrix());
if (normal.z() < 0)
continue;
for (std::vector<osg::Node*>::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it)
{
osg::Node* node = *it;
if (osg::ref_ptr<CSVRender::TagBase> tag = dynamic_cast<CSVRender::TagBase *>(node->getUserData()))
{
WorldspaceHitResult hit = { true, tag, 0, 0, 0, intersection.getWorldIntersectPoint() };
if (intersection.indexList.size() >= 3)
{
hit.index0 = intersection.indexList[0];
hit.index1 = intersection.indexList[1];
hit.index2 = intersection.indexList[2];
}
return hit;
}
}
// Something untagged, probably terrain
WorldspaceHitResult hit = { true, 0, 0, 0, 0, intersection.getWorldIntersectPoint() };
if (intersection.indexList.size() >= 3)
{
hit.index0 = intersection.indexList[0];
hit.index1 = intersection.indexList[1];
hit.index2 = intersection.indexList[2];
}
return hit;
}
WorldspaceHitResult hit = { false, 0, 0, 0, 0, osg::Vec3d() };
return hit;
}
void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event)
{
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
@ -606,7 +576,7 @@ void CSVRender::WorldspaceWidget::showToolTip()
{
QPoint pos = QCursor::pos();
WorldspaceHitResult hit = mousePick (mapFromGlobal (pos));
WorldspaceHitResult hit = mousePick (mapFromGlobal (pos), getInteractionMask());
if (hit.tag)
{
bool hideBasics = CSMPrefs::get()["Tooltips"]["scene-hide-basic"].isTrue();
@ -643,22 +613,20 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
editMode.drag (diffX, diffY, factor);
editMode.drag (event->pos(), diffX, diffY, factor);
}
else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="p-select" || mDragMode=="s-select")
{
WorldspaceHitResult hit = mousePick (event->pos());
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
if (mDragMode=="p-edit")
mDragging = editMode.primaryEditStartDrag (hit);
mDragging = editMode.primaryEditStartDrag (event->pos());
else if (mDragMode=="s-edit")
mDragging = editMode.secondaryEditStartDrag (hit);
mDragging = editMode.secondaryEditStartDrag (event->pos());
else if (mDragMode=="p-select")
mDragging = editMode.primarySelectStartDrag (hit);
mDragging = editMode.primarySelectStartDrag (event->pos());
else if (mDragMode=="s-select")
mDragging = editMode.secondarySelectStartDrag (hit);
mDragging = editMode.secondarySelectStartDrag (event->pos());
if (mDragging)
{
@ -710,14 +678,13 @@ void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event)
if (mDragging)
{
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
WorldspaceHitResult hit = mousePick (event->pos());
editMode.dragCompleted(hit);
editMode.dragCompleted(event->pos());
mDragging = false;
}
else
{
WorldspaceHitResult hit = mousePick (event->pos());
WorldspaceHitResult hit = mousePick(event->pos(), getInteractionMask());
handleMouseClick (hit, button, event->modifiers() & Qt::ShiftModifier);
}

@ -149,16 +149,11 @@ namespace CSVRender
/// \param elementMask Elements to be affected by the select operation
virtual void selectAllWithSameParentId (int elementMask) = 0;
/// Return the next intersection point with scene elements matched by
/// Return the next intersection with scene elements matched by
/// \a interactionMask based on \a localPos and the camera vector.
/// If there is no such point, instead a point "in front" of \a localPos will be
/// If there is no such intersection, instead a point "in front" of \a localPos will be
/// returned.
///
/// \param ignoreHidden ignore elements specified in interactionMask that are
/// flagged as not visible.
osg::Vec3f getIntersectionPoint (const QPoint& localPos,
unsigned int interactionMask = Mask_Reference | Mask_Terrain,
bool ignoreHidden = false) const;
WorldspaceHitResult mousePick (const QPoint& localPos, unsigned int interactionMask) const;
virtual std::string getCellId (const osg::Vec3f& point) const = 0;
@ -225,8 +220,6 @@ namespace CSVRender
void dragMoveEvent(QDragMoveEvent *event);
WorldspaceHitResult mousePick (const QPoint& localPos);
virtual std::string getStartupInstruction() = 0;
private slots:

Loading…
Cancel
Save