Now generating roads on terrain. Still some trouble left.
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
.*.swp
|
||||||
|
__pycache__
|
||||||
@@ -303,7 +303,7 @@ Vector2 RoadGrid::get_influence(int x, int y) const
|
|||||||
Vector2 seg[] = {a, b};
|
Vector2 seg[] = {a, b};
|
||||||
Vector2 pt = Geometry::get_closest_point_to_segment_2d(p, seg);
|
Vector2 pt = Geometry::get_closest_point_to_segment_2d(p, seg);
|
||||||
float d = pt.distance_squared_to(p);
|
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;
|
Vector2 ret;
|
||||||
ret.x = 1.0f;
|
ret.x = 1.0f;
|
||||||
assert(diagram_vertex_heights.size() > he->a);
|
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 m1 = pt.distance_to(a) / l;
|
||||||
float m2 = CLAMP(1.0f - m1, 0.0f, 1.0f);
|
float m2 = CLAMP(1.0f - m1, 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;
|
ret.y = h - 0.5f;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,8 +197,12 @@ void Roads::update_all()
|
|||||||
mat = mesh->surface_get_material(0);
|
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);
|
rg->build(curve, noise);
|
||||||
|
}
|
||||||
printf("vertices: %d\n", rg->diagram_vertices.size());
|
printf("vertices: %d\n", rg->diagram_vertices.size());
|
||||||
printf("heights: %d\n", rg->diagram_vertex_heights.size());
|
printf("heights: %d\n", rg->diagram_vertex_heights.size());
|
||||||
printf("edges: %d\n", rg->map_hedges.size());
|
printf("edges: %d\n", rg->map_hedges.size());
|
||||||
@@ -588,13 +592,35 @@ void RoadsData::destroy_singleton()
|
|||||||
memdelete(g_roads_data);
|
memdelete(g_roads_data);
|
||||||
g_roads_data = NULL;
|
g_roads_data = NULL;
|
||||||
}
|
}
|
||||||
RoadGrid *RoadsData::get_road_grid()
|
RoadGrid *RoadsData::get_road_grid() const
|
||||||
{
|
{
|
||||||
return rg;
|
return rg;
|
||||||
}
|
}
|
||||||
void RoadsData::_bind_methods()
|
void RoadsData::_bind_methods()
|
||||||
{
|
{
|
||||||
ClassDB::bind_method(D_METHOD("get_road_grid"), &RoadsData::get_road_grid);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -93,12 +93,17 @@ class RoadsData: public Object {
|
|||||||
protected:
|
protected:
|
||||||
RoadGrid *rg;
|
RoadGrid *rg;
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
Ref<Curve> curve;
|
||||||
|
Ref<OpenSimplexNoise> noise;
|
||||||
public:
|
public:
|
||||||
RoadsData();
|
RoadsData();
|
||||||
~RoadsData();
|
~RoadsData();
|
||||||
static RoadsData *get_singleton();
|
static RoadsData *get_singleton();
|
||||||
static void create_singleton();
|
static void create_singleton();
|
||||||
static void destroy_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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ Ref<DensityMap> WorldGenerator::get_density_map() const
|
|||||||
|
|
||||||
VoxelGenerator::Result WorldGenerator::generate_block(VoxelBlockRequest &input) {
|
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());
|
ERR_FAIL_COND_V(_noise.is_null(), Result());
|
||||||
#ifdef WORLD_MAP_TESTS
|
#ifdef WORLD_MAP_TESTS
|
||||||
WorldMapData *wmd = WorldMapData::get_singleton();
|
WorldMapData *wmd = WorldMapData::get_singleton();
|
||||||
@@ -101,8 +100,8 @@ VoxelGenerator::Result WorldGenerator::generate_block(VoxelBlockRequest &input)
|
|||||||
#endif
|
#endif
|
||||||
Result result;
|
Result result;
|
||||||
|
|
||||||
VoxelBuffer &out_buffer = **input.voxel_buffer;
|
VoxelBufferInternal &out_buffer = input.voxel_buffer;
|
||||||
WorldGenerator::generate(
|
result = WorldGenerator::generate(
|
||||||
out_buffer,
|
out_buffer,
|
||||||
[this](int x, int y, int z) { return height_func(x, y, z); },
|
[this](int x, int y, int z) { return height_func(x, y, z); },
|
||||||
input.origin_in_voxels, input.lod);
|
input.origin_in_voxels, input.lod);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ private:
|
|||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
protected:
|
protected:
|
||||||
template <typename Height_F>
|
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 int channel = _channel;
|
||||||
const Vector3i bs = out_buffer.get_size();
|
const Vector3i bs = out_buffer.get_size();
|
||||||
@@ -60,12 +60,16 @@ protected:
|
|||||||
|
|
||||||
if (origin.y > get_height_start() + get_height_range()) {
|
if (origin.y > get_height_start() + get_height_range()) {
|
||||||
// The bottom of the block is above the highest ground can go (default is air)
|
// 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()) {
|
if (origin.y + (bs.y << lod) < get_height_start()) {
|
||||||
// The top of the block is below the lowest ground can go
|
// The top of the block is below the lowest ground can go
|
||||||
out_buffer.clear_channel(_channel, use_sdf ? 0 : _matter_type);
|
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;
|
const int stride = 1 << lod;
|
||||||
@@ -111,6 +115,8 @@ protected:
|
|||||||
} // for x
|
} // for x
|
||||||
} // for z
|
} // for z
|
||||||
} // use_sdf
|
} // use_sdf
|
||||||
|
|
||||||
|
return Result();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user