mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-15 18:39:51 +00:00
Merge branch 'marker'
This commit is contained in:
commit
6c65081643
@ -90,7 +90,7 @@ opencs_units (view/render
|
|||||||
|
|
||||||
opencs_units_noqt (view/render
|
opencs_units_noqt (view/render
|
||||||
lighting lightingday lightingnight
|
lighting lightingday lightingnight
|
||||||
lightingbright object cell terrainstorage tagbase
|
lightingbright object cell terrainstorage tagbase cellarrow
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (view/render
|
opencs_hdrs_noqt (view/render
|
||||||
|
@ -32,6 +32,23 @@ std::string CSMWorld::CellCoordinates::getId (const std::string& worldspace) con
|
|||||||
return stream.str();
|
return stream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<CSMWorld::CellCoordinates, bool> CSMWorld::CellCoordinates::fromId (
|
||||||
|
const std::string& id)
|
||||||
|
{
|
||||||
|
// no worldspace for now, needs to be changed for 1.1
|
||||||
|
if (!id.empty() && id[0]=='#')
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
char ignore;
|
||||||
|
|
||||||
|
std::istringstream stream (id);
|
||||||
|
if (stream >> ignore >> x >> y)
|
||||||
|
return std::make_pair (CellCoordinates (x, y), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair (CellCoordinates(), false);
|
||||||
|
}
|
||||||
|
|
||||||
bool CSMWorld::operator== (const CellCoordinates& left, const CellCoordinates& right)
|
bool CSMWorld::operator== (const CellCoordinates& left, const CellCoordinates& right)
|
||||||
{
|
{
|
||||||
return left.getX()==right.getX() && left.getY()==right.getY();
|
return left.getX()==right.getX() && left.getY()==right.getY();
|
||||||
|
@ -28,6 +28,12 @@ namespace CSMWorld
|
|||||||
|
|
||||||
std::string getId (const std::string& worldspace) const;
|
std::string getId (const std::string& worldspace) const;
|
||||||
///< Return the ID for the cell at these coordinates.
|
///< Return the ID for the cell at these coordinates.
|
||||||
|
|
||||||
|
/// \return first: CellCoordinates (or 0, 0 if cell does not have coordinates),
|
||||||
|
/// second: is cell paged?
|
||||||
|
///
|
||||||
|
/// \note The worldspace part of \a id is ignored
|
||||||
|
static std::pair<CellCoordinates, bool> fromId (const std::string& id);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator== (const CellCoordinates& left, const CellCoordinates& right);
|
bool operator== (const CellCoordinates& left, const CellCoordinates& right);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "../../model/world/columns.hpp"
|
#include "../../model/world/columns.hpp"
|
||||||
#include "../../model/world/data.hpp"
|
#include "../../model/world/data.hpp"
|
||||||
#include "../../model/world/refcollection.hpp"
|
#include "../../model/world/refcollection.hpp"
|
||||||
|
#include "../../model/world/cellcoordinates.hpp"
|
||||||
|
|
||||||
#include "elements.hpp"
|
#include "elements.hpp"
|
||||||
#include "terrainstorage.hpp"
|
#include "terrainstorage.hpp"
|
||||||
@ -50,12 +51,20 @@ bool CSVRender::Cell::addObjects (int start, int end)
|
|||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mX(0), mY(0)
|
bool deleted)
|
||||||
|
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mDeleted (deleted)
|
||||||
{
|
{
|
||||||
|
std::pair<CSMWorld::CellCoordinates, bool> result = CSMWorld::CellCoordinates::fromId (id);
|
||||||
|
|
||||||
|
if (result.second)
|
||||||
|
mCoordinates = result.first;
|
||||||
|
|
||||||
mCellNode = new osg::Group;
|
mCellNode = new osg::Group;
|
||||||
rootNode->addChild(mCellNode);
|
rootNode->addChild(mCellNode);
|
||||||
|
|
||||||
|
if (!mDeleted)
|
||||||
|
{
|
||||||
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
@ -74,9 +83,7 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st
|
|||||||
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Element_Terrain<<1));
|
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Element_Terrain<<1));
|
||||||
mTerrain->loadCell(esmLand.mX,
|
mTerrain->loadCell(esmLand.mX,
|
||||||
esmLand.mY);
|
esmLand.mY);
|
||||||
|
}
|
||||||
mX = esmLand.mX;
|
|
||||||
mY = esmLand.mY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,6 +129,9 @@ bool CSVRender::Cell::referenceableAboutToBeRemoved (const QModelIndex& parent,
|
|||||||
bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft,
|
bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft,
|
||||||
const QModelIndex& bottomRight)
|
const QModelIndex& bottomRight)
|
||||||
{
|
{
|
||||||
|
if (mDeleted)
|
||||||
|
return false;
|
||||||
|
|
||||||
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
@ -189,6 +199,9 @@ bool CSVRender::Cell::referenceAboutToBeRemoved (const QModelIndex& parent, int
|
|||||||
if (parent.isValid())
|
if (parent.isValid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (mDeleted)
|
||||||
|
return false;
|
||||||
|
|
||||||
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
@ -209,6 +222,9 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int
|
|||||||
if (parent.isValid())
|
if (parent.isValid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (mDeleted)
|
||||||
|
return false;
|
||||||
|
|
||||||
return addObjects (start, end);
|
return addObjects (start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,3 +248,31 @@ void CSVRender::Cell::setSelection (int elementMask, Selection mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::Cell::setCellArrows (int mask)
|
||||||
|
{
|
||||||
|
for (int i=0; i<4; ++i)
|
||||||
|
{
|
||||||
|
CellArrow::Direction direction = static_cast<CellArrow::Direction> (1<<i);
|
||||||
|
|
||||||
|
bool enable = mask & direction;
|
||||||
|
|
||||||
|
if (enable!=(mCellArrows[i].get()!=0))
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
mCellArrows[i].reset (new CellArrow (mCellNode, direction, mCoordinates));
|
||||||
|
else
|
||||||
|
mCellArrows[i].reset (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::CellCoordinates CSVRender::Cell::getCoordinates() const
|
||||||
|
{
|
||||||
|
return mCoordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Cell::isDeleted() const
|
||||||
|
{
|
||||||
|
return mDeleted;
|
||||||
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
|
#include "cellarrow.hpp"
|
||||||
|
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ namespace osg
|
|||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
class Data;
|
class Data;
|
||||||
|
class CellCoordinates;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
@ -36,8 +38,9 @@ namespace CSVRender
|
|||||||
osg::ref_ptr<osg::Group> mCellNode;
|
osg::ref_ptr<osg::Group> mCellNode;
|
||||||
std::map<std::string, Object *> mObjects;
|
std::map<std::string, Object *> mObjects;
|
||||||
std::auto_ptr<Terrain::TerrainGrid> mTerrain;
|
std::auto_ptr<Terrain::TerrainGrid> mTerrain;
|
||||||
int mX;
|
CSMWorld::CellCoordinates mCoordinates;
|
||||||
int mY;
|
std::auto_ptr<CellArrow> mCellArrows[4];
|
||||||
|
bool mDeleted;
|
||||||
|
|
||||||
/// Ignored if cell does not have an object with the given ID.
|
/// Ignored if cell does not have an object with the given ID.
|
||||||
///
|
///
|
||||||
@ -60,7 +63,10 @@ namespace CSVRender
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id);
|
/// \note Deleted covers both cells that are deleted and cells that don't exist in
|
||||||
|
/// the first place.
|
||||||
|
Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id,
|
||||||
|
bool deleted = false);
|
||||||
|
|
||||||
~Cell();
|
~Cell();
|
||||||
|
|
||||||
@ -86,6 +92,13 @@ namespace CSVRender
|
|||||||
bool referenceAdded (const QModelIndex& parent, int start, int end);
|
bool referenceAdded (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
void setSelection (int elementMask, Selection mode);
|
void setSelection (int elementMask, Selection mode);
|
||||||
|
|
||||||
|
void setCellArrows (int mask);
|
||||||
|
|
||||||
|
/// Returns 0, 0 in case of an unpaged cell.
|
||||||
|
CSMWorld::CellCoordinates getCoordinates() const;
|
||||||
|
|
||||||
|
bool isDeleted() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
161
apps/opencs/view/render/cellarrow.cpp
Normal file
161
apps/opencs/view/render/cellarrow.cpp
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
|
||||||
|
#include "cellarrow.hpp"
|
||||||
|
|
||||||
|
#include <osg/Group>
|
||||||
|
#include <osg/PositionAttitudeTransform>
|
||||||
|
#include <osg/Geode>
|
||||||
|
#include <osg/Geometry>
|
||||||
|
#include <osg/PrimitiveSet>
|
||||||
|
|
||||||
|
#include "elements.hpp"
|
||||||
|
|
||||||
|
CSVRender::CellArrowTag::CellArrowTag (CellArrow *arrow)
|
||||||
|
: TagBase (Element_CellArrow), mArrow (arrow)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSVRender::CellArrow *CSVRender::CellArrowTag::getCellArrow() const
|
||||||
|
{
|
||||||
|
return mArrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSVRender::CellArrow::adjustTransform()
|
||||||
|
{
|
||||||
|
// position
|
||||||
|
const int cellSize = 8192;
|
||||||
|
const int offset = cellSize / 2 + 800;
|
||||||
|
|
||||||
|
int x = mCoordinates.getX()*cellSize + cellSize/2;
|
||||||
|
int y = mCoordinates.getY()*cellSize + cellSize/2;
|
||||||
|
|
||||||
|
float xr = 0;
|
||||||
|
float yr = 0;
|
||||||
|
float zr = 0;
|
||||||
|
|
||||||
|
float angle = osg::DegreesToRadians (90.0f);
|
||||||
|
|
||||||
|
switch (mDirection)
|
||||||
|
{
|
||||||
|
case Direction_North: y += offset; xr = -angle; zr = angle; break;
|
||||||
|
case Direction_West: x -= offset; yr = -angle; break;
|
||||||
|
case Direction_South: y -= offset; xr = angle; zr = angle; break;
|
||||||
|
case Direction_East: x += offset; yr = angle; break;
|
||||||
|
};
|
||||||
|
|
||||||
|
mBaseNode->setPosition (osg::Vec3f (x, y, 0));
|
||||||
|
|
||||||
|
// orientation
|
||||||
|
osg::Quat xr2 (xr, osg::Vec3f (1,0,0));
|
||||||
|
osg::Quat yr2 (yr, osg::Vec3f (0,1,0));
|
||||||
|
osg::Quat zr2 (zr, osg::Vec3f (0,0,1));
|
||||||
|
mBaseNode->setAttitude (zr2*yr2*xr2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::CellArrow::buildShape()
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry);
|
||||||
|
|
||||||
|
const int arrowWidth = 4000;
|
||||||
|
const int arrowLength = 1500;
|
||||||
|
const int arrowHeight = 500;
|
||||||
|
|
||||||
|
osg::Vec3Array *vertices = new osg::Vec3Array;
|
||||||
|
for (int i2=0; i2<2; ++i2)
|
||||||
|
for (int i=0; i<2; ++i)
|
||||||
|
{
|
||||||
|
float height = i ? -arrowHeight/2 : arrowHeight/2;
|
||||||
|
vertices->push_back (osg::Vec3f (height, -arrowWidth/2, 0));
|
||||||
|
vertices->push_back (osg::Vec3f (height, arrowWidth/2, 0));
|
||||||
|
vertices->push_back (osg::Vec3f (height, 0, arrowLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
geometry->setVertexArray (vertices);
|
||||||
|
|
||||||
|
osg::DrawElementsUShort *primitives = new osg::DrawElementsUShort (osg::PrimitiveSet::TRIANGLES, 0);
|
||||||
|
|
||||||
|
// top
|
||||||
|
primitives->push_back (0);
|
||||||
|
primitives->push_back (1);
|
||||||
|
primitives->push_back (2);
|
||||||
|
|
||||||
|
// bottom
|
||||||
|
primitives->push_back (5);
|
||||||
|
primitives->push_back (4);
|
||||||
|
primitives->push_back (3);
|
||||||
|
|
||||||
|
// back
|
||||||
|
primitives->push_back (3+6);
|
||||||
|
primitives->push_back (4+6);
|
||||||
|
primitives->push_back (1+6);
|
||||||
|
|
||||||
|
primitives->push_back (3+6);
|
||||||
|
primitives->push_back (1+6);
|
||||||
|
primitives->push_back (0+6);
|
||||||
|
|
||||||
|
// sides
|
||||||
|
primitives->push_back (0+6);
|
||||||
|
primitives->push_back (2+6);
|
||||||
|
primitives->push_back (5+6);
|
||||||
|
|
||||||
|
primitives->push_back (0+6);
|
||||||
|
primitives->push_back (5+6);
|
||||||
|
primitives->push_back (3+6);
|
||||||
|
|
||||||
|
primitives->push_back (4+6);
|
||||||
|
primitives->push_back (5+6);
|
||||||
|
primitives->push_back (2+6);
|
||||||
|
|
||||||
|
primitives->push_back (4+6);
|
||||||
|
primitives->push_back (2+6);
|
||||||
|
primitives->push_back (1+6);
|
||||||
|
|
||||||
|
geometry->addPrimitiveSet (primitives);
|
||||||
|
|
||||||
|
osg::Vec4Array *colours = new osg::Vec4Array;
|
||||||
|
|
||||||
|
for (int i=0; i<6; ++i)
|
||||||
|
colours->push_back (osg::Vec4f (1.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
for (int i=0; i<6; ++i)
|
||||||
|
colours->push_back (osg::Vec4f (0.8f, (i==2 || i==5) ? 0.6f : 0.4f, 0.0f, 1.0f));
|
||||||
|
|
||||||
|
geometry->setColorArray (colours, osg::Array::BIND_PER_VERTEX);
|
||||||
|
|
||||||
|
geometry->getOrCreateStateSet()->setMode (GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geode> geode (new osg::Geode);
|
||||||
|
geode->addDrawable (geometry);
|
||||||
|
|
||||||
|
mBaseNode->addChild (geode);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::CellArrow::CellArrow (osg::Group *cellNode, Direction direction,
|
||||||
|
const CSMWorld::CellCoordinates& coordinates)
|
||||||
|
: mDirection (direction), mParentNode (cellNode), mCoordinates (coordinates)
|
||||||
|
{
|
||||||
|
mBaseNode = new osg::PositionAttitudeTransform;
|
||||||
|
|
||||||
|
mBaseNode->setUserData (new CellArrowTag (this));
|
||||||
|
|
||||||
|
mParentNode->addChild (mBaseNode);
|
||||||
|
|
||||||
|
// 0x1 reserved for separating cull and update visitors
|
||||||
|
mBaseNode->setNodeMask (Element_CellArrow<<1);
|
||||||
|
|
||||||
|
adjustTransform();
|
||||||
|
buildShape();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::CellArrow::~CellArrow()
|
||||||
|
{
|
||||||
|
mParentNode->removeChild (mBaseNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::CellCoordinates CSVRender::CellArrow::getCoordinates() const
|
||||||
|
{
|
||||||
|
return mCoordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::CellArrow::Direction CSVRender::CellArrow::getDirection() const
|
||||||
|
{
|
||||||
|
return mDirection;
|
||||||
|
}
|
72
apps/opencs/view/render/cellarrow.hpp
Normal file
72
apps/opencs/view/render/cellarrow.hpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#ifndef OPENCS_VIEW_CELLARROW_H
|
||||||
|
#define OPENCS_VIEW_CELLARROW_H
|
||||||
|
|
||||||
|
#include "tagbase.hpp"
|
||||||
|
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
|
#include "../../model/world/cellcoordinates.hpp"
|
||||||
|
|
||||||
|
namespace osg
|
||||||
|
{
|
||||||
|
class PositionAttitudeTransform;
|
||||||
|
class Group;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class CellArrow;
|
||||||
|
|
||||||
|
class CellArrowTag : public TagBase
|
||||||
|
{
|
||||||
|
CellArrow *mArrow;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CellArrowTag (CellArrow *arrow);
|
||||||
|
|
||||||
|
CellArrow *getCellArrow() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CellArrow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum Direction
|
||||||
|
{
|
||||||
|
Direction_North = 1,
|
||||||
|
Direction_West = 2,
|
||||||
|
Direction_South = 4,
|
||||||
|
Direction_East = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// not implemented
|
||||||
|
CellArrow (const CellArrow&);
|
||||||
|
CellArrow& operator= (const CellArrow&);
|
||||||
|
|
||||||
|
Direction mDirection;
|
||||||
|
osg::Group* mParentNode;
|
||||||
|
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
||||||
|
CSMWorld::CellCoordinates mCoordinates;
|
||||||
|
|
||||||
|
void adjustTransform();
|
||||||
|
|
||||||
|
void buildShape();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CellArrow (osg::Group *cellNode, Direction direction,
|
||||||
|
const CSMWorld::CellCoordinates& coordinates);
|
||||||
|
|
||||||
|
~CellArrow();
|
||||||
|
|
||||||
|
CSMWorld::CellCoordinates getCoordinates() const;
|
||||||
|
|
||||||
|
Direction getDirection() const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,8 +1,10 @@
|
|||||||
#include "pagedworldspacewidget.hpp"
|
#include "pagedworldspacewidget.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
#include <osgGA/TrackballManipulator>
|
#include <osgGA/TrackballManipulator>
|
||||||
|
|
||||||
@ -21,20 +23,19 @@
|
|||||||
bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
||||||
{
|
{
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
bool wasEmpty = mCells.empty();
|
||||||
|
|
||||||
const CSMWorld::IdCollection<CSMWorld::Cell>& cells = mDocument.getData().getCells();
|
const CSMWorld::IdCollection<CSMWorld::Cell>& cells = mDocument.getData().getCells();
|
||||||
|
|
||||||
{
|
{
|
||||||
// remove (or name/region modified)
|
// remove/update
|
||||||
std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
|
std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
|
||||||
|
|
||||||
while (iter!=mCells.end())
|
while (iter!=mCells.end())
|
||||||
{
|
{
|
||||||
int index = cells.searchId (iter->first.getId (mWorldspace));
|
if (!mSelection.has (iter->first))
|
||||||
|
|
||||||
if (!mSelection.has (iter->first) || index==-1 ||
|
|
||||||
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted)
|
|
||||||
{
|
{
|
||||||
|
// remove
|
||||||
delete iter->second;
|
delete iter->second;
|
||||||
mCells.erase (iter++);
|
mCells.erase (iter++);
|
||||||
|
|
||||||
@ -42,12 +43,33 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// check if name or region field has changed
|
// update
|
||||||
|
int index = cells.searchId (iter->first.getId (mWorldspace));
|
||||||
|
|
||||||
|
bool deleted = index==-1 ||
|
||||||
|
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted;
|
||||||
|
|
||||||
|
if (deleted!=iter->second->isDeleted())
|
||||||
|
{
|
||||||
|
modified = true;
|
||||||
|
|
||||||
|
std::auto_ptr<Cell> cell (new Cell (mDocument.getData(), mRootNode,
|
||||||
|
iter->first.getId (mWorldspace), deleted));
|
||||||
|
|
||||||
|
delete iter->second;
|
||||||
|
iter->second = cell.release();
|
||||||
|
}
|
||||||
|
else if (!deleted)
|
||||||
|
{
|
||||||
|
// delete state has not changed -> just update
|
||||||
|
|
||||||
|
// TODO check if name or region field has changed (cell marker)
|
||||||
// FIXME: config setting
|
// FIXME: config setting
|
||||||
//std::string name = cells.getRecord(index).get().mName;
|
//std::string name = cells.getRecord(index).get().mName;
|
||||||
//std::string region = cells.getRecord(index).get().mRegion;
|
//std::string region = cells.getRecord(index).get().mRegion;
|
||||||
|
|
||||||
// cell marker update goes here
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
@ -58,20 +80,43 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
|||||||
for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end();
|
for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end();
|
||||||
++iter)
|
++iter)
|
||||||
{
|
{
|
||||||
int index = cells.searchId (iter->getId (mWorldspace));
|
if (mCells.find (*iter)==mCells.end())
|
||||||
|
|
||||||
if (index > 0 && cells.getRecord (index).mState!=CSMWorld::RecordBase::State_Deleted &&
|
|
||||||
mCells.find (*iter)==mCells.end())
|
|
||||||
{
|
{
|
||||||
Cell *cell = new Cell (mDocument.getData(), mRootNode,
|
addCellToScene (*iter);
|
||||||
iter->getId (mWorldspace));
|
|
||||||
mCells.insert (std::make_pair (*iter, cell));
|
|
||||||
|
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modified)
|
if (modified)
|
||||||
|
{
|
||||||
|
for (std::map<CSMWorld::CellCoordinates, Cell *>::const_iterator iter (mCells.begin());
|
||||||
|
iter!=mCells.end(); ++iter)
|
||||||
|
{
|
||||||
|
int mask = 0;
|
||||||
|
|
||||||
|
for (int i=CellArrow::Direction_North; i<=CellArrow::Direction_East; i *= 2)
|
||||||
|
{
|
||||||
|
CSMWorld::CellCoordinates coordinates (iter->second->getCoordinates());
|
||||||
|
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case CellArrow::Direction_North: coordinates = coordinates.move (0, 1); break;
|
||||||
|
case CellArrow::Direction_West: coordinates = coordinates.move (-1, 0); break;
|
||||||
|
case CellArrow::Direction_South: coordinates = coordinates.move (0, -1); break;
|
||||||
|
case CellArrow::Direction_East: coordinates = coordinates.move (1, 0); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mSelection.has (coordinates))
|
||||||
|
mask |= i;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter->second->setCellArrows (mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \todo do not overwrite manipulator object
|
||||||
|
/// \todo move code to useViewHint function
|
||||||
|
if (modified && wasEmpty)
|
||||||
mView->setCameraManipulator(new osgGA::TrackballManipulator);
|
mView->setCameraManipulator(new osgGA::TrackballManipulator);
|
||||||
|
|
||||||
return modified;
|
return modified;
|
||||||
@ -105,6 +150,76 @@ void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
|
|||||||
"terrain-move");
|
"terrain-move");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button)
|
||||||
|
{
|
||||||
|
if (tag && tag->getElement()==Element_CellArrow)
|
||||||
|
{
|
||||||
|
if (button=="p-edit" || button=="s-edit")
|
||||||
|
{
|
||||||
|
if (CellArrowTag *cellArrowTag =
|
||||||
|
dynamic_cast<CSVRender::CellArrowTag *> (tag.get()))
|
||||||
|
{
|
||||||
|
CellArrow *arrow = cellArrowTag->getCellArrow();
|
||||||
|
|
||||||
|
CSMWorld::CellCoordinates coordinates = arrow->getCoordinates();
|
||||||
|
|
||||||
|
CellArrow::Direction direction = arrow->getDirection();
|
||||||
|
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case CellArrow::Direction_North: y = 1; break;
|
||||||
|
case CellArrow::Direction_West: x = -1; break;
|
||||||
|
case CellArrow::Direction_South: y = -1; break;
|
||||||
|
case CellArrow::Direction_East: x = 1; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
if (QApplication::keyboardModifiers() & Qt::ShiftModifier)
|
||||||
|
{
|
||||||
|
if (button=="p-edit")
|
||||||
|
addCellSelection (x, y);
|
||||||
|
else
|
||||||
|
moveCellSelection (x, y);
|
||||||
|
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CSMWorld::CellCoordinates newCoordinates = coordinates.move (x, y);
|
||||||
|
|
||||||
|
if (mCells.find (newCoordinates)==mCells.end())
|
||||||
|
{
|
||||||
|
addCellToScene (newCoordinates);
|
||||||
|
mSelection.add (newCoordinates);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (button=="s-edit")
|
||||||
|
{
|
||||||
|
if (mCells.find (coordinates)!=mCells.end())
|
||||||
|
{
|
||||||
|
removeCellFromScene (coordinates);
|
||||||
|
mSelection.remove (coordinates);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modified)
|
||||||
|
adjustCells();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldspaceWidget::handleMouseClick (tag, button);
|
||||||
|
}
|
||||||
|
|
||||||
void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
|
void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
const QModelIndex& bottomRight)
|
const QModelIndex& bottomRight)
|
||||||
{
|
{
|
||||||
@ -184,6 +299,72 @@ std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction()
|
|||||||
return stream.str();
|
return stream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::addCellToScene (
|
||||||
|
const CSMWorld::CellCoordinates& coordinates)
|
||||||
|
{
|
||||||
|
const CSMWorld::IdCollection<CSMWorld::Cell>& cells = mDocument.getData().getCells();
|
||||||
|
|
||||||
|
int index = cells.searchId (coordinates.getId (mWorldspace));
|
||||||
|
|
||||||
|
bool deleted = index==-1 ||
|
||||||
|
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted;
|
||||||
|
|
||||||
|
Cell *cell = new Cell (mDocument.getData(), mRootNode, coordinates.getId (mWorldspace),
|
||||||
|
deleted);
|
||||||
|
|
||||||
|
mCells.insert (std::make_pair (coordinates, cell));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::removeCellFromScene (
|
||||||
|
const CSMWorld::CellCoordinates& coordinates)
|
||||||
|
{
|
||||||
|
std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter = mCells.find (coordinates);
|
||||||
|
|
||||||
|
if (iter!=mCells.end())
|
||||||
|
{
|
||||||
|
delete iter->second;
|
||||||
|
mCells.erase (iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::addCellSelection (int x, int y)
|
||||||
|
{
|
||||||
|
CSMWorld::CellSelection newSelection = mSelection;
|
||||||
|
newSelection.move (x, y);
|
||||||
|
|
||||||
|
for (CSMWorld::CellSelection::Iterator iter (newSelection.begin()); iter!=newSelection.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
if (mCells.find (*iter)==mCells.end())
|
||||||
|
{
|
||||||
|
addCellToScene (*iter);
|
||||||
|
mSelection.add (*iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::moveCellSelection (int x, int y)
|
||||||
|
{
|
||||||
|
CSMWorld::CellSelection newSelection = mSelection;
|
||||||
|
newSelection.move (x, y);
|
||||||
|
|
||||||
|
for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
if (!newSelection.has (*iter))
|
||||||
|
removeCellFromScene (*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (CSMWorld::CellSelection::Iterator iter (newSelection.begin()); iter!=newSelection.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
if (!mSelection.has (*iter))
|
||||||
|
addCellToScene (*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
mSelection = newSelection;
|
||||||
|
}
|
||||||
|
|
||||||
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document)
|
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document)
|
||||||
: WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default"),
|
: WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default"),
|
||||||
mControlElements(NULL), mDisplayCellCoord(true)
|
mControlElements(NULL), mDisplayCellCoord(true)
|
||||||
|
@ -53,6 +53,20 @@ namespace CSVRender
|
|||||||
|
|
||||||
virtual std::string getStartupInstruction();
|
virtual std::string getStartupInstruction();
|
||||||
|
|
||||||
|
/// \note Does not update the view or any cell marker
|
||||||
|
void addCellToScene (const CSMWorld::CellCoordinates& coordinates);
|
||||||
|
|
||||||
|
/// \note Does not update the view or any cell marker
|
||||||
|
///
|
||||||
|
/// \note Calling this function for a cell that is not in the selection is a no-op.
|
||||||
|
void removeCellFromScene (const CSMWorld::CellCoordinates& coordinates);
|
||||||
|
|
||||||
|
/// \note Does not update the view or any cell marker
|
||||||
|
void addCellSelection (int x, int y);
|
||||||
|
|
||||||
|
/// \note Does not update the view or any cell marker
|
||||||
|
void moveCellSelection (int x, int y);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document);
|
PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document);
|
||||||
@ -88,6 +102,8 @@ namespace CSVRender
|
|||||||
|
|
||||||
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
|
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
|
||||||
|
|
||||||
|
virtual void handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void cellSelectionChanged (const CSMWorld::CellSelection& selection);
|
void cellSelectionChanged (const CSMWorld::CellSelection& selection);
|
||||||
|
@ -574,14 +574,7 @@ void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event)
|
|||||||
{
|
{
|
||||||
osg::ref_ptr<TagBase> tag = mousePick (event);
|
osg::ref_ptr<TagBase> tag = mousePick (event);
|
||||||
|
|
||||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
handleMouseClick (tag, button);
|
||||||
|
|
||||||
if (button=="p-edit")
|
|
||||||
editMode.primaryEditPressed (tag);
|
|
||||||
else if (button=="s-edit")
|
|
||||||
editMode.secondaryEditPressed (tag);
|
|
||||||
else if (button=="select")
|
|
||||||
editMode.selectPressed (tag);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -650,3 +643,15 @@ void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
|
|||||||
else
|
else
|
||||||
RenderWidget::keyPressEvent(event);
|
RenderWidget::keyPressEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button)
|
||||||
|
{
|
||||||
|
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||||
|
|
||||||
|
if (button=="p-edit")
|
||||||
|
editMode.primaryEditPressed (tag);
|
||||||
|
else if (button=="s-edit")
|
||||||
|
editMode.secondaryEditPressed (tag);
|
||||||
|
else if (button=="select")
|
||||||
|
editMode.selectPressed (tag);
|
||||||
|
}
|
||||||
|
@ -27,6 +27,7 @@ namespace CSVWidget
|
|||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
class TagBase;
|
class TagBase;
|
||||||
|
class CellArrow;
|
||||||
|
|
||||||
class WorldspaceWidget : public SceneWidget
|
class WorldspaceWidget : public SceneWidget
|
||||||
{
|
{
|
||||||
@ -132,6 +133,8 @@ namespace CSVRender
|
|||||||
virtual void wheelEvent (QWheelEvent *event);
|
virtual void wheelEvent (QWheelEvent *event);
|
||||||
virtual void keyPressEvent (QKeyEvent *event);
|
virtual void keyPressEvent (QKeyEvent *event);
|
||||||
|
|
||||||
|
virtual void handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void dragEnterEvent(QDragEnterEvent *event);
|
void dragEnterEvent(QDragEnterEvent *event);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user