mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-12 04:14:05 +00:00
Merge branch 'help-i-dropped-it-into-oblivion' into 'master'
Task #8141: Merge instance drop modes See merge request OpenMW/openmw!4350
This commit is contained in:
commit
cb8e2809ac
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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",
|
||||
@ -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", "" };
|
||||
|
@ -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);
|
||||
@ -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)
|
||||
@ -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++)
|
||||
{
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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())
|
||||
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user