#ifndef CSV_RENDER_INSTANCEMODE_H #define CSV_RENDER_INSTANCEMODE_H #include #include #include #include #include #include #include #include #include "editmode.hpp" #include "instancedragmodes.hpp" #include #include class QDragEnterEvent; class QDropEvent; class QObject; class QPoint; class QWidget; namespace CSVWidget { class SceneToolMode; class SceneToolbar; } namespace CSVRender { class TagBase; class InstanceSelectionMode; class Object; class WorldspaceWidget; struct WorldspaceHitResult; class InstanceMode : public EditMode { Q_OBJECT CSVWidget::SceneToolMode* mSubMode; std::string mSubModeId; InstanceSelectionMode* mSelectionMode; DragMode mDragMode; int mDragAxis; bool mLocked; float mUnitScaleDist; osg::ref_ptr mParentNode; osg::Vec3 mDragStart; std::vector mObjectsAtDragStart; CSMWorld::IdTable* mSelectionGroups; int getSubModeFromId(const std::string& id) const; osg::Vec3 quatToEuler(const osg::Quat& quat) const; osg::Quat eulerToQuat(const osg::Vec3& euler) const; float roundFloatToMult(const float val, const double mult) const; osg::Vec3 getSelectionCenter(const std::vector>& selection) const; osg::Vec3 getScreenCoords(const osg::Vec3& pos); osg::Vec3 getProjectionSpaceCoords(const osg::Vec3& pos); osg::Vec3 getMousePlaneCoords(const QPoint& point, const osg::Vec3d& dragStart); void handleSelectDrag(const QPoint& pos); void dropInstance(CSVRender::Object* object, float dropHeight); float calculateDropHeight(CSVRender::Object* object, float objectHeight); osg::Vec3 calculateSnapPositionRelativeToTarget(osg::Vec3 initalPosition, osg::Vec3 targetPosition, osg::Vec3 targetRotation, osg::Vec3 translation, double snap) const; public: InstanceMode( WorldspaceWidget* worldspaceWidget, osg::ref_ptr parentNode, QWidget* parent = nullptr); void activate(CSVWidget::SceneToolbar* toolbar) override; void deactivate(CSVWidget::SceneToolbar* toolbar) override; void setEditLock(bool locked) override; void primaryOpenPressed(const WorldspaceHitResult& hit) override; void primaryEditPressed(const WorldspaceHitResult& hit) override; void secondaryEditPressed(const WorldspaceHitResult& hit) override; void primarySelectPressed(const WorldspaceHitResult& hit) override; void secondarySelectPressed(const WorldspaceHitResult& hit) override; void tertiarySelectPressed(const WorldspaceHitResult& hit) override; bool primaryEditStartDrag(const QPoint& pos) override; bool secondaryEditStartDrag(const QPoint& pos) override; bool primarySelectStartDrag(const QPoint& pos) override; bool secondarySelectStartDrag(const QPoint& pos) override; void drag(const QPoint& pos, int diffX, int diffY, double speedFactor) override; void dragCompleted(const QPoint& pos) override; /// \note dragAborted will not be called, if the drag is aborted via changing /// editing mode void dragAborted() override; void dragWheel(int diff, double speedFactor) override; void dragEnterEvent(QDragEnterEvent* event) override; void dropEvent(QDropEvent* event) override; int getSubMode() const override; signals: void requestFocus(const std::string& id); private slots: void setDragAxis(const char axis); void subModeChanged(const std::string& id); void deleteSelectedInstances(); void cloneSelectedInstances(); void getSelectionGroup(const int group); void saveSelectionGroup(const int group); void dropToCollision(); }; /// \brief Helper class to handle object mask data in safe way class DropObjectHeightHandler { public: DropObjectHeightHandler(WorldspaceWidget* worldspacewidget); ~DropObjectHeightHandler(); std::vector mObjectHeights; private: WorldspaceWidget* mWorldspaceWidget; std::vector mOldMasks; }; } #endif