diff --git a/apps/opencs/view/render/editmode.cpp b/apps/opencs/view/render/editmode.cpp index be264afc7c..8da000dc93 100644 --- a/apps/opencs/view/render/editmode.cpp +++ b/apps/opencs/view/render/editmode.cpp @@ -29,30 +29,30 @@ void CSVRender::EditMode::setEditLock (bool locked) } -void CSVRender::EditMode::primaryEditPressed (osg::ref_ptr tag) {} +void CSVRender::EditMode::primaryEditPressed (const WorldspaceHitResult& hit) {} -void CSVRender::EditMode::secondaryEditPressed (osg::ref_ptr tag) {} +void CSVRender::EditMode::secondaryEditPressed (const WorldspaceHitResult& hit) {} -void CSVRender::EditMode::primarySelectPressed (osg::ref_ptr tag) {} +void CSVRender::EditMode::primarySelectPressed (const WorldspaceHitResult& hit) {} -void CSVRender::EditMode::secondarySelectPressed (osg::ref_ptr tag) {} +void CSVRender::EditMode::secondarySelectPressed (const WorldspaceHitResult& hit) {} -bool CSVRender::EditMode::primaryEditStartDrag (osg::ref_ptr tag) +bool CSVRender::EditMode::primaryEditStartDrag (const WorldspaceHitResult& hit) { return false; } -bool CSVRender::EditMode::secondaryEditStartDrag (osg::ref_ptr tag) +bool CSVRender::EditMode::secondaryEditStartDrag (const WorldspaceHitResult& hit) { return false; } -bool CSVRender::EditMode::primarySelectStartDrag (osg::ref_ptr tag) +bool CSVRender::EditMode::primarySelectStartDrag (const WorldspaceHitResult& hit) { return false; } -bool CSVRender::EditMode::secondarySelectStartDrag (osg::ref_ptr tag) +bool CSVRender::EditMode::secondarySelectStartDrag (const WorldspaceHitResult& hit) { return false; } diff --git a/apps/opencs/view/render/editmode.hpp b/apps/opencs/view/render/editmode.hpp index f5cef1be29..3381a7105e 100644 --- a/apps/opencs/view/render/editmode.hpp +++ b/apps/opencs/view/render/editmode.hpp @@ -12,6 +12,7 @@ class QDragMoveEvent; namespace CSVRender { class WorldspaceWidget; + struct WorldspaceHitResult; class TagBase; class EditMode : public CSVWidget::ModeButton @@ -38,36 +39,36 @@ namespace CSVRender virtual void setEditLock (bool locked); /// Default-implementation: Ignored. - virtual void primaryEditPressed (osg::ref_ptr tag); + virtual void primaryEditPressed (const WorldspaceHitResult& hit); /// Default-implementation: Ignored. - virtual void secondaryEditPressed (osg::ref_ptr tag); + virtual void secondaryEditPressed (const WorldspaceHitResult& hit); /// Default-implementation: Ignored. - virtual void primarySelectPressed (osg::ref_ptr tag); + virtual void primarySelectPressed (const WorldspaceHitResult& hit); /// Default-implementation: Ignored. - virtual void secondarySelectPressed (osg::ref_ptr tag); + virtual void secondarySelectPressed (const WorldspaceHitResult& hit); /// Default-implementation: ignore and return false /// /// \return Drag accepted? - virtual bool primaryEditStartDrag (osg::ref_ptr tag); + virtual bool primaryEditStartDrag (const WorldspaceHitResult& hit); /// Default-implementation: ignore and return false /// /// \return Drag accepted? - virtual bool secondaryEditStartDrag (osg::ref_ptr tag); + virtual bool secondaryEditStartDrag (const WorldspaceHitResult& hit); /// Default-implementation: ignore and return false /// /// \return Drag accepted? - virtual bool primarySelectStartDrag (osg::ref_ptr tag); + virtual bool primarySelectStartDrag (const WorldspaceHitResult& hit); /// Default-implementation: ignore and return false /// /// \return Drag accepted? - virtual bool secondarySelectStartDrag (osg::ref_ptr tag); + virtual bool secondarySelectStartDrag (const WorldspaceHitResult& hit); /// Default-implementation: ignored virtual void drag (int diffX, int diffY, double speedFactor); diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index 4c708242ab..52335f2440 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -103,25 +103,25 @@ void CSVRender::InstanceMode::setEditLock (bool locked) getWorldspaceWidget().abortDrag(); } -void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr tag) +void CSVRender::InstanceMode::primaryEditPressed (const WorldspaceHitResult& hit) { if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) - primarySelectPressed (tag); + primarySelectPressed (hit); } -void CSVRender::InstanceMode::secondaryEditPressed (osg::ref_ptr tag) +void CSVRender::InstanceMode::secondaryEditPressed (const WorldspaceHitResult& hit) { if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) - secondarySelectPressed (tag); + secondarySelectPressed (hit); } -void CSVRender::InstanceMode::primarySelectPressed (osg::ref_ptr tag) +void CSVRender::InstanceMode::primarySelectPressed (const WorldspaceHitResult& hit) { getWorldspaceWidget().clearSelection (Mask_Reference); - if (tag) + if (hit.tag) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) + if (CSVRender::ObjectTag *objectTag = dynamic_cast (hit.tag.get())) { // hit an Object, select it CSVRender::Object* object = objectTag->mObject; @@ -131,11 +131,11 @@ void CSVRender::InstanceMode::primarySelectPressed (osg::ref_ptr tag) } } -void CSVRender::InstanceMode::secondarySelectPressed (osg::ref_ptr tag) +void CSVRender::InstanceMode::secondarySelectPressed (const WorldspaceHitResult& hit) { - if (tag) + if (hit.tag) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) + if (CSVRender::ObjectTag *objectTag = dynamic_cast (hit.tag.get())) { // hit an Object, toggle its selection state CSVRender::Object* object = objectTag->mObject; @@ -145,15 +145,15 @@ void CSVRender::InstanceMode::secondarySelectPressed (osg::ref_ptr tag) } } -bool CSVRender::InstanceMode::primaryEditStartDrag (osg::ref_ptr tag) +bool CSVRender::InstanceMode::primaryEditStartDrag (const WorldspaceHitResult& hit) { if (mDragMode!=DragMode_None || mLocked) return false; - if (tag && CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) + if (hit.tag && CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) { getWorldspaceWidget().clearSelection (Mask_Reference); - if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) + if (CSVRender::ObjectTag *objectTag = dynamic_cast (hit.tag.get())) { CSVRender::Object* object = objectTag->mObject; object->setSelected (true); @@ -177,7 +177,7 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (osg::ref_ptr tag) // \todo check for sub-mode - if (CSVRender::ObjectMarkerTag *objectTag = dynamic_cast (tag.get())) + if (CSVRender::ObjectMarkerTag *objectTag = dynamic_cast (hit.tag.get())) { mDragAxis = objectTag->mAxis; } @@ -189,7 +189,7 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (osg::ref_ptr tag) return true; } -bool CSVRender::InstanceMode::secondaryEditStartDrag (osg::ref_ptr tag) +bool CSVRender::InstanceMode::secondaryEditStartDrag (const WorldspaceHitResult& hit) { if (mLocked) return false; diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index db7fdaa96e..5b12529123 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -41,17 +41,17 @@ namespace CSVRender virtual void setEditLock (bool locked); - virtual void primaryEditPressed (osg::ref_ptr tag); + virtual void primaryEditPressed (const WorldspaceHitResult& hit); - virtual void secondaryEditPressed (osg::ref_ptr tag); + virtual void secondaryEditPressed (const WorldspaceHitResult& hit); - virtual void primarySelectPressed (osg::ref_ptr tag); + virtual void primarySelectPressed (const WorldspaceHitResult& hit); - virtual void secondarySelectPressed (osg::ref_ptr tag); + virtual void secondarySelectPressed (const WorldspaceHitResult& hit); - virtual bool primaryEditStartDrag (osg::ref_ptr tag); + virtual bool primaryEditStartDrag (const WorldspaceHitResult& hit); - virtual bool secondaryEditStartDrag (osg::ref_ptr tag); + virtual bool secondaryEditStartDrag (const WorldspaceHitResult& hit); virtual void drag (int diffX, int diffY, double speedFactor); diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 1d9b22216c..90088f24e3 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -142,14 +142,15 @@ void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons ( "terrain-move"); } -void CSVRender::PagedWorldspaceWidget::handleMouseClick (osg::ref_ptr tag, const std::string& button, bool shift) +void CSVRender::PagedWorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, + bool shift) { - if (tag && tag->getMask()==Mask_CellArrow) + if (hit.tag && hit.tag->getMask()==Mask_CellArrow) { if (button=="p-edit" || button=="s-edit") { if (CellArrowTag *cellArrowTag = - dynamic_cast (tag.get())) + dynamic_cast (hit.tag.get())) { CellArrow *arrow = cellArrowTag->getCellArrow(); @@ -209,7 +210,7 @@ void CSVRender::PagedWorldspaceWidget::handleMouseClick (osg::ref_ptr t } } - WorldspaceWidget::handleMouseClick (tag, button, shift); + WorldspaceWidget::handleMouseClick (hit, button, shift); } void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft, diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 3cd628df0a..8c17d4fcdc 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -135,7 +135,7 @@ namespace CSVRender virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool); - virtual void handleMouseClick (osg::ref_ptr tag, const std::string& button, bool shift); + virtual void handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, bool shift); signals: diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 1bd3df9818..e90a4fd5ae 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -469,7 +469,7 @@ bool CSVRender::WorldspaceWidget::storeMappingSetting (const CSMPrefs::Setting * return SceneWidget::storeMappingSetting(setting); } -osg::ref_ptr CSVRender::WorldspaceWidget::mousePick (const QPoint& localPos) +CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPoint& localPos) { // (0,0) is considered the lower left corner of an OpenGL window int x = localPos.x(); @@ -499,16 +499,31 @@ osg::ref_ptr CSVRender::WorldspaceWidget::mousePick (const Q { osg::Node* node = *it; if (osg::ref_ptr tag = dynamic_cast(node->getUserData())) - return tag; + { + WorldspaceHitResult hit = { true, tag, 0, 0, 0, intersection.getWorldIntersectPoint() }; + if (intersection.indexList.size() >= 3) + { + hit.i0 = intersection.indexList[0]; + hit.i1 = intersection.indexList[1]; + hit.i2 = intersection.indexList[2]; + } + return hit; + } } -// ignoring terrain for now - // must be terrain, report coordinates -// std::cout << "Terrain hit at " << intersection.getWorldIntersectPoint().x() << " " << intersection.getWorldIntersectPoint().y() << std::endl; -// return; + // Something untagged, probably terrain + WorldspaceHitResult hit = { true, 0, 0, 0, 0, intersection.getWorldIntersectPoint() }; + if (intersection.indexList.size() >= 3) + { + hit.i0 = intersection.indexList[0]; + hit.i1 = intersection.indexList[1]; + hit.i2 = intersection.indexList[2]; + } + return hit; } - return osg::ref_ptr(); + WorldspaceHitResult hit = { false, 0, 0, 0, 0, osg::Vec3d() }; + return hit; } void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event) @@ -595,10 +610,11 @@ void CSVRender::WorldspaceWidget::showToolTip() { QPoint pos = QCursor::pos(); - if (osg::ref_ptr tag = mousePick (mapFromGlobal (pos))) + WorldspaceHitResult hit = mousePick (mapFromGlobal (pos)); + if (hit.tag) { bool hideBasics = CSMPrefs::get()["Tooltips"]["scene-hide-basic"].isTrue(); - QToolTip::showText (pos, tag->getToolTip (hideBasics), this); + QToolTip::showText (pos, hit.tag->getToolTip (hideBasics), this); } } } @@ -635,18 +651,18 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event) } else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="p-select" || mDragMode=="s-select") { - osg::ref_ptr tag = mousePick (event->pos()); + WorldspaceHitResult hit = mousePick (event->pos()); EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); if (mDragMode=="p-edit") - mDragging = editMode.primaryEditStartDrag (tag); + mDragging = editMode.primaryEditStartDrag (hit); else if (mDragMode=="s-edit") - mDragging = editMode.secondaryEditStartDrag (tag); + mDragging = editMode.secondaryEditStartDrag (hit); else if (mDragMode=="p-select") - mDragging = editMode.primarySelectStartDrag (tag); + mDragging = editMode.primarySelectStartDrag (hit); else if (mDragMode=="s-select") - mDragging = editMode.secondarySelectStartDrag (tag); + mDragging = editMode.secondarySelectStartDrag (hit); if (mDragging) { @@ -704,9 +720,9 @@ void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) } else { - osg::ref_ptr tag = mousePick (event->pos()); + WorldspaceHitResult hit = mousePick (event->pos()); - handleMouseClick (tag, button, event->modifiers() & Qt::ShiftModifier); + handleMouseClick (hit, button, event->modifiers() & Qt::ShiftModifier); } } else @@ -740,18 +756,18 @@ void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event) SceneWidget::keyPressEvent(event); } -void CSVRender::WorldspaceWidget::handleMouseClick (osg::ref_ptr tag, const std::string& button, bool shift) +void CSVRender::WorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, bool shift) { EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); if (button=="p-edit") - editMode.primaryEditPressed (tag); + editMode.primaryEditPressed (hit); else if (button=="s-edit") - editMode.secondaryEditPressed (tag); + editMode.secondaryEditPressed (hit); else if (button=="p-select") - editMode.primarySelectPressed (tag); + editMode.primarySelectPressed (hit); else if (button=="s-select") - editMode.secondarySelectPressed (tag); + editMode.secondarySelectPressed (hit); } CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode() diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index d70694d22c..4160da3d82 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -4,6 +4,7 @@ #include #include +#include #include "../../model/doc/document.hpp" #include "../../model/world/tablemimedata.hpp" @@ -35,6 +36,14 @@ namespace CSVRender class CellArrow; class EditMode; + struct WorldspaceHitResult + { + bool hit; + osg::ref_ptr tag; + unsigned int i0, i1, i2; + osg::Vec3d worldPos; + }; + class WorldspaceWidget : public SceneWidget { Q_OBJECT @@ -191,7 +200,7 @@ namespace CSVRender virtual void wheelEvent (QWheelEvent *event); virtual void keyPressEvent (QKeyEvent *event); - virtual void handleMouseClick (osg::ref_ptr tag, const std::string& button, + virtual void handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, bool shift); /// \return Is \a key a button mapping setting? (ignored otherwise) @@ -209,7 +218,7 @@ namespace CSVRender void dragMoveEvent(QDragMoveEvent *event); - osg::ref_ptr mousePick (const QPoint& localPos); + WorldspaceHitResult mousePick (const QPoint& localPos); virtual std::string getStartupInstruction() = 0;