Drop objects with a keyboard shortcut

pull/578/head
Nelsson Huotari 5 years ago
parent 79517f3f42
commit f063eeb36e

@ -356,6 +356,8 @@ void CSMPrefs::State::declare()
QKeySequence(Qt::ControlModifier | (int)Qt::MiddleButton));
declareModifier ("scene-speed-modifier", "Speed Modifier", Qt::Key_Shift);
declareShortcut ("scene-delete", "Delete Instance", QKeySequence(Qt::Key_Delete));
declareShortcut ("scene-instance-groundlevel", "Instance to Ground Level", QKeySequence(Qt::Key_G));
declareShortcut ("scene-instance-drop", "Drop Instance", QKeySequence(Qt::Key_H));
declareShortcut ("scene-load-cam-cell", "Load Camera Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_5));
declareShortcut ("scene-load-cam-eastcell", "Load East Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_6));
declareShortcut ("scene-load-cam-northcell", "Load North Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_8));

@ -6,6 +6,10 @@
#include "../../model/prefs/state.hpp"
#include <osg/Group>
#include <osg/Vec3d>
#include <osgUtil/LineSegmentIntersector>
#include "../../model/world/idtable.hpp"
#include "../../model/world/idtree.hpp"
#include "../../model/world/commands.hpp"
@ -90,16 +94,20 @@ osg::Vec3f CSVRender::InstanceMode::getScreenCoords(const osg::Vec3f& pos)
return pos * combined;
}
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, osg::ref_ptr<osg::Group> parentNode, QWidget *parent)
: EditMode (worldspaceWidget, QIcon (":scenetoolbar/editing-instance"), SceneUtil::Mask_EditorReference | SceneUtil::Mask_Terrain, "Instance editing",
parent), mSubMode (0), mSubModeId ("move"), mSelectionMode (0), mDragMode (DragMode_None),
mDragAxis (-1), mLocked (false), mUnitScaleDist(1)
mDragAxis (-1), mLocked (false), mUnitScaleDist(1), mParentNode (parentNode)
{
connect(this, SIGNAL(requestFocus(const std::string&)),
worldspaceWidget, SIGNAL(requestFocus(const std::string&)));
CSMPrefs::Shortcut* deleteShortcut = new CSMPrefs::Shortcut("scene-delete", worldspaceWidget);
connect(deleteShortcut, SIGNAL(activated(bool)), this, SLOT(deleteSelectedInstances(bool)));
CSMPrefs::Shortcut* dropShortcut = new CSMPrefs::Shortcut("scene-instance-drop", worldspaceWidget);
connect(dropShortcut, SIGNAL(activated(bool)), this, SLOT(dropSelectedInstances(bool)));
CSMPrefs::Shortcut* groundlevelShortcut = new CSMPrefs::Shortcut("scene-instance-groundlevel", worldspaceWidget);
connect(groundlevelShortcut, SIGNAL(activated(bool)), this, SLOT(groundlevelSelectedInstances(bool)));
}
void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
@ -681,3 +689,75 @@ void CSVRender::InstanceMode::deleteSelectedInstances(bool active)
getWorldspaceWidget().clearSelection (SceneUtil::Mask_EditorReference);
}
void CSVRender::InstanceMode::dropInstance(DropMode dropMode, CSVRender::Object* object)
{
const osg::Vec3d& point = object->getPosition().asVec3();
osg::ref_ptr<osg::Group> objectNode = object->getRootNode();
osg::Node::NodeMask oldMask = objectNode->getNodeMask();
objectNode->setNodeMask(SceneUtil::Mask_Disabled);
osg::Vec3d start = point;
osg::Vec3d end = point;
start.z() += 1.0f;
end.z() = std::numeric_limits<float>::min();
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (new osgUtil::LineSegmentIntersector(
osgUtil::Intersector::MODEL, start, end) );
intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT);
osgUtil::IntersectionVisitor visitor(intersector);
if (dropMode == Ground_level) visitor.setTraversalMask(SceneUtil::Mask_Terrain);
if (dropMode == Coillision_Below) visitor.setTraversalMask(SceneUtil::Mask_Terrain | SceneUtil::Mask_EditorReference);
mParentNode->accept(visitor);
for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin();
it != intersector->getIntersections().end(); ++it)
{
osgUtil::LineSegmentIntersector::Intersection intersection = *it;
ESM::Position position = object->getPosition();
object->setEdited (Object::Override_Position);
position.pos[2] = intersection.getWorldIntersectPoint().z();
object->setPosition(position.pos);
objectNode->setNodeMask(oldMask);
return;
}
objectNode->setNodeMask(oldMask);
}
void CSVRender::InstanceMode::dropSelectedInstances(bool active)
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_EditorReference);
if (selection.empty()) return;
CSMDoc::Document& document = getWorldspaceWidget().getDocument();
QUndoStack& undoStack = document.getUndoStack();
CSMWorld::CommandMacro macro (undoStack, "Drop Instances to next coillision");
for(osg::ref_ptr<TagBase> tag: selection)
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
{
dropInstance(Coillision_Below, objectTag->mObject);
objectTag->mObject->apply (macro);
}
}
void CSVRender::InstanceMode::groundlevelSelectedInstances(bool active)
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_EditorReference);
if (selection.empty()) return;
CSMDoc::Document& document = getWorldspaceWidget().getDocument();
QUndoStack& undoStack = document.getUndoStack();
CSMWorld::CommandMacro macro (undoStack, "Drop Instances to Ground Level");
for(osg::ref_ptr<TagBase> tag: selection)
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
{
dropInstance(Ground_level, objectTag->mObject);
objectTag->mObject->apply (macro);
}
}

@ -2,6 +2,7 @@
#define CSV_RENDER_INSTANCEMODE_H
#include <osg/ref_ptr>
#include <osg/Group>
#include <osg/Quat>
#include <osg/Vec3f>
@ -16,6 +17,7 @@ namespace CSVRender
{
class TagBase;
class InstanceSelectionMode;
class Object;
class InstanceMode : public EditMode
{
@ -29,6 +31,12 @@ namespace CSVRender
DragMode_Scale
};
enum DropMode
{
Coillision_Below,
Ground_level
};
CSVWidget::SceneToolMode *mSubMode;
std::string mSubModeId;
InstanceSelectionMode *mSelectionMode;
@ -36,6 +44,7 @@ namespace CSVRender
int mDragAxis;
bool mLocked;
float mUnitScaleDist;
osg::ref_ptr<osg::Group> mParentNode;
int getSubModeFromId (const std::string& id) const;
@ -44,10 +53,11 @@ namespace CSVRender
osg::Vec3f getSelectionCenter(const std::vector<osg::ref_ptr<TagBase> >& selection) const;
osg::Vec3f getScreenCoords(const osg::Vec3f& pos);
void dropInstance(DropMode dropMode, CSVRender::Object* object);
public:
InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0);
InstanceMode (WorldspaceWidget *worldspaceWidget, osg::ref_ptr<osg::Group> parentNode, QWidget *parent = 0);
virtual void activate (CSVWidget::SceneToolbar *toolbar);
@ -93,6 +103,8 @@ namespace CSVRender
void subModeChanged (const std::string& id);
void deleteSelectedInstances(bool active);
void dropSelectedInstances(bool active);
void groundlevelSelectedInstances(bool active);
};
}

@ -477,6 +477,11 @@ bool CSVRender::Object::getSelected() const
return mSelected;
}
osg::ref_ptr<osg::Group> CSVRender::Object::getRootNode()
{
return mRootNode;
}
bool CSVRender::Object::referenceableDataChanged (const QModelIndex& topLeft,
const QModelIndex& bottomRight)
{

@ -146,6 +146,9 @@ namespace CSVRender
bool getSelected() const;
/// For direct altering of object rendering
osg::ref_ptr<osg::Group> getRootNode();
/// \return Did this call result in a modification of the visual representation of
/// this object?
bool referenceableDataChanged (const QModelIndex& topLeft,

@ -370,7 +370,7 @@ void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons (
void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool)
{
/// \todo replace EditMode with suitable subclasses
tool->addButton (new InstanceMode (this, tool), "object");
tool->addButton (new InstanceMode (this, mRootNode, tool), "object");
tool->addButton (new PathgridMode (this, tool), "pathgrid");
}

Loading…
Cancel
Save