Size now contains grid size of subdivisions, so size is never truncated

This commit is contained in:
Yousef Khadadeh 2025-09-16 09:35:03 +03:00
parent 83ff3f689d
commit 65b4f7116c
6 changed files with 63 additions and 36 deletions

View file

@ -87,7 +87,7 @@ namespace FixedPoint {
// Base should be a power of 2 to be accurate
template <typename T> T exp_int(const T& x, const T& base) {
return exp2(x * log2(base));
return exp2_int(x * log2_int(base));
}
template <typename T> T exp_int_accurate(uint64_t x, uint64_t base) {

View file

@ -7,7 +7,7 @@
#include <iostream>
DrawCamera::DrawCamera():
//c({0, 0}, WorldScalar(1e30), 0.0)
//c({0, 0}, WorldScalar(12), 0.0)
c({"1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, WorldScalar(100), 0.0)
{}

View file

@ -625,6 +625,12 @@ void Toolbar::grid_menu(bool justOpened) {
});
});
g.gridType = static_cast<WorldGrid::GridType>(typeSelected);
uint32_t sDiv = g.get_subdivisions();
gui.input_scalar_field<uint32_t>("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);

View file

@ -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;
}

View file

@ -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<uint32_t>(subdivisions, 1);
}
bool WorldGrid::get_remove_divisions_outwards() {
return removeDivisionsOutwards;
}
void WorldGrid::set_subdivisions(uint32_t v) {
subdivisions = v;
if(removeDivisionsOutwards)
subdivisions = std::max<uint32_t>(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<WorldScalar>(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<float>(worldSize);
float floatDivWorldSize = static_cast<float>(divWorldSize);
float floatSubDivWorldSize = static_cast<float>(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<float>(worldSize);
float floatDivWorldSize = static_cast<float>(divWorldSize);
float floatSubDivWorldSize = static_cast<float>(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
}));
}

View file

@ -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;