From 65b4f7116c79c430814797166b465f5cdb4c1594 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Tue, 16 Sep 2025 09:35:03 +0300 Subject: [PATCH] Size now contains grid size of subdivisions, so size is never truncated --- include/Helpers/FixedPoint.hpp | 2 +- src/DrawCamera.cpp | 2 +- src/Toolbar.cpp | 6 +++ src/World.cpp | 2 +- src/WorldGrid.cpp | 75 ++++++++++++++++++++-------------- src/WorldGrid.hpp | 12 +++++- 6 files changed, 63 insertions(+), 36 deletions(-) diff --git a/include/Helpers/FixedPoint.hpp b/include/Helpers/FixedPoint.hpp index 1ceb1bf..153fcea 100644 --- a/include/Helpers/FixedPoint.hpp +++ b/include/Helpers/FixedPoint.hpp @@ -87,7 +87,7 @@ namespace FixedPoint { // Base should be a power of 2 to be accurate template T exp_int(const T& x, const T& base) { - return exp2(x * log2(base)); + return exp2_int(x * log2_int(base)); } template T exp_int_accurate(uint64_t x, uint64_t base) { diff --git a/src/DrawCamera.cpp b/src/DrawCamera.cpp index ed6a343..16aca9d 100755 --- a/src/DrawCamera.cpp +++ b/src/DrawCamera.cpp @@ -7,7 +7,7 @@ #include DrawCamera::DrawCamera(): - //c({0, 0}, WorldScalar(1e30), 0.0) + //c({0, 0}, WorldScalar(12), 0.0) c({"1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, WorldScalar(100), 0.0) {} diff --git a/src/Toolbar.cpp b/src/Toolbar.cpp index 9801855..ac7d223 100644 --- a/src/Toolbar.cpp +++ b/src/Toolbar.cpp @@ -625,6 +625,12 @@ void Toolbar::grid_menu(bool justOpened) { }); }); g.gridType = static_cast(typeSelected); + uint32_t sDiv = g.get_subdivisions(); + gui.input_scalar_field("Subdivisions", "Subdivisions", &sDiv, 0, 10); + g.set_subdivisions(sDiv); + bool divOut = g.get_remove_divisions_outwards(); + gui.checkbox_field("Subdivide outwards", "Subdivide outwards", &divOut); + g.set_remove_divisions_outwards(divOut); } } main.world->drawProg.modify_grid(gridMenu.newName); diff --git a/src/World.cpp b/src/World.cpp index a380040..e564311 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -66,7 +66,7 @@ World::World(MainProgram& initMain, OpenWorldInfo& worldInfo): gridMan.add_grid("b"); gridMan.grids["b"].size = WorldScalar(1000); - gridMan.grids["b"].removeDivisionsOutwards = true; + gridMan.grids["b"].set_remove_divisions_outwards(true); gridMan.grids["b"].gridType = WorldGrid::GridType::CIRCLE_POINTS; } diff --git a/src/WorldGrid.cpp b/src/WorldGrid.cpp index bbf81a2..cb3c0f1 100644 --- a/src/WorldGrid.cpp +++ b/src/WorldGrid.cpp @@ -187,6 +187,26 @@ Vector2f WorldGrid::get_closest_grid_point(const WorldVec& gridOffset, const Wor return closestGridPointScreenPos; } +void WorldGrid::set_remove_divisions_outwards(bool v) { + removeDivisionsOutwards = v; + if(removeDivisionsOutwards) + subdivisions = std::max(subdivisions, 1); +} + +bool WorldGrid::get_remove_divisions_outwards() { + return removeDivisionsOutwards; +} + +void WorldGrid::set_subdivisions(uint32_t v) { + subdivisions = v; + if(removeDivisionsOutwards) + subdivisions = std::max(subdivisions, 1); +} + +uint32_t WorldGrid::get_subdivisions() { + return subdivisions; +} + void WorldGrid::draw(GridManager& gMan, SkCanvas* canvas, const DrawData& drawData) { if(!visible) return; @@ -198,16 +218,9 @@ void WorldGrid::draw(GridManager& gMan, SkCanvas* canvas, const DrawData& drawDa ruledEffect = compile_effect_shader_init("Ruled", ruledShaderCode); } - unsigned subdivisionsTrue = subdivisions + 1; - if(removeDivisionsOutwards && subdivisionsTrue < 2) - subdivisionsTrue = 2; + unsigned subdivisionsTrue = get_subdivisions() + 1; - // Make sure the initial size is divisible by the subdivision count, so that it remains accurate across the entire infinite grid - WorldScalar truncatedSize = FixedPoint::trunc(size / WorldScalar(subdivisionsTrue)) * WorldScalar(subdivisionsTrue); - if(truncatedSize == WorldScalar(0)) - truncatedSize = WorldScalar(subdivisionsTrue); - - WorldScalar sizeDetermineSubdivisionsToRemove = (drawData.cam.c.inverseScale / truncatedSize) * WorldScalar(subdivisionsTrue * 125); + WorldScalar sizeDetermineSubdivisionsToRemove = (drawData.cam.c.inverseScale / size) * WorldScalar(125); SkPaint linePaint; @@ -217,63 +230,63 @@ void WorldGrid::draw(GridManager& gMan, SkCanvas* canvas, const DrawData& drawDa uint64_t divLog = divLogDouble; WorldScalar logMultiplier = FixedPoint::exp_int_accurate(divLog, subdivisionsTrue); - WorldScalar sizeToUse = truncatedSize * logMultiplier; - WorldScalar divSize = sizeToUse / WorldScalar(subdivisionsTrue); - WorldScalar worldSize = sizeToUse / drawData.cam.c.inverseScale; + WorldScalar subDivSize = size * logMultiplier; + WorldScalar divSize = subDivSize * WorldScalar(subdivisionsTrue); + WorldScalar subDivWorldSize = subDivSize / drawData.cam.c.inverseScale; WorldScalar divWorldSize = divSize / drawData.cam.c.inverseScale; - float floatWorldSize = static_cast(worldSize); float floatDivWorldSize = static_cast(divWorldSize); + float floatSubDivWorldSize = static_cast(subDivWorldSize); - Vector2f closestGridPointScreenPos = get_closest_grid_point(offset, sizeToUse, drawData); - Vector2f divClosestGridPointScreenPos = get_closest_grid_point(offset, divSize, drawData); + Vector2f closestGridPointScreenPos = get_closest_grid_point(offset, divSize, drawData); + Vector2f subClosestGridPointScreenPos = get_closest_grid_point(offset, subDivSize, drawData); SkColor4f pointColor = gMan.world.canvasTheme.toolFrontColor; - pointColor.fA = std::clamp(floatWorldSize / 100.0f, 0.0f, 0.6f); + pointColor.fA = std::clamp(floatDivWorldSize / 100.0f, 0.0f, 0.6f); float gridPointSize = 5.0f; float finalDivMultiplier = (1.0 - divLogFraction) * ((divLog == 0) ? 0.5 : 1.0); linePaint.setShader(get_shader(gridType, { .gridColor = pointColor, - .mainGridScale = floatWorldSize, + .mainGridScale = floatDivWorldSize, .mainGridClosestPoint = closestGridPointScreenPos, .mainGridPointSize = gridPointSize, .divGridAlphaFrac = finalDivMultiplier, - .divGridScale = floatDivWorldSize, - .divGridClosestPoint = divClosestGridPointScreenPos, + .divGridScale = floatSubDivWorldSize, + .divGridClosestPoint = subClosestGridPointScreenPos, .divGridPointSize = gridPointSize * finalDivMultiplier })); } else { - WorldScalar sizeToUse = truncatedSize; - WorldScalar divSize = sizeToUse / WorldScalar(subdivisionsTrue); - WorldScalar worldSize = sizeToUse / drawData.cam.c.inverseScale; + WorldScalar subDivSize = size; + WorldScalar divSize = subDivSize * WorldScalar(subdivisionsTrue); + WorldScalar subDivWorldSize = subDivSize / drawData.cam.c.inverseScale; WorldScalar divWorldSize = divSize / drawData.cam.c.inverseScale; - if(worldSize < WorldScalar(7)) + if(divWorldSize < WorldScalar(7)) return; - float floatWorldSize = static_cast(worldSize); float floatDivWorldSize = static_cast(divWorldSize); + float floatSubDivWorldSize = static_cast(subDivWorldSize); - Vector2f closestGridPointScreenPos = get_closest_grid_point(offset, sizeToUse, drawData); - Vector2f divClosestGridPointScreenPos = get_closest_grid_point(offset, divSize, drawData); + Vector2f closestGridPointScreenPos = get_closest_grid_point(offset, divSize, drawData); + Vector2f subClosestGridPointScreenPos = get_closest_grid_point(offset, subDivSize, drawData); SkColor4f pointColor = gMan.world.canvasTheme.toolFrontColor; - pointColor.fA = std::clamp(floatWorldSize / 100.0f, 0.0f, 0.6f); - float gridPointSize = std::clamp(floatWorldSize / 10.0f, 0.0f, 5.0f); + pointColor.fA = std::clamp(floatDivWorldSize / 100.0f, 0.0f, 0.6f); + float gridPointSize = std::clamp(floatDivWorldSize / 10.0f, 0.0f, 5.0f); linePaint.setShader(get_shader(gridType, { .gridColor = pointColor, - .mainGridScale = floatWorldSize, + .mainGridScale = floatDivWorldSize, .mainGridClosestPoint = closestGridPointScreenPos, .mainGridPointSize = gridPointSize, .divGridAlphaFrac = 0.5f, - .divGridScale = floatDivWorldSize, - .divGridClosestPoint = divClosestGridPointScreenPos, + .divGridScale = floatSubDivWorldSize, + .divGridClosestPoint = subClosestGridPointScreenPos, .divGridPointSize = gridPointSize * 0.5f })); } diff --git a/src/WorldGrid.hpp b/src/WorldGrid.hpp index 9f3bf75..439e13a 100644 --- a/src/WorldGrid.hpp +++ b/src/WorldGrid.hpp @@ -17,9 +17,17 @@ class WorldGrid { WorldScalar size{50000000}; bool visible = true; WorldVec offset{0, 0}; - unsigned subdivisions = 0; - bool removeDivisionsOutwards = false; + + void set_remove_divisions_outwards(bool v); + bool get_remove_divisions_outwards(); + + void set_subdivisions(uint32_t v); + uint32_t get_subdivisions(); + private: + bool removeDivisionsOutwards = false; + uint32_t subdivisions = 1; + struct ShaderData { SkColor4f gridColor; float mainGridScale;