Now generating roads on terrain. Still some trouble left.

This commit is contained in:
Segey Lapin
2021-10-13 20:09:02 +03:00
parent 1b244e80ef
commit 2c7a6af437
6 changed files with 52 additions and 12 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*.o
*.a
.*.swp
__pycache__

View File

@@ -303,7 +303,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 < he->depth * he->depth) {
if (d < MAX(96.0f * 96.0f, he->depth * he->depth) + 96.0f * 96.0f) {
Vector2 ret;
ret.x = 1.0f;
assert(diagram_vertex_heights.size() > he->a);
@@ -315,7 +315,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;
ret.y = h - 0.5f;
return ret;
}
}

View File

@@ -197,8 +197,12 @@ void Roads::update_all()
mat = mesh->surface_get_material(0);
}
}
if (curve.is_valid() && noise.is_valid())
if (curve.is_valid() && noise.is_valid()) {
curve->bake();
RoadsData::get_singleton()->set_noise(noise);
RoadsData::get_singleton()->set_curve(curve);
rg->build(curve, noise);
}
printf("vertices: %d\n", rg->diagram_vertices.size());
printf("heights: %d\n", rg->diagram_vertex_heights.size());
printf("edges: %d\n", rg->map_hedges.size());
@@ -588,13 +592,35 @@ void RoadsData::destroy_singleton()
memdelete(g_roads_data);
g_roads_data = NULL;
}
RoadGrid *RoadsData::get_road_grid()
RoadGrid *RoadsData::get_road_grid() const
{
return rg;
}
void RoadsData::_bind_methods()
{
ClassDB::bind_method(D_METHOD("get_road_grid"), &RoadsData::get_road_grid);
ClassDB::bind_method(D_METHOD("get_sdf", "x", "y", "z"), &RoadsData::get_sdf);
}
void RoadsData::set_noise(Ref<OpenSimplexNoise> noise)
{
this->noise = noise;
}
void RoadsData::set_curve(Ref<Curve> curve)
{
this->curve = curve;
}
float RoadsData::get_sdf(int x, int y, int z)
{
if (!curve.is_valid() || !noise.is_valid())
return (float)y;
float n = curve->interpolate_baked(0.5f + noise->get_noise_2d(x, z) * 0.5f);
Vector2 ifl = rg->get_influence(x, z);
if (ifl.x > 0.0f) {
if (n <= ifl.y + 2.0f)
return (float)y - ifl.y;
else
return (float)y - ifl.y;
}
return y - n;
}

View File

@@ -93,12 +93,17 @@ class RoadsData: public Object {
protected:
RoadGrid *rg;
static void _bind_methods();
Ref<Curve> curve;
Ref<OpenSimplexNoise> noise;
public:
RoadsData();
~RoadsData();
static RoadsData *get_singleton();
static void create_singleton();
static void destroy_singleton();
RoadGrid *get_road_grid();
RoadGrid *get_road_grid() const;
void set_noise(Ref<OpenSimplexNoise> noise);
void set_curve(Ref<Curve> curve);
float get_sdf(int x, int y, int z);
};

View File

@@ -90,7 +90,6 @@ Ref<DensityMap> WorldGenerator::get_density_map() const
VoxelGenerator::Result WorldGenerator::generate_block(VoxelBlockRequest &input) {
ERR_FAIL_COND_V(input.voxel_buffer.is_null(), Result());
ERR_FAIL_COND_V(_noise.is_null(), Result());
#ifdef WORLD_MAP_TESTS
WorldMapData *wmd = WorldMapData::get_singleton();
@@ -101,8 +100,8 @@ VoxelGenerator::Result WorldGenerator::generate_block(VoxelBlockRequest &input)
#endif
Result result;
VoxelBuffer &out_buffer = **input.voxel_buffer;
WorldGenerator::generate(
VoxelBufferInternal &out_buffer = input.voxel_buffer;
result = WorldGenerator::generate(
out_buffer,
[this](int x, int y, int z) { return height_func(x, y, z); },
input.origin_in_voxels, input.lod);

View File

@@ -52,7 +52,7 @@ private:
static void _bind_methods();
protected:
template <typename Height_F>
void generate(VoxelBuffer &out_buffer, Height_F height_func, Vector3i origin, int lod) {
Result generate(VoxelBufferInternal &out_buffer, Height_F height_func, Vector3i origin, int lod) {
const int channel = _channel;
const Vector3i bs = out_buffer.get_size();
@@ -60,12 +60,16 @@ protected:
if (origin.y > get_height_start() + get_height_range()) {
// The bottom of the block is above the highest ground can go (default is air)
return;
Result result;
result.max_lod_hint = true;
return result;
}
if (origin.y + (bs.y << lod) < get_height_start()) {
// The top of the block is below the lowest ground can go
out_buffer.clear_channel(_channel, use_sdf ? 0 : _matter_type);
return;
Result result;
result.max_lod_hint = true;
return result;
}
const int stride = 1 << lod;
@@ -111,6 +115,8 @@ protected:
} // for x
} // for z
} // use_sdf
return Result();
}
private: