Cleaned up and updated project
@ -7,7 +7,6 @@ const COLLISION_LAYER_AVATAR = 2
|
||||
export(NodePath) var terrain_path = null
|
||||
export(Material) var cursor_material = null
|
||||
|
||||
onready var _light = get_node("../../DirectionalLight") # For debug shadow toggle
|
||||
onready var _head = get_parent().get_node("Camera")
|
||||
|
||||
var _terrain = null
|
||||
@ -16,7 +15,7 @@ var _cursor = null
|
||||
var _action_place = false
|
||||
var _action_remove = false
|
||||
|
||||
var _inventory = [1, 2]
|
||||
var _inventory = [1, 2, 3]
|
||||
var _inventory_index = 0
|
||||
|
||||
|
||||
@ -54,10 +53,10 @@ func _physics_process(delta):
|
||||
if hit != null:
|
||||
_cursor.show()
|
||||
_cursor.set_translation(hit.position)
|
||||
get_parent().get_node("debug_label").text = str(hit.position)
|
||||
DDD.set_text("Pointed voxel", str(hit.position))
|
||||
else:
|
||||
_cursor.hide()
|
||||
get_parent().get_node("debug_label").text = "---"
|
||||
DDD.set_text("Pointed voxel", "---")
|
||||
|
||||
# These inputs have to be in _fixed_process because they rely on collision queries
|
||||
if hit != null:
|
||||
@ -97,8 +96,8 @@ func _input(event):
|
||||
select_inventory(0)
|
||||
KEY_2:
|
||||
select_inventory(1)
|
||||
KEY_L:
|
||||
_light.shadow_enabled = not _light.shadow_enabled
|
||||
KEY_3:
|
||||
select_inventory(2)
|
||||
|
||||
|
||||
func select_inventory(i):
|
||||
|
@ -6,157 +6,62 @@
|
||||
[ext_resource path="res://blocky_terrain/crosshair.png" type="Texture" id=4]
|
||||
[ext_resource path="res://blocky_terrain/center.gd" type="Script" id=5]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[sub_resource type="SpatialMaterial" id=1]
|
||||
|
||||
flags_transparent = false
|
||||
flags_unshaded = false
|
||||
flags_vertex_lighting = false
|
||||
flags_no_depth_test = false
|
||||
flags_use_point_size = false
|
||||
flags_world_triplanar = false
|
||||
flags_fixed_size = false
|
||||
vertex_color_use_as_albedo = true
|
||||
vertex_color_is_srgb = false
|
||||
params_diffuse_mode = 0
|
||||
params_specular_mode = 0
|
||||
params_blend_mode = 0
|
||||
params_cull_mode = 0
|
||||
params_depth_draw_mode = 0
|
||||
params_line_width = 2.0
|
||||
params_point_size = 1.0
|
||||
params_billboard_mode = 0
|
||||
params_grow = false
|
||||
params_use_alpha_scissor = false
|
||||
albedo_color = Color( 1, 1, 1, 1 )
|
||||
metallic = 0.0
|
||||
metallic_specular = 0.5
|
||||
metallic_texture_channel = 0
|
||||
roughness = 0.0
|
||||
roughness_texture_channel = 0
|
||||
emission_enabled = false
|
||||
normal_enabled = false
|
||||
rim_enabled = false
|
||||
clearcoat_enabled = false
|
||||
anisotropy_enabled = false
|
||||
ao_enabled = false
|
||||
depth_enabled = false
|
||||
subsurf_scatter_enabled = false
|
||||
transmission_enabled = false
|
||||
refraction_enabled = false
|
||||
detail_enabled = false
|
||||
uv1_scale = Vector3( 1, 1, 1 )
|
||||
uv1_offset = Vector3( 0, 0, 0 )
|
||||
uv1_triplanar = false
|
||||
uv1_triplanar_sharpness = 1.0
|
||||
uv2_scale = Vector3( 1, 1, 1 )
|
||||
uv2_offset = Vector3( 0, 0, 0 )
|
||||
uv2_triplanar = false
|
||||
uv2_triplanar_sharpness = 1.0
|
||||
|
||||
[sub_resource type="CubeMesh" id=2]
|
||||
|
||||
size = Vector3( 0.8, 1.8, 0.8 )
|
||||
subdivide_width = 0
|
||||
subdivide_height = 0
|
||||
subdivide_depth = 0
|
||||
|
||||
[node name="CharacterAvatar" type="Spatial"]
|
||||
|
||||
script = ExtResource( 1 )
|
||||
speed = 10.0
|
||||
gravity = 40.0
|
||||
jump_force = 8.0
|
||||
head = NodePath("Camera")
|
||||
terrain = null
|
||||
|
||||
[node name="Camera" type="Camera" parent="."]
|
||||
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.702764, 0 )
|
||||
projection = 0
|
||||
current = true
|
||||
fov = 90.0
|
||||
near = 0.1
|
||||
far = 500.0
|
||||
keep_aspect = 1
|
||||
current = true
|
||||
cull_mask = 1048575
|
||||
environment = null
|
||||
h_offset = 0.0
|
||||
v_offset = 0.0
|
||||
doppler/tracking = 0
|
||||
script = ExtResource( 2 )
|
||||
_sections_unfolded = [ "Transform" ]
|
||||
sensitivity = 0.3
|
||||
min_angle = -90
|
||||
max_angle = 90
|
||||
capture_mouse = true
|
||||
distance = 4.0
|
||||
|
||||
[node name="interaction" type="Node" parent="."]
|
||||
|
||||
[node name="Interaction" type="Node" parent="."]
|
||||
script = ExtResource( 3 )
|
||||
terrain_path = null
|
||||
cursor_material = SubResource( 1 )
|
||||
|
||||
[node name="debug_label" type="Label" parent="."]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_right = 379.0
|
||||
margin_bottom = 325.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 2
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 0
|
||||
percent_visible = 1.0
|
||||
lines_skipped = 0
|
||||
max_lines_visible = -1
|
||||
|
||||
[node name="crosshair" type="Sprite" parent="."]
|
||||
|
||||
visible = false
|
||||
position = Vector2( 510.693, 285.793 )
|
||||
texture = ExtResource( 4 )
|
||||
script = ExtResource( 5 )
|
||||
|
||||
[node name="OmniLight" type="OmniLight" parent="."]
|
||||
|
||||
layers = 1
|
||||
visible = false
|
||||
light_color = Color( 1, 1, 0.533333, 1 )
|
||||
light_energy = 1.0
|
||||
light_negative = false
|
||||
light_specular = 0.5
|
||||
light_cull_mask = -1
|
||||
shadow_enabled = false
|
||||
shadow_color = Color( 0, 0, 0, 1 )
|
||||
shadow_bias = 0.1
|
||||
shadow_contact = 0.0
|
||||
shadow_reverse_cull_face = false
|
||||
editor_only = false
|
||||
omni_range = 10.0
|
||||
omni_attenuation = 2.54912
|
||||
omni_shadow_mode = 1
|
||||
omni_shadow_detail = 1
|
||||
|
||||
[node name="MeshInstance" type="MeshInstance" parent="."]
|
||||
|
||||
layers = 1
|
||||
material_override = null
|
||||
cast_shadow = 1
|
||||
extra_cull_margin = 0.0
|
||||
use_in_baked_light = false
|
||||
lod_min_distance = 0.0
|
||||
lod_min_hysteresis = 0.0
|
||||
lod_max_distance = 0.0
|
||||
lod_max_hysteresis = 0.0
|
||||
mesh = SubResource( 2 )
|
||||
skeleton = NodePath("..")
|
||||
material/0 = null
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="CenterContainer"]
|
||||
margin_left = 504.0
|
||||
margin_top = 292.0
|
||||
margin_right = 520.0
|
||||
margin_bottom = 308.0
|
||||
texture = ExtResource( 4 )
|
||||
|
@ -20,7 +20,6 @@ func _ready():
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
|
||||
var forward = _head.get_transform().basis.z.normalized()
|
||||
forward = Plane(Vector3(0, 1, 0), 0).project(forward)
|
||||
var right = _head.get_transform().basis.x.normalized()
|
||||
|
69
project/blocky_terrain/custom_mesh.obj
Normal file
@ -0,0 +1,69 @@
|
||||
# Blender v2.80 (sub 75) OBJ File: 'blocks.blend'
|
||||
# www.blender.org
|
||||
o Cube
|
||||
v 0.862249 0.394306 0.157047
|
||||
v 1.000000 0.000000 0.000000
|
||||
v 0.862249 0.394306 0.842953
|
||||
v 1.000000 0.000000 1.000000
|
||||
v 0.137751 0.790983 0.157047
|
||||
v 0.000000 0.000000 0.000000
|
||||
v 0.137751 0.790983 0.842953
|
||||
v 0.000000 0.000000 1.000000
|
||||
v 1.000000 0.318884 1.000000
|
||||
v 0.000000 0.866404 1.000000
|
||||
v 1.000000 0.318884 0.000000
|
||||
v 0.000000 0.866404 0.000000
|
||||
v 0.862249 0.182468 0.842953
|
||||
v 0.137751 0.182468 0.842953
|
||||
v 0.862249 0.182468 0.157047
|
||||
v 0.137751 0.182468 0.157047
|
||||
vt 0.590562 0.039262
|
||||
vt 0.590562 0.210738
|
||||
vt 0.590562 0.210738
|
||||
vt 0.590562 0.039262
|
||||
vt 0.375000 0.250000
|
||||
vt 0.625000 0.250000
|
||||
vt 0.625000 0.500000
|
||||
vt 0.375000 0.500000
|
||||
vt 0.625000 0.750000
|
||||
vt 0.375000 0.750000
|
||||
vt 0.625000 0.750000
|
||||
vt 0.625000 1.000000
|
||||
vt 0.375000 1.000000
|
||||
vt 0.125000 0.500000
|
||||
vt 0.375000 0.500000
|
||||
vt 0.375000 0.750000
|
||||
vt 0.125000 0.750000
|
||||
vt 0.625000 0.500000
|
||||
vt 0.875000 0.500000
|
||||
vt 0.875000 0.750000
|
||||
vt 0.409438 0.210738
|
||||
vt 0.625000 0.250000
|
||||
vt 0.375000 0.250000
|
||||
vt 0.409438 0.039262
|
||||
vt 0.375000 0.000000
|
||||
vt 0.625000 0.000000
|
||||
vt 0.409438 0.039262
|
||||
vt 0.409438 0.210738
|
||||
vn 1.0000 0.0000 -0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 0.4802 0.8771 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
s off
|
||||
f 5/1/1 7/2/1 14/3/1 16/4/1
|
||||
f 4/5/2 9/6/2 10/7/2 8/8/2
|
||||
f 8/8/3 10/7/3 12/9/3 6/10/3
|
||||
f 6/10/4 2/11/4 4/12/4 8/13/4
|
||||
f 2/14/1 11/15/1 9/16/1 4/17/1
|
||||
f 6/18/5 12/19/5 11/20/5 2/11/5
|
||||
f 3/21/6 7/2/6 10/22/6 9/23/6
|
||||
f 1/24/6 3/21/6 9/23/6 11/25/6
|
||||
f 7/2/6 5/1/6 12/26/6 10/22/6
|
||||
f 5/1/6 1/24/6 11/25/6 12/26/6
|
||||
f 15/27/7 16/4/7 14/3/7 13/28/7
|
||||
f 7/2/5 3/21/5 13/28/5 14/3/5
|
||||
f 1/24/2 5/1/2 16/4/2 15/27/2
|
||||
f 3/21/3 1/24/3 15/27/3 13/28/3
|
19
project/blocky_terrain/custom_mesh.obj.import
Normal file
@ -0,0 +1,19 @@
|
||||
[remap]
|
||||
|
||||
importer="wavefront_obj"
|
||||
type="Mesh"
|
||||
path="res://.import/custom_mesh.obj-87fe42838aa24483eaffe897aca10e00.mesh"
|
||||
|
||||
[deps]
|
||||
|
||||
files=[ "res://.import/custom_mesh.obj-87fe42838aa24483eaffe897aca10e00.mesh" ]
|
||||
|
||||
source_file="res://blocky_terrain/custom_mesh.obj"
|
||||
dest_files=[ "res://.import/custom_mesh.obj-87fe42838aa24483eaffe897aca10e00.mesh", "res://.import/custom_mesh.obj-87fe42838aa24483eaffe897aca10e00.mesh" ]
|
||||
|
||||
[params]
|
||||
|
||||
generate_tangents=true
|
||||
scale_mesh=Vector3( 1, 1, 1 )
|
||||
offset_mesh=Vector3( 0, 0, 0 )
|
||||
optimize_mesh=true
|
@ -1,109 +0,0 @@
|
||||
extends MeshInstance
|
||||
|
||||
|
||||
var _boxes = []
|
||||
var _colors = []
|
||||
var _mesh = null
|
||||
|
||||
# Who said "use ImmediateGeometry" node?
|
||||
|
||||
func draw_wire_box(box, color=Color(1,1,1,1)):
|
||||
_boxes.append(box)
|
||||
_colors.append(color)
|
||||
|
||||
|
||||
func _fixed_process(delta):
|
||||
|
||||
if _mesh == null:
|
||||
_mesh = ArrayMesh.new()
|
||||
mesh = _mesh
|
||||
|
||||
if _mesh.get_surface_count() != 0:
|
||||
_mesh.surface_remove(0)
|
||||
|
||||
var positions = PoolVector3Array()
|
||||
var colors = PoolColorArray()
|
||||
var indices = PoolIntArray()
|
||||
|
||||
for i in range(0, _boxes.size()):
|
||||
var box = _boxes[i]
|
||||
var color = _colors[i]
|
||||
|
||||
var vi = positions.size()
|
||||
|
||||
var pos = box.position
|
||||
var end = box.end
|
||||
|
||||
var x0 = pos.x
|
||||
var y0 = pos.y
|
||||
var z0 = pos.z
|
||||
|
||||
var x1 = end.x
|
||||
var y1 = end.y
|
||||
var z1 = end.z
|
||||
|
||||
positions.append_array([
|
||||
Vector3(x0, y0, z0),
|
||||
Vector3(x1, y0, z0),
|
||||
Vector3(x1, y0, z1),
|
||||
Vector3(x0, y0, z1),
|
||||
|
||||
Vector3(x0, y1, z0),
|
||||
Vector3(x1, y1, z0),
|
||||
Vector3(x1, y1, z1),
|
||||
Vector3(x0, y1, z1)
|
||||
])
|
||||
|
||||
colors.append_array([
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color,
|
||||
color
|
||||
])
|
||||
|
||||
indices.append_array([
|
||||
indices.append(vi),
|
||||
indices.append(vi+1),
|
||||
indices.append(vi+1),
|
||||
indices.append(vi+2),
|
||||
indices.append(vi+2),
|
||||
indices.append(vi+3),
|
||||
indices.append(vi+3),
|
||||
indices.append(vi),
|
||||
|
||||
indices.append(vi+4),
|
||||
indices.append(vi+5),
|
||||
indices.append(vi+5),
|
||||
indices.append(vi+6),
|
||||
indices.append(vi+6),
|
||||
indices.append(vi+7),
|
||||
indices.append(vi+7),
|
||||
indices.append(vi+4),
|
||||
|
||||
indices.append(vi),
|
||||
indices.append(vi+4),
|
||||
indices.append(vi+1),
|
||||
indices.append(vi+5),
|
||||
indices.append(vi+2),
|
||||
indices.append(vi+6),
|
||||
indices.append(vi+3),
|
||||
indices.append(vi+7)
|
||||
])
|
||||
|
||||
if positions.size() != 0:
|
||||
var arrays = []
|
||||
# TODO Use ArrayMesh.ARRAY_MAX
|
||||
arrays.resize(9)
|
||||
arrays[ArrayMesh.ARRAY_VERTEX] = positions
|
||||
arrays[ArrayMesh.ARRAY_COLOR] = colors
|
||||
arrays[ArrayMesh.ARRAY_INDEX] = indices
|
||||
|
||||
_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_LINES, arrays)
|
||||
|
||||
_boxes.clear()
|
||||
_colors.clear()
|
||||
|
27
project/blocky_terrain/debug_info.gd
Normal file
@ -0,0 +1,27 @@
|
||||
extends Node
|
||||
|
||||
onready var _terrain = get_parent().get_node("VoxelTerrain")
|
||||
|
||||
|
||||
func _process(delta):
|
||||
var dm = OS.get_dynamic_memory_usage()
|
||||
var sm = OS.get_static_memory_usage()
|
||||
|
||||
var stats = _terrain.get_statistics()
|
||||
|
||||
DDD.set_text("Dynamic memory", _format_memory(dm))
|
||||
DDD.set_text("Static memory", _format_memory(sm))
|
||||
|
||||
for i in len(stats.stream.remaining_blocks_per_thread):
|
||||
DDD.set_text(str("Stream[", i, "]"), stats.stream.remaining_blocks_per_thread[i])
|
||||
|
||||
for i in len(stats.updater.remaining_blocks_per_thread):
|
||||
DDD.set_text(str("Updater[", i, "]"), stats.updater.remaining_blocks_per_thread[i])
|
||||
|
||||
DDD.set_text("Main thread block updates", stats.remaining_main_thread_blocks)
|
||||
|
||||
|
||||
static func _format_memory(m):
|
||||
var mb = m / 1000000
|
||||
var mbr = m % 1000000
|
||||
return str(mb, ".", mbr, " Mb")
|
4
project/blocky_terrain/generator_waves_blocky.tres
Normal file
@ -0,0 +1,4 @@
|
||||
[gd_resource type="VoxelGeneratorWaves" load_steps=2 format=2]
|
||||
|
||||
[resource]
|
||||
channel = 0
|
13
project/blocky_terrain/main.gd
Normal file
@ -0,0 +1,13 @@
|
||||
extends Node
|
||||
|
||||
|
||||
onready var _light = $DirectionalLight
|
||||
|
||||
|
||||
func _unhandled_input(event):
|
||||
# TODO Make a pause menu with options?
|
||||
if event is InputEventKey:
|
||||
if event.pressed:
|
||||
if event.scancode == KEY_L:
|
||||
# Toggle shadows
|
||||
_light.shadow_enabled = not _light.shadow_enabled
|
@ -1,13 +1,12 @@
|
||||
[gd_scene load_steps=18 format=2]
|
||||
[gd_scene load_steps=10 format=2]
|
||||
|
||||
[ext_resource path="res://blocky_terrain/provider_image.tres" type="VoxelStreamImage" id=1]
|
||||
[ext_resource path="res://blocky_terrain/voxel_library.tres" type="VoxelLibrary" id=1]
|
||||
[ext_resource path="res://blocky_terrain/terrain_material.tres" type="Material" id=2]
|
||||
[ext_resource path="res://blocky_terrain/terrain_marerial_transparent.tres" type="Material" id=3]
|
||||
[ext_resource path="res://common/axes.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://common/grid.gd" type="Script" id=5]
|
||||
[ext_resource path="res://blocky_terrain/terrain_material_transparent.tres" type="Material" id=3]
|
||||
[ext_resource path="res://blocky_terrain/voxel_generator_noise_2d_blocky.tres" type="VoxelGeneratorNoise2D" id=4]
|
||||
[ext_resource path="res://blocky_terrain/main.gd" type="Script" id=5]
|
||||
[ext_resource path="res://blocky_terrain/character_avatar.tscn" type="PackedScene" id=6]
|
||||
[ext_resource path="res://blocky_terrain/profiling_gui.gd" type="Script" id=8]
|
||||
[ext_resource path="res://blocky_terrain/debug3d.gd" type="Script" id=9]
|
||||
[ext_resource path="res://blocky_terrain/debug_info.gd" type="Script" id=8]
|
||||
|
||||
[sub_resource type="ProceduralSky" id=1]
|
||||
sky_top_color = Color( 0.268204, 0.522478, 0.847656, 1 )
|
||||
@ -24,9 +23,9 @@ 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_depth_begin = 50.0
|
||||
fog_depth_end = 300.0
|
||||
fog_height_min = -100.0
|
||||
fog_height_max = -50.0
|
||||
fog_height_curve = 0.965937
|
||||
@ -35,87 +34,28 @@ dof_blur_far_distance = 128.0
|
||||
dof_blur_far_transition = 10.0
|
||||
glow_hdr_threshold = 0.5
|
||||
|
||||
[sub_resource type="Voxel" id=3]
|
||||
transparent = true
|
||||
|
||||
[sub_resource type="Voxel" id=4]
|
||||
geometry_type = 1
|
||||
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=5]
|
||||
geometry_type = 1
|
||||
cube_geometry/padding_y = 0.0
|
||||
cube_tiles/left = Vector2( 1, 0 )
|
||||
cube_tiles/right = Vector2( 1, 0 )
|
||||
cube_tiles/bottom = Vector2( 1, 0 )
|
||||
cube_tiles/top = Vector2( 1, 0 )
|
||||
cube_tiles/back = Vector2( 1, 0 )
|
||||
cube_tiles/front = Vector2( 1, 0 )
|
||||
|
||||
[sub_resource type="VoxelLibrary" id=6]
|
||||
atlas_size = 4
|
||||
voxels/0 = SubResource( 3 )
|
||||
voxels/1 = SubResource( 4 )
|
||||
voxels/2 = SubResource( 5 )
|
||||
|
||||
[sub_resource type="SpatialMaterial" id=7]
|
||||
albedo_color = Color( 0.7, 0.7, 0.7, 1 )
|
||||
roughness = 0.0
|
||||
|
||||
[sub_resource type="SpatialMaterial" id=8]
|
||||
flags_unshaded = true
|
||||
vertex_color_use_as_albedo = true
|
||||
|
||||
[sub_resource type="QuadMesh" id=9]
|
||||
|
||||
[node name="Node" type="Node"]
|
||||
[node name="Main" type="Node"]
|
||||
script = ExtResource( 5 )
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = SubResource( 2 )
|
||||
|
||||
[node name="VoxelTerrain" type="VoxelTerrain" parent="."]
|
||||
stream = ExtResource( 1 )
|
||||
voxel_library = SubResource( 6 )
|
||||
stream = ExtResource( 4 )
|
||||
voxel_library = ExtResource( 1 )
|
||||
view_distance = 256
|
||||
viewer_path = NodePath("../CharacterAvatar")
|
||||
material/0 = ExtResource( 2 )
|
||||
material/1 = ExtResource( 3 )
|
||||
|
||||
[node name="Grid" type="MeshInstance" parent="."]
|
||||
visible = false
|
||||
material_override = SubResource( 7 )
|
||||
script = ExtResource( 5 )
|
||||
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( 6 )]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 58.0914, 17 )
|
||||
terrain = NodePath("../VoxelTerrain")
|
||||
head = NodePath("../../Main/CharacterAvatar/Camera")
|
||||
terrain = NodePath("../../Main/VoxelTerrain")
|
||||
|
||||
[node name="axes" parent="." instance=ExtResource( 4 )]
|
||||
visible = false
|
||||
|
||||
[node name="ProfilingInfo" type="Label" parent="."]
|
||||
margin_top = 20.0
|
||||
margin_right = 104.0
|
||||
margin_bottom = 34.0
|
||||
size_flags_vertical = 0
|
||||
[node name="DebugInfo" type="Node" parent="."]
|
||||
script = ExtResource( 8 )
|
||||
|
||||
[node name="Debug3D" type="MeshInstance" parent="."]
|
||||
material_override = SubResource( 8 )
|
||||
script = ExtResource( 9 )
|
||||
|
||||
[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( 9 )
|
||||
material/0 = null
|
||||
|
@ -1,133 +0,0 @@
|
||||
[gd_scene load_steps=19 format=2]
|
||||
|
||||
[ext_resource path="res://blocky_terrain/provider_image.tres" type="VoxelStreamImage" id=1]
|
||||
[ext_resource path="res://common/axes.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://common/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
|
Before Width: | Height: | Size: 654 KiB |
@ -1,13 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="image"
|
||||
type="Image"
|
||||
path="res://.import/noise_distorted.png-431e74ee8f15629296a2c1f483b52286.image"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://blocky_terrain/noise_distorted.png"
|
||||
dest_files=[ "res://.import/noise_distorted.png-431e74ee8f15629296a2c1f483b52286.image" ]
|
||||
|
||||
[params]
|
||||
|
@ -1,115 +0,0 @@
|
||||
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):
|
||||
var dm = OS.get_dynamic_memory_usage()
|
||||
var sm = OS.get_static_memory_usage()
|
||||
|
||||
var terrain = get_parent().get_node("VoxelTerrain")
|
||||
var stats = terrain.get_statistics()
|
||||
|
||||
var s = str("Dynamic memory: ", _format_memory(dm), \
|
||||
"\nStatic memory: ", _format_memory(sm))
|
||||
|
||||
for i in len(stats.stream.remaining_blocks_per_thread):
|
||||
s += str("\nStream[", i, "]: ", stats.stream.remaining_blocks_per_thread[i])
|
||||
|
||||
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 _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_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_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"))
|
||||
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventKey:
|
||||
if event.pressed:
|
||||
if event.scancode == KEY_F4:
|
||||
_deferred_print_stats = true
|
||||
|
||||
|
||||
func _draw():
|
||||
if not Input.is_key_pressed(KEY_F3):
|
||||
return
|
||||
var terrain = get_parent().get_node("VoxelTerrain")
|
||||
var avatar = get_parent().get_node("CharacterAvatar")
|
||||
|
||||
var center_bpos = terrain.voxel_to_block(avatar.translation)
|
||||
var ry = 1
|
||||
var rx = 20
|
||||
var rz = 20
|
||||
|
||||
var gui_origin = Vector2(400, 100)
|
||||
var a = 0.3
|
||||
var w = 4
|
||||
|
||||
for y in range(-ry, ry):
|
||||
for z in range(-rz, rz):
|
||||
for x in range(-rx, rx):
|
||||
|
||||
var bpos = center_bpos + Vector3(x, y, z)
|
||||
var state = terrain.get_block_state(bpos)
|
||||
var col
|
||||
|
||||
match state:
|
||||
VoxelTerrain.BLOCK_NONE:
|
||||
col = Color(0, 0, 0, a)
|
||||
|
||||
VoxelTerrain.BLOCK_LOAD:
|
||||
col = Color(1, 0, 0, a)
|
||||
|
||||
VoxelTerrain.BLOCK_UPDATE_NOT_SENT, \
|
||||
VoxelTerrain.BLOCK_UPDATE_SENT:
|
||||
col = Color(1, 0.5, 0, a)
|
||||
|
||||
_:
|
||||
col = Color(1, 1, 1, a)
|
||||
|
||||
draw_rect(Rect2(gui_origin + Vector2(x, z) * w, Vector2(w, w)), col)
|
||||
|
||||
|
||||
static func _format_memory(m):
|
||||
var mb = m / 1000000
|
||||
var mbr = m % 1000000
|
||||
return str(mb, ".", mbr, " Mb")
|
@ -1,6 +0,0 @@
|
||||
[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 )
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,8 @@
|
||||
[gd_resource type="VoxelGeneratorNoise2D" load_steps=2 format=2]
|
||||
|
||||
[sub_resource type="OpenSimplexNoise" id=1]
|
||||
|
||||
[resource]
|
||||
channel = 0
|
||||
height_range = 100.0
|
||||
noise = SubResource( 1 )
|
41
project/blocky_terrain/voxel_library.tres
Normal file
@ -0,0 +1,41 @@
|
||||
[gd_resource type="VoxelLibrary" load_steps=6 format=2]
|
||||
|
||||
[ext_resource path="res://blocky_terrain/custom_mesh.obj" type="ArrayMesh" id=1]
|
||||
|
||||
[sub_resource type="Voxel" id=1]
|
||||
transparent = true
|
||||
|
||||
[sub_resource type="Voxel" id=2]
|
||||
geometry_type = 1
|
||||
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
|
||||
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=3]
|
||||
geometry_type = 1
|
||||
collision_aabbs = [ AABB( 0, 0, 0, 1, 1, 1 ) ]
|
||||
cube_geometry/padding_y = 0.0
|
||||
cube_tiles/left = Vector2( 1, 0 )
|
||||
cube_tiles/right = Vector2( 1, 0 )
|
||||
cube_tiles/bottom = Vector2( 1, 0 )
|
||||
cube_tiles/top = Vector2( 1, 0 )
|
||||
cube_tiles/back = Vector2( 1, 0 )
|
||||
cube_tiles/front = Vector2( 1, 0 )
|
||||
|
||||
[sub_resource type="Voxel" id=4]
|
||||
voxel_name = "MeshTest"
|
||||
geometry_type = 2
|
||||
custom_mesh = ExtResource( 1 )
|
||||
collision_aabbs = [ AABB( 0, 0, 0, 1, 0.8, 1 ) ]
|
||||
|
||||
[resource]
|
||||
atlas_size = 4
|
||||
voxels/0 = SubResource( 1 )
|
||||
voxels/1 = SubResource( 2 )
|
||||
voxels/2 = SubResource( 3 )
|
||||
voxels/3 = SubResource( 4 )
|
@ -7,13 +7,46 @@ extends Node
|
||||
|
||||
const TEXT_LINGER_FRAMES = 5
|
||||
const LINES_LINGER_FRAMES = 1
|
||||
const BOXES_LINGER_FRAMES = 1
|
||||
|
||||
var _lines = []
|
||||
var _line_material = null
|
||||
|
||||
var _label = null
|
||||
var _canvas_item = null
|
||||
var _texts = {}
|
||||
|
||||
var _boxes = []
|
||||
var _box_pool = []
|
||||
var _box_mesh = null
|
||||
|
||||
var _line_material_pool = []
|
||||
|
||||
var _font = null
|
||||
|
||||
|
||||
func _ready():
|
||||
# Meh
|
||||
var c = Control.new()
|
||||
add_child(c)
|
||||
_font = c.get_font("font")
|
||||
c.queue_free()
|
||||
print("Got font ", _font)
|
||||
|
||||
|
||||
func draw_box(position: Vector3, size: Vector3, color: Color = Color(1,1,1)):
|
||||
if _box_mesh == null:
|
||||
_box_mesh = _create_wirecube_mesh(Color(1,1,1))
|
||||
var mi = _get_box()
|
||||
mi.mesh = _box_mesh
|
||||
var mat = _get_line_material()
|
||||
mat.albedo_color = color
|
||||
mi.material_override = mat
|
||||
mi.translation = position
|
||||
mi.scale = size
|
||||
_boxes.append({
|
||||
"node": mi,
|
||||
"frame": Engine.get_frames_drawn() + LINES_LINGER_FRAMES
|
||||
})
|
||||
|
||||
|
||||
func draw_line(a, b, color):
|
||||
var g = ImmediateGeometry.new()
|
||||
@ -25,48 +58,147 @@ func draw_line(a, b, color):
|
||||
g.end()
|
||||
add_child(g)
|
||||
_lines.append({
|
||||
"node": g,
|
||||
"frame": Engine.get_frames_drawn() + LINES_LINGER_FRAMES,
|
||||
"node": g
|
||||
})
|
||||
|
||||
|
||||
func _get_line_material():
|
||||
if _line_material == null:
|
||||
var mat = SpatialMaterial.new()
|
||||
mat.flags_unshaded = true
|
||||
mat.vertex_color_use_as_albedo = true
|
||||
_line_material = mat
|
||||
return _line_material
|
||||
|
||||
|
||||
func _process(delta):
|
||||
var i = 0
|
||||
while i < len(_lines):
|
||||
var d = _lines[i]
|
||||
if d.frame <= Engine.get_frames_drawn():
|
||||
d.node.queue_free()
|
||||
_lines[i] = _lines[i - 1]
|
||||
_lines.pop_back()
|
||||
else:
|
||||
i += 1
|
||||
|
||||
if _label != null:
|
||||
var text = ""
|
||||
for key in _texts.keys():
|
||||
var t = _texts[key]
|
||||
if t.frame <= Engine.get_frames_drawn():
|
||||
_texts.erase(key)
|
||||
else:
|
||||
text = str(text, key, ": ", t.text, "\n")
|
||||
_label.text = text
|
||||
|
||||
|
||||
func set_text(key, text):
|
||||
if _label == null:
|
||||
_label = Label.new()
|
||||
add_child(_label)
|
||||
_texts[key] = {
|
||||
"text": text,
|
||||
"frame": Engine.get_frames_drawn() + TEXT_LINGER_FRAMES
|
||||
}
|
||||
|
||||
|
||||
func _get_box():
|
||||
var mi
|
||||
if len(_box_pool) == 0:
|
||||
mi = MeshInstance.new()
|
||||
mi.mesh = _box_mesh
|
||||
add_child(mi)
|
||||
else:
|
||||
mi = _box_pool[-1]
|
||||
_box_pool.pop_back()
|
||||
return mi
|
||||
|
||||
|
||||
func _recycle_box(mi):
|
||||
mi.hide()
|
||||
_box_pool.append(mi)
|
||||
|
||||
|
||||
func _get_line_material():
|
||||
var mat
|
||||
if len(_line_material_pool) == 0:
|
||||
mat = SpatialMaterial.new()
|
||||
mat.flags_unshaded = true
|
||||
mat.vertex_color_use_as_albedo = true
|
||||
else:
|
||||
mat = _line_material_pool[-1]
|
||||
_line_material_pool.pop_back()
|
||||
return mat
|
||||
|
||||
|
||||
func _recycle_line_material(mat):
|
||||
_line_material_pool.append(mat)
|
||||
|
||||
|
||||
func _process_delayed_free(items):
|
||||
var i = 0
|
||||
while i < len(items):
|
||||
var d = items[i]
|
||||
if d.frame <= Engine.get_frames_drawn():
|
||||
_recycle_line_material(d.node.material_override)
|
||||
d.node.queue_free()
|
||||
items[i] = items[i - 1]
|
||||
items.pop_back()
|
||||
else:
|
||||
i += 1
|
||||
|
||||
|
||||
func _process(delta):
|
||||
_process_delayed_free(_lines)
|
||||
_process_delayed_free(_boxes)
|
||||
|
||||
# Progressively delete boxes
|
||||
if len(_box_pool) > 0:
|
||||
var last = _box_pool[-1]
|
||||
_box_pool.pop_back()
|
||||
last.queue_free()
|
||||
|
||||
# Remove text lines after some time
|
||||
for key in _texts.keys():
|
||||
var t = _texts[key]
|
||||
if t.frame <= Engine.get_frames_drawn():
|
||||
_texts.erase(key)
|
||||
|
||||
# Update canvas
|
||||
if _canvas_item == null:
|
||||
_canvas_item = Node2D.new()
|
||||
_canvas_item.position = Vector2(8, 8)
|
||||
_canvas_item.connect("draw", self, "_on_CanvasItem_draw")
|
||||
add_child(_canvas_item)
|
||||
_canvas_item.update()
|
||||
|
||||
|
||||
func _on_CanvasItem_draw():
|
||||
var ci = _canvas_item
|
||||
var fg_color = Color(1,1,1)
|
||||
var bg_color = Color(0.3, 0.3, 0.3, 0.8)
|
||||
|
||||
var ascent = Vector2(0, _font.get_ascent())
|
||||
var pos = Vector2()
|
||||
var xpad = 2
|
||||
var ypad = 1
|
||||
var font_offset = ascent + Vector2(xpad, ypad)
|
||||
var line_height = _font.get_height() + 2 * ypad
|
||||
|
||||
for key in _texts.keys():
|
||||
var t = _texts[key]
|
||||
var text = str(key, ": ", t.text, "\n")
|
||||
var ss = _font.get_string_size(text)
|
||||
ci.draw_rect(Rect2(pos, Vector2(ss.x + xpad * 2, line_height)), bg_color)
|
||||
ci.draw_string(_font, pos + font_offset, text, fg_color)
|
||||
pos.y += line_height
|
||||
|
||||
|
||||
static func _create_wirecube_mesh(color = Color(1,1,1)):
|
||||
var positions = PoolVector3Array([
|
||||
Vector3(0, 0, 0),
|
||||
Vector3(1, 0, 0),
|
||||
Vector3(1, 0, 1),
|
||||
Vector3(0, 0, 1),
|
||||
Vector3(0, 1, 0),
|
||||
Vector3(1, 1, 0),
|
||||
Vector3(1, 1, 1),
|
||||
Vector3(0, 1, 1)
|
||||
])
|
||||
var colors = PoolColorArray([
|
||||
color, color, color, color,
|
||||
color, color, color, color,
|
||||
])
|
||||
var indices = PoolIntArray([
|
||||
0, 1,
|
||||
1, 2,
|
||||
2, 3,
|
||||
3, 0,
|
||||
|
||||
4, 5,
|
||||
5, 6,
|
||||
6, 7,
|
||||
7, 4,
|
||||
|
||||
0, 4,
|
||||
1, 5,
|
||||
2, 6,
|
||||
3, 7
|
||||
])
|
||||
var arrays = []
|
||||
arrays.resize(Mesh.ARRAY_MAX)
|
||||
arrays[Mesh.ARRAY_VERTEX] = positions
|
||||
arrays[Mesh.ARRAY_COLOR] = colors
|
||||
arrays[Mesh.ARRAY_INDEX] = indices
|
||||
var mesh = ArrayMesh.new()
|
||||
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_LINES, arrays)
|
||||
return mesh
|
||||
|
||||
|
@ -35,7 +35,7 @@ func _physics_process(delta):
|
||||
if dir_len > 0.01:
|
||||
|
||||
dir /= dir_len
|
||||
|
||||
DDD.set_text("Speed", speed)
|
||||
var motor = dir * (speed * delta)
|
||||
|
||||
translate(motor)
|
||||
|
@ -8,7 +8,7 @@ static func create_wirecube_mesh(color = Color(1,1,1)):
|
||||
Vector3(0, 1, 0),
|
||||
Vector3(1, 1, 0),
|
||||
Vector3(1, 1, 1),
|
||||
Vector3(0, 1, 1),
|
||||
Vector3(0, 1, 1)
|
||||
])
|
||||
var colors = PoolColorArray([
|
||||
color, color, color, color,
|
||||
@ -39,3 +39,47 @@ static func create_wirecube_mesh(color = Color(1,1,1)):
|
||||
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_LINES, arrays)
|
||||
return mesh
|
||||
|
||||
|
||||
static func calculate_normals(positions, indices) -> PoolVector3Array:
|
||||
var out_normals = PoolVector3Array()
|
||||
|
||||
var tcounts = []
|
||||
tcounts.resize(positions.size())
|
||||
out_normals.resize(positions.size())
|
||||
|
||||
for i in range(0, tcounts.size()):
|
||||
tcounts[i] = 0
|
||||
|
||||
var tri_count = indices.size() / 3
|
||||
|
||||
var i = 0
|
||||
while i < indices.size():
|
||||
|
||||
var i0 = indices[i]
|
||||
var i1 = indices[i+1]
|
||||
var i2 = indices[i+2]
|
||||
i += 3
|
||||
|
||||
# TODO does triangle area matter?
|
||||
# If it does then we don't need to normalize in triangle calculation since it will account for its length
|
||||
var n = get_triangle_normal(positions[i0], positions[i1], positions[i2])
|
||||
|
||||
out_normals[i0] += n
|
||||
out_normals[i1] += n
|
||||
out_normals[i2] += n
|
||||
|
||||
tcounts[i0] += 1
|
||||
tcounts[i1] += 1
|
||||
tcounts[i2] += 1
|
||||
|
||||
for j in range(out_normals.size()):
|
||||
out_normals[j] = (out_normals[j] / float(tcounts[j])).normalized()
|
||||
#print("DDD ", out_normals.size())
|
||||
return out_normals
|
||||
|
||||
|
||||
static func get_triangle_normal(a: Vector3, b: Vector3, c: Vector3) -> Vector3:
|
||||
var u = (a - b).normalized()
|
||||
var v = (a - c).normalized()
|
||||
return v.cross(u)
|
||||
|
||||
|
44
project/common/wireframe_builder.gd
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
var _wireframe_indices = []
|
||||
var _blacklist = {}
|
||||
|
||||
|
||||
func build(mesh):
|
||||
if mesh == null:
|
||||
return null
|
||||
var arrays = mesh.surface_get_arrays(0)
|
||||
var positions = arrays[Mesh.ARRAY_VERTEX]
|
||||
var indices = arrays[Mesh.ARRAY_INDEX]
|
||||
_wireframe_indices.clear()
|
||||
_blacklist.clear()
|
||||
var i = 0
|
||||
assert(len(indices) % 3 == 0)
|
||||
while i < len(indices):
|
||||
_try_add_edge(indices[i], indices[i + 1])
|
||||
_try_add_edge(indices[i + 1], indices[i + 2])
|
||||
_try_add_edge(indices[i + 2], indices[i])
|
||||
i += 3
|
||||
var wireframe_arrays = []
|
||||
wireframe_arrays.resize(Mesh.ARRAY_MAX)
|
||||
wireframe_arrays[Mesh.ARRAY_VERTEX] = positions
|
||||
wireframe_arrays[Mesh.ARRAY_INDEX] = PoolIntArray(_wireframe_indices)
|
||||
|
||||
var colors = PoolColorArray()
|
||||
colors.resize(len(positions))
|
||||
wireframe_arrays[Mesh.ARRAY_COLOR] = colors
|
||||
|
||||
var wireframe_mesh = ArrayMesh.new()
|
||||
wireframe_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_LINES, wireframe_arrays)
|
||||
return wireframe_mesh
|
||||
|
||||
|
||||
func _try_add_edge(i0, i1):
|
||||
assert(i0 < 0xffff)
|
||||
assert(i1 < 0xffff)
|
||||
var e = i0 | (i1 << 16)
|
||||
if _blacklist.has(e):
|
||||
return
|
||||
_blacklist[e] = true
|
||||
_wireframe_indices.append(i0)
|
||||
_wireframe_indices.append(i1)
|
||||
|
@ -1,102 +0,0 @@
|
||||
extends Control
|
||||
|
||||
onready var _terrain = get_node("../VoxelTerrain")
|
||||
|
||||
export var block_y_offset = 0
|
||||
var _lod_index = 0
|
||||
|
||||
|
||||
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)
|
@ -1,37 +0,0 @@
|
||||
shader_type spatial;
|
||||
|
||||
uniform sampler2D u_texture_top : hint_albedo;
|
||||
uniform sampler2D u_texture_sides : hint_albedo;
|
||||
|
||||
varying vec3 v_world_pos;
|
||||
varying vec3 v_world_normal;
|
||||
|
||||
vec3 get_triplanar_blend(vec3 world_normal) {
|
||||
vec3 blending = abs(world_normal);
|
||||
blending = normalize(max(blending, vec3(0.00001))); // Force weights to sum to 1.0
|
||||
float b = blending.x + blending.y + blending.z;
|
||||
return blending / vec3(b, b, b);
|
||||
}
|
||||
|
||||
vec4 texture_triplanar(sampler2D tex, vec3 world_pos, vec3 blend) {
|
||||
vec4 xaxis = texture(tex, world_pos.yz);
|
||||
vec4 yaxis = texture(tex, world_pos.xz);
|
||||
vec4 zaxis = texture(tex, world_pos.xy);
|
||||
// blend the results of the 3 planar projections.
|
||||
return xaxis * blend.x + yaxis * blend.y + zaxis * blend.z;
|
||||
}
|
||||
|
||||
void vertex() {
|
||||
v_world_pos = VERTEX;
|
||||
v_world_normal = NORMAL;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec3 normal = normalize(v_world_normal);
|
||||
vec3 wpos = v_world_pos * 0.2;
|
||||
vec3 blending = get_triplanar_blend(normal);
|
||||
vec3 top_col = texture_triplanar(u_texture_top, wpos, blending).rgb;
|
||||
vec3 side_col = texture_triplanar(u_texture_sides, wpos, blending).rgb;
|
||||
float r = top_col.r;
|
||||
ALBEDO = mix(side_col, top_col, clamp(normal.y * 10.0 - 4.0 - 8.0*r, 0.0, 1.0));
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
[gd_resource type="ShaderMaterial" load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://dmc_terrain/dmc_terrain.shader" type="Shader" id=1]
|
||||
[ext_resource path="res://dmc_terrain/grass_albedo.png" type="Texture" id=2]
|
||||
[ext_resource path="res://dmc_terrain/dirt_albedo.png" type="Texture" id=3]
|
||||
|
||||
[resource]
|
||||
shader = ExtResource( 1 )
|
||||
shader_param/u_texture_top = ExtResource( 2 )
|
||||
shader_param/u_texture_sides = ExtResource( 3 )
|
@ -1,7 +0,0 @@
|
||||
[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
|
@ -1,76 +0,0 @@
|
||||
[gd_scene load_steps=13 format=2]
|
||||
|
||||
[ext_resource path="res://dmc_terrain/interaction.gd" type="Script" id=1]
|
||||
[ext_resource path="res://dmc_terrain/dmc_terrain_material.tres" type="Material" id=2]
|
||||
[ext_resource path="res://blocky_terrain/noise_distorted.png" type="Image" id=3]
|
||||
[ext_resource path="res://common/spectator_avatar.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://common/axes.tscn" type="PackedScene" 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
|
||||
|
||||
[sub_resource type="VoxelStreamImage" id=3]
|
||||
image = ExtResource( 3 )
|
||||
channel = 1
|
||||
|
||||
[sub_resource type="Voxel" id=4]
|
||||
transparent = true
|
||||
|
||||
[sub_resource type="Voxel" id=5]
|
||||
geometry_type = 1
|
||||
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="VoxelLibrary" id=6]
|
||||
voxels/0 = SubResource( 4 )
|
||||
voxels/1 = SubResource( 5 )
|
||||
|
||||
[sub_resource type="SphereMesh" id=7]
|
||||
|
||||
[node name="Node" type="Node"]
|
||||
|
||||
[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
|
||||
|
||||
[node name="Axes" parent="." instance=ExtResource( 5 )]
|
||||
|
||||
[node name="SpectatorAvatar" parent="." instance=ExtResource( 4 )]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 19.9349, 17.285 )
|
||||
speed = 20.0
|
||||
|
||||
[node name="Camera" parent="SpectatorAvatar" index="0"]
|
||||
far = 800.0
|
||||
|
||||
[node name="Interaction" type="Node" parent="SpectatorAvatar"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="VoxelTerrain" type="VoxelTerrain" parent="."]
|
||||
stream = SubResource( 3 )
|
||||
voxel_library = SubResource( 6 )
|
||||
view_distance = 256
|
||||
viewer_path = NodePath("../SpectatorAvatar")
|
||||
smooth_meshing_enabled = true
|
||||
material/0 = ExtResource( 2 )
|
||||
|
||||
[node name="MeshInstance" type="MeshInstance" parent="."]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.0254497 )
|
||||
mesh = SubResource( 7 )
|
||||
material/0 = ExtResource( 2 )
|
||||
|
||||
[editable path="SpectatorAvatar"]
|
@ -1,75 +0,0 @@
|
||||
[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://common/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://common/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"]
|
@ -1,11 +0,0 @@
|
||||
[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
|
@ -1,234 +0,0 @@
|
||||
extends Node
|
||||
|
||||
|
||||
var _sphere_position = Vector3(8, 8, 8)
|
||||
var _sphere_radius = 3.5
|
||||
var _geometric_error = 0.01
|
||||
var _mesh_instance = null
|
||||
var _debug_mesh_instance = null
|
||||
var _sphere_mesh_instance = null
|
||||
var _model_rotation = 0.0
|
||||
var _voxels = VoxelBuffer.new()
|
||||
var _mesher = VoxelMesherDMC.new()
|
||||
var _need_generate = false
|
||||
var _iso_scale = 1.0
|
||||
|
||||
func _ready():
|
||||
|
||||
_mesher.set_simplify_mode(VoxelMesherDMC.SIMPLIFY_NONE)
|
||||
|
||||
_voxels.create(20, 20, 20)
|
||||
|
||||
_mesh_instance = MeshInstance.new()
|
||||
_mesh_instance.material_override = SpatialMaterial.new()
|
||||
add_child(_mesh_instance)
|
||||
|
||||
var mat = SpatialMaterial.new()
|
||||
mat.flags_unshaded = true
|
||||
mat.vertex_color_use_as_albedo = true
|
||||
_debug_mesh_instance = MeshInstance.new()
|
||||
_debug_mesh_instance.material_override = mat
|
||||
add_child(_debug_mesh_instance)
|
||||
|
||||
_sphere_mesh_instance = create_sphere(_sphere_position, _sphere_radius)
|
||||
|
||||
generate()
|
||||
|
||||
|
||||
static func make_plane(pos, dir):
|
||||
return Plane(dir, dir.dot(pos))
|
||||
|
||||
|
||||
func generate_with_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_statistics()
|
||||
for k in stats:
|
||||
stats_average[k] += stats[k]
|
||||
|
||||
for k in stats_average:
|
||||
stats_average[k] = stats_average[k] / float(iterations)
|
||||
|
||||
print("---")
|
||||
print("Sphere at ", _sphere_position, ", radius ", _sphere_radius)
|
||||
print("Geometric error: ", _geometric_error, ", iso_scale=", _iso_scale)
|
||||
print(stats_average)
|
||||
|
||||
#------------------------------------------------------
|
||||
#_sphere_position = Vector3(8, 8, 8)
|
||||
#_sphere_radius = 3.5
|
||||
#_geometric_error = 0.01
|
||||
|
||||
# On 3c366b1f098f7aa62b0c0bf61f97ef5e38531caa
|
||||
# {commit_time:663.96, dualgrid_derivation_time:4422, meshing_time:14576.8, octree_build_time:61293.9}
|
||||
|
||||
# On 0e569df945f0277869d90b5df189df2a39d11ee0
|
||||
# {commit_time:588.13, dualgrid_derivation_time:2155.79, meshing_time:14476.36, octree_build_time:5830.69}
|
||||
|
||||
|
||||
func generate():
|
||||
_voxels.fill_f(1.0, VoxelBuffer.CHANNEL_ISOLEVEL)
|
||||
|
||||
var vt = VoxelIsoSurfaceTool.new()
|
||||
vt.set_iso_scale(_iso_scale)
|
||||
vt.set_offset(Vector3(1, 1, 1)) # For padding
|
||||
vt.set_buffer(_voxels)
|
||||
vt.do_cube(Transform(Basis(Vector3(1, 0, 0), _model_rotation), _sphere_position), Vector3(_sphere_radius, _sphere_radius, _sphere_radius))
|
||||
#vt.do_sphere(_sphere_position, _sphere_radius)
|
||||
#vt.do_sphere(_sphere_position + Vector3(5,2,3), _sphere_radius / 1.5)
|
||||
#vt.do_plane(make_plane(_sphere_position, Vector3(0,1,0)))
|
||||
|
||||
_mesher.set_mesh_mode(VoxelMesherDMC.MESH_NORMAL)
|
||||
_mesher.set_geometric_error(_geometric_error)
|
||||
var mesh = _mesher.build_mesh(_voxels)
|
||||
_mesh_instance.mesh = mesh
|
||||
_mesh_instance.material_override = load("res://dmc_terrain/dmc_terrain_material.tres")
|
||||
|
||||
if false:
|
||||
_mesher.set_mesh_mode(VoxelMesherDMC.MODE_DEBUG_DUAL_GRID)
|
||||
mesh = _mesher.build_mesh(_voxels)
|
||||
_debug_mesh_instance.mesh = mesh
|
||||
|
||||
_sphere_mesh_instance.translation = _sphere_position
|
||||
|
||||
|
||||
func _process(delta):
|
||||
if _need_generate:
|
||||
generate_with_stats()
|
||||
_need_generate = false
|
||||
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventKey:
|
||||
if event.pressed:
|
||||
|
||||
# Doesn't work, because reasons
|
||||
#if event.scancode == KEY_TAB:
|
||||
# if get_viewport().debug_draw == Viewport.DEBUG_DRAW_DISABLED:
|
||||
# print("Switched to wireframe render")
|
||||
# get_viewport().debug_draw = Viewport.DEBUG_DRAW_WIREFRAME
|
||||
# else:
|
||||
# print("Switched to normal render")
|
||||
# get_viewport().debug_draw = Viewport.DEBUG_DRAW_DISABLED
|
||||
|
||||
if event.scancode == KEY_RIGHT:
|
||||
_sphere_position.x += 0.1
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_LEFT:
|
||||
_sphere_position.x -= 0.1
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_UP:
|
||||
_sphere_position.z += 0.1
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_DOWN:
|
||||
_sphere_position.z -= 0.1
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_PAGEUP:
|
||||
_sphere_position.y += 0.1
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_PAGEDOWN:
|
||||
_sphere_position.y -= 0.1
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_KP_ADD:
|
||||
_sphere_radius += 0.1
|
||||
_sphere_mesh_instance.mesh.radius = _sphere_radius
|
||||
_sphere_mesh_instance.mesh.height = 2.0 * _sphere_radius
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_KP_SUBTRACT:
|
||||
_sphere_radius -= 0.1
|
||||
if _sphere_radius < 0.1:
|
||||
_sphere_radius = 0.1
|
||||
_sphere_mesh_instance.mesh.radius = _sphere_radius
|
||||
_sphere_mesh_instance.mesh.height = 2.0 * _sphere_radius
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_KP_8:
|
||||
_geometric_error += 0.025
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_KP_2:
|
||||
_geometric_error -= 0.025
|
||||
if _geometric_error < 0.0:
|
||||
_geometric_error = 0.0
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_KP_4:
|
||||
_model_rotation -= PI / 32.0
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_KP_6:
|
||||
_model_rotation += PI / 32.0
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_KP_7:
|
||||
_iso_scale -= 0.1
|
||||
if _iso_scale < 0.1:
|
||||
_iso_scale = 0.1
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_KP_9:
|
||||
_iso_scale += 0.1
|
||||
_need_generate = true
|
||||
|
||||
elif event.scancode == KEY_P:
|
||||
print_buffer_to_images(_voxels, VoxelBuffer.CHANNEL_ISOLEVEL, "isolevel", 10)
|
||||
|
||||
elif event.scancode == KEY_R:
|
||||
_need_generate = true
|
||||
|
||||
|
||||
func create_sphere(pos, r):
|
||||
var mat = SpatialMaterial.new()
|
||||
mat.flags_transparent = true
|
||||
mat.albedo_color = Color(0,0,1,0.3)
|
||||
var mesh = SphereMesh.new()
|
||||
mesh.radius = r
|
||||
mesh.height = r * 2.0
|
||||
var mi = MeshInstance.new()
|
||||
mi.translation = pos
|
||||
mi.mesh = mesh
|
||||
mi.material_override = mat
|
||||
add_child(mi)
|
||||
return mi
|
||||
|
||||
|
||||
static func print_buffer_to_images(voxels, channel, fname, upscale):
|
||||
|
||||
for y in voxels.get_size_y():
|
||||
|
||||
var im = Image.new()
|
||||
im.create(voxels.get_size_x(), voxels.get_size_z(), false, Image.FORMAT_RGB8)
|
||||
|
||||
im.lock()
|
||||
|
||||
for z in voxels.get_size_z():
|
||||
for x in voxels.get_size_x():
|
||||
var r = 0.5 * voxels.get_voxel_f(x, y, z, channel) + 0.5
|
||||
if r < 0.5:
|
||||
im.set_pixel(x, z, Color(r, r, r*0.5 + 0.5))
|
||||
else:
|
||||
im.set_pixel(x, z, Color(r, r, r))
|
||||
|
||||
im.unlock()
|
||||
|
||||
if upscale > 1:
|
||||
im.resize(im.get_width() * upscale, im.get_height() * upscale, Image.INTERPOLATE_NEAREST)
|
||||
|
||||
var fname_png = str(fname, "_", y, ".png")
|
||||
print("Saved ", fname_png)
|
||||
im.save_png(fname_png)
|
||||
|
||||
|
@ -1,32 +0,0 @@
|
||||
[gd_scene load_steps=6 format=2]
|
||||
|
||||
[ext_resource path="res://dmc_test/main.gd" type="Script" id=1]
|
||||
[ext_resource path="res://common/axes.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://common/spectator_avatar.tscn" type="PackedScene" id=3]
|
||||
|
||||
|
||||
|
||||
[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
|
||||
|
||||
[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
|
||||
|
||||
[node name="Axes" parent="." instance=ExtResource( 2 )]
|
||||
|
||||
[node name="SpectatorAvatar" parent="." instance=ExtResource( 3 )]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.20169, 17.285 )
|
@ -16,7 +16,7 @@ _global_script_class_icons={
|
||||
[application]
|
||||
|
||||
config/name="New Game Project"
|
||||
run/main_scene="res://dmc_terrain/main_lod.tscn"
|
||||
run/main_scene="res://smooth_terrain/main.tscn"
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[autoload]
|
||||
|
Before Width: | Height: | Size: 2.2 MiB After Width: | Height: | Size: 2.2 MiB |
@ -2,8 +2,8 @@
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path.s3tc="res://.import/dirt_albedo.png-75b50e042275a94a5dad2f9e0c994d5e.s3tc.stex"
|
||||
path.etc2="res://.import/dirt_albedo.png-75b50e042275a94a5dad2f9e0c994d5e.etc2.stex"
|
||||
path.s3tc="res://.import/dirt_albedo.png-1ea566b45deb8325a8458a1304e770f2.s3tc.stex"
|
||||
path.etc2="res://.import/dirt_albedo.png-1ea566b45deb8325a8458a1304e770f2.etc2.stex"
|
||||
metadata={
|
||||
"imported_formats": [ "s3tc", "etc2" ],
|
||||
"vram_texture": true
|
||||
@ -11,8 +11,8 @@ metadata={
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://dmc_terrain/dirt_albedo.png"
|
||||
dest_files=[ "res://.import/dirt_albedo.png-75b50e042275a94a5dad2f9e0c994d5e.s3tc.stex", "res://.import/dirt_albedo.png-75b50e042275a94a5dad2f9e0c994d5e.etc2.stex" ]
|
||||
source_file="res://smooth_terrain/dirt_albedo.png"
|
||||
dest_files=[ "res://.import/dirt_albedo.png-1ea566b45deb8325a8458a1304e770f2.s3tc.stex", "res://.import/dirt_albedo.png-1ea566b45deb8325a8458a1304e770f2.etc2.stex" ]
|
||||
|
||||
[params]
|
||||
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 2.8 MiB |
@ -2,8 +2,8 @@
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path.s3tc="res://.import/grass_albedo.png-919a5785cc1d44de952c7e630d907cd2.s3tc.stex"
|
||||
path.etc2="res://.import/grass_albedo.png-919a5785cc1d44de952c7e630d907cd2.etc2.stex"
|
||||
path.s3tc="res://.import/grass_albedo.png-daa10982e29958da33d5e57c02c43db6.s3tc.stex"
|
||||
path.etc2="res://.import/grass_albedo.png-daa10982e29958da33d5e57c02c43db6.etc2.stex"
|
||||
metadata={
|
||||
"imported_formats": [ "s3tc", "etc2" ],
|
||||
"vram_texture": true
|
||||
@ -11,8 +11,8 @@ metadata={
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://dmc_terrain/grass_albedo.png"
|
||||
dest_files=[ "res://.import/grass_albedo.png-919a5785cc1d44de952c7e630d907cd2.s3tc.stex", "res://.import/grass_albedo.png-919a5785cc1d44de952c7e630d907cd2.etc2.stex" ]
|
||||
source_file="res://smooth_terrain/grass_albedo.png"
|
||||
dest_files=[ "res://.import/grass_albedo.png-daa10982e29958da33d5e57c02c43db6.s3tc.stex", "res://.import/grass_albedo.png-daa10982e29958da33d5e57c02c43db6.etc2.stex" ]
|
||||
|
||||
[params]
|
||||
|
@ -23,6 +23,12 @@ func _input(event):
|
||||
if event.pressed:
|
||||
if event.scancode == KEY_P:
|
||||
print_map_slice()
|
||||
elif event.scancode == KEY_K:
|
||||
var p = Spatial.new()
|
||||
p.translation = get_parent().translation
|
||||
print("Freezing viewer tracking at ", p.translation)
|
||||
get_parent().get_parent().add_child(p)
|
||||
_terrain.set_viewer_path(p.get_path())
|
||||
|
||||
|
||||
func _process(delta):
|
||||
@ -30,6 +36,9 @@ func _process(delta):
|
||||
var head_trans = _head.global_transform
|
||||
var pointed_pos = head_trans.origin - 6.0 * head_trans.basis.z
|
||||
|
||||
if Input.is_mouse_button_pressed(BUTTON_RIGHT):
|
||||
_action_remove = true
|
||||
|
||||
if _action_place:
|
||||
do_sphere(pointed_pos, 3.5, true)
|
||||
elif _action_remove:
|
@ -1,11 +1,19 @@
|
||||
extends Node
|
||||
|
||||
const Util = preload("res://common/util.gd")
|
||||
|
||||
onready var _terrain = get_node("VoxelTerrain")
|
||||
onready var _avatar = get_node("SpectatorAvatar")
|
||||
onready var _camera = get_node("SpectatorAvatar/Camera")
|
||||
onready var _light = get_node("DirectionalLight")
|
||||
|
||||
var _process_stats = {}
|
||||
var _displayed_process_stats = {}
|
||||
var _time_before_display_process_stats = 1.0
|
||||
var _block_highlights = []
|
||||
var _first_process_time = -1.0
|
||||
var _first_time_no_blocked_lods = -1.0
|
||||
var _process_count = 0
|
||||
|
||||
const _process_stat_names = [
|
||||
"time_detect_required_blocks",
|
||||
@ -17,7 +25,33 @@ const _process_stat_names = [
|
||||
]
|
||||
|
||||
|
||||
func _ready():
|
||||
#test_downscale()
|
||||
pass
|
||||
|
||||
|
||||
static func test_downscale():
|
||||
var vb = VoxelBuffer.new()
|
||||
vb.create(16, 16, 16)
|
||||
var vb2 = VoxelBuffer.new()
|
||||
vb2.create(16, 16, 16)
|
||||
for z in 16:
|
||||
for x in 16:
|
||||
for y in 16:
|
||||
vb.set_voxel_f(2.0 * randf() - 0.1, x, y, z, VoxelBuffer.CHANNEL_SDF)
|
||||
var d = Vector3(x, y, z).distance_to(Vector3(8,8,8)) - 7
|
||||
vb2.set_voxel_f(d, x, y, z, VoxelBuffer.CHANNEL_SDF)
|
||||
vb2.downscale_to(vb, Vector3(), vb2.get_size(), Vector3(0,8,0))
|
||||
var im = vb.debug_print_sdf_top_down()
|
||||
im.save_png("downscale_test.png")
|
||||
im = vb2.debug_print_sdf_top_down()
|
||||
im.save_png("downscale_test_src.png")
|
||||
|
||||
|
||||
func _process(delta):
|
||||
if _first_process_time < 0:
|
||||
_first_process_time = OS.get_ticks_msec()
|
||||
|
||||
var stats = _terrain.get_statistics()
|
||||
|
||||
for i in len(stats.stream.remaining_blocks_per_thread):
|
||||
@ -28,6 +62,7 @@ func _process(delta):
|
||||
var remaining = stats.updater.remaining_blocks_per_thread[i]
|
||||
DDD.set_text(str("Meshing blocks [", i, "]"), str(remaining))
|
||||
|
||||
DDD.set_text("FPS", Engine.get_frames_per_second())
|
||||
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()))
|
||||
@ -36,6 +71,13 @@ func _process(delta):
|
||||
DDD.set_text("Mesh sort time", stats.updater.sorting_time)
|
||||
DDD.set_text("Position", _avatar.translation)
|
||||
|
||||
if _first_time_no_blocked_lods < 0 and stats.blocked_lods == 0 and _process_count > 200:
|
||||
_first_time_no_blocked_lods = OS.get_ticks_msec()
|
||||
var load_time = _first_time_no_blocked_lods - _first_process_time
|
||||
print("Time to reach full load: ", float(load_time) / 1000.0, " seconds")
|
||||
print("First process time: ", _first_process_time)
|
||||
print(stats)
|
||||
|
||||
for k in _process_stat_names:
|
||||
var v = stats[k]
|
||||
if k in _process_stats:
|
||||
@ -52,6 +94,63 @@ func _process(delta):
|
||||
for k in _displayed_process_stats:
|
||||
DDD.set_text(k, _displayed_process_stats[k])
|
||||
|
||||
#debug_pointed_block()
|
||||
#if Input.is_key_pressed(KEY_SPACE):
|
||||
#debug_show_octrees()
|
||||
|
||||
_process_count += 1
|
||||
|
||||
|
||||
func debug_show_octrees():
|
||||
var octrees = _terrain.debug_get_octrees()
|
||||
var octree_side = _terrain.get_block_size() << (_terrain.get_lod_count() - 1)
|
||||
var octree_size = Vector3(1,1,1) * octree_side
|
||||
var r = octree_side * 2
|
||||
var pad = Vector3(1,1,1)
|
||||
var ppos = _camera.global_transform.origin #_avatar.translation
|
||||
for pos in octrees:
|
||||
var wpos = pos * octree_size
|
||||
if ppos.distance_to(wpos) < r:
|
||||
DDD.draw_box(wpos + pad, octree_size - 2 * pad, Color(0,1,0))
|
||||
|
||||
|
||||
func debug_pointed_block():
|
||||
|
||||
var ray_origin = _camera.global_transform.origin
|
||||
var ray_dir = -_camera.global_transform.basis.z
|
||||
var hits = _terrain.debug_raycast_block(ray_origin, ray_dir)
|
||||
|
||||
if len(hits) > 0:
|
||||
var d = hits[0]
|
||||
for k in d:
|
||||
DDD.set_text(str("Pointed block ", k), d[k])
|
||||
|
||||
for mi in _block_highlights:
|
||||
mi.hide()
|
||||
|
||||
for i in len(hits):
|
||||
var d = hits[i]
|
||||
|
||||
var mi
|
||||
if i < len(_block_highlights):
|
||||
mi = _block_highlights[i]
|
||||
else:
|
||||
mi = MeshInstance.new()
|
||||
var mesh = Util.create_wirecube_mesh()
|
||||
mi.mesh = mesh
|
||||
var mat = SpatialMaterial.new()
|
||||
mat.flags_unshaded = true
|
||||
mat.vertex_color_use_as_albedo = true
|
||||
mi.material_override = mat
|
||||
add_child(mi)
|
||||
_block_highlights.append(mi)
|
||||
|
||||
var pad = 0.1 * d.lod
|
||||
var scale = (16 << d.lod)
|
||||
mi.translation = d.position * scale - Vector3(pad, pad, pad)
|
||||
mi.scale = Vector3(scale, scale, scale) + pad * Vector3(2, 2, 2)
|
||||
mi.show()
|
||||
|
||||
|
||||
static func _format_memory(m):
|
||||
var mb = m / 1000000
|
||||
@ -80,6 +179,9 @@ func _input(event):
|
||||
else:
|
||||
vp.debug_draw = Viewport.DEBUG_DRAW_DISABLED
|
||||
|
||||
elif event.scancode == KEY_L:
|
||||
_light.shadow_enabled = not _light.shadow_enabled
|
||||
|
||||
|
||||
static func pretty_print(d, depth=0):
|
||||
var indent = ""
|
@ -1,31 +1,29 @@
|
||||
[gd_scene load_steps=11 format=2]
|
||||
[gd_scene load_steps=8 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://smooth_terrain/main.gd" type="Script" id=1]
|
||||
[ext_resource path="res://smooth_terrain/transvoxel_terrain_material.tres" type="Material" id=2]
|
||||
[ext_resource path="res://common/spectator_avatar.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://common/axes.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://dmc_terrain/block_debug.gd" type="Script" id=5]
|
||||
[ext_resource path="res://smooth_terrain/interaction.gd" type="Script" id=6]
|
||||
[ext_resource path="res://smooth_terrain/voxel_generator_noise_2d_smooth.tres" type="VoxelGeneratorNoise2D" id=7]
|
||||
|
||||
[sub_resource type="ProceduralSky" id=1]
|
||||
sky_top_color = Color( 0.388235, 0.533333, 0.615686, 1 )
|
||||
sky_top_color = Color( 0.611765, 0.764706, 0.8, 1 )
|
||||
ground_bottom_color = Color( 0.266667, 0.266667, 0.266667, 1 )
|
||||
ground_horizon_color = Color( 0.733333, 0.733333, 0.733333, 1 )
|
||||
sun_curve = 0.018301
|
||||
|
||||
[sub_resource type="Environment" id=2]
|
||||
background_mode = 2
|
||||
background_sky = SubResource( 1 )
|
||||
background_color = Color( 1, 1, 1, 1 )
|
||||
ambient_light_energy = 0.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="VoxelStreamNoise" id=5]
|
||||
noise = SubResource( 4 )
|
||||
height_range = 1200.0
|
||||
fog_color = Color( 0.552734, 0.818359, 0.908691, 1 )
|
||||
fog_depth_begin = 100.0
|
||||
fog_depth_end = 1600.0
|
||||
fog_height_min = -100.0
|
||||
fog_height_max = -50.0
|
||||
fog_height_curve = 0.965937
|
||||
|
||||
[node name="Node" type="Node"]
|
||||
script = ExtResource( 1 )
|
||||
@ -39,37 +37,29 @@ shadow_enabled = true
|
||||
shadow_bias = 0.05
|
||||
directional_shadow_max_distance = 1000.0
|
||||
|
||||
[node name="Axes" parent="." instance=ExtResource( 4 )]
|
||||
|
||||
[node name="SpectatorAvatar" parent="." instance=ExtResource( 3 )]
|
||||
transform = Transform( -0.386615, 0, 0.922241, 0, 1, 0, -0.922241, 0, -0.386615, 0, 0, 0 )
|
||||
speed = 100.0
|
||||
|
||||
[node name="Camera" parent="SpectatorAvatar" index="0"]
|
||||
far = 2000.0
|
||||
near = 0.1
|
||||
far = 10000.0
|
||||
|
||||
[node name="OmniLight" type="OmniLight" parent="SpectatorAvatar"]
|
||||
visible = false
|
||||
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="Interaction" type="Node" parent="SpectatorAvatar"]
|
||||
script = ExtResource( 6 )
|
||||
|
||||
[node name="VoxelTerrain" type="VoxelLodTerrain" parent="."]
|
||||
stream = SubResource( 5 )
|
||||
lod_count = 8
|
||||
stream = ExtResource( 7 )
|
||||
view_distance = 2048
|
||||
lod_count = 6
|
||||
viewer_path = NodePath("../SpectatorAvatar")
|
||||
material = ExtResource( 2 )
|
||||
generate_collisions = false
|
||||
|
||||
[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( 5 )
|
||||
collision_lod_count = 1
|
||||
|
||||
[editable path="SpectatorAvatar"]
|
4
project/smooth_terrain/terrain_curve.tres
Normal file
@ -0,0 +1,4 @@
|
||||
[gd_resource type="Curve" format=2]
|
||||
|
||||
[resource]
|
||||
_data = [ Vector2( 0, 0 ), 0.0, 0.0, 0, 0, Vector2( 0.377652, 0.0438596 ), 0.432681, 0.432681, 0, 0, Vector2( 0.527581, 0.236842 ), 1.74921, 1.74921, 0, 0, Vector2( 0.561528, 0.421053 ), 0.904422, 0.904422, 0, 0, Vector2( 0.683168, 0.552632 ), 2.26894, 2.26894, 0, 0, Vector2( 0.74116, 0.815789 ), 2.36257, 2.36257, 0, 0, Vector2( 1, 1 ), 0.295322, 0.0, 0, 0 ]
|
77
project/smooth_terrain/transvoxel_terrain.shader
Normal file
@ -0,0 +1,77 @@
|
||||
shader_type spatial;
|
||||
//render_mode skip_vertex_transform;
|
||||
|
||||
uniform sampler2D u_texture_top : hint_albedo;
|
||||
uniform sampler2D u_texture_sides : hint_albedo;
|
||||
uniform int u_transition_mask;
|
||||
|
||||
varying vec3 v_world_pos;
|
||||
varying vec3 v_world_normal;
|
||||
|
||||
vec3 get_triplanar_blend(vec3 world_normal) {
|
||||
vec3 blending = abs(world_normal);
|
||||
blending = normalize(max(blending, vec3(0.00001))); // Force weights to sum to 1.0
|
||||
float b = blending.x + blending.y + blending.z;
|
||||
return blending / vec3(b, b, b);
|
||||
}
|
||||
|
||||
vec4 texture_triplanar(sampler2D tex, vec3 world_pos, vec3 blend) {
|
||||
vec4 xaxis = texture(tex, world_pos.yz);
|
||||
vec4 yaxis = texture(tex, world_pos.xz);
|
||||
vec4 zaxis = texture(tex, world_pos.xy);
|
||||
// blend the results of the 3 planar projections.
|
||||
return xaxis * blend.x + yaxis * blend.y + zaxis * blend.z;
|
||||
}
|
||||
|
||||
float get_hash(vec2 c) {
|
||||
return fract(sin(dot(c.xy, vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
vec3 get_transvoxel_position(vec3 vertex_pos, vec4 vertex_col) {
|
||||
|
||||
int border_mask = int(vertex_col.a);
|
||||
int cell_border_mask = border_mask & 63; // Which sides the cell is touching
|
||||
int vertex_border_mask = (border_mask >> 6) & 63; // Which sides the vertex is touching
|
||||
|
||||
// If the vertex is near a side where there is a low-resolution neighbor,
|
||||
// move it to secondary position
|
||||
int m = u_transition_mask & (cell_border_mask & 63);
|
||||
float t = float(m != 0);
|
||||
|
||||
// If the vertex lies on one or more sides, and at least one side has no low-resolution neighbor,
|
||||
// don't move the vertex.
|
||||
t *= float((vertex_border_mask & ~u_transition_mask) == 0);
|
||||
|
||||
// Position to use when border mask matches
|
||||
vec3 secondary_position = vertex_col.rgb;
|
||||
return mix(vertex_pos, secondary_position, t);
|
||||
}
|
||||
|
||||
void vertex() {
|
||||
//VERTEX = get_transvoxel_position(VERTEX, COLOR);
|
||||
|
||||
//VERTEX = (MODELVIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
||||
//VERTEX = floor(VERTEX * 100.0) * 0.01;
|
||||
|
||||
vec3 world_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
||||
v_world_pos = world_pos;
|
||||
v_world_normal = NORMAL;
|
||||
|
||||
// int border_mask = int(COLOR.a);
|
||||
// int cell_border_mask = border_mask & 63; // Which sides the cell is touching
|
||||
// int vertex_border_mask = (border_mask >> 6) & 63; // Which sides the vertex is touching
|
||||
// COLOR = vec4(float(cell_border_mask != 0), float(vertex_border_mask != 0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
|
||||
vec3 normal = v_world_normal;//normalize(v_world_normal);
|
||||
vec3 wpos = v_world_pos * 0.2;
|
||||
vec3 blending = get_triplanar_blend(normal);
|
||||
vec3 top_col = texture_triplanar(u_texture_top, wpos, blending).rgb;
|
||||
vec3 side_col = texture_triplanar(u_texture_sides, wpos, blending).rgb;
|
||||
float r = top_col.r;
|
||||
ALBEDO = mix(side_col, top_col, clamp(normal.y * 10.0 - 4.0 - 8.0*r, 0.0, 1.0));
|
||||
|
||||
//ALBEDO = COLOR.rgb * 0.2;
|
||||
}
|
13
project/smooth_terrain/transvoxel_terrain_material.tres
Normal file
@ -0,0 +1,13 @@
|
||||
[gd_resource type="ShaderMaterial" load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://smooth_terrain/transvoxel_terrain.shader" type="Shader" id=1]
|
||||
[ext_resource path="res://smooth_terrain/grass_albedo.png" type="Texture" id=2]
|
||||
[ext_resource path="res://smooth_terrain/dirt_albedo.png" type="Texture" id=3]
|
||||
|
||||
|
||||
|
||||
[resource]
|
||||
shader = ExtResource( 1 )
|
||||
shader_param/u_transition_mask = null
|
||||
shader_param/u_texture_top = ExtResource( 2 )
|
||||
shader_param/u_texture_sides = ExtResource( 3 )
|
14
project/smooth_terrain/voxel_generator_noise_2d_smooth.tres
Normal file
@ -0,0 +1,14 @@
|
||||
[gd_resource type="VoxelGeneratorNoise2D" load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://smooth_terrain/terrain_curve.tres" type="Curve" id=1]
|
||||
|
||||
[sub_resource type="OpenSimplexNoise" id=1]
|
||||
octaves = 6
|
||||
period = 256.0
|
||||
persistence = 0.4
|
||||
|
||||
[resource]
|
||||
height_start = -100.0
|
||||
height_range = 400.0
|
||||
noise = SubResource( 1 )
|
||||
curve = ExtResource( 1 )
|
@ -1,89 +0,0 @@
|
||||
extends Node
|
||||
|
||||
var radius = 0
|
||||
|
||||
func _ready():
|
||||
generate()
|
||||
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventKey:
|
||||
if event.pressed:
|
||||
match event.scancode:
|
||||
KEY_KP_ADD:
|
||||
radius += 8
|
||||
if radius > 255:
|
||||
radius = 255
|
||||
generate()
|
||||
KEY_KP_SUBTRACT:
|
||||
radius -= 8
|
||||
if radius < 0:
|
||||
radius = 0
|
||||
generate()
|
||||
|
||||
|
||||
func generate():
|
||||
print("iso: ", radius)
|
||||
var voxels = VoxelBuffer.new()
|
||||
|
||||
var size = 32
|
||||
voxels.create(size,size,size)
|
||||
var channel = VoxelBuffer.CHANNEL_ISOLEVEL
|
||||
|
||||
voxels.fill(255, channel)
|
||||
|
||||
if false:
|
||||
voxels.set_voxel(0, 4,4,4, channel)
|
||||
var v = 0
|
||||
voxels.set_voxel(120, 5,4,4, channel)
|
||||
voxels.set_voxel(v, 4,5,4, channel)
|
||||
voxels.set_voxel(v, 4,4,5, channel)
|
||||
voxels.set_voxel(v, 3,4,4, channel)
|
||||
voxels.set_voxel(v, 4,3,4, channel)
|
||||
voxels.set_voxel(v, 4,4,3, channel)
|
||||
|
||||
if false:
|
||||
var s = 3
|
||||
var e = 5
|
||||
for z in range(s, e):
|
||||
for x in range(s, e):
|
||||
for y in range(s, e):
|
||||
voxels.set_voxel(int(radius), x, y, z, channel)
|
||||
|
||||
if false:
|
||||
var r = 15
|
||||
for z in range(0, voxels.get_size_z()):
|
||||
for x in range(0, voxels.get_size_x()):
|
||||
for y in range(0, voxels.get_size_y()):
|
||||
var d = Vector3(16,16,16).distance_to(Vector3(x,y,z))
|
||||
var v = 0
|
||||
if d < r:
|
||||
v = 255
|
||||
voxels.set_voxel(v, x, y, z, channel)
|
||||
|
||||
if true:
|
||||
var fractal_noise = OpenSimplexNoise.new()
|
||||
fractal_noise.octaves = 3
|
||||
fractal_noise.period = 16
|
||||
fractal_noise.persistence = 0.5
|
||||
|
||||
for z in range(0, voxels.get_size_z()):
|
||||
for x in range(0, voxels.get_size_x()):
|
||||
for y in range(0, voxels.get_size_y()):
|
||||
var v = fractal_noise.get_noise_3d(x,y,z)
|
||||
if true:
|
||||
voxels.set_voxel_f(v, x,y,z, channel)
|
||||
else:
|
||||
if v > 0:
|
||||
v = 0
|
||||
else:
|
||||
v = 255
|
||||
voxels.set_voxel(v, x, y, z, channel)
|
||||
|
||||
var tvm = VoxelMesherTransvoxel.new()
|
||||
var mesh = tvm.build_mesh(voxels)
|
||||
|
||||
if mesh == null:
|
||||
print("The mesh is empty")
|
||||
get_node("MeshInstance").set_mesh(mesh)
|
||||
|
@ -1,41 +0,0 @@
|
||||
[gd_scene load_steps=7 format=2]
|
||||
|
||||
[ext_resource path="res://transvoxel_test/transvoxel_test.gd" type="Script" id=1]
|
||||
[ext_resource path="res://common/axes.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://common/spectator_avatar.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://common/grid.gd" type="Script" id=4]
|
||||
|
||||
|
||||
|
||||
|
||||
[sub_resource type="SpatialMaterial" id=1]
|
||||
albedo_color = Color( 0.7, 0.7, 0.7, 1 )
|
||||
|
||||
[sub_resource type="Environment" id=2]
|
||||
ssao_light_affect = 1.0
|
||||
ssao_blur = 1
|
||||
|
||||
[node name="Node" type="Node"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="MeshInstance" type="MeshInstance" parent="."]
|
||||
material_override = SubResource( 1 )
|
||||
|
||||
[node name="axes" parent="." instance=ExtResource( 2 )]
|
||||
transform = Transform( 20, 0, 0, 0, 20, 0, 0, 0, 20, -20, 0, -20 )
|
||||
|
||||
[node name="DirectionalLight" type="DirectionalLight" parent="."]
|
||||
transform = Transform( 0.230139, -0.950812, 0.207346, 0.479203, 0.296166, 0.826226, -0.846995, -0.0907862, 0.523791, 14.2262, 0, 0 )
|
||||
shadow_bias = 0.2
|
||||
directional_shadow_normal_bias = 0.2
|
||||
directional_shadow_bias_split_scale = 0.1
|
||||
|
||||
[node name="grid" type="MeshInstance" parent="."]
|
||||
script = ExtResource( 4 )
|
||||
step = 1
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = SubResource( 2 )
|
||||
|
||||
[node name="SpectatorAvatar" parent="." instance=ExtResource( 3 )]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 8.80608, 11.0698, 35.9803 )
|