From bad548dbd5b2d543cd8ebf6354dd7528e19a2db3 Mon Sep 17 00:00:00 2001 From: Valentin Stark Date: Sat, 27 Aug 2022 19:41:14 +0200 Subject: [PATCH] =?UTF-8?q?cr=C3=A9ation=20d'une=20class=20chunk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- project.godot | 6 ++ utils/terrain/Terrain.gd | 5 ++ utils/world_generation/WorldGeneration.gd | 3 +- world/World3d.gd | 76 +++++++++++++++++++++- world/chunk.gd | 71 ++++++++++++++++++++ world/materials/world.material | Bin 1319 -> 642 bytes 6 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 world/chunk.gd diff --git a/project.godot b/project.godot index baed0d8..3750e34 100644 --- a/project.godot +++ b/project.godot @@ -19,6 +19,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://utils/camera/outline.gd" }, { +"base": "Spatial", +"class": "Chunk", +"language": "GDScript", +"path": "res://world/chunk.gd" +}, { "base": "Reference", "class": "Delaunator", "language": "GDScript", @@ -42,6 +47,7 @@ _global_script_classes=[ { _global_script_class_icons={ "CameraController": "", "CameraOutline": "", +"Chunk": "", "Delaunator": "", "PoissonDiscSampling": "", "Terrain": "", diff --git a/utils/terrain/Terrain.gd b/utils/terrain/Terrain.gd index a24ebc7..de35550 100644 --- a/utils/terrain/Terrain.gd +++ b/utils/terrain/Terrain.gd @@ -850,3 +850,8 @@ func get_voronoi_cells_as_polygon(): list_polygon.append(center.polygon()) return(list_polygon) +func get_chunk(vect): + var centers = [] + for idx in _data["find_point"][int(vect[0] / 64.0) * 32 + int(vect[1] / 64.0)]: + centers.append(get_center(idx)) + return centers diff --git a/utils/world_generation/WorldGeneration.gd b/utils/world_generation/WorldGeneration.gd index f00364b..c409e6c 100644 --- a/utils/world_generation/WorldGeneration.gd +++ b/utils/world_generation/WorldGeneration.gd @@ -44,8 +44,9 @@ func _init(): Global.terrain.save() if Global.terrain.is_created() or Global.terrain.is_loaded(): + pass # create_map() - Global.terrain.set_data("mesh", create_mesh()) + # Global.terrain.set_data("mesh", create_mesh()) # add_trees() # get_tree().change_scene("res://world/game.tscn") else: diff --git a/world/World3d.gd b/world/World3d.gd index 62c90ef..2682307 100644 --- a/world/World3d.gd +++ b/world/World3d.gd @@ -1,11 +1,17 @@ extends Spatial var rng = RandomNumberGenerator.new() +var chunk_size = 16 +var chunk_amount = 16 +var chunks = {} +var unready_chunks = {} +var thread func _ready(): - var mi = Global.terrain.get_data("mesh") - add_child(mi) - add_trees() + # var mi = Global.terrain.get_data("mesh") + # add_child(mi) + # add_trees() + thread = Thread.new() func add_trees(): rng.randomize() @@ -25,3 +31,67 @@ func add_trees(): tree.rotate_y(rng.randi_range(0, 2*PI)) tree.translation = Vector3(point.x, center.get_elevation() * 120, point.y) add_child(tree) + + +func add_chunk(x, z): + var key = str(x) + "," + str(z) + if chunks.has(key) or unready_chunks.has(key): + return + + if not thread.is_active(): + thread.start(self, "load_chunk", [thread, x, z]) + unready_chunks[key] = 1 + +func load_chunk(array): + var thread = array[0] + var x = array[1] + var z = array[2] + + var chunk = Chunk.new(x * chunk_size, z * chunk_size) + + chunk.translation = Vector3(x * chunk_size, 0, z * chunk_size) + + call_deferred("load_done", chunk, thread) + +func load_done(chunk, thread): + add_child(chunk) + var key = str(chunk.x / chunk_size) + "," + str(chunk.z / chunk_size) + chunks[key] = chunk + unready_chunks.erase(key) + thread.wait_to_finish() + +func get_chunk(x, z): + var key = str(x) + "," + str(z) + if chunks.has(key): + return chunks.get(key) + + return null + +func _process(delta): + update_chunks() + clean_up_chunks() + reset_chunks() + +func update_chunks(): + var camera_translation = $CamBase/Camera.translation +# print(camera_translation) + var c_x = int(camera_translation.x) / chunk_size + var c_z = int(camera_translation.z) / chunk_size + + for x in range(c_x - chunk_amount * 0.5, c_x + chunk_amount * 0.53): + for z in range(c_z - chunk_amount * 0.5, c_z + chunk_amount * 0.53): + add_chunk(x, z) + var chunk = get_chunk(x, z) + if chunk != null: + chunk.should_remove = false + +func clean_up_chunks(): + for key in chunks: + var chunk = chunks[key] + if chunk.should_remove: + chunk.queue_free() + chunks.erase(key) + +func reset_chunks(): + for key in chunks: + chunks[key].should_remove = true diff --git a/world/chunk.gd b/world/chunk.gd new file mode 100644 index 0000000..b5430a8 --- /dev/null +++ b/world/chunk.gd @@ -0,0 +1,71 @@ +extends Spatial +class_name Chunk + +var noise +var should_remove = true +var x +var z + +func _init(x, z): + self.x = x + self.z = z + +func _ready(): + generate_chunk() + +func generate_chunk(): + var file = File.new() + file.open("res://world/materials/materials.json", File.READ) + var materials = JSON.parse(file.get_as_text()).result + + var st = SurfaceTool.new() + + st.begin(Mesh.PRIMITIVE_TRIANGLES) + var factor = Vector3(1, 120, 1) + for center in Global.terrain.get_chunk(Vector2(x, z)): + if not center.get_data("water"): + var material_id = materials[center.get_data("material")] + var top_uv = Vector2(0, float(material_id) / (materials.size()-1)) + var border_uv = Vector2(1, float(material_id) / (materials.size()-1)) + + 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_uv(border_uv) + 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] + + st.add_uv(Vector2(top_uv)) + 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.index() + + var mi = MeshInstance.new() + mi.mesh = st.commit() + var material = load("res://world/materials/world.material") + mi.set_surface_material(0, material) + mi.create_trimesh_collision() + mi.cast_shadow = GeometryInstance.SHADOW_CASTING_SETTING_ON + add_child(mi) diff --git a/world/materials/world.material b/world/materials/world.material index c5148d278ff330b70274fd00158ccb29ef546adc..dce9da7b8c829044dc3cb5ec0fed169b9b80e244 100644 GIT binary patch literal 642 zcmV-|0)72bQ$s@n000005C8xt1ONbP0ssIgwJ-f(Cj$i&0OlZWJ`jzzIRF3w01yy? z2mnBO42Zyr0X#-~S-0IiN#9;}?*b8KV%NBqc?c`g@;);@@{mSjCG7SlDb%X zW?Dx}A!6;l06~_Znnd?du3m`3$Ac}KcE(FTCf!IZzo;S<5 z#+gPVV-x~k#?6_*r~?*^h50{00As`k3kMAp70`nLqJxM3lb=Ge8g|e#^D>q$qzfrR z>ng8WwQQr^Xw-JTEmAFPojD(r`B9s**BYhz@aSmM1ZAi+OvVMoQdO`Xh^jQpsyZfY zfOue@O0!V7TrxfaK&VlnGl)zeGb1u-!YIc;0%WG@>=IzKHP0&JOjMV)X8q5Qa30mp z`P>EHQNYN0zkiyZjQUu?-2G>D5az@2VHAH;ts8=bqil(HiXW=51hl|8ARf2WsH%(3yq0=03>KhR+WH^oz&=c@3ARL(S#L=eAYR$0jq= cceENILvu2baUtPx9tpKn`9-DRl2TJcL*|Yv+yDRo literal 1319 zcmV+?1=#vhQ$s@n000005C8!13jhEQ1pojjwJ-f(@Cq#`07kdDMDTW-1C$9Z*hGsj z!yCuI@bC;SUc3xP20`xbMx=7K$Uzj_CcBqK7XLq+AJ?)L!=q>*7BY4tgGoh)^h{cd zr%I1c0hj=u0Hy$#i$F~gyu0&+?*pe7Zw}Bv>@+vLK z?oKUH6N76_Z^;XBrr=z)c5eDj8*&uX*f;Y8NLR_}Yg+dF?&d=e6g2Iv$I9cV@Y7ExpQT zzbCe&|1u`k8^)NSJWsmdsx5I^c2d;lkVaA+l1R1dxZoy@v^L~AG<-2ZEKf6cva~_k zbx`$_-KCc1X@|d<*;)4l^;0ml-HrHl!QFrO2g6j{1Gsm=OMh5rGd^LMiq_yXhZ{v> z-2H&N18|+O4Iht)&&QKl9M9$XSSXtIGcq79&x5{-8P%3n@olP@RaLBcPKIGIpFJR{zw0=@O5nsdl; zI#_>mxM{9prgf-1crNSKnKRvzgyp7Qj5aZAS#c4;yu9{R%u?5iP>d)v^V(OjhGU`V z&eZf>#ikguj5msY6DXNl@S8d;qLIkm9Yh3138)B+B`Jgq*;*h;vSlYv9(Z!-*fbwM z9Dr`zz_Eqc!DC}#DKfJ^FuM&!Z zd3g+rHrk6;T4Y#4Dn?bzv>%N^FDOpPz=$fA6fG?)F(DTi6QL3iOI^5I9y6LrEGu5u1VW_sDSNStr2YeHh6)NQbEu9ZG=T8I^A#1z7>WC9uku zDZZ!*Y;!7pyYRL(-jk-?J+*6Kf?<3OrtQv!d;7$hus(RxaMDgBfdCmk;SfSj{IbEA z{>fl<4Hm0mB#FIe*%&i4$?JN^&MFkUibtwWe4Dh0*2I2KH1N?L;aMiqm2(!2;pidD z8P-PX78HCC<>tm9Jg^?!=GLe6nlB)pASDTn@5A;6-xxS#FE9=G!wa@(W{D5}0XhvP ze?=t`KJ1o|p@oeMD%SE}P{@sl9>B%M19gS>^iX0!CzN9@@*Tw`kcu9C%Q1u($ znmK}|xB}9j{XH}m0>S>7_E$Cq$~>$EiA6>1Zj}(e+aDb)j%uL_vVyUQRjyqrMDsSGeSp3SB(B)SerK&~QI=t~C;{!gS-^z9dKFk9# zBWqIFokbzA4t4=*P)(?a%^7j6H5U++sUkpW7?fG0ZlN`CDc~2&NW>_@9y}0chw^?K d7=PR(12APnK?