diff --git a/source/graphics/tests/test_Camera.h b/source/graphics/tests/test_Camera.h index 3cd9173d5e..f71ac63900 100644 --- a/source/graphics/tests/test_Camera.h +++ b/source/graphics/tests/test_Camera.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 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 @@ -126,18 +126,32 @@ public: std::fabs(p1.m_Norm.Z - p2.m_Norm.Z) < EPS; } - void CompareQuads(const CCamera::Quad& quad, const CCamera::Quad& expected_quad) + void CompareQuads(const CCamera::Quad& quad, const CCamera::Quad& expectedQuad) { const float EPS = 1e-4f; - for (size_t index = 0; index < expected_quad.size(); ++index) + for (size_t index = 0; index < expectedQuad.size(); ++index) { - TS_ASSERT_DELTA(quad[index].X, expected_quad[index].X, EPS); - TS_ASSERT_DELTA(quad[index].Y, expected_quad[index].Y, EPS); - TS_ASSERT_DELTA(quad[index].Z, expected_quad[index].Z, EPS); + TS_ASSERT_DELTA(quad[index].X, expectedQuad[index].X, EPS); + TS_ASSERT_DELTA(quad[index].Y, expectedQuad[index].Y, EPS); + TS_ASSERT_DELTA(quad[index].Z, expectedQuad[index].Z, EPS); } } - void test_persepctive_plane_points() + void CompareQuadsInWorldSpace(const CCamera& camera, const CCamera::Quad& quad, const CCamera::Quad& expectedQuad) + { + const float EPS = 1e-4f; + for (size_t index = 0; index < expectedQuad.size(); ++index) + { + // Transform quad points from camera space to world space. + CVector3D point = camera.GetOrientation().Transform(quad[index]); + + TS_ASSERT_DELTA(point.X, expectedQuad[index].X, EPS); + TS_ASSERT_DELTA(point.Y, expectedQuad[index].Y, EPS); + TS_ASSERT_DELTA(point.Z, expectedQuad[index].Z, EPS); + } + } + + void test_perspective_plane_points() { SViewPort viewPort; viewPort.m_X = 0; @@ -147,12 +161,11 @@ public: CCamera camera; camera.SetViewPort(viewPort); - camera.LookAlong( - CVector3D(0.0f, 0.0f, 0.0f), - CVector3D(0.0f, 0.0f, 1.0f), - CVector3D(0.0f, 1.0f, 0.0f) + 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.m_Orientation.SetTranslation(CVector3D(1.0f, 2.0f, 3.0f)); camera.SetPerspectiveProjection(1.0f, 101.0f, DEGTORAD(90.0f)); CCamera::Quad quad; @@ -163,6 +176,25 @@ public: for (const CVector3D& point : quad) TS_ASSERT_EQUALS(point, CVector3D(0.0f, 0.0f, 0.0f)); + // Points lying on the near plane. + CCamera::Quad expectedNearQuad = { + CVector3D(-1.0f, -1.0f, 1.0f), + CVector3D(1.0f, -1.0f, 1.0f), + CVector3D(1.0f, 1.0f, 1.0f), + CVector3D(-1.0f, 1.0f, 1.0f) + }; + CCamera::Quad nearQuad; + camera.GetViewQuad(camera.GetNearPlane(), nearQuad); + CompareQuads(nearQuad, expectedNearQuad); + + CCamera::Quad expectedWorldSpaceNearQuad = { + CVector3D(9.0f, 18.5857868f, 10.0f), + CVector3D(11.0f, 18.5857868f, 10.0f), + CVector3D(11.0f, 20.0f, 11.4142132f), + CVector3D(9.0f, 20.0f, 11.4142132f) + }; + CompareQuadsInWorldSpace(camera, nearQuad, expectedWorldSpaceNearQuad); + // Points lying on the far plane. CCamera::Quad expectedFarQuad = { CVector3D(-101.0f, -101.0f, 101.0f), @@ -170,7 +202,16 @@ public: CVector3D(101.0f, 101.0f, 101.0f), CVector3D(-101.0f, 101.0f, 101.0f) }; - camera.GetViewQuad(camera.GetFarPlane(), quad); - CompareQuads(quad, expectedFarQuad); + CCamera::Quad farQuad; + camera.GetViewQuad(camera.GetFarPlane(), farQuad); + CompareQuads(farQuad, expectedFarQuad); + + CCamera::Quad expectedWorldSpaceFarQuad = { + CVector3D(-91.0000153f, -122.8355865f, 10.0f), + CVector3D(111.0000153f, -122.8355865f, 10.0f), + CVector3D(111.0000153f, 20.0f, 152.8355865f), + CVector3D(-91.0000153f, 20.0f, 152.8355865f) + }; + CompareQuadsInWorldSpace(camera, farQuad, expectedWorldSpaceFarQuad); } }; diff --git a/source/maths/Vector3D.h b/source/maths/Vector3D.h index fe2b0fb6f7..cc2462a7eb 100644 --- a/source/maths/Vector3D.h +++ b/source/maths/Vector3D.h @@ -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 @@ -99,27 +99,26 @@ class CVector3D return CVector3D(-X, -Y, -Z); } - public: - float Dot (const CVector3D &vector) const + float Dot(const CVector3D& vector) const { return ( X * vector.X + Y * vector.Y + Z * vector.Z ); } - CVector3D Cross (const CVector3D &vector) const + CVector3D Cross(const CVector3D& vector) const { - CVector3D Temp; - Temp.X = (Y * vector.Z) - (Z * vector.Y); - Temp.Y = (Z * vector.X) - (X * vector.Z); - Temp.Z = (X * vector.Y) - (Y * vector.X); - return Temp; + CVector3D temp; + temp.X = (Y * vector.Z) - (Z * vector.Y); + temp.Y = (Z * vector.X) - (X * vector.Z); + temp.Z = (X * vector.Y) - (Y * vector.X); + return temp; } - float Length () const; - float LengthSquared () const; - void Normalize (); - CVector3D Normalized () const; + float Length() const; + float LengthSquared() const; + void Normalize(); + CVector3D Normalized() const; // Returns 3 element array of floats, e.g. for glVertex3fv const float* GetFloatArray() const { return &X; }