Skip to content

Commit

Permalink
#5710: Start constructing some tests to check the legacy Q3 brush imp…
Browse files Browse the repository at this point in the history
…orter code
  • Loading branch information
codereader committed Sep 3, 2021
1 parent 789562a commit 2dfb14f
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 0 deletions.
75 changes: 75 additions & 0 deletions test/Brush.cpp
Expand Up @@ -6,6 +6,9 @@
#include "itransformable.h"
#include "scenelib.h"
#include "math/Quaternion.h"
#include "algorithm/Scene.h"
#include "algorithm/Primitives.h"
#include "math/Vector3.h"

namespace test
{
Expand All @@ -19,6 +22,8 @@ void expectNear(const Plane3& p1, const Plane3& p2, double epsilon)
EXPECT_NEAR(p1.dist(), p2.dist(), epsilon);
}

using Quake3BrushTest = RadiantTest;

class BrushTest: public RadiantTest
{
protected:
Expand Down Expand Up @@ -177,4 +182,74 @@ TEST_F(BrushTest, FacePlaneTranslate)
});
}

inline bool faceHasVertex(const IFace* face, const Vector3& expectedXYZ, const Vector2& expectedUV)
{
return algorithm::faceHasVertex(face, [&](const WindingVertex& vertex)
{
return math::isNear(vertex.vertex, expectedXYZ, 0.01) && math::isNear(vertex.texcoord, expectedUV, 0.01);
});
}

// Load a brush with one vertex at 0,0,0, and an identity shift/scale/rotation texdef
TEST_F(Quake3BrushTest, LoadBrushWithIdentityTexDef)
{
std::string mapPath = "maps/quake3maps/brush_no_transform.map";
GlobalCommandSystem().executeCommand("OpenMap", mapPath);

auto worldspawn = GlobalMapModule().findOrInsertWorldspawn();
EXPECT_EQ(algorithm::getChildCount(worldspawn), 1) << "Scene has not exactly 1 brush";

// Check that we have exactly one brush loaded
auto brushNode = algorithm::findFirstBrushWithMaterial(worldspawn, "textures/a_1024x512");
EXPECT_TRUE(brushNode && brushNode->getNodeType() == scene::INode::Type::Brush) << "Couldn't locate the test brush";

auto face = algorithm::findBrushFaceWithNormal(Node_getIBrush(brushNode), Vector3(0, 0, 1));
EXPECT_TRUE(face != nullptr) << "No brush plane is facing upwards?";

EXPECT_TRUE(faceHasVertex(face, Vector3(64, 0, 64), Vector2(0.0625, 0)));
EXPECT_TRUE(faceHasVertex(face, Vector3( 0, 0, 64), Vector2(0, 0)));
EXPECT_TRUE(faceHasVertex(face, Vector3( 0, 64, 64), Vector2(0, -0.125)));
EXPECT_TRUE(faceHasVertex(face, Vector3(64, 64, 64), Vector2(0.0625, -0.125)));

face = algorithm::findBrushFaceWithNormal(Node_getIBrush(brushNode), Vector3(0, 0, -1));
EXPECT_TRUE(face != nullptr) << "No brush plane is facing down?";

EXPECT_TRUE(faceHasVertex(face, Vector3(0, 0, 0), Vector2(0, 0)));
EXPECT_TRUE(faceHasVertex(face, Vector3(64, 0, 0), Vector2(0.0625, 0)));
EXPECT_TRUE(faceHasVertex(face, Vector3(64, 64, 0), Vector2(0.0625, -0.125)));
EXPECT_TRUE(faceHasVertex(face, Vector3(0, 64, 64), Vector2(0, -0.125)));

face = algorithm::findBrushFaceWithNormal(Node_getIBrush(brushNode), Vector3(0, -1, 0));
EXPECT_TRUE(face != nullptr) << "No brush plane with normal 0,-1,0?";

EXPECT_TRUE(faceHasVertex(face, Vector3(64, 0, 0), Vector2(0.0625, 0)));
EXPECT_TRUE(faceHasVertex(face, Vector3(0, 0, 0), Vector2(0, 0)));
EXPECT_TRUE(faceHasVertex(face, Vector3(0, 64, 64), Vector2(0, -0.125)));
EXPECT_TRUE(faceHasVertex(face, Vector3(64, 0, 64), Vector2(0.0625, -0.125)));

face = algorithm::findBrushFaceWithNormal(Node_getIBrush(brushNode), Vector3(0, 1, 0));
EXPECT_TRUE(face != nullptr) << "No brush plane with normal 0,1,0?";

EXPECT_TRUE(faceHasVertex(face, Vector3(0, 64, 0), Vector2(0, 0)));
EXPECT_TRUE(faceHasVertex(face, Vector3(64, 64, 0), Vector2(0.0625, 0)));
EXPECT_TRUE(faceHasVertex(face, Vector3(64, 64, 64), Vector2(0.0625, -0.125)));
EXPECT_TRUE(faceHasVertex(face, Vector3(0, 64, 64), Vector2(0, -0.125)));

face = algorithm::findBrushFaceWithNormal(Node_getIBrush(brushNode), Vector3(1, 0, 0));
EXPECT_TRUE(face != nullptr) << "No brush plane with normal 1,0,0?";

EXPECT_TRUE(faceHasVertex(face, Vector3(64, 64, 0), Vector2(0.0625, 0)));
EXPECT_TRUE(faceHasVertex(face, Vector3(64, 0, 0), Vector2(0, 0)));
EXPECT_TRUE(faceHasVertex(face, Vector3(64, 0, 64), Vector2(0, -0.125)));
EXPECT_TRUE(faceHasVertex(face, Vector3(64, 64, 64), Vector2(0.0625, -0.125)));

face = algorithm::findBrushFaceWithNormal(Node_getIBrush(brushNode), Vector3(-1, 0, 0));
EXPECT_TRUE(face != nullptr) << "No brush plane with normal -1,0,0?";

EXPECT_TRUE(faceHasVertex(face, Vector3(0, 0, 0), Vector2(0, 0)));
EXPECT_TRUE(faceHasVertex(face, Vector3(0, 64, 0), Vector2(0.0625, 0)));
EXPECT_TRUE(faceHasVertex(face, Vector3(0, 64, 64), Vector2(0.0625, -0.125)));
EXPECT_TRUE(faceHasVertex(face, Vector3(0, 0, 64), Vector2(0, -0.125)));
}

}
30 changes: 30 additions & 0 deletions test/algorithm/Primitives.h
Expand Up @@ -59,6 +59,36 @@ inline scene::INodePtr createCuboidBrush(const scene::INodePtr& parent,
return brushNode;
}

inline const IFace* findBrushFaceWithNormal(const IBrush* brush, const Vector3& normal)
{
for (auto i = 0; brush->getNumFaces(); ++i)
{
const auto& face = brush->getFace(i);

if (math::isNear(face.getPlane3().normal(), normal, 0.01))
{
return &face;
}
}

return nullptr;
}

inline bool faceHasVertex(const IFace* face, const std::function<bool(const WindingVertex&)>& predicate)
{
const auto& winding = face->getWinding();

for (const auto& vertex : winding)
{
if (predicate(vertex))
{
return true;
}
}

return false;
}

}

}
7 changes: 7 additions & 0 deletions test/algorithm/Scene.h
Expand Up @@ -185,4 +185,11 @@ inline std::size_t getChildCount(const scene::INodePtr& parent,
return count;
}

// Returns the number of children of the given parent node
inline std::size_t getChildCount(const scene::INodePtr& parent)
{
return getChildCount(parent, [](const scene::INodePtr&) { return true; });
}


}
13 changes: 13 additions & 0 deletions test/resources/tdm/maps/quake3maps/brush_no_transform.map
@@ -0,0 +1,13 @@
// entity 0
{
"classname" "worldspawn"
// brush 0
{
( 0 208 64 ) ( 0 -16 64 ) ( 0 -16 48 ) a_1024x512 0 0 0 1.000000 1.000000 0 0 0
( 240 64 64 ) ( 0 64 64 ) ( 0 64 48 ) a_1024x512 0 0 0 1.000000 1.000000 0 0 0
( 64 -16 128 ) ( 64 208 128 ) ( 64 208 112 ) a_1024x512 0 0 0 1.000000 1.000000 0 0 0
( 0 0 64 ) ( 240 0 64 ) ( 240 0 48 ) a_1024x512 0 0 0 1.000000 1.000000 0 0 0
( 0 -16 64 ) ( 0 208 64 ) ( 240 208 64 ) a_1024x512 0 0 0 1.000000 1.000000 0 0 0
( 192 208 0 ) ( -48 208 0 ) ( -48 -16 0 ) a_1024x512 0 0 0 1.000000 1.000000 0 0 0
}
}
5 changes: 5 additions & 0 deletions test/resources/tdm/materials/example.mtr
Expand Up @@ -3,3 +3,8 @@ textures/orbweaver/drain_grille
diffusemap textures/darkmod/metal/flat/heavy_rust_pocked01
bumpmap textures/orbweaver/draingrille_n.tga
}

textures/a_1024x512
{
diffusemap textures/a_1024x512
}
Binary file added test/resources/tdm/textures/a_1024x512.tga
Binary file not shown.
10 changes: 10 additions & 0 deletions tools/msvc/natvis/mathlib.natvis
Expand Up @@ -10,4 +10,14 @@
<Item Name="Z">(*((Eigen::PlainObjectBase&lt;Eigen::Matrix&lt;double,3,1,0,3,1&gt; &gt;*)&amp;_v)).m_storage.m_data.array[2]</Item>
</Expand>
</Type>
<Type Name="Matrix4">
<DisplayString>
{(*((Eigen::PlainObjectBase&lt;Eigen::Matrix&lt;double,4,4,0,4,4&gt; &gt;*)&amp;_transform.m_matrix)).m_storage.m_data.array}
</DisplayString>
<Expand>
<Item Name="Data">
(*((Eigen::PlainObjectBase&lt;Eigen::Matrix&lt;double,4,4,0,4,4&gt; &gt;*)&amp;_transform.m_matrix)).m_storage.m_data.array
</Item>
</Expand>
</Type>
</AutoVisualizer>

0 comments on commit 2dfb14f

Please sign in to comment.