Updated world module (now voronoi roads work
This commit is contained in:
197
modules/world/road_grid.h
Normal file
197
modules/world/road_grid.h
Normal file
@@ -0,0 +1,197 @@
|
||||
#ifndef ROAD_GRID_H
|
||||
#define ROAD_GRID_H
|
||||
#include <core/object.h>
|
||||
#include <core/reference.h>
|
||||
#include <scene/resources/curve.h>
|
||||
#include <core/math/random_number_generator.h>
|
||||
#include <modules/opensimplex/open_simplex_noise.h>
|
||||
|
||||
class CanvasItem;
|
||||
|
||||
/* TODO:
|
||||
* a
|
||||
* - Implement diagram edges with site reference.
|
||||
* - Implement draw edges according to current position,
|
||||
* indicating which are drawn.
|
||||
* - Implement removal of draw edges by distance
|
||||
*
|
||||
* - Rewrite debug draw using distance logic.
|
||||
* - Implement 3D position for road vertices based on heightmap object;
|
||||
* - Implement SDF influence calculation based on distance to road
|
||||
* - Implement SDF calculation for roads (height cutoff by segment)
|
||||
* b
|
||||
* - Implement nodes (intersections) for drawing road intersections
|
||||
* - Implement draw edge splitting and position improvement.
|
||||
* - Find "wall" edges?
|
||||
* c
|
||||
* - Implement lot system based on sites
|
||||
* - Split lots to place buildings and other environment
|
||||
* objects
|
||||
* d
|
||||
* - Implement 3D positions and geometry generation
|
||||
*/
|
||||
|
||||
class RoadGrid: public Reference {
|
||||
GDCLASS(RoadGrid, Object)
|
||||
protected:
|
||||
Ref<RandomNumberGenerator> rnd;
|
||||
struct cluster {
|
||||
Vector2i c;
|
||||
float r;
|
||||
};
|
||||
List<struct cluster> clusters;
|
||||
Dictionary build_diagram(int npatches, int center_count, int center_step,
|
||||
int spread, int dim);
|
||||
HashMap<int, int> class_sizes;
|
||||
struct half_edge;
|
||||
HashMap<int, HashMap<int, List<struct half_edge *> > > hedge_grid;
|
||||
Rect2 bounds;
|
||||
void set_class_size(int cl, int sz)
|
||||
{
|
||||
class_sizes[cl] = sz;
|
||||
}
|
||||
static void _bind_methods();
|
||||
enum {
|
||||
SITE_UNASSIGNED = 0,
|
||||
SITE_FOREST,
|
||||
SITE_FARM,
|
||||
SITE_TOWN,
|
||||
SITE_EMPTY,
|
||||
SITE_MAX
|
||||
};
|
||||
struct graphedge {
|
||||
int a, b;
|
||||
int edge;
|
||||
};
|
||||
struct half_edge {
|
||||
int a, b;
|
||||
int site;
|
||||
float depth;
|
||||
float length;
|
||||
};
|
||||
struct map_site {
|
||||
int index;
|
||||
Vector2 pos;
|
||||
Vector<struct graphedge> graphedges;
|
||||
Vector<Vector2> vertices;
|
||||
Vector<Vector2> polygon;
|
||||
Vector<int> vertices_ind;
|
||||
Vector<int> polygon_ind;
|
||||
int site_type;
|
||||
int cluster;
|
||||
Vector<struct half_edge> hedges;
|
||||
};
|
||||
void index_site(struct map_site *site);
|
||||
Vector<Vector2> diagram_vertices;
|
||||
Vector<float> diagram_vertex_heights;
|
||||
Vector<struct map_site> map_sites;
|
||||
Vector<struct half_edge *> map_hedges;
|
||||
void classify_sites()
|
||||
{
|
||||
int i, j;
|
||||
for (j = 0; j < map_sites.size(); j++) {
|
||||
Rect2 r;
|
||||
for (i = 0; i < map_sites[j].polygon.size(); i++) {
|
||||
if (i == 0) {
|
||||
r.position = map_sites[j].polygon[0];
|
||||
r.size = Vector2();
|
||||
} else {
|
||||
r.expand_to(map_sites[j].polygon[i]);
|
||||
}
|
||||
}
|
||||
int cl_area = (int)(r.get_area() + 1.0f);
|
||||
for (i = 0; i < SITE_MAX; i++) {
|
||||
if (class_sizes.has(i))
|
||||
if (cl_area <= class_sizes[i]) {
|
||||
map_sites.write[j].site_type = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("area: %d class: %d\n", cl_area, map_sites[j].site_type);
|
||||
}
|
||||
}
|
||||
void process_diagram(const Dictionary &diagram);
|
||||
bool segment_intersects_rect(const Vector2 &a, const Vector2 &b, const Rect2 &rect);
|
||||
inline bool segment_in_grid_rect(const Vector2 &a, const Vector2 &b, int x, int y)
|
||||
{
|
||||
Rect2 r((float)(x * grid_width), (float)(y * grid_height), grid_width, grid_height);
|
||||
return segment_intersects_rect(a, b, r);
|
||||
}
|
||||
inline Rect2 segment_to_rect(const Vector2 &a, const Vector2 &b) const
|
||||
{
|
||||
Rect2 r(a, Vector2());
|
||||
r.expand_to(b);
|
||||
return r;
|
||||
}
|
||||
inline Rect2i rect_to_grid(const Rect2 &r) const
|
||||
{
|
||||
Rect2i ret;
|
||||
ret.position.x = get_grid_x(r.position.x);
|
||||
ret.position.y = get_grid_y(r.position.y);
|
||||
ret.size.x = get_grid_x(r.size.x) + 1;
|
||||
ret.size.y = get_grid_y(r.size.y) + 1;
|
||||
return ret;
|
||||
}
|
||||
inline Rect2 get_grid_rect(int x, int y) const
|
||||
{
|
||||
Rect2 rect;
|
||||
rect.position.x = (float)x * grid_width;
|
||||
rect.position.y = (float)y * grid_height;
|
||||
rect.size.x = grid_width;
|
||||
rect.size.x = grid_height;
|
||||
return rect;
|
||||
}
|
||||
inline void insert_hedge_to_grid_cell(int x, int y, struct half_edge *hedge)
|
||||
{
|
||||
if (hedge_grid.has(x) && hedge_grid[x].has(y))
|
||||
hedge_grid[x][y].push_back(hedge);
|
||||
else {
|
||||
List<struct half_edge *> items;
|
||||
items.push_back(hedge);
|
||||
hedge_grid[x][y] = items;
|
||||
}
|
||||
}
|
||||
inline void add_hedge_to_grid(struct half_edge *hedge)
|
||||
{
|
||||
Vector2 a = diagram_vertices[hedge->a];
|
||||
Vector2 b = diagram_vertices[hedge->b];
|
||||
|
||||
if (bounds.position.length_squared() == 0.0f && bounds.position.length_squared() == 0.0f) {
|
||||
bounds.position.x = a.x;
|
||||
bounds.position.y = a.y;
|
||||
} else
|
||||
bounds.expand_to(a);
|
||||
|
||||
bounds.expand_to(b);
|
||||
|
||||
Rect2 r = segment_to_rect(a, b).grow(1.0f);
|
||||
Rect2i rgrid = rect_to_grid(r);
|
||||
int x, y;
|
||||
for (y = 0; y < rgrid.size.y; y++) {
|
||||
for (x = 0; x < rgrid.size.x; x++) {
|
||||
int px = rgrid.position.x + x;
|
||||
int py = rgrid.position.y + y;
|
||||
Rect2 xr = get_grid_rect(px, py).grow(16.0f);
|
||||
if (segment_intersects_rect(a, b, xr))
|
||||
insert_hedge_to_grid_cell(px, py, hedge);
|
||||
}
|
||||
}
|
||||
}
|
||||
inline int get_grid_x(float x) const
|
||||
{
|
||||
return (int)(x / grid_width);
|
||||
}
|
||||
inline int get_grid_y(float y) const
|
||||
{
|
||||
return (int)(y / grid_height);
|
||||
}
|
||||
float grid_width, grid_height;
|
||||
friend class Roads;
|
||||
public:
|
||||
void build(Ref<Curve> curve, Ref<OpenSimplexNoise> noise);
|
||||
void draw_debug(Node *drawable, int size_x, int size_y) const;
|
||||
Vector2 get_influence(int x, int y) const;
|
||||
RoadGrid();
|
||||
~RoadGrid();
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user