Updated godot, voxel module; fixed spawners; added C++ border and radial points calculation

This commit is contained in:
Segey Lapin
2021-10-29 00:58:53 +03:00
parent db6430230e
commit 7cad4daf2f
8 changed files with 131 additions and 35 deletions

View File

@@ -528,6 +528,7 @@ void RoadGrid::generate_3d_vertices(Ref<Curve> curve, Ref<FastNoiseLite> noise)
d = CLAMP(d, 1.0f, 30.0f);
diagram_vertex_heights.write[i] = d;
}
#if 0
for (j = 0; j < 3; j++) {
for (i = 0; i < map_hedges.size(); i++) {
int x1 = map_hedges[i]->a;
@@ -538,12 +539,51 @@ void RoadGrid::generate_3d_vertices(Ref<Curve> curve, Ref<FastNoiseLite> noise)
diagram_vertex_heights.write[x2] = diagram_vertex_heights[x1] + dh / fabsf(dh) * 0.01f * xd;
}
}
#endif
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;
}
smooth_heights();
}
void RoadGrid::smooth_heights()
{
int i;
float ok = true;
while (ok) {
for (i = 0; i < map_hedges.size(); i++) {
int a = map_hedges[i]->a;
int b = map_hedges[i]->b;
Vector3 p1 = vertices[a];
Vector3 p2 = vertices[b];
float dst = p1.distance_to(p2);
float h = fabsf(p2.y - p1.y);
if (dst <= 48.0f && h > 0.0f) {
ok = false;
float m = (p1.y + p2.y) * 0.5f;
m = CLAMP(m, 0.0f, 70.0f);
p1.y = m;
p2.y = m;
} else if (h > 0.0f) {
ok = false;
float t = h / dst;
if (t > 0.35) {
ok = false;
float m1 = p1.y + (p2.y - p1.y) / 10.0f;
float m2 = p2.y + (p1.y - p2.y) / 10.0f;
p1.y = m1;
p2.y = m2;
}
}
if (!ok) {
vertices.write()[map_hedges[i]->a] = p1;
vertices.write()[map_hedges[i]->b] = p2;
}
}
}
}
void RoadGrid::generate_building_positions()
@@ -680,6 +720,7 @@ void RoadGrid::save_json(const String &path)
f->close();
}
}
#if 0
PoolVector<Vector3> RoadGrid::get_site_border(int site)
{
const struct map_site &msite = map_sites[site];
@@ -716,4 +757,73 @@ PoolVector<Vector3> RoadGrid::get_site_border(int site)
assert(msite.polygon_ind.size() == ret.size());
return ret;
}
#endif
PoolVector<Vector3> RoadGrid::get_site_border(int site, float offt)
{
int k, i;
float height = get_site_avg_height(site);
PoolVector<Vector3> border;
PoolVector<Vector3> poly = get_site_polygon_3d(site);
if (poly.size() == 0)
return PoolVector<Vector3>();
border.resize(poly.size());
for (k = 0; k < poly.size(); k++) {
i = k - 1;
if (i < 0)
i += poly.size();
Vector3 p1 = poly[i];
Vector3 p2 = poly[k];
Vector3 p3 = poly[(k + 1) % poly.size()];
Vector2 p1x(p1.x, p1.z);
Vector2 p2x(p2.x, p2.z);
Vector2 p3x(p2.x, p2.z);
Vector2 p4x(p3.x, p3.z);
Vector2 n1 = (p2x - p1x).tangent().normalized();
Vector2 n2 = (p4x - p3x).tangent().normalized();
p1x -= n1 * offt;
p2x -= n1 * offt;
p3x -= n2 * offt;
p4x -= n2 * offt;
Vector2 xp;
if (!Geometry::segment_intersects_segment_2d(p1x, p2x, p3x, p4x, &xp))
xp = p2x.linear_interpolate(p3x, 0.5) - (n1 + n2).normalized() * offt;
Vector3 tp(xp.x, height, xp.y);
border.write()[k] = tp;
}
return border;
}
PoolVector<Vector3> RoadGrid::get_site_radial_points(int site, float bofft, float offt)
{
int i;
float height = get_site_avg_height(site), max_r = 0.0f;
PoolVector<Vector3> poly = get_site_border(site, bofft);
PoolVector<Vector3> ret;
if (poly.size() == 0)
return PoolVector<Vector3>();
List<Vector3> rpoints;
List<Vector3>::Element *e;
Vector3 center;
for (i = 0; i < poly.size(); i++)
center += poly[i];
center /= poly.size();
for (i = 0; i < poly.size(); i++) {
Vector3 ep1 = poly[i];
Vector3 ep2 = poly[(i + 1) % poly.size()];
Vector3 d = (ep2 - ep1).normalized();
rpoints.push_back(ep1);
float dst = ep1.distance_to(ep2);
while (dst > offt) {
ep1 += d * offt;
rpoints.push_back(ep1);
dst -= offt;
}
}
ret.resize(rpoints.size());
i = 0;
for (e = rpoints.front(); e; e = e->next())
ret.write()[i++] = e->get();
return ret;
}

View File

@@ -249,6 +249,7 @@ protected:
}
float grid_width, grid_height;
void sort_angle(Vector<int> &sort_data);
void smooth_heights();
public:
void build(Ref<Curve> curve, Ref<FastNoiseLite> noise);
void draw_debug(Node *drawable, int size_x, int size_y) const;
@@ -366,5 +367,7 @@ public:
{
return map_sites[site].site_type;
}
PoolVector<Vector3> get_site_border(int site, float offt);
PoolVector<Vector3> get_site_radial_points(int site, float bofft, float offt);
};
#endif

View File

@@ -564,12 +564,16 @@ void RoadsData::_bind_methods()
ClassDB::bind_method(D_METHOD("get_site_polygon_3d", "site"), &RoadsData::get_site_polygon_3d);
ClassDB::bind_method(D_METHOD("get_here_sites", "position"), &RoadsData::get_here_sites);
ClassDB::bind_method(D_METHOD("get_site_avg_height", "site"), &RoadsData::get_site_avg_height);
#if 0
ClassDB::bind_method(D_METHOD("get_site_border", "site"), &RoadsData::get_site_border);
#endif
ClassDB::bind_method(D_METHOD("site_is_town", "site"), &RoadsData::site_is_town);
ClassDB::bind_method(D_METHOD("site_is_farm", "site"), &RoadsData::site_is_farm);
ClassDB::bind_method(D_METHOD("get_site_count"), &RoadsData::get_site_count);
ClassDB::bind_method(D_METHOD("save_json", "path"), &RoadsData::save_json);
ClassDB::bind_method(D_METHOD("get_site_type", "site"), &RoadsData::get_site_type);
ClassDB::bind_method(D_METHOD("get_site_border", "site", "offt"), &RoadsData::get_site_border);
ClassDB::bind_method(D_METHOD("get_site_radial_points", "site", "bofft", "offt"), &RoadsData::get_site_radial_points);
}
void RoadsData::set_noise(Ref<FastNoiseLite> noise)
{

View File

@@ -128,10 +128,12 @@ public:
{
rg->save_json(path);
}
#if 0
inline PoolVector<Vector3> get_site_border(int site)
{
return rg->get_site_border(site);
}
#endif
inline int get_site_count() const
{
return rg->get_site_count();
@@ -140,5 +142,13 @@ public:
{
return rg->get_site_type(site);
}
inline PoolVector<Vector3> get_site_border(int site, float offt)
{
return rg->get_site_border(site, offt);
}
inline PoolVector<Vector3> get_site_radial_points(int site, float bofft, float offt)
{
return rg->get_site_radial_points(site, bofft, offt);
}
};

View File

@@ -60,7 +60,6 @@ void Spawner::place_scene(const StringName &name, const Transform &place)
struct spawn_object obj;
obj.xform = place;
obj.active = false;
obj.relative = false;
obj.instance = -1;
PoolVector<struct spawn_object> pos = positions[name];
pos.resize(pos.size() + 1);
@@ -72,21 +71,6 @@ void Spawner::place_scene(const StringName &name, const Transform &place)
}
void Spawner::place_scene_relative(const StringName &name, Node *parent, const Transform &place)
{
lock.lock();
if (scenes.has(name)) {
struct spawn_object obj;
obj.xform = place;
obj.active = false;
obj.relative = true;
obj.instance = -1;
obj.parent_instance = parent->get_instance_id();
PoolVector<struct spawn_object> pos = positions[name];
pos.resize(pos.size() + 1);
pos.write()[pos.size() - 1] = obj;
positions[name] = pos;
force_update = true;
}
lock.unlock();
}
void Spawner::update_view(Node *node, float distance)
{
@@ -109,30 +93,17 @@ void Spawner::update_view(Node *node, float distance)
int i;
PoolVector<struct spawn_object> pos = positions[*key];
for (i = 0; i < pos.size(); i++) {
Spatial *pnode = NULL;
if (pos[i].relative) {
Object *p = ObjectDB::get_instance(pos[i].parent_instance);
pnode = Object::cast_to<Spatial>(p);
assert(pnode);
}
if (!pos[i].active) {
Transform x = pos[i].xform;
Vector3 npos = x.origin;
if (pnode)
npos = pnode->get_global_transform().xform(npos);
float d = org.distance_squared_to(x.origin);
if (d < distance * distance) {
Node *pn = scenes[*key]->instance();
if (pn) {
Spatial *sp = Object::cast_to<Spatial>(pn);
if (sp) {
if (pnode) {
pnode->add_child(sp);
sp->set_transform(x);
} else {
view->add_child(sp);
sp->set_global_transform(x);
}
view->add_child(sp);
sp->set_global_transform(x);
pos.write()[i].instance = sp->get_instance_id();
pos.write()[i].active = true;
} else

View File

@@ -9,8 +9,6 @@ protected:
struct spawn_object {
Transform xform;
bool active;
bool relative;
int parent_instance;
int instance;
};
HashMap<String, PoolVector<struct spawn_object> > positions;