feat: multithreading for terrain mesh gen

This commit is contained in:
Sara Gerretsen 2026-02-24 23:16:21 +01:00
parent d3561eb218
commit 8ff1b1404d
7 changed files with 130 additions and 30 deletions

View file

@ -11,12 +11,12 @@ void TerrainChunkMesh::generate_vertices() {
ERR_FAIL_COND_EDMSG(points_per_side() <= 0, "TerrainChunkMesh::generate_vertices: points per side <= 0");
float const half_extent{ (float)this->size / 2.f };
float const point_distance{ (float)this->size / ((float)points_per_side() - 1) };
Vector3 origin{ this->get_global_position() - Vector3{ half_extent, 0, half_extent } };
Vector3 origin{ this->safe_position - Vector3{ half_extent, 0, half_extent } };
for (size_t x{ 0 }; x < points_per_side(); ++x) {
for (size_t y{ 0 }; y < points_per_side(); ++y) {
Vector2 const coordinate{ origin.x + point_distance * x, origin.z + point_distance * y };
this->surface->set_uv({ (float)x / (float)points_per_side(), (float)y / (float)points_per_side() });
this->surface->add_vertex({ coordinate.x - get_global_position().x, this->terrain->height_at(coordinate), coordinate.y - get_global_position().z });
this->surface->add_vertex({ coordinate.x - this->safe_position.x, this->terrain->height_at(coordinate), coordinate.y - this->safe_position.z });
}
}
}
@ -51,17 +51,30 @@ void TerrainChunkMesh::generate_faces() {
}
}
void TerrainChunkMesh::_notification(int what) {
switch (what) {
default:
return;
case NOTIFICATION_READY:
if (!get_mesh().is_valid()) {
set_mesh(memnew(ArrayMesh));
}
this->safe_position = get_global_position();
return;
}
}
void TerrainChunkMesh::update_mesh() {
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");
this->set_mesh(memnew(ArrayMesh));
this->surface->clear();
this->surface->begin(Mesh::PRIMITIVE_TRIANGLES);
generate_vertices();
generate_faces();
this->surface->generate_normals();
this->surface->generate_tangents();
this->surface->commit(this->mesh);
callable_mp(Ref<ArrayMesh>(this->mesh).ptr(), &ArrayMesh::clear_surfaces).call_deferred();
callable_mp(Ref<ArrayMesh>(this->mesh).ptr(), &ArrayMesh::add_surface_from_arrays).call_deferred(Mesh::PRIMITIVE_TRIANGLES, this->surface->commit_to_arrays(), TypedArray<Array>(), Dictionary(), 0);
}
size_t TerrainChunkMesh::points_per_side() const {