diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..588865c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +*.a +.*.swp +__pycache__ diff --git a/modules/world/road_grid.cpp b/modules/world/road_grid.cpp index 4563343..d9be4c9 100644 --- a/modules/world/road_grid.cpp +++ b/modules/world/road_grid.cpp @@ -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; } } diff --git a/modules/world/roads.cpp b/modules/world/roads.cpp index 9a8c76a..040c1cc 100644 --- a/modules/world/roads.cpp +++ b/modules/world/roads.cpp @@ -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 noise) +{ + this->noise = noise; +} +void RoadsData::set_curve(Ref 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; } - diff --git a/modules/world/roads.h b/modules/world/roads.h index e7395eb..1b71393 100644 --- a/modules/world/roads.h +++ b/modules/world/roads.h @@ -93,12 +93,17 @@ class RoadsData: public Object { protected: RoadGrid *rg; static void _bind_methods(); + Ref curve; + Ref 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 noise); + void set_curve(Ref curve); + float get_sdf(int x, int y, int z); }; diff --git a/modules/world/world_generator.cpp b/modules/world/world_generator.cpp index 1038cd6..2885279 100644 --- a/modules/world/world_generator.cpp +++ b/modules/world/world_generator.cpp @@ -90,7 +90,6 @@ Ref 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); diff --git a/modules/world/world_generator.h b/modules/world/world_generator.h index 9e8329c..468f5ed 100644 --- a/modules/world/world_generator.h +++ b/modules/world/world_generator.h @@ -52,7 +52,7 @@ private: static void _bind_methods(); protected: template - 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: