feat: caching meshes and heightmaps
This commit is contained in:
parent
7dd18810c3
commit
b738f076c2
8 changed files with 66 additions and 124 deletions
|
|
@ -1,4 +1,4 @@
|
|||
- [ ] Cache chunk meshes
|
||||
- [x] Cache chunk meshes
|
||||
- [ ] Noise modifier
|
||||
- [ ] Min/Max modifier
|
||||
- [ ] Only load Defined chunks
|
||||
|
|
@ -6,3 +6,4 @@
|
|||
- [ ] Texturing step
|
||||
- [ ] Use Semaphores in mesh gen multi-threading
|
||||
- [ ] Separate files for terrain modifiers
|
||||
- [ ] Stop threads when generation finishes
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ void Terrain::_bind_methods() {
|
|||
BIND_HPROPERTY(Variant::OBJECT, mesh_material, PROPERTY_HINT_RESOURCE_TYPE, "Material");
|
||||
BIND_PROPERTY(Variant::INT, side_length);
|
||||
BIND_PROPERTY(Variant::INT, chunk_size);
|
||||
BIND_PROPERTY(Variant::INT, detail);
|
||||
BIND_PROPERTY(Variant::INT, thread_count);
|
||||
BIND_HPROPERTY(Variant::ARRAY, terrain_meshes, PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:TerrainMeshChunk", Variant::OBJECT, PROPERTY_HINT_NODE_TYPE), PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY);
|
||||
}
|
||||
|
||||
void Terrain::child_order_changed() {
|
||||
|
|
@ -85,15 +85,31 @@ void Terrain::_notification(int what) {
|
|||
switch (what) {
|
||||
default:
|
||||
return;
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
if (!is_ready()) {
|
||||
connect("child_order_changed", callable_mp(this, &self_type::child_order_changed));
|
||||
case NOTIFICATION_CHILD_ORDER_CHANGED:
|
||||
if (is_ready()) {
|
||||
this->child_order_changed();
|
||||
}
|
||||
return;
|
||||
case NOTIFICATION_READY:
|
||||
construct_chunk_grid();
|
||||
synchronous_generate_terrain();
|
||||
case NOTIFICATION_READY: {
|
||||
this->meshes.clear();
|
||||
this->modifiers.clear();
|
||||
for (Variant var : get_children()) {
|
||||
if (TerrainChunkMesh * mesh{ cast_to<TerrainChunkMesh>(var) }) {
|
||||
this->meshes.push_back(mesh);
|
||||
mesh->set_terrain(this);
|
||||
}
|
||||
if (TerrainModifier * mod{ cast_to<TerrainModifier>(var) }) {
|
||||
this->modifiers.push_back(mod);
|
||||
mod->set_terrain(this);
|
||||
}
|
||||
}
|
||||
size_t expected_size{ this->side_length / this->chunk_size };
|
||||
if (this->meshes.size() != expected_size * expected_size) {
|
||||
construct_chunk_grid();
|
||||
synchronous_generate_terrain();
|
||||
}
|
||||
return;
|
||||
}
|
||||
case NOTIFICATION_PROCESS:
|
||||
update_meshes();
|
||||
update_threads();
|
||||
|
|
@ -166,8 +182,9 @@ void Terrain::construct_chunk_grid() {
|
|||
chunk->set_terrain(this);
|
||||
chunk->set_material_override(this->mesh_material);
|
||||
chunk->set_position(origin + Vector3{ (float)this->chunk_size * (float)x, 0.f, (float)this->chunk_size * (float)y });
|
||||
chunk->set_name(vformat("Chunk%dx%d", x, y));
|
||||
add_child(chunk);
|
||||
chunk->set_owner(this);
|
||||
chunk->set_owner(get_owner());
|
||||
this->meshes.push_back(chunk);
|
||||
this->workload.push_back(chunk);
|
||||
}
|
||||
|
|
@ -269,3 +286,22 @@ void Terrain::set_thread_count(size_t num) {
|
|||
size_t Terrain::get_thread_count() const {
|
||||
return this->threads.size();
|
||||
}
|
||||
|
||||
void Terrain::set_terrain_meshes(Array array) {
|
||||
return;
|
||||
this->meshes.clear();
|
||||
for (Variant var : array) {
|
||||
if (TerrainChunkMesh * mesh{ cast_to<TerrainChunkMesh>(var) }) {
|
||||
mesh->set_terrain(this);
|
||||
this->meshes.push_back(mesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Array Terrain::get_terrain_meshes() const {
|
||||
Array a{};
|
||||
for (TerrainChunkMesh *mesh : this->meshes) {
|
||||
a.push_back(mesh);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,4 +55,6 @@ public:
|
|||
size_t get_detail() const;
|
||||
void set_thread_count(size_t num);
|
||||
size_t get_thread_count() const;
|
||||
void set_terrain_meshes(Array array);
|
||||
Array get_terrain_meshes() const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "terrain_chunk.h"
|
||||
#include "core/math/math_defs.h"
|
||||
#include "core/math/math_funcs.h"
|
||||
#include "core/object/object.h"
|
||||
#include "core/variant/variant.h"
|
||||
#include "scene/3d/physics/collision_shape_3d.h"
|
||||
#include "scene/3d/physics/static_body_3d.h"
|
||||
|
|
@ -8,7 +9,10 @@
|
|||
#include "scene/resources/surface_tool.h"
|
||||
#include "terrain/terrain.h"
|
||||
|
||||
void TerrainChunkMesh::_bind_methods() {}
|
||||
void TerrainChunkMesh::_bind_methods() {
|
||||
BIND_HPROPERTY(Variant::OBJECT, shape, PROPERTY_HINT_RESOURCE_TYPE, "HeightMapShape3D", PROPERTY_USAGE_READ_ONLY | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE);
|
||||
BIND_HPROPERTY(Variant::INT, size, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_READ_ONLY | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE);
|
||||
}
|
||||
|
||||
void TerrainChunkMesh::ready() {
|
||||
this->position_buffer = get_global_position();
|
||||
|
|
@ -22,11 +26,15 @@ void TerrainChunkMesh::ready() {
|
|||
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);
|
||||
if (this->shape.is_null()) {
|
||||
this->shape = memnew(HeightMapShape3D);
|
||||
this->shape->set_map_depth(heightmap_side_length());
|
||||
this->shape->set_map_width(heightmap_side_length());
|
||||
} else {
|
||||
this->heightmap.append_array(this->shape->get_map_data());
|
||||
}
|
||||
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() {
|
||||
|
|
@ -85,8 +93,10 @@ void TerrainChunkMesh::_notification(int what) {
|
|||
switch (what) {
|
||||
default:
|
||||
return;
|
||||
case NOTIFICATION_READY:
|
||||
ready();
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
if (!is_ready()) {
|
||||
ready();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ private:
|
|||
public:
|
||||
GET_SET_FNS(Rect2, bounds);
|
||||
GET_SET_FNS(Terrain *, terrain);
|
||||
GET_SET_FNS(Ref<HeightMapShape3D>, shape);
|
||||
GET_SET_FNS(size_t, detail);
|
||||
GET_SET_FNS(size_t, size);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ compatibility/default_parent_skeleton_in_mesh_instance_3d=true
|
|||
[application]
|
||||
|
||||
config/name="authority"
|
||||
run/main_scene="uid://1qvpc2ej32pd"
|
||||
run/main_scene="uid://ct2wadj5e8xsl"
|
||||
config/features=PackedStringArray("4.6", "Forward Plus")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
|
|
|
|||
BIN
project/scenes/terrain_test.scn
Normal file
BIN
project/scenes/terrain_test.scn
Normal file
Binary file not shown.
|
|
@ -1,108 +0,0 @@
|
|||
[gd_scene format=3 uid="uid://d2w73ie2k01xg"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://b2gybv8h8h0u0" path="res://assets/style/terrain_material.tres" id="1_w3uoq"]
|
||||
[ext_resource type="PackedScene" uid="uid://bedet0our63p0" path="res://objects/player_vehicle.tscn" id="2_o3i6r"]
|
||||
|
||||
[sub_resource type="Curve" id="Curve_o3i6r"]
|
||||
_limits = [0.0, 1.0, 0.0, 30.0]
|
||||
_data = [Vector2(0, 1), 0.0, -0.039764207, 0, 1, Vector2(18.735312, 0.25500518), -0.023317037, -0.023317037, 0, 0, Vector2(30, 0), -0.008611488, 0.0, 0, 0]
|
||||
point_count = 3
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_kbmr5"]
|
||||
|
||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_8mrfl"]
|
||||
sky_top_color = Color(0.28, 0.33600003, 0.56, 1)
|
||||
sky_horizon_color = Color(0.6590071, 0.7017287, 0.7452071, 1)
|
||||
ground_bottom_color = Color(0.18026966, 0.32224965, 0.43171933, 1)
|
||||
ground_horizon_color = Color(0.6590071, 0.7017287, 0.7452071, 1)
|
||||
|
||||
[sub_resource type="Sky" id="Sky_m8orc"]
|
||||
sky_material = SubResource("ProceduralSkyMaterial_8mrfl")
|
||||
|
||||
[sub_resource type="Environment" id="Environment_1b7vx"]
|
||||
background_mode = 4
|
||||
sky = SubResource("Sky_m8orc")
|
||||
ambient_light_source = 2
|
||||
ambient_light_color = Color(1, 1, 1, 1)
|
||||
ambient_light_energy = 0.77
|
||||
reflected_light_source = 1
|
||||
tonemap_mode = 2
|
||||
ssao_radius = 16.0
|
||||
ssao_intensity = 9.65
|
||||
ssao_power = 0.21446471
|
||||
ssao_detail = 0.0
|
||||
ssao_horizon = 0.57
|
||||
ssil_radius = 16.0
|
||||
ssil_intensity = 0.65
|
||||
fog_enabled = true
|
||||
fog_mode = 1
|
||||
fog_light_color = Color(0.49139997, 0.60203, 0.78, 1)
|
||||
fog_light_energy = 0.5
|
||||
fog_density = 0.0403
|
||||
fog_sky_affect = 0.0
|
||||
fog_depth_curve = 16.856052
|
||||
fog_depth_begin = 20.0
|
||||
fog_depth_end = 300.0
|
||||
|
||||
[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_7eqww"]
|
||||
dof_blur_far_enabled = true
|
||||
dof_blur_far_distance = 1000.0
|
||||
dof_blur_far_transition = 250.0
|
||||
dof_blur_near_enabled = true
|
||||
dof_blur_near_distance = 1.0
|
||||
dof_blur_amount = 0.15
|
||||
|
||||
[sub_resource type="Compositor" id="Compositor_n0ica"]
|
||||
|
||||
[sub_resource type="SphereMesh" id="SphereMesh_o3i6r"]
|
||||
flip_faces = true
|
||||
radius = 750.0
|
||||
height = 1500.0
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_chm2y"]
|
||||
shading_mode = 0
|
||||
diffuse_mode = 3
|
||||
specular_mode = 2
|
||||
disable_ambient_light = true
|
||||
disable_fog = true
|
||||
disable_specular_occlusion = true
|
||||
albedo_color = Color(0.37199998, 0.5951999, 0.93, 1)
|
||||
|
||||
[node name="Node3D" type="Node3D" unique_id=289500437]
|
||||
|
||||
[node name="Terrain" type="Terrain" parent="." unique_id=1169843565]
|
||||
mesh_material = ExtResource("1_w3uoq")
|
||||
side_length = 1000
|
||||
chunk_size = 100
|
||||
thread_count = 5
|
||||
|
||||
[node name="TerrainModifierComposite" type="TerrainModifierComposite" parent="Terrain" unique_id=831035468]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 93.48691, 13.848653, 332.4415)
|
||||
|
||||
[node name="TerrainModifierDistance" type="TerrainModifierDistance" parent="Terrain/TerrainModifierComposite" unique_id=1223634269]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4.1339216, 0)
|
||||
distance_weight_curve = SubResource("Curve_o3i6r")
|
||||
|
||||
[node name="TerrainModifierDistance2" type="TerrainModifierDistance" parent="Terrain/TerrainModifierComposite" unique_id=517982974]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4.1339216, 17.476501)
|
||||
distance_weight_curve = SubResource("Curve_o3i6r")
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1089775425]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 62.376347, 0.5, 364.3086)
|
||||
mesh = SubResource("BoxMesh_kbmr5")
|
||||
|
||||
[node name="PlayerVehicle" parent="." unique_id=2037675333 instance=ExtResource("2_o3i6r")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 59.221, 0.03404631, 364.57117)
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1509403058]
|
||||
environment = SubResource("Environment_1b7vx")
|
||||
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, 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