diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 238f60bb5d..4e3416111f 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -315,8 +315,7 @@ float CSVRender::Cell::getTerrainHeightAt(const Ogre::Vector3 &pos) const // FIXME: // - updating indicies -// - add pathgrid point above an object -// - adding edges +// - adding edges (need the ability to select a pathgrid and highlight) // - save to document & signals // - repainting edges while moving void CSVRender::Cell::loadPathgrid() diff --git a/apps/opencs/view/render/mousestate.cpp b/apps/opencs/view/render/mousestate.cpp index ee77768908..ee59770e45 100644 --- a/apps/opencs/view/render/mousestate.cpp +++ b/apps/opencs/view/render/mousestate.cpp @@ -234,8 +234,9 @@ namespace CSVRender // move pathgrid point, but don't save yet (need pathgrid // table feature & its data structure to be completed) // FIXME: need to signal PathgridPoint object of change + // FIXME: shouldn't allow pathgrid points under the cursor std::pair result = - terrainUnderCursor(event->x(), event->y()); // FIXME: some pathgrid points are on objects + anyUnderCursor(event->x(), event->y()); if(result.first != "") { // FIXME: rather than just updating at the end, should @@ -243,8 +244,6 @@ namespace CSVRender // while dragging the pathgrid point (maybe check whether // the object is a pathgrid point at the begging and set // a flag?) - // FIXME: this also disallows dragging over objects, so - // may need to use ignoreObjects while raycasting placeObject(mGrabbedSceneNode, result.second); mParent->pathgridMoved(referenceId, result.second); } @@ -440,13 +439,7 @@ namespace CSVRender std::pair MouseState::terrainUnderCursor(const int mouseX, const int mouseY) { - if(!getViewport()) - return std::make_pair("", Ogre::Vector3()); - - float x = (float) mouseX / getViewport()->getActualWidth(); - float y = (float) mouseY / getViewport()->getActualHeight(); - - std::pair result = mPhysics->castRay(x, y, mSceneManager, getCamera()); + std::pair result = anyUnderCursor(mouseX, mouseY); if(result.first != "") { // FIXME: is there a better way to distinguish terrain from objects? @@ -463,13 +456,7 @@ namespace CSVRender // NOTE: also returns pathgrids std::pair MouseState::objectUnderCursor(const int mouseX, const int mouseY) { - if(!getViewport()) - return std::make_pair("", Ogre::Vector3()); - - float x = (float) mouseX / getViewport()->getActualWidth(); - float y = (float) mouseY / getViewport()->getActualHeight(); - - std::pair result = mPhysics->castRay(x, y, mSceneManager, getCamera()); + std::pair result = anyUnderCursor(mouseX, mouseY); if(result.first != "") { // NOTE: anything not terrain is assumed to be an object, e.g pathgrid points @@ -490,6 +477,23 @@ namespace CSVRender return std::make_pair("", Ogre::Vector3()); } + std::pair MouseState::anyUnderCursor(const int mouseX, const int mouseY) + { + if(!getViewport()) + return std::make_pair("", Ogre::Vector3()); + + float x = (float) mouseX / getViewport()->getActualWidth(); + float y = (float) mouseY / getViewport()->getActualHeight(); + + std::pair result = mPhysics->castRay(x, y, mSceneManager, getCamera()); + if(result.first != "") + { + return result; + } + + return std::make_pair("", Ogre::Vector3()); + } + void MouseState::updateSceneWidgets() { std::map sceneWidgets = mPhysics->sceneWidgets(); diff --git a/apps/opencs/view/render/mousestate.hpp b/apps/opencs/view/render/mousestate.hpp index b56860cace..fd752349a7 100644 --- a/apps/opencs/view/render/mousestate.hpp +++ b/apps/opencs/view/render/mousestate.hpp @@ -72,13 +72,14 @@ namespace CSVRender void mouseDoubleClickEvent (QMouseEvent *event); bool wheelEvent (QWheelEvent *event); std::pair pgPointUnderCursor(const int mouseX, const int mouseY); - std::pair terrainUnderCursor(const int mouseX, const int mouseY); + std::pair anyUnderCursor(const int mouseX, const int mouseY); void cancelDrag(); private: std::pair mousePositionOnPlane(const QPoint &pos, const Ogre::Plane &plane); + std::pair terrainUnderCursor(const int mouseX, const int mouseY); std::pair objectUnderCursor(const int mouseX, const int mouseY); std::pair planeAxis(); void updateSceneWidgets(); diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index e528733c01..506fd54df9 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -21,6 +21,7 @@ #include "../../model/world/idtable.hpp" #include "../widget/scenetooltoggle.hpp" +#include "../world/physicssystem.hpp" #include "pathgridpoint.hpp" #include "elements.hpp" @@ -332,26 +333,44 @@ CSVRender::Cell *CSVRender::PagedWorldspaceWidget::findCell(const std::string &c return NULL; } -// FIXME: pathgrid may be inserted above an object, the parsing needs to change -void CSVRender::PagedWorldspaceWidget::pathgridInserted (const std::string &terrain, const Ogre::Vector3 &pos) +// NOTE: allow placing pathgrid points above objects and terrain +void CSVRender::PagedWorldspaceWidget::pathgridInserted (const std::string &name, const Ogre::Vector3 &pos) { - // decode name - QString id = QString(terrain.c_str()); - QRegExp terrainRe("^HeightField_([\\d-]+)_([\\d-]+)$"); + QString id = QString(name.c_str()); + std::string referenceId = getPhysics()->sceneNodeToRefId(name); // FIXME: move back - if (id.isEmpty() || !id.startsWith("HeightField_")) + bool terrain = id.startsWith("HeightField_"); + bool object = QString(referenceId.c_str()).startsWith("ref#"); + // don't allow placing another one on top of a pathgrid point + if (id.isEmpty() || (!terrain && !object)) return; - if (terrainRe.indexIn(id) == -1) - return; + std::string cellId; + if(terrain) + { + QRegExp nameRe("^HeightField_([\\d-]+)_([\\d-]+)$"); + if (nameRe.indexIn(id) == -1) + return; - int cellX = terrainRe.cap(1).toInt(); - int cellY = terrainRe.cap(2).toInt(); + int cellX = nameRe.cap(1).toInt(); + int cellY = nameRe.cap(2).toInt(); - std::ostringstream stream; - stream << "#" << cellX << " " << cellY; + std::ostringstream stream; + stream << "#" << cellX << " " << cellY; + cellId = stream.str(); + } + else + { + const CSMWorld::RefCollection& references = mDocument.getData().getReferences(); + int index = references.searchId(referenceId); + if(index == -1) + return; - Cell *cell = findCell(stream.str()); + cellId = references.getData(index, references.findColumnIndex(CSMWorld::Columns::ColumnId_Cell)) + .toString().toUtf8().constData(); + } + + Cell *cell = findCell(cellId); if(cell) { cell->pathgridPointAdded(pos); diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 1fedc8aa12..4f85f3a30c 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -422,7 +422,7 @@ void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event) else if(event->key() == Qt::Key_Insert) { QPoint p = this->mapFromGlobal(QCursor::pos()); - std::pair result = mMouse->terrainUnderCursor(p.x(), p.y()); + std::pair result = mMouse->anyUnderCursor(p.x(), p.y()); if(result.first != "") { pathgridInserted(result.first, result.second);