Fixes big screenshots, implements CCamera::GetViewQuad properly for custom projections.
Differential Revision: https://code.wildfiregames.com/D4165 This was SVN commit r25794.
This commit is contained in:
parent
08400276e1
commit
6b493aa52c
@ -28,6 +28,7 @@
|
||||
#include "graphics/Terrain.h"
|
||||
#include "lib/ogl.h"
|
||||
#include "maths/MathUtil.h"
|
||||
#include "maths/Vector2D.h"
|
||||
#include "maths/Vector4D.h"
|
||||
#include "ps/Game.h"
|
||||
#include "ps/World.h"
|
||||
@ -166,7 +167,29 @@ float CCamera::GetAspectRatio() const
|
||||
|
||||
void CCamera::GetViewQuad(float dist, Quad& quad) const
|
||||
{
|
||||
ENSURE(m_ProjType == ProjectionType::PERSPECTIVE || m_ProjType == ProjectionType::ORTHO);
|
||||
if (m_ProjType == ProjectionType::CUSTOM)
|
||||
{
|
||||
const CMatrix3D invProjection = m_ProjMat.GetInverse();
|
||||
const std::array<CVector2D, 4> ndcCorners = {
|
||||
CVector2D{-1.0f, -1.0f}, CVector2D{1.0f, -1.0f},
|
||||
CVector2D{1.0f, 1.0f}, CVector2D{-1.0f, 1.0f}};
|
||||
for (size_t idx = 0; idx < 4; ++idx)
|
||||
{
|
||||
const CVector2D& corner = ndcCorners[idx];
|
||||
CVector4D nearCorner =
|
||||
invProjection.Transform(CVector4D(corner.X, corner.Y, -1.0f, 1.0f));
|
||||
nearCorner /= nearCorner.W;
|
||||
CVector4D farCorner =
|
||||
invProjection.Transform(CVector4D(corner.X, corner.Y, 1.0f, 1.0f));
|
||||
farCorner /= farCorner.W;
|
||||
const float t = (dist - nearCorner.Z) / (farCorner.Z - nearCorner.Z);
|
||||
const CVector4D quadCorner = nearCorner * (1.0 - t) + farCorner * t;
|
||||
quad[idx].X = quadCorner.X;
|
||||
quad[idx].Y = quadCorner.Y;
|
||||
quad[idx].Z = quadCorner.Z;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const float y = m_ProjType == ProjectionType::PERSPECTIVE ? dist * tanf(m_FOV * 0.5f) : m_OrthoScale * 0.5f;
|
||||
const float x = y * GetAspectRatio();
|
||||
|
@ -284,6 +284,46 @@ public:
|
||||
CompareQuadsInWorldSpace(camera, farQuad, expectedWorldSpaceFarQuad);
|
||||
}
|
||||
|
||||
void test_custom_plane_points()
|
||||
{
|
||||
SViewPort viewPort;
|
||||
viewPort.m_X = 0;
|
||||
viewPort.m_Y = 0;
|
||||
viewPort.m_Width = 512;
|
||||
viewPort.m_Height = 512;
|
||||
|
||||
CCamera camera;
|
||||
camera.SetViewPort(viewPort);
|
||||
camera.LookAt(
|
||||
CVector3D(10.0f, 20.0f, 10.0f),
|
||||
CVector3D(10.0f, 10.0f, 20.0f),
|
||||
CVector3D(0.0f, 1.0f, 1.0f).Normalized()
|
||||
);
|
||||
|
||||
CCamera cameraPerspective = camera;
|
||||
cameraPerspective.SetPerspectiveProjection(1.0f, 101.0f, DEGTORAD(90.0f));
|
||||
|
||||
CMatrix3D projection;
|
||||
projection.SetPerspective(
|
||||
cameraPerspective.GetFOV(), cameraPerspective.GetAspectRatio(),
|
||||
cameraPerspective.GetNearPlane(), cameraPerspective.GetFarPlane());
|
||||
camera.SetProjection(projection);
|
||||
|
||||
const std::vector<float> distances = {
|
||||
cameraPerspective.GetNearPlane(),
|
||||
(cameraPerspective.GetNearPlane() + cameraPerspective.GetFarPlane()) / 2.0f,
|
||||
cameraPerspective.GetFarPlane()
|
||||
};
|
||||
|
||||
CCamera::Quad quad, expectedQuad;
|
||||
for (const float distance : distances)
|
||||
{
|
||||
camera.GetViewQuad(distance, quad);
|
||||
cameraPerspective.GetViewQuad(distance, expectedQuad);
|
||||
CompareQuads(quad, expectedQuad);
|
||||
}
|
||||
}
|
||||
|
||||
void test_perspective_screen_rays()
|
||||
{
|
||||
const float EPS = 1e-4f;
|
||||
|
Loading…
Reference in New Issue
Block a user