forked from mirrors/0ad
Adds more detailed test for perspective camera projection and its corners in world space.
Cleanups CVector3D a little bit. This was SVN commit r25066.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
+12
-13
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user