Compare commits

..

2 commits

Author SHA1 Message Date
Sara Gerretsen 6164be2def tweak: performance and scale 2025-11-22 23:53:37 +01:00
Sara Gerretsen c197f4c33b feat: groundwork for collision 2025-11-22 23:53:26 +01:00
4 changed files with 72 additions and 24 deletions

View file

@ -2,7 +2,9 @@
#include "core/config/engine.h" #include "core/config/engine.h"
#include "macros.h" #include "macros.h"
#include "scene/3d/camera_3d.h" #include "scene/3d/camera_3d.h"
#include "scene/3d/physics/static_body_3d.h"
#include "scene/main/viewport.h" #include "scene/main/viewport.h"
#include "scene/resources/mesh.h"
#include "terrain_editor/terrain_mesh_generator.h" #include "terrain_editor/terrain_mesh_generator.h"
void TerrainChunk::_bind_methods() { void TerrainChunk::_bind_methods() {
@ -17,15 +19,19 @@ void TerrainChunk::ready() {
print_error(vformat("Chunk %s ready without generator.", get_path())); print_error(vformat("Chunk %s ready without generator.", get_path()));
return; return;
} }
process_lod();
on_terrain_changed(); on_terrain_changed();
process_lod();
} }
void TerrainChunk::on_terrain_changed() { void TerrainChunk::on_terrain_changed() {
if (this->generator) { if (this->generator) {
Vector3 const position{ get_global_position() }; Vector3 const position{ get_global_position() };
this->meshes.resize_zeroed(5); this->meshes.resize_zeroed(3);
size_t lod{ 0 }; size_t lod{ 0 };
if (this->collisions) {
this->collisions->queue_free();
this->collisions = nullptr;
}
for (MeshStatus &status : this->meshes) { for (MeshStatus &status : this->meshes) {
if (!status.mesh.is_valid()) { if (!status.mesh.is_valid()) {
status.mesh.instantiate(); status.mesh.instantiate();
@ -39,7 +45,23 @@ void TerrainChunk::on_terrain_changed() {
} }
void TerrainChunk::lod_generated(size_t lod) { void TerrainChunk::lod_generated(size_t lod) {
this->meshes.set(lod, MeshStatus{ this->meshes[lod].mesh, false }); //if (this->collisions && lod <= this->collisions_lod && (lod == 0 || lod == (this->meshes.size() - 1))) {
#if 0
if (this->collisions && lod == this->meshes.size() - 1) {
this->collisions->queue_free();
this->collisions = nullptr;
}
if (!this->collisions) {
this->set_mesh(this->meshes[lod].mesh);
//static Ref<MeshConvexDecompositionSettings> settings{};
if ((this->collisions = create_multiple_convex_collisions_node())) {
add_child(this->collisions);
}
this->collisions_lod = lod;
}
#endif
this->meshes.set(lod, { this->meshes[lod].mesh, false });
process_lod();
} }
void TerrainChunk::process_lod() { void TerrainChunk::process_lod() {
@ -47,10 +69,11 @@ void TerrainChunk::process_lod() {
if (is_ready() && this->meshes.size() > 0) { if (is_ready() && this->meshes.size() > 0) {
Vector3 position{ get_global_position() }; Vector3 position{ get_global_position() };
Vector3 camera{ get_viewport()->get_camera_3d()->get_global_position() }; Vector3 camera{ get_viewport()->get_camera_3d()->get_global_position() };
position.y = camera.y = 0; Vector3 diff{ (position - camera).abs() };
float distance{ camera.distance_to(position) }; float distance{ (diff.x > diff.z ? diff.z : diff.x) - this->size };
size_t lod{ size_t(Math::floor(distance / (this->lod4_distance / 5.f))) }; distance = distance > 0.f ? distance : 0.f;
result = lod < 5 ? lod : 4; size_t lod{ size_t(Math::floor(distance / (this->lod_end_distance / this->meshes.size()))) };
result = lod < this->meshes.size() ? lod : (this->meshes.size() - 1);
while (this->meshes[result].dirty && result < (this->meshes.size() - 1)) { while (this->meshes[result].dirty && result < (this->meshes.size() - 1)) {
result++; result++;
} }

View file

@ -1,6 +1,5 @@
#pragma once #pragma once
#include "core/templates/pair.h"
#include "core/templates/vector.h" #include "core/templates/vector.h"
#include "scene/3d/mesh_instance_3d.h" #include "scene/3d/mesh_instance_3d.h"
class TerrainMeshGenerator; class TerrainMeshGenerator;
@ -27,9 +26,11 @@ public:
int get_lod0_detail() const; int get_lod0_detail() const;
private: private:
Node *collisions{ nullptr };
size_t collisions_lod{ 0 };
Vector<MeshStatus> meshes{}; Vector<MeshStatus> meshes{};
TerrainMeshGenerator *generator{ nullptr };
int lod0_detail{ 200 }; int lod0_detail{ 200 };
float lod4_distance{ 1500 }; float lod_end_distance{ 1000 };
float size{ 200 }; float size{ 200 };
TerrainMeshGenerator *generator{ nullptr };
}; };

View file

@ -4,3 +4,5 @@
[node name="TerrainChunk" type="TerrainChunk"] [node name="TerrainChunk" type="TerrainChunk"]
material_override = ExtResource("1_6vjd7") material_override = ExtResource("1_6vjd7")
size = 30.0
lod0_detail = 30

View file

@ -1,31 +1,48 @@
[gd_scene load_steps=13 format=3 uid="uid://xm383pc5pcnn"] [gd_scene load_steps=18 format=3 uid="uid://xm383pc5pcnn"]
[ext_resource type="PackedScene" uid="uid://cnux2fqne284i" path="res://objects/primitive_nodes/point_primitive_node.tscn" id="1_b1cmn"] [ext_resource type="PackedScene" uid="uid://cnux2fqne284i" path="res://objects/primitive_nodes/point_primitive_node.tscn" id="1_b1cmn"]
[ext_resource type="PackedScene" uid="uid://wkqhvjnxs2mx" path="res://objects/terrain_chunk.tscn" id="1_pxqd5"] [ext_resource type="PackedScene" uid="uid://wkqhvjnxs2mx" path="res://objects/terrain_chunk.tscn" id="1_pxqd5"]
[sub_resource type="PointPrimitive" id="PointPrimitive_pxqd5"] [sub_resource type="PointPrimitive" id="PointPrimitive_pxqd5"]
slope = -0.585 slope = -0.7
height = 200.0 height = 0.0
[sub_resource type="PointPrimitive" id="PointPrimitive_ba0ut"]
center = Vector2(50, 0)
slope = -0.7
[sub_resource type="FastNoiseLite" id="FastNoiseLite_pxqd5"] [sub_resource type="FastNoiseLite" id="FastNoiseLite_pxqd5"]
frequency = 0.02
fractal_octaves = 3 fractal_octaves = 3
[sub_resource type="NoisePrimitive" id="NoisePrimitive_ba0ut"] [sub_resource type="NoisePrimitive" id="NoisePrimitive_ba0ut"]
blend_range = 20.0 blend_range = 5.0
noise = SubResource("FastNoiseLite_pxqd5") noise = SubResource("FastNoiseLite_pxqd5")
noise_scale = 3.0 noise_amplitude = 20.0
noise_amplitude = 100.0
[sub_resource type="FastNoiseLite" id="FastNoiseLite_b1cmn"] [sub_resource type="FastNoiseLite" id="FastNoiseLite_b1cmn"]
noise_type = 0
frequency = 0.03
fractal_type = 2 fractal_type = 2
fractal_gain = 0.7
metadata/_preview_in_3d_space_ = true metadata/_preview_in_3d_space_ = true
[sub_resource type="NoisePrimitive" id="NoisePrimitive_pxqd5"] [sub_resource type="NoisePrimitive" id="NoisePrimitive_pxqd5"]
blend_range = 10.0 blend_range = 10.0
noise = SubResource("FastNoiseLite_b1cmn") noise = SubResource("FastNoiseLite_b1cmn")
noise_scale = 5.0 noise_amplitude = 5.0
noise_amplitude = 20.0
[sub_resource type="FastNoiseLite" id="FastNoiseLite_ba0ut"]
fractal_type = 2
fractal_gain = 1.0
fractal_weighted_strength = 0.58
[sub_resource type="NoisePrimitive" id="NoisePrimitive_q68jb"]
blend_mode = 1
noise = SubResource("FastNoiseLite_ba0ut")
[sub_resource type="PlanePrimitive" id="PlanePrimitive_pxqd5"]
blend_range = 10.0
baseline = -1.0
[sub_resource type="Gradient" id="Gradient_b1cmn"] [sub_resource type="Gradient" id="Gradient_b1cmn"]
interpolation_mode = 2 interpolation_mode = 2
@ -61,10 +78,10 @@ script/source = "extends Camera3D
var pan_speed = .001 var pan_speed = .001
var rotate_speed := .0015 var rotate_speed := .0015
var zoom_speed := 30.0 var zoom_speed := 5.0
var rotating := false var rotating := false
var panning := false var panning := false
var distance := 707 var distance := 50
var pivot := Vector3.ZERO var pivot := Vector3.ZERO
func _ready(): func _ready():
@ -101,13 +118,14 @@ func _unhandled_input(event: InputEvent) -> void:
global_position = (global_position - pivot).normalized() * distance + pivot global_position = (global_position - pivot).normalized() * distance + pivot
" "
[sub_resource type="CylinderMesh" id="CylinderMesh_pxqd5"]
[node name="Node3D" type="Node3D"] [node name="Node3D" type="Node3D"]
[node name="TerrainMeshEditor" type="TerrainMeshEditor" parent="."] [node name="TerrainMeshEditor" type="TerrainMeshEditor" parent="."]
primitives = [SubResource("PointPrimitive_pxqd5"), SubResource("NoisePrimitive_ba0ut"), SubResource("NoisePrimitive_pxqd5")] primitives = [SubResource("PointPrimitive_pxqd5"), SubResource("PointPrimitive_ba0ut"), SubResource("NoisePrimitive_ba0ut"), SubResource("NoisePrimitive_pxqd5"), SubResource("NoisePrimitive_q68jb"), SubResource("PlanePrimitive_pxqd5")]
vertex_color_gradient = SubResource("Gradient_b1cmn") vertex_color_gradient = SubResource("Gradient_b1cmn")
color_gradient_end_height = 200.0 color_gradient_end_height = 100.0
chunk_count = 5
chunk_scene = ExtResource("1_pxqd5") chunk_scene = ExtResource("1_pxqd5")
point_primitive_object = ExtResource("1_b1cmn") point_primitive_object = ExtResource("1_b1cmn")
@ -127,4 +145,8 @@ fov = 57.3
far = 2000.0 far = 2000.0
script = SubResource("GDScript_b1cmn") script = SubResource("GDScript_b1cmn")
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0)
mesh = SubResource("CylinderMesh_pxqd5")
[connection signal="primitives_changed" from="TerrainMeshEditor" to="TerrainMeshEditor" method="_on_primitives_changed"] [connection signal="primitives_changed" from="TerrainMeshEditor" to="TerrainMeshEditor" method="_on_primitives_changed"]