From a5a76cadca8f5cc4002eec0f6d2cf2c0ffeb997a Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 9 Nov 2014 14:36:58 +1100 Subject: [PATCH] Adding, deleting and moving pathgrid points work. However still not saving to the document. --- apps/opencs/view/render/cell.cpp | 204 +++++++++++++++++- apps/opencs/view/render/cell.hpp | 16 +- apps/opencs/view/render/mousestate.cpp | 38 +++- apps/opencs/view/render/mousestate.hpp | 3 +- .../view/render/pagedworldspacewidget.cpp | 94 ++++++++ .../view/render/pagedworldspacewidget.hpp | 13 ++ apps/opencs/view/render/pathgridpoint.cpp | 35 +++ apps/opencs/view/render/pathgridpoint.hpp | 4 + .../view/render/unpagedworldspacewidget.cpp | 18 ++ .../view/render/unpagedworldspacewidget.hpp | 6 + apps/opencs/view/render/worldspacewidget.cpp | 50 +++++ apps/opencs/view/render/worldspacewidget.hpp | 10 + 12 files changed, 474 insertions(+), 17 deletions(-) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 6979a4042b..e703c8a9dc 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -112,7 +112,8 @@ bool CSVRender::Cell::addObjects (int start, int end) CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, const std::string& id, CSVWorld::PhysicsSystem *physics, const Ogre::Vector3& origin) -: mData (data), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager), mPhysics(physics) +: mData (data), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager), mPhysics(physics), + mPathgridId("") { mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode(); mCellNode->setPosition (origin); @@ -146,7 +147,7 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, } } - addPathgrid(); + loadPathgrid(); } CSVRender::Cell::~Cell() @@ -156,7 +157,13 @@ CSVRender::Cell::~Cell() iter != mPgEdges.end(); ++iter) { if(mSceneMgr->hasManualObject((*iter).second)) + { + Ogre::ManualObject *manual = mSceneMgr->getManualObject((*iter).second); + Ogre::SceneNode *node = manual->getParentSceneNode(); mSceneMgr->destroyManualObject((*iter).second); + if(mSceneMgr->hasSceneNode(node->getName())) + mSceneMgr->destroySceneNode(node); + } } destroyGridMaterials(); Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(DEBUGGING_GROUP); @@ -306,7 +313,14 @@ float CSVRender::Cell::getTerrainHeightAt(const Ogre::Vector3 &pos) const return -std::numeric_limits::max(); } -void CSVRender::Cell::addPathgrid() +// FIXME: +// - updating indicies +// - collision mask +// - add pathgrid point above an object +// - adding edges +// - save to document & signals +// - repainting edges while moving +void CSVRender::Cell::loadPathgrid() { if(!Ogre::ResourceGroupManager::getSingleton().resourceGroupExists(DEBUGGING_GROUP)) Ogre::ResourceGroupManager::getSingleton().createResourceGroup(DEBUGGING_GROUP); @@ -318,19 +332,20 @@ void CSVRender::Cell::addPathgrid() int index = pathgridCollection.searchId(mId); if(index != -1) { - const CSMWorld::Pathgrid pathgrid = pathgridCollection.getRecord(index).get(); + const CSMWorld::Pathgrid &pathgrid = pathgridCollection.getRecord(index).get(); + mPathgridId = pathgrid.mId; // FIXME: temporary storage (should be document) + mPoints.resize(pathgrid.mPoints.size()); std::vector::const_iterator iter = pathgrid.mPoints.begin(); for(index = 0; iter != pathgrid.mPoints.end(); ++iter, ++index) { - std::ostringstream stream; - stream << "Pathgrid_" << mId << "_" << index; - std::string name = stream.str(); + std::string name = PathgridPoint::getName(pathgrid.mId, index); Ogre::Vector3 pos = Ogre::Vector3(worldsize*mX+(*iter).mX, worldsize*mY+(*iter).mY, (*iter).mZ); mPgPoints.insert(std::make_pair(name, new PathgridPoint(name, mCellNode, pos, mPhysics))); + mPoints[index] = *iter; // FIXME: temporary storage (should be document) } for(ESM::Pathgrid::EdgeList::const_iterator it = pathgrid.mEdges.begin(); @@ -343,7 +358,7 @@ void CSVRender::Cell::addPathgrid() const ESM::Pathgrid::Point &p1 = pathgrid.mPoints[edge.mV1]; std::ostringstream stream; - stream << mId << "_" << edge.mV0 << " " << edge.mV1; + stream << pathgrid.mId << "_" << edge.mV0 << " " << edge.mV1; std::string name = stream.str(); Ogre::ManualObject *line = createPathgridEdge(name, @@ -353,6 +368,179 @@ void CSVRender::Cell::addPathgrid() node->attachObject(line); mPgEdges.insert(std::make_pair(std::make_pair(edge.mV0, edge.mV1), name)); + mEdges.push_back(*it); // FIXME: temporary storage (should be document) } } } + +// NOTE: pos is in world coordinates +// FIXME: save to the document +void CSVRender::Cell::pathgridPointAdded(const Ogre::Vector3 &pos) +{ + std::string name = PathgridPoint::getName(mId, mPoints.size()); + + mPgPoints.insert(std::make_pair(name, new PathgridPoint(name, mCellNode, pos, mPhysics))); + + // store to document + ESM::Pathgrid::Point point((int)pos.x, (int)pos.y, (int)pos.z); + point.mConnectionNum = 0; + mPoints.push_back(point); + mPathgridId = mId; + // FIXME: update other scene managers +} + +// FIXME: save to the document +void CSVRender::Cell::pathgridPointRemoved(const std::string &name) +{ + std::pair result = PathgridPoint::getIdAndIndex(name); + if(result.first == "") + return; + + std::string pathgridId = result.first; + int index = result.second; + + // check if the point exists + if(index < 0 || mPathgridId != pathgridId || index >= mPoints.size()) + return; + + int numToDelete = mPoints[index].mConnectionNum * 2; // for sanity check later + int edgeCount = 0; + + // find edges to delete + std::vector > edges; + for(unsigned i = 0; i < mEdges.size(); ++i) + { + if(mEdges[i].mV0 == index || mEdges[i].mV1 == index) + { + for(std::map, std::string>::iterator iter = mPgEdges.begin(); + iter != mPgEdges.end(); ++iter) + { + if((*iter).first.first == index || (*iter).first.second == index) + { + edges.push_back(std::make_pair((*iter).first.first, (*iter).first.second)); + } + } + } + } + + // delete the edges + for(std::vector >::iterator iter = edges.begin(); + iter != edges.end(); ++iter) + { + std::string name = mPgEdges[*iter]; + if(mSceneMgr->hasManualObject(name)) + { + // remove manual objects + Ogre::ManualObject *manual = mSceneMgr->getManualObject(name); + Ogre::SceneNode *node = manual->getParentSceneNode(); + mSceneMgr->destroyManualObject(name); + if(mSceneMgr->hasSceneNode(node->getName())) + mSceneMgr->destroySceneNode(node); + + edgeCount++; // for sanity check later + + // update map + mPgEdges.erase(*iter); + + // update document + assert(mPoints[(*iter).first].mConnectionNum > 0); + mPoints[(*iter).first].mConnectionNum -= 1; + for(unsigned i = mEdges.size() - 1; i > 0; --i) + { + if(mEdges[i].mV0 == index || mEdges[i].mV1 == index) + mEdges.erase(mEdges.begin() + i); + } + } + } + + if(edgeCount != numToDelete) + { + // WARNING: continue anyway? Or should this be an exception? + std::cerr << "The no of edges del does not match the no of conn for: " + << mPathgridId + "_" + QString::number(index).toStdString() << std::endl; + } + + if(edgeCount || mPoints[index].mConnectionNum == 0) + { + // remove the point + delete mPgPoints[name]; + mPgPoints.erase(name); + // FIXME: update other scene managers + } + + // store to document + //mPoints.erase(mPoints.begin() + index); // WARNING: Can't erase because the index will change + // FIXME: it should be possible to refresh indicies but that means index values + // can't be stored in maps, names, etc +} + +// NOTE: newPos is in world coordinates +void CSVRender::Cell::pathgridPointMoved(const std::string &name, const Ogre::Vector3 &newPos) +{ + std::pair result = PathgridPoint::getIdAndIndex(name); + if(result.first == "") + return; + + std::string pathgridId = result.first; + int index = result.second; + + // check if the point exists + if(index < 0 || mPathgridId != pathgridId || index >= mPoints.size()) + return; + + float worldsize = ESM::Land::REAL_SIZE; + + // delete then recreate the edges + for(unsigned i = 0; i < mEdges.size(); ++i) + { + if(mEdges[i].mV0 == index || mEdges[i].mV1 == index) + { + std::ostringstream stream; + stream << pathgridId << "_" << mEdges[i].mV0 << " " << mEdges[i].mV1; + std::string name = stream.str(); + + if(mSceneMgr->hasManualObject(name)) + { + // remove manual objects + Ogre::ManualObject *manual = mSceneMgr->getManualObject(name); + Ogre::SceneNode *node = manual->getParentSceneNode(); + mSceneMgr->destroyManualObject(name); + + if(mEdges[i].mV0 == index) + { + const ESM::Pathgrid::Point &p1 = mPoints[mEdges[i].mV1]; + + Ogre::ManualObject *line = createPathgridEdge(name, + newPos, + Ogre::Vector3(worldsize*mX+p1.mX, worldsize*mY+p1.mY, p1.mZ)); + line->setVisibilityFlags(Element_Pathgrid); + node->attachObject(line); + } + else if(mEdges[i].mV1 == index) + { + const ESM::Pathgrid::Point &p0 = mPoints[mEdges[i].mV0]; + + Ogre::ManualObject *line = createPathgridEdge(name, + Ogre::Vector3(worldsize*mX+p0.mX, worldsize*mY+p0.mY, p0.mZ), + newPos); + line->setVisibilityFlags(Element_Pathgrid); + node->attachObject(line); + } + } + } + } +} + +// FIXME: save to the document +void CSVRender::Cell::addPathgridEdge() +{ + // check if the points exist + // update the edges + // store to document + // FIXME: update other scene managers +} + +// FIXME: save to the document +void CSVRender::Cell::removePathgridEdge() +{ +} diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index c88b593532..5d7b9088a5 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -8,6 +8,7 @@ #include #include +#include // FIXME: temporaty storage until saving to document #include "object.hpp" @@ -23,6 +24,7 @@ namespace Ogre namespace CSMWorld { class Data; + class Pathgrid; } namespace CSVWorld @@ -42,6 +44,11 @@ namespace CSVRender std::map mObjects; std::map mPgPoints; std::map, std::string> mPgEdges; + + ESM::Pathgrid::PointList mPoints; // FIXME: temporary storage until saving to document + ESM::Pathgrid::EdgeList mEdges; // FIXME: temporary storage until saving to document + std::string mPathgridId; // FIXME: temporary storage until saving to document + std::auto_ptr mTerrain; CSVWorld::PhysicsSystem *mPhysics; Ogre::SceneManager *mSceneMgr; @@ -88,14 +95,21 @@ namespace CSVRender float getTerrainHeightAt(const Ogre::Vector3 &pos) const; + void pathgridPointAdded(const Ogre::Vector3 &pos); + void pathgridPointMoved(const std::string &name, const Ogre::Vector3 &newPos); + void pathgridPointRemoved(const std::string &name); + private: // for drawing pathgrid points & lines void createGridMaterials(); void destroyGridMaterials(); - void addPathgrid(); + void loadPathgrid(); Ogre::ManualObject *createPathgridEdge(const std::string &name, const Ogre::Vector3 &start, const Ogre::Vector3 &end); + + void addPathgridEdge(); + void removePathgridEdge(); }; } diff --git a/apps/opencs/view/render/mousestate.cpp b/apps/opencs/view/render/mousestate.cpp index aa8f1a785b..bceae716cf 100644 --- a/apps/opencs/view/render/mousestate.cpp +++ b/apps/opencs/view/render/mousestate.cpp @@ -209,9 +209,9 @@ namespace CSVRender // print some debug info std::string referenceId = mPhysics->sceneNodeToRefId(result.first); if(referenceId != "") - std::cout << "result: " << referenceId << std::endl; + std::cout << "result grab release: " << referenceId << std::endl; else - std::cout << "result: " << result.first << std::endl; + std::cout << "result grab release: " << result.first << std::endl; std::cout << " hit pos "+ QString::number(result.second.x).toStdString() + ", " + QString::number(result.second.y).toStdString() + ", " + QString::number(result.second.z).toStdString() << std::endl; @@ -234,7 +234,20 @@ 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 - placeObject(mGrabbedSceneNode, pos); + std::pair result = + terrainUnderCursor(event->x(), event->y()); // FIXME: some pathgrid points are on objects + if(result.first != "") + { + // FIXME: rather than just updating at the end, should + // consider providing visual feedback of terrain height + // 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); + } } else { @@ -389,6 +402,21 @@ namespace CSVRender } } + // FIXME: castRay converts referenceId to scene node name only to be re-converted + // here - investigate whether refactoring required + std::pair MouseState::pgPointUnderCursor(const int mouseX, const int mouseY) + { + std::pair result = objectUnderCursor(mouseX, mouseY); + std::string referenceId = mPhysics->sceneNodeToRefId(result.first); + if(result.first != "" && + referenceId != "" && QString(referenceId.c_str()).contains(QRegExp("^Pathgrid"))) + { + return std::make_pair(referenceId, result.second); + } + + return std::make_pair("", Ogre::Vector3()); + } + std::pair MouseState::mousePositionOnPlane(const QPoint &pos, const Ogre::Plane &plane) { // using a really small value seems to mess up with the projections @@ -417,10 +445,6 @@ namespace CSVRender std::pair result = mPhysics->castRay(x, y, mSceneManager, getCamera()); if(result.first != "") { - std::cout << "result: " << result.first << std::endl; - std::cout << " hit pos "+ QString::number(result.second.x).toStdString() - + ", " + QString::number(result.second.y).toStdString() - + ", " + QString::number(result.second.z).toStdString() << std::endl; // FIXME: is there a better way to distinguish terrain from objects? QString name = QString(result.first.c_str()); if(name.contains(QRegExp("^HeightField"))) diff --git a/apps/opencs/view/render/mousestate.hpp b/apps/opencs/view/render/mousestate.hpp index 36d04ef6ba..b56860cace 100644 --- a/apps/opencs/view/render/mousestate.hpp +++ b/apps/opencs/view/render/mousestate.hpp @@ -71,13 +71,14 @@ namespace CSVRender void mouseReleaseEvent (QMouseEvent *event); 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); 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 49e7e1f097..e528733c01 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -22,6 +22,7 @@ #include "../widget/scenetooltoggle.hpp" +#include "pathgridpoint.hpp" #include "elements.hpp" bool CSVRender::PagedWorldspaceWidget::adjustCells() @@ -295,6 +296,99 @@ void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent flagAsModified(); } +//void CSVRender::PagedWorldspaceWidget::pathgridAdded (const QModelIndex& parent, +// int start, int end) +//{ +// // FIXME: +//} +// +//void CSVRender::PagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& topLeft, +// const QModelIndex& bottomRight) +//{ +// // FIXME: +//} +// +//void CSVRender::PagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelIndex& parent, +// int start, int end) +//{ +// // FIXME: +//} + +CSVRender::Cell *CSVRender::PagedWorldspaceWidget::findCell(const std::string &cellId) +{ + const CSMWorld::IdCollection& cells = mDocument.getData().getCells(); + + std::map::iterator iter (mCells.begin()); + for(; iter!= mCells.end(); ++iter) + { + int index = cells.searchId(cellId); + + if (index != -1 && cellId == iter->first.getId (mWorldspace)) + { + return iter->second; + } + } + + 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) +{ + // decode name + QString id = QString(terrain.c_str()); + QRegExp terrainRe("^HeightField_([\\d-]+)_([\\d-]+)$"); + + if (id.isEmpty() || !id.startsWith("HeightField_")) + return; + + if (terrainRe.indexIn(id) == -1) + return; + + int cellX = terrainRe.cap(1).toInt(); + int cellY = terrainRe.cap(2).toInt(); + + std::ostringstream stream; + stream << "#" << cellX << " " << cellY; + + Cell *cell = findCell(stream.str()); + if(cell) + { + cell->pathgridPointAdded(pos); + flagAsModified(); + + return; + } +} + +void CSVRender::PagedWorldspaceWidget::pathgridMoved (const std::string &pgName, const Ogre::Vector3 &pos) +{ + std::pair result = PathgridPoint::getIdAndIndex(pgName); + + Cell *cell = findCell(result.first); + if(cell) + { + cell->pathgridPointMoved(pgName, pos); + flagAsModified(); + + return; + } +} + +void CSVRender::PagedWorldspaceWidget::pathgridAboutToBeRemoved (const std::string &pgName) +{ + std::pair result = PathgridPoint::getIdAndIndex(pgName); + + Cell *cell = findCell(result.first); + if(cell) + { + cell->pathgridPointRemoved(pgName); + flagAsModified(); + + return; + } +} + std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction() { Ogre::Vector3 position = getCamera()->getPosition(); diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index fe79e761e5..b5ca91880b 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -49,8 +49,16 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end); + //virtual void pathgridAdded (const QModelIndex& parent, int start, int end); + + //virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + //virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end); + virtual std::string getStartupInstruction(); + Cell *findCell(const std::string &cellId); + public: PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document); @@ -87,6 +95,11 @@ namespace CSVRender virtual void mouseDoubleClickEvent (QMouseEvent *event); + // FIXME: temporary only until signals from the document is implemented + virtual void pathgridInserted (const std::string &terrain, const Ogre::Vector3 &pos); + virtual void pathgridMoved (const std::string &pgName, const Ogre::Vector3 &pos); + virtual void pathgridAboutToBeRemoved (const std::string &pgName); + signals: void cellSelectionChanged (const CSMWorld::CellSelection& selection); diff --git a/apps/opencs/view/render/pathgridpoint.cpp b/apps/opencs/view/render/pathgridpoint.cpp index 2455ea1a83..3e365932f9 100644 --- a/apps/opencs/view/render/pathgridpoint.cpp +++ b/apps/opencs/view/render/pathgridpoint.cpp @@ -2,6 +2,8 @@ #include // FIXME +#include + #include #include @@ -35,4 +37,37 @@ namespace CSVRender if (mBase) mBase->getCreator()->destroySceneNode(mBase); } + + // FIXME: Is there a way to identify the pathgrid point other than via the index? + // ESM::Pathgrid::Edge itself uses the indicies so any change (add/delete) must be + // propagated everywhere. + std::pair PathgridPoint::getIdAndIndex(const std::string &name) + { + // decode name + QString id = QString(name.c_str()); + QRegExp pathgridRe("^Pathgrid_(.+)_(\\d+)$"); + + if (id.isEmpty() || !id.startsWith("Pathgrid_")) + return std::make_pair("", -1); + + std::string pathgridId = ""; + int index = -1; + if (pathgridRe.indexIn(id) != -1) + { + pathgridId = pathgridRe.cap(1).toStdString(); + index = pathgridRe.cap(2).toInt(); + + return std::make_pair(pathgridId, index); + } + + return std::make_pair("", -1); + } + + std::string PathgridPoint::getName(const std::string &pathgridId, const int index) + { + std::ostringstream stream; + stream << "Pathgrid_" << pathgridId << "_" << index; + + return stream.str(); + } } diff --git a/apps/opencs/view/render/pathgridpoint.hpp b/apps/opencs/view/render/pathgridpoint.hpp index f4fa42790d..3419082c3a 100644 --- a/apps/opencs/view/render/pathgridpoint.hpp +++ b/apps/opencs/view/render/pathgridpoint.hpp @@ -29,6 +29,10 @@ namespace CSVRender Ogre::SceneNode *cellNode, const Ogre::Vector3 &pos, CSVWorld::PhysicsSystem *physics); ~PathgridPoint(); + + static std::pair getIdAndIndex(const std::string &name); + + static std::string getName(const std::string &pathgridId, int index); }; } diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 8012b1b246..a1a8a89219 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -160,6 +160,24 @@ void CSVRender::UnpagedWorldspaceWidget::referenceAdded (const QModelIndex& pare flagAsModified(); } +//void CSVRender::UnpagedWorldspaceWidget::pathgridAdded (const QModelIndex& parent, +// int start, int end) +//{ +// // FIXME: +//} +// +//void CSVRender::UnpagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& topLeft, +// const QModelIndex& bottomRight) +//{ +// // FIXME: +//} +// +//void CSVRender::UnpagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelIndex& parent, +// int start, int end) +//{ +// // FIXME: +//} + std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction() { Ogre::Vector3 position = getCamera()->getPosition(); diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index 5924abaa9e..ee397d467a 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -62,6 +62,12 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end); + //virtual void pathgridAdded (const QModelIndex& index, int start, int end); + + //virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + //virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end); + virtual std::string getStartupInstruction(); private slots: diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 9c86760640..1fedc8aa12 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -8,6 +8,7 @@ #include #include +#include #include "../../model/world/universalid.hpp" #include "../../model/world/idtable.hpp" @@ -54,6 +55,16 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int))); + //QAbstractItemModel *pathgrids = + //document.getData().getTableModel (CSMWorld::UniversalId::Type_Pathgrid); + + //connect (pathgrids, SIGNAL (rowsInserted (const QModelIndex&, int, int)), + //this, SLOT (pathgridAdded (const QModelIndex&, int, int))); + //connect (pathgrids, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + //this, SLOT (pathgridDataChanged (const QModelIndex&, const QModelIndex&))); + //connect (pathgrids, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), + //this, SLOT (pathgridAboutToBeRemoved (const QModelIndex&, int, int))); + // associate WorldSpaceWidgets (and their SceneManagers) with Documents // then create physics if there is a new document mPhysics = CSVWorld::PhysicsManager::instance()->addSceneWidget(document, this); @@ -389,12 +400,51 @@ void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event) SceneWidget::wheelEvent(event); } +// FIXME: mouse button events are processed in MouseState but key events are +// processed here - seems inconsistent void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event) { if(event->key() == Qt::Key_Escape) { mMouse->cancelDrag(); } + else if(event->key() == Qt::Key_Delete) + { + QPoint p = this->mapFromGlobal(QCursor::pos()); + std::pair result = mMouse->pgPointUnderCursor(p.x(), p.y()); + if(result.first != "") + { + pathgridAboutToBeRemoved(result.first); + } + else + SceneWidget::keyPressEvent(event); + } + else if(event->key() == Qt::Key_Insert) + { + QPoint p = this->mapFromGlobal(QCursor::pos()); + std::pair result = mMouse->terrainUnderCursor(p.x(), p.y()); + if(result.first != "") + { + pathgridInserted(result.first, result.second); + } + else + SceneWidget::keyPressEvent(event); + } else SceneWidget::keyPressEvent(event); } + +// FIXME: temporary until signals from the document are implemented +void CSVRender::WorldspaceWidget::pathgridAboutToBeRemoved (const std::string &pgName) +{ +} + +// FIXME: temporary until signals from the document are implemented +void CSVRender::WorldspaceWidget::pathgridMoved (const std::string &pgName, const Ogre::Vector3 &newPos) +{ +} + +// FIXME: temporary until signals from the document are implemented +void CSVRender::WorldspaceWidget::pathgridInserted (const std::string &name, const Ogre::Vector3 &pos) +{ +} diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 5bad3933d8..75dc0c2647 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -109,6 +109,11 @@ namespace CSVRender virtual void wheelEvent (QWheelEvent *event); virtual void keyPressEvent (QKeyEvent *event); + // FIXME: temporary only until the signals from the document are implemented + virtual void pathgridInserted (const std::string &terrain, const Ogre::Vector3 &pos); + virtual void pathgridMoved (const std::string &pgName, const Ogre::Vector3 &pos); + virtual void pathgridAboutToBeRemoved (const std::string &pgName); + private: void dragEnterEvent(QDragEnterEvent *event); @@ -143,6 +148,11 @@ namespace CSVRender void debugProfileAboutToBeRemoved (const QModelIndex& parent, int start, int end); + //virtual void pathgridAdded (const QModelIndex& index, int start, int end) = 0; + + //virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) = 0; + + //virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) = 0; protected slots: