diff --git a/test/Selection.cpp b/test/Selection.cpp index 1901a37053..2a03927b93 100644 --- a/test/Selection.cpp +++ b/test/Selection.cpp @@ -7,11 +7,15 @@ #include "ibrush.h" #include "ipatch.h" #include "ientity.h" +#include "ishaders.h" #include "ieclass.h" #include "algorithm/Scene.h" #include "scenelib.h" #include "selectionlib.h" #include "string/convert.h" +#include "render/View.h" +#include "selection/SelectionVolume.h" +#include "Rectangle.h" namespace test { @@ -77,4 +81,100 @@ TEST_F(SelectionTest, LightBoundsChangedAfterRadiusChange) EXPECT_TRUE(GlobalSelectionSystem().getWorkZone().bounds.getExtents().isEqual(changedBounds, 0.01)); } +void constructCenteredXyView(render::View& view, const Vector3& origin) +{ + double scale = 1.0; + + Matrix4 projection; + + projection[0] = 1.0 / static_cast(640 / 2); + projection[5] = 1.0 / static_cast(640 / 2); + projection[10] = 1.0 / (32768 * scale); + + projection[12] = 0.0; + projection[13] = 0.0; + projection[14] = -1.0; + + projection[1] = projection[2] = projection[3] = + projection[4] = projection[6] = projection[7] = + projection[8] = projection[9] = projection[11] = 0.0; + + projection[15] = 1.0f; + + // Modelview + Matrix4 modelView; + + // Translate the view to the center of the brush + modelView[12] = -origin.x() * scale; + modelView[13] = -origin.y() * scale; + modelView[14] = 32768 * scale; + + // axis base + modelView[0] = scale; + modelView[1] = 0; + modelView[2] = 0; + + modelView[4] = 0; + modelView[5] = scale; + modelView[6] = 0; + + modelView[8] = 0; + modelView[9] = 0; + modelView[10] = -scale; + + modelView[3] = modelView[7] = modelView[11] = 0; + modelView[15] = 1; + + view.construct(projection, modelView, 640, 640); +} + +void performSelectionTest(const scene::INodePtr& node) +{ + render::View xyView; + + // Move the orthoview exactly to the center of this object + constructCenteredXyView(xyView, node->worldAABB().origin); + + // Selection Point + auto rectangle = selection::Rectangle::ConstructFromPoint(Vector2(0, 0), Vector2(8.0 / 640, 8.0 / 640)); + ConstructSelectionTest(xyView, rectangle); + + EXPECT_FALSE(Node_isSelected(node)); + + SelectionVolume test(xyView); + GlobalSelectionSystem().selectPoint(test, SelectionSystem::eToggle, false); + + EXPECT_TRUE(Node_isSelected(node)); +} + +void performBrushSelectionTest(const std::string& materialName) +{ + // Filter caulk faces + auto material = GlobalMaterialManager().getMaterialForName("textures/common/caulk"); + material->setVisible(false); + + auto worldspawn = GlobalMapModule().findOrInsertWorldspawn(); + auto brush = algorithm::findFirstBrushWithMaterial(worldspawn, materialName); + EXPECT_TRUE(brush); + + Node_getIBrush(brush)->updateFaceVisibility(); + + performSelectionTest(brush); +} + +TEST_F(SelectionTest, BrushesFacingTowardsXYAreSelectable) +{ + loadMap("selection_test.map"); + + performBrushSelectionTest("textures/numbers/1"); +} + +// #5444: Brushes faces facing away were unselectable in orthoview +TEST_F(SelectionTest, BrushesFacingAwayFromXYAreSelectable) +{ + loadMap("selection_test.map"); + + performBrushSelectionTest("textures/numbers/2"); +} + } diff --git a/test/resources/tdm/maps/selection_test.map b/test/resources/tdm/maps/selection_test.map new file mode 100644 index 0000000000..2526a0b5ca --- /dev/null +++ b/test/resources/tdm/maps/selection_test.map @@ -0,0 +1,55 @@ +Version 2 +// entity 0 +{ +"classname" "worldspawn" +// primitive 0 +{ +brushDef3 +{ +( 0 0 1 -64 ) ( ( 0.03125 0 0 ) ( 0 0.03125 119.75 ) ) "textures/common/caulk" 0 0 0 +( 0 1 0 -80 ) ( ( 0.03125 0 0 ) ( 0 0.03125 0 ) ) "textures/common/caulk" 0 0 0 +( 1 0 0 -272 ) ( ( 0.03125 0 0 ) ( 0 0.03125 0 ) ) "textures/common/caulk" 0 0 0 +( 0 0 -1 -64 ) ( ( 0.03125 0 0 ) ( 0 0.03125 0 ) ) "textures/numbers/2" 0 0 0 +( 0 -1 0 -56 ) ( ( 0.03125 0 0 ) ( 0 0.03125 0 ) ) "textures/common/caulk" 0 0 0 +( -1 0 0 80 ) ( ( 0.03125 0 0 ) ( 0 0.03125 0 ) ) "textures/common/caulk" 0 0 0 +} +} +// primitive 1 +{ +brushDef3 +{ +( 0 0 1 -64 ) ( ( 0.03125 0 0 ) ( 0 0.03125 0 ) ) "textures/numbers/1" 0 0 0 +( 0 1 0 -80 ) ( ( 0.03125 0 8.25 ) ( 0 0.03125 0 ) ) "textures/common/caulk" 0 0 0 +( 1 0 0 -536 ) ( ( 0.03125 0 0 ) ( 0 0.03125 0 ) ) "textures/common/caulk" 0 0 0 +( 0 0 -1 -64 ) ( ( 0.03125 0 0 ) ( 0 0.03125 8.25 ) ) "textures/common/caulk" 0 0 0 +( 0 -1 0 -56 ) ( ( 0.03125 0 119.75 ) ( 0 0.03125 0 ) ) "textures/common/caulk" 0 0 0 +( -1 0 0 344 ) ( ( 0.03125 0 0 ) ( 0 0.03125 0 ) ) "textures/common/caulk" 0 0 0 +} +} +// primitive 2 +{ +patchDef2 +{ +"textures/numbers/1" +( 3 3 0 0 0 ) +( +( ( 344 128 0 4 10.75 ) ( 344 196 0 6.125 10.75 ) ( 344 264 0 8.25 10.75 ) ) +( ( 440 128 0 4 13.75 ) ( 440 196 0 6.125 13.75 ) ( 440 264 0 8.25 13.75 ) ) +( ( 536 128 0 4 16.75 ) ( 536 196 0 6.125 16.75 ) ( 536 264 0 8.25 16.75 ) ) +) +} +} +// primitive 3 +{ +patchDef2 +{ +"textures/numbers/2" +( 3 3 0 0 0 ) +( +( ( 80 264 0 8.25 -2.5 ) ( 80 196 0 6.125 -2.5 ) ( 80 128 0 4 -2.5 ) ) +( ( 176 264 0 8.25 -5.5 ) ( 176 196 0 6.125 -5.5 ) ( 176 128 0 4 -5.5 ) ) +( ( 272 264 0 8.25 -8.5 ) ( 272 196 0 6.125 -8.5 ) ( 272 128 0 4 -8.5 ) ) +) +} +} +}