mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-25 09:09:53 +00:00
Adding, deleting and moving pathgrid points work. However still not saving to the document.
This commit is contained in:
parent
2c09b9ba21
commit
a5a76cadca
12 changed files with 474 additions and 17 deletions
|
@ -112,7 +112,8 @@ bool CSVRender::Cell::addObjects (int start, int end)
|
||||||
|
|
||||||
CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager,
|
CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager,
|
||||||
const std::string& id, CSVWorld::PhysicsSystem *physics, const Ogre::Vector3& origin)
|
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 = sceneManager->getRootSceneNode()->createChildSceneNode();
|
||||||
mCellNode->setPosition (origin);
|
mCellNode->setPosition (origin);
|
||||||
|
@ -146,7 +147,7 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addPathgrid();
|
loadPathgrid();
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVRender::Cell::~Cell()
|
CSVRender::Cell::~Cell()
|
||||||
|
@ -156,7 +157,13 @@ CSVRender::Cell::~Cell()
|
||||||
iter != mPgEdges.end(); ++iter)
|
iter != mPgEdges.end(); ++iter)
|
||||||
{
|
{
|
||||||
if(mSceneMgr->hasManualObject((*iter).second))
|
if(mSceneMgr->hasManualObject((*iter).second))
|
||||||
|
{
|
||||||
|
Ogre::ManualObject *manual = mSceneMgr->getManualObject((*iter).second);
|
||||||
|
Ogre::SceneNode *node = manual->getParentSceneNode();
|
||||||
mSceneMgr->destroyManualObject((*iter).second);
|
mSceneMgr->destroyManualObject((*iter).second);
|
||||||
|
if(mSceneMgr->hasSceneNode(node->getName()))
|
||||||
|
mSceneMgr->destroySceneNode(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
destroyGridMaterials();
|
destroyGridMaterials();
|
||||||
Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(DEBUGGING_GROUP);
|
Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(DEBUGGING_GROUP);
|
||||||
|
@ -306,7 +313,14 @@ float CSVRender::Cell::getTerrainHeightAt(const Ogre::Vector3 &pos) const
|
||||||
return -std::numeric_limits<float>::max();
|
return -std::numeric_limits<float>::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))
|
if(!Ogre::ResourceGroupManager::getSingleton().resourceGroupExists(DEBUGGING_GROUP))
|
||||||
Ogre::ResourceGroupManager::getSingleton().createResourceGroup(DEBUGGING_GROUP);
|
Ogre::ResourceGroupManager::getSingleton().createResourceGroup(DEBUGGING_GROUP);
|
||||||
|
@ -318,19 +332,20 @@ void CSVRender::Cell::addPathgrid()
|
||||||
int index = pathgridCollection.searchId(mId);
|
int index = pathgridCollection.searchId(mId);
|
||||||
if(index != -1)
|
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<ESM::Pathgrid::Point>::const_iterator iter = pathgrid.mPoints.begin();
|
std::vector<ESM::Pathgrid::Point>::const_iterator iter = pathgrid.mPoints.begin();
|
||||||
for(index = 0; iter != pathgrid.mPoints.end(); ++iter, ++index)
|
for(index = 0; iter != pathgrid.mPoints.end(); ++iter, ++index)
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::string name = PathgridPoint::getName(pathgrid.mId, index);
|
||||||
stream << "Pathgrid_" << mId << "_" << index;
|
|
||||||
std::string name = stream.str();
|
|
||||||
|
|
||||||
Ogre::Vector3 pos =
|
Ogre::Vector3 pos =
|
||||||
Ogre::Vector3(worldsize*mX+(*iter).mX, worldsize*mY+(*iter).mY, (*iter).mZ);
|
Ogre::Vector3(worldsize*mX+(*iter).mX, worldsize*mY+(*iter).mY, (*iter).mZ);
|
||||||
|
|
||||||
mPgPoints.insert(std::make_pair(name, new PathgridPoint(name, mCellNode, pos, mPhysics)));
|
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();
|
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];
|
const ESM::Pathgrid::Point &p1 = pathgrid.mPoints[edge.mV1];
|
||||||
|
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
stream << mId << "_" << edge.mV0 << " " << edge.mV1;
|
stream << pathgrid.mId << "_" << edge.mV0 << " " << edge.mV1;
|
||||||
std::string name = stream.str();
|
std::string name = stream.str();
|
||||||
|
|
||||||
Ogre::ManualObject *line = createPathgridEdge(name,
|
Ogre::ManualObject *line = createPathgridEdge(name,
|
||||||
|
@ -353,6 +368,179 @@ void CSVRender::Cell::addPathgrid()
|
||||||
node->attachObject(line);
|
node->attachObject(line);
|
||||||
|
|
||||||
mPgEdges.insert(std::make_pair(std::make_pair(edge.mV0, edge.mV1), name));
|
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<std::string, int> 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<std::pair<int, int> > edges;
|
||||||
|
for(unsigned i = 0; i < mEdges.size(); ++i)
|
||||||
|
{
|
||||||
|
if(mEdges[i].mV0 == index || mEdges[i].mV1 == index)
|
||||||
|
{
|
||||||
|
for(std::map<std::pair<int, int>, 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<std::pair<int, int> >::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<std::string, int> 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()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <OgreVector3.h>
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
#include <components/terrain/terraingrid.hpp>
|
#include <components/terrain/terraingrid.hpp>
|
||||||
|
#include <components/esm/loadpgrd.hpp> // FIXME: temporaty storage until saving to document
|
||||||
|
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ namespace Ogre
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
class Data;
|
class Data;
|
||||||
|
class Pathgrid;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVWorld
|
namespace CSVWorld
|
||||||
|
@ -42,6 +44,11 @@ namespace CSVRender
|
||||||
std::map<std::string, Object *> mObjects;
|
std::map<std::string, Object *> mObjects;
|
||||||
std::map<std::string, PathgridPoint *> mPgPoints;
|
std::map<std::string, PathgridPoint *> mPgPoints;
|
||||||
std::map<std::pair<int, int>, std::string> mPgEdges;
|
std::map<std::pair<int, int>, 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<Terrain::TerrainGrid> mTerrain;
|
std::auto_ptr<Terrain::TerrainGrid> mTerrain;
|
||||||
CSVWorld::PhysicsSystem *mPhysics;
|
CSVWorld::PhysicsSystem *mPhysics;
|
||||||
Ogre::SceneManager *mSceneMgr;
|
Ogre::SceneManager *mSceneMgr;
|
||||||
|
@ -88,14 +95,21 @@ namespace CSVRender
|
||||||
|
|
||||||
float getTerrainHeightAt(const Ogre::Vector3 &pos) const;
|
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:
|
private:
|
||||||
|
|
||||||
// for drawing pathgrid points & lines
|
// for drawing pathgrid points & lines
|
||||||
void createGridMaterials();
|
void createGridMaterials();
|
||||||
void destroyGridMaterials();
|
void destroyGridMaterials();
|
||||||
void addPathgrid();
|
void loadPathgrid();
|
||||||
Ogre::ManualObject *createPathgridEdge(const std::string &name,
|
Ogre::ManualObject *createPathgridEdge(const std::string &name,
|
||||||
const Ogre::Vector3 &start, const Ogre::Vector3 &end);
|
const Ogre::Vector3 &start, const Ogre::Vector3 &end);
|
||||||
|
|
||||||
|
void addPathgridEdge();
|
||||||
|
void removePathgridEdge();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,9 +209,9 @@ namespace CSVRender
|
||||||
// print some debug info
|
// print some debug info
|
||||||
std::string referenceId = mPhysics->sceneNodeToRefId(result.first);
|
std::string referenceId = mPhysics->sceneNodeToRefId(result.first);
|
||||||
if(referenceId != "")
|
if(referenceId != "")
|
||||||
std::cout << "result: " << referenceId << std::endl;
|
std::cout << "result grab release: " << referenceId << std::endl;
|
||||||
else
|
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()
|
std::cout << " hit pos "+ QString::number(result.second.x).toStdString()
|
||||||
+ ", " + QString::number(result.second.y).toStdString()
|
+ ", " + QString::number(result.second.y).toStdString()
|
||||||
+ ", " + QString::number(result.second.z).toStdString() << std::endl;
|
+ ", " + QString::number(result.second.z).toStdString() << std::endl;
|
||||||
|
@ -234,7 +234,20 @@ namespace CSVRender
|
||||||
// move pathgrid point, but don't save yet (need pathgrid
|
// move pathgrid point, but don't save yet (need pathgrid
|
||||||
// table feature & its data structure to be completed)
|
// table feature & its data structure to be completed)
|
||||||
// FIXME: need to signal PathgridPoint object of change
|
// FIXME: need to signal PathgridPoint object of change
|
||||||
placeObject(mGrabbedSceneNode, pos);
|
std::pair<std::string, Ogre::Vector3> 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
|
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<std::string, Ogre::Vector3> MouseState::pgPointUnderCursor(const int mouseX, const int mouseY)
|
||||||
|
{
|
||||||
|
std::pair<std::string, Ogre::Vector3> 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<bool, Ogre::Vector3> MouseState::mousePositionOnPlane(const QPoint &pos, const Ogre::Plane &plane)
|
std::pair<bool, Ogre::Vector3> MouseState::mousePositionOnPlane(const QPoint &pos, const Ogre::Plane &plane)
|
||||||
{
|
{
|
||||||
// using a really small value seems to mess up with the projections
|
// using a really small value seems to mess up with the projections
|
||||||
|
@ -417,10 +445,6 @@ namespace CSVRender
|
||||||
std::pair<std::string, Ogre::Vector3> result = mPhysics->castRay(x, y, mSceneManager, getCamera());
|
std::pair<std::string, Ogre::Vector3> result = mPhysics->castRay(x, y, mSceneManager, getCamera());
|
||||||
if(result.first != "")
|
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?
|
// FIXME: is there a better way to distinguish terrain from objects?
|
||||||
QString name = QString(result.first.c_str());
|
QString name = QString(result.first.c_str());
|
||||||
if(name.contains(QRegExp("^HeightField")))
|
if(name.contains(QRegExp("^HeightField")))
|
||||||
|
|
|
@ -71,13 +71,14 @@ namespace CSVRender
|
||||||
void mouseReleaseEvent (QMouseEvent *event);
|
void mouseReleaseEvent (QMouseEvent *event);
|
||||||
void mouseDoubleClickEvent (QMouseEvent *event);
|
void mouseDoubleClickEvent (QMouseEvent *event);
|
||||||
bool wheelEvent (QWheelEvent *event);
|
bool wheelEvent (QWheelEvent *event);
|
||||||
|
std::pair<std::string, Ogre::Vector3> pgPointUnderCursor(const int mouseX, const int mouseY);
|
||||||
|
std::pair<std::string, Ogre::Vector3> terrainUnderCursor(const int mouseX, const int mouseY);
|
||||||
|
|
||||||
void cancelDrag();
|
void cancelDrag();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::pair<bool, Ogre::Vector3> mousePositionOnPlane(const QPoint &pos, const Ogre::Plane &plane);
|
std::pair<bool, Ogre::Vector3> mousePositionOnPlane(const QPoint &pos, const Ogre::Plane &plane);
|
||||||
std::pair<std::string, Ogre::Vector3> terrainUnderCursor(const int mouseX, const int mouseY);
|
|
||||||
std::pair<std::string, Ogre::Vector3> objectUnderCursor(const int mouseX, const int mouseY);
|
std::pair<std::string, Ogre::Vector3> objectUnderCursor(const int mouseX, const int mouseY);
|
||||||
std::pair<Ogre::Vector3, Ogre::Vector3> planeAxis();
|
std::pair<Ogre::Vector3, Ogre::Vector3> planeAxis();
|
||||||
void updateSceneWidgets();
|
void updateSceneWidgets();
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "../widget/scenetooltoggle.hpp"
|
#include "../widget/scenetooltoggle.hpp"
|
||||||
|
|
||||||
|
#include "pathgridpoint.hpp"
|
||||||
#include "elements.hpp"
|
#include "elements.hpp"
|
||||||
|
|
||||||
bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
||||||
|
@ -295,6 +296,99 @@ void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent
|
||||||
flagAsModified();
|
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<CSMWorld::Cell>& cells = mDocument.getData().getCells();
|
||||||
|
|
||||||
|
std::map<CSMWorld::CellCoordinates, Cell *>::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<std::string, int> 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<std::string, int> result = PathgridPoint::getIdAndIndex(pgName);
|
||||||
|
|
||||||
|
Cell *cell = findCell(result.first);
|
||||||
|
if(cell)
|
||||||
|
{
|
||||||
|
cell->pathgridPointRemoved(pgName);
|
||||||
|
flagAsModified();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction()
|
std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction()
|
||||||
{
|
{
|
||||||
Ogre::Vector3 position = getCamera()->getPosition();
|
Ogre::Vector3 position = getCamera()->getPosition();
|
||||||
|
|
|
@ -49,8 +49,16 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void referenceAdded (const QModelIndex& index, int start, int end);
|
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();
|
virtual std::string getStartupInstruction();
|
||||||
|
|
||||||
|
Cell *findCell(const std::string &cellId);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document);
|
PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document);
|
||||||
|
@ -87,6 +95,11 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void mouseDoubleClickEvent (QMouseEvent *event);
|
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:
|
signals:
|
||||||
|
|
||||||
void cellSelectionChanged (const CSMWorld::CellSelection& selection);
|
void cellSelectionChanged (const CSMWorld::CellSelection& selection);
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <iostream> // FIXME
|
#include <iostream> // FIXME
|
||||||
|
|
||||||
|
#include <QRegExp>
|
||||||
|
|
||||||
#include <OgreSceneManager.h>
|
#include <OgreSceneManager.h>
|
||||||
#include <OgreSceneNode.h>
|
#include <OgreSceneNode.h>
|
||||||
|
|
||||||
|
@ -35,4 +37,37 @@ namespace CSVRender
|
||||||
if (mBase)
|
if (mBase)
|
||||||
mBase->getCreator()->destroySceneNode(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<std::string, int> 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,10 @@ namespace CSVRender
|
||||||
Ogre::SceneNode *cellNode, const Ogre::Vector3 &pos, CSVWorld::PhysicsSystem *physics);
|
Ogre::SceneNode *cellNode, const Ogre::Vector3 &pos, CSVWorld::PhysicsSystem *physics);
|
||||||
|
|
||||||
~PathgridPoint();
|
~PathgridPoint();
|
||||||
|
|
||||||
|
static std::pair<std::string, int> getIdAndIndex(const std::string &name);
|
||||||
|
|
||||||
|
static std::string getName(const std::string &pathgridId, int index);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,24 @@ void CSVRender::UnpagedWorldspaceWidget::referenceAdded (const QModelIndex& pare
|
||||||
flagAsModified();
|
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()
|
std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction()
|
||||||
{
|
{
|
||||||
Ogre::Vector3 position = getCamera()->getPosition();
|
Ogre::Vector3 position = getCamera()->getPosition();
|
||||||
|
|
|
@ -62,6 +62,12 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void referenceAdded (const QModelIndex& index, int start, int end);
|
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();
|
virtual std::string getStartupInstruction();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <OgreEntity.h>
|
#include <OgreEntity.h>
|
||||||
|
|
||||||
#include <QtGui/qevent.h>
|
#include <QtGui/qevent.h>
|
||||||
|
#include <QPoint>
|
||||||
|
|
||||||
#include "../../model/world/universalid.hpp"
|
#include "../../model/world/universalid.hpp"
|
||||||
#include "../../model/world/idtable.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)),
|
connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
this, SLOT (debugProfileAboutToBeRemoved (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
|
// associate WorldSpaceWidgets (and their SceneManagers) with Documents
|
||||||
// then create physics if there is a new document
|
// then create physics if there is a new document
|
||||||
mPhysics = CSVWorld::PhysicsManager::instance()->addSceneWidget(document, this);
|
mPhysics = CSVWorld::PhysicsManager::instance()->addSceneWidget(document, this);
|
||||||
|
@ -389,12 +400,51 @@ void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
|
||||||
SceneWidget::wheelEvent(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)
|
void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
|
||||||
{
|
{
|
||||||
if(event->key() == Qt::Key_Escape)
|
if(event->key() == Qt::Key_Escape)
|
||||||
{
|
{
|
||||||
mMouse->cancelDrag();
|
mMouse->cancelDrag();
|
||||||
}
|
}
|
||||||
|
else if(event->key() == Qt::Key_Delete)
|
||||||
|
{
|
||||||
|
QPoint p = this->mapFromGlobal(QCursor::pos());
|
||||||
|
std::pair<std::string, Ogre::Vector3> result = mMouse->pgPointUnderCursor(p.x(), p.y());
|
||||||
|
if(result.first != "")
|
||||||
|
{
|
||||||
|
pathgridAboutToBeRemoved(result.first);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
SceneWidget::keyPressEvent(event);
|
SceneWidget::keyPressEvent(event);
|
||||||
}
|
}
|
||||||
|
else if(event->key() == Qt::Key_Insert)
|
||||||
|
{
|
||||||
|
QPoint p = this->mapFromGlobal(QCursor::pos());
|
||||||
|
std::pair<std::string, Ogre::Vector3> 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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -109,6 +109,11 @@ namespace CSVRender
|
||||||
virtual void wheelEvent (QWheelEvent *event);
|
virtual void wheelEvent (QWheelEvent *event);
|
||||||
virtual void keyPressEvent (QKeyEvent *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:
|
private:
|
||||||
|
|
||||||
void dragEnterEvent(QDragEnterEvent *event);
|
void dragEnterEvent(QDragEnterEvent *event);
|
||||||
|
@ -143,6 +148,11 @@ namespace CSVRender
|
||||||
|
|
||||||
void debugProfileAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
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:
|
protected slots:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue