diff --git a/libs/scenelib.h b/libs/scenelib.h index 2518275332..8f1059a5ec 100644 --- a/libs/scenelib.h +++ b/libs/scenelib.h @@ -332,13 +332,12 @@ inline void assignVisibilityFlagsFromNode(INode& target, const INode& source) } } -inline std::pair getOriginAndAnglesToLookAtNode(const scene::INode& node) +inline std::pair getOriginAndAnglesToLookAtBounds(const AABB& aabb) { - const AABB& aabb = node.worldAABB(); Vector3 origin(aabb.origin); // Move the camera a bit off the AABB origin - origin += Vector3(aabb.extents.getLength() * 5, 0, aabb.extents.getLength() * 5); + origin += Vector3(aabb.extents.getLength() * 3, 0, aabb.extents.getLength() * 3); // Rotate the camera a bit towards the "ground" Vector3 angles(0, 0, 0); @@ -348,4 +347,9 @@ inline std::pair getOriginAndAnglesToLookAtNode(const scene::I return std::make_pair(origin, angles); } +inline std::pair getOriginAndAnglesToLookAtNode(const scene::INode& node) +{ + return getOriginAndAnglesToLookAtBounds(node.worldAABB()); +} + } // namespace scene diff --git a/radiantcore/map/Map.cpp b/radiantcore/map/Map.cpp index 53aab0df29..5aa0ff48a9 100644 --- a/radiantcore/map/Map.cpp +++ b/radiantcore/map/Map.cpp @@ -540,6 +540,21 @@ void Map::focusViewCmd(const cmd::ArgumentList& args) focusViews(args[0].getVector3(), args[1].getVector3()); } +void Map::focusCameraOnSelectionCmd(const cmd::ArgumentList& args) +{ + if (GlobalSelectionSystem().countSelected() == 0) + { + throw cmd::ExecutionNotPossible(_("Cannot focus, selection is empty")); + } + + // Determine the bounds of the current selection + const auto& workZone = GlobalSelectionSystem().getWorkZone(); + auto originAndAngles = scene::getOriginAndAnglesToLookAtBounds(workZone.bounds); + + // Set the camera and the views to the given point + GlobalCameraManager().focusAllCameras(originAndAngles.first, originAndAngles.second); +} + scene::INodePtr Map::findWorldspawn() { scene::INodePtr worldspawn; @@ -986,6 +1001,7 @@ void Map::registerCommands() GlobalCommandSystem().addCommand("SaveSelected", Map::exportSelection); GlobalCommandSystem().addCommand("ReloadSkins", map::algorithm::reloadSkins); GlobalCommandSystem().addCommand("FocusViews", std::bind(&Map::focusViewCmd, this, std::placeholders::_1), { cmd::ARGTYPE_VECTOR3, cmd::ARGTYPE_VECTOR3 }); + GlobalCommandSystem().addCommand("FocusCameraOnSelection", std::bind(&Map::focusCameraOnSelectionCmd, this, std::placeholders::_1)); GlobalCommandSystem().addCommand("ExportSelectedAsModel", map::algorithm::exportSelectedAsModelCmd, { cmd::ARGTYPE_STRING, cmd::ARGTYPE_STRING, diff --git a/radiantcore/map/Map.h b/radiantcore/map/Map.h index a76782423f..e95e166a2d 100644 --- a/radiantcore/map/Map.h +++ b/radiantcore/map/Map.h @@ -299,6 +299,7 @@ class Map : */ void focusViews(const Vector3& point, const Vector3& angles); void focusViewCmd(const cmd::ArgumentList& args); + void focusCameraOnSelectionCmd(const cmd::ArgumentList& args); void undoCmd(const cmd::ArgumentList& args); void redoCmd(const cmd::ArgumentList& args);