SDcmWeb/webassembly/camera.cpp
2025-10-12 00:17:30 +09:00

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());
}
}