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