diff --git a/include/polyscope/options.h b/include/polyscope/options.h index 12e794f6..a439ddda 100644 --- a/include/polyscope/options.h +++ b/include/polyscope/options.h @@ -64,8 +64,10 @@ extern bool hideWindowAfterShow; // Behavior of the ground plane extern GroundPlaneMode groundPlaneMode; +extern GroundPlaneHeightMode groundPlaneHeightMode; extern bool groundPlaneEnabled; // deprecated, but kept and respected for compatability. use groundPlaneMode. extern ScaledValue groundPlaneHeightFactor; +extern float groundPlaneHeight; extern int shadowBlurIters; extern float shadowDarkness; diff --git a/include/polyscope/types.h b/include/polyscope/types.h index c4be1d4d..e2b961c2 100644 --- a/include/polyscope/types.h +++ b/include/polyscope/types.h @@ -13,6 +13,7 @@ enum class BackgroundView { None = 0 }; enum class ProjectionMode { Perspective = 0, Orthographic }; enum class TransparencyMode { None = 0, Simple, Pretty }; enum class GroundPlaneMode { None, Tile, TileReflection, ShadowOnly }; +enum class GroundPlaneHeightMode { Relative = 0, Absolute }; enum class BackFacePolicy { Identical, Different, Custom, Cull }; enum class PointRenderMode { Sphere = 0, Quad }; diff --git a/src/options.cpp b/src/options.cpp index ebca63b9..960bcbc2 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -31,7 +31,9 @@ std::string screenshotExtension = ".png"; // Ground plane / shadows bool groundPlaneEnabled = true; GroundPlaneMode groundPlaneMode = GroundPlaneMode::TileReflection; +GroundPlaneHeightMode groundPlaneHeightMode = GroundPlaneHeightMode::Relative; ScaledValue groundPlaneHeightFactor = 0; +float groundPlaneHeight = 0.; int shadowBlurIters = 2; float shadowDarkness = 0.25; diff --git a/src/render/ground_plane.cpp b/src/render/ground_plane.cpp index c1ab4113..1f86270d 100644 --- a/src/render/ground_plane.cpp +++ b/src/render/ground_plane.cpp @@ -196,7 +196,18 @@ void GroundPlane::draw(bool isRedraw) { double bboxBottom = sign == 1.0 ? std::get<0>(state::boundingBox)[iP] : std::get<1>(state::boundingBox)[iP]; double bboxHeight = std::get<1>(state::boundingBox)[iP] - std::get<0>(state::boundingBox)[iP]; double heightEPS = state::lengthScale * 1e-4; - double groundHeight = bboxBottom - sign * (options::groundPlaneHeightFactor.asAbsolute() + heightEPS); + + double groundHeight = -777; + switch (options::groundPlaneHeightMode) { + case GroundPlaneHeightMode::Relative: { + groundHeight = bboxBottom - sign * (options::groundPlaneHeightFactor.asAbsolute() + heightEPS); + break; + } + case GroundPlaneHeightMode::Absolute: { + groundHeight = options::groundPlaneHeight; + break; + } + } // Viewport glm::vec4 viewport = render::engine->getCurrentViewport(); @@ -387,6 +398,16 @@ void GroundPlane::buildGui() { return ""; }; + auto heightModeName = [](const GroundPlaneHeightMode& m) -> std::string { + switch (m) { + case GroundPlaneHeightMode::Relative: + return "Relative"; + case GroundPlaneHeightMode::Absolute: + return "Absolute"; + } + return ""; + }; + ImGui::SetNextItemOpen(false, ImGuiCond_FirstUseEver); if (ImGui::TreeNode("Ground Plane")) { @@ -404,7 +425,39 @@ void GroundPlane::buildGui() { } ImGui::PopItemWidth(); - if (ImGui::SliderFloat("Height", options::groundPlaneHeightFactor.getValuePtr(), -1.0, 1.0)) requestRedraw(); + // Height + ImGui::PushItemWidth(80); + switch (options::groundPlaneHeightMode) { + case GroundPlaneHeightMode::Relative: + if (ImGui::SliderFloat("##HeightValue", options::groundPlaneHeightFactor.getValuePtr(), -1.0, 1.0)) + requestRedraw(); + break; + case GroundPlaneHeightMode::Absolute: + int iP; + float sign; + std::tie(iP, sign) = getGroundPlaneAxisAndSign(); + double bboxBottom = sign == 1.0 ? std::get<0>(state::boundingBox)[iP] : std::get<1>(state::boundingBox)[iP]; + double bboxHeight = std::get<1>(state::boundingBox)[iP] - std::get<0>(state::boundingBox)[iP]; + if (ImGui::SliderFloat("##HeightValue", &options::groundPlaneHeight, bboxBottom - 0.5 * bboxHeight, + bboxBottom + bboxHeight)) { + requestRedraw(); + } + break; + } + ImGui::PopItemWidth(); + ImGui::SameLine(); + ImGui::PushItemWidth(100); + if (ImGui::BeginCombo("Height##Mode", heightModeName(options::groundPlaneHeightMode).c_str())) { + for (GroundPlaneHeightMode m : {GroundPlaneHeightMode::Relative, GroundPlaneHeightMode::Absolute}) { + std::string mName = heightModeName(m); + if (ImGui::Selectable(mName.c_str(), options::groundPlaneHeightMode == m)) { + options::groundPlaneHeightMode = m; + requestRedraw(); + } + } + ImGui::EndCombo(); + } + ImGui::PopItemWidth(); switch (options::groundPlaneMode) { case GroundPlaneMode::None: diff --git a/test/src/basics_test.cpp b/test/src/basics_test.cpp index a8248a5f..040f1fcf 100644 --- a/test/src/basics_test.cpp +++ b/test/src/basics_test.cpp @@ -134,5 +134,12 @@ TEST_F(PolyscopeTest, GroundPlaneTest) { polyscope::refresh(); polyscope::show(3); + polyscope::options::groundPlaneHeightMode = polyscope::GroundPlaneHeightMode::Absolute; + polyscope::options::groundPlaneHeight = -0.3; + polyscope::show(3); + + polyscope::options::groundPlaneHeightMode = polyscope::GroundPlaneHeightMode::Relative; + polyscope::show(3); + polyscope::removeAllStructures(); }