151 lines
4.4 KiB
C++
151 lines
4.4 KiB
C++
//
|
|
// Camera - pan, zoom, and window resizing
|
|
//
|
|
#include <algorithm>
|
|
#include <SDL.h>
|
|
#include <SDL_opengles2.h>
|
|
#include "camera.h"
|
|
|
|
bool Camera::updated()
|
|
{
|
|
bool updated = mCameraUpdated;
|
|
mCameraUpdated = false;
|
|
return updated;
|
|
}
|
|
|
|
bool Camera::windowResized()
|
|
{
|
|
bool resized = mWindowResized;
|
|
mWindowResized = false;
|
|
return resized;
|
|
}
|
|
|
|
void Camera::setWindowSize(int width, int height)
|
|
{
|
|
if (mWindowSize.width != width || mWindowSize.height != height)
|
|
{
|
|
mWindowResized = true;
|
|
mWindowSize = {width, height};
|
|
mViewport = {(float)width, (float)height};
|
|
//setAspect((float)width / (float)height);
|
|
setAspect(1.0);
|
|
|
|
printf("setWindowSize: %d, %d, %f\n", width, height, (float)width/(float)height);
|
|
}
|
|
}
|
|
|
|
// Clamp val between lo and hi
|
|
float Camera::clamp (float val, float lo, float hi)
|
|
{
|
|
return std::max(lo, std::min(val, hi));
|
|
}
|
|
|
|
// Convert from normalized window coords (x,y) in ([0.0, 1.0], [1.0, 0.0]) to device coords ([-1.0, 1.0], [-1.0,1.0])
|
|
void Camera::normWindowToDeviceCoords (float normWinX, float normWinY, float& deviceX, float& deviceY)
|
|
{
|
|
deviceX = (normWinX - 0.5f) * 2.0f;
|
|
deviceY = (1.0f - normWinY - 0.5f) * 2.0f;
|
|
}
|
|
|
|
// Convert from window coords (x,y) in ([0, mWindowWidth], [mWindowHeight, 0]) to device coords ([-1.0, 1.0], [-1.0,1.0])
|
|
void Camera::windowToDeviceCoords (int winX, int winY, float& deviceX, float& deviceY)
|
|
{
|
|
normWindowToDeviceCoords(winX / (float)mWindowSize.width, winY / (float)mWindowSize.height, deviceX, deviceY);
|
|
}
|
|
|
|
// Convert from device coords ([-1.0, 1.0], [-1.0,1.0]) to world coords ([-inf, inf], [-inf, inf])
|
|
void Camera::deviceToWorldCoords (float deviceX, float deviceY, float& worldX, float& worldY)
|
|
{
|
|
worldX = deviceX / mZoom - mPan.x;
|
|
worldY = deviceY / mAspect / mZoom - mPan.y;
|
|
}
|
|
|
|
// Convert from window coords (x,y) in ([0, windowWidth], [windowHeight, 0]) to world coords ([-inf, inf], [-inf, inf])
|
|
void Camera::windowToWorldCoords(int winX, int winY, float& worldX, float& worldY)
|
|
{
|
|
float deviceX, deviceY;
|
|
windowToDeviceCoords(winX, winY, deviceX, deviceY);
|
|
deviceToWorldCoords(deviceX, deviceY, worldX, worldY);
|
|
}
|
|
|
|
// Convert from normalized window coords (x,y) in in ([0.0, 1.0], [1.0, 0.0]) to world coords ([-inf, inf], [-inf, inf])
|
|
void Camera::normWindowToWorldCoords(float normWinX, float normWinY, float& worldX, float& worldY)
|
|
{
|
|
float deviceX, deviceY;
|
|
normWindowToDeviceCoords(normWinX, normWinY, deviceX, deviceY);
|
|
deviceToWorldCoords(deviceX, deviceY, worldX, worldY);
|
|
}
|
|
|
|
void Camera::reset()
|
|
{
|
|
mZoom = 1.0f;
|
|
mPan = Vec2{0.0f, 0.0f};
|
|
mBasePan = Vec2{0.0f, 0.0f};
|
|
mAspect = 1.0f;
|
|
|
|
mCameraUpdated = true;
|
|
|
|
}
|
|
|
|
void Camera::toJson(nlohmann::json& json_obj) const
|
|
{
|
|
printf("1");
|
|
json_obj["camera"]["cameraUpdated"] = mCameraUpdated;
|
|
json_obj["camera"]["windowResized"] = mWindowResized;
|
|
|
|
printf("2");
|
|
json_obj["camera"]["width"] = mWindowSize.width;
|
|
json_obj["camera"]["height"] = mWindowSize.height;
|
|
|
|
printf("3");
|
|
json_obj["camera"]["viewport_x"] = mViewport.x;
|
|
json_obj["camera"]["viewport_y"] = mViewport.y;
|
|
|
|
printf("4");
|
|
json_obj["camera"]["pan_x"] = mPan.x;
|
|
json_obj["camera"]["pan_y"] = mPan.y;
|
|
|
|
printf("5");
|
|
json_obj["camera"]["zoom"] = mZoom;
|
|
json_obj["camera"]["aspect"] = mAspect;
|
|
|
|
printf("6");
|
|
json_obj["camera"]["basepan_x"] = mBasePan.x;
|
|
json_obj["camera"]["basepan_y"] = mBasePan.y;
|
|
|
|
printf("exit toJson");
|
|
}
|
|
|
|
void Camera::fromString(const char* pStrDumpJson)
|
|
{
|
|
printf("Camera::fromString enter!%s\n", pStrDumpJson);
|
|
|
|
try
|
|
{
|
|
nlohmann::json json_obj = nlohmann::json::parse(pStrDumpJson);
|
|
|
|
printf("1");
|
|
const auto& camera_data = json_obj["camera"];
|
|
mCameraUpdated = camera_data["cameraUpdated"];
|
|
mWindowResized = camera_data["windowResized"];
|
|
mWindowSize.width = camera_data["width"];
|
|
mWindowSize.height = camera_data["height"];
|
|
mViewport.x = camera_data["viewport_x"];
|
|
mViewport.y = camera_data["viewport_y"];
|
|
mPan.x = camera_data["pan_x"];
|
|
mPan.y = camera_data["pan_y"];
|
|
mZoom = camera_data["zoom"];
|
|
mAspect = camera_data["aspect"];
|
|
mBasePan.x = camera_data["basepan_x"];
|
|
mBasePan.y = camera_data["basepan_y"];
|
|
|
|
|
|
}
|
|
catch (const nlohmann::json::exception& e)
|
|
{
|
|
// It's good practice to catch potential errors
|
|
printf("JSON parsing error: %s\n", e.what());
|
|
}
|
|
|
|
}
|