summaryrefslogtreecommitdiffstats
path: root/water/Water.gd
blob: 5a4bfe2aa660b97b773c53233ca97ec8214c2c2f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
extends Spatial
tool

export var wave1_steepness = 0.5 setget _set_wave1_steepness
export var wave1_wavelength = 10.0 setget _set_wave1_wavelength
export var wave1_direction = Vector2(1.0,0.0) setget _set_wave1_direction

export var wave2_steepness = 0.5 setget _set_wave2_steepness
export var wave2_wavelength = 10.0 setget _set_wave2_wavelength
export var wave2_direction = Vector2(1.0,0.0) setget _set_wave2_direction

export var wave3_steepness = 0.5 setget _set_wave3_steepness
export var wave3_wavelength = 10.0 setget _set_wave3_wavelength
export var wave3_direction = Vector2(1.0,0.0) setget _set_wave3_direction

export var wave4_steepness = 0.5 setget _set_wave4_steepness
export var wave4_wavelength = 10.0 setget _set_wave4_wavelength
export var wave4_direction = Vector2(1.0,0.0) setget _set_wave4_direction

export var wave5_steepness = 0.5 setget _set_wave5_steepness
export var wave5_wavelength = 10.0 setget _set_wave5_wavelength
export var wave5_direction = Vector2(1.0,0.0) setget _set_wave5_direction

export var wave6_steepness = 0.5 setget _set_wave6_steepness
export var wave6_wavelength = 10.0 setget _set_wave6_wavelength
export var wave6_direction = Vector2(1.0,0.0) setget _set_wave6_direction

export var wave_speed = 2.0 setget _set_wave_speed
export var wave_size = 1.0 setget _set_wave_size

onready var water_plane = $"MeshInstance"

func _set_wave_prop(idx, prop, val):
    if val == null: return
    if idx >= waves.size(): return
    waves[idx].set(prop,val)
    _update_wave(idx)

func _set_wave1_steepness(val):
    wave1_steepness = val
    _set_wave_prop(0,"steepness",val)

func _set_wave1_wavelength(val):
    wave1_wavelength = val
    _set_wave_prop(0,"wavelength",val)

func _set_wave1_direction(val):
    wave1_direction = val
    _set_wave_prop(0,"direction",val)

func _set_wave2_steepness(val):
    wave2_steepness = val
    _set_wave_prop(1,"steepness",val)

func _set_wave2_wavelength(val):
    wave2_wavelength = val
    _set_wave_prop(1,"wavelength",val)

func _set_wave2_direction(val):
    wave2_direction = val
    _set_wave_prop(1,"direction",val)

func _set_wave3_steepness(val):
    wave3_steepness = val
    _set_wave_prop(2,"steepness",val)

func _set_wave3_wavelength(val):
    wave3_wavelength = val
    _set_wave_prop(2,"wavelength",val)

func _set_wave3_direction(val):
    wave3_direction = val
    _set_wave_prop(2,"direction",val)

func _set_wave4_steepness(val):
    wave4_steepness = val
    _set_wave_prop(3,"steepness",val)

func _set_wave4_wavelength(val):
    wave4_wavelength = val
    _set_wave_prop(3,"wavelength",val)

func _set_wave4_direction(val):
    wave4_direction = val
    _set_wave_prop(3,"direction",val)

func _set_wave5_steepness(val):
    wave5_steepness = val
    _set_wave_prop(4,"steepness",val)

func _set_wave5_wavelength(val):
    wave5_wavelength = val
    _set_wave_prop(4,"wavelength",val)

func _set_wave5_direction(val):
    wave5_direction = val
    _set_wave_prop(4,"direction",val)

func _set_wave6_steepness(val):
    wave6_steepness = val
    _set_wave_prop(5,"steepness",val)

func _set_wave6_wavelength(val):
    wave6_wavelength = val
    _set_wave_prop(5,"wavelength",val)

func _set_wave6_direction(val):
    wave6_direction = val
    _set_wave_prop(5,"direction",val)

var _time = 0.0 setget _set_time
var waves = []
func _ready():
    waves.push_back(Wave.new(wave1_steepness,wave1_wavelength,wave1_direction,_time))
    waves.push_back(Wave.new(wave2_steepness,wave2_wavelength,wave2_direction,_time))
    waves.push_back(Wave.new(wave3_steepness,wave3_wavelength,wave3_direction,_time))
    waves.push_back(Wave.new(wave4_steepness,wave4_wavelength,wave4_direction,_time))
    waves.push_back(Wave.new(wave5_steepness,wave5_wavelength,wave5_direction,_time))
    waves.push_back(Wave.new(wave6_steepness,wave6_wavelength,wave6_direction,_time))
    for i in waves.size():
        _update_wave(i)
    _update_multipliers()
    self._time = 0.0

func _wave_to_v3(wave):
    return Vector3(wave.steepness,wave._k,wave._a)

func _update_wave(idx):
    var material = self.water_plane.get_surface_material(0)
    material.set_shader_param("wave" + str(idx+1), _wave_to_v3(waves[idx]))
    material.set_shader_param("wave" + str(idx+1) + "_dir", waves[idx].direction)

func _update_multipliers():
    if water_plane != null:
        var material = self.water_plane.get_surface_material(0)
        material.set_shader_param("wave_speed", wave_speed)
        material.set_shader_param("wave_size", wave_size)

func _set_wave_speed(val):
    wave_speed = val
    if val == null: return
    _update_multipliers()

func _set_wave_size(val):
    wave_size = val
    if val == null: return
    _update_multipliers()

func _set_time(val):
    _time = val
    if val == null: return
    var material = self.water_plane.get_surface_material(0)
    for idx in waves.size():
        waves[idx]._time = _time
        material.set_shader_param("wave" + str(idx+1) + "_t", waves[idx]._t)

func _physics_process(delta):
    self._time += delta * wave_speed

func gertsner_wave(pos, idx):
    if idx >= waves.size(): return 0.0
    var wave = waves[idx]
    var k = wave._k
    var a = wave._a
    var t = wave._t

    var d = wave.direction.normalized()
    var f = k * (d.dot(Vector2(pos.x,pos.z)) - t)

    var tmp = a * cos(f)
    var new_pos = Vector3(d.x * tmp, a * sin(f), d.y * tmp)

    return new_pos

func sample_wave(pos):
    var offset = Vector3.ZERO
    for idx in waves.size():
        offset += gertsner_wave(pos, idx)
    offset.y *= wave_size
    return offset

func height(pos):
    var test_pos = pos
    var offset = Vector3.ZERO
    for _i in range(3):
        offset = sample_wave(test_pos)
        test_pos += (pos - (test_pos + offset))
    return offset.y + self.water_plane.global_transform.origin.y