fix: no gaps in terrain collision time/space
Terrain collision is generated before the first _process Terrain collision is generated from and to the edges of chunks with no gaps inbetween
This commit is contained in:
parent
9ea423a2cb
commit
da0419bc13
7 changed files with 104 additions and 39 deletions
|
|
@ -55,6 +55,32 @@ void Terrain::update_threads() {
|
|||
}
|
||||
}
|
||||
|
||||
void Terrain::synchronous_generate_terrain() {
|
||||
this->workload_lock.lock();
|
||||
this->threads_stop = false;
|
||||
this->workload.clear();
|
||||
this->workload.append_array(this->meshes);
|
||||
for (Thread &thread : this->threads) {
|
||||
if (!thread.is_started()) {
|
||||
thread.start(&Terrain::generate_meshes_thread, this);
|
||||
}
|
||||
}
|
||||
do {
|
||||
this->workload_lock.unlock();
|
||||
Thread::yield();
|
||||
this->workload_lock.lock();
|
||||
} while (!this->workload.is_empty());
|
||||
this->threads_stop = true;
|
||||
this->workload_lock.unlock();
|
||||
for (Thread &thread : this->threads) {
|
||||
thread.wait_to_finish();
|
||||
}
|
||||
for (TerrainChunkMesh *mesh : this->dirty_meshes) {
|
||||
mesh->apply_new_mesh();
|
||||
}
|
||||
this->dirty_meshes.clear();
|
||||
}
|
||||
|
||||
void Terrain::_notification(int what) {
|
||||
switch (what) {
|
||||
default:
|
||||
|
|
@ -66,6 +92,7 @@ void Terrain::_notification(int what) {
|
|||
return;
|
||||
case NOTIFICATION_READY:
|
||||
construct_chunk_grid();
|
||||
synchronous_generate_terrain();
|
||||
return;
|
||||
case NOTIFICATION_PROCESS:
|
||||
update_meshes();
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class Terrain : public Node {
|
|||
void child_order_changed();
|
||||
void update_meshes();
|
||||
void update_threads();
|
||||
void synchronous_generate_terrain();
|
||||
|
||||
protected:
|
||||
void _notification(int what);
|
||||
|
|
|
|||
|
|
@ -1,22 +1,54 @@
|
|||
#include "terrain_chunk.h"
|
||||
#include "core/math/math_defs.h"
|
||||
#include "core/math/math_funcs.h"
|
||||
#include "core/variant/variant.h"
|
||||
#include "scene/3d/physics/collision_shape_3d.h"
|
||||
#include "scene/3d/physics/static_body_3d.h"
|
||||
#include "scene/resources/3d/height_map_shape_3d.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
#include "terrain/terrain.h"
|
||||
|
||||
void TerrainChunkMesh::_bind_methods() {}
|
||||
|
||||
void TerrainChunkMesh::ready() {
|
||||
this->position_buffer = get_global_position();
|
||||
float const sizef{ (float)get_size() };
|
||||
this->bounds.position = { this->position_buffer.x - sizef / 2.f, this->position_buffer.z - sizef / 2.f };
|
||||
this->bounds.size = { sizef, sizef };
|
||||
|
||||
add_child(this->body = memnew(StaticBody3D));
|
||||
ERR_FAIL_COND_EDMSG(this->body == nullptr, "Failed to instantiate StaticBody3D");
|
||||
this->body->add_child(this->collider = memnew(CollisionShape3D));
|
||||
this->body->set_owner(this);
|
||||
ERR_FAIL_COND_EDMSG(this->collider == nullptr, "Failed to instantiate CollisionShape3D");
|
||||
this->collider->set_owner(this);
|
||||
this->shape = memnew(HeightMapShape3D);
|
||||
ERR_FAIL_COND_EDMSG(!this->shape.is_valid(), "Failed to instantiate HeightMapShape3D");
|
||||
this->collider->set_shape(this->shape);
|
||||
this->shape->set_map_depth(heightmap_side_length());
|
||||
this->shape->set_map_width(heightmap_side_length());
|
||||
}
|
||||
|
||||
void TerrainChunkMesh::generate_vertices() {
|
||||
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(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->safe_position - Vector3{ half_extent, 0, half_extent } };
|
||||
Vector3 origin{ this->position_buffer - 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 - this->safe_position.x, this->terrain->height_at(coordinate), coordinate.y - this->safe_position.z });
|
||||
float height{ this->terrain->height_at(coordinate) };
|
||||
this->surface->add_vertex({ coordinate.x - this->position_buffer.x, height, coordinate.y - this->position_buffer.z });
|
||||
}
|
||||
}
|
||||
this->heightmap.resize_initialized(heightmap_side_length() * heightmap_side_length());
|
||||
for (size_t x{ 0 }; x < heightmap_side_length(); x++) {
|
||||
for (size_t y{ 0 }; y < heightmap_side_length(); y++) {
|
||||
Vector2 coordinate{ origin.x + x, origin.z + y };
|
||||
this->heightmap.set(x + y * heightmap_side_length(), this->terrain->height_at(coordinate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -54,10 +86,7 @@ void TerrainChunkMesh::_notification(int what) {
|
|||
default:
|
||||
return;
|
||||
case NOTIFICATION_READY:
|
||||
this->safe_position = get_global_position();
|
||||
float const sizef{ (float)get_size() };
|
||||
this->bounds.position = { this->safe_position.x - sizef / 2.f, this->safe_position.z - sizef / 2.f };
|
||||
this->bounds.size = { sizef, sizef };
|
||||
ready();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -65,6 +94,11 @@ void TerrainChunkMesh::_notification(int what) {
|
|||
void TerrainChunkMesh::apply_new_mesh() {
|
||||
this->lock.lock();
|
||||
set_mesh(this->new_mesh);
|
||||
if (this->shape->get_map_depth() != heightmap_side_length() || this->shape->get_map_width() != heightmap_side_length()) {
|
||||
this->shape->set_map_depth(heightmap_side_length());
|
||||
this->shape->set_map_width(heightmap_side_length());
|
||||
}
|
||||
this->shape->set_map_data(heightmap);
|
||||
this->lock.unlock();
|
||||
}
|
||||
|
||||
|
|
@ -87,3 +121,7 @@ void TerrainChunkMesh::update_mesh() {
|
|||
size_t TerrainChunkMesh::points_per_side() const {
|
||||
return this->size * this->detail;
|
||||
}
|
||||
|
||||
int TerrainChunkMesh::heightmap_side_length() const {
|
||||
return get_size() + 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
#include "core/math/rect2.h"
|
||||
#include "macros.h"
|
||||
#include "scene/3d/mesh_instance_3d.h"
|
||||
#include "scene/3d/physics/collision_shape_3d.h"
|
||||
#include "scene/3d/physics/static_body_3d.h"
|
||||
#include "scene/resources/3d/height_map_shape_3d.h"
|
||||
#include "scene/resources/mesh.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
class Terrain;
|
||||
|
|
@ -10,6 +13,7 @@ class Terrain;
|
|||
class TerrainChunkMesh : public MeshInstance3D {
|
||||
GDCLASS(TerrainChunkMesh, MeshInstance3D);
|
||||
static void _bind_methods();
|
||||
void ready();
|
||||
void generate_vertices();
|
||||
void generate_faces();
|
||||
|
||||
|
|
@ -20,10 +24,11 @@ public:
|
|||
void apply_new_mesh();
|
||||
void update_mesh();
|
||||
size_t points_per_side() const;
|
||||
int heightmap_side_length() const;
|
||||
|
||||
private:
|
||||
Mutex lock{};
|
||||
Vector3 safe_position{};
|
||||
Vector3 position_buffer{};
|
||||
Ref<SurfaceTool> surface{};
|
||||
Ref<ArrayMesh> new_mesh{};
|
||||
Terrain *terrain{ nullptr };
|
||||
|
|
@ -31,6 +36,11 @@ private:
|
|||
size_t size{ 1 };
|
||||
Rect2 bounds{};
|
||||
|
||||
Ref<HeightMapShape3D> shape{};
|
||||
StaticBody3D *body{ nullptr };
|
||||
CollisionShape3D *collider{ nullptr };
|
||||
Vector<real_t> heightmap{};
|
||||
|
||||
public:
|
||||
GET_SET_FNS(Rect2, bounds);
|
||||
GET_SET_FNS(Terrain *, terrain);
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ shader_parameter/floor_3_tiling = 500.0
|
|||
shader_parameter/floor_3_specular = 0.5
|
||||
shader_parameter/floor_3_metallic = 0.5
|
||||
shader_parameter/region_blending = 1.0
|
||||
shader_parameter/slope_threshold = 0.355
|
||||
shader_parameter/slope_blend_distance = 0.028
|
||||
shader_parameter/slope_threshold = 0.3
|
||||
shader_parameter/slope_blend_distance = 0.0
|
||||
shader_parameter/slope_albedo = SubResource("NoiseTexture2D_pkl7k")
|
||||
shader_parameter/slope_tiling = 0.106
|
||||
shader_parameter/slope_roughness = 0.7
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_e6s0j"]
|
||||
render_priority = 1
|
||||
transparency = 2
|
||||
alpha_scissor_threshold = 1.0
|
||||
alpha_antialiasing_mode = 0
|
||||
transparency = 1
|
||||
shading_mode = 0
|
||||
albedo_color = Color(0, 0, 0, 1)
|
||||
grow = true
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ point_count = 2
|
|||
|
||||
[sub_resource type="Curve" id="Curve_4kj3c"]
|
||||
_limits = [0.0, 1.0, 0.0, 4.0]
|
||||
_data = [Vector2(0.78173465, 1), 0.0, 0.0, 0, 0, Vector2(3.0802917, 0), 0.0, 0.0, 0, 0]
|
||||
_data = [Vector2(1.1431929, 1), 0.0, 0.0, 0, 0, Vector2(3.4741035, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 2
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_kbmr5"]
|
||||
|
|
@ -96,8 +96,8 @@ dof_blur_amount = 0.15
|
|||
|
||||
[sub_resource type="SphereMesh" id="SphereMesh_o3i6r"]
|
||||
flip_faces = true
|
||||
radius = 1000.0
|
||||
height = 2000.0
|
||||
radius = 750.0
|
||||
height = 1500.0
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_chm2y"]
|
||||
shading_mode = 0
|
||||
|
|
@ -106,7 +106,7 @@ specular_mode = 2
|
|||
disable_ambient_light = true
|
||||
disable_fog = true
|
||||
disable_specular_occlusion = true
|
||||
albedo_color = Color(0.3, 0.42, 0.6, 1)
|
||||
albedo_color = Color(0.055481255, 0.09639085, 0.15917248, 1)
|
||||
|
||||
[node name="Node3D" type="Node3D" unique_id=289500437]
|
||||
|
||||
|
|
@ -376,7 +376,7 @@ transform = Transform3D(1.0000001, 0, 0, 0, 1, 0, 0, 0, 1.0000001, -9.991547, -6
|
|||
gizmo_extents = 5.0
|
||||
|
||||
[node name="TerrainModifierPathPoint23" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath16" unique_id=1120921338]
|
||||
transform = Transform3D(1.0000004, 0, 0, 0, 1, 0, 0, 0, 1.0000004, -14.902985, -4.79982, -20.752014)
|
||||
transform = Transform3D(1.0000007, 0, 0, 0, 1, 0, 0, 0, 1.0000007, -14.680634, -6.0471573, -22.171997)
|
||||
gizmo_extents = 5.0
|
||||
|
||||
[node name="TerrainModifierPath19" type="TerrainModifierPath" parent="Terrain" unique_id=1676642694]
|
||||
|
|
@ -451,11 +451,8 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.441101, 0.8837204, 19.30413
|
|||
[node name="TerrainModifierPathPoint21" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=1607100253]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.441101, 2.210205, 14.580994)
|
||||
|
||||
[node name="TerrainModifierPathPoint5" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=1820799746]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.534241, 5.0986557, 4.118469)
|
||||
|
||||
[node name="TerrainModifierPathPoint6" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=2116612387]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.9170227, 8.299988, -11.543091)
|
||||
[node name="TerrainModifierPathPoint23" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=2000472843]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.022736, 6.2285767, -4.9683228)
|
||||
|
||||
[node name="TerrainModifierPathPoint7" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=1272225499]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.5455017, 10.130386, -23.116821)
|
||||
|
|
@ -470,7 +467,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.5961, 11.085152, -18.563782
|
|||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 13.502441, 12.257561, -3.0429688)
|
||||
|
||||
[node name="TerrainModifierPathPoint11" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=43577796]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 13.093262, 12.385696, 10.487976)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.110291, 13.22065, 16.20935)
|
||||
|
||||
[node name="TerrainModifierPathPoint12" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=1921440501]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 11.920105, 13.9776535, 22.744324)
|
||||
|
|
@ -479,35 +476,26 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 11.920105, 13.9776535, 22.744
|
|||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.705017, 14.232437, 23.40039)
|
||||
|
||||
[node name="TerrainModifierPathPoint14" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=22432767]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 17.276093, 16.732018, 12.025452)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 16.127441, 15.883354, 15.772705)
|
||||
|
||||
[node name="TerrainModifierPathPoint16" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=159801860]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 17.724762, 18.037773, 3.9212646)
|
||||
|
||||
[node name="TerrainModifierPathPoint15" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=2059353099]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 17.2388, 19.639542, -3.52417)
|
||||
|
||||
[node name="TerrainModifierPathPoint17" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=1928936301]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 16.626587, 21.457283, -9.916443)
|
||||
|
||||
[node name="TerrainModifierPathPoint18" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=2071609159]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.835022, 22.994705, -16.712402)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 16.948792, 21.457283, -11.136475)
|
||||
|
||||
[node name="TerrainModifierPathPoint19" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=2055368136]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.000671, 24.554016, -23.884766)
|
||||
|
||||
[node name="TerrainModifierPathPoint20" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=1567587602]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 18.630096, 24.856354, -23.92749)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.000671, 24.39434, -23.884766)
|
||||
|
||||
[node name="TerrainModifierPathPoint22" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath17" unique_id=1457562552]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 24.136475, 25.229156, -20.645813)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 26.076569, 24.770523, -26.303467)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1089775425]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 430.6339, 81.57795, 686.2748)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 415.88525, 69.94918, 697.9054)
|
||||
mesh = SubResource("BoxMesh_kbmr5")
|
||||
|
||||
[node name="PlayerVehicle" parent="." unique_id=2037675333 instance=ExtResource("2_o3i6r")]
|
||||
transform = Transform3D(-0.1691032, -0.0145671945, -0.9854907, -0.0020476654, 0.99989396, -0.014428737, 0.9855962, -0.00042199076, -0.16911517, 542.1524, 107.626686, 693.53375)
|
||||
transform = Transform3D(-0.9999769, -0.002140658, -0.006432563, -0.0020476652, 0.9998938, -0.014428736, 0.006462857, -0.014415228, -0.99987507, 433.92926, 89.578415, 688.07916)
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1509403058]
|
||||
environment = SubResource("Environment_1b7vx")
|
||||
|
|
@ -515,6 +503,9 @@ camera_attributes = SubResource("CameraAttributesPractical_7eqww")
|
|||
compositor = SubResource("Compositor_n0ica")
|
||||
|
||||
[node name="SkySphere" type="MeshInstance3D" parent="." unique_id=56834935]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 482.60254, 3.9775167, 432.92352)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 543.9732, 3.9775777, 555.09717)
|
||||
mesh = SubResource("SphereMesh_o3i6r")
|
||||
surface_material_override/0 = SubResource("StandardMaterial3D_chm2y")
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="." unique_id=241002743]
|
||||
transform = Transform3D(-0.13388503, 0.50896627, -0.8503106, 0.0791636, 0.86078644, 0.5027721, 0.9878299, 0, -0.15553802, 388.02707, 99.978836, 697.3086)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue