mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-15 09:39:53 +00:00
render marker
This commit is contained in:
parent
6f619ea85f
commit
a19ac72215
@ -51,7 +51,12 @@ bool CSVRender::Cell::addObjects (int start, int end)
|
||||
{
|
||||
std::string id = Misc::StringUtils::lowerCase (collection.getRecord (i).get().mId);
|
||||
|
||||
mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false)));
|
||||
std::auto_ptr<Object> object (new Object (mData, mCellNode, id, false));
|
||||
|
||||
if (mSubModeElementMask & Mask_Reference)
|
||||
object->setSubMode (mSubMode);
|
||||
|
||||
mObjects.insert (std::make_pair (id, object.release()));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
@ -61,7 +66,8 @@ bool CSVRender::Cell::addObjects (int start, int end)
|
||||
|
||||
CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id,
|
||||
bool deleted)
|
||||
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mDeleted (deleted)
|
||||
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mDeleted (deleted), mSubMode (0),
|
||||
mSubModeElementMask (0)
|
||||
{
|
||||
std::pair<CSMWorld::CellCoordinates, bool> result = CSMWorld::CellCoordinates::fromId (id);
|
||||
|
||||
@ -359,3 +365,14 @@ std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::Cell::getEdited (unsig
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CSVRender::Cell::setSubMode (int subMode, unsigned int elementMask)
|
||||
{
|
||||
mSubMode = subMode;
|
||||
mSubModeElementMask = elementMask;
|
||||
|
||||
if (elementMask & Mask_Reference)
|
||||
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
|
||||
iter!=mObjects.end(); ++iter)
|
||||
iter->second->setSubMode (subMode);
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ namespace CSVRender
|
||||
std::auto_ptr<CellArrow> mCellArrows[4];
|
||||
std::auto_ptr<CellMarker> mCellMarker;
|
||||
bool mDeleted;
|
||||
int mSubMode;
|
||||
unsigned int mSubModeElementMask;
|
||||
|
||||
/// Ignored if cell does not have an object with the given ID.
|
||||
///
|
||||
@ -118,6 +120,8 @@ namespace CSVRender
|
||||
std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask) const;
|
||||
|
||||
std::vector<osg::ref_ptr<TagBase> > getEdited (unsigned int elementMask) const;
|
||||
|
||||
void setSubMode (int subMode, unsigned int elementMask);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -70,3 +70,8 @@ void CSVRender::EditMode::dragEnterEvent (QDragEnterEvent *event) {}
|
||||
void CSVRender::EditMode::dropEvent (QDropEvent* event) {}
|
||||
|
||||
void CSVRender::EditMode::dragMoveEvent (QDragMoveEvent *event) {}
|
||||
|
||||
int CSVRender::EditMode::getSubMode() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -92,6 +92,9 @@ namespace CSVRender
|
||||
|
||||
/// Default-implementation: ignored
|
||||
virtual void dragMoveEvent (QDragMoveEvent *event);
|
||||
|
||||
/// Default: return -1
|
||||
virtual int getSubMode() const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,11 @@
|
||||
#include "instanceselectionmode.hpp"
|
||||
#include "instancemovemode.hpp"
|
||||
|
||||
int CSVRender::InstanceMode::getSubModeFromId (const std::string& id) const
|
||||
{
|
||||
return id=="move" ? 0 : (id=="rotate" ? 1 : 2);
|
||||
}
|
||||
|
||||
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
|
||||
: EditMode (worldspaceWidget, QIcon (":placeholder"), Mask_Reference, "Instance editing",
|
||||
parent), mSubMode (0), mSelectionMode (0), mDragMode (DragMode_None)
|
||||
@ -44,6 +49,9 @@ void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
|
||||
"<li>Use secondary edit to scale instances along the grid</li>"
|
||||
"</ul>"
|
||||
"<font color=Red>Not implemented yet</font color>");
|
||||
|
||||
connect (mSubMode, SIGNAL (modeChanged (const std::string&)),
|
||||
this, SLOT (subModeChanged (const std::string&)));
|
||||
}
|
||||
|
||||
if (!mSelectionMode)
|
||||
@ -55,6 +63,10 @@ void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
|
||||
|
||||
toolbar->addTool (mSubMode);
|
||||
toolbar->addTool (mSelectionMode);
|
||||
|
||||
std::string subMode = mSubMode->getCurrentId();
|
||||
|
||||
getWorldspaceWidget().setSubMode (getSubModeFromId (subMode), Mask_Reference);
|
||||
}
|
||||
|
||||
void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar)
|
||||
@ -402,3 +414,13 @@ void CSVRender::InstanceMode::dropEvent (QDropEvent* event)
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
int CSVRender::InstanceMode::getSubMode() const
|
||||
{
|
||||
return mSubMode ? getSubModeFromId (mSubMode->getCurrentId()) : 0;
|
||||
}
|
||||
|
||||
void CSVRender::InstanceMode::subModeChanged (const std::string& id)
|
||||
{
|
||||
getWorldspaceWidget().setSubMode (getSubModeFromId (id), Mask_Reference);
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ namespace CSVRender
|
||||
InstanceSelectionMode *mSelectionMode;
|
||||
DragMode mDragMode;
|
||||
|
||||
int getSubModeFromId (const std::string& id) const;
|
||||
|
||||
public:
|
||||
|
||||
InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0);
|
||||
@ -56,6 +58,12 @@ namespace CSVRender
|
||||
virtual void dragEnterEvent (QDragEnterEvent *event);
|
||||
|
||||
virtual void dropEvent (QDropEvent* event);
|
||||
|
||||
virtual int getSubMode() const;
|
||||
|
||||
private slots:
|
||||
|
||||
void subModeChanged (const std::string& id);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osg/Shape>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/PrimitiveSet>
|
||||
|
||||
#include <osgFX/Scribe>
|
||||
|
||||
@ -52,6 +54,11 @@ QString CSVRender::ObjectTag::getToolTip (bool hideBasics) const
|
||||
}
|
||||
|
||||
|
||||
CSVRender::ObjectMarkerTag::ObjectMarkerTag (Object* object, int axis)
|
||||
: TagBase (Mask_Reference), mObject (object), mAxis (axis)
|
||||
{}
|
||||
|
||||
|
||||
void CSVRender::Object::clear()
|
||||
{
|
||||
}
|
||||
@ -156,10 +163,144 @@ const CSMWorld::CellRef& CSVRender::Object::getReference() const
|
||||
return mData.getReferences().getRecord (mReferenceId).get();
|
||||
}
|
||||
|
||||
void CSVRender::Object::updateMarker()
|
||||
{
|
||||
for (int i=0; i<3; ++i)
|
||||
{
|
||||
if (mMarker[i])
|
||||
{
|
||||
mRootNode->removeChild (mMarker[i]);
|
||||
mMarker[i] = osg::ref_ptr<osg::Node>();
|
||||
}
|
||||
|
||||
if (mSelected)
|
||||
{
|
||||
if (mSubMode==0)
|
||||
{
|
||||
mMarker[i] = makeMarker (i);
|
||||
mMarker[i]->setUserData(new ObjectMarkerTag (this, i));
|
||||
|
||||
mRootNode->addChild (mMarker[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> CSVRender::Object::makeMarker (int axis)
|
||||
{
|
||||
osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry);
|
||||
|
||||
const float shaftWidth = 10;
|
||||
const float shaftBaseLength = 50;
|
||||
const float headWidth = 30;
|
||||
const float headLength = 30;
|
||||
|
||||
float shaftLength = shaftBaseLength + mBaseNode->getBound().radius();
|
||||
|
||||
// shaft
|
||||
osg::Vec3Array *vertices = new osg::Vec3Array;
|
||||
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
float length = i ? shaftLength : 0;
|
||||
|
||||
vertices->push_back (getMarkerPosition (-shaftWidth/2, -shaftWidth/2, length, axis));
|
||||
vertices->push_back (getMarkerPosition (-shaftWidth/2, shaftWidth/2, length, axis));
|
||||
vertices->push_back (getMarkerPosition (shaftWidth/2, shaftWidth/2, length, axis));
|
||||
vertices->push_back (getMarkerPosition (shaftWidth/2, -shaftWidth/2, length, axis));
|
||||
}
|
||||
|
||||
// head backside
|
||||
vertices->push_back (getMarkerPosition (-headWidth/2, -headWidth/2, shaftLength, axis));
|
||||
vertices->push_back (getMarkerPosition (-headWidth/2, headWidth/2, shaftLength, axis));
|
||||
vertices->push_back (getMarkerPosition (headWidth/2, headWidth/2, shaftLength, axis));
|
||||
vertices->push_back (getMarkerPosition (headWidth/2, -headWidth/2, shaftLength, axis));
|
||||
|
||||
// head
|
||||
vertices->push_back (getMarkerPosition (0, 0, shaftLength+headLength, axis));
|
||||
|
||||
geometry->setVertexArray (vertices);
|
||||
|
||||
osg::DrawElementsUShort *primitives = new osg::DrawElementsUShort (osg::PrimitiveSet::TRIANGLES, 0);
|
||||
|
||||
// shaft
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
int i2 = i==3 ? 0 : i+1;
|
||||
primitives->push_back (i);
|
||||
primitives->push_back (4+i);
|
||||
primitives->push_back (i2);
|
||||
|
||||
primitives->push_back (4+i);
|
||||
primitives->push_back (4+i2);
|
||||
primitives->push_back (i2);
|
||||
}
|
||||
|
||||
// cap
|
||||
primitives->push_back (0);
|
||||
primitives->push_back (1);
|
||||
primitives->push_back (2);
|
||||
|
||||
primitives->push_back (2);
|
||||
primitives->push_back (3);
|
||||
primitives->push_back (0);
|
||||
|
||||
// head, backside
|
||||
primitives->push_back (0+8);
|
||||
primitives->push_back (1+8);
|
||||
primitives->push_back (2+8);
|
||||
|
||||
primitives->push_back (2+8);
|
||||
primitives->push_back (3+8);
|
||||
primitives->push_back (0+8);
|
||||
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
primitives->push_back (12);
|
||||
primitives->push_back (8+(i==3 ? 0 : i+1));
|
||||
primitives->push_back (8+i);
|
||||
}
|
||||
|
||||
geometry->addPrimitiveSet (primitives);
|
||||
|
||||
osg::Vec4Array *colours = new osg::Vec4Array;
|
||||
|
||||
for (int i=0; i<8; ++i)
|
||||
colours->push_back (osg::Vec4f (axis==0 ? 1.0f : 0.2f, axis==1 ? 1.0f : 0.2f,
|
||||
axis==2 ? 1.0f : 0.2f, 1.0f));
|
||||
|
||||
for (int i=8; i<8+4+1; ++i)
|
||||
colours->push_back (osg::Vec4f (axis==0 ? 1.0f : 0.0f, axis==1 ? 1.0f : 0.0f,
|
||||
axis==2 ? 1.0f : 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);
|
||||
|
||||
return geode;
|
||||
}
|
||||
|
||||
osg::Vec3f CSVRender::Object::getMarkerPosition (float x, float y, float z, int axis)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case 0: return osg::Vec3f (x, y, z);
|
||||
case 1: return osg::Vec3f (z, x, y);
|
||||
case 2: return osg::Vec3f (y, z, x);
|
||||
|
||||
default:
|
||||
|
||||
throw std::logic_error ("invalid axis for marker geometry");
|
||||
}
|
||||
}
|
||||
|
||||
CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
|
||||
const std::string& id, bool referenceable, bool forceBaseToZero)
|
||||
: mData (data), mBaseNode(0), mSelected(false), mParentNode(parentNode), mResourceSystem(data.getResourceSystem().get()), mForceBaseToZero (forceBaseToZero),
|
||||
mScaleOverride (1), mOverrideFlags (0)
|
||||
mScaleOverride (1), mOverrideFlags (0), mSubMode (-1)
|
||||
{
|
||||
mRootNode = new osg::PositionAttitudeTransform;
|
||||
|
||||
@ -188,6 +329,7 @@ CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
|
||||
|
||||
adjustTransform();
|
||||
update();
|
||||
updateMarker();
|
||||
}
|
||||
|
||||
CSVRender::Object::~Object()
|
||||
@ -211,6 +353,8 @@ void CSVRender::Object::setSelected(bool selected)
|
||||
}
|
||||
else
|
||||
mRootNode->addChild(mBaseNode);
|
||||
|
||||
updateMarker();
|
||||
}
|
||||
|
||||
bool CSVRender::Object::getSelected() const
|
||||
@ -229,6 +373,7 @@ bool CSVRender::Object::referenceableDataChanged (const QModelIndex& topLeft,
|
||||
{
|
||||
adjustTransform();
|
||||
update();
|
||||
updateMarker();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -279,6 +424,7 @@ bool CSVRender::Object::referenceDataChanged (const QModelIndex& topLeft,
|
||||
references.getData (index, columnIndex).toString().toUtf8().constData();
|
||||
|
||||
update();
|
||||
updateMarker();
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -419,3 +565,12 @@ void CSVRender::Object::apply (QUndoStack& undoStack)
|
||||
|
||||
mOverrideFlags = 0;
|
||||
}
|
||||
|
||||
void CSVRender::Object::setSubMode (int subMode)
|
||||
{
|
||||
if (subMode!=mSubMode)
|
||||
{
|
||||
mSubMode = subMode;
|
||||
updateMarker();
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ namespace osg
|
||||
{
|
||||
class PositionAttitudeTransform;
|
||||
class Group;
|
||||
class Node;
|
||||
class Geode;
|
||||
}
|
||||
|
||||
namespace osgFX
|
||||
@ -53,6 +55,15 @@ namespace CSVRender
|
||||
virtual QString getToolTip (bool hideBasics) const;
|
||||
};
|
||||
|
||||
class ObjectMarkerTag : public TagBase
|
||||
{
|
||||
public:
|
||||
|
||||
ObjectMarkerTag (Object* object, int axis);
|
||||
|
||||
Object* mObject;
|
||||
int mAxis;
|
||||
};
|
||||
|
||||
class Object
|
||||
{
|
||||
@ -80,6 +91,8 @@ namespace CSVRender
|
||||
ESM::Position mPositionOverride;
|
||||
int mScaleOverride;
|
||||
int mOverrideFlags;
|
||||
osg::ref_ptr<osg::Node> mMarker[3];
|
||||
int mSubMode;
|
||||
|
||||
/// Not implemented
|
||||
Object (const Object&);
|
||||
@ -100,6 +113,12 @@ namespace CSVRender
|
||||
/// Throws an exception if *this was constructed with referenceable
|
||||
const CSMWorld::CellRef& getReference() const;
|
||||
|
||||
void updateMarker();
|
||||
|
||||
osg::ref_ptr<osg::Node> makeMarker (int axis);
|
||||
|
||||
osg::Vec3f getMarkerPosition (float x, float y, float z, int axis);
|
||||
|
||||
public:
|
||||
|
||||
Object (CSMWorld::Data& data, osg::Group *cellNode,
|
||||
@ -155,6 +174,8 @@ namespace CSVRender
|
||||
|
||||
/// Apply override changes via command and end edit mode
|
||||
void apply (QUndoStack& undoStack);
|
||||
|
||||
void setSubMode (int subMode);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -309,10 +309,13 @@ void CSVRender::PagedWorldspaceWidget::addCellToScene (
|
||||
bool deleted = index==-1 ||
|
||||
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted;
|
||||
|
||||
Cell *cell = new Cell (mDocument.getData(), mRootNode, coordinates.getId (mWorldspace),
|
||||
deleted);
|
||||
std::auto_ptr<Cell> cell (
|
||||
new Cell (mDocument.getData(), mRootNode, coordinates.getId (mWorldspace),
|
||||
deleted));
|
||||
EditMode *editMode = getEditMode();
|
||||
cell->setSubMode (editMode->getSubMode(), editMode->getInteractionMask());
|
||||
|
||||
mCells.insert (std::make_pair (coordinates, cell));
|
||||
mCells.insert (std::make_pair (coordinates, cell.release()));
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::removeCellFromScene (
|
||||
@ -572,6 +575,13 @@ std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::PagedWorldspaceWidget:
|
||||
return result;
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::setSubMode (int subMode, unsigned int elementMask)
|
||||
{
|
||||
for (std::map<CSMWorld::CellCoordinates, Cell *>::const_iterator iter = mCells.begin();
|
||||
iter!=mCells.end(); ++iter)
|
||||
iter->second->setSubMode (subMode, elementMask);
|
||||
}
|
||||
|
||||
CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector (
|
||||
CSVWidget::SceneToolbar *parent)
|
||||
{
|
||||
|
@ -115,6 +115,8 @@ namespace CSVRender
|
||||
virtual std::vector<osg::ref_ptr<TagBase> > getEdited (unsigned int elementMask)
|
||||
const;
|
||||
|
||||
virtual void setSubMode (int subMode, unsigned int elementMask);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);
|
||||
|
@ -137,6 +137,11 @@ std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::UnpagedWorldspaceWidge
|
||||
return mCell->getEdited (elementMask);
|
||||
}
|
||||
|
||||
void CSVRender::UnpagedWorldspaceWidget::setSubMode (int subMode, unsigned int elementMask)
|
||||
{
|
||||
mCell->setSubMode (subMode, elementMask);
|
||||
}
|
||||
|
||||
void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight)
|
||||
{
|
||||
|
@ -63,6 +63,8 @@ namespace CSVRender
|
||||
virtual std::vector<osg::ref_ptr<TagBase> > getEdited (unsigned int elementMask)
|
||||
const;
|
||||
|
||||
virtual void setSubMode (int subMode, unsigned int elementMask);
|
||||
|
||||
private:
|
||||
|
||||
virtual void referenceableDataChanged (const QModelIndex& topLeft,
|
||||
|
@ -761,3 +761,8 @@ void CSVRender::WorldspaceWidget::handleMouseClick (osg::ref_ptr<TagBase> tag, c
|
||||
else if (button=="s-select")
|
||||
editMode.secondarySelectPressed (tag);
|
||||
}
|
||||
|
||||
CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
|
||||
{
|
||||
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ namespace CSVRender
|
||||
{
|
||||
class TagBase;
|
||||
class CellArrow;
|
||||
class EditMode;
|
||||
|
||||
class WorldspaceWidget : public SceneWidget
|
||||
{
|
||||
@ -155,6 +156,8 @@ namespace CSVRender
|
||||
virtual std::vector<osg::ref_ptr<TagBase> > getEdited (unsigned int elementMask)
|
||||
const = 0;
|
||||
|
||||
virtual void setSubMode (int subMode, unsigned int elementMask) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/// Visual elements in a scene
|
||||
@ -184,6 +187,8 @@ namespace CSVRender
|
||||
virtual void handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button,
|
||||
bool shift);
|
||||
|
||||
EditMode *getEditMode();
|
||||
|
||||
private:
|
||||
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
|
@ -96,6 +96,11 @@ CSVWidget::ModeButton *CSVWidget::SceneToolMode::getCurrent()
|
||||
return mCurrent;
|
||||
}
|
||||
|
||||
std::string CSVWidget::SceneToolMode::getCurrentId() const
|
||||
{
|
||||
return mButtons.find (mCurrent)->second;
|
||||
}
|
||||
|
||||
void CSVWidget::SceneToolMode::selected()
|
||||
{
|
||||
std::map<ModeButton *, std::string>::const_iterator iter =
|
||||
|
@ -56,6 +56,9 @@ namespace CSVWidget
|
||||
/// Will return a 0-pointer only if the mode does not have any buttons yet.
|
||||
ModeButton *getCurrent();
|
||||
|
||||
/// Must not be called if there aren't any buttons yet.
|
||||
std::string getCurrentId() const;
|
||||
|
||||
signals:
|
||||
|
||||
void modeChanged (const std::string& id);
|
||||
|
Loading…
x
Reference in New Issue
Block a user