Merge pull request #35 from eriwyn:triangle-to-voronoi

Triangle-to-voronoi
pull/41/head
eriwyn 3 years ago committed by GitHub
commit c1d0a422fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      menu/MainMenu.tscn
  2. 33
      ui/map/map.gd
  3. 2
      utils/camera/CameraController.gd
  4. 35
      utils/terrain/Terrain.gd
  5. 244
      utils/world_generation/WorldGeneration.gd
  6. 150
      world/game.tscn

@ -47,6 +47,10 @@ margin_right = 316.0
margin_bottom = 266.0
text = "Quitter"
[node name="Viewport" type="Viewport" parent="."]
size = Vector2( 2048, 2048 )
own_world = true
[connection signal="pressed" from="VBoxContainer/NewButton" to="." method="_on_NewButton_pressed"]
[connection signal="pressed" from="VBoxContainer/LoadButton" to="." method="_on_LoadButton_pressed"]
[connection signal="pressed" from="VBoxContainer/QuitButton" to="." method="_on_QuitButton_pressed"]

@ -3,29 +3,38 @@ extends Node2D
signal map_clicked
func heightmap():
draw_rect(Rect2(Vector2(0, 0), Vector2(2048, 2048)), Color("#0e88bd"))
print (Global.terrain)
for triangle in Global.terrain.get_triangles():
for center in Global.terrain.get_centers():
if not center.get_data("ocean"):
var colors = Gradient.new()
colors.add_point(0.999, Color("#9e0142")) # red
colors.add_point(0.5, Color("#dc865d")) # orange
colors.add_point(0.25, Color("#fbf8b0")) # yellow
colors.add_point(0.0, Color("#89cfa5")) # green
colors.add_point(-0.999, Color("#5e4fa2")) # blue
var color = colors.interpolate(min(triangle.get_elevation() + 0.001, 0.999))
var color = colors.interpolate(min(center.get_elevation() + 0.001, 0.999))
# color = Color.green
if triangle.is_water():
# var factor = pow((triangle.get_elevation()+1.001), 10) / 5.0
if center.get_data("ocean"):
# var factor = pow((center.get_elevation()+1.001), 10) / 5.0
color = Color("#5e4fa2")
if triangle.polygon().size() > 2:
draw_polygon(triangle.polygon(), PoolColorArray([color]))
# if center.get_data("coast"):
# color = Color.black
if center.polygon().size() > 2:
draw_polygon(center.polygon(), PoolColorArray([color]))
var coastline = PoolVector2Array()
for edge in Global.terrain.get_edges():
if edge.get_data("coast"):
coastline.append(edge.line()[0])
coastline.append(edge.line()[1])
if edge.get_data("river"):
draw_line(edge.line()[0], edge.line()[1], Color.blue, 5.0)
for center in Global.terrain.get_centers():
if center.get_data("coast"):
for border in center.borders():
if (border.end_center().get_data("ocean")):
coastline.append(border.line()[0])
coastline.append(border.line()[1])
# for edge in Global.terrain.get_edges():
# if edge.get_data("coast"):
# if edge.get_data("river"):
# draw_line(edge.line()[0], edge.line()[1], Color.blue, 5.0)
draw_multiline(coastline, Color.black)
func draw_triangles_edges(color=Color("#000000")):

@ -25,7 +25,7 @@ export(float, 10,100) var max_zoom = 100
export(float, 1,3) var zoom_sensibility = 1.4
export(float, 1,3) var rotation_sensibility = 2.3
export(float, 1.0, 10.0) var height = 15.0
export(float, 1.0, 20.0) var height = 15.0
var pitch : float
var yaw : float

@ -244,11 +244,40 @@ class Triangle:
func center2d():
var points = points()
return (points[0].point2d() + points[1].point2d() + points[2].point2d()) / 3.0
var a = points[0].point2d()
var b = points[1].point2d()
var c = points[2].point2d()
var ad = a[0] * a[0] + a[1] * a[1]
var bd = b[0] * b[0] + b[1] * b[1]
var cd = c[0] * c[0] + c[1] * c[1]
var D = 2 * (a[0] * (b[1] - c[1]) + b[0] * (c[1] - a[1]) + c[0] * (a[1] - b[1]))
return Vector2(
1 / D * (ad * (b[1] - c[1]) + bd * (c[1] - a[1]) + cd * (a[1] - b[1])),
1 / D * (ad * (c[0] - b[0]) + bd * (a[0] - c[0]) + cd * (b[0] - a[0]))
)
# return (points[0].point2d() + points[1].point2d() + points[2].point2d()) / 3.0
func center3d():
var points = points()
return (points[0].point3d() + points[1].point3d() + points[2].point3d()) / 3.0
var a = points[0].point2d()
var b = points[1].point2d()
var c = points[2].point2d()
var ad = a[0] * a[0] + a[1] * a[1]
var bd = b[0] * b[0] + b[1] * b[1]
var cd = c[0] * c[0] + c[1] * c[1]
var D = 2 * (a[0] * (b[1] - c[1]) + b[0] * (c[1] - a[1]) + c[0] * (a[1] - b[1]))
return Vector3(
1 / D * (ad * (b[1] - c[1]) + bd * (c[1] - a[1]) + cd * (a[1] - b[1])),
points[0].get_elevation(),
1 / D * (ad * (c[0] - b[0]) + bd * (a[0] - c[0]) + cd * (b[0] - a[0]))
)
# var center2d = center2d()
# return Vector3(center2d.x, )
# var points = points()
# return (points[0].point3d() + points[1].point3d() + points[2].point3d()) / 3.0
func set_elevation(elevation:float):
for point in points():
@ -573,7 +602,7 @@ func create(width:int, height:int, spacing:int, name:String):
func _create_points():
var rect = Rect2(Vector2(0, 0), Vector2(_width, _height))
var poisson_disc_sampling: PoissonDiscSampling = PoissonDiscSampling.new()
var points2d = poisson_disc_sampling.generate_points(_spacing, rect, 5)
var points2d = poisson_disc_sampling.generate_points(_spacing, rect, 2)
_points.resize(points2d.size())
for point_idx in points2d.size():
_points[point_idx].x = points2d[point_idx].x

@ -8,7 +8,7 @@ export(int) var spacing = 20
export(int, 1, 9) var octaves = 5
export(int, 1, 30) var wavelength = 8
export(int) var border_width = 200
export(int) var terraces = 10
export(int) var terraces = 100
export(int) var terrace_height = 5
export(float) var mountain_height = 6.0 / 24.0
export(int) var river_proba = 200
@ -28,13 +28,13 @@ func _init():
Global.terrain.create(width,height,spacing,Global.terrain_name)
var max_step = (
Global.terrain.get_triangles().size()
# + height
# Global.terrain.get_triangles().size()
Global.terrain.get_points().size()
)
if Global.terrain.is_created():
max_step += Global.terrain.get_points().size()
max_step += Global.terrain.get_triangles().size()
max_step += Global.terrain.get_centers().size()
Global.loading.set_step(Global.terrain.get_points().size())
Global.loading.set_max_step(max_step)
@ -44,8 +44,8 @@ func _init():
Global.terrain.save()
if Global.terrain.is_created() or Global.terrain.is_loaded():
Global.terrain.set_data("mesh", create_mesh())
# create_map()
Global.terrain.set_data("mesh", create_mesh())
# add_trees()
# get_tree().change_scene("res://world/game.tscn")
else:
@ -56,6 +56,22 @@ func _init():
Global.loading.set_end_time()
func init_data():
for center in Global.terrain.get_centers():
center.set_elevation(find_elevation(center.point2d()))
if center.get_elevation() <= 0.0:
center.set_data("water", true)
Global.loading.increment_step()
fill_oceans()
remove_holes()
for center in Global.terrain.get_centers():
center.set_data("coast", is_coast(center.to_point()))
# if center.get_data("ocean"):
# center.set_elevation(-1.0)
# for point in Global.terrain.get_points():
# point.set_elevation(point_find_elevation(point.point2d()))
# point.set_data("water", point_is_water(point))
@ -71,16 +87,23 @@ func init_data():
# point.set_data("coast", point_is_coast(point))
# if point.get_data("river"):
# set_river_path(point)
for triangle in Global.terrain.get_triangles():
triangle.set_elevation(find_elevation(triangle.center2d()))
# triangle.set_data("elevation", triangle_find_elevation(triangle))
triangle.set_data("water", triangle_is_water(triangle))
if not triangle.get_data("water"):
if triangle.get_elevation() < 0:
print(triangle.get_elevation())
if triangle.is_water():
triangle.set_elevation(0)
Global.loading.increment_step()
# print("a")
# for center in Global.terrain.get_centers():
# print("z")
# center.set_elevation(find_elevation(center.point2d))
# Global.loading.increment_step()
# print(center.get_elevation())
# for triangle in Global.terrain.get_triangles():
# triangle.set_elevation(find_elevation(triangle.center2d()))
# # triangle.set_data("elevation", triangle_find_elevation(triangle))
# triangle.set_data("water", triangle_is_water(triangle))
# if not triangle.get_data("water"):
# if triangle.get_elevation() < 0:
# print(triangle.get_elevation())
# if triangle.is_water():
# triangle.set_elevation(0)
# Global.loading.increment_step()
# triangle.set_data("ocean", false)
# for point in triangle.points():
# if point.get_data("ocean"):
@ -89,18 +112,7 @@ func init_data():
# edge.set_data("coast", edge_is_coast(edge))
# edge.set_data("river", edge_is_river(edge))
func fill_oceans():
var stack = []
for point in Global.terrain.get_points():
if point.point2d().x < 10 and point.get_data("water") and not point.get_data("ocean"):
stack.append(point.get_index())
while stack.size():
var current_point_id = stack.pop_back()
Global.terrain.get_point(current_point_id).set_data("ocean", true)
for neighbour in Global.terrain.get_point(current_point_id).points_around():
if neighbour.get_data("water") and not neighbour.get_data("ocean"):
stack.append(neighbour.get_index())
break
func set_river_path(point):
#TODO #2 fix rivers
@ -138,30 +150,7 @@ func set_river_path(point):
# Point
func find_elevation(point):
# var border = border_width + rng.randf_range(-20.0, 20.0)
var elevation = noise.get_noise_2d(point.x / wavelength, point.y / wavelength)
var nx = 2 * point.x / width - 1
var ny = 2 * point.y / height - 1
var radius = range_lerp(elevation, -1, 1, 0.8, 1.0)
var distance = 1 - (1-pow(nx, 2)) * (1-pow(ny,2))
distance = sqrt(pow(nx, 2) + pow(ny, 2))
if distance > radius:
elevation = (elevation - range_lerp(distance, radius, 1.0, 0.0, 1.0))
elevation = max(elevation, -1)
if elevation > 0.1:
elevation = max(pow((elevation) * 1.2, 1.5), 0.1)
elevation = min(elevation, 1)
elevation = round(elevation * terraces) / terraces
return elevation
func point_is_water(point):
if (point.get_elevation() < 0):
@ -224,51 +213,150 @@ func edge_is_river(edge):
# tree.translation = Vector3(triangle.center3d() * Vector3(1, 12*10, 1))
# add_child(tree)
func find_elevation(point):
# var border = border_width + rng.randf_range(-20.0, 20.0)
var elevation = noise.get_noise_2d(point.x / wavelength, point.y / wavelength)
var nx = 2 * point.x / width - 1
var ny = 2 * point.y / height - 1
var radius = range_lerp(elevation, -1, 1, 0.8, 1.0)
var distance = 1 - (1-pow(nx, 2)) * (1-pow(ny,2))
distance = sqrt(pow(nx, 2) + pow(ny, 2))
if distance > radius:
elevation = (elevation - range_lerp(distance, radius, 1.0, 0.0, 1.0))
elevation = max(elevation, -1)
if elevation > 0.1:
elevation = max(pow((elevation) * 1.2, 1.5), 0.1)
elevation = min(elevation, 1)
elevation = round(elevation * terraces) / terraces
return elevation
func fill_oceans():
var stack = []
var first_center = null
var i = 0.0
while not first_center:
first_center = Global.terrain.find_point(Vector2(i, i))
i += 1.0
stack.append(first_center.get_index())
while stack.size():
var current_point_id = stack.pop_back()
Global.terrain.get_point(current_point_id).set_data("ocean", true)
for neighbour in Global.terrain.get_point(current_point_id).points_around():
if neighbour.get_data("water") and not neighbour.get_data("ocean"):
stack.append(neighbour.get_index())
func remove_holes():
for center in Global.terrain.get_centers():
if center.get_data("water") and not center.get_data("ocean"):
center.set_elevation(0.2)
center.set_data("water", false)
func is_coast(point):
if not point.get_data("water"):
for neighbour in point.points_around():
if neighbour.get_data("ocean"):
return true
return false
func create_mesh():
var st = SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
for triangle in Global.terrain.get_triangles():
if not triangle.is_water():
if triangle.get_elevation() < 0:
print(triangle.get_elevation())
var factor = Vector3(1, 120, 1)
for edge in triangle.edges():
if triangle.get_elevation() > edge.opposite_triangle().get_elevation():
st.add_vertex(Vector3(edge.start().point3d().x, triangle.get_elevation(), edge.start().point3d().z) * factor)
st.add_vertex(Vector3(edge.end().point3d().x, triangle.get_elevation(), edge.end().point3d().z) * factor)
st.add_vertex(Vector3(edge.start().point3d().x, edge.opposite_triangle().get_elevation(), edge.start().point3d().z) * factor)
st.add_vertex(Vector3(edge.end().point3d().x, triangle.get_elevation(), edge.end().point3d().z) * factor)
st.add_vertex(Vector3(edge.end().point3d().x, edge.opposite_triangle().get_elevation(), edge.end().point3d().z) * factor)
st.add_vertex(Vector3(edge.start().point3d().x, edge.opposite_triangle().get_elevation(), edge.start().point3d().z) * factor)
for center in Global.terrain.get_centers():
if not center.get_data("water"):
for edge in center.borders():
if edge.end_center().get_elevation() < edge.start_center().get_elevation():
var top = edge.start_center().get_elevation()
# if edge.start_center().get_data("ocean"):
# top = -1.0
var bottom = edge.end_center().get_elevation()
if edge.end_center().get_data("ocean"):
bottom = 0.0
st.add_vertex(Vector3(edge.start_corner().point3d().x, bottom, edge.start_corner().point3d().z) * factor)
st.add_vertex(Vector3(edge.end_corner().point3d().x, top, edge.end_corner().point3d().z) * factor)
st.add_vertex(Vector3(edge.start_corner().point3d().x, top, edge.start_corner().point3d().z) * factor)
st.add_vertex(Vector3(edge.start_corner().point3d().x, bottom, edge.start_corner().point3d().z) * factor)
st.add_vertex(Vector3(edge.end_corner().point3d().x, bottom, edge.end_corner().point3d().z) * factor)
st.add_vertex(Vector3(edge.end_corner().point3d().x, top, edge.end_corner().point3d().z) * factor)
for corner_count in center.corners().size():
var current_corner = center.corners()[corner_count]
var next_corner
if corner_count < center.corners().size() - 1:
next_corner = center.corners()[corner_count+1]
else:
next_corner = center.corners()[0]
for point in triangle.points():
st.add_vertex(Vector3(point.point3d().x, triangle.get_elevation(), point.point3d().z) * factor)
st.add_vertex(Vector3(current_corner.point2d().x, center.get_elevation(), current_corner.point2d().y) * factor)
st.add_vertex(Vector3(next_corner.point2d().x, center.get_elevation(), next_corner.point2d().y) * factor)
st.add_vertex(Vector3(center.point2d().x, center.get_elevation(), center.point2d().y) * factor)
Global.loading.increment_step()
st.generate_normals()
st.generate_tangents()
st.index()
var mi = MeshInstance.new()
mi.mesh = st.commit()
var material = load("res://world/world.material")
mi.set_surface_material(0, material)
mi.create_convex_collision()
mi.create_trimesh_collision()
mi.cast_shadow = GeometryInstance.SHADOW_CASTING_SETTING_ON
return mi
# Enregistrement de la map + intégration dans la génération du monde #32
func create_map():
var img = Image.new()
img.create(width, height, false, Image.FORMAT_RGBA8)
img.lock()
for y in height:
Global.loading.increment_step()
for x in width:
img.set_pixel(x,y,Color(randf(), randf(), randf()))
img.unlock()
# func create_map():
# print("oui")
# var viewport = Viewport.new()
# viewport.size = Vector2(width, height)
# var canvas = Node2D.new()
# viewport.add_child(canvas)
# canvas.draw_line(Vector2(0.0, 0.0), Vector2(1000.0, 1000.0), [Color("#5e4fa2"))
# for center in Global.terrain.get_centers():
# var colors = Gradient.new()
# colors.add_point(0.999, Color("#9e0142")) # red
# colors.add_point(0.5, Color("#dc865d")) # orange
# colors.add_point(0.25, Color("#fbf8b0")) # yellow
# colors.add_point(0.0, Color("#89cfa5")) # green
# colors.add_point(-0.999, Color("#5e4fa2")) # blue
# var color = colors.interpolate(min(center.get_elevation() + 0.001, 0.999))
# # color = Color.green
# if center.get_data("water"):
# # var factor = pow((center.get_elevation()+1.001), 10) / 5.0
# color = Color("#5e4fa2")
# if center.polygon().size() > 2:
# canvas.draw_polygon(center.polygon(), PoolColorArray([color]))
# Global.loading.increment_step()
# var img = viewport.get_texture().get_data()
# img.flip_y()
# var err = img.save_png("user://terrain/heightmap.png")
# print(err)
# # print("non")

@ -1,4 +1,4 @@
[gd_scene load_steps=7 format=2]
[gd_scene load_steps=12 format=2]
[ext_resource path="res://ui/ui.tscn" type="PackedScene" id=1]
[ext_resource path="res://world/default_env.tres" type="Environment" id=3]
@ -8,8 +8,144 @@
[sub_resource type="PlaneMesh" id=1]
size = Vector2( 2000, 2000 )
[sub_resource type="SpatialMaterial" id=2]
albedo_color = Color( 0.054902, 0.533333, 0.741176, 1 )
[sub_resource type="Shader" id=2]
code = "shader_type spatial;
render_mode specular_phong, cull_disabled;
uniform float speed: hint_range(-1, 1) = 0.0;
uniform sampler2D noise1;
uniform sampler2D noise2;
uniform sampler2D normalmap: hint_normal;
uniform vec4 color : hint_color;
uniform vec4 deep_water: hint_color;
//depth-fade var
uniform float beer_law_factor = 2.0;
uniform float _distance = 0.0;
//foam var
uniform vec4 edge_color: hint_color;
uniform float edge_scale = 0.25;
uniform float near = 0.1;
uniform float far = 100.0f;
// wave var
uniform vec2 wave_strength = vec2(0.5, 0.25);
uniform vec2 wave_frequ = vec2(12.0, 12.0);
uniform vec2 time_factor = vec2(1.0, 2.0);
float waves(vec2 pos, float time) {
return (wave_strength.y * sin(pos.y * wave_frequ.y + time * time_factor.y)) + (wave_strength.x * sin(pos.x * wave_frequ.x + time * time_factor.x));
}
void vertex() {
VERTEX.y += waves(VERTEX.xy, TIME);
}
float rim(float depth) {
depth = 2.0 * depth - 1.0;
return near * far / (far + depth * (near - far));
}
float calc_depth_fade(float depth, mat4 projection_matrix,
vec4 fragcoord, float beer_factor, float __distance, vec3 vertex) {
float scene_depth = depth;
scene_depth = scene_depth * 2.0 - 1.0;
scene_depth = projection_matrix[3][2] / (scene_depth + projection_matrix[2][2]);
scene_depth = scene_depth + vertex.z; // z is negative
// application of beers law
scene_depth = exp(-scene_depth * beer_factor);
float screen_depth = fragcoord.z;
float depth_fade = (scene_depth - screen_depth) / __distance;
depth_fade = clamp(depth_fade, 0.0, 1.0);
return depth_fade;
}
void fragment() {
float time = TIME * speed;
vec3 n1 = texture(noise1, UV * 1.0 + time).rgb;
vec3 n2 = texture(noise2, UV * 1.0 - time * 0.2).rgb;
vec2 uv_movement = UV * 4.0;
uv_movement += TIME * speed * 4.0;
float sum = (n1.r + n2.r) - 1.0;
float z_depth = rim(texture(DEPTH_TEXTURE, SCREEN_UV).x);
float z_pos = rim(FRAGCOORD.z);
float diff = z_depth - z_pos;
// depth-fade
float z_depth_fade = calc_depth_fade(texture(DEPTH_TEXTURE, SCREEN_UV).x, PROJECTION_MATRIX, FRAGCOORD, beer_law_factor, _distance, VERTEX);
float z_fade = rim(FRAGCOORD.z);
float fade_diff = z_depth_fade - z_fade;
vec4 gradientcolor = mix(color, deep_water, z_depth_fade);
vec2 displacement = vec2(sum * 0.1);
diff += displacement.x * 70.0;
vec4 col = mix(edge_color, gradientcolor, step(edge_scale, diff));
vec4 alpha = texture(SCREEN_TEXTURE, SCREEN_UV + displacement);
alpha = vec4(9.0);
float fin = 0.0;
if (sum > 0.0 && sum < 0.4) fin = 0.1;
if (sum > 0.4 && sum < 0.8) fin = 0.0;
if (sum > 0.8) fin = 1.0;
// konvertier fin in vec3 um
ALBEDO = vec3(fin) + mix(alpha.rgb, col.rgb, gradientcolor.a);
NORMALMAP = texture(normalmap, uv_movement).rgb;
ROUGHNESS = 0.1;
}"
[sub_resource type="OpenSimplexNoise" id=4]
[sub_resource type="NoiseTexture" id=5]
width = 2048
height = 2048
seamless = true
noise = SubResource( 4 )
[sub_resource type="OpenSimplexNoise" id=6]
[sub_resource type="NoiseTexture" id=7]
width = 2048
height = 2048
seamless = true
noise = SubResource( 6 )
[sub_resource type="ShaderMaterial" id=3]
shader = SubResource( 2 )
shader_param/speed = 0.003
shader_param/color = Color( 0.054902, 0.533333, 0.741176, 1 )
shader_param/deep_water = Color( 0.0518, 0.31561, 0.74, 1 )
shader_param/beer_law_factor = 2.0
shader_param/_distance = 0.0
shader_param/edge_color = Color( 1, 1, 1, 1 )
shader_param/edge_scale = 0.25
shader_param/near = 0.1
shader_param/far = 100.0
shader_param/wave_strength = Vector2( 1, 0.5 )
shader_param/wave_frequ = Vector2( 12, 12 )
shader_param/time_factor = Vector2( 1, 2 )
shader_param/noise1 = SubResource( 5 )
shader_param/noise2 = SubResource( 7 )
[node name="Game" type="Node"]
@ -28,7 +164,7 @@ script = ExtResource( 4 )
[node name="Water" type="MeshInstance" parent="World3d"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 1000, 0, 1000 )
mesh = SubResource( 1 )
material/0 = SubResource( 2 )
material/0 = SubResource( 3 )
[node name="WorldEnvironment" type="WorldEnvironment" parent="World3d"]
environment = ExtResource( 3 )
@ -36,9 +172,11 @@ environment = ExtResource( 3 )
[node name="CamBase" parent="World3d" instance=ExtResource( 5 )]
[node name="Camera" parent="World3d/CamBase" index="0"]
transform = Transform( 1, 0, 0, 0, 0.659983, -0.75128, 0, 0.75128, 0.659983, 0, -1.90735e-06, 6.618 )
physics_interpolation_mode = 1
transform = Transform( 1, 0, 0, 0, 0.659983, -0.75128, 0, 0.75128, 0.659983, 0, -5.72205e-06, 6.618 )
fov = 55.0
depth_multiplier = 99.0
depth_threshold = 0.001
depth_multiplier = 999.0
zoom_sensibility = 1.436
[node name="DirectionalLight" type="DirectionalLight" parent="World3d"]

Loading…
Cancel
Save