Skip to content

Commit

Permalink
Merge branch 'help-i-dropped-it-into-oblivion' into 'master'
Browse files Browse the repository at this point in the history
Task #8141: Merge instance drop modes

See merge request OpenMW/openmw!4350
  • Loading branch information
psi29a committed Nov 23, 2024
2 parents fe15803 + 1e6ed3e commit cb8e280
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 112 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 1 addition & 4 deletions apps/opencs/model/prefs/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
13 changes: 3 additions & 10 deletions apps/opencs/model/prefs/values.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,14 +447,7 @@ namespace CSMPrefs
Settings::SettingValue<std::string> mSceneSelectTertiary{ mIndex, sName, "scene-select-tertiary", "Shift+LMB" };
Settings::SettingValue<std::string> mSceneSpeedModifier{ mIndex, sName, "scene-speed-modifier", "Shift" };
Settings::SettingValue<std::string> mSceneDelete{ mIndex, sName, "scene-delete", "Delete" };
Settings::SettingValue<std::string> mSceneInstanceDropTerrain{ mIndex, sName, "scene-instance-drop-terrain",
"B" };
Settings::SettingValue<std::string> mSceneInstanceDropCollision{ mIndex, sName, "scene-instance-drop-collision",
"H" };
Settings::SettingValue<std::string> mSceneInstanceDropTerrainSeparately{ mIndex, sName,
"scene-instance-drop-terrain-separately", "" };
Settings::SettingValue<std::string> mSceneInstanceDropCollisionSeparately{ mIndex, sName,
"scene-instance-drop-collision-separately", "" };
Settings::SettingValue<std::string> mSceneInstanceDrop{ mIndex, sName, "scene-instance-drop", "F" };
Settings::SettingValue<std::string> mSceneDuplicate{ mIndex, sName, "scene-duplicate", "Shift+C" };
Settings::SettingValue<std::string> mSceneLoadCamCell{ mIndex, sName, "scene-load-cam-cell", "Keypad+5" };
Settings::SettingValue<std::string> mSceneLoadCamEastcell{ mIndex, sName, "scene-load-cam-eastcell",
Expand Down Expand Up @@ -505,14 +498,14 @@ namespace CSMPrefs
Settings::SettingValue<std::string> mFreeRight{ mIndex, sName, "free-right", "D" };
Settings::SettingValue<std::string> mFreeRollLeft{ mIndex, sName, "free-roll-left", "Q" };
Settings::SettingValue<std::string> mFreeRollRight{ mIndex, sName, "free-roll-right", "E" };
Settings::SettingValue<std::string> mFreeSpeedMode{ mIndex, sName, "free-speed-mode", "F" };
Settings::SettingValue<std::string> mFreeSpeedMode{ mIndex, sName, "free-speed-mode", "" };
Settings::SettingValue<std::string> mOrbitUp{ mIndex, sName, "orbit-up", "W" };
Settings::SettingValue<std::string> mOrbitDown{ mIndex, sName, "orbit-down", "S" };
Settings::SettingValue<std::string> mOrbitLeft{ mIndex, sName, "orbit-left", "A" };
Settings::SettingValue<std::string> mOrbitRight{ mIndex, sName, "orbit-right", "D" };
Settings::SettingValue<std::string> mOrbitRollLeft{ mIndex, sName, "orbit-roll-left", "Q" };
Settings::SettingValue<std::string> mOrbitRollRight{ mIndex, sName, "orbit-roll-right", "E" };
Settings::SettingValue<std::string> mOrbitSpeedMode{ mIndex, sName, "orbit-speed-mode", "F" };
Settings::SettingValue<std::string> mOrbitSpeedMode{ mIndex, sName, "orbit-speed-mode", "" };
Settings::SettingValue<std::string> mOrbitCenterSelection{ mIndex, sName, "orbit-center-selection", "C" };
Settings::SettingValue<std::string> mScriptEditorComment{ mIndex, sName, "script-editor-comment", "" };
Settings::SettingValue<std::string> mScriptEditorUncomment{ mIndex, sName, "script-editor-uncomment", "" };
Expand Down
115 changes: 34 additions & 81 deletions apps/opencs/view/render/instancemode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,24 @@
#include "pagedworldspacewidget.hpp"
#include "worldspacewidget.hpp"

namespace
{
constexpr std::string_view sInstanceModeTooltip = R"(
Instance editing
<ul><li>Use {scene-select-primary} and {scene-select-secondary} to select and unselect instances</li>
<li>Use {scene-edit-primary} to manipulate instances</li>
<li>Use {scene-select-tertiary} to select a reference object and then {scene-edit-secondary} to snap
selection relative to the reference object</li>
<li>Use {scene-submode-move}, {scene-submode-rotate}, {scene-submode-scale} to change to move, rotate, and
scale modes respectively</li>
<li>Use {scene-axis-x}, {scene-axis-y}, and {scene-axis-z} to lock changes to X, Y, and Z axes
respectively</li>
<li>Use {scene-delete} to delete currently selected objects</li>
<li>Use {scene-duplicate} to duplicate instances</li>
<li>Use {scene-instance-drop} to drop instances</li></ul>
)";
}

int CSVRender::InstanceMode::getSubModeFromId(const std::string& id) const
{
return id == "move" ? 0 : (id == "rotate" ? 1 : 2);
Expand Down Expand Up @@ -297,7 +315,7 @@ void CSVRender::InstanceMode::setDragAxis(const char axis)
CSVRender::InstanceMode::InstanceMode(
WorldspaceWidget* worldspaceWidget, osg::ref_ptr<osg::Group> parentNode, QWidget* parent)
: EditMode(worldspaceWidget, Misc::ScalableIcon::load(":scenetoolbar/editing-instance"),
Mask_Reference | Mask_Terrain, "Instance editing", parent)
Mask_Reference | Mask_Terrain, sInstanceModeTooltip.data(), parent)
, mSubMode(nullptr)
, mSubModeId("move")
, mSelectionMode(nullptr)
Expand All @@ -320,26 +338,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++)
{
Expand Down Expand Up @@ -1254,7 +1254,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();

Expand All @@ -1268,10 +1268,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);

Expand All @@ -1286,27 +1283,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<osg::ref_ptr<TagBase>> selection = getWorldspaceWidget().getSelection(Mask_Reference);
if (selection.empty())
Expand All @@ -1315,43 +1292,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<TagBase> tag : selection)
if (CSVRender::ObjectTag* objectTag = dynamic_cast<CSVRender::ObjectTag*>(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<float>::max();
int counter = 0;
for (osg::ref_ptr<TagBase> tag : selection)
if (CSVRender::ObjectTag* objectTag = dynamic_cast<CSVRender::ObjectTag*>(tag.get()))
{
float objectHeight = dropObjectDataHandler.mObjectHeights[counter];
float thisDrop = calculateDropHeight(dropMode, objectTag->mObject, objectHeight);
if (thisDrop < smallestDropHeight)
smallestDropHeight = thisDrop;
counter++;
}
for (osg::ref_ptr<TagBase> tag : selection)
if (CSVRender::ObjectTag* objectTag = dynamic_cast<CSVRender::ObjectTag*>(tag.get()))
{
dropInstance(objectTag->mObject, smallestDropHeight);
objectTag->mObject->apply(macro);
}
}
int counter = 0;
for (osg::ref_ptr<TagBase> tag : selection)
if (CSVRender::ObjectTag* objectTag = dynamic_cast<CSVRender::ObjectTag*>(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)
Expand Down
19 changes: 2 additions & 17 deletions apps/opencs/view/render/instancemode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit cb8e280

Please sign in to comment.