// // Camera - pan, zoom, and window resizing // #include #include #include #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()); } }