From 0fea0868ed64bc696826e55a9fb63bae28abe980 Mon Sep 17 00:00:00 2001 From: Dave Corley Date: Fri, 30 Aug 2024 17:54:43 -0700 Subject: [PATCH 1/5] CLEANUP(values.hpp): Unbind camera speed mode (later rebind to wheel?) --- apps/opencs/model/prefs/values.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/prefs/values.hpp b/apps/opencs/model/prefs/values.hpp index c4b7010aaf9..957927b087b 100644 --- a/apps/opencs/model/prefs/values.hpp +++ b/apps/opencs/model/prefs/values.hpp @@ -505,14 +505,14 @@ namespace CSMPrefs Settings::SettingValue mFreeRight{ mIndex, sName, "free-right", "D" }; Settings::SettingValue mFreeRollLeft{ mIndex, sName, "free-roll-left", "Q" }; Settings::SettingValue mFreeRollRight{ mIndex, sName, "free-roll-right", "E" }; - Settings::SettingValue mFreeSpeedMode{ mIndex, sName, "free-speed-mode", "F" }; + Settings::SettingValue mFreeSpeedMode{ mIndex, sName, "free-speed-mode", "" }; Settings::SettingValue mOrbitUp{ mIndex, sName, "orbit-up", "W" }; Settings::SettingValue mOrbitDown{ mIndex, sName, "orbit-down", "S" }; Settings::SettingValue mOrbitLeft{ mIndex, sName, "orbit-left", "A" }; Settings::SettingValue mOrbitRight{ mIndex, sName, "orbit-right", "D" }; Settings::SettingValue mOrbitRollLeft{ mIndex, sName, "orbit-roll-left", "Q" }; Settings::SettingValue mOrbitRollRight{ mIndex, sName, "orbit-roll-right", "E" }; - Settings::SettingValue mOrbitSpeedMode{ mIndex, sName, "orbit-speed-mode", "F" }; + Settings::SettingValue mOrbitSpeedMode{ mIndex, sName, "orbit-speed-mode", "" }; Settings::SettingValue mOrbitCenterSelection{ mIndex, sName, "orbit-center-selection", "C" }; Settings::SettingValue mScriptEditorComment{ mIndex, sName, "script-editor-comment", "" }; Settings::SettingValue mScriptEditorUncomment{ mIndex, sName, "script-editor-uncomment", "" }; From fb9b19102718b7e58c9da73f0b6b32dc7805958c Mon Sep 17 00:00:00 2001 From: Dave Corley Date: Fri, 30 Aug 2024 22:29:40 -0700 Subject: [PATCH 2/5] CLEANUP(instancemode): Always drop everything the same way --- apps/opencs/model/prefs/state.cpp | 5 +- apps/opencs/model/prefs/values.hpp | 9 +-- apps/opencs/view/render/instancemode.cpp | 95 ++++-------------------- apps/opencs/view/render/instancemode.hpp | 19 +---- 4 files changed, 19 insertions(+), 109 deletions(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 3dcc5194016..f0af163bf21 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -336,10 +336,7 @@ void CSMPrefs::State::declare() declareShortcut(mValues->mKeyBindings.mSceneSelectTertiary, "Tertiary Select"); declareModifier(mValues->mKeyBindings.mSceneSpeedModifier, "Speed Modifier"); declareShortcut(mValues->mKeyBindings.mSceneDelete, "Delete Instance"); - declareShortcut(mValues->mKeyBindings.mSceneInstanceDropTerrain, "Drop to Terrain Level"); - declareShortcut(mValues->mKeyBindings.mSceneInstanceDropCollision, "Drop to Collision"); - declareShortcut(mValues->mKeyBindings.mSceneInstanceDropTerrainSeparately, "Drop to Terrain Level Separately"); - declareShortcut(mValues->mKeyBindings.mSceneInstanceDropCollisionSeparately, "Drop to Collision Separately"); + declareShortcut(mValues->mKeyBindings.mSceneInstanceDrop, "Drop to Collision"); declareShortcut(mValues->mKeyBindings.mSceneLoadCamCell, "Load Camera Cell"); declareShortcut(mValues->mKeyBindings.mSceneLoadCamEastcell, "Load East Cell"); declareShortcut(mValues->mKeyBindings.mSceneLoadCamNorthcell, "Load North Cell"); diff --git a/apps/opencs/model/prefs/values.hpp b/apps/opencs/model/prefs/values.hpp index 957927b087b..1339fa62ed7 100644 --- a/apps/opencs/model/prefs/values.hpp +++ b/apps/opencs/model/prefs/values.hpp @@ -447,14 +447,7 @@ namespace CSMPrefs Settings::SettingValue mSceneSelectTertiary{ mIndex, sName, "scene-select-tertiary", "Shift+LMB" }; Settings::SettingValue mSceneSpeedModifier{ mIndex, sName, "scene-speed-modifier", "Shift" }; Settings::SettingValue mSceneDelete{ mIndex, sName, "scene-delete", "Delete" }; - Settings::SettingValue mSceneInstanceDropTerrain{ mIndex, sName, "scene-instance-drop-terrain", - "B" }; - Settings::SettingValue mSceneInstanceDropCollision{ mIndex, sName, "scene-instance-drop-collision", - "H" }; - Settings::SettingValue mSceneInstanceDropTerrainSeparately{ mIndex, sName, - "scene-instance-drop-terrain-separately", "" }; - Settings::SettingValue mSceneInstanceDropCollisionSeparately{ mIndex, sName, - "scene-instance-drop-collision-separately", "" }; + Settings::SettingValue mSceneInstanceDrop{ mIndex, sName, "scene-instance-drop", "F" }; Settings::SettingValue mSceneDuplicate{ mIndex, sName, "scene-duplicate", "Shift+C" }; Settings::SettingValue mSceneLoadCamCell{ mIndex, sName, "scene-load-cam-cell", "Keypad+5" }; Settings::SettingValue mSceneLoadCamEastcell{ mIndex, sName, "scene-load-cam-eastcell", diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index 58513110355..ae73e6780c4 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -320,26 +320,8 @@ CSVRender::InstanceMode::InstanceMode( connect( duplicateShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, &InstanceMode::cloneSelectedInstances); - // Following classes could be simplified by using QSignalMapper, which is obsolete in Qt5.10, but not in Qt4.8 and - // Qt5.14 - CSMPrefs::Shortcut* dropToCollisionShortcut - = new CSMPrefs::Shortcut("scene-instance-drop-collision", worldspaceWidget); - - connect(dropToCollisionShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, - &InstanceMode::dropSelectedInstancesToCollision); - - CSMPrefs::Shortcut* dropToTerrainLevelShortcut - = new CSMPrefs::Shortcut("scene-instance-drop-terrain", worldspaceWidget); - connect(dropToTerrainLevelShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, - &InstanceMode::dropSelectedInstancesToTerrain); - CSMPrefs::Shortcut* dropToCollisionShortcut2 - = new CSMPrefs::Shortcut("scene-instance-drop-collision-separately", worldspaceWidget); - connect(dropToCollisionShortcut2, qOverload<>(&CSMPrefs::Shortcut::activated), this, - &InstanceMode::dropSelectedInstancesToCollisionSeparately); - CSMPrefs::Shortcut* dropToTerrainLevelShortcut2 - = new CSMPrefs::Shortcut("scene-instance-drop-terrain-separately", worldspaceWidget); - connect(dropToTerrainLevelShortcut2, qOverload<>(&CSMPrefs::Shortcut::activated), this, - &InstanceMode::dropSelectedInstancesToTerrainSeparately); + connect(new CSMPrefs::Shortcut("scene-instance-drop", worldspaceWidget), + qOverload<>(&CSMPrefs::Shortcut::activated), this, &InstanceMode::dropToCollision); for (short i = 0; i <= 9; i++) { @@ -1254,7 +1236,7 @@ void CSVRender::InstanceMode::dropInstance(CSVRender::Object* object, float drop object->setPosition(position.pos); } -float CSVRender::InstanceMode::calculateDropHeight(DropMode dropMode, CSVRender::Object* object, float objectHeight) +float CSVRender::InstanceMode::calculateDropHeight(CSVRender::Object* object, float objectHeight) { osg::Vec3d point = object->getPosition().asVec3(); @@ -1268,10 +1250,7 @@ float CSVRender::InstanceMode::calculateDropHeight(DropMode dropMode, CSVRender: intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT); osgUtil::IntersectionVisitor visitor(intersector); - if (dropMode & Terrain) - visitor.setTraversalMask(Mask_Terrain); - if (dropMode & Collision) - visitor.setTraversalMask(Mask_Terrain | Mask_Reference); + visitor.setTraversalMask(Mask_Terrain | Mask_Reference); mParentNode->accept(visitor); @@ -1286,27 +1265,7 @@ float CSVRender::InstanceMode::calculateDropHeight(DropMode dropMode, CSVRender: return 0.0f; } -void CSVRender::InstanceMode::dropSelectedInstancesToCollision() -{ - handleDropMethod(Collision, "Drop instances to next collision"); -} - -void CSVRender::InstanceMode::dropSelectedInstancesToTerrain() -{ - handleDropMethod(Terrain, "Drop instances to terrain level"); -} - -void CSVRender::InstanceMode::dropSelectedInstancesToCollisionSeparately() -{ - handleDropMethod(CollisionSep, "Drop instances to next collision level separately"); -} - -void CSVRender::InstanceMode::dropSelectedInstancesToTerrainSeparately() -{ - handleDropMethod(TerrainSep, "Drop instances to terrain level separately"); -} - -void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString commandMsg) +void CSVRender::InstanceMode::dropToCollision() { std::vector> selection = getWorldspaceWidget().getSelection(Mask_Reference); if (selection.empty()) @@ -1315,43 +1274,19 @@ void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString comman CSMDoc::Document& document = getWorldspaceWidget().getDocument(); QUndoStack& undoStack = document.getUndoStack(); - CSMWorld::CommandMacro macro(undoStack, commandMsg); + CSMWorld::CommandMacro macro(undoStack, "Drop objects to collision"); DropObjectHeightHandler dropObjectDataHandler(&getWorldspaceWidget()); - if (dropMode & Separate) - { - int counter = 0; - for (osg::ref_ptr tag : selection) - if (CSVRender::ObjectTag* objectTag = dynamic_cast(tag.get())) - { - float objectHeight = dropObjectDataHandler.mObjectHeights[counter]; - float dropHeight = calculateDropHeight(dropMode, objectTag->mObject, objectHeight); - dropInstance(objectTag->mObject, dropHeight); - objectTag->mObject->apply(macro); - counter++; - } - } - else - { - float smallestDropHeight = std::numeric_limits::max(); - int counter = 0; - for (osg::ref_ptr tag : selection) - if (CSVRender::ObjectTag* objectTag = dynamic_cast(tag.get())) - { - float objectHeight = dropObjectDataHandler.mObjectHeights[counter]; - float thisDrop = calculateDropHeight(dropMode, objectTag->mObject, objectHeight); - if (thisDrop < smallestDropHeight) - smallestDropHeight = thisDrop; - counter++; - } - for (osg::ref_ptr tag : selection) - if (CSVRender::ObjectTag* objectTag = dynamic_cast(tag.get())) - { - dropInstance(objectTag->mObject, smallestDropHeight); - objectTag->mObject->apply(macro); - } - } + int counter = 0; + for (osg::ref_ptr tag : selection) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(tag.get())) + { + float objectHeight = dropObjectDataHandler.mObjectHeights[counter++]; + float dropHeight = calculateDropHeight(objectTag->mObject, objectHeight); + dropInstance(objectTag->mObject, dropHeight); + objectTag->mObject->apply(macro); + } } CSVRender::DropObjectHeightHandler::DropObjectHeightHandler(WorldspaceWidget* worldspacewidget) diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index 45d7c2b6fd1..193423efd5c 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -41,17 +41,6 @@ namespace CSVRender { Q_OBJECT - enum DropMode - { - Separate = 0b1, - - Collision = 0b10, - Terrain = 0b100, - - CollisionSep = Collision | Separate, - TerrainSep = Terrain | Separate, - }; - CSVWidget::SceneToolMode* mSubMode; std::string mSubModeId; InstanceSelectionMode* mSelectionMode; @@ -77,7 +66,7 @@ namespace CSVRender osg::Vec3 getMousePlaneCoords(const QPoint& point, const osg::Vec3d& dragStart); void handleSelectDrag(const QPoint& pos); void dropInstance(CSVRender::Object* object, float dropHeight); - float calculateDropHeight(DropMode dropMode, CSVRender::Object* object, float objectHeight); + 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; @@ -139,11 +128,7 @@ namespace CSVRender void cloneSelectedInstances(); void getSelectionGroup(const int group); void saveSelectionGroup(const int group); - void dropSelectedInstancesToCollision(); - void dropSelectedInstancesToTerrain(); - void dropSelectedInstancesToCollisionSeparately(); - void dropSelectedInstancesToTerrainSeparately(); - void handleDropMethod(DropMode dropMode, QString commandMsg); + void dropToCollision(); }; /// \brief Helper class to handle object mask data in safe way From 44d593957294f9a0376f0d1bd6d056eb1ce05aac Mon Sep 17 00:00:00 2001 From: Dave Corley Date: Fri, 30 Aug 2024 22:30:58 -0700 Subject: [PATCH 3/5] FEAT(InstanceMode): Add a tooltip for InstanceMode in the same style as that of PathgridMode --- apps/opencs/view/render/instancemode.cpp | 19 ++++++++++++++++++- apps/opencs/view/render/instancemode.hpp | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index ae73e6780c4..615ca42aa1c 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -297,7 +297,7 @@ void CSVRender::InstanceMode::setDragAxis(const char axis) CSVRender::InstanceMode::InstanceMode( WorldspaceWidget* worldspaceWidget, osg::ref_ptr parentNode, QWidget* parent) : EditMode(worldspaceWidget, Misc::ScalableIcon::load(":scenetoolbar/editing-instance"), - Mask_Reference | Mask_Terrain, "Instance editing", parent) + Mask_Reference | Mask_Terrain, getTooltip(), parent) , mSubMode(nullptr) , mSubModeId("move") , mSelectionMode(nullptr) @@ -345,6 +345,23 @@ CSVRender::InstanceMode::InstanceMode( qOverload<>(&CSMPrefs::Shortcut::activated), this, [this, axis] { this->setDragAxis(axis); }); } +QString CSVRender::InstanceMode::getTooltip() +{ + return QString( + "Instance editing" + "
  • Use {scene-select-primary} and {scene-select-secondary} to select and unselect instances
  • " + "
  • Use {scene-edit-primary} to manipulate instances
  • " + "
  • Use {scene-select-tertiary} to select a reference object and then {scene-edit-secondary} to snap " + "selection relative to the reference object
  • " + "
  • Use {scene-submode-move}, {scene-submode-rotate}, {scene-submode-scale} to change to move, rotate, and " + "scale modes respectively
  • " + "
  • Use {scene-axis-x}, {scene-axis-y}, and {scene-axis-z} to lock changes to X, Y, and Z axes " + "respectively
  • " + "
  • Use {scene-delete} to delete currently selected objects
  • " + "
  • Use {scene-duplicate} to duplicate instances
  • " + "
  • Use {scene-instance-drop} to drop instances
"); +} + void CSVRender::InstanceMode::activate(CSVWidget::SceneToolbar* toolbar) { if (!mSubMode) diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index 193423efd5c..ae7be10322a 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -74,6 +74,8 @@ namespace CSVRender InstanceMode( WorldspaceWidget* worldspaceWidget, osg::ref_ptr parentNode, QWidget* parent = nullptr); + QString getTooltip(); + void activate(CSVWidget::SceneToolbar* toolbar) override; void deactivate(CSVWidget::SceneToolbar* toolbar) override; From 1b0312dc80f6dddec8f17342a2effed046c47577 Mon Sep 17 00:00:00 2001 From: Dave Corley Date: Fri, 30 Aug 2024 22:41:13 -0700 Subject: [PATCH 4/5] c h a n g e l o g --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97941564a31..ceb9894539c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -290,6 +290,7 @@ Task #7182: FFMpeg 5.1.1+ support Task #7394: Drop support for --fs-strict Task #7720: Drop 360-degree screenshot support + Task #8141: Merge Instance Drop Modes Task #8214: Drop script blacklisting functionality 0.48.0 From 1e6ed3eb70dd534f33f31a9b0d9b7f75b02be417 Mon Sep 17 00:00:00 2001 From: Dave Corley Date: Fri, 22 Nov 2024 04:49:55 -0600 Subject: [PATCH 5/5] CLEANUP: Define the tooltip text as constexpr --- apps/opencs/view/render/instancemode.cpp | 37 ++++++++++++------------ apps/opencs/view/render/instancemode.hpp | 2 -- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index 615ca42aa1c..7a59222eff8 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -60,6 +60,24 @@ #include "pagedworldspacewidget.hpp" #include "worldspacewidget.hpp" +namespace +{ + constexpr std::string_view sInstanceModeTooltip = R"( + Instance editing +
  • Use {scene-select-primary} and {scene-select-secondary} to select and unselect instances
  • +
  • Use {scene-edit-primary} to manipulate instances
  • +
  • Use {scene-select-tertiary} to select a reference object and then {scene-edit-secondary} to snap + selection relative to the reference object
  • +
  • Use {scene-submode-move}, {scene-submode-rotate}, {scene-submode-scale} to change to move, rotate, and + scale modes respectively
  • +
  • Use {scene-axis-x}, {scene-axis-y}, and {scene-axis-z} to lock changes to X, Y, and Z axes + respectively
  • +
  • Use {scene-delete} to delete currently selected objects
  • +
  • Use {scene-duplicate} to duplicate instances
  • +
  • Use {scene-instance-drop} to drop instances
+)"; +} + int CSVRender::InstanceMode::getSubModeFromId(const std::string& id) const { return id == "move" ? 0 : (id == "rotate" ? 1 : 2); @@ -297,7 +315,7 @@ void CSVRender::InstanceMode::setDragAxis(const char axis) CSVRender::InstanceMode::InstanceMode( WorldspaceWidget* worldspaceWidget, osg::ref_ptr parentNode, QWidget* parent) : EditMode(worldspaceWidget, Misc::ScalableIcon::load(":scenetoolbar/editing-instance"), - Mask_Reference | Mask_Terrain, getTooltip(), parent) + Mask_Reference | Mask_Terrain, sInstanceModeTooltip.data(), parent) , mSubMode(nullptr) , mSubModeId("move") , mSelectionMode(nullptr) @@ -345,23 +363,6 @@ CSVRender::InstanceMode::InstanceMode( qOverload<>(&CSMPrefs::Shortcut::activated), this, [this, axis] { this->setDragAxis(axis); }); } -QString CSVRender::InstanceMode::getTooltip() -{ - return QString( - "Instance editing" - "
  • Use {scene-select-primary} and {scene-select-secondary} to select and unselect instances
  • " - "
  • Use {scene-edit-primary} to manipulate instances
  • " - "
  • Use {scene-select-tertiary} to select a reference object and then {scene-edit-secondary} to snap " - "selection relative to the reference object
  • " - "
  • Use {scene-submode-move}, {scene-submode-rotate}, {scene-submode-scale} to change to move, rotate, and " - "scale modes respectively
  • " - "
  • Use {scene-axis-x}, {scene-axis-y}, and {scene-axis-z} to lock changes to X, Y, and Z axes " - "respectively
  • " - "
  • Use {scene-delete} to delete currently selected objects
  • " - "
  • Use {scene-duplicate} to duplicate instances
  • " - "
  • Use {scene-instance-drop} to drop instances
"); -} - void CSVRender::InstanceMode::activate(CSVWidget::SceneToolbar* toolbar) { if (!mSubMode) diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index ae7be10322a..193423efd5c 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -74,8 +74,6 @@ namespace CSVRender InstanceMode( WorldspaceWidget* worldspaceWidget, osg::ref_ptr parentNode, QWidget* parent = nullptr); - QString getTooltip(); - void activate(CSVWidget::SceneToolbar* toolbar) override; void deactivate(CSVWidget::SceneToolbar* toolbar) override;