summaryrefslogtreecommitdiffstats
path: root/water/Water.gd
blob: 9937725d9ed9df0d680faa9e71610f11fbc0ba45 (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
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 wave_speed = 2.0 setget _set_wave_speed
export var wave_size = 1.5 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)

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))

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 _set_wave_speed(val):
    var material = self.water_plane.get_surface_material(0)
    wave_speed = val
    material.set_shader_param("wave_speed", wave_speed)

func _set_wave_size(val):
    var material = self.water_plane.get_surface_material(0)
    wave_size = val
    material.set_shader_param("wave_size", wave_size)

func _set_time(val):
    _time = val
    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