summaryrefslogtreecommitdiffstats
path: root/water/Water.gd
blob: 02bf96611659628127a560ea30a955ad1b901ab2 (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
extends MeshInstance
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

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

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_quad(wave):
    return Quat(wave.steepness,wave._k,wave._a,wave._t)

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

func _set_time(val):
    _time = val
    for idx in waves.size():
        waves[idx]._time = _time
        _update_wave(idx)

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

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 new_pos = Vector3(pos.x,0,pos.z)
    for idx in waves.size():
        new_pos += gertsner_wave(pos, idx)
    return new_pos

func height(pos):
    var old_pos = pos
    var y = old_pos.y
    for _i in range(2):
        var new_pos = sample_wave(old_pos)
        y = new_pos.y
        new_pos = old_pos - (new_pos - old_pos)
        old_pos = new_pos
    y += self.global_transform.origin.y
    return y