Adds ortho projection type and its test.
This was SVN commit r25073.
This commit is contained in:
parent
e7612e8fed
commit
92f94e25c6
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -35,7 +35,6 @@
|
||||
#include "renderer/WaterManager.h"
|
||||
|
||||
CCamera::CCamera()
|
||||
: m_NearPlane(0.0f), m_FarPlane(0.0f), m_FOV(0.0f), m_ProjType(CUSTOM)
|
||||
{
|
||||
// Set viewport to something anything should handle, but should be initialised
|
||||
// to window size before use.
|
||||
@ -49,7 +48,7 @@ CCamera::~CCamera() = default;
|
||||
|
||||
void CCamera::SetProjection(const CMatrix3D& matrix)
|
||||
{
|
||||
m_ProjType = CUSTOM;
|
||||
m_ProjType = ProjectionType::CUSTOM;
|
||||
m_ProjMat = matrix;
|
||||
}
|
||||
|
||||
@ -58,16 +57,32 @@ void CCamera::SetProjectionFromCamera(const CCamera& camera)
|
||||
m_ProjType = camera.m_ProjType;
|
||||
m_NearPlane = camera.m_NearPlane;
|
||||
m_FarPlane = camera.m_FarPlane;
|
||||
if (m_ProjType == PERSPECTIVE)
|
||||
if (m_ProjType == ProjectionType::PERSPECTIVE)
|
||||
{
|
||||
m_FOV = camera.m_FOV;
|
||||
}
|
||||
else if (m_ProjType == ProjectionType::ORTHO)
|
||||
{
|
||||
m_OrthoScale = camera.m_OrthoScale;
|
||||
}
|
||||
m_ProjMat = camera.m_ProjMat;
|
||||
}
|
||||
|
||||
void CCamera::SetOrthoProjection(float nearp, float farp, float scale)
|
||||
{
|
||||
m_ProjType = ProjectionType::ORTHO;
|
||||
m_NearPlane = nearp;
|
||||
m_FarPlane = farp;
|
||||
m_OrthoScale = scale;
|
||||
|
||||
const float halfHeight = 0.5f * m_OrthoScale;
|
||||
const float halfWidth = halfHeight * GetAspectRatio();
|
||||
m_ProjMat.SetOrtho(-halfWidth, halfWidth, -halfHeight, halfHeight, m_NearPlane, m_FarPlane);
|
||||
}
|
||||
|
||||
void CCamera::SetPerspectiveProjection(float nearp, float farp, float fov)
|
||||
{
|
||||
m_ProjType = PERSPECTIVE;
|
||||
m_ProjType = ProjectionType::PERSPECTIVE;
|
||||
m_NearPlane = nearp;
|
||||
m_FarPlane = farp;
|
||||
m_FOV = fov;
|
||||
@ -151,8 +166,9 @@ float CCamera::GetAspectRatio() const
|
||||
|
||||
void CCamera::GetViewQuad(float dist, Quad& quad) const
|
||||
{
|
||||
ENSURE(m_ProjType == PERSPECTIVE);
|
||||
const float y = dist * tanf(m_FOV * 0.5f);
|
||||
ENSURE(m_ProjType == ProjectionType::PERSPECTIVE || m_ProjType == ProjectionType::ORTHO);
|
||||
|
||||
const float y = m_ProjType == ProjectionType::PERSPECTIVE ? dist * tanf(m_FOV * 0.5f) : m_OrthoScale * 0.5f;
|
||||
const float x = y * GetAspectRatio();
|
||||
|
||||
quad[0].X = -x;
|
||||
@ -214,7 +230,6 @@ CVector3D CCamera::GetWorldCoordinates(int px, int py, bool aboveWater) const
|
||||
|
||||
BuildCameraRay(px, py, origin, dir);
|
||||
|
||||
|
||||
bool gotTerrain = tracer.RayIntersect(origin, dir, x, z, terrainPoint);
|
||||
|
||||
if (!aboveWater)
|
||||
@ -351,9 +366,9 @@ CVector3D CCamera::GetFocus() const
|
||||
}
|
||||
}
|
||||
|
||||
void CCamera::LookAt(const CVector3D& camera, const CVector3D& target, const CVector3D& up)
|
||||
void CCamera::LookAt(const CVector3D& camera, const CVector3D& focus, const CVector3D& up)
|
||||
{
|
||||
CVector3D delta = target - camera;
|
||||
CVector3D delta = focus - camera;
|
||||
LookAlong(camera, delta, up);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -44,9 +44,10 @@ class CCamera
|
||||
// Represents camera viewport or frustum side in 3D space.
|
||||
using Quad = std::array<CVector3D, 4>;
|
||||
|
||||
enum ProjectionType
|
||||
enum class ProjectionType
|
||||
{
|
||||
CUSTOM,
|
||||
ORTHO,
|
||||
PERSPECTIVE,
|
||||
};
|
||||
|
||||
@ -58,6 +59,7 @@ class CCamera
|
||||
CMatrix3D GetViewProjection() const { return m_ProjMat * m_Orientation.GetInverse(); }
|
||||
void SetProjection(const CMatrix3D& matrix);
|
||||
void SetProjectionFromCamera(const CCamera& camera);
|
||||
void SetOrthoProjection(float nearp, float farp, float scale);
|
||||
void SetPerspectiveProjection(float nearp, float farp, float fov);
|
||||
ProjectionType GetProjectionType() const { return m_ProjType; }
|
||||
|
||||
@ -78,6 +80,7 @@ class CCamera
|
||||
float GetNearPlane() const { return m_NearPlane; }
|
||||
float GetFarPlane() const { return m_FarPlane; }
|
||||
float GetFOV() const { return m_FOV; }
|
||||
float GetOrthoScale() const { return m_OrthoScale; }
|
||||
|
||||
// Returns a quad of view in camera space at given distance from camera.
|
||||
void GetViewQuad(float dist, Quad& quad) const;
|
||||
@ -102,10 +105,10 @@ class CCamera
|
||||
CVector3D GetFocus() const;
|
||||
|
||||
// Build an orientation matrix from camera position, camera focus point, and up-vector
|
||||
void LookAt(const CVector3D& camera, const CVector3D& orientation, const CVector3D& up);
|
||||
void LookAt(const CVector3D& camera, const CVector3D& focus, const CVector3D& up);
|
||||
|
||||
// Build an orientation matrix from camera position, camera orientation, and up-vector
|
||||
void LookAlong(const CVector3D& camera, CVector3D focus, CVector3D up);
|
||||
void LookAlong(const CVector3D& camera, CVector3D orientation, CVector3D up);
|
||||
|
||||
/**
|
||||
* Render: Renders the camera's frustum in world space.
|
||||
@ -123,15 +126,18 @@ class CCamera
|
||||
|
||||
private:
|
||||
CMatrix3D m_ProjMat;
|
||||
ProjectionType m_ProjType;
|
||||
ProjectionType m_ProjType = ProjectionType::CUSTOM;
|
||||
|
||||
float m_NearPlane = 0.0f;
|
||||
float m_FarPlane = 0.0f;
|
||||
union
|
||||
{
|
||||
float m_FOV;
|
||||
float m_OrthoScale;
|
||||
};
|
||||
SViewPort m_ViewPort;
|
||||
|
||||
float m_NearPlane;
|
||||
float m_FarPlane;
|
||||
float m_FOV;
|
||||
SViewPort m_ViewPort;
|
||||
|
||||
CFrustum m_ViewFrustum;
|
||||
CFrustum m_ViewFrustum;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CAMERA
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
CVector3D(0.0f, 1.0f, 0.0f)
|
||||
);
|
||||
camera.SetPerspectiveProjection(1.0f, 101.0f, DEGTORAD(90.0f));
|
||||
TS_ASSERT_EQUALS(camera.GetProjectionType(), CCamera::PERSPECTIVE);
|
||||
TS_ASSERT_EQUALS(camera.GetProjectionType(), CCamera::ProjectionType::PERSPECTIVE);
|
||||
camera.UpdateFrustum();
|
||||
|
||||
const float sqrt2 = sqrtf(2.0f) / 2.0f;
|
||||
@ -76,7 +76,7 @@ public:
|
||||
CMatrix3D projection;
|
||||
projection.SetOrtho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 10.0f);
|
||||
camera.SetProjection(projection);
|
||||
TS_ASSERT_EQUALS(camera.GetProjectionType(), CCamera::CUSTOM);
|
||||
TS_ASSERT_EQUALS(camera.GetProjectionType(), CCamera::ProjectionType::CUSTOM);
|
||||
camera.UpdateFrustum();
|
||||
|
||||
const std::vector<CPlane> expectedPlanes = {
|
||||
@ -171,7 +171,7 @@ public:
|
||||
CCamera::Quad quad;
|
||||
|
||||
// Zero distance point is the origin of all camera rays,
|
||||
// so all plane points should be stay there.
|
||||
// so all plane points should stay there.
|
||||
camera.GetViewQuad(0.0f, quad);
|
||||
for (const CVector3D& point : quad)
|
||||
TS_ASSERT_EQUALS(point, CVector3D(0.0f, 0.0f, 0.0f));
|
||||
@ -214,4 +214,70 @@ public:
|
||||
};
|
||||
CompareQuadsInWorldSpace(camera, farQuad, expectedWorldSpaceFarQuad);
|
||||
}
|
||||
|
||||
void test_ortho_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()
|
||||
);
|
||||
camera.SetOrthoProjection(2.0f, 128.0f, 10.0f);
|
||||
|
||||
// Zero distance is the origin plane of all camera rays,
|
||||
// so all plane points should stay there.
|
||||
CCamera::Quad quad;
|
||||
camera.GetViewQuad(0.0f, quad);
|
||||
for (const CVector3D& point : quad)
|
||||
{
|
||||
constexpr float EPS = 1e-4f;
|
||||
TS_ASSERT_DELTA(point.Z, 0.0f, EPS);
|
||||
}
|
||||
|
||||
// Points lying on the near plane.
|
||||
CCamera::Quad expectedNearQuad = {
|
||||
CVector3D(-5.0f, -5.0f, 2.0f),
|
||||
CVector3D(5.0f, -5.0f, 2.0f),
|
||||
CVector3D(5.0f, 5.0f, 2.0f),
|
||||
CVector3D(-5.0f, 5.0f, 2.0f)
|
||||
};
|
||||
CCamera::Quad nearQuad;
|
||||
camera.GetViewQuad(camera.GetNearPlane(), nearQuad);
|
||||
CompareQuads(nearQuad, expectedNearQuad);
|
||||
|
||||
CCamera::Quad expectedWorldSpaceNearQuad = {
|
||||
CVector3D(4.9999995f, 15.0502520f, 7.8786793f),
|
||||
CVector3D(15.0f, 15.0502520f, 7.8786793f),
|
||||
CVector3D(15.0f, 22.1213207f, 14.9497480f),
|
||||
CVector3D(4.9999995f, 22.1213207f, 14.9497480f)
|
||||
};
|
||||
CompareQuadsInWorldSpace(camera, nearQuad, expectedWorldSpaceNearQuad);
|
||||
|
||||
// Points lying on the far plane.
|
||||
CCamera::Quad expectedFarQuad = {
|
||||
CVector3D(-5.0f, -5.0f, 128.0f),
|
||||
CVector3D(5.0f, -5.0f, 128.0f),
|
||||
CVector3D(5.0f, 5.0f, 128.0f),
|
||||
CVector3D(-5.0f, 5.0f, 128.0f)
|
||||
};
|
||||
CCamera::Quad farQuad;
|
||||
camera.GetViewQuad(camera.GetFarPlane(), farQuad);
|
||||
CompareQuads(farQuad, expectedFarQuad);
|
||||
|
||||
CCamera::Quad expectedWorldSpaceFarQuad = {
|
||||
CVector3D(4.9999995f, -74.0452118f, 96.9741364f),
|
||||
CVector3D(15.0f, -74.0452118f, 96.9741364f),
|
||||
CVector3D(15.0f, -66.9741364f, 104.0452118f),
|
||||
CVector3D(4.9999995f, -66.9741364f, 104.0452118f)
|
||||
};
|
||||
CompareQuadsInWorldSpace(camera, farQuad, expectedWorldSpaceFarQuad);
|
||||
}
|
||||
};
|
||||
|
@ -389,7 +389,7 @@ void WriteBigScreenshot(const VfsPath& extension, int tiles, int tileWidth, int
|
||||
for (int tile_x = 0; tile_x < tiles; ++tile_x)
|
||||
{
|
||||
// Adjust the camera to render the appropriate region
|
||||
if (oldCamera.GetProjectionType() == CCamera::PERSPECTIVE)
|
||||
if (oldCamera.GetProjectionType() == CCamera::ProjectionType::PERSPECTIVE)
|
||||
{
|
||||
projection.SetPerspectiveTile(oldCamera.GetFOV(), aspectRatio, oldCamera.GetNearPlane(), oldCamera.GetFarPlane(), tiles, tile_x, tile_y);
|
||||
}
|
||||
|
@ -927,7 +927,7 @@ void CRenderer::ComputeReflectionCamera(CCamera& camera, const CBoundingBoxAlign
|
||||
WaterManager& wm = m->waterManager;
|
||||
|
||||
CMatrix3D projection;
|
||||
if (m_ViewCamera.GetProjectionType() == CCamera::PERSPECTIVE)
|
||||
if (m_ViewCamera.GetProjectionType() == CCamera::ProjectionType::PERSPECTIVE)
|
||||
{
|
||||
const float aspectRatio = 1.0f;
|
||||
// Expand fov slightly since ripples can reflect parts of the scene that
|
||||
@ -972,7 +972,7 @@ void CRenderer::ComputeRefractionCamera(CCamera& camera, const CBoundingBoxAlign
|
||||
WaterManager& wm = m->waterManager;
|
||||
|
||||
CMatrix3D projection;
|
||||
if (m_ViewCamera.GetProjectionType() == CCamera::PERSPECTIVE)
|
||||
if (m_ViewCamera.GetProjectionType() == CCamera::ProjectionType::PERSPECTIVE)
|
||||
{
|
||||
const float aspectRatio = 1.0f;
|
||||
// Expand fov slightly since ripples can reflect parts of the scene that
|
||||
|
Loading…
Reference in New Issue
Block a user