1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
extends Node
var chunk_half_size setget _set_chunk_size
var chunk_size
func _set_chunk_size(val):
chunk_half_size = val
chunk_size = val * 2.0
onready var noise = OpenSimplexNoise.new()
onready var rng = RandomNumberGenerator.new()
var _seed
func _ready():
#randomize()
#self._seed = randi()
self._seed = 0
self.noise.seed = self._seed
self.noise.seed = 0
self.noise.period = 16
self.noise.persistence = 0
self.rng.seed = self._seed
func rng_2dv(coords:Vector2):
self.rng.seed = hash(coords)
func gen_chunk(chunk):
gen_distance(chunk,chunk.get_node("gen_tree/lod_distance"))
gen_mid(chunk,chunk.get_node("gen_tree/lod_mid"))
gen_close(chunk,chunk.get_node("gen_tree/lod_close"))
func gen_distance(chunk,tree):
gen_lowres_rocks(chunk,tree)
func gen_mid(chunk,tree):
gen_rocks(chunk,tree)
func gen_close(chunk,tree):
gen_rock_hitboxes(chunk,tree)
func v2_coords(coords:Vector3):
return Vector2(coords.x,coords.z)
func v3_coords(coords:Vector2):
return Vector3(coords.x,0.0,coords.y)
func iterate_chunk(chunk,tree,step:Vector2,cb:FuncRef,data):
var chunk_size_rounded = Vector2(chunk_half_size,chunk_half_size).snapped(step)
for x in range(-chunk_size_rounded.x,chunk_size_rounded.x,step.x):
for y in range(-chunk_size_rounded.y,chunk_size_rounded.y,step.y):
cb.call_func(chunk,tree,Vector2(x,y),data)
func make_multimesh(name,cnt,mesh):
var multi_inst = MultiMeshInstance.new()
multi_inst.name = name
var multi = MultiMesh.new()
multi_inst.multimesh = multi
multi.transform_format = MultiMesh.TRANSFORM_3D
multi.instance_count = cnt
multi.visible_instance_count = 0
multi.mesh = mesh
return multi_inst
var rock_mesh = preload("res://world/obstacles/Rock_mesh.tres")
var rock_mat = preload("res://world/obstacles/Rock_mat.tres")
func gen_rocks(chunk,tree):
rock_mesh.material = rock_mat
var multi = make_multimesh("rocks",200,rock_mesh)
tree.add_child(multi)
iterate_chunk(chunk, multi.multimesh, Vector2(10.0,10.0), funcref(self,"rock_rng"), [0.4,0.6,1.0,4.0,1.0,funcref(self,"make_rock")])
var rock_lowres_mesh = preload("res://world/obstacles/Rock_lowres_mesh.tres")
func gen_lowres_rocks(chunk,tree):
rock_lowres_mesh.material = rock_mat
var multi = make_multimesh("rocks",50,rock_lowres_mesh)
tree.add_child(multi)
iterate_chunk(chunk, multi.multimesh, Vector2(20.0,20.0), funcref(self,"rock_rng"), [0.4,0.6,2.0,8.0,0.5,funcref(self,"make_rock")])
var rock_coll = preload("res://world/obstacles/Rock_coll.tres")
func gen_rock_hitboxes(chunk,tree):
iterate_chunk(chunk, tree, Vector2(20.0,20.0), funcref(self,"rock_rng"), [0.4,0.6,1.0,4.0,1.0,funcref(self,"make_rock_hitbox")])
func rock_rng(chunk,rocks,chunk_coords:Vector2,data):
var coords = v3_coords(chunk_coords)
var basis = Basis()
var world_coords = chunk_coords + v2_coords(chunk.transform.origin)
self.rng_2dv(world_coords)
var rng_val = self.rng.randf_range(0.0,TAU)
basis = Basis(Vector3.UP,rng_val) * basis
var noise_val = self.noise.get_noise_2dv(world_coords * 0.125)
if noise_val < data[0]:
return
noise_val = min(noise_val,data[1])
noise_val -= data[0]
noise_val /= data[1] - data[0]
noise_val = lerp(data[2],data[3],noise_val)
basis = basis.scaled(Vector3.ONE*noise_val)
basis = basis.scaled(Vector3(1.0,data[4],1.0))
coords.y += (noise_val*data[4]*5.0)-5.0
data[5].call_func(rocks,Transform(basis,coords))
func make_rock(rocks,xform:Transform):
rocks.visible_instance_count += 1
rocks.set_instance_transform(rocks.visible_instance_count-1, xform)
func make_rock_hitbox(rocks,xform:Transform):
var shape = CollisionShape.new()
shape.shape = rock_coll
shape.transform = xform
rocks.add_child(shape)
|