From 48fa3404bd837efc6393992854aecb98fa3e0c37 Mon Sep 17 00:00:00 2001 From: Marc Gilleron Date: Thu, 12 Sep 2019 19:02:08 +0100 Subject: [PATCH] Fixed things for latest version --- project/blocky_terrain/avatar_interaction.gd | 63 +++++---- .../blocky_terrain/character_controller.gd | 12 -- project/blocky_terrain/main_with_saving.tscn | 131 ++++++++++++++++++ project/blocky_terrain/profiling_gui.gd | 32 ++++- project/dmc_terrain/block_debug.gd | 2 +- project/dmc_terrain/heightmap_stream_sdf.tres | 7 + project/dmc_terrain/interaction.gd | 31 +---- project/dmc_terrain/main_lod.gd | 29 +++- project/dmc_terrain/main_lod.tscn | 2 + project/dmc_terrain/main_lod_with_saving.tscn | 75 ++++++++++ .../dmc_terrain/noise_generator_stream.tres | 11 ++ project/dmc_test/main.gd | 4 +- project/spectator_avatar.tscn | 1 + 13 files changed, 328 insertions(+), 72 deletions(-) create mode 100644 project/blocky_terrain/main_with_saving.tscn create mode 100644 project/dmc_terrain/heightmap_stream_sdf.tres create mode 100644 project/dmc_terrain/main_lod_with_saving.tscn create mode 100644 project/dmc_terrain/noise_generator_stream.tres diff --git a/project/blocky_terrain/avatar_interaction.gd b/project/blocky_terrain/avatar_interaction.gd index ce2aa55..2d8606d 100644 --- a/project/blocky_terrain/avatar_interaction.gd +++ b/project/blocky_terrain/avatar_interaction.gd @@ -1,16 +1,21 @@ extends Node +const COLLISION_LAYER_AVATAR = 2 + export(NodePath) var terrain_path = null export(Material) var cursor_material = null -const COLLISION_LAYER_AVATAR = 2 +onready var _light = get_node("../../DirectionalLight") # For debug shadow toggle +onready var _head = get_parent().get_node("Camera") var _terrain = null +var _terrain_tool = null var _cursor = null var _action_place = false var _action_remove = false -onready var _head = get_parent().get_node("Camera") +var _inventory = [1, 2] +var _inventory_index = 0 func _ready(): @@ -21,12 +26,13 @@ func _ready(): _terrain = get_node(terrain_path) _cursor = _make_cursor() _terrain.add_child(_cursor) + _terrain_tool = _terrain.get_voxel_tool() func get_pointed_voxel(): var origin = _head.get_global_transform().origin var forward = -_head.get_transform().basis.z.normalized() - var hit = _terrain.raycast(origin, forward, 10) + var hit = _terrain_tool.raycast(origin, forward, 10) return hit @@ -45,22 +51,18 @@ func _physics_process(delta): # These inputs have to be in _fixed_process because they rely on collision queries if hit != null: - var has_cube = _terrain.get_storage().get_voxel_v(hit.position) != 0 + var has_cube = _terrain_tool.get_voxel(hit.position) != 0 if _action_place and has_cube: var pos = hit.position do_sphere(pos, 5, 0) - #_terrain.get_storage().set_voxel_v(0, pos) - #_terrain.make_voxel_dirty(pos) elif _action_remove: - var pos = hit.prev_position + var pos = hit.previous_position if has_cube == false: pos = hit.position if can_place_voxel_at(pos): - do_sphere(pos, 4, 2) - #_terrain.get_storage().set_voxel_v(2, pos) - #_terrain.make_voxel_dirty(pos) + do_sphere(pos, 4, _inventory[_inventory_index]) print("Place voxel at ", pos) else: print("Can't place here!") @@ -72,10 +74,29 @@ func _physics_process(delta): func _input(event): if event is InputEventMouseButton: if event.pressed: - if event.button_index == BUTTON_LEFT: - _action_place = true - elif event.button_index == BUTTON_RIGHT: - _action_remove = true + match event.button_index: + BUTTON_LEFT: + _action_place = true + BUTTON_RIGHT: + _action_remove = true + + elif event is InputEventKey: + if event.pressed: + match event.scancode: + KEY_1: + select_inventory(0) + KEY_2: + select_inventory(1) + KEY_L: + _light.shadow_enabled = not _light.shadow_enabled + + +func select_inventory(i): + if i < 0 or i >= len(_inventory): + return + _inventory_index = i + var vi = _inventory[i] + print("Inventory select ", _terrain.voxel_library.get_voxel(vi).voxel_name, " (", vi, ")") func can_place_voxel_at(pos): @@ -106,16 +127,10 @@ func _make_cursor(): func do_sphere(center, r, type): - var storage = _terrain.get_storage() - - for z in range(-r, r): - for x in range(-r, r): - for y in range(-r, r): - var pos = Vector3(x, y, z) - if pos.length() <= r: - storage.set_voxel_v(type, center + pos, 0) - - _terrain.make_area_dirty(AABB(center - Vector3(r,r,r), 2*Vector3(r,r,r))) + _terrain_tool.channel = VoxelBuffer.CHANNEL_TYPE + _terrain_tool.value = type + #_terrain_tool.do_sphere(center, r) + _terrain_tool.do_point(center) static func _add_wireframe_cube(st, pos, step, color): diff --git a/project/blocky_terrain/character_controller.gd b/project/blocky_terrain/character_controller.gd index 6e56fc9..aac0514 100644 --- a/project/blocky_terrain/character_controller.gd +++ b/project/blocky_terrain/character_controller.gd @@ -22,18 +22,6 @@ func _ready(): #set_shape_transform(0, Transform().rotated(Vector3(1,0,0), PI/2.0)) -func _input(event): - if event is InputEventKey: - if event.pressed: - if event.scancode == KEY_1: - var light = get_node("../DirectionalLight") - light.shadow_enabled = not light.shadow_enabled - - elif event.scancode == KEY_2: - OS.set_use_vsync(not OS.is_vsync_enabled()) - print("Vsync: ", OS.is_vsync_enabled()) - - func _physics_process(delta): var forward = _head.get_transform().basis.z.normalized() diff --git a/project/blocky_terrain/main_with_saving.tscn b/project/blocky_terrain/main_with_saving.tscn new file mode 100644 index 0000000..1378514 --- /dev/null +++ b/project/blocky_terrain/main_with_saving.tscn @@ -0,0 +1,131 @@ +[gd_scene load_steps=19 format=2] + +[ext_resource path="res://blocky_terrain/provider_image.tres" type="VoxelStreamImage" id=1] +[ext_resource path="res://axes.tscn" type="PackedScene" id=2] +[ext_resource path="res://grid.gd" type="Script" id=3] +[ext_resource path="res://blocky_terrain/terrain_marerial_transparent.tres" type="Material" id=4] +[ext_resource path="res://blocky_terrain/terrain_material.tres" type="Material" id=5] +[ext_resource path="res://blocky_terrain/profiling_gui.gd" type="Script" id=6] +[ext_resource path="res://blocky_terrain/debug3d.gd" type="Script" id=7] +[ext_resource path="res://blocky_terrain/character_avatar.tscn" type="PackedScene" id=8] + +[sub_resource type="ProceduralSky" id=1] +sky_top_color = Color( 0.268204, 0.522478, 0.847656, 1 ) +sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) +sky_curve = 0.25 +ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) +ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) +ground_curve = 0.01 +sun_curve = 0.0176777 +sun_energy = 16.0 + +[sub_resource type="Environment" id=2] +background_mode = 2 +background_sky = SubResource( 1 ) +ambient_light_color = Color( 0.0546875, 0.0546875, 0.0546875, 1 ) +ambient_light_sky_contribution = 0.7 +fog_enabled = true +fog_color = Color( 0.552734, 0.818359, 0.908691, 1 ) +fog_depth_begin = 40.0 +fog_height_min = -100.0 +fog_height_max = -50.0 +fog_height_curve = 0.965937 +ssao_blur = 1 +dof_blur_far_distance = 128.0 +dof_blur_far_transition = 10.0 +glow_hdr_threshold = 0.5 + +[sub_resource type="VoxelStreamRegionFiles" id=3] +fallback_stream = ExtResource( 1 ) +directory = "blocky_terrain/save" + +[sub_resource type="Voxel" id=4] +transparent = true + +[sub_resource type="Voxel" id=5] +voxel_name = "Dirt" +material_id = 0 +geometry_type = 1 +color = Color( 0.5, 1.0, 0.5, 1.0 ) +cube_geometry/padding_y = 0.0 +cube_tiles/left = Vector2( 0, 0 ) +cube_tiles/right = Vector2( 0, 0 ) +cube_tiles/bottom = Vector2( 0, 0 ) +cube_tiles/top = Vector2( 0, 0 ) +cube_tiles/back = Vector2( 0, 0 ) +cube_tiles/front = Vector2( 0, 0 ) + +[sub_resource type="Voxel" id=6] +voxel_name = "Water" +transparent = true +material_id = 1 +geometry_type = 1 +cube_geometry/padding_y = 0.0 +cube_tiles/left = Vector2( 2, 1 ) +cube_tiles/right = Vector2( 2, 1 ) +cube_tiles/bottom = Vector2( 2, 1 ) +cube_tiles/top = Vector2( 2, 1 ) +cube_tiles/back = Vector2( 2, 1 ) +cube_tiles/front = Vector2( 2, 1 ) + +[sub_resource type="VoxelLibrary" id=7] +atlas_size = 4 +voxels/0 = SubResource( 4 ) +voxels/1 = SubResource( 5 ) +voxels/2 = SubResource( 6 ) + +[sub_resource type="SpatialMaterial" id=8] +albedo_color = Color( 0.7, 0.7, 0.7, 1 ) +roughness = 0.0 + +[sub_resource type="SpatialMaterial" id=9] +flags_unshaded = true +vertex_color_use_as_albedo = true + +[sub_resource type="QuadMesh" id=10] + +[node name="Node" type="Node"] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource( 2 ) + +[node name="VoxelTerrain" type="VoxelTerrain" parent="."] +stream = SubResource( 3 ) +voxel_library = SubResource( 7 ) +view_distance = 256 +viewer_path = NodePath("../CharacterAvatar") +material/0 = ExtResource( 5 ) +material/1 = ExtResource( 4 ) + +[node name="Grid" type="MeshInstance" parent="."] +visible = false +material_override = SubResource( 8 ) +script = ExtResource( 3 ) +size = 8 + +[node name="DirectionalLight" type="DirectionalLight" parent="."] +transform = Transform( -0.985468, 0.124099, -0.11598, 0.0154004, 0.745271, 0.666584, 0.169159, 0.655111, -0.736353, 1.51966, 19.7004, 14.0879 ) +directional_shadow_normal_bias = 0.1 + +[node name="CharacterAvatar" parent="." instance=ExtResource( 8 )] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 58.0914, 17 ) +terrain = NodePath("../VoxelTerrain") + +[node name="axes" parent="." instance=ExtResource( 2 )] +visible = false + +[node name="ProfilingInfo" type="Label" parent="."] +margin_top = 20.0 +margin_right = 104.0 +margin_bottom = 34.0 +size_flags_vertical = 0 +script = ExtResource( 6 ) + +[node name="Debug3D" type="MeshInstance" parent="."] +material_override = SubResource( 9 ) +script = ExtResource( 7 ) + +[node name="MeshInstance2" type="MeshInstance" parent="."] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 3.24619, 16.9203, 17.301 ) +mesh = SubResource( 10 ) +material/0 = null diff --git a/project/blocky_terrain/profiling_gui.gd b/project/blocky_terrain/profiling_gui.gd index 3f4dc5f..8a49f6e 100644 --- a/project/blocky_terrain/profiling_gui.gd +++ b/project/blocky_terrain/profiling_gui.gd @@ -3,6 +3,12 @@ extends Label # Deferred because stats are reset everytime the terrain is processing, # so we make sure we get them always at the same point in time var _deferred_print_stats = false +var _span_timer = 0.0 +var _span_timer_interval = 0.5 +var _previous_file_count = 0 +var _previous_time_spent_opening_files = 0 +var _file_openings_per_second = 0 +var _time_spent_opening_files_per_second = 0 func _process(delta): @@ -21,19 +27,37 @@ func _process(delta): for i in len(stats.updater.remaining_blocks_per_thread): s += str("\nUpdater[", i, "]: ", stats.updater.remaining_blocks_per_thread[i]) + s += str("\nMain thread block updates: ", stats.remaining_main_thread_blocks) + + _span_timer -= delta + if _span_timer <= 0.0: + _span_timer = _span_timer_interval + + var file_openings = stats.stream.file_openings + var time_spent_opening_files = stats.stream.time_spent_opening_files + + _file_openings_per_second = int((file_openings - _previous_file_count) / _span_timer) + _time_spent_opening_files_per_second = int((time_spent_opening_files - _previous_time_spent_opening_files) / _span_timer) + + _previous_file_count = file_openings + _previous_time_spent_opening_files = time_spent_opening_files + + s += str("\nFile openings per second: ", _file_openings_per_second) + s += str("\nTime spent opening files per second: ", _time_spent_opening_files_per_second, " us") + set_text(s) - if stats.updater.mesh_alloc_time > 15: - print("Mesh alloc time is ", stats.updater.mesh_alloc_time, " for ", stats.updater.updated_blocks) + #if stats.updater.mesh_alloc_time > 15: + # print("Mesh alloc time is ", stats.updater.mesh_alloc_time, " for ", stats.updater.updated_blocks) if _deferred_print_stats: _deferred_print_stats = false print(str("Time stats:", \ "\t\n", "time_detect_required_blocks: ", stats.time_detect_required_blocks, " usec", \ - "\t\n", "time_send_load_requests: ", stats.time_send_load_requests, " usec", \ + "\t\n", "time_request_blocks_to_load: ", stats.time_request_blocks_to_load, " usec", \ "\t\n", "time_process_load_responses: ", stats.time_process_load_responses, " usec", \ - "\t\n", "time_send_update_requests: ", stats.time_send_update_requests, " usec", \ + "\t\n", "time_request_blocks_to_update: ", stats.time_request_blocks_to_update, " usec", \ "\t\n", "time_process_update_responses: ", stats.time_process_update_responses, " usec", \ "\t\n")) diff --git a/project/dmc_terrain/block_debug.gd b/project/dmc_terrain/block_debug.gd index ce1ea87..dcf9373 100644 --- a/project/dmc_terrain/block_debug.gd +++ b/project/dmc_terrain/block_debug.gd @@ -3,7 +3,7 @@ extends Control onready var _terrain = get_node("../VoxelTerrain") export var block_y_offset = 0 -var _lod_index = 1 +var _lod_index = 0 func _process(delta): diff --git a/project/dmc_terrain/heightmap_stream_sdf.tres b/project/dmc_terrain/heightmap_stream_sdf.tres new file mode 100644 index 0000000..931e6d3 --- /dev/null +++ b/project/dmc_terrain/heightmap_stream_sdf.tres @@ -0,0 +1,7 @@ +[gd_resource type="VoxelStreamImage" load_steps=2 format=2] + +[ext_resource path="res://blocky_terrain/noise_distorted.png" type="Image" id=1] + +[resource] +image = ExtResource( 1 ) +channel = 1 diff --git a/project/dmc_terrain/interaction.gd b/project/dmc_terrain/interaction.gd index 73fa5cf..6c105ef 100644 --- a/project/dmc_terrain/interaction.gd +++ b/project/dmc_terrain/interaction.gd @@ -40,31 +40,12 @@ func _process(delta): func do_sphere(center, fradius, add): - var storage = _terrain.get_storage() - var r = int(floor(fradius)) + 2 - var channel = VoxelBuffer.CHANNEL_ISOLEVEL - - var xc = int(floor(center.x)) - var yc = int(floor(center.y)) - var zc = int(floor(center.z)) - - for zi in range(-r, r): - for xi in range(-r, r): - for yi in range(-r, r): - var x = xi + xc - var y = yi + yc - var z = zi + zc - var pos = Vector3(x, y, z) - var d = pos.distance_to(center) - fradius - var e = storage.get_voxel_f(x, y, z, channel) - var res - if add: - res = min(d, e) - else: - res = max(-d, e) - storage.set_voxel_f(res, x, y, z, channel) - - _terrain.make_area_dirty(AABB(center - Vector3(r,r,r), 2*Vector3(r,r,r))) + var vt = _terrain.get_voxel_tool() + if add: + vt.mode = VoxelTool.MODE_ADD + else: + vt.mode = VoxelTool.MODE_REMOVE + vt.do_sphere(center, fradius) func print_map_slice(): diff --git a/project/dmc_terrain/main_lod.gd b/project/dmc_terrain/main_lod.gd index 757d0cc..2a44fae 100644 --- a/project/dmc_terrain/main_lod.gd +++ b/project/dmc_terrain/main_lod.gd @@ -7,9 +7,18 @@ var _process_stats = {} var _displayed_process_stats = {} var _time_before_display_process_stats = 1.0 +const _process_stat_names = [ + "time_detect_required_blocks", + "time_request_blocks_to_load", + "time_process_load_responses", + "time_request_blocks_to_update", + "time_process_update_responses", + "updated_blocks" +] + func _process(delta): - var stats = _terrain.get_stats() + var stats = _terrain.get_statistics() for i in len(stats.stream.remaining_blocks_per_thread): var remaining = stats.stream.remaining_blocks_per_thread[i] @@ -19,14 +28,16 @@ func _process(delta): var remaining = stats.updater.remaining_blocks_per_thread[i] DDD.set_text(str("Meshing blocks [", i, "]"), str(remaining)) + DDD.set_text("Main thread block updates", stats.remaining_main_thread_blocks) DDD.set_text("Static memory", _format_memory(OS.get_static_memory_usage())) DDD.set_text("Dynamic memory", _format_memory(OS.get_dynamic_memory_usage())) DDD.set_text("Blocked lods", stats.blocked_lods) DDD.set_text("Load sort time", stats.stream.sorting_time) DDD.set_text("Mesh sort time", stats.updater.sorting_time) + DDD.set_text("Position", _avatar.translation) - for k in stats.process: - var v = stats.process[k] + for k in _process_stat_names: + var v = stats[k] if k in _process_stats: _process_stats[k] = max(_process_stats[k], v) else: @@ -57,7 +68,17 @@ func _input(event): _print_map_state(_terrain, _avatar.global_transform.origin) elif event.scancode == KEY_N: - pretty_print(_terrain.get_stats()) + pretty_print(_terrain.get_statistics()) + + elif event.scancode == KEY_P: + get_tree().get_root().print_tree_pretty() + + elif event.scancode == KEY_O: + var vp = get_viewport() + if vp.debug_draw == Viewport.DEBUG_DRAW_DISABLED: + vp.debug_draw = Viewport.DEBUG_DRAW_OVERDRAW + else: + vp.debug_draw = Viewport.DEBUG_DRAW_DISABLED static func pretty_print(d, depth=0): diff --git a/project/dmc_terrain/main_lod.tscn b/project/dmc_terrain/main_lod.tscn index 27fbf63..bacbfe0 100644 --- a/project/dmc_terrain/main_lod.tscn +++ b/project/dmc_terrain/main_lod.tscn @@ -59,6 +59,8 @@ material/0 = ExtResource( 2 ) stream = SubResource( 5 ) viewer_path = NodePath("../SpectatorAvatar") material = ExtResource( 2 ) +lod_count = 8 +generate_collisions = false [node name="BlockDebug" type="Control" parent="."] modulate = Color( 1, 1, 1, 0.8 ) diff --git a/project/dmc_terrain/main_lod_with_saving.tscn b/project/dmc_terrain/main_lod_with_saving.tscn new file mode 100644 index 0000000..a4f44df --- /dev/null +++ b/project/dmc_terrain/main_lod_with_saving.tscn @@ -0,0 +1,75 @@ +[gd_scene load_steps=12 format=2] + +[ext_resource path="res://dmc_terrain/block_debug.gd" type="Script" id=1] +[ext_resource path="res://dmc_terrain/main_lod.gd" type="Script" id=2] +[ext_resource path="res://dmc_terrain/dmc_terrain_material.tres" type="Material" id=3] +[ext_resource path="res://dmc_terrain/interaction.gd" type="Script" id=4] +[ext_resource path="res://spectator_avatar.tscn" type="PackedScene" id=5] +[ext_resource path="res://dmc_terrain/noise_generator_stream.tres" type="VoxelStreamNoise" id=6] +[ext_resource path="res://axes.tscn" type="PackedScene" id=7] + +[sub_resource type="ProceduralSky" id=1] +sky_top_color = Color( 0.388235, 0.533333, 0.615686, 1 ) +sun_curve = 0.018301 + +[sub_resource type="Environment" id=2] +background_mode = 2 +background_sky = SubResource( 1 ) +ambient_light_sky_contribution = 0.5 +fog_enabled = true + +[sub_resource type="SphereMesh" id=3] + +[sub_resource type="VoxelStreamRegionFiles" id=4] +fallback_stream = ExtResource( 6 ) +directory = "res://dmc_terrain/save" +lod_count = 8 + +[node name="Node" type="Node"] +script = ExtResource( 2 ) + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource( 2 ) + +[node name="DirectionalLight" type="DirectionalLight" parent="."] +transform = Transform( 0.912457, -0.352848, 0.207171, 0, 0.506317, 0.862348, -0.409172, -0.786855, 0.461992, 14.4885, 6.21497, 0 ) +shadow_enabled = true +shadow_bias = 0.05 +directional_shadow_max_distance = 1000.0 + +[node name="Axes" parent="." instance=ExtResource( 7 )] + +[node name="SpectatorAvatar" parent="." instance=ExtResource( 5 )] +speed = 100.0 + +[node name="Camera" parent="SpectatorAvatar" index="0"] +far = 8000.0 + +[node name="OmniLight" type="OmniLight" parent="SpectatorAvatar"] +light_color = Color( 0.905882, 0.886275, 0.698039, 1 ) +omni_range = 100.462 + +[node name="Interaction" type="Node" parent="SpectatorAvatar"] +script = ExtResource( 4 ) + +[node name="MeshInstance" type="MeshInstance" parent="."] +mesh = SubResource( 3 ) +material/0 = ExtResource( 3 ) + +[node name="VoxelTerrain" type="VoxelLodTerrain" parent="."] +stream = SubResource( 4 ) +lod_count = 8 +viewer_path = NodePath("../SpectatorAvatar") +material = ExtResource( 3 ) + +[node name="BlockDebug" type="Control" parent="."] +visible = false +modulate = Color( 1, 1, 1, 0.8 ) +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_top = -311.0 +mouse_filter = 2 +script = ExtResource( 1 ) + +[editable path="SpectatorAvatar"] diff --git a/project/dmc_terrain/noise_generator_stream.tres b/project/dmc_terrain/noise_generator_stream.tres new file mode 100644 index 0000000..8360e98 --- /dev/null +++ b/project/dmc_terrain/noise_generator_stream.tres @@ -0,0 +1,11 @@ +[gd_resource type="VoxelStreamNoise" load_steps=2 format=2] + +[sub_resource type="OpenSimplexNoise" id=1] +octaves = 6 +period = 256.0 +persistence = 0.4 + +[resource] +noise = SubResource( 1 ) +height_start = -60.0 +height_range = 400.0 diff --git a/project/dmc_test/main.gd b/project/dmc_test/main.gd index 384f897..1bd0ff7 100644 --- a/project/dmc_test/main.gd +++ b/project/dmc_test/main.gd @@ -41,14 +41,14 @@ static func make_plane(pos, dir): func generate_with_stats(): - var stats_average = _mesher.get_stats() + var stats_average = _mesher.get_statistics() for k in stats_average: stats_average[k] = 0.0 var iterations = 1 for i in iterations: generate() - var stats = _mesher.get_stats() + var stats = _mesher.get_statistics() for k in stats: stats_average[k] += stats[k] diff --git a/project/spectator_avatar.tscn b/project/spectator_avatar.tscn index e5d7b2a..1ee015c 100644 --- a/project/spectator_avatar.tscn +++ b/project/spectator_avatar.tscn @@ -11,3 +11,4 @@ speed = 5.0 script = ExtResource( 1 ) sensitivity = 0.2 distance = 0.0 +far = 4000.0 \ No newline at end of file