forked from mirror/openmw-tes3mp
Initial pathgrid editting, support for selection and movement.
This commit is contained in:
parent
9645d0cc8a
commit
32ba5bf8b8
10 changed files with 707 additions and 40 deletions
|
@ -86,12 +86,12 @@ opencs_units (view/widget
|
||||||
opencs_units (view/render
|
opencs_units (view/render
|
||||||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||||
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
||||||
orbitcameramode
|
orbitcameramode pathgridmode
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/render
|
opencs_units_noqt (view/render
|
||||||
lighting lightingday lightingnight lightingbright object cell terrainstorage tagbase
|
lighting lightingday lightingnight lightingbright object cell terrainstorage tagbase
|
||||||
cellarrow cellmarker cellborder cameracontroller
|
cellarrow cellmarker cellborder cameracontroller pathgrid
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (view/render
|
opencs_hdrs_noqt (view/render
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "../../model/world/cellcoordinates.hpp"
|
#include "../../model/world/cellcoordinates.hpp"
|
||||||
|
|
||||||
#include "mask.hpp"
|
#include "mask.hpp"
|
||||||
|
#include "pathgrid.hpp"
|
||||||
#include "terrainstorage.hpp"
|
#include "terrainstorage.hpp"
|
||||||
|
|
||||||
bool CSVRender::Cell::removeObject (const std::string& id)
|
bool CSVRender::Cell::removeObject (const std::string& id)
|
||||||
|
@ -68,18 +69,6 @@ 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),
|
||||||
|
@ -93,17 +82,6 @@ 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)
|
||||||
|
@ -132,7 +110,7 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recreatePathgrid();
|
mPathgrid.reset(new Pathgrid(mData, mCellNode, mId, mCoordinates));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,27 +263,27 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int
|
||||||
|
|
||||||
void CSVRender::Cell::pathgridAdded(const CSMWorld::Pathgrid& pathgrid)
|
void CSVRender::Cell::pathgridAdded(const CSMWorld::Pathgrid& pathgrid)
|
||||||
{
|
{
|
||||||
recreatePathgrid();
|
mPathgrid->recreateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::Cell::pathgridRemoved()
|
void CSVRender::Cell::pathgridRemoved()
|
||||||
{
|
{
|
||||||
mPathgridGeode->removeDrawable(mPathgridGeometry);
|
mPathgrid->recreateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::Cell::pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
void CSVRender::Cell::pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
||||||
{
|
{
|
||||||
recreatePathgrid();
|
mPathgrid->recreateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::Cell::pathgridRowRemoved(const QModelIndex& parent, int start, int end)
|
void CSVRender::Cell::pathgridRowRemoved(const QModelIndex& parent, int start, int end)
|
||||||
{
|
{
|
||||||
recreatePathgrid();
|
mPathgrid->recreateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::Cell::pathgridRowAdded(const QModelIndex& parent, int start, int end)
|
void CSVRender::Cell::pathgridRowAdded(const QModelIndex& parent, int start, int end)
|
||||||
{
|
{
|
||||||
recreatePathgrid();
|
mPathgrid->recreateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::Cell::setSelection (int elementMask, Selection mode)
|
void CSVRender::Cell::setSelection (int elementMask, Selection mode)
|
||||||
|
@ -327,6 +305,15 @@ void CSVRender::Cell::setSelection (int elementMask, Selection mode)
|
||||||
iter->second->setSelected (selected);
|
iter->second->setSelected (selected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (elementMask & Mask_Pathgrid)
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case Selection_Clear: mPathgrid->clearSelected(); break;
|
||||||
|
case Selection_All: mPathgrid->selectAll(); break;
|
||||||
|
case Selection_Invert: mPathgrid->invertSelected(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::Cell::selectAllWithSameParentId (int elementMask)
|
void CSVRender::Cell::selectAllWithSameParentId (int elementMask)
|
||||||
|
@ -406,6 +393,9 @@ std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::Cell::getSelection (un
|
||||||
iter!=mObjects.end(); ++iter)
|
iter!=mObjects.end(); ++iter)
|
||||||
if (iter->second->getSelected())
|
if (iter->second->getSelected())
|
||||||
result.push_back (iter->second->getTag());
|
result.push_back (iter->second->getTag());
|
||||||
|
if (elementMask & Mask_Pathgrid)
|
||||||
|
if (mPathgrid->isSelected())
|
||||||
|
result.push_back(mPathgrid->getTag());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -440,4 +430,6 @@ void CSVRender::Cell::reset (unsigned int elementMask)
|
||||||
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
|
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
|
||||||
iter!=mObjects.end(); ++iter)
|
iter!=mObjects.end(); ++iter)
|
||||||
iter->second->reset();
|
iter->second->reset();
|
||||||
|
if (elementMask & Mask_Pathgrid)
|
||||||
|
mPathgrid->resetMove();
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ namespace CSMWorld
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
|
class Pathgrid;
|
||||||
class TagBase;
|
class TagBase;
|
||||||
|
|
||||||
class Cell
|
class Cell
|
||||||
|
@ -43,14 +44,13 @@ 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;
|
||||||
std::auto_ptr<CellArrow> mCellArrows[4];
|
std::auto_ptr<CellArrow> mCellArrows[4];
|
||||||
std::auto_ptr<CellMarker> mCellMarker;
|
std::auto_ptr<CellMarker> mCellMarker;
|
||||||
std::auto_ptr<CellBorder> mCellBorder;
|
std::auto_ptr<CellBorder> mCellBorder;
|
||||||
|
std::auto_ptr<Pathgrid> mPathgrid;
|
||||||
bool mDeleted;
|
bool mDeleted;
|
||||||
int mSubMode;
|
int mSubMode;
|
||||||
unsigned int mSubModeElementMask;
|
unsigned int mSubModeElementMask;
|
||||||
|
@ -69,8 +69,6 @@ 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
|
||||||
|
|
287
apps/opencs/view/render/pathgrid.cpp
Normal file
287
apps/opencs/view/render/pathgrid.cpp
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
#include "pathgrid.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <osg/Geode>
|
||||||
|
#include <osg/Geometry>
|
||||||
|
#include <osg/Group>
|
||||||
|
#include <osg/PositionAttitudeTransform>
|
||||||
|
#include <osg/Vec3>
|
||||||
|
|
||||||
|
#include <components/sceneutil/pathgridutil.hpp>
|
||||||
|
|
||||||
|
#include "../../model/world/commands.hpp"
|
||||||
|
#include "../../model/world/commandmacro.hpp"
|
||||||
|
#include "../../model/world/data.hpp"
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
PathgridTag::PathgridTag(Pathgrid* pathgrid)
|
||||||
|
: TagBase(Mask_Pathgrid), mPathgrid(pathgrid)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Pathgrid* PathgridTag::getPathgrid() const
|
||||||
|
{
|
||||||
|
return mPathgrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PathgridTag::getToolTip(bool hideBasics) const
|
||||||
|
{
|
||||||
|
QString text("Pathgrid: ");
|
||||||
|
text += mPathgrid->getId().c_str();
|
||||||
|
|
||||||
|
if (!hideBasics)
|
||||||
|
{
|
||||||
|
text += "<p>Only one pathgrid may be edited at a time.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pathgrid::Pathgrid(CSMWorld::Data& data, osg::Group* parent, const std::string& pathgridId,
|
||||||
|
const CSMWorld::CellCoordinates& coordinates)
|
||||||
|
: mData(data)
|
||||||
|
, mId(pathgridId)
|
||||||
|
, mCoords(coordinates)
|
||||||
|
, mParent(parent)
|
||||||
|
, mPathgridGeometry(0)
|
||||||
|
, mSelectedGeometry(0)
|
||||||
|
, mTag(new PathgridTag(this))
|
||||||
|
{
|
||||||
|
const float CoordScalar = ESM::Land::REAL_SIZE;
|
||||||
|
|
||||||
|
mBaseNode = new osg::PositionAttitudeTransform ();
|
||||||
|
mBaseNode->setPosition(osg::Vec3f(mCoords.getX() * CoordScalar, mCoords.getY() * CoordScalar, 0.f));
|
||||||
|
mBaseNode->setUserData(mTag);
|
||||||
|
mBaseNode->setNodeMask(Mask_Pathgrid);
|
||||||
|
mParent->addChild(mBaseNode);
|
||||||
|
|
||||||
|
mSelectedNode = new osg::PositionAttitudeTransform();
|
||||||
|
mBaseNode->addChild(mSelectedNode);
|
||||||
|
|
||||||
|
mPathgridGeode = new osg::Geode();
|
||||||
|
mBaseNode->addChild(mPathgridGeode);
|
||||||
|
|
||||||
|
mSelectedGeode = new osg::Geode();
|
||||||
|
mSelectedNode->addChild(mSelectedGeode);
|
||||||
|
|
||||||
|
recreateGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
Pathgrid::~Pathgrid()
|
||||||
|
{
|
||||||
|
mParent->removeChild(mBaseNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
const CSMWorld::CellCoordinates& Pathgrid::getCoordinates() const
|
||||||
|
{
|
||||||
|
return mCoords;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& Pathgrid::getId() const
|
||||||
|
{
|
||||||
|
return mId;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Pathgrid::isSelected() const
|
||||||
|
{
|
||||||
|
return !mSelected.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Pathgrid::NodeList& Pathgrid::getSelected() const
|
||||||
|
{
|
||||||
|
return mSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::selectAll()
|
||||||
|
{
|
||||||
|
mSelected.clear();
|
||||||
|
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mData.getPathgrids();
|
||||||
|
int pathgridIndex = pathgrids.searchId(mId);
|
||||||
|
if (pathgridIndex != -1)
|
||||||
|
{
|
||||||
|
const CSMWorld::Pathgrid& source = pathgrids.getRecord(pathgridIndex).get();
|
||||||
|
for (unsigned short i = 0; i < static_cast<unsigned short>(source.mPoints.size()); ++i)
|
||||||
|
mSelected.push_back(i);
|
||||||
|
|
||||||
|
recreateSelectedGeometry(source);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
removeSelectedGeometry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::toggleSelected(unsigned short node)
|
||||||
|
{
|
||||||
|
NodeList::iterator searchResult = std::find(mSelected.begin(), mSelected.end(), node);
|
||||||
|
if (searchResult != mSelected.end())
|
||||||
|
{
|
||||||
|
mSelected.erase(searchResult);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mSelected.push_back(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
recreateSelectedGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::invertSelected()
|
||||||
|
{
|
||||||
|
NodeList temp = NodeList(mSelected.begin(), mSelected.end());
|
||||||
|
mSelected.clear();
|
||||||
|
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mData.getPathgrids();
|
||||||
|
int pathgridIndex = pathgrids.searchId(mId);
|
||||||
|
if (pathgridIndex != -1)
|
||||||
|
{
|
||||||
|
const CSMWorld::Pathgrid& source = pathgrids.getRecord(pathgridIndex).get();
|
||||||
|
for (unsigned short i = 0; i < static_cast<unsigned short>(source.mPoints.size()); ++i)
|
||||||
|
{
|
||||||
|
if (std::find(temp.begin(), temp.end(), i) == temp.end())
|
||||||
|
mSelected.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
recreateSelectedGeometry(source);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
removeSelectedGeometry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::clearSelected()
|
||||||
|
{
|
||||||
|
mSelected.clear();
|
||||||
|
removeSelectedGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::moveSelected(const osg::Vec3d& offset)
|
||||||
|
{
|
||||||
|
mSelectedNode->setPosition(mSelectedNode->getPosition() + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::resetMove()
|
||||||
|
{
|
||||||
|
mSelectedNode->setPosition(osg::Vec3f(0,0,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::applyPosition(CSMWorld::CommandMacro& commands)
|
||||||
|
{
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mData.getPathgrids();
|
||||||
|
int pathgridIndex = pathgrids.searchId(mId);
|
||||||
|
if (pathgridIndex != -1)
|
||||||
|
{
|
||||||
|
const CSMWorld::Pathgrid& source = pathgrids.getRecord(pathgridIndex).get();
|
||||||
|
osg::Vec3d localCoords = mSelectedNode->getPosition();
|
||||||
|
|
||||||
|
int oX = static_cast<int>(localCoords.x());
|
||||||
|
int oY = static_cast<int>(localCoords.y());
|
||||||
|
int oZ = static_cast<int>(localCoords.z());
|
||||||
|
|
||||||
|
CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& collection = mData.getPathgrids();
|
||||||
|
QAbstractItemModel* model = mData.getTableModel (CSMWorld::UniversalId::Type_Pathgrids);
|
||||||
|
|
||||||
|
int recordIndex = collection.getIndex (mId);
|
||||||
|
int parentColumn = collection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints);
|
||||||
|
|
||||||
|
QModelIndex parent = model->index(recordIndex, parentColumn);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < mSelected.size(); ++i)
|
||||||
|
{
|
||||||
|
const CSMWorld::Pathgrid::Point& point = source.mPoints[mSelected[i]];
|
||||||
|
int row = mSelected[i];
|
||||||
|
|
||||||
|
// X
|
||||||
|
int column = collection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridPosX);
|
||||||
|
commands.push (new CSMWorld::ModifyCommand(*model, model->index(row, column, parent), point.mX + oX));
|
||||||
|
|
||||||
|
// Y
|
||||||
|
column = collection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridPosY);
|
||||||
|
commands.push (new CSMWorld::ModifyCommand(*model, model->index(row, column, parent), point.mY + oY));
|
||||||
|
|
||||||
|
// Z
|
||||||
|
column = collection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridPosZ);
|
||||||
|
commands.push (new CSMWorld::ModifyCommand(*model, model->index(row, column, parent), point.mZ + oZ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resetMove();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::applyEdge(CSMWorld::CommandMacro& commands, unsigned short node1, unsigned short node2)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::applyEdges(CSMWorld::CommandMacro& commands, unsigned short node)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<PathgridTag> Pathgrid::getTag() const
|
||||||
|
{
|
||||||
|
return mTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::recreateGeometry()
|
||||||
|
{
|
||||||
|
removePathgridGeometry();
|
||||||
|
removeSelectedGeometry();
|
||||||
|
|
||||||
|
// Make new
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mData.getPathgrids();
|
||||||
|
int pathgridIndex = pathgrids.searchId(mId);
|
||||||
|
if (pathgridIndex != -1)
|
||||||
|
{
|
||||||
|
const CSMWorld::Pathgrid& source = pathgrids.getRecord(pathgridIndex).get();
|
||||||
|
mPathgridGeometry = SceneUtil::createPathgridGeometry(source);
|
||||||
|
mPathgridGeode->addDrawable(mPathgridGeometry);
|
||||||
|
|
||||||
|
recreateSelectedGeometry(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::recreateSelectedGeometry()
|
||||||
|
{
|
||||||
|
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mData.getPathgrids();
|
||||||
|
int pathgridIndex = pathgrids.searchId(mId);
|
||||||
|
if (pathgridIndex != -1)
|
||||||
|
{
|
||||||
|
const CSMWorld::Pathgrid& source = pathgrids.getRecord(pathgridIndex).get();
|
||||||
|
recreateSelectedGeometry(source);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
removeSelectedGeometry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::recreateSelectedGeometry(const CSMWorld::Pathgrid& source)
|
||||||
|
{
|
||||||
|
removeSelectedGeometry();
|
||||||
|
mSelectedGeometry = SceneUtil::createPathgridSelectedWireframe(source, mSelected);
|
||||||
|
mSelectedGeode->addDrawable(mSelectedGeometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::removePathgridGeometry()
|
||||||
|
{
|
||||||
|
if (mPathgridGeometry)
|
||||||
|
{
|
||||||
|
mPathgridGeode->removeDrawable(mPathgridGeometry);
|
||||||
|
mPathgridGeometry.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pathgrid::removeSelectedGeometry()
|
||||||
|
{
|
||||||
|
if (mSelectedGeometry)
|
||||||
|
{
|
||||||
|
mSelectedGeode->removeDrawable(mSelectedGeometry);
|
||||||
|
mSelectedGeometry.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
105
apps/opencs/view/render/pathgrid.hpp
Normal file
105
apps/opencs/view/render/pathgrid.hpp
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
#ifndef CSV_RENDER_PATHGRID_H
|
||||||
|
#define CSV_RENDER_PATHGRID_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
|
#include "../../model/world/cellcoordinates.hpp"
|
||||||
|
|
||||||
|
#include "tagbase.hpp"
|
||||||
|
|
||||||
|
namespace osg
|
||||||
|
{
|
||||||
|
class Geode;
|
||||||
|
class Geometry;
|
||||||
|
class Group;
|
||||||
|
class PositionAttitudeTransform;
|
||||||
|
class Vec3d;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class CommandMacro;
|
||||||
|
class Data;
|
||||||
|
class Pathgrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class Pathgrid;
|
||||||
|
|
||||||
|
class PathgridTag : public TagBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
PathgridTag (Pathgrid* pathgrid);
|
||||||
|
|
||||||
|
Pathgrid* getPathgrid () const;
|
||||||
|
|
||||||
|
virtual QString getToolTip (bool hideBasics) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Pathgrid* mPathgrid;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Pathgrid
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef std::vector<unsigned short> NodeList;
|
||||||
|
|
||||||
|
Pathgrid(CSMWorld::Data& data, osg::Group* parent, const std::string& pathgridId,
|
||||||
|
const CSMWorld::CellCoordinates& coordinates);
|
||||||
|
|
||||||
|
~Pathgrid();
|
||||||
|
|
||||||
|
const CSMWorld::CellCoordinates& getCoordinates() const;
|
||||||
|
const std::string& getId() const;
|
||||||
|
|
||||||
|
bool isSelected() const;
|
||||||
|
const NodeList& getSelected() const;
|
||||||
|
void selectAll();
|
||||||
|
void toggleSelected(unsigned short node); // Adds to end of vector
|
||||||
|
void invertSelected();
|
||||||
|
void clearSelected();
|
||||||
|
|
||||||
|
void moveSelected(const osg::Vec3d& offset);
|
||||||
|
void resetMove();
|
||||||
|
|
||||||
|
void applyPosition(CSMWorld::CommandMacro& commands);
|
||||||
|
void applyEdge(CSMWorld::CommandMacro& commands, unsigned short node1, unsigned short node2);
|
||||||
|
void applyEdges(CSMWorld::CommandMacro& commands, unsigned short node);
|
||||||
|
|
||||||
|
osg::ref_ptr<PathgridTag> getTag() const;
|
||||||
|
|
||||||
|
void recreateGeometry();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
CSMWorld::Data& mData;
|
||||||
|
std::string mId;
|
||||||
|
CSMWorld::CellCoordinates mCoords;
|
||||||
|
|
||||||
|
NodeList mSelected;
|
||||||
|
|
||||||
|
osg::Group* mParent;
|
||||||
|
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
||||||
|
osg::ref_ptr<osg::PositionAttitudeTransform> mSelectedNode;
|
||||||
|
osg::ref_ptr<osg::Geode> mPathgridGeode;
|
||||||
|
osg::ref_ptr<osg::Geode> mSelectedGeode;
|
||||||
|
osg::ref_ptr<osg::Geometry> mPathgridGeometry;
|
||||||
|
osg::ref_ptr<osg::Geometry> mSelectedGeometry;
|
||||||
|
|
||||||
|
osg::ref_ptr<PathgridTag> mTag;
|
||||||
|
|
||||||
|
void recreateSelectedGeometry();
|
||||||
|
void recreateSelectedGeometry(const CSMWorld::Pathgrid& source);
|
||||||
|
void removePathgridGeometry();
|
||||||
|
void removeSelectedGeometry();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
152
apps/opencs/view/render/pathgridmode.cpp
Normal file
152
apps/opencs/view/render/pathgridmode.cpp
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
#include "pathgridmode.hpp"
|
||||||
|
|
||||||
|
#include <components/sceneutil/pathgridutil.hpp>
|
||||||
|
|
||||||
|
#include "../../model/world/commands.hpp"
|
||||||
|
#include "../../model/world/commandmacro.hpp"
|
||||||
|
#include "../../model/world/idtable.hpp"
|
||||||
|
#include "../../model/world/idtree.hpp"
|
||||||
|
|
||||||
|
#include "mask.hpp"
|
||||||
|
#include "pathgrid.hpp"
|
||||||
|
#include "worldspacewidget.hpp"
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
PathgridMode::PathgridMode(WorldspaceWidget* worldspaceWidget, QWidget* parent)
|
||||||
|
: EditMode(worldspaceWidget, QIcon(":placeholder"), Mask_Pathgrid, "Pathgrid editing", parent)
|
||||||
|
, mDragMode(DragMode_None)
|
||||||
|
, mFromNode(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathgridMode::primaryEditPressed(const WorldspaceHitResult& hit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathgridMode::secondaryEditPressed(const WorldspaceHitResult& hit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathgridMode::primarySelectPressed(const WorldspaceHitResult& hit)
|
||||||
|
{
|
||||||
|
getWorldspaceWidget().clearSelection(Mask_Pathgrid);
|
||||||
|
|
||||||
|
if (hit.tag)
|
||||||
|
{
|
||||||
|
if (PathgridTag* tag = dynamic_cast<PathgridTag*>(hit.tag.get()))
|
||||||
|
{
|
||||||
|
unsigned short node = SceneUtil::getPathgridNode(static_cast<unsigned short>(hit.i0));
|
||||||
|
tag->getPathgrid()->toggleSelected(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathgridMode::secondarySelectPressed(const WorldspaceHitResult& hit)
|
||||||
|
{
|
||||||
|
if (hit.tag)
|
||||||
|
{
|
||||||
|
if (PathgridTag* tag = dynamic_cast<PathgridTag*>(hit.tag.get()))
|
||||||
|
{
|
||||||
|
if (tag->getPathgrid()->getId() != mLastId)
|
||||||
|
{
|
||||||
|
getWorldspaceWidget().clearSelection(Mask_Pathgrid);
|
||||||
|
mLastId = tag->getPathgrid()->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short node = SceneUtil::getPathgridNode(static_cast<unsigned short>(hit.i0));
|
||||||
|
tag->getPathgrid()->toggleSelected(node);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getWorldspaceWidget().clearSelection(Mask_Pathgrid);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PathgridMode::primaryEditStartDrag(const WorldspaceHitResult& hit)
|
||||||
|
{
|
||||||
|
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
|
||||||
|
|
||||||
|
if (!selection.empty())
|
||||||
|
{
|
||||||
|
mDragMode = DragMode_Move;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PathgridMode::secondaryEditStartDrag(const WorldspaceHitResult& hit)
|
||||||
|
{
|
||||||
|
if (hit.tag)
|
||||||
|
{
|
||||||
|
if (PathgridTag* tag = dynamic_cast<PathgridTag*>(hit.tag.get()))
|
||||||
|
{
|
||||||
|
mDragMode = DragMode_Edge;
|
||||||
|
mFromNode = SceneUtil::getPathgridNode(static_cast<unsigned short>(hit.i0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathgridMode::drag(int diffX, int diffY, double speedFactor)
|
||||||
|
{
|
||||||
|
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
|
||||||
|
|
||||||
|
for (std::vector<osg::ref_ptr<TagBase> >::iterator it = selection.begin(); it != selection.end(); ++it)
|
||||||
|
{
|
||||||
|
if (PathgridTag* tag = dynamic_cast<PathgridTag*>(it->get()))
|
||||||
|
{
|
||||||
|
if (mDragMode == DragMode_Move)
|
||||||
|
{
|
||||||
|
osg::Vec3d eye, center, up, offset;
|
||||||
|
getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt (eye, center, up);
|
||||||
|
|
||||||
|
offset = (up * diffY * speedFactor) + (((center - eye) ^ up) * diffX * speedFactor);
|
||||||
|
|
||||||
|
tag->getPathgrid()->moveSelected(offset);
|
||||||
|
}
|
||||||
|
else if (mDragMode == DragMode_Edge)
|
||||||
|
{
|
||||||
|
// TODO make indicators
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathgridMode::dragCompleted()
|
||||||
|
{
|
||||||
|
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
|
||||||
|
|
||||||
|
for (std::vector<osg::ref_ptr<TagBase> >::iterator it = selection.begin(); it != selection.end(); ++it)
|
||||||
|
{
|
||||||
|
if (PathgridTag* tag = dynamic_cast<PathgridTag*>(it->get()))
|
||||||
|
{
|
||||||
|
if (mDragMode == DragMode_Move)
|
||||||
|
{
|
||||||
|
QUndoStack& undoStack = getWorldspaceWidget().getDocument().getUndoStack();
|
||||||
|
QString description = "Move pathgrid node(s)";
|
||||||
|
|
||||||
|
CSMWorld::CommandMacro macro(undoStack, description);
|
||||||
|
tag->getPathgrid()->applyPosition(macro);
|
||||||
|
}
|
||||||
|
else if (mDragMode == DragMode_Edge)
|
||||||
|
{
|
||||||
|
// TODO raycast for other node and apply if needed with mFromNode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mDragMode = DragMode_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathgridMode::dragAborted()
|
||||||
|
{
|
||||||
|
getWorldspaceWidget().reset(Mask_Pathgrid);
|
||||||
|
}
|
||||||
|
}
|
53
apps/opencs/view/render/pathgridmode.hpp
Normal file
53
apps/opencs/view/render/pathgridmode.hpp
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef CSV_RENDER_PATHGRIDMODE_H
|
||||||
|
#define CSV_RENDER_PATHGRIDMODE_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "editmode.hpp"
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class PathgridMode : public EditMode
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PathgridMode(WorldspaceWidget* worldspace, QWidget* parent=0);
|
||||||
|
|
||||||
|
virtual void primaryEditPressed(const WorldspaceHitResult& hit);
|
||||||
|
|
||||||
|
virtual void secondaryEditPressed(const WorldspaceHitResult& hit);
|
||||||
|
|
||||||
|
virtual void primarySelectPressed(const WorldspaceHitResult& hit);
|
||||||
|
|
||||||
|
virtual void secondarySelectPressed(const WorldspaceHitResult& hit);
|
||||||
|
|
||||||
|
virtual bool primaryEditStartDrag (const WorldspaceHitResult& hit);
|
||||||
|
|
||||||
|
virtual bool secondaryEditStartDrag (const WorldspaceHitResult& hit);
|
||||||
|
|
||||||
|
virtual void drag (int diffX, int diffY, double speedFactor);
|
||||||
|
|
||||||
|
virtual void dragCompleted();
|
||||||
|
|
||||||
|
/// \note dragAborted will not be called, if the drag is aborted via changing
|
||||||
|
/// editing mode
|
||||||
|
virtual void dragAborted();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum DragMode
|
||||||
|
{
|
||||||
|
DragMode_None,
|
||||||
|
DragMode_Move,
|
||||||
|
DragMode_Edge
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string mLastId;
|
||||||
|
DragMode mDragMode;
|
||||||
|
unsigned short mFromNode;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -27,8 +27,8 @@
|
||||||
|
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
#include "mask.hpp"
|
#include "mask.hpp"
|
||||||
#include "editmode.hpp"
|
|
||||||
#include "instancemode.hpp"
|
#include "instancemode.hpp"
|
||||||
|
#include "pathgridmode.hpp"
|
||||||
#include "cameracontroller.hpp"
|
#include "cameracontroller.hpp"
|
||||||
|
|
||||||
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
|
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
|
||||||
|
@ -295,7 +295,7 @@ unsigned int CSVRender::WorldspaceWidget::getVisibilityMask() const
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::setInteractionMask (unsigned int mask)
|
void CSVRender::WorldspaceWidget::setInteractionMask (unsigned int mask)
|
||||||
{
|
{
|
||||||
mInteractionMask = mask | Mask_CellMarker | Mask_CellArrow;
|
mInteractionMask = mask | Mask_CellMarker | Mask_CellArrow | Mask_Pathgrid | Mask_Terrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const
|
unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const
|
||||||
|
@ -320,9 +320,7 @@ void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneTo
|
||||||
{
|
{
|
||||||
/// \todo replace EditMode with suitable subclasses
|
/// \todo replace EditMode with suitable subclasses
|
||||||
tool->addButton (new InstanceMode (this, tool), "object");
|
tool->addButton (new InstanceMode (this, tool), "object");
|
||||||
tool->addButton (
|
tool->addButton (new PathgridMode (this, tool), "pathgrid");
|
||||||
new EditMode (this, QIcon (":placeholder"), Mask_Pathgrid, "Pathgrid editing"),
|
|
||||||
"pathgrid");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMDoc::Document& CSVRender::WorldspaceWidget::getDocument()
|
CSMDoc::Document& CSVRender::WorldspaceWidget::getDocument()
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace SceneUtil
|
||||||
{
|
{
|
||||||
const unsigned short DiamondVertexCount = 6;
|
const unsigned short DiamondVertexCount = 6;
|
||||||
const unsigned short DiamondIndexCount = 24;
|
const unsigned short DiamondIndexCount = 24;
|
||||||
|
const unsigned short DiamondWireframeIndexCount = 24;
|
||||||
|
|
||||||
const unsigned short DiamondConnectorVertexCount = 4;
|
const unsigned short DiamondConnectorVertexCount = 4;
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ namespace SceneUtil
|
||||||
|
|
||||||
const float DiamondHalfHeight = 40.f;
|
const float DiamondHalfHeight = 40.f;
|
||||||
const float DiamondHalfWidth = 16.f;
|
const float DiamondHalfWidth = 16.f;
|
||||||
|
const float DiamondWireframeScalar = 1.1f;
|
||||||
|
|
||||||
const osg::Vec3f DiamondPoints[DiamondVertexCount] =
|
const osg::Vec3f DiamondPoints[DiamondVertexCount] =
|
||||||
{
|
{
|
||||||
|
@ -39,6 +41,22 @@ namespace SceneUtil
|
||||||
5, 2, 4
|
5, 2, 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const unsigned short DiamondWireframeIndices[DiamondWireframeIndexCount] =
|
||||||
|
{
|
||||||
|
0, 1,
|
||||||
|
0, 2,
|
||||||
|
0, 3,
|
||||||
|
0, 4,
|
||||||
|
1, 2,
|
||||||
|
2, 4,
|
||||||
|
4, 3,
|
||||||
|
3, 1,
|
||||||
|
5, 1,
|
||||||
|
5, 2,
|
||||||
|
5, 3,
|
||||||
|
5, 4
|
||||||
|
};
|
||||||
|
|
||||||
const unsigned short DiamondConnectorVertices[DiamondConnectorVertexCount] =
|
const unsigned short DiamondConnectorVertices[DiamondConnectorVertexCount] =
|
||||||
{
|
{
|
||||||
1, 2, 3, 4
|
1, 2, 3, 4
|
||||||
|
@ -55,6 +73,8 @@ namespace SceneUtil
|
||||||
};
|
};
|
||||||
|
|
||||||
const osg::Vec4f DiamondEdgeColor = osg::Vec4f(0.5f, 1.f, 1.f, 1.f);
|
const osg::Vec4f DiamondEdgeColor = osg::Vec4f(0.5f, 1.f, 1.f, 1.f);
|
||||||
|
const osg::Vec4f DiamondWireColor = osg::Vec4f(0.8f, 1.f, 0.9f, 1.f);
|
||||||
|
const osg::Vec4f DiamondFocusWireColor = osg::Vec4f(0.4f, 1.f, 0.4f, 1.f);
|
||||||
|
|
||||||
osg::ref_ptr<osg::Geometry> createPathgridGeometry(const ESM::Pathgrid& pathgrid)
|
osg::ref_ptr<osg::Geometry> createPathgridGeometry(const ESM::Pathgrid& pathgrid)
|
||||||
{
|
{
|
||||||
|
@ -155,4 +175,61 @@ namespace SceneUtil
|
||||||
|
|
||||||
return gridGeometry;
|
return gridGeometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geometry> createPathgridSelectedWireframe(const ESM::Pathgrid& pathgrid,
|
||||||
|
const std::vector<unsigned short>& selected)
|
||||||
|
{
|
||||||
|
const unsigned short PointCount = selected.size();
|
||||||
|
|
||||||
|
const unsigned short VertexCount = PointCount * DiamondVertexCount;
|
||||||
|
const unsigned short ColorCount = VertexCount;
|
||||||
|
const size_t IndexCount = PointCount * DiamondWireframeIndexCount;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geometry> wireframeGeometry = 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> indices =
|
||||||
|
new osg::DrawElementsUShort(osg::PrimitiveSet::LINES, IndexCount);
|
||||||
|
|
||||||
|
osg::Vec3f wireOffset = osg::Vec3f(0, 0, (1 - DiamondWireframeScalar) * DiamondHalfHeight);
|
||||||
|
|
||||||
|
// Add each point/node
|
||||||
|
for (unsigned short it = 0; it < PointCount; ++it)
|
||||||
|
{
|
||||||
|
const ESM::Pathgrid::Point& point = pathgrid.mPoints[selected[it]];
|
||||||
|
osg::Vec3f position = osg::Vec3f(point.mX, point.mY, point.mZ) + wireOffset;
|
||||||
|
|
||||||
|
unsigned short vertexOffset = it * DiamondVertexCount;
|
||||||
|
unsigned short indexOffset = it * DiamondWireframeIndexCount;
|
||||||
|
|
||||||
|
// Point
|
||||||
|
for (unsigned short i = 0; i < DiamondVertexCount; ++i)
|
||||||
|
{
|
||||||
|
(*vertices)[vertexOffset + i] = position + DiamondPoints[i] * DiamondWireframeScalar;
|
||||||
|
|
||||||
|
if (it == PointCount - 1)
|
||||||
|
(*colors)[vertexOffset + i] = DiamondFocusWireColor;
|
||||||
|
else
|
||||||
|
(*colors)[vertexOffset + i] = DiamondWireColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned short i = 0; i < DiamondWireframeIndexCount; ++i)
|
||||||
|
{
|
||||||
|
indices->setElement(indexOffset + i, vertexOffset + DiamondWireframeIndices[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wireframeGeometry->setVertexArray(vertices);
|
||||||
|
wireframeGeometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
|
||||||
|
wireframeGeometry->addPrimitiveSet(indices);
|
||||||
|
wireframeGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
|
return wireframeGeometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short getPathgridNode(unsigned short vertexIndex)
|
||||||
|
{
|
||||||
|
return vertexIndex / (DiamondVertexCount + DiamondConnectorVertexCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,11 @@ namespace ESM
|
||||||
namespace SceneUtil
|
namespace SceneUtil
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::Geometry> createPathgridGeometry(const ESM::Pathgrid& pathgrid);
|
osg::ref_ptr<osg::Geometry> createPathgridGeometry(const ESM::Pathgrid& pathgrid);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geometry> createPathgridSelectedWireframe(const ESM::Pathgrid& pathgrid,
|
||||||
|
const std::vector<unsigned short>& selected);
|
||||||
|
|
||||||
|
unsigned short getPathgridNode(unsigned short vertexIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue