Updated sdf code to work in C++

This commit is contained in:
Segey Lapin
2021-10-14 13:42:21 +03:00
parent 2c7a6af437
commit 8c4432031e
5 changed files with 77 additions and 287 deletions

View File

@@ -170,25 +170,30 @@ void RoadGrid::index_site(struct map_site *site)
site->polygon_ind.resize(site->polygon.size());
/* slow as fuck */
for (i = 0; i < site->vertices.size(); i++) {
int idx = diagram_vertices.find(site->vertices[i]);
Vector2 v = site->vertices[i].snapped(Vector2(2.0f, 2.0f));
int idx = diagram_vertices.find(v);
if (idx < 0) {
idx = diagram_vertices.size();
diagram_vertices.push_back(site->vertices[i]);
diagram_vertices.push_back(v);
}
site->vertices_ind.write[i] = idx;
}
for (i = 0; i < site->polygon.size(); i++) {
int idx = diagram_vertices.find(site->polygon[i]);
Vector2 v = site->polygon[i].snapped(Vector2(2.0f, 2.0f));
int idx = diagram_vertices.find(v);
if (idx < 0) {
idx = diagram_vertices.size();
diagram_vertices.push_back(site->polygon[i]);
diagram_vertices.push_back(v);
}
site->polygon_ind.write[i] = idx;
}
site->hedges.resize(site->polygon.size());
int count = 0;
for (i = 0; i < site->polygon.size(); i++) {
int idx1 = site->polygon_ind[i];
int idx2 = site->polygon_ind[(i + 1) % site->polygon.size()];
if (idx1 == idx2)
continue;
struct half_edge he;
he.a = idx1;
he.b = idx2;
@@ -196,8 +201,9 @@ void RoadGrid::index_site(struct map_site *site)
/* use length to decide */
he.depth = 6.0f;
he.length = diagram_vertices[idx1].distance_to(diagram_vertices[idx2]);
site->hedges.write[i] = he;
site->hedges.write[count++] = he;
}
site->hedges.resize(count);
}
void RoadGrid::process_diagram(const Dictionary &diagram)
@@ -256,14 +262,14 @@ void RoadGrid::build(Ref<Curve> curve, Ref<OpenSimplexNoise> noise)
rnd->randomize();
printf("build_diagram\n");
// Dictionary diagram = build_diagram(8, 2 + (rnd->randi() % 2), 100, 100, 50);
Dictionary diagram = build_diagram(8, 2, 100, 100, 30);
Dictionary diagram = build_diagram(8, 2, 100, 100, 500);
printf("build_diagram done\n");
printf("process_diagram\n");
process_diagram(diagram);
printf("process_diagram done\n");
printf("%d %d\n", curve.is_valid(), noise.is_valid());
assert(curve.is_valid() && noise.is_valid());
int i;
int i, j;
if (curve.is_valid() && noise.is_valid()) {
printf("building 3rd dimention\n");
diagram_vertex_heights.resize(diagram_vertices.size());
@@ -271,30 +277,49 @@ void RoadGrid::build(Ref<Curve> curve, Ref<OpenSimplexNoise> noise)
float n = noise->get_noise_2dv(diagram_vertices[i]);
float t = (n + 1.0f) * 0.5f;
float d = MAX(1.0f, curve->interpolate_baked(t));
d = CLAMP(d, 1.0f, 30.0f);
diagram_vertex_heights.write[i] = d;
}
for (i = 0; i < map_hedges.size(); i++) {
int x1 = map_hedges[i]->a;
int x2 = map_hedges[i]->b;
float xd = diagram_vertices[x1].distance_squared_to(diagram_vertices[x2]);
float dh = fabsf(diagram_vertex_heights[x2] - diagram_vertex_heights[x1]);
if (fabsf(dh / xd) > 0.02f)
diagram_vertex_heights.write[x2] = diagram_vertex_heights[x1] + dh / fabsf(dh) * 0.02f * xd;
for (j = 0; j < 3; j++) {
for (i = 0; i < map_hedges.size(); i++) {
int x1 = map_hedges[i]->a;
int x2 = map_hedges[i]->b;
float xd = map_hedges[i]->length;
float dh = fabsf(diagram_vertex_heights[x2] - diagram_vertex_heights[x1]);
if (fabsf(dh / xd) > 0.01f)
diagram_vertex_heights.write[x2] = diagram_vertex_heights[x1] + dh / fabsf(dh) * 0.01f * xd;
}
#if 0
for (i = 0; i < diagram_vertices.size(); i++)
diagram_vertex_heights.write[i] = Math::stepify(diagram_vertex_heights.write[i], 4.0f);
for (i = 0; i < diagram_vertices.size(); i++)
diagram_vertex_heights.write[i] = 2.0;
#endif
}
printf("building 3rd dimention done\n");
}
}
Vector2 RoadGrid::get_influence(int x, int y) const
Vector2 RoadGrid::get_influence(int x, int y, float radius) const
{
static int mind = 1000000;
static int maxd = 0;
int rd = (int)(radius / grid_width) + 1;
List<struct half_edge *> hlist;
if (hedge_grid.has(x / grid_width) && hedge_grid[x / grid_width].has(y / grid_height))
hlist = hedge_grid[x / grid_width][y / grid_height];
List<struct half_edge *>::Element *e;
int i = 0, j = 0;
for (i = -rd; i < rd + 1; i++)
for (j = -rd; j < rd + 1; j++) {
List<struct half_edge *> tmp;
if (hedge_grid.has(x / grid_width + i) && hedge_grid[x / grid_width + i].has(y / grid_height + j)) {
tmp = hedge_grid[x / grid_width + i][y / grid_height + j];
for (e = tmp.front(); e; e = e->next()) {
struct half_edge *d = e->get();
hlist.push_back(d);
}
}
}
if (hlist.size() == 0)
return Vector2();
List<struct half_edge *>::Element *e;
for (e = hlist.front(); e; e = e->next()) {
struct half_edge *he = e->get();
Vector2 a = diagram_vertices[he->a];
@@ -303,7 +328,7 @@ Vector2 RoadGrid::get_influence(int x, int y) const
Vector2 seg[] = {a, b};
Vector2 pt = Geometry::get_closest_point_to_segment_2d(p, seg);
float d = pt.distance_squared_to(p);
if (d < MAX(96.0f * 96.0f, he->depth * he->depth) + 96.0f * 96.0f) {
if (d < radius * radius) {
Vector2 ret;
ret.x = 1.0f;
assert(diagram_vertex_heights.size() > he->a);
@@ -315,7 +340,7 @@ Vector2 RoadGrid::get_influence(int x, int y) const
float m1 = pt.distance_to(a) / l;
float m2 = CLAMP(1.0f - m1, 0.0f, 1.0f);
float h = h1 * (1.0f - m1) + h2 * (1.0f - m2);
ret.y = h - 0.5f;
ret.y = h - 2.5f;
return ret;
}
}
@@ -325,7 +350,7 @@ Vector2 RoadGrid::get_influence(int x, int y) const
void RoadGrid::_bind_methods()
{
ClassDB::bind_method(D_METHOD("draw_debug", "drawable", "size_x", "size_y"), &RoadGrid::draw_debug);
ClassDB::bind_method(D_METHOD("get_influence", "x", "y"), &RoadGrid::get_influence);
ClassDB::bind_method(D_METHOD("get_influence", "x", "y", "radius"), &RoadGrid::get_influence);
ClassDB::bind_method(D_METHOD("build", "curve", "noise"), &RoadGrid::build);
}