Optimized, updated
This commit is contained in:
2
godot
2
godot
Submodule godot updated: 2b5d89e635...3ca8003199
@@ -32,8 +32,10 @@ Dictionary RoadGrid::build_diagram(int npatches, int center_count, int center_st
|
|||||||
float sa = rnd->randf() * 2.0 * Math_PI;
|
float sa = rnd->randf() * 2.0 * Math_PI;
|
||||||
int i, bad = 0, cx, cp;
|
int i, bad = 0, cx, cp;
|
||||||
while (centers.size() < center_count) {
|
while (centers.size() < center_count) {
|
||||||
int center_x = CLAMP(center_step * (int)((rnd->randi() % spread) - spread / 2), -dim, dim);
|
int center_x = center_step * (int)((rnd->randi() % spread) - spread / 2);
|
||||||
int center_y = CLAMP(center_step * (int)((rnd->randi() % spread) - spread / 2), -dim, dim);
|
int center_y = center_step * (int)((rnd->randi() % spread) - spread / 2);
|
||||||
|
center_x = CLAMP(center_x, -dim, dim);
|
||||||
|
center_y = CLAMP(center_y, -dim, dim);
|
||||||
Vector2i c(center_x, center_y);
|
Vector2i c(center_x, center_y);
|
||||||
if (centers.find(c) < 0) {
|
if (centers.find(c) < 0) {
|
||||||
centers.push_back(c);
|
centers.push_back(c);
|
||||||
@@ -114,9 +116,10 @@ bool RoadGrid::segment_intersects_rect(const Vector2 &a, const Vector2 &b, const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is heavy when rendered on top of 3D viewport! */
|
||||||
void RoadGrid::draw_debug(Node *drawable, int size_x, int size_y) const
|
void RoadGrid::draw_debug(Node *drawable, int size_x, int size_y) const
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j, k;
|
||||||
CanvasItem *ci = Object::cast_to<CanvasItem>(drawable);
|
CanvasItem *ci = Object::cast_to<CanvasItem>(drawable);
|
||||||
if (!ci)
|
if (!ci)
|
||||||
return;
|
return;
|
||||||
@@ -138,11 +141,10 @@ void RoadGrid::draw_debug(Node *drawable, int size_x, int size_y) const
|
|||||||
Rect2i g = rect_to_grid(bounds);
|
Rect2i g = rect_to_grid(bounds);
|
||||||
for (i = g.position.y - 1; i < g.position.y + g.size.y + 1; i++) {
|
for (i = g.position.y - 1; i < g.position.y + g.size.y + 1; i++) {
|
||||||
for (j = g.position.x - 1; j < g.position.x + g.size.x + 1; j++) {
|
for (j = g.position.x - 1; j < g.position.x + g.size.x + 1; j++) {
|
||||||
if (hedge_grid.has(j) && hedge_grid[j].has(i)) {
|
if (hedge_grid.has(j, i)) {
|
||||||
List<struct half_edge *> items = hedge_grid[j][i];
|
const Vector<struct half_edge *> &items = hedge_grid.get(j, i);
|
||||||
List<struct half_edge *>::Element *e;
|
for (k = 0; k < items.size(); k++) {
|
||||||
for (e = items.front(); e; e = e->next()) {
|
struct half_edge *he = items[k];
|
||||||
struct half_edge *he = e->get();
|
|
||||||
|
|
||||||
assert(he->a >= 0);
|
assert(he->a >= 0);
|
||||||
assert(he->b >= 0);
|
assert(he->b >= 0);
|
||||||
@@ -215,6 +217,8 @@ void RoadGrid::process_diagram(const Dictionary &diagram)
|
|||||||
printf("start processing sites\n");
|
printf("start processing sites\n");
|
||||||
for (i = 0; i < sites.size(); i++) {
|
for (i = 0; i < sites.size(); i++) {
|
||||||
struct map_site site;
|
struct map_site site;
|
||||||
|
/* We use Dictionary to build native structure only once,
|
||||||
|
* then we use native data. */
|
||||||
const Dictionary &site_data = sites[i];
|
const Dictionary &site_data = sites[i];
|
||||||
const Array &graphedges = site_data["graphedges"];
|
const Array &graphedges = site_data["graphedges"];
|
||||||
printf("processing site: %d\n", i);
|
printf("processing site: %d\n", i);
|
||||||
@@ -256,7 +260,7 @@ void RoadGrid::process_diagram(const Dictionary &diagram)
|
|||||||
printf("processing done, sites count: %d\n", map_sites.size());
|
printf("processing done, sites count: %d\n", map_sites.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoadGrid::build(Ref<Curve> curve, Ref<OpenSimplexNoise> noise)
|
void RoadGrid::build(Ref<Curve> curve, Ref<FastNoiseLite> noise)
|
||||||
{
|
{
|
||||||
rnd.instance();
|
rnd.instance();
|
||||||
rnd->randomize();
|
rnd->randomize();
|
||||||
@@ -274,7 +278,8 @@ void RoadGrid::build(Ref<Curve> curve, Ref<OpenSimplexNoise> noise)
|
|||||||
printf("building 3rd dimention\n");
|
printf("building 3rd dimention\n");
|
||||||
diagram_vertex_heights.resize(diagram_vertices.size());
|
diagram_vertex_heights.resize(diagram_vertices.size());
|
||||||
for (i = 0; i < diagram_vertices.size(); i++) {
|
for (i = 0; i < diagram_vertices.size(); i++) {
|
||||||
float n = noise->get_noise_2dv(diagram_vertices[i]);
|
const Vector2 &v = diagram_vertices[i];
|
||||||
|
float n = noise->get_noise_2d(v.x, v.y);
|
||||||
float t = (n + 1.0f) * 0.5f;
|
float t = (n + 1.0f) * 0.5f;
|
||||||
float d = MAX(1.0f, curve->interpolate_baked(t));
|
float d = MAX(1.0f, curve->interpolate_baked(t));
|
||||||
d = CLAMP(d, 1.0f, 30.0f);
|
d = CLAMP(d, 1.0f, 30.0f);
|
||||||
@@ -303,25 +308,21 @@ void RoadGrid::build(Ref<Curve> curve, Ref<OpenSimplexNoise> noise)
|
|||||||
Vector2 RoadGrid::get_influence(int x, int y, float radius) const
|
Vector2 RoadGrid::get_influence(int x, int y, float radius) const
|
||||||
{
|
{
|
||||||
int rd = (int)(radius / grid_width) + 1;
|
int rd = (int)(radius / grid_width) + 1;
|
||||||
List<struct half_edge *> hlist;
|
Vector<struct half_edge *> hlist;
|
||||||
List<struct half_edge *>::Element *e;
|
const List<struct half_edge *>::Element *e;
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
for (i = -rd; i < rd + 1; i++)
|
for (i = -rd; i < rd + 1; i++)
|
||||||
for (j = -rd; j < rd + 1; j++) {
|
for (j = -rd; j < rd + 1; j++) {
|
||||||
List<struct half_edge *> tmp;
|
if (hedge_grid.has(x / grid_width + i, y / grid_height + j)) {
|
||||||
if (hedge_grid.has(x / grid_width + i) && hedge_grid[x / grid_width + i].has(y / grid_height + j)) {
|
const Vector<struct half_edge *> &tmp = hedge_grid.get(x / grid_width + i, y / grid_height + j);
|
||||||
tmp = hedge_grid[x / grid_width + i][y / grid_height + j];
|
hlist.append_array(tmp);
|
||||||
for (e = tmp.front(); e; e = e->next()) {
|
|
||||||
struct half_edge *d = e->get();
|
|
||||||
hlist.push_back(d);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (hlist.size() == 0)
|
if (hlist.size() == 0)
|
||||||
return Vector2();
|
return Vector2();
|
||||||
for (e = hlist.front(); e; e = e->next()) {
|
for (i = 0; i < hlist.size(); i++) {
|
||||||
struct half_edge *he = e->get();
|
struct half_edge *he = hlist[i];
|
||||||
Vector2 a = diagram_vertices[he->a];
|
Vector2 a = diagram_vertices[he->a];
|
||||||
Vector2 b = diagram_vertices[he->b];
|
Vector2 b = diagram_vertices[he->b];
|
||||||
Vector2 p(x, y);
|
Vector2 p(x, y);
|
||||||
@@ -338,7 +339,8 @@ Vector2 RoadGrid::get_influence(int x, int y, float radius) const
|
|||||||
float l = he->length;
|
float l = he->length;
|
||||||
assert(l > 0.0f);
|
assert(l > 0.0f);
|
||||||
float m1 = pt.distance_to(a) / l;
|
float m1 = pt.distance_to(a) / l;
|
||||||
float m2 = CLAMP(1.0f - m1, 0.0f, 1.0f);
|
float m2 = 1.0f - m1;
|
||||||
|
m2 = CLAMP(m2, 0.0f, 1.0f);
|
||||||
float h = h1 * (1.0f - m1) + h2 * (1.0f - m2);
|
float h = h1 * (1.0f - m1) + h2 * (1.0f - m2);
|
||||||
ret.y = h - 2.5f;
|
ret.y = h - 2.5f;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -354,3 +356,132 @@ void RoadGrid::_bind_methods()
|
|||||||
ClassDB::bind_method(D_METHOD("build", "curve", "noise"), &RoadGrid::build);
|
ClassDB::bind_method(D_METHOD("build", "curve", "noise"), &RoadGrid::build);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RoadGrid::find_edge(int a, int b)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < map_hedges.size(); i++) {
|
||||||
|
if (map_hedges[i]->a == a &&
|
||||||
|
map_hedges[i]->b == b)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
void RoadGrid::setup_vshapes()
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
vertices.resize(get_diagram_vertex_count());
|
||||||
|
for (i = 0; i < vertices.size(); i++) {
|
||||||
|
vertices.write()[i].x = diagram_vertices[i].x;
|
||||||
|
vertices.write()[i].y = diagram_vertex_heights[i];
|
||||||
|
vertices.write()[i].z = diagram_vertices[i].y;
|
||||||
|
}
|
||||||
|
List<struct vshape> vdata_list;
|
||||||
|
for (i = 0; i < map_hedges.size(); i++) {
|
||||||
|
for (j = 0; j < map_hedges.size(); j++) {
|
||||||
|
if (i == j)
|
||||||
|
continue;
|
||||||
|
if (map_hedges[i]->b !=
|
||||||
|
map_hedges[j]->a)
|
||||||
|
continue;
|
||||||
|
if (map_hedges[i]->site !=
|
||||||
|
map_hedges[j]->site)
|
||||||
|
continue;
|
||||||
|
int a, b1, b2;
|
||||||
|
struct vshape v;
|
||||||
|
/* star topology */
|
||||||
|
a = map_hedges[i]->b;
|
||||||
|
b1 = map_hedges[i]->a;
|
||||||
|
b2 = map_hedges[j]->b;
|
||||||
|
v.e1 = i;
|
||||||
|
v.e2 = j;
|
||||||
|
v.site = map_hedges[i]->site;
|
||||||
|
v.area.position = vertices[a];
|
||||||
|
v.area.expand_to(vertices[b1] + Vector3(0, 1, 0));
|
||||||
|
v.area.expand_to(vertices[b2] + Vector3(0, -1, 0));
|
||||||
|
v.instance = -1;
|
||||||
|
Vector3 p1 = vertices[map_hedges[v.e1]->a];
|
||||||
|
Vector3 p2 = vertices[map_hedges[v.e1]->b];
|
||||||
|
Vector3 p3 = vertices[map_hedges[v.e2]->b];
|
||||||
|
p1 = (p2 + (p1 - p2) * 0.5f).snapped(Vector3(4.0f, 0.1f, 4.0f));
|
||||||
|
p3 = (p2 + (p3 - p2) * 0.5f).snapped(Vector3(4.0f, 0.1f, 4.0f));
|
||||||
|
p2 = p2.snapped(Vector3(4.0f, 0.1f, 4.0f));
|
||||||
|
v.p1 = p1;
|
||||||
|
v.p2 = p2;
|
||||||
|
v.p3 = p3;
|
||||||
|
/* add v-shape only if we can actually generate it */
|
||||||
|
if (v.p1.distance_squared_to(v.p2) > 2.0f &&
|
||||||
|
v.p2.distance_squared_to(v.p3) > 2.0f &&
|
||||||
|
v.p1.distance_squared_to(v.p3) > 2.0f)
|
||||||
|
vdata_list.push_back(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vshapes.resize(vdata_list.size());
|
||||||
|
for (i = 0; i < vdata_list.size(); i++)
|
||||||
|
vshapes.write()[i] = vdata_list[i];
|
||||||
|
for (i = 0; i < vshapes.size(); i++) {
|
||||||
|
for (j = 0; j < vshapes.size(); j++) {
|
||||||
|
if (i == j)
|
||||||
|
continue;
|
||||||
|
if (vshapes[i].e1 == vshapes[j].e1)
|
||||||
|
vshapes.write()[j].p1 = vshapes[i].p1;
|
||||||
|
if (vshapes[i].e2 == vshapes[j].e1)
|
||||||
|
vshapes.write()[j].p1 = vshapes[i].p3;
|
||||||
|
if (vshapes[i].e1 == vshapes[j].e2)
|
||||||
|
vshapes.write()[j].p3 = vshapes[i].p1;
|
||||||
|
if (vshapes[i].e2 == vshapes[j].e2)
|
||||||
|
vshapes.write()[j].p3 = vshapes[i].p3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < vshapes.size(); i++) {
|
||||||
|
const struct vshape &v = vshapes[i];
|
||||||
|
assert(map_hedges[v.e1]->site == map_hedges[v.e2]->site);
|
||||||
|
assert(v.e1 >= 0 && v.e2 >= 0 && v.e1 != v.e2);
|
||||||
|
int e1a = map_hedges[vshapes[i].e1]->a;
|
||||||
|
int e1b = map_hedges[vshapes[i].e1]->b;
|
||||||
|
int e2a = map_hedges[vshapes[i].e2]->a;
|
||||||
|
int e2b = map_hedges[vshapes[i].e2]->b;
|
||||||
|
printf("vshape %d: %d: %d: %f %f %f -> %d: %f %f %f -> %d: %d: %f %f %f -> %d: %f %f %f\n",
|
||||||
|
i,
|
||||||
|
vshapes[i].e1,
|
||||||
|
e1a,
|
||||||
|
vertices[e1a].x,
|
||||||
|
vertices[e1a].y,
|
||||||
|
vertices[e1a].z,
|
||||||
|
e1b,
|
||||||
|
vertices[e1b].x,
|
||||||
|
vertices[e1b].y,
|
||||||
|
vertices[e1b].z,
|
||||||
|
vshapes[i].e2,
|
||||||
|
e2a,
|
||||||
|
vertices[e2a].x,
|
||||||
|
vertices[e2a].y,
|
||||||
|
vertices[e2a].z,
|
||||||
|
e2b,
|
||||||
|
vertices[e2b].x,
|
||||||
|
vertices[e2b].y,
|
||||||
|
vertices[e2b].z
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoadGrid::sort_angle(Vector<int> &sort_data)
|
||||||
|
{
|
||||||
|
struct comparator {
|
||||||
|
Vector3 *vertices;
|
||||||
|
bool operator()(int a, int b) const {
|
||||||
|
Vector3 p1 = vertices[a];
|
||||||
|
Vector3 p2 = vertices[b];
|
||||||
|
Vector2 rp1(p1.x, p1.z);
|
||||||
|
Vector2 rp2(p2.x, p2.z);
|
||||||
|
return rp1.angle() < rp2.angle();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
SortArray<int, struct comparator> sorter;
|
||||||
|
sorter.compare.vertices = vertices.write().ptr();
|
||||||
|
sorter.sort(sort_data.ptrw(), sort_data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoadGrid::build_building_positions()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#ifndef ROAD_GRID_H
|
#ifndef ROAD_GRID_H
|
||||||
#define ROAD_GRID_H
|
#define ROAD_GRID_H
|
||||||
|
#include <unordered_map>
|
||||||
#include <core/object.h>
|
#include <core/object.h>
|
||||||
#include <core/reference.h>
|
#include <core/reference.h>
|
||||||
#include <scene/resources/curve.h>
|
#include <scene/resources/curve.h>
|
||||||
#include <core/math/random_number_generator.h>
|
#include <core/math/random_number_generator.h>
|
||||||
#include <modules/opensimplex/open_simplex_noise.h>
|
#include <modules/voxel/util/noise/fast_noise_lite.h>
|
||||||
|
|
||||||
class CanvasItem;
|
class CanvasItem;
|
||||||
|
|
||||||
@@ -44,7 +45,6 @@ protected:
|
|||||||
int spread, int dim);
|
int spread, int dim);
|
||||||
HashMap<int, int> class_sizes;
|
HashMap<int, int> class_sizes;
|
||||||
struct half_edge;
|
struct half_edge;
|
||||||
HashMap<int, HashMap<int, List<struct half_edge *> > > hedge_grid;
|
|
||||||
Rect2 bounds;
|
Rect2 bounds;
|
||||||
void set_class_size(int cl, int sz)
|
void set_class_size(int cl, int sz)
|
||||||
{
|
{
|
||||||
@@ -141,15 +141,38 @@ protected:
|
|||||||
rect.size.x = grid_height;
|
rect.size.x = grid_height;
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
inline void insert_hedge_to_grid_cell(int x, int y, struct half_edge *hedge)
|
class hg {
|
||||||
{
|
typedef Vector<struct half_edge *> tvalue;
|
||||||
if (hedge_grid.has(x) && hedge_grid[x].has(y))
|
std::unordered_map<int, std::unordered_map<int, Vector<struct half_edge *> > > hedge_grid;
|
||||||
hedge_grid[x][y].push_back(hedge);
|
public:
|
||||||
else {
|
inline const tvalue get(int x, int y) const
|
||||||
List<struct half_edge *> items;
|
{
|
||||||
items.push_back(hedge);
|
return hedge_grid.at(x).at(y);
|
||||||
|
}
|
||||||
|
inline bool has(int x, int y) const
|
||||||
|
{
|
||||||
|
if (hedge_grid.find(x) != hedge_grid.end() &&
|
||||||
|
hedge_grid.at(x).find(y) != hedge_grid.at(x).end())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline void set(int x, int y, struct half_edge *hedge)
|
||||||
|
{
|
||||||
|
Vector<struct half_edge *> items;
|
||||||
|
if (has(x, y))
|
||||||
|
items = get(x, y);
|
||||||
|
items.resize(items.size() + 1);
|
||||||
|
items.write[items.size() - 1] = hedge;
|
||||||
hedge_grid[x][y] = items;
|
hedge_grid[x][y] = items;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
class hg hedge_grid;
|
||||||
|
inline void insert_hedge_to_grid_cell(int x, int y, struct half_edge *hedge)
|
||||||
|
{
|
||||||
|
static int count = 0;
|
||||||
|
count++;
|
||||||
|
hedge_grid.set(x, y, hedge);
|
||||||
|
printf("count: %d\n", count);
|
||||||
}
|
}
|
||||||
inline void add_hedge_to_grid(struct half_edge *hedge)
|
inline void add_hedge_to_grid(struct half_edge *hedge)
|
||||||
{
|
{
|
||||||
@@ -186,12 +209,44 @@ protected:
|
|||||||
return (int)(y / grid_height);
|
return (int)(y / grid_height);
|
||||||
}
|
}
|
||||||
float grid_width, grid_height;
|
float grid_width, grid_height;
|
||||||
friend class Roads;
|
PoolVector<Vector3> vertices;
|
||||||
public:
|
public:
|
||||||
void build(Ref<Curve> curve, Ref<OpenSimplexNoise> noise);
|
struct vshape {
|
||||||
|
AABB area;
|
||||||
|
int instance;
|
||||||
|
int e1, e2;
|
||||||
|
int site;
|
||||||
|
Vector3 p1, p2, p3;
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
PoolVector<struct vshape> vshapes;
|
||||||
|
void sort_angle(Vector<int> &sort_data);
|
||||||
|
public:
|
||||||
|
void build(Ref<Curve> curve, Ref<FastNoiseLite> noise);
|
||||||
void draw_debug(Node *drawable, int size_x, int size_y) const;
|
void draw_debug(Node *drawable, int size_x, int size_y) const;
|
||||||
|
int find_edge(int a, int b);
|
||||||
|
void setup_vshapes();
|
||||||
|
inline const PoolVector<struct vshape> &get_vshapes() const
|
||||||
|
{
|
||||||
|
const PoolVector<struct vshape> &ret = vshapes;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
inline PoolVector<struct vshape> &get_vshapes()
|
||||||
|
{
|
||||||
|
PoolVector<struct vshape> &ret = vshapes;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
Vector2 get_influence(int x, int y, float radius) const;
|
Vector2 get_influence(int x, int y, float radius) const;
|
||||||
RoadGrid();
|
RoadGrid();
|
||||||
~RoadGrid();
|
~RoadGrid();
|
||||||
|
inline int get_diagram_vertex_count() const
|
||||||
|
{
|
||||||
|
return diagram_vertices.size();
|
||||||
|
}
|
||||||
|
inline int get_map_hedges_count() const
|
||||||
|
{
|
||||||
|
return map_hedges.size();
|
||||||
|
}
|
||||||
|
void build_building_positions();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -54,121 +54,6 @@ bool Roads::_set(const StringName &p_name, const Variant &p_value)
|
|||||||
|
|
||||||
return update;
|
return update;
|
||||||
}
|
}
|
||||||
void Roads::sort_angle(Vector<int> &sort_data)
|
|
||||||
{
|
|
||||||
struct comparator {
|
|
||||||
Vector3 *vertices;
|
|
||||||
bool operator()(int a, int b) const {
|
|
||||||
Vector3 p1 = vertices[a];
|
|
||||||
Vector3 p2 = vertices[b];
|
|
||||||
Vector2 rp1(p1.x, p1.z);
|
|
||||||
Vector2 rp2(p2.x, p2.z);
|
|
||||||
return rp1.angle() < rp2.angle();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
SortArray<int, struct comparator> sorter;
|
|
||||||
sorter.compare.vertices = vertices.write().ptr();
|
|
||||||
sorter.sort(sort_data.ptrw(), sort_data.size());
|
|
||||||
}
|
|
||||||
void Roads::setup_vshapes()
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
RoadGrid *rg = RoadsData::get_singleton()->get_road_grid();
|
|
||||||
vertices.resize(rg->diagram_vertices.size());
|
|
||||||
for (i = 0; i < vertices.size(); i++) {
|
|
||||||
vertices.write()[i].x = rg->diagram_vertices[i].x;
|
|
||||||
vertices.write()[i].y = rg->diagram_vertex_heights[i];
|
|
||||||
vertices.write()[i].z = rg->diagram_vertices[i].y;
|
|
||||||
}
|
|
||||||
List<struct vshape> vdata_list;
|
|
||||||
for (i = 0; i < rg->map_hedges.size(); i++) {
|
|
||||||
for (j = 0; j < rg->map_hedges.size(); j++) {
|
|
||||||
if (i == j)
|
|
||||||
continue;
|
|
||||||
if (rg->map_hedges[i]->b !=
|
|
||||||
rg->map_hedges[j]->a)
|
|
||||||
continue;
|
|
||||||
if (rg->map_hedges[i]->site !=
|
|
||||||
rg->map_hedges[j]->site)
|
|
||||||
continue;
|
|
||||||
int a, b1, b2;
|
|
||||||
struct vshape v;
|
|
||||||
/* star topology */
|
|
||||||
a = rg->map_hedges[i]->b;
|
|
||||||
b1 = rg->map_hedges[i]->a;
|
|
||||||
b2 = rg->map_hedges[j]->b;
|
|
||||||
v.e1 = i;
|
|
||||||
v.e2 = j;
|
|
||||||
v.site = rg->map_hedges[i]->site;
|
|
||||||
v.area.position = vertices[a];
|
|
||||||
v.area.expand_to(vertices[b1] + Vector3(0, 1, 0));
|
|
||||||
v.area.expand_to(vertices[b2] + Vector3(0, -1, 0));
|
|
||||||
v.instance = -1;
|
|
||||||
Vector3 p1 = vertices[rg->map_hedges[v.e1]->a];
|
|
||||||
Vector3 p2 = vertices[rg->map_hedges[v.e1]->b];
|
|
||||||
Vector3 p3 = vertices[rg->map_hedges[v.e2]->b];
|
|
||||||
p1 = (p2 + (p1 - p2) * 0.5f).snapped(Vector3(4.0f, 0.1f, 4.0f));
|
|
||||||
p3 = (p2 + (p3 - p2) * 0.5f).snapped(Vector3(4.0f, 0.1f, 4.0f));
|
|
||||||
p2 = p2.snapped(Vector3(4.0f, 0.1f, 4.0f));
|
|
||||||
v.p1 = p1;
|
|
||||||
v.p2 = p2;
|
|
||||||
v.p3 = p3;
|
|
||||||
/* add v-shape only if we can actually generate it */
|
|
||||||
if (v.p1.distance_squared_to(v.p2) > 2.0f &&
|
|
||||||
v.p2.distance_squared_to(v.p3) > 2.0f &&
|
|
||||||
v.p1.distance_squared_to(v.p3) > 2.0f)
|
|
||||||
vdata_list.push_back(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vshapes.resize(vdata_list.size());
|
|
||||||
for (i = 0; i < vdata_list.size(); i++)
|
|
||||||
vshapes.write()[i] = vdata_list[i];
|
|
||||||
for (i = 0; i < vshapes.size(); i++) {
|
|
||||||
for (j = 0; j < vshapes.size(); j++) {
|
|
||||||
if (i == j)
|
|
||||||
continue;
|
|
||||||
if (vshapes[i].e1 == vshapes[j].e1)
|
|
||||||
vshapes.write()[j].p1 = vshapes[i].p1;
|
|
||||||
if (vshapes[i].e2 == vshapes[j].e1)
|
|
||||||
vshapes.write()[j].p1 = vshapes[i].p3;
|
|
||||||
if (vshapes[i].e1 == vshapes[j].e2)
|
|
||||||
vshapes.write()[j].p3 = vshapes[i].p1;
|
|
||||||
if (vshapes[i].e2 == vshapes[j].e2)
|
|
||||||
vshapes.write()[j].p3 = vshapes[i].p3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < vshapes.size(); i++) {
|
|
||||||
const struct vshape &v = vshapes[i];
|
|
||||||
assert(rg->map_hedges[v.e1]->site == rg->map_hedges[v.e2]->site);
|
|
||||||
assert(v.e1 >= 0 && v.e2 >= 0 && v.e1 != v.e2);
|
|
||||||
int e1a = rg->map_hedges[vshapes[i].e1]->a;
|
|
||||||
int e1b = rg->map_hedges[vshapes[i].e1]->b;
|
|
||||||
int e2a = rg->map_hedges[vshapes[i].e2]->a;
|
|
||||||
int e2b = rg->map_hedges[vshapes[i].e2]->b;
|
|
||||||
printf("vshape %d: %d: %d: %f %f %f -> %d: %f %f %f -> %d: %d: %f %f %f -> %d: %f %f %f\n",
|
|
||||||
i,
|
|
||||||
vshapes[i].e1,
|
|
||||||
e1a,
|
|
||||||
vertices[e1a].x,
|
|
||||||
vertices[e1a].y,
|
|
||||||
vertices[e1a].z,
|
|
||||||
e1b,
|
|
||||||
vertices[e1b].x,
|
|
||||||
vertices[e1b].y,
|
|
||||||
vertices[e1b].z,
|
|
||||||
vshapes[i].e2,
|
|
||||||
e2a,
|
|
||||||
vertices[e2a].x,
|
|
||||||
vertices[e2a].y,
|
|
||||||
vertices[e2a].z,
|
|
||||||
e2b,
|
|
||||||
vertices[e2b].x,
|
|
||||||
vertices[e2b].y,
|
|
||||||
vertices[e2b].z
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void Roads::update_all()
|
void Roads::update_all()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -195,7 +80,7 @@ void Roads::update_all()
|
|||||||
}
|
}
|
||||||
printf("vertices: %d\n", rg->get_diagram_vertex_count());
|
printf("vertices: %d\n", rg->get_diagram_vertex_count());
|
||||||
printf("edges: %d\n", rg->get_map_hedges_count());
|
printf("edges: %d\n", rg->get_map_hedges_count());
|
||||||
setup_vshapes();
|
rg->setup_vshapes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,11 +361,13 @@ void Roads::process_vshapes()
|
|||||||
{
|
{
|
||||||
if (get_viewport() && get_viewport()->get_camera())
|
if (get_viewport() && get_viewport()->get_camera())
|
||||||
cam_xform = get_viewport()->get_camera()->get_global_transform();
|
cam_xform = get_viewport()->get_camera()->get_global_transform();
|
||||||
|
RoadGrid *rg = RoadsData::get_singleton()->get_road_grid();
|
||||||
AABB camarea;
|
AABB camarea;
|
||||||
camarea.position = cam_xform.origin;
|
camarea.position = cam_xform.origin;
|
||||||
camarea.grow_by(550.0f);
|
camarea.grow_by(550.0f);
|
||||||
int i;
|
int i;
|
||||||
List<int> active_vshapes;
|
List<int> active_vshapes;
|
||||||
|
const PoolVector<struct RoadGrid::vshape> &vshapes = rg->get_vshapes();
|
||||||
printf("camera %f %f %f\n", cam_xform.origin.x, cam_xform.origin.y, cam_xform.origin.z);
|
printf("camera %f %f %f\n", cam_xform.origin.x, cam_xform.origin.y, cam_xform.origin.z);
|
||||||
for (i = 0; i < vshapes.size(); i++) {
|
for (i = 0; i < vshapes.size(); i++) {
|
||||||
if (active_vshapes.size() > 32)
|
if (active_vshapes.size() > 32)
|
||||||
@@ -504,7 +391,7 @@ void Roads::process_vshapes()
|
|||||||
List<int>::Element *e;
|
List<int>::Element *e;
|
||||||
for (e = active_vshapes.front(); e; e = e->next()) {
|
for (e = active_vshapes.front(); e; e = e->next()) {
|
||||||
i = e->get();
|
i = e->get();
|
||||||
const struct vshape &v = vshapes[i];
|
const struct RoadGrid::vshape &v = vshapes[i];
|
||||||
assert(v.p1.distance_squared_to(v.p2) > 2.0f);
|
assert(v.p1.distance_squared_to(v.p2) > 2.0f);
|
||||||
assert(v.p2.distance_squared_to(v.p3) > 2.0f);
|
assert(v.p2.distance_squared_to(v.p3) > 2.0f);
|
||||||
assert(v.p1.distance_squared_to(v.p3) > 2.0f);
|
assert(v.p1.distance_squared_to(v.p3) > 2.0f);
|
||||||
@@ -546,14 +433,16 @@ void Roads::generate_threaded(void *p_userdata)
|
|||||||
struct thread_data *data = (struct thread_data *)p_userdata;
|
struct thread_data *data = (struct thread_data *)p_userdata;
|
||||||
Roads *obj = Object::cast_to<Roads>(data->root);
|
Roads *obj = Object::cast_to<Roads>(data->root);
|
||||||
obj->mutex.lock();
|
obj->mutex.lock();
|
||||||
Vector3 p1 = obj->vshapes[data->vshape].p1;
|
RoadGrid *rg = RoadsData::get_singleton()->get_road_grid();
|
||||||
Vector3 p2 = obj->vshapes[data->vshape].p2;
|
const PoolVector<RoadGrid::vshape> &vshapes = rg->get_vshapes();
|
||||||
Vector3 p3 = obj->vshapes[data->vshape].p3;
|
Vector3 p1 = vshapes[data->vshape].p1;
|
||||||
|
Vector3 p2 = vshapes[data->vshape].p2;
|
||||||
|
Vector3 p3 = vshapes[data->vshape].p3;
|
||||||
obj->mutex.unlock();
|
obj->mutex.unlock();
|
||||||
int instance = obj->make_vmesh(obj, data->mat, data->mesh, data->xmi, p1, p2, p3, data->width, data->flags, data->sidewalk_width);
|
int instance = obj->make_vmesh(obj, data->mat, data->mesh, data->xmi, p1, p2, p3, data->width, data->flags, data->sidewalk_width);
|
||||||
assert(instance >= 0);
|
assert(instance >= 0);
|
||||||
obj->mutex.lock();
|
obj->mutex.lock();
|
||||||
obj->vshapes.write()[data->vshape].instance = instance;
|
rg->get_vshapes().write()[data->vshape].instance = instance;
|
||||||
obj->mutex.unlock();
|
obj->mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ protected:
|
|||||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
void update_all();
|
void update_all();
|
||||||
PoolVector<Vector3> vertices;
|
|
||||||
struct thread_data {
|
struct thread_data {
|
||||||
Thread thread;
|
Thread thread;
|
||||||
Ref<Material> mat;
|
Ref<Material> mat;
|
||||||
@@ -49,19 +48,9 @@ protected:
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
struct vshape {
|
|
||||||
AABB area;
|
|
||||||
int instance;
|
|
||||||
int e1, e2;
|
|
||||||
int site;
|
|
||||||
Vector3 p1, p2, p3;
|
|
||||||
};
|
|
||||||
#if 0
|
#if 0
|
||||||
PoolVector<struct edge_data> edges;
|
PoolVector<struct edge_data> edges;
|
||||||
#endif
|
#endif
|
||||||
PoolVector<struct vshape> vshapes;
|
|
||||||
void setup_vshapes();
|
|
||||||
void sort_angle(Vector<int> &sort_data);
|
|
||||||
#if 0
|
#if 0
|
||||||
void extrude_direct(Array &out, const Array &arrays, const struct edge_data *data) const;
|
void extrude_direct(Array &out, const Array &arrays, const struct edge_data *data) const;
|
||||||
void extrude_vshape(Array &out, const Array &arrays, const struct vshape *data) const;
|
void extrude_vshape(Array &out, const Array &arrays, const struct vshape *data) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user