diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index ab819c7c..d059ee8b 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -983,6 +983,11 @@ static void ProcessEntity(mapentity_t &entity, hull_index_t hullnum) return; } + // corner case, -omitdetail with all detail in an bmodel + if (brushes.empty() && entity.bounds == aabb3d()) { + return; + } + // simpler operation for hulls if (hullnum.value_or(0)) { tree_t tree; diff --git a/testmaps/q2_omitdetail_in_func.map b/testmaps/q2_omitdetail_in_func.map new file mode 100644 index 00000000..3afd37a7 --- /dev/null +++ b/testmaps/q2_omitdetail_in_func.map @@ -0,0 +1,86 @@ +// Game: Quake 2 +// Format: Quake2 (Valve) +// entity 0 +{ +"mapversion" "220" +"classname" "worldspawn" +"_tb_textures" "textures/e1u1" +// brush 0 +{ +( 24 244 64 ) ( 24 245 64 ) ( 24 244 65 ) e1u1/ggrat4_2 [ 0 1.0000000000000002 0 -16 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1 +( 24 68 64 ) ( 24 68 65 ) ( 25 68 64 ) e1u1/ggrat4_2 [ -1 0 0 -16 ] [ 0 0 -1 -32 ] 0 1 1 +( 24 244 96 ) ( 25 244 96 ) ( 24 245 96 ) e1u1/ggrat4_2 [ -1.0000000000000002 0 0 -16 ] [ 0 1.0000000000000002 0 -48 ] 0 1 1 +( 40 692 352 ) ( 40 693 352 ) ( 41 692 352 ) e1u1/ggrat4_2 [ -1.0000000000000002 0 0 -16 ] [ 0 -1.0000000000000002 0 -80 ] 0 1 1 +( 40 676 80 ) ( 41 676 80 ) ( 40 676 81 ) e1u1/ggrat4_2 [ -1 0 0 -16 ] [ 0 0 -1 -32 ] 0 1 1 +( 40 692 80 ) ( 40 692 81 ) ( 40 693 80 ) e1u1/ggrat4_2 [ 0 -1.0000000000000002 0 64 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1 +} +// brush 1 +{ +( 40 676 88 ) ( 40 677 88 ) ( 40 676 89 ) e1u1/ggrat4_2 [ 0 1.0000000000000002 0 -32 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1 +( 40 676 88 ) ( 40 676 89 ) ( 41 676 88 ) e1u1/ggrat4_2 [ -1 0 0 -16 ] [ 0 0 -1 -32 ] 0 1 1 +( 40 676 96 ) ( 41 676 96 ) ( 40 677 96 ) e1u1/ggrat4_2 [ -1.0000000000000002 0 0 -16 ] [ 0 1.0000000000000002 0 -40 ] 0 1 1 +( 488 692 352 ) ( 488 693 352 ) ( 489 692 352 ) e1u1/ggrat4_2 [ -1.0000000000000002 0 0 -16 ] [ 0 -1.0000000000000002 0 48 ] 0 1 1 +( 488 692 96 ) ( 489 692 96 ) ( 488 692 97 ) e1u1/ggrat4_2 [ -1 0 0 -16 ] [ 0 0 -1 -32 ] 0 1 1 +( 488 692 96 ) ( 488 692 97 ) ( 488 693 96 ) e1u1/ggrat4_2 [ 0 -1.0000000000000002 0 0 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1 +} +// brush 2 +{ +( 40 388 96 ) ( 40 389 96 ) ( 40 388 97 ) e1u1/florr1_8 [ 0 1 0 -16 ] [ 0 0 -1 0 ] 0 1 1 +( 120 68 80 ) ( 119 68 80 ) ( 120 68 81 ) e1u1/florr1_8 [ -1 0 0 16 ] [ 0 0 -1 0 ] 180 1 1 +( 120 68 80 ) ( 120 69 80 ) ( 119 68 80 ) e1u1/florr1_8 [ 1 0 0 -16 ] [ 0 -1 0 16 ] 180 1 1 +( 40 388 96 ) ( 39 388 96 ) ( 40 389 96 ) e1u1/florr1_8 [ -1 0 0 16 ] [ 0 -1 0 16 ] 180 1 1 +( 40 676 96 ) ( 40 676 97 ) ( 39 676 96 ) e1u1/florr1_8 [ 1 0 0 -16 ] [ 0 0 -1 0 ] 180 1 1 +( 488 68 80 ) ( 488 68 81 ) ( 488 69 80 ) e1u1/florr1_8 [ 0 -1 0 16 ] [ 0 0 -1 0 ] 0 1 1 +} +// brush 3 +{ +( 40 52 88 ) ( 40 53 88 ) ( 40 52 89 ) e1u1/ggrat4_2 [ 0 1 0 0 ] [ 0 0 -1 -32 ] 0 1 1 +( 40 52 88 ) ( 40 52 89 ) ( 41 52 88 ) e1u1/ggrat4_2 [ -1.0000000000000002 0 0 -32 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1 +( 40 52 96 ) ( 41 52 96 ) ( 40 53 96 ) e1u1/ggrat4_2 [ 0 1.0000000000000002 0 0 ] [ 1.0000000000000002 0 0 -32 ] 0 1 1 +( 488 68 352 ) ( 488 69 352 ) ( 489 68 352 ) e1u1/ggrat4_2 [ 0 1.0000000000000002 0 0 ] [ -1.0000000000000002 0 0 -96 ] 0 1 1 +( 488 68 96 ) ( 489 68 96 ) ( 488 68 97 ) e1u1/ggrat4_2 [ 1.0000000000000002 0 0 -80 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1 +( 488 68 96 ) ( 488 68 97 ) ( 488 69 96 ) e1u1/ggrat4_2 [ 0 1 0 0 ] [ 0 0 -1 -32 ] 0 1 1 +} +// brush 4 +{ +( 40 244 352 ) ( 40 245 352 ) ( 40 244 353 ) e1u1/florr1_8 [ 0 0 -1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 180 1 1 +( 488 68 360 ) ( 488 68 361 ) ( 489 68 360 ) e1u1/florr1_8 [ -1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 -16 ] 180 1 1 +( 40 244 352 ) ( 41 244 352 ) ( 40 245 352 ) e1u1/florr1_8 [ -1 0 0 0 ] [ 0 -1 0 0 ] 180 1 1 +( 488 676 368 ) ( 488 677 368 ) ( 489 676 368 ) e1u1/florr1_8 [ -1 0 0 0 ] [ 0 -1 0 0 ] 180 1 1 +( 488 676 360 ) ( 489 676 360 ) ( 488 676 361 ) e1u1/florr1_8 [ -1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 -16 ] 180 1 1 +( 488 676 360 ) ( 488 676 361 ) ( 488 677 360 ) e1u1/florr1_8 [ 0 0 1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 180 1 1 +} +// brush 5 +{ +( 488 692 80 ) ( 488 693 80 ) ( 488 692 81 ) e1u1/ggrat4_2 [ 0 1 0 0 ] [ 0 0 -1 -32 ] 0 1 1 +( 504 68 64 ) ( 503 68 64 ) ( 504 68 65 ) e1u1/ggrat4_2 [ -1 0 0 16 ] [ 0 0 -1 -32 ] 180 1 1 +( 504 244 96 ) ( 504 245 96 ) ( 503 244 96 ) e1u1/ggrat4_2 [ 1 0 0 -16 ] [ 0 -1 0 0 ] 180 1 1 +( 504 244 352 ) ( 503 244 352 ) ( 504 245 352 ) e1u1/ggrat4_2 [ 1 0 0 -16 ] [ 0 -1 0 0 ] 180 1 1 +( 488 676 80 ) ( 488 676 81 ) ( 487 676 80 ) e1u1/ggrat4_2 [ 1 0 0 -16 ] [ 0 0 -1 -32 ] 180 1 1 +( 504 244 64 ) ( 504 244 65 ) ( 504 245 64 ) e1u1/ggrat4_2 [ 0 -1 0 0 ] [ 0 0 -1 -32 ] 0 1 1 +} +} +// entity 1 +{ +"classname" "light" +"origin" "272 364 168" +"light" "3000" +} +// entity 2 +{ +"classname" "info_player_start" +"origin" "112 436 120" +} +// entity 3 +{ +"classname" "func_wall" +// brush 0 +{ +( 232 380 96 ) ( 232 381 96 ) ( 232 380 97 ) e1u1/box3_8 [ 0 0 -1.0000000000000002 48 ] [ 0 -1.0000000000000002 0 -24 ] 180 1 1 134217728 0 0 +( 216 412 96 ) ( 216 412 97 ) ( 217 412 96 ) e1u1/box3_8 [ -1.0000000000000002 0 0 -32 ] [ 0 0 -1.0000000000000002 48 ] 180 1 1 134217728 0 0 +( 216 380 96 ) ( 217 380 96 ) ( 216 381 96 ) e1u1/box3_8 [ -1 0 0 -32 ] [ 0 -1 0 -24 ] 180 1 1 134217728 0 0 +( 280 460 144 ) ( 280 461 144 ) ( 281 460 144 ) e1u1/box3_8 [ -1 0 0 -32 ] [ 0 -1 0 -24 ] 180 1 1 134217728 0 0 +( 280 476 112 ) ( 281 476 112 ) ( 280 476 113 ) e1u1/box3_8 [ -1.0000000000000002 0 0 -32 ] [ 0 0 1.0000000000000002 -16 ] 180 1 1 134217728 0 0 +( 296 460 112 ) ( 296 460 113 ) ( 296 461 112 ) e1u1/box3_8 [ 0 0 1.0000000000000002 -16 ] [ 0 -1.0000000000000002 0 -24 ] 180 1 1 134217728 0 0 +} +} diff --git a/tests/test_qbsp_q2.cc b/tests/test_qbsp_q2.cc index f10afaa7..3c42d194 100644 --- a/tests/test_qbsp_q2.cc +++ b/tests/test_qbsp_q2.cc @@ -125,6 +125,10 @@ TEST_CASE("q2 detail with -omitdetail" * doctest::test_suite("testmaps_q2")) { CHECK(inside_button_leaf == above_button_leaf); } +TEST_CASE("-omitdetail removing all brushes in a func" * doctest::test_suite("testmaps_q2")) { + const auto [bsp, bspx, prt] = LoadTestmapQ2("q2_omitdetail_in_func.map", {"-omitdetail"}); +} + TEST_CASE("playerclip" * doctest::test_suite("testmaps_q2")) { const auto [bsp, bspx, prt] = LoadTestmapQ2("qbsp_q2_playerclip.map");