Skip to content

Commit

Permalink
#5456: Basic unit tests checking the things that got implemented in t…
Browse files Browse the repository at this point in the history
…his feature request.
  • Loading branch information
codereader committed Jan 22, 2021
1 parent 408fa40 commit c0d0fd0
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 0 deletions.
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Expand Up @@ -22,6 +22,7 @@ add_executable(drtest
Models.cpp
PatchIterators.cpp
PatchWelding.cpp
Prefabs.cpp
SelectionAlgorithm.cpp
Selection.cpp
VFS.cpp
Expand Down
99 changes: 99 additions & 0 deletions test/Prefabs.cpp
@@ -0,0 +1,99 @@
#include "RadiantTest.h"

#include "icommandsystem.h"
#include "ispeakernode.h"
#include "ilightnode.h"
#include "ibrush.h"
#include "scene/PrefabBoundsAccumulator.h"
#include "os/path.h"
#include "algorithm/Scene.h"

namespace test
{

class PrefabTest : public RadiantTest
{
protected:
void loadPrefabAtOrigin(const std::string& prefabFolderRelativePath)
{
fs::path prefabPath = _context.getTestProjectPath();
prefabPath /= "prefabs";
prefabPath /= prefabFolderRelativePath;

GlobalCommandSystem().executeCommand("LoadPrefabAt", prefabPath.string(), Vector3(0, 0, 0), 1);
}
};

TEST_F(PrefabTest, LoadPrefabAt)
{
loadPrefabAtOrigin("large_bounds.pfbx");

auto numSpeakers = algorithm::getChildCount(GlobalMapModule().getRoot(), [](const scene::INodePtr& node)
{
return Node_getSpeakerNode(node) != nullptr;
});

auto numLights = algorithm::getChildCount(GlobalMapModule().getRoot(), [](const scene::INodePtr& node)
{
return Node_getLightNode(node) != nullptr;
});

auto numBrushes = algorithm::getChildCount(GlobalMapModule().getWorldspawn(), [](const scene::INodePtr& node)
{
return Node_getIBrush(node) != nullptr;
});

EXPECT_EQ(numSpeakers, 1);
EXPECT_EQ(numLights, 1);
EXPECT_EQ(numBrushes, 1);
}

TEST_F(PrefabTest, PrefabBoundsCalculation)
{
loadPrefabAtOrigin("large_bounds.pfbx");

EXPECT_NE(GlobalSelectionSystem().countSelected(), 0);

scene::PrefabBoundsAccumulator accumulator;
GlobalSelectionSystem().foreachSelected(accumulator);

// Speaker and light bounds should not influence the prefab bounds
EXPECT_EQ(accumulator.getBounds().getExtents(), Vector3(32, 16, 64));
}

TEST_F(PrefabTest, PrefabBoundsAccumulatorGetNodeBounds)
{
loadPrefabAtOrigin("large_bounds.pfbx");

// Prefab bounds calculation should ignore the speaker radius
auto speaker = algorithm::getEntityByName(GlobalMapModule().getRoot(), "speaker_1");
auto bounds = scene::PrefabBoundsAccumulator::GetNodeBounds(speaker);
EXPECT_EQ(bounds.getExtents(), Vector3(8, 8, 8));

// Prefab bounds calculation should ignore the light volume
auto light = algorithm::getEntityByName(GlobalMapModule().getRoot(), "light_1");
bounds = scene::PrefabBoundsAccumulator::GetNodeBounds(light);
EXPECT_EQ(bounds.getExtents(), Vector3(8, 8, 8));
}

TEST_F(PrefabTest, PrefabInsertPosition)
{
// The saved prefab is slightly off-center at 128 0 0
// When inserting it at 0,0,0 the insertion code should compensate the offset

fs::path prefabPath = _context.getTestProjectPath();
prefabPath /= "prefabs/large_bounds.pfbx";

GlobalCommandSystem().executeCommand("LoadPrefabAt", prefabPath.string(), Vector3(0, 0, 0), 1);

auto speaker = algorithm::getEntityByName(GlobalMapModule().getRoot(), "speaker_1");
EXPECT_EQ(speaker->worldAABB().getOrigin(), Vector3(0, 0, 0));

auto light = algorithm::getEntityByName(GlobalMapModule().getRoot(), "light_1");
EXPECT_EQ(light->worldAABB().getOrigin(), Vector3(0, 0, 0));

auto brush = algorithm::findFirstBrushWithMaterial(GlobalMapModule().getWorldspawn(), "textures/common/caulk");
EXPECT_EQ(brush->worldAABB().getOrigin(), Vector3(0, 0, 0));
}

}
9 changes: 9 additions & 0 deletions test/resources/tdm/def/speaker.def
@@ -0,0 +1,9 @@
entityDef speaker
{
"editor_color" "0 1 0"
"editor_mins" "-8 -8 -8"
"editor_maxs" "8 8 8"

"editor_displayFolder" "Sound"
"spawnclass" "idSound"
}
100 changes: 100 additions & 0 deletions test/resources/tdm/prefabs/large_bounds.pfbx
@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<map version="1" format="portable">
<layers>
<layer id="0" name="Default"/>
</layers>
<selectionGroups/>
<selectionSets/>
<properties>
<property key="EditTimeInSeconds" value="170"/>
<property key="LastCameraAngle" value="0 0 0"/>
<property key="LastCameraPosition" value="0 0 0"/>
</properties>
<entity number="0">
<primitives>
<brush number="0">
<faces>
<face>
<plane x="0" y="0" z="1.000000" d="-64.000000"/>
<textureProjection xx="0.031250" yx="0" tx="0" xy="0" yy="0.031250" ty="0"/>
<material name="textures/common/caulk"/>
<contentsFlag value="0"/>
</face>
<face>
<plane x="0" y="1.000000" z="0" d="-16.000000"/>
<textureProjection xx="0.031250" yx="0" tx="0" xy="0" yy="0.031250" ty="0"/>
<material name="textures/common/caulk"/>
<contentsFlag value="0"/>
</face>
<face>
<plane x="1.000000" y="0" z="0" d="-160.000000"/>
<textureProjection xx="0.031250" yx="0" tx="0" xy="0" yy="0.031250" ty="0"/>
<material name="textures/common/caulk"/>
<contentsFlag value="0"/>
</face>
<face>
<plane x="0" y="0" z="-1.000000" d="-64.000000"/>
<textureProjection xx="0.031250" yx="0" tx="0" xy="0" yy="0.031250" ty="0"/>
<material name="textures/common/caulk"/>
<contentsFlag value="0"/>
</face>
<face>
<plane x="0" y="-1.000000" z="0" d="-16.000000"/>
<textureProjection xx="0.031250" yx="0" tx="0" xy="0" yy="0.031250" ty="0"/>
<material name="textures/common/caulk"/>
<contentsFlag value="0"/>
</face>
<face>
<plane x="-1.000000" y="0" z="0" d="96.000000"/>
<textureProjection xx="0.031250" yx="0" tx="0" xy="0" yy="0.031250" ty="0"/>
<material name="textures/common/caulk"/>
<contentsFlag value="0"/>
</face>
</faces>
<layers>
<layer id="0"/>
</layers>
<selectionGroups/>
<selectionSets/>
</brush>
</primitives>
<keyValues>
<keyValue key="classname" value="worldspawn"/>
</keyValues>
<layers>
<layer id="0"/>
</layers>
<selectionGroups/>
<selectionSets/>
</entity>
<entity number="1">
<primitives/>
<keyValues>
<keyValue key="classname" value="speaker"/>
<keyValue key="name" value="speaker_1"/>
<keyValue key="origin" value="128 0 0"/>
<keyValue key="s_shader" value="arrow_broadhead_wood"/>
<keyValue key="s_maxdistance" value="19.347200"/>
</keyValues>
<layers>
<layer id="0"/>
</layers>
<selectionGroups/>
<selectionSets/>
</entity>
<entity number="2">
<primitives/>
<keyValues>
<keyValue key="classname" value="light"/>
<keyValue key="name" value="light_1"/>
<keyValue key="origin" value="128 0 0"/>
<keyValue key="light_center" value="0 0 0"/>
<keyValue key="light_radius" value="592 320 320"/>
</keyValues>
<layers>
<layer id="0"/>
</layers>
<selectionGroups/>
<selectionSets/>
</entity>
</map>
1 change: 1 addition & 0 deletions tools/msvc/Tests/Tests.vcxproj
Expand Up @@ -91,6 +91,7 @@
<ClCompile Include="..\..\..\test\ModelScale.cpp" />
<ClCompile Include="..\..\..\test\PatchIterators.cpp" />
<ClCompile Include="..\..\..\test\PatchWelding.cpp" />
<ClCompile Include="..\..\..\test\Prefabs.cpp" />
<ClCompile Include="..\..\..\test\Selection.cpp" />
<ClCompile Include="..\..\..\test\SelectionAlgorithm.cpp" />
<ClCompile Include="..\..\..\test\VFS.cpp" />
Expand Down
1 change: 1 addition & 0 deletions tools/msvc/Tests/Tests.vcxproj.filters
Expand Up @@ -36,6 +36,7 @@
<ClCompile Include="..\..\..\test\ImageLoading.cpp" />
<ClCompile Include="..\..\..\test\LayerManipulation.cpp" />
<ClCompile Include="..\..\..\test\Favourites.cpp" />
<ClCompile Include="..\..\..\test\Prefabs.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\test\HeadlessOpenGLContext.h" />
Expand Down

0 comments on commit c0d0fd0

Please sign in to comment.