feat: apply_mesh for chunks is smeared over frames
This commit is contained in:
parent
226c821454
commit
1e44fcd09f
5 changed files with 47 additions and 11 deletions
|
|
@ -19,6 +19,23 @@ void Terrain::child_order_changed() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Terrain::update_meshes() {
|
||||||
|
size_t num{ 1 };
|
||||||
|
this->dirty_meshes_lock.lock();
|
||||||
|
num = num > this->dirty_meshes.size() ? this->dirty_meshes.size() : num;
|
||||||
|
this->dirty_meshes_lock.unlock();
|
||||||
|
for (size_t i{ 0 }; i < num; i++) {
|
||||||
|
this->dirty_meshes_lock.lock();
|
||||||
|
TerrainChunkMesh *mesh{ this->dirty_meshes[0] };
|
||||||
|
this->dirty_meshes.remove_at(0);
|
||||||
|
this->dirty_meshes_lock.unlock();
|
||||||
|
mesh->apply_new_mesh();
|
||||||
|
}
|
||||||
|
if (this->dirty_meshes.is_empty()) {
|
||||||
|
set_process(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Terrain::_notification(int what) {
|
void Terrain::_notification(int what) {
|
||||||
switch (what) {
|
switch (what) {
|
||||||
default:
|
default:
|
||||||
|
|
@ -31,6 +48,9 @@ void Terrain::_notification(int what) {
|
||||||
case NOTIFICATION_READY:
|
case NOTIFICATION_READY:
|
||||||
construct_chunk_grid();
|
construct_chunk_grid();
|
||||||
return;
|
return;
|
||||||
|
case NOTIFICATION_PROCESS:
|
||||||
|
update_meshes();
|
||||||
|
return;
|
||||||
case NOTIFICATION_EXIT_TREE:
|
case NOTIFICATION_EXIT_TREE:
|
||||||
this->workload_lock.lock();
|
this->workload_lock.lock();
|
||||||
this->threads_stop = true;
|
this->threads_stop = true;
|
||||||
|
|
@ -116,6 +136,13 @@ void Terrain::push_changed(Rect2 area) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Terrain::mesh_dirty(TerrainChunkMesh *mesh) {
|
||||||
|
this->dirty_meshes_lock.lock();
|
||||||
|
this->dirty_meshes.push_back(mesh);
|
||||||
|
callable_mp(cast_to<Node>(this), &self_type::set_process).call_deferred(true);
|
||||||
|
this->dirty_meshes_lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
void Terrain::set_side_length(size_t length) {
|
void Terrain::set_side_length(size_t length) {
|
||||||
this->side_length = length;
|
this->side_length = length;
|
||||||
if (is_inside_tree()) {
|
if (is_inside_tree()) {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ class Terrain : public Node {
|
||||||
GDCLASS(Terrain, Node);
|
GDCLASS(Terrain, Node);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
void child_order_changed();
|
void child_order_changed();
|
||||||
|
void update_meshes();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int what);
|
void _notification(int what);
|
||||||
|
|
@ -21,11 +22,16 @@ public:
|
||||||
void construct_chunk_grid();
|
void construct_chunk_grid();
|
||||||
float height_at(Vector2 world_coordinate);
|
float height_at(Vector2 world_coordinate);
|
||||||
void push_changed(Rect2 area);
|
void push_changed(Rect2 area);
|
||||||
|
void mesh_dirty(TerrainChunkMesh *mesh);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<TerrainChunkMesh *> workload{};
|
Vector<TerrainChunkMesh *> workload{};
|
||||||
Mutex workload_lock;
|
|
||||||
bool threads_stop{ false };
|
bool threads_stop{ false };
|
||||||
|
Mutex workload_lock;
|
||||||
|
|
||||||
|
Vector<TerrainChunkMesh *> dirty_meshes{};
|
||||||
|
Mutex dirty_meshes_lock{};
|
||||||
|
|
||||||
Vector<TerrainChunkMesh *> meshes{};
|
Vector<TerrainChunkMesh *> meshes{};
|
||||||
Vector<TerrainModifier *> modifiers{};
|
Vector<TerrainModifier *> modifiers{};
|
||||||
LocalVector<Thread> threads{};
|
LocalVector<Thread> threads{};
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,6 @@
|
||||||
|
|
||||||
void TerrainChunkMesh::_bind_methods() {}
|
void TerrainChunkMesh::_bind_methods() {}
|
||||||
|
|
||||||
void TerrainChunkMesh::apply_new_mesh() {
|
|
||||||
set_mesh(this->new_mesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TerrainChunkMesh::generate_vertices() {
|
void TerrainChunkMesh::generate_vertices() {
|
||||||
ERR_FAIL_COND_EDMSG(this->terrain == nullptr, "TerrainChunkMesh::generate_vertices: no terrain assigned");
|
ERR_FAIL_COND_EDMSG(this->terrain == nullptr, "TerrainChunkMesh::generate_vertices: no terrain assigned");
|
||||||
ERR_FAIL_COND_EDMSG(this->size <= 0.f, "TerrainChunkMesh::generate_vertices: size <= 0");
|
ERR_FAIL_COND_EDMSG(this->size <= 0.f, "TerrainChunkMesh::generate_vertices: size <= 0");
|
||||||
|
|
@ -68,6 +64,12 @@ void TerrainChunkMesh::_notification(int what) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TerrainChunkMesh::apply_new_mesh() {
|
||||||
|
this->lock.lock();
|
||||||
|
set_mesh(this->new_mesh);
|
||||||
|
this->lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
void TerrainChunkMesh::update_mesh() {
|
void TerrainChunkMesh::update_mesh() {
|
||||||
ERR_FAIL_COND_EDMSG(this->size <= 0.f, "TerrainChunkMesh::generate: size <= 0");
|
ERR_FAIL_COND_EDMSG(this->size <= 0.f, "TerrainChunkMesh::generate: size <= 0");
|
||||||
ERR_FAIL_COND_EDMSG(points_per_side() <= 0, "TerrainChunkMesh::generate: points per side <= 0");
|
ERR_FAIL_COND_EDMSG(points_per_side() <= 0, "TerrainChunkMesh::generate: points per side <= 0");
|
||||||
|
|
@ -80,8 +82,8 @@ void TerrainChunkMesh::update_mesh() {
|
||||||
this->surface->generate_tangents();
|
this->surface->generate_tangents();
|
||||||
this->new_mesh = memnew(ArrayMesh);
|
this->new_mesh = memnew(ArrayMesh);
|
||||||
this->surface->commit(this->new_mesh);
|
this->surface->commit(this->new_mesh);
|
||||||
callable_mp(this, &self_type::apply_new_mesh).call_deferred();
|
|
||||||
this->lock.unlock();
|
this->lock.unlock();
|
||||||
|
this->terrain->mesh_dirty(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TerrainChunkMesh::points_per_side() const {
|
size_t TerrainChunkMesh::points_per_side() const {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ class Terrain;
|
||||||
class TerrainChunkMesh : public MeshInstance3D {
|
class TerrainChunkMesh : public MeshInstance3D {
|
||||||
GDCLASS(TerrainChunkMesh, MeshInstance3D);
|
GDCLASS(TerrainChunkMesh, MeshInstance3D);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
void apply_new_mesh();
|
|
||||||
void generate_vertices();
|
void generate_vertices();
|
||||||
void generate_faces();
|
void generate_faces();
|
||||||
|
|
||||||
|
|
@ -18,6 +17,7 @@ protected:
|
||||||
void _notification(int what);
|
void _notification(int what);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void apply_new_mesh();
|
||||||
void update_mesh();
|
void update_mesh();
|
||||||
size_t points_per_side() const;
|
size_t points_per_side() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ point_count = 4
|
||||||
[sub_resource type="Curve" id="Curve_w3uoq"]
|
[sub_resource type="Curve" id="Curve_w3uoq"]
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_chm2y"]
|
[sub_resource type="Curve" id="Curve_chm2y"]
|
||||||
_limits = [0.0, 1.0, 0.0, 300.0]
|
_limits = [0.0, 1.0, 0.0, 200.0]
|
||||||
_data = [Vector2(0, 1), 0.0, -0.0043322877, 0, 0, Vector2(92.849304, 0.5972115), -0.0058290004, -0.0058290004, 0, 0, Vector2(300, 0), 0.00017739221, -0.05797184, 0, 0]
|
_data = [Vector2(0, 1), 0.0, -0.0043322877, 0, 0, Vector2(92.849304, 0.5972115), -0.0058290004, -0.0058290004, 0, 0, Vector2(199.46088, 0), 0.00017739221, -0.05797184, 0, 0]
|
||||||
point_count = 3
|
point_count = 3
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_o3i6r"]
|
[sub_resource type="Curve" id="Curve_o3i6r"]
|
||||||
|
|
@ -48,16 +48,17 @@ environment = SubResource("Environment_o3i6r")
|
||||||
|
|
||||||
[node name="Terrain" type="Terrain" parent="." unique_id=1169843565]
|
[node name="Terrain" type="Terrain" parent="." unique_id=1169843565]
|
||||||
side_length = 1000
|
side_length = 1000
|
||||||
|
chunk_size = 200
|
||||||
thread_count = 2
|
thread_count = 2
|
||||||
|
|
||||||
[node name="TerrainModifierDistance" type="TerrainModifierDistance" parent="Terrain" unique_id=1885116624]
|
[node name="TerrainModifierDistance" type="TerrainModifierDistance" parent="Terrain" unique_id=1885116624]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 544.8632, 188.56836, 713.1275)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 544.8632, 213.3872, 613.2415)
|
||||||
blend_distance = 4.0
|
blend_distance = 4.0
|
||||||
distance_weight_curve = SubResource("Curve_kbmr5")
|
distance_weight_curve = SubResource("Curve_kbmr5")
|
||||||
distance_height_curve = SubResource("Curve_w3uoq")
|
distance_height_curve = SubResource("Curve_w3uoq")
|
||||||
|
|
||||||
[node name="TerrainModifierDistance3" type="TerrainModifierDistance" parent="Terrain" unique_id=1846439541]
|
[node name="TerrainModifierDistance3" type="TerrainModifierDistance" parent="Terrain" unique_id=1846439541]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 534.7505, 273.91986, 453.44415)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 534.7505, 330.91986, 385.44415)
|
||||||
blend_distance = 4.0
|
blend_distance = 4.0
|
||||||
distance_weight_curve = SubResource("Curve_chm2y")
|
distance_weight_curve = SubResource("Curve_chm2y")
|
||||||
distance_height_curve = SubResource("Curve_o3i6r")
|
distance_height_curve = SubResource("Curve_o3i6r")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue