-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathvoxel_debug_info.gd
233 lines (191 loc) · 7.96 KB
/
voxel_debug_info.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# Debug stuff. A bunch of hotkeys that do things.
extends Node
const CollisionScannerScene = \
preload("res://addons/zylann.collision_scanner/collision_overlay.tscn")
const CollisionScannerOverlay = \
preload("res://addons/zylann.collision_scanner/collision_overlay.gd")
@export var enable_hotkeys := false
@onready var _solar_system : SolarSystem = get_parent()
func _ready():
enable_hotkeys = true
set_process_unhandled_input(enable_hotkeys)
func _unhandled_input(event: InputEvent):
if event is InputEventKey:
if event.pressed:
match event.keycode:
KEY_C:
_toggle_collision_scanner()
KEY_KP_2:
_debug_voxel_raycast_sweep()
KEY_O:
var vp := get_viewport()
if vp.debug_draw == Viewport.DEBUG_DRAW_OVERDRAW:
vp.debug_draw = Viewport.DEBUG_DRAW_DISABLED
else:
vp.debug_draw = Viewport.DEBUG_DRAW_OVERDRAW
KEY_P:
_dump_octree()
KEY_U:
print("PINNING VIEWER")
var cam := get_viewport().get_camera_3d()
var viewer : VoxelViewer = cam.get_node("VoxelViewer")
cam.remove_child(viewer)
add_child(viewer)
viewer.global_transform = cam.global_transform
KEY_M:
_log_pointed_mesh_block_info()
KEY_I:
print("Dumping planet as scene")
var current_planet := _solar_system.get_reference_stellar_body()
var err := current_planet.volume.debug_dump_as_scene(
"debug_scene_dump.scn", true)
if err != OK:
push_error(str("Error when dumping: ", err))
# KEY_KP_3:
# var current_planet = _solar_system.get_reference_stellar_body()
# if current_planet.instancer != null:
# current_planet.instancer.debug_log_edited_bocks()
func _log_pointed_mesh_block_info():
var current_planet := _solar_system.get_reference_stellar_body()
if current_planet == null or current_planet.volume == null:
print("No volume")
return
var volume := current_planet.volume
var vt : VoxelToolLodTerrain = volume.get_voxel_tool()
vt.set_raycast_binary_search_iterations(4)
var vtrans := volume.get_global_transform()
var vtrans_inv := vtrans.affine_inverse()
var cam := get_viewport().get_camera_3d()
var vp_size := Vector2(get_viewport().size)
var vp_center := vp_size / 2.0
var ray_pos_local := vtrans_inv * cam.project_ray_origin(vp_center)
var ray_dir_local := vtrans_inv.basis * cam.project_ray_normal(vp_center)
var hit := vt.raycast(ray_pos_local, ray_dir_local, 20)
if hit == null:
print("No hit")
return
var lod_index := 0
var bpos := volume.voxel_to_mesh_block_position(hit.position, lod_index)
var info := volume.debug_get_mesh_block_info(bpos, lod_index)
print("Info about mesh block ", bpos, " at lod ", lod_index, ":")
for key in info:
print("- ", key, ": ", info[key])
var render_to_data_factor := volume.get_mesh_block_size() / volume.get_data_block_size()
for lz in render_to_data_factor:
for ly in render_to_data_factor:
for lx in render_to_data_factor:
var lp := Vector3i(lx, ly, lz)
var dbpos := bpos * render_to_data_factor + lp
var data_info := volume.debug_get_data_block_info(dbpos, lod_index)
print("- data_block ", lp, ": ", data_info)
func _dump_octree():
var current_planet := _solar_system.get_reference_stellar_body()
var volume := current_planet.volume
if volume == null:
return
var data := volume.debug_get_octrees_detailed()
var f := ConfigFile.new()
var cam := get_viewport().get_camera_3d()
f.set_value("debug", "octree", data)
f.set_value("debug", "lod_count", volume.get_lod_count())
f.set_value("debug", "block_size", volume.get_mesh_block_size())
f.set_value("debug", "camera_transform", cam.global_transform)
f.save("debug_data/octree.dat")
func _debug_voxel_raycast_sweep():
var old_cubes := get_tree().get_nodes_in_group("ddd_ray_cubes")
for c in old_cubes:
c.queue_free()
var current_planet := _solar_system.get_reference_stellar_body()
var cube_mesh := BoxMesh.new()
cube_mesh.size = 0.1 * Vector3(1,1,1)
var volume := current_planet.volume
if volume != null:
var vt : VoxelToolLodTerrain = volume.get_voxel_tool()
vt.set_raycast_binary_search_iterations(4)
var vtrans := volume.get_global_transform()
var vtrans_inv := vtrans.affine_inverse()
var cam := get_viewport().get_camera_3d()
var vp_size := Vector2(get_viewport().size)
var vp_center := vp_size / 2
var vp_r := vp_size.y / 3
var ccount := 32
for cy in ccount:
for cx in ccount:
var ndc := Vector2(
float(cx) / float(ccount) - 0.5,
float(cy) / float(ccount) - 0.5)
var spos := vp_center + vp_r * ndc
var ray_pos_local := vtrans_inv * cam.project_ray_origin(spos)
var ray_dir_local := vtrans_inv.basis * cam.project_ray_normal(spos)
var hit := vt.raycast(ray_pos_local, ray_dir_local, 20)
if hit != null:
var mi := MeshInstance3D.new()
mi.mesh = cube_mesh
mi.position = vtrans * (ray_pos_local + ray_dir_local * hit.distance)
mi.add_to_group("ddd_ray_cubes")
add_child(mi)
func _toggle_collision_scanner():
if get_parent().has_node("CollisionOverlay"):
print("Turn off collision scanner")
get_parent().get_node("CollisionOverlay").queue_free()
else:
print("Turn on collision scanner")
var overlay : CollisionScannerOverlay = CollisionScannerScene.instantiate()
overlay.name = "CollisionOverlay"
overlay.set_restart_when_camera_transform_changes(false)
overlay.set_camera(get_viewport().get_camera_3d())
get_parent().add_child(overlay)
func _process(delta: float):
DDD.set_text("FPS", Engine.get_frames_per_second())
DDD.set_text("Static memory", _format_memory(OS.get_static_memory_usage()))
# Global stats
var global_stats := VoxelEngine.get_stats()
for group_key in ["tasks", "memory_pools"]:
var stats : Dictionary = global_stats[group_key]
for key in stats:
DDD.set_text(str(group_key, "_", key), stats[key])
var thread_pools_stats : Dictionary = global_stats["thread_pools"]
for thread_pool_name in thread_pools_stats:
var thread_pool_stats : Dictionary = thread_pools_stats[thread_pool_name]
var prefix := str("thread_pool_", thread_pool_name)
DDD.set_text(str(prefix, "_tasks"), thread_pool_stats["tasks"])
DDD.set_text(str(prefix, "_threads"),
str(thread_pool_stats["active_threads"], "/", thread_pool_stats["thread_count"]))
# var task_names = thread_pool_stats["task_names"]
# for i in len(task_names):
# var task_name = task_names[i]
# DDD.set_text(str(prefix, "_", i), task_name if task_name != null else "---")
# Planet stats
var current_planet := _solar_system.get_reference_stellar_body()
if current_planet != null and current_planet.volume != null:
var volume_stats := current_planet.volume.get_statistics()
DDD.set_text(str("[", current_planet.name, "] Blocked lods: "), volume_stats.blocked_lods)
_debug_voxel_raycast(current_planet.volume)
if current_planet.instancer != null:
var instance_counts := current_planet.instancer.debug_get_instance_counts()
var lib := current_planet.instancer.library
for item_id in instance_counts:
var item := lib.get_item(item_id)
var count : int = instance_counts[item_id]
DDD.set_text(str("Instances of ", item.name), count)
func _debug_voxel_raycast(volume: VoxelLodTerrain):
var vt : VoxelToolLodTerrain = volume.get_voxel_tool()
vt.set_raycast_binary_search_iterations(4)
var vtrans := volume.get_global_transform()
var vtrans_inv := vtrans.affine_inverse()
var cam := get_viewport().get_camera_3d()
var vp_size := Vector2(get_viewport().size)
var vp_center := vp_size / 2
var ray_pos_local := vtrans_inv * cam.project_ray_origin(vp_center)
var ray_dir_local := vtrans_inv.basis * cam.project_ray_normal(vp_center)
var hit := vt.raycast(ray_pos_local, ray_dir_local, 20)
if hit != null:
DDD.draw_box(vtrans * (Vector3(hit.position) + Vector3(0.5, 0.5, 0.5)),
Vector3(1.0, 1.0, 1.0), Color(0.5, 0.5, 0.5))
var wpos := vtrans * (ray_pos_local + ray_dir_local * hit.distance)
var s := 0.2
DDD.draw_box(wpos, Vector3(s, s, s), Color(0, 1, 0))
static func _format_memory(m: int) -> String:
var mb := m / 1000000
var mbr := m % 1000000
return str(mb, ".", mbr, " Mb")