Added lod DMC terrain scene
This commit is contained in:
parent
17cd56dca0
commit
9328e96ad5
102
project/dmc_terrain/block_debug.gd
Normal file
102
project/dmc_terrain/block_debug.gd
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
extends Control
|
||||||
|
|
||||||
|
onready var _terrain = get_node("../VoxelTerrain")
|
||||||
|
|
||||||
|
export var block_y_offset = 0
|
||||||
|
var _lod_index = 1
|
||||||
|
|
||||||
|
|
||||||
|
func _process(delta):
|
||||||
|
update()
|
||||||
|
DDD.set_text("Debugged LOD", _lod_index)
|
||||||
|
|
||||||
|
|
||||||
|
func _input(event):
|
||||||
|
if event is InputEventKey:
|
||||||
|
if event.pressed:
|
||||||
|
|
||||||
|
if event.scancode == KEY_KP_8:
|
||||||
|
_lod_index += 1
|
||||||
|
if _lod_index >= _terrain.get_lod_count():
|
||||||
|
_lod_index = _terrain.get_lod_count() - 1
|
||||||
|
|
||||||
|
elif event.scancode == KEY_KP_2:
|
||||||
|
_lod_index -= 1
|
||||||
|
if _lod_index < 0:
|
||||||
|
_lod_index = 0
|
||||||
|
|
||||||
|
elif event.scancode == KEY_H:
|
||||||
|
visible = not visible
|
||||||
|
set_process(visible)
|
||||||
|
|
||||||
|
|
||||||
|
func draw_block_overlaps():
|
||||||
|
var ts0 = 8
|
||||||
|
var block_range_lod0 = 32
|
||||||
|
|
||||||
|
var viewer = _terrain.get_node(_terrain.viewer_path)
|
||||||
|
var viewer_pos = viewer.global_transform.origin
|
||||||
|
var viewer_block_pos_lod0 = _terrain.voxel_to_block_position(viewer_pos, 0)
|
||||||
|
var by0 = int(viewer_block_pos_lod0.y) + block_y_offset
|
||||||
|
var lod_count = _terrain.get_lod_count()
|
||||||
|
|
||||||
|
draw_rect(Rect2(0, 0, ts0 * block_range_lod0, ts0 * block_range_lod0), Color(0,0,0))
|
||||||
|
|
||||||
|
for lod_index in lod_count:
|
||||||
|
var block_range = block_range_lod0 >> lod_index
|
||||||
|
var red = float(lod_index) / float(lod_count)
|
||||||
|
for bz in block_range:
|
||||||
|
for bx in block_range:
|
||||||
|
var by = by0 >> lod_index
|
||||||
|
var ts = ts0 << lod_index
|
||||||
|
var info = _terrain.get_block_info(Vector3(bx, by, bz), lod_index)
|
||||||
|
if info.visible:
|
||||||
|
draw_rect(Rect2(bx * ts, bz * ts, ts, ts), Color(red, 1, 1, 0.5))
|
||||||
|
|
||||||
|
|
||||||
|
func _draw():
|
||||||
|
draw_block_states()
|
||||||
|
#draw_block_overlaps()
|
||||||
|
|
||||||
|
|
||||||
|
func draw_block_states():
|
||||||
|
var ts = 8
|
||||||
|
|
||||||
|
var viewer = _terrain.get_node(_terrain.viewer_path)
|
||||||
|
var viewer_pos = viewer.global_transform.origin
|
||||||
|
var viewer_block_pos = _terrain.voxel_to_block_position(viewer_pos, _lod_index)
|
||||||
|
var by = int(viewer_block_pos.y) + block_y_offset
|
||||||
|
|
||||||
|
for bz in 32:
|
||||||
|
for bx in 32:
|
||||||
|
|
||||||
|
var info = _terrain.get_block_info(Vector3(bx, by, bz), _lod_index)
|
||||||
|
|
||||||
|
var col = Color(0.1, 0.1, 0.1)
|
||||||
|
|
||||||
|
if info.loading == 1:
|
||||||
|
col = Color(0, 0, 0.5)
|
||||||
|
elif info.loading == 2:
|
||||||
|
if info.visible:
|
||||||
|
if info.meshed:
|
||||||
|
col = Color(1, 1, 1)
|
||||||
|
else:
|
||||||
|
col = Color(1, 0, 0)
|
||||||
|
else:
|
||||||
|
if info.meshed:
|
||||||
|
col = Color(0.5, 0.5, 0.5)
|
||||||
|
else:
|
||||||
|
col = Color(0.5, 0.0, 0)
|
||||||
|
|
||||||
|
# Flickering states
|
||||||
|
var now_ms = OS.get_ticks_msec()
|
||||||
|
var now = float(now_ms) / 1000.0
|
||||||
|
var ftime = float(info.debug_unexpected_drop_time) / 1000.0
|
||||||
|
var ft = 1.0 - clamp(now - ftime, 0.0, 1.0)
|
||||||
|
if ft > 0.0:
|
||||||
|
var fcolor = Color(1, 0, 1)
|
||||||
|
if (now_ms / 100) % 2 == 0:
|
||||||
|
fcolor = Color(0, 0, 0)
|
||||||
|
col = col.linear_interpolate(fcolor, ft)
|
||||||
|
|
||||||
|
draw_rect(Rect2(bx * ts, bz * ts, ts, ts), col)
|
142
project/dmc_terrain/main_lod.gd
Normal file
142
project/dmc_terrain/main_lod.gd
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
onready var _terrain = get_node("VoxelTerrain")
|
||||||
|
onready var _avatar = get_node("SpectatorAvatar")
|
||||||
|
|
||||||
|
var _process_stats = {}
|
||||||
|
var _displayed_process_stats = {}
|
||||||
|
var _time_before_display_process_stats = 1.0
|
||||||
|
|
||||||
|
|
||||||
|
func _process(delta):
|
||||||
|
var stats = _terrain.get_stats()
|
||||||
|
|
||||||
|
for i in len(stats.provider.remaining_blocks_per_thread):
|
||||||
|
var remaining = stats.provider.remaining_blocks_per_thread[i]
|
||||||
|
DDD.set_text(str("Loading blocks [", i, "]"), str(remaining))
|
||||||
|
|
||||||
|
for i in len(stats.updater.remaining_blocks_per_thread):
|
||||||
|
var remaining = stats.updater.remaining_blocks_per_thread[i]
|
||||||
|
DDD.set_text(str("Meshing blocks [", i, "]"), str(remaining))
|
||||||
|
|
||||||
|
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.provider.sorting_time)
|
||||||
|
DDD.set_text("Mesh sort time", stats.updater.sorting_time)
|
||||||
|
|
||||||
|
for k in stats.process:
|
||||||
|
var v = stats.process[k]
|
||||||
|
if k in _process_stats:
|
||||||
|
_process_stats[k] = max(_process_stats[k], v)
|
||||||
|
else:
|
||||||
|
_process_stats[k] = v
|
||||||
|
|
||||||
|
_time_before_display_process_stats -= delta
|
||||||
|
if _time_before_display_process_stats < 0:
|
||||||
|
_time_before_display_process_stats = 1.0
|
||||||
|
_displayed_process_stats = _process_stats
|
||||||
|
_process_stats = {}
|
||||||
|
|
||||||
|
for k in _displayed_process_stats:
|
||||||
|
DDD.set_text(k, _displayed_process_stats[k])
|
||||||
|
|
||||||
|
|
||||||
|
static func _format_memory(m):
|
||||||
|
var mb = m / 1000000
|
||||||
|
var mbr = m % 1000000
|
||||||
|
return str(mb, ".", mbr, " Mb")
|
||||||
|
|
||||||
|
|
||||||
|
func _input(event):
|
||||||
|
if event is InputEventKey:
|
||||||
|
if event.pressed:
|
||||||
|
|
||||||
|
if event.scancode == KEY_M:
|
||||||
|
print("Printing map state")
|
||||||
|
_print_map_state(_terrain, _avatar.global_transform.origin)
|
||||||
|
|
||||||
|
elif event.scancode == KEY_N:
|
||||||
|
pretty_print(_terrain.get_stats())
|
||||||
|
|
||||||
|
|
||||||
|
static func pretty_print(d, depth=0):
|
||||||
|
var indent = ""
|
||||||
|
for i in depth:
|
||||||
|
indent += " "
|
||||||
|
for k in d:
|
||||||
|
var v = d[k]
|
||||||
|
if typeof(v) == TYPE_DICTIONARY:
|
||||||
|
print(indent, k, ": ")
|
||||||
|
pretty_print(v, depth + 1)
|
||||||
|
else:
|
||||||
|
print(indent, k, ": ", d[k])
|
||||||
|
|
||||||
|
|
||||||
|
static func _print_map_state(terrain, avatar_pos):
|
||||||
|
var r = terrain.get_block_region_extent()
|
||||||
|
var im_w = 2 * r
|
||||||
|
var im_h = im_w
|
||||||
|
|
||||||
|
for lod_index in terrain.get_lod_count():
|
||||||
|
var avatar_block_pos = terrain.voxel_to_block_position(avatar_pos, lod_index)
|
||||||
|
|
||||||
|
for y in im_h:
|
||||||
|
var by = avatar_block_pos.y + y - r
|
||||||
|
|
||||||
|
var im = Image.new()
|
||||||
|
im.create(im_w, im_h, false, Image.FORMAT_RGB8)
|
||||||
|
im.fill(Color(0, 0, 0))
|
||||||
|
|
||||||
|
im.lock()
|
||||||
|
|
||||||
|
for z in im_w:
|
||||||
|
for x in im_h:
|
||||||
|
var bx = avatar_block_pos.x + x - r
|
||||||
|
var bz = avatar_block_pos.z + z - r
|
||||||
|
|
||||||
|
var info = terrain.get_block_info(Vector3(bx, by, bz), lod_index)
|
||||||
|
|
||||||
|
var col = Color(0.1, 0.1, 0.1)
|
||||||
|
|
||||||
|
if info.loading == 1:
|
||||||
|
col = Color(0, 0, 0.5)
|
||||||
|
elif info.loading == 2:
|
||||||
|
if info.visible:
|
||||||
|
if info.meshed:
|
||||||
|
col = Color(1, 1, 1)
|
||||||
|
else:
|
||||||
|
col = Color(1, 0, 0)
|
||||||
|
else:
|
||||||
|
if info.meshed:
|
||||||
|
col = Color(0.5, 0.5, 0.5)
|
||||||
|
else:
|
||||||
|
col = Color(0.5, 0.0, 0)
|
||||||
|
|
||||||
|
im.set_pixel(x, z, col)
|
||||||
|
|
||||||
|
im.unlock()
|
||||||
|
|
||||||
|
im.resize(im.get_width() * 16, im.get_height() * 16, Image.INTERPOLATE_NEAREST)
|
||||||
|
|
||||||
|
var fname = str("debug_data/lod", lod_index, "_y", y, ".png")
|
||||||
|
print("Saving ", fname)
|
||||||
|
im.save_png(fname)
|
||||||
|
|
||||||
|
if terrain.has_method("dump_block_history"):
|
||||||
|
var history = terrain.dump_block_history()
|
||||||
|
var json = JSON.print(history)
|
||||||
|
var f = File.new()
|
||||||
|
var fname = "debug_data/block_history.json"
|
||||||
|
print("Saving ", fname)
|
||||||
|
f.open(fname, File.WRITE)
|
||||||
|
f.store_string(json)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
print("Done")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
72
project/dmc_terrain/main_lod.tscn
Normal file
72
project/dmc_terrain/main_lod.tscn
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
[gd_scene load_steps=11 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://dmc_terrain/main_lod.gd" type="Script" id=1]
|
||||||
|
[ext_resource path="res://dmc_terrain/dmc_terrain_material.tres" type="Material" id=2]
|
||||||
|
[ext_resource path="res://axes.tscn" type="PackedScene" id=3]
|
||||||
|
[ext_resource path="res://spectator_avatar.tscn" type="PackedScene" id=4]
|
||||||
|
[ext_resource path="res://dmc_terrain/block_debug.gd" type="Script" id=5]
|
||||||
|
|
||||||
|
[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="OpenSimplexNoise" id=4]
|
||||||
|
octaves = 6
|
||||||
|
period = 256.0
|
||||||
|
persistence = 0.4
|
||||||
|
|
||||||
|
[sub_resource type="VoxelProviderNoise" id=5]
|
||||||
|
noise = SubResource( 4 )
|
||||||
|
height_range = 1200.0
|
||||||
|
|
||||||
|
[node name="Node" type="Node"]
|
||||||
|
script = ExtResource( 1 )
|
||||||
|
|
||||||
|
[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( 3 )]
|
||||||
|
|
||||||
|
[node name="SpectatorAvatar" parent="." instance=ExtResource( 4 )]
|
||||||
|
speed = 100.0
|
||||||
|
|
||||||
|
[node name="Camera" parent="SpectatorAvatar" index="0"]
|
||||||
|
far = 2000.0
|
||||||
|
|
||||||
|
[node name="OmniLight" type="OmniLight" parent="SpectatorAvatar"]
|
||||||
|
light_color = Color( 0.905882, 0.886275, 0.698039, 1 )
|
||||||
|
omni_range = 100.462
|
||||||
|
|
||||||
|
[node name="MeshInstance" type="MeshInstance" parent="."]
|
||||||
|
mesh = SubResource( 3 )
|
||||||
|
material/0 = ExtResource( 2 )
|
||||||
|
|
||||||
|
[node name="VoxelTerrain" type="VoxelLodTerrain" parent="."]
|
||||||
|
provider = SubResource( 5 )
|
||||||
|
viewer_path = NodePath("../SpectatorAvatar")
|
||||||
|
material = ExtResource( 2 )
|
||||||
|
|
||||||
|
[node name="BlockDebug" type="Control" parent="."]
|
||||||
|
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( 5 )
|
||||||
|
|
||||||
|
[editable path="SpectatorAvatar"]
|
@ -16,7 +16,7 @@ _global_script_class_icons={
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="New Game Project"
|
config/name="New Game Project"
|
||||||
run/main_scene="res://dmc_terrain/main.tscn"
|
run/main_scene="res://dmc_terrain/main_lod.tscn"
|
||||||
config/icon="res://icon.png"
|
config/icon="res://icon.png"
|
||||||
|
|
||||||
[autoload]
|
[autoload]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user