Skip to content

Commit

Permalink
#5382: Add PatchControlIterator tests
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Dec 6, 2020
1 parent 24fbf89 commit efb4ecf
Show file tree
Hide file tree
Showing 4 changed files with 246 additions and 0 deletions.
2 changes: 2 additions & 0 deletions test/Makefile.am
Expand Up @@ -41,6 +41,8 @@ drtest_SOURCES = math/Matrix4.cpp \
Models.cpp \
ModelExport.cpp \
ModelScale.cpp \
PatchIterators.cpp \
PatchWelding.cpp \
Selection.cpp \
SelectionAlgorithm.cpp \
VFS.cpp
242 changes: 242 additions & 0 deletions test/PatchIterators.cpp
@@ -0,0 +1,242 @@
#include "RadiantTest.h"

#include "imap.h"
#include "ipatch.h"
#include "patch/PatchIterators.h"

namespace test
{

using PatchIteratorTest = RadiantTest;

namespace
{

// Patch will be parallel to the XY plane, its vertex coordinates x = col*64 and y = row*64
inline IPatchNodePtr createWorldspawnPatch(std::size_t width, std::size_t height)
{
auto world = GlobalMapModule().findOrInsertWorldspawn();

auto sceneNode = GlobalPatchModule().createPatch(patch::PatchDefType::Def2);
auto patchNode = std::dynamic_pointer_cast<IPatchNode>(sceneNode);

world->addChildNode(sceneNode);

auto& patch = patchNode->getPatch();

patch.setDims(width, height);

for (auto row = 0; row < height; ++row)
{
for (auto col = 0; col < width; ++col)
{
patch.ctrlAt(row, col).vertex.set(col * 64, row * 64, 0);
patch.ctrlAt(row, col).texcoord[0] = col * 1.0 / (width - 1.0);
patch.ctrlAt(row, col).texcoord[1] = row * 1.0 / (height - 1.0);
}
}

patch.controlPointsChanged();

return patchNode;
}

}

TEST_F(PatchIteratorTest, IterateOverWholePatchColumnWise)
{
auto patch = createWorldspawnPatch(3, 5);

std::vector<Vector3> expectedValues;

// Fill the vector with the expected values
for (auto col = 0; col < patch->getPatch().getWidth(); ++col)
{
for (auto row = 0; row < patch->getPatch().getHeight(); ++row)
{
expectedValues.push_back(patch->getPatch().ctrlAt(row, col).vertex);
}
}

patch::ColumnWisePatchIterator it(patch->getPatch());
auto expected = expectedValues.begin();

while (it.isValid())
{
EXPECT_EQ((it++)->vertex, *(expected++));
}

EXPECT_EQ(expected, expectedValues.end()); // assume no underflow
}

TEST_F(PatchIteratorTest, IterateOverWholePatchRowWise)
{
auto patch = createWorldspawnPatch(3, 5);

std::vector<Vector3> expectedValues;

// Fill the vector with the expected values
for (auto row = 0; row < patch->getPatch().getHeight(); ++row)
{
for (auto col = 0; col < patch->getPatch().getWidth(); ++col)
{
expectedValues.push_back(patch->getPatch().ctrlAt(row, col).vertex);
}
}

patch::RowWisePatchIterator it(patch->getPatch());
auto expected = expectedValues.begin();

while (it.isValid())
{
EXPECT_EQ((it++)->vertex, *(expected++));
}

EXPECT_EQ(expected, expectedValues.end()); // assume no underflow
}

void iterateOverPartialPatchColumnWise(IPatch& patch, std::size_t startCol, std::size_t endCol)
{
std::vector<Vector3> expectedValues;

// Fill the vector with the expected values
for (auto col = startCol; col <= endCol; ++col)
{
for (auto row = 0; row < patch.getHeight(); ++row)
{
expectedValues.push_back(patch.ctrlAt(row, col).vertex);
}
}

patch::ColumnWisePatchIterator it(patch, startCol, endCol);
auto expected = expectedValues.begin();

while (it.isValid())
{
EXPECT_EQ((it++)->vertex, *(expected++));
}

EXPECT_EQ(expected, expectedValues.end()); // assume no underflow
}

TEST_F(PatchIteratorTest, IterateOverPartialPatchColumnWise)
{
auto patch = createWorldspawnPatch(5, 7);

// Try various start and end column configs
iterateOverPartialPatchColumnWise(patch->getPatch(), 0, 4);
iterateOverPartialPatchColumnWise(patch->getPatch(), 0, 3);
iterateOverPartialPatchColumnWise(patch->getPatch(), 0, 0);
iterateOverPartialPatchColumnWise(patch->getPatch(), 0, 4);
iterateOverPartialPatchColumnWise(patch->getPatch(), 3, 4);
iterateOverPartialPatchColumnWise(patch->getPatch(), 1, 3);
iterateOverPartialPatchColumnWise(patch->getPatch(), 4, 4);
iterateOverPartialPatchColumnWise(patch->getPatch(), 3, 4);
}

void iterateOverPartialPatchRowWise(IPatch& patch, std::size_t startRow, std::size_t endRow)
{
std::vector<Vector3> expectedValues;

// Fill the vector with the expected values
for (auto row = startRow; row <= endRow; ++row)
{
for (auto col = 0; col < patch.getWidth(); ++col)
{
expectedValues.push_back(patch.ctrlAt(row, col).vertex);
}
}

patch::RowWisePatchIterator it(patch, startRow, endRow);
auto expected = expectedValues.begin();

while (it.isValid())
{
EXPECT_EQ((it++)->vertex, *(expected++));
}

EXPECT_EQ(expected, expectedValues.end()); // assume no underflow
}

TEST_F(PatchIteratorTest, IterateOverPartialPatchRowWise)
{
auto patch = createWorldspawnPatch(5, 7);

// Try various start and end column configs
iterateOverPartialPatchRowWise(patch->getPatch(), 0, 6);
iterateOverPartialPatchRowWise(patch->getPatch(), 0, 3);
iterateOverPartialPatchRowWise(patch->getPatch(), 0, 0);
iterateOverPartialPatchRowWise(patch->getPatch(), 0, 4);
iterateOverPartialPatchRowWise(patch->getPatch(), 3, 6);
iterateOverPartialPatchRowWise(patch->getPatch(), 1, 3);
iterateOverPartialPatchRowWise(patch->getPatch(), 6, 6);
iterateOverPartialPatchRowWise(patch->getPatch(), 3, 4);
}

void iterateOverSingleColum(IPatch& patch, std::size_t colToTest)
{
std::vector<Vector3> expectedValues;

// Fill the vector with the expected values
for (auto row = 0; row < patch.getHeight(); ++row)
{
expectedValues.push_back(patch.ctrlAt(row, colToTest).vertex);
}

patch::SinglePatchColumnIterator it(patch, colToTest);
auto expected = expectedValues.begin();

while (it.isValid())
{
EXPECT_EQ((it++)->vertex, *(expected++));
}

EXPECT_EQ(expected, expectedValues.end()); // assume no underflow
}

TEST_F(PatchIteratorTest, IterateOverSingleColumn)
{
auto patch = createWorldspawnPatch(5, 7);

iterateOverSingleColum(patch->getPatch(), 0);
iterateOverSingleColum(patch->getPatch(), 1);
iterateOverSingleColum(patch->getPatch(), 2);
iterateOverSingleColum(patch->getPatch(), 3);
iterateOverSingleColum(patch->getPatch(), 4);
}

void iterateOverSingleRow(IPatch& patch, std::size_t rowToTest)
{
std::vector<Vector3> expectedValues;

// Fill the vector with the expected values
for (auto col = 0; col < patch.getWidth(); ++col)
{
expectedValues.push_back(patch.ctrlAt(rowToTest, col).vertex);
}

patch::SinglePatchRowIterator it(patch, rowToTest);
auto expected = expectedValues.begin();

while (it.isValid())
{
EXPECT_EQ((it++)->vertex, *(expected++));
}

EXPECT_EQ(expected, expectedValues.end()); // assume no underflow
}

TEST_F(PatchIteratorTest, IterateOverSingleRow)
{
auto patch = createWorldspawnPatch(5, 7);

iterateOverSingleRow(patch->getPatch(), 0);
iterateOverSingleRow(patch->getPatch(), 1);
iterateOverSingleRow(patch->getPatch(), 2);
iterateOverSingleRow(patch->getPatch(), 3);
iterateOverSingleRow(patch->getPatch(), 4);
iterateOverSingleRow(patch->getPatch(), 5);
iterateOverSingleRow(patch->getPatch(), 6);
}

}
1 change: 1 addition & 0 deletions tools/msvc/Tests/Tests.vcxproj
Expand Up @@ -85,6 +85,7 @@
<ClCompile Include="..\..\..\test\ModelExport.cpp" />
<ClCompile Include="..\..\..\test\Models.cpp" />
<ClCompile Include="..\..\..\test\ModelScale.cpp" />
<ClCompile Include="..\..\..\test\PatchIterators.cpp" />
<ClCompile Include="..\..\..\test\PatchWelding.cpp" />
<ClCompile Include="..\..\..\test\Selection.cpp" />
<ClCompile Include="..\..\..\test\SelectionAlgorithm.cpp" />
Expand Down
1 change: 1 addition & 0 deletions tools/msvc/Tests/Tests.vcxproj.filters
Expand Up @@ -32,6 +32,7 @@
<ClCompile Include="..\..\..\test\ColourSchemes.cpp" />
<ClCompile Include="..\..\..\test\WorldspawnColour.cpp" />
<ClCompile Include="..\..\..\test\PatchWelding.cpp" />
<ClCompile Include="..\..\..\test\PatchIterators.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\test\HeadlessOpenGLContext.h" />
Expand Down

0 comments on commit efb4ecf

Please sign in to comment.