forked from mirror/openmw-tes3mp
Merge remote-tracking branch 'aesylwinn/RenderPathgrid'
This commit is contained in:
commit
b4e341e1e2
13 changed files with 476 additions and 113 deletions
|
@ -1,10 +1,14 @@
|
||||||
#include "cell.hpp"
|
#include "cell.hpp"
|
||||||
|
|
||||||
|
#include <osg/PositionAttitudeTransform>
|
||||||
|
#include <osg/Geode>
|
||||||
|
#include <osg/Geometry>
|
||||||
#include <osg/Group>
|
#include <osg/Group>
|
||||||
|
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
#include <components/esm/loadcell.hpp>
|
#include <components/esm/loadcell.hpp>
|
||||||
#include <components/esm/loadland.hpp>
|
#include <components/esm/loadland.hpp>
|
||||||
|
#include <components/sceneutil/pathgridutil.hpp>
|
||||||
|
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
#include "../../model/world/columns.hpp"
|
#include "../../model/world/columns.hpp"
|
||||||
|
@ -64,6 +68,18 @@ bool CSVRender::Cell::addObjects (int start, int end)
|
||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::Cell::recreatePathgrid()
|
||||||
|
{
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mData.getPathgrids();
|
||||||
|
int pathgridIndex = pathgrids.searchId(mId);
|
||||||
|
if (pathgridIndex != -1)
|
||||||
|
{
|
||||||
|
mPathgridGeode->removeDrawable(mPathgridGeometry);
|
||||||
|
mPathgridGeometry = SceneUtil::createPathgridGeometry(pathgrids.getRecord(pathgridIndex).get());
|
||||||
|
mPathgridGeode->addDrawable(mPathgridGeometry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id,
|
CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id,
|
||||||
bool deleted)
|
bool deleted)
|
||||||
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mDeleted (deleted), mSubMode (0),
|
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mDeleted (deleted), mSubMode (0),
|
||||||
|
@ -77,6 +93,17 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st
|
||||||
mCellNode = new osg::Group;
|
mCellNode = new osg::Group;
|
||||||
rootNode->addChild(mCellNode);
|
rootNode->addChild(mCellNode);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::PositionAttitudeTransform> pathgridTransform = new osg::PositionAttitudeTransform();
|
||||||
|
pathgridTransform->setPosition(osg::Vec3f(mCoordinates.getX() * ESM::Land::REAL_SIZE,
|
||||||
|
mCoordinates.getY() * ESM::Land::REAL_SIZE, 0));
|
||||||
|
pathgridTransform->setNodeMask(Mask_Pathgrid);
|
||||||
|
mCellNode->addChild(pathgridTransform);
|
||||||
|
|
||||||
|
mPathgridGeode = new osg::Geode();
|
||||||
|
pathgridTransform->addChild(mPathgridGeode);
|
||||||
|
|
||||||
|
mPathgridGeometry = 0;
|
||||||
|
|
||||||
setCellMarker();
|
setCellMarker();
|
||||||
|
|
||||||
if (!mDeleted)
|
if (!mDeleted)
|
||||||
|
@ -104,6 +131,8 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st
|
||||||
mCellBorder->buildShape(esmLand);
|
mCellBorder->buildShape(esmLand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recreatePathgrid();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,6 +283,31 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int
|
||||||
return addObjects (start, end);
|
return addObjects (start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::Cell::pathgridAdded(const CSMWorld::Pathgrid& pathgrid)
|
||||||
|
{
|
||||||
|
recreatePathgrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Cell::pathgridRemoved()
|
||||||
|
{
|
||||||
|
mPathgridGeode->removeDrawable(mPathgridGeometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Cell::pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
recreatePathgrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Cell::pathgridRowRemoved(const QModelIndex& parent, int start, int end)
|
||||||
|
{
|
||||||
|
recreatePathgrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Cell::pathgridRowAdded(const QModelIndex& parent, int start, int end)
|
||||||
|
{
|
||||||
|
recreatePathgrid();
|
||||||
|
}
|
||||||
|
|
||||||
void CSVRender::Cell::setSelection (int elementMask, Selection mode)
|
void CSVRender::Cell::setSelection (int elementMask, Selection mode)
|
||||||
{
|
{
|
||||||
if (elementMask & Mask_Reference)
|
if (elementMask & Mask_Reference)
|
||||||
|
|
|
@ -23,12 +23,15 @@ class QModelIndex;
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
class Group;
|
class Group;
|
||||||
|
class Geometry;
|
||||||
|
class Geode;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
class Data;
|
class Data;
|
||||||
class CellCoordinates;
|
class CellCoordinates;
|
||||||
|
class Pathgrid;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
|
@ -40,6 +43,8 @@ namespace CSVRender
|
||||||
CSMWorld::Data& mData;
|
CSMWorld::Data& mData;
|
||||||
std::string mId;
|
std::string mId;
|
||||||
osg::ref_ptr<osg::Group> mCellNode;
|
osg::ref_ptr<osg::Group> mCellNode;
|
||||||
|
osg::ref_ptr<osg::Geode> mPathgridGeode;
|
||||||
|
osg::ref_ptr<osg::Geometry> mPathgridGeometry;
|
||||||
std::map<std::string, Object *> mObjects;
|
std::map<std::string, Object *> mObjects;
|
||||||
std::auto_ptr<Terrain::TerrainGrid> mTerrain;
|
std::auto_ptr<Terrain::TerrainGrid> mTerrain;
|
||||||
CSMWorld::CellCoordinates mCoordinates;
|
CSMWorld::CellCoordinates mCoordinates;
|
||||||
|
@ -64,6 +69,8 @@ namespace CSVRender
|
||||||
/// \return Have any objects been added?
|
/// \return Have any objects been added?
|
||||||
bool addObjects (int start, int end);
|
bool addObjects (int start, int end);
|
||||||
|
|
||||||
|
void recreatePathgrid();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Selection
|
enum Selection
|
||||||
|
@ -103,6 +110,16 @@ namespace CSVRender
|
||||||
/// this cell?
|
/// this cell?
|
||||||
bool referenceAdded (const QModelIndex& parent, int start, int end);
|
bool referenceAdded (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
void pathgridAdded(const CSMWorld::Pathgrid& pathgrid);
|
||||||
|
|
||||||
|
void pathgridRemoved();
|
||||||
|
|
||||||
|
void pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
void pathgridRowRemoved(const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
void pathgridRowAdded(const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
void setSelection (int elementMask, Selection mode);
|
void setSelection (int elementMask, Selection mode);
|
||||||
|
|
||||||
// Select everything that references the same ID as at least one of the elements
|
// Select everything that references the same ID as at least one of the elements
|
||||||
|
|
|
@ -275,6 +275,107 @@ void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
|
||||||
|
|
||||||
|
if (topLeft.parent().isValid())
|
||||||
|
{
|
||||||
|
int row = topLeft.parent().row();
|
||||||
|
|
||||||
|
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
|
||||||
|
CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY);
|
||||||
|
|
||||||
|
std::map<CSMWorld::CellCoordinates, Cell*>::iterator searchResult = mCells.find(coords);
|
||||||
|
if (searchResult != mCells.end())
|
||||||
|
{
|
||||||
|
searchResult->second->pathgridDataChanged(topLeft, bottomRight);
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::pathgridRemoved (const QModelIndex& parent, int start, int end)
|
||||||
|
{
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
|
||||||
|
|
||||||
|
if (parent.isValid())
|
||||||
|
{
|
||||||
|
// Pathgrid data was modified
|
||||||
|
int row = parent.row();
|
||||||
|
|
||||||
|
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
|
||||||
|
CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY);
|
||||||
|
|
||||||
|
std::map<CSMWorld::CellCoordinates, Cell*>::iterator searchResult = mCells.find(coords);
|
||||||
|
if (searchResult != mCells.end())
|
||||||
|
{
|
||||||
|
searchResult->second->pathgridRowRemoved(parent, start, end);
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end)
|
||||||
|
{
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
|
||||||
|
|
||||||
|
if (!parent.isValid())
|
||||||
|
{
|
||||||
|
// Pathgrid going to be deleted
|
||||||
|
for (int row = start; row <= end; ++row)
|
||||||
|
{
|
||||||
|
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
|
||||||
|
CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY);
|
||||||
|
|
||||||
|
std::map<CSMWorld::CellCoordinates, Cell*>::iterator searchResult = mCells.find(coords);
|
||||||
|
if (searchResult != mCells.end())
|
||||||
|
{
|
||||||
|
searchResult->second->pathgridRemoved();
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::pathgridAdded(const QModelIndex& parent, int start, int end)
|
||||||
|
{
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
|
||||||
|
|
||||||
|
if (!parent.isValid())
|
||||||
|
{
|
||||||
|
// Pathgrid added theoretically, unable to test until it is possible to add pathgrids
|
||||||
|
for (int row = start; row <= end; ++row)
|
||||||
|
{
|
||||||
|
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
|
||||||
|
CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY);
|
||||||
|
|
||||||
|
std::map<CSMWorld::CellCoordinates, Cell*>::iterator searchResult = mCells.find(coords);
|
||||||
|
if (searchResult != mCells.end())
|
||||||
|
{
|
||||||
|
searchResult->second->pathgridAdded(pathgrid);
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Pathgrid data was modified
|
||||||
|
int row = parent.row();
|
||||||
|
|
||||||
|
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
|
||||||
|
CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY);
|
||||||
|
|
||||||
|
std::map<CSMWorld::CellCoordinates, Cell*>::iterator searchResult = mCells.find(coords);
|
||||||
|
if (searchResult != mCells.end())
|
||||||
|
{
|
||||||
|
searchResult->second->pathgridRowAdded(parent, start, end);
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction()
|
std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction()
|
||||||
{
|
{
|
||||||
osg::Vec3d eye, center, up;
|
osg::Vec3d eye, center, up;
|
||||||
|
|
|
@ -52,6 +52,14 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void referenceAdded (const QModelIndex& index, int start, int end);
|
virtual void referenceAdded (const QModelIndex& index, int start, int end);
|
||||||
|
|
||||||
|
virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
virtual void pathgridRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
virtual void pathgridAdded (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
virtual std::string getStartupInstruction();
|
virtual std::string getStartupInstruction();
|
||||||
|
|
||||||
/// \note Does not update the view or any cell marker
|
/// \note Does not update the view or any cell marker
|
||||||
|
|
|
@ -32,7 +32,7 @@ void CSVRender::UnpagedWorldspaceWidget::update()
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget* parent)
|
CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget* parent)
|
||||||
: WorldspaceWidget (document, parent), mCellId (cellId)
|
: WorldspaceWidget (document, parent), mDocument(document), mCellId (cellId)
|
||||||
{
|
{
|
||||||
mCellsModel = &dynamic_cast<CSMWorld::IdTable&> (
|
mCellsModel = &dynamic_cast<CSMWorld::IdTable&> (
|
||||||
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
|
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
|
||||||
|
@ -197,6 +197,90 @@ void CSVRender::UnpagedWorldspaceWidget::referenceAdded (const QModelIndex& pare
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
|
||||||
|
|
||||||
|
if (topLeft.parent().isValid())
|
||||||
|
{
|
||||||
|
int row = topLeft.parent().row();
|
||||||
|
|
||||||
|
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
|
||||||
|
if (mCellId == pathgrid.mId)
|
||||||
|
{
|
||||||
|
mCell->pathgridDataChanged(topLeft, bottomRight);
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::pathgridRemoved (const QModelIndex& parent, int start, int end)
|
||||||
|
{
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
|
||||||
|
|
||||||
|
if (parent.isValid()){
|
||||||
|
// Pathgrid data was modified
|
||||||
|
int row = parent.row();
|
||||||
|
|
||||||
|
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
|
||||||
|
if (mCellId == pathgrid.mId)
|
||||||
|
{
|
||||||
|
mCell->pathgridRowRemoved(parent, start, end);
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end)
|
||||||
|
{
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
|
||||||
|
|
||||||
|
if (!parent.isValid())
|
||||||
|
{
|
||||||
|
// Pathgrid going to be deleted
|
||||||
|
for (int row = start; row <= end; ++row)
|
||||||
|
{
|
||||||
|
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
|
||||||
|
if (mCellId == pathgrid.mId)
|
||||||
|
{
|
||||||
|
mCell->pathgridRemoved();
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::pathgridAdded (const QModelIndex& parent, int start, int end)
|
||||||
|
{
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
|
||||||
|
|
||||||
|
if (!parent.isValid())
|
||||||
|
{
|
||||||
|
// Pathgrid added theoretically, unable to test until it is possible to add pathgrids
|
||||||
|
for (int row = start; row <= end; ++row)
|
||||||
|
{
|
||||||
|
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
|
||||||
|
if (mCellId == pathgrid.mId)
|
||||||
|
{
|
||||||
|
mCell->pathgridAdded(pathgrid);
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Pathgrid data was modified
|
||||||
|
int row = parent.row();
|
||||||
|
|
||||||
|
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
|
||||||
|
if (mCellId == pathgrid.mId)
|
||||||
|
{
|
||||||
|
mCell->pathgridRowAdded(parent, start, end);
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons (
|
void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons (
|
||||||
CSVWidget::SceneToolToggle2 *tool)
|
CSVWidget::SceneToolToggle2 *tool)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace CSVRender
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSMDoc::Document& mDocument;
|
||||||
std::string mCellId;
|
std::string mCellId;
|
||||||
CSMWorld::IdTable *mCellsModel;
|
CSMWorld::IdTable *mCellsModel;
|
||||||
CSMWorld::IdTable *mReferenceablesModel;
|
CSMWorld::IdTable *mReferenceablesModel;
|
||||||
|
@ -83,6 +84,15 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void referenceAdded (const QModelIndex& index, int start, int end);
|
virtual void referenceAdded (const QModelIndex& index, int start, int end);
|
||||||
|
|
||||||
|
virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
virtual void pathgridRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
virtual void pathgridAdded (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
|
||||||
virtual std::string getStartupInstruction();
|
virtual std::string getStartupInstruction();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -59,6 +59,17 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
|
||||||
connect (references, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
connect (references, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||||
this, SLOT (referenceAdded (const QModelIndex&, int, int)));
|
this, SLOT (referenceAdded (const QModelIndex&, int, int)));
|
||||||
|
|
||||||
|
QAbstractItemModel *pathgrids = document.getData().getTableModel (CSMWorld::UniversalId::Type_Pathgrids);
|
||||||
|
|
||||||
|
connect (pathgrids, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
|
this, SLOT (pathgridDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
|
connect (pathgrids, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (pathgridRemoved (const QModelIndex&, int, int)));
|
||||||
|
connect (pathgrids, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (pathgridAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
connect (pathgrids, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (pathgridAdded (const QModelIndex&, int, int)));
|
||||||
|
|
||||||
QAbstractItemModel *debugProfiles =
|
QAbstractItemModel *debugProfiles =
|
||||||
document.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles);
|
document.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles);
|
||||||
|
|
||||||
|
|
|
@ -228,6 +228,15 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void referenceAdded (const QModelIndex& index, int start, int end) = 0;
|
virtual void referenceAdded (const QModelIndex& index, int start, int end) = 0;
|
||||||
|
|
||||||
|
virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) = 0;
|
||||||
|
|
||||||
|
virtual void pathgridRemoved (const QModelIndex& parent, int start, int end) = 0;
|
||||||
|
|
||||||
|
virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) = 0;
|
||||||
|
|
||||||
|
virtual void pathgridAdded (const QModelIndex& parent, int start, int end) = 0;
|
||||||
|
|
||||||
|
|
||||||
virtual void runRequest (const std::string& profile);
|
virtual void runRequest (const std::string& profile);
|
||||||
|
|
||||||
void debugProfileDataChanged (const QModelIndex& topLeft,
|
void debugProfileDataChanged (const QModelIndex& topLeft,
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <components/esm/loadstat.hpp>
|
#include <components/esm/loadstat.hpp>
|
||||||
#include <components/esm/loadpgrd.hpp>
|
#include <components/esm/loadpgrd.hpp>
|
||||||
|
#include <components/sceneutil/pathgridutil.hpp>
|
||||||
|
|
||||||
#include "../mwbase/world.hpp" // these includes can be removed once the static-hack is gone
|
#include "../mwbase/world.hpp" // these includes can be removed once the static-hack is gone
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -23,107 +24,6 @@
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
|
|
||||||
static const int POINT_MESH_BASE = 35;
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Geometry> Pathgrid::createPathgridLines(const ESM::Pathgrid *pathgrid)
|
|
||||||
{
|
|
||||||
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
|
|
||||||
|
|
||||||
for(ESM::Pathgrid::EdgeList::const_iterator it = pathgrid->mEdges.begin();
|
|
||||||
it != pathgrid->mEdges.end();
|
|
||||||
++it)
|
|
||||||
{
|
|
||||||
const ESM::Pathgrid::Edge &edge = *it;
|
|
||||||
const ESM::Pathgrid::Point &p1 = pathgrid->mPoints[edge.mV0], &p2 = pathgrid->mPoints[edge.mV1];
|
|
||||||
|
|
||||||
osg::Vec3f direction = MWMechanics::PathFinder::MakeOsgVec3(p2) - MWMechanics::PathFinder::MakeOsgVec3(p1);
|
|
||||||
osg::Vec3f lineDisplacement = (direction^osg::Vec3f(0,0,1));
|
|
||||||
lineDisplacement.normalize();
|
|
||||||
|
|
||||||
lineDisplacement = lineDisplacement * POINT_MESH_BASE +
|
|
||||||
osg::Vec3f(0, 0, 10); // move lines up a little, so they will be less covered by meshes/landscape
|
|
||||||
|
|
||||||
vertices->push_back(MWMechanics::PathFinder::MakeOsgVec3(p1) + lineDisplacement);
|
|
||||||
vertices->push_back(MWMechanics::PathFinder::MakeOsgVec3(p2) + lineDisplacement);
|
|
||||||
}
|
|
||||||
|
|
||||||
geom->setVertexArray(vertices);
|
|
||||||
|
|
||||||
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vertices->size()));
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
|
|
||||||
colors->push_back(osg::Vec4(1.f, 1.f, 0.f, 1.f));
|
|
||||||
geom->setColorArray(colors, osg::Array::BIND_OVERALL);
|
|
||||||
|
|
||||||
return geom;
|
|
||||||
}
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Geometry> Pathgrid::createPathgridPoints(const ESM::Pathgrid *pathgrid)
|
|
||||||
{
|
|
||||||
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
|
|
||||||
|
|
||||||
const float height = POINT_MESH_BASE * sqrtf(2);
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
|
|
||||||
osg::ref_ptr<osg::UShortArray> indices = new osg::UShortArray;
|
|
||||||
|
|
||||||
bool first = true;
|
|
||||||
unsigned short startIndex = 0;
|
|
||||||
for(ESM::Pathgrid::PointList::const_iterator it = pathgrid->mPoints.begin();
|
|
||||||
it != pathgrid->mPoints.end();
|
|
||||||
++it, startIndex += 6)
|
|
||||||
{
|
|
||||||
osg::Vec3f pointPos(MWMechanics::PathFinder::MakeOsgVec3(*it));
|
|
||||||
|
|
||||||
if (!first)
|
|
||||||
{
|
|
||||||
// degenerate triangle from previous octahedron
|
|
||||||
indices->push_back(startIndex - 4); // 2nd point of previous octahedron
|
|
||||||
indices->push_back(startIndex); // start point of current octahedron
|
|
||||||
}
|
|
||||||
|
|
||||||
float pointMeshBase = static_cast<float>(POINT_MESH_BASE);
|
|
||||||
|
|
||||||
vertices->push_back(pointPos + osg::Vec3f(0, 0, height)); // 0
|
|
||||||
vertices->push_back(pointPos + osg::Vec3f(-pointMeshBase, -pointMeshBase, 0)); // 1
|
|
||||||
vertices->push_back(pointPos + osg::Vec3f(pointMeshBase, -pointMeshBase, 0)); // 2
|
|
||||||
vertices->push_back(pointPos + osg::Vec3f(pointMeshBase, pointMeshBase, 0)); // 3
|
|
||||||
vertices->push_back(pointPos + osg::Vec3f(-pointMeshBase, pointMeshBase, 0)); // 4
|
|
||||||
vertices->push_back(pointPos + osg::Vec3f(0, 0, -height)); // 5
|
|
||||||
|
|
||||||
indices->push_back(startIndex + 0);
|
|
||||||
indices->push_back(startIndex + 1);
|
|
||||||
indices->push_back(startIndex + 2);
|
|
||||||
indices->push_back(startIndex + 5);
|
|
||||||
indices->push_back(startIndex + 3);
|
|
||||||
indices->push_back(startIndex + 4);
|
|
||||||
// degenerates
|
|
||||||
indices->push_back(startIndex + 4);
|
|
||||||
indices->push_back(startIndex + 5);
|
|
||||||
indices->push_back(startIndex + 5);
|
|
||||||
// end degenerates
|
|
||||||
indices->push_back(startIndex + 1);
|
|
||||||
indices->push_back(startIndex + 4);
|
|
||||||
indices->push_back(startIndex + 0);
|
|
||||||
indices->push_back(startIndex + 3);
|
|
||||||
indices->push_back(startIndex + 2);
|
|
||||||
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
geom->setVertexArray(vertices);
|
|
||||||
|
|
||||||
geom->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, indices->size(), &(*indices)[0]));
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
|
|
||||||
colors->push_back(osg::Vec4(1.f, 0.f, 0.f, 1.f));
|
|
||||||
geom->setColorArray(colors, osg::Array::BIND_OVERALL);
|
|
||||||
|
|
||||||
return geom;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pathgrid::Pathgrid(osg::ref_ptr<osg::Group> root)
|
Pathgrid::Pathgrid(osg::ref_ptr<osg::Group> root)
|
||||||
: mPathgridEnabled(false)
|
: mPathgridEnabled(false)
|
||||||
, mRootNode(root)
|
, mRootNode(root)
|
||||||
|
@ -212,12 +112,9 @@ void Pathgrid::enableCellPathgrid(const MWWorld::CellStore *store)
|
||||||
osg::ref_ptr<osg::PositionAttitudeTransform> cellPathGrid = new osg::PositionAttitudeTransform;
|
osg::ref_ptr<osg::PositionAttitudeTransform> cellPathGrid = new osg::PositionAttitudeTransform;
|
||||||
cellPathGrid->setPosition(cellPathGridPos);
|
cellPathGrid->setPosition(cellPathGridPos);
|
||||||
|
|
||||||
osg::ref_ptr<osg::Geometry> lines = createPathgridLines(pathgrid);
|
osg::ref_ptr<osg::Geometry> geometry = SceneUtil::createPathgridGeometry(*pathgrid);
|
||||||
|
|
||||||
osg::ref_ptr<osg::Geometry> points = createPathgridPoints(pathgrid);
|
cellPathGrid->addChild(geometry);
|
||||||
|
|
||||||
cellPathGrid->addChild(lines);
|
|
||||||
cellPathGrid->addChild(points);
|
|
||||||
|
|
||||||
mPathGridRoot->addChild(cellPathGrid);
|
mPathGridRoot->addChild(cellPathGrid);
|
||||||
|
|
||||||
|
|
|
@ -48,9 +48,6 @@ namespace MWRender
|
||||||
void enableCellPathgrid(const MWWorld::CellStore *store);
|
void enableCellPathgrid(const MWWorld::CellStore *store);
|
||||||
void disableCellPathgrid(const MWWorld::CellStore *store);
|
void disableCellPathgrid(const MWWorld::CellStore *store);
|
||||||
|
|
||||||
// path grid meshes
|
|
||||||
osg::ref_ptr<osg::Geometry> createPathgridLines(const ESM::Pathgrid *pathgrid);
|
|
||||||
osg::ref_ptr<osg::Geometry> createPathgridPoints(const ESM::Pathgrid *pathgrid);
|
|
||||||
public:
|
public:
|
||||||
Pathgrid(osg::ref_ptr<osg::Group> root);
|
Pathgrid(osg::ref_ptr<osg::Group> root);
|
||||||
~Pathgrid();
|
~Pathgrid();
|
||||||
|
|
|
@ -50,7 +50,7 @@ add_component_dir (shader
|
||||||
|
|
||||||
add_component_dir (sceneutil
|
add_component_dir (sceneutil
|
||||||
clone attach visitor util statesetupdater controller skeleton riggeometry lightcontroller
|
clone attach visitor util statesetupdater controller skeleton riggeometry lightcontroller
|
||||||
lightmanager lightutil positionattitudetransform workqueue unrefqueue
|
lightmanager lightutil positionattitudetransform workqueue unrefqueue pathgridutil
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (nif
|
add_component_dir (nif
|
||||||
|
|
158
components/sceneutil/pathgridutil.cpp
Normal file
158
components/sceneutil/pathgridutil.cpp
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
#include "pathgridutil.hpp"
|
||||||
|
|
||||||
|
#include <osg/Geometry>
|
||||||
|
|
||||||
|
#include <components/esm/loadland.hpp>
|
||||||
|
#include <components/esm/loadpgrd.hpp>
|
||||||
|
|
||||||
|
namespace SceneUtil
|
||||||
|
{
|
||||||
|
const unsigned short DiamondVertexCount = 6;
|
||||||
|
const unsigned short DiamondIndexCount = 24;
|
||||||
|
|
||||||
|
const unsigned short DiamondConnectorVertexCount = 4;
|
||||||
|
|
||||||
|
const unsigned short DiamondTotalVertexCount = DiamondVertexCount + DiamondConnectorVertexCount;
|
||||||
|
|
||||||
|
const float DiamondHalfHeight = 40.f;
|
||||||
|
const float DiamondHalfWidth = 16.f;
|
||||||
|
|
||||||
|
const osg::Vec3f DiamondPoints[DiamondVertexCount] =
|
||||||
|
{
|
||||||
|
osg::Vec3f( 0.f, 0.f, DiamondHalfHeight * 2.f),
|
||||||
|
osg::Vec3f(-DiamondHalfWidth, -DiamondHalfWidth, DiamondHalfHeight),
|
||||||
|
osg::Vec3f(-DiamondHalfWidth, DiamondHalfWidth, DiamondHalfHeight),
|
||||||
|
osg::Vec3f( DiamondHalfWidth, -DiamondHalfWidth, DiamondHalfHeight),
|
||||||
|
osg::Vec3f( DiamondHalfWidth, DiamondHalfWidth, DiamondHalfHeight),
|
||||||
|
osg::Vec3f( 0.f, 0.f, 0.f)
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned short DiamondIndices[DiamondIndexCount] =
|
||||||
|
{
|
||||||
|
0, 2, 1,
|
||||||
|
0, 1, 3,
|
||||||
|
0, 3, 4,
|
||||||
|
0, 4, 2,
|
||||||
|
5, 1, 2,
|
||||||
|
5, 3, 1,
|
||||||
|
5, 4, 3,
|
||||||
|
5, 2, 4
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned short DiamondConnectorVertices[DiamondConnectorVertexCount] =
|
||||||
|
{
|
||||||
|
1, 2, 3, 4
|
||||||
|
};
|
||||||
|
|
||||||
|
const osg::Vec4f DiamondColors[DiamondVertexCount] =
|
||||||
|
{
|
||||||
|
osg::Vec4f(0.f, 0.f, 1.f, 1.f),
|
||||||
|
osg::Vec4f(0.f, .05f, .95f, 1.f),
|
||||||
|
osg::Vec4f(0.f, .1f, .95f, 1.f),
|
||||||
|
osg::Vec4f(0.f, .15f, .95f, 1.f),
|
||||||
|
osg::Vec4f(0.f, .2f, .95f, 1.f),
|
||||||
|
osg::Vec4f(0.f, .25f, 9.f, 1.f)
|
||||||
|
};
|
||||||
|
|
||||||
|
const osg::Vec4f DiamondEdgeColor = osg::Vec4f(0.5f, 1.f, 1.f, 1.f);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geometry> createPathgridGeometry(const ESM::Pathgrid& pathgrid)
|
||||||
|
{
|
||||||
|
const unsigned short PointCount = static_cast<unsigned short>(pathgrid.mPoints.size());
|
||||||
|
const size_t EdgeCount = pathgrid.mEdges.size();
|
||||||
|
|
||||||
|
const unsigned short VertexCount = PointCount * DiamondTotalVertexCount;
|
||||||
|
const unsigned short ColorCount = VertexCount;
|
||||||
|
const size_t PointIndexCount = PointCount * DiamondIndexCount;
|
||||||
|
const size_t EdgeIndexCount = EdgeCount * 2;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geometry> gridGeometry = new osg::Geometry();
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array(VertexCount);
|
||||||
|
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(ColorCount);
|
||||||
|
osg::ref_ptr<osg::DrawElementsUShort> pointIndices =
|
||||||
|
new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, PointIndexCount);
|
||||||
|
osg::ref_ptr<osg::DrawElementsUShort> lineIndices =
|
||||||
|
new osg::DrawElementsUShort(osg::PrimitiveSet::LINES, EdgeIndexCount);
|
||||||
|
|
||||||
|
// Add each point/node
|
||||||
|
for (unsigned short pointIndex = 0; pointIndex < PointCount; ++pointIndex)
|
||||||
|
{
|
||||||
|
const ESM::Pathgrid::Point& point = pathgrid.mPoints[pointIndex];
|
||||||
|
osg::Vec3f position = osg::Vec3f(point.mX, point.mY, point.mZ);
|
||||||
|
|
||||||
|
unsigned short vertexOffset = pointIndex * DiamondTotalVertexCount;
|
||||||
|
unsigned short indexOffset = pointIndex * DiamondIndexCount;
|
||||||
|
|
||||||
|
// Point
|
||||||
|
for (unsigned short i = 0; i < DiamondVertexCount; ++i)
|
||||||
|
{
|
||||||
|
(*vertices)[vertexOffset + i] = position + DiamondPoints[i];
|
||||||
|
(*colors)[vertexOffset + i] = DiamondColors[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned short i = 0; i < DiamondIndexCount; ++i)
|
||||||
|
{
|
||||||
|
pointIndices->setElement(indexOffset + i, vertexOffset + DiamondIndices[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connectors
|
||||||
|
vertexOffset += DiamondVertexCount;
|
||||||
|
for (unsigned short i = 0; i < DiamondConnectorVertexCount; ++i)
|
||||||
|
{
|
||||||
|
(*vertices)[vertexOffset + i] = position + DiamondPoints[DiamondConnectorVertices[i]];
|
||||||
|
(*colors)[vertexOffset + i] = DiamondEdgeColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add edges
|
||||||
|
unsigned short lineIndex = 0;
|
||||||
|
|
||||||
|
for (ESM::Pathgrid::EdgeList::const_iterator edge = pathgrid.mEdges.begin();
|
||||||
|
edge != pathgrid.mEdges.end(); ++edge)
|
||||||
|
{
|
||||||
|
if (edge->mV0 == edge->mV1 || edge->mV0 < 0 || edge->mV0 >= PointCount ||
|
||||||
|
edge->mV1 < 0 || edge->mV1 >= PointCount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const ESM::Pathgrid::Point& from = pathgrid.mPoints[edge->mV0];
|
||||||
|
const ESM::Pathgrid::Point& to = pathgrid.mPoints[edge->mV1];
|
||||||
|
|
||||||
|
osg::Vec3f fromPos = osg::Vec3f(from.mX, from.mY, from.mZ);
|
||||||
|
osg::Vec3f toPos = osg::Vec3f(to.mX, to.mY, to.mZ);
|
||||||
|
osg::Vec3f dir = toPos - fromPos;
|
||||||
|
dir.normalize();
|
||||||
|
|
||||||
|
osg::Quat rot = osg::Quat(-osg::PI / 2, osg::Vec3(0, 0, 1));
|
||||||
|
dir = rot * dir;
|
||||||
|
|
||||||
|
unsigned short diamondIndex = 0;
|
||||||
|
if (dir.isNaN())
|
||||||
|
diamondIndex = 0;
|
||||||
|
else if (dir.y() >= 0 && dir.x() > 0)
|
||||||
|
diamondIndex = 3;
|
||||||
|
else if (dir.x() <= 0 && dir.y() > 0)
|
||||||
|
diamondIndex = 1;
|
||||||
|
else if (dir.y() <= 0 && dir.x() < 0)
|
||||||
|
diamondIndex = 0;
|
||||||
|
else if (dir.x() >= 0 && dir.y() < 0)
|
||||||
|
diamondIndex = 2;
|
||||||
|
|
||||||
|
unsigned short fromIndex = static_cast<unsigned short>(edge->mV0);
|
||||||
|
unsigned short toIndex = static_cast<unsigned short>(edge->mV1);
|
||||||
|
|
||||||
|
lineIndices->setElement(lineIndex++, fromIndex * DiamondTotalVertexCount + DiamondVertexCount + diamondIndex);
|
||||||
|
lineIndices->setElement(lineIndex++, toIndex * DiamondTotalVertexCount + DiamondVertexCount + diamondIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
lineIndices->resize(lineIndex);
|
||||||
|
|
||||||
|
gridGeometry->setVertexArray(vertices);
|
||||||
|
gridGeometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
|
||||||
|
gridGeometry->addPrimitiveSet(pointIndices);
|
||||||
|
gridGeometry->addPrimitiveSet(lineIndices);
|
||||||
|
gridGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
|
return gridGeometry;
|
||||||
|
}
|
||||||
|
}
|
17
components/sceneutil/pathgridutil.hpp
Normal file
17
components/sceneutil/pathgridutil.hpp
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef OPENMW_COMPONENTS_PATHGRIDUTIL_H
|
||||||
|
#define OPENMW_COMPONENTS_PATHGRIDUTIL_H
|
||||||
|
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
#include <osg/Geometry>
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
class Pathgrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace SceneUtil
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Geometry> createPathgridGeometry(const ESM::Pathgrid& pathgrid);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue