Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(OverviewCam): Add OverviewRotation option #714

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 45 additions & 2 deletions rts/Game/Camera/OverviewController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
#include "Game/UI/MiniMap.h"
#include "Game/UI/MouseHandler.h"
#include "System/Log/ILog.h"
#include "System/Config/ConfigHandler.h"


CONFIG(bool, OverviewRotation)
.defaultValue(false)
.headlessValue(false)
.description("Set Overview camera controller to follow camera rotation instead of default orientation");

static float GetCamHeightToFitMapInView(float mapx, float mapy, float fov) {
static constexpr float marginForUI = 1.037f; // leave some space for UI outside of map edges
Expand All @@ -23,9 +30,29 @@ COverviewController::COverviewController()
minimizeMinimap = false;

pos.y = GetCamHeightToFitMapInView(pos.x, pos.z, fov/2.0);
dir = float3(0.0f, -1.0f, -0.001f).ANormalize();
dir = DIR_UP;

configHandler->NotifyOnChange(this, {"OverviewRotation"});
ConfigUpdate();
}

COverviewController::~COverviewController()
{
configHandler->RemoveObserver(this);
}

void COverviewController::ConfigUpdate()
{
followRotation = configHandler->GetBool("OverviewRotation");

if (!followRotation)
dir = DIR_UP;
}

void COverviewController::ConfigNotify(const std::string & key, const std::string & value)
{
ConfigUpdate();
}

float3 COverviewController::SwitchFrom() const
{
Expand Down Expand Up @@ -59,6 +86,22 @@ bool COverviewController::SetState(const StateMap& sm)
// CCameraController::SetState(sm);
// always centered, allow only for FOV change
SetStateFloat(sm, "fov", fov);
pos.y = GetCamHeightToFitMapInView(pos.x, pos.z, fov/2.0);

// allow dir change so if previous camera on high rotY transition is not jarring
if (followRotation) {
SetStateFloat(sm, "dx", dir.x);
SetStateFloat(sm, "dy", dir.y);
SetStateFloat(sm, "dz", dir.z);
}

float mapx = pos.x;
float mapz = pos.z;

if (followRotation && (dir == DIR_LEFT || dir == DIR_RIGHT)) {
mapx = pos.z;
mapz = pos.x;
}

pos.y = GetCamHeightToFitMapInView(mapx, mapz, fov/2.0);
return true;
}
10 changes: 10 additions & 0 deletions rts/Game/Camera/OverviewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,18 @@ class COverviewController : public CCameraController
{
public:
COverviewController();
~COverviewController();

constexpr static float3 DIR_UP = float3(0.0f, -0.999999500000375f, -0.000999999500000375f); // -90 deg
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks suspiciously close to (0, -1, 0), could use a comment on why the tiny difference

Copy link
Collaborator Author

@badosu badosu Mar 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good question! This is the explicit version of what was the previous dir float3(0.0f, -1.0f, -0.001f).ANormalize().

I have absolutely no idea! My intuition was that it is looking down (almost negative 1 on y direction) and a tiny x,-x,z,-z component for each of the directions (the comments are wrong).

Copy link
Collaborator

@sprunk sprunk Mar 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try (0, -1, 0) and see what happens.

I think it's just to specify a "heading" around the Y axis, i.e. otherwise it's unspecified where "north" is, for example for camera panning purposes - these two could both have (0, -1, 0) dir up:
image
But hopefully that's where the other constants (DIR_{LEFT,RIGHT}) come in to disambiguate.

A straight top-down angle also used to break shadows in the past AFAIK, could check if that is still the case.

constexpr static float3 DIR_LEFT = float3(0.000999999500000375f, -0.999999500000375f, 0.0f); // -90 deg
constexpr static float3 DIR_BOTTOM = float3(0.0f, -0.999999500000375f, 0.000999999500000375f); // 90 deg
constexpr static float3 DIR_RIGHT = float3(-0.000999999500000375f, -0.999999500000375f, 0.0f); // -90 deg

const std::string GetName() const { return "ov"; }

void ConfigNotify(const std::string& key, const std::string& value);
void ConfigUpdate();

void KeyMove(float3 move) override {}
void MouseMove(float3 move) override {}
void ScreenEdgeMove(float3 move) override {}
Expand All @@ -29,6 +38,7 @@ class COverviewController : public CCameraController

private:
bool minimizeMinimap;
bool followRotation;
};

#endif // _OV_CONTROLLER_H
28 changes: 28 additions & 0 deletions rts/Game/CameraHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,34 @@ void CCameraHandler::ToggleOverviewCamera()

if (controllerStack.empty()) {
PushMode();

// Set overview camera direction according to rotation of current camera
// controller. This way we avoid jarring transitions.
if (configHandler->GetBool("OverviewRotation")) {
const float rotY = fmod(abs(camHandler->GetCurrentController().GetRot().y), math::TWOPI);
float3 dir = COverviewController::DIR_UP;

static constexpr float three_quarters_pi = math::HALFPI + math::QUARTERPI;
static constexpr float five_quarters_pi = math::PI + math::QUARTERPI;
static constexpr float seven_quarters_pi = five_quarters_pi + math::HALFPI;

if (rotY < math::QUARTERPI) {
} else if (rotY < three_quarters_pi) {
dir = COverviewController::DIR_LEFT;
} else if (rotY < five_quarters_pi) {
dir = COverviewController::DIR_BOTTOM;
} else if (rotY < seven_quarters_pi) {
dir = COverviewController::DIR_RIGHT;
}

CCameraController::StateMap sm;
camControllers[CAMERA_MODE_OVERVIEW]->GetState(sm);
sm["dx"] = dir.x;
sm["dy"] = dir.y;
sm["dz"] = dir.z;
camControllers[CAMERA_MODE_OVERVIEW]->SetState(sm);
}

SetCameraMode(CAMERA_MODE_OVERVIEW);
} else {
PopMode();
Expand Down