add random start for train o start from a stop
This commit is contained in:
@@ -47,15 +47,112 @@ var next_stop_index: int = 0
|
|||||||
var stop_multiply: float = 1.0
|
var stop_multiply: float = 1.0
|
||||||
var is_restarting: bool = false
|
var is_restarting: bool = false
|
||||||
var tween_restart: Tween
|
var tween_restart: Tween
|
||||||
|
var environment_config: EnvironmentConfig
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
_cache_environment_config()
|
||||||
if curve != null and curve.get_baked_length() > 0:
|
if curve != null and curve.get_baked_length() > 0:
|
||||||
build_rails()
|
build_rails()
|
||||||
build_train()
|
build_train()
|
||||||
_plan_stops()
|
_plan_stops()
|
||||||
|
_apply_initial_train_start()
|
||||||
else:
|
else:
|
||||||
print("WARNING: Draw Path3D for rails!")
|
print("WARNING: Draw Path3D for rails!")
|
||||||
|
|
||||||
|
func _cache_environment_config() -> void:
|
||||||
|
var parent_node: Node = get_parent()
|
||||||
|
if parent_node != null:
|
||||||
|
var day_night_node := parent_node.get_node_or_null("DayNight") as EnvironmentManagerRoot
|
||||||
|
if day_night_node != null:
|
||||||
|
environment_config = day_night_node.environment_config
|
||||||
|
return
|
||||||
|
|
||||||
|
var current_scene: Node = get_tree().current_scene
|
||||||
|
if current_scene == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
for child in current_scene.get_children():
|
||||||
|
var environment_manager := child as EnvironmentManagerRoot
|
||||||
|
if environment_manager != null:
|
||||||
|
environment_config = environment_manager.environment_config
|
||||||
|
return
|
||||||
|
|
||||||
|
func _apply_initial_train_start() -> void:
|
||||||
|
if train_instance == null or curve == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
var total_length: float = curve.get_baked_length()
|
||||||
|
if total_length <= 0.0:
|
||||||
|
return
|
||||||
|
|
||||||
|
#start from a random position
|
||||||
|
if environment_config != null and environment_config.train_start_from_random_position:
|
||||||
|
train_progress = randf() * total_length
|
||||||
|
_update_next_stop_index_from_progress()
|
||||||
|
elif environment_config != null and not stop_offset.is_empty():
|
||||||
|
#start from a specific stop
|
||||||
|
var stop_index: int = clampi(environment_config.train_start_stop_index, 0, stop_offset.size() - 1)
|
||||||
|
train_progress = stop_offset[stop_index]
|
||||||
|
_set_next_stop_index_from_current(stop_index)
|
||||||
|
else:
|
||||||
|
train_progress = wrapf(train_progress, 0.0, total_length)
|
||||||
|
_update_next_stop_index_from_progress()
|
||||||
|
|
||||||
|
_snap_train_to_progress()
|
||||||
|
|
||||||
|
func _set_next_stop_index_from_current(current_stop_index: int) -> void:
|
||||||
|
if stop_offset.is_empty():
|
||||||
|
next_stop_index = 0
|
||||||
|
return
|
||||||
|
|
||||||
|
if train_speed >= 0.0:
|
||||||
|
next_stop_index = (current_stop_index + 1) % stop_offset.size()
|
||||||
|
else:
|
||||||
|
next_stop_index = current_stop_index - 1
|
||||||
|
if next_stop_index < 0:
|
||||||
|
next_stop_index = stop_offset.size() - 1
|
||||||
|
|
||||||
|
func _update_next_stop_index_from_progress() -> void:
|
||||||
|
if stop_offset.is_empty():
|
||||||
|
next_stop_index = 0
|
||||||
|
return
|
||||||
|
|
||||||
|
if train_speed >= 0.0:
|
||||||
|
next_stop_index = 0
|
||||||
|
for i in range(stop_offset.size()):
|
||||||
|
if stop_offset[i] > train_progress + 0.001:
|
||||||
|
next_stop_index = i
|
||||||
|
return
|
||||||
|
return
|
||||||
|
|
||||||
|
next_stop_index = stop_offset.size() - 1
|
||||||
|
for i in range(stop_offset.size() - 1, -1, -1):
|
||||||
|
if stop_offset[i] < train_progress - 0.001:
|
||||||
|
next_stop_index = i
|
||||||
|
return
|
||||||
|
|
||||||
|
func _snap_train_to_progress() -> void:
|
||||||
|
if train_instance == null or curve == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
var total_length: float = curve.get_baked_length()
|
||||||
|
if total_length <= 0.0:
|
||||||
|
return
|
||||||
|
|
||||||
|
train_progress = wrapf(train_progress, 0.0, total_length)
|
||||||
|
var center_position: Vector3 = to_global(curve.sample_baked(train_progress, true))
|
||||||
|
var prog_forward: float = wrapf(train_progress + 2.0, 0.0, total_length)
|
||||||
|
var forward_position: Vector3 = to_global(curve.sample_baked(prog_forward, true))
|
||||||
|
|
||||||
|
train_instance.global_position = center_position
|
||||||
|
if center_position.distance_to(forward_position) > 0.01:
|
||||||
|
train_instance.look_at(forward_position, Vector3.UP)
|
||||||
|
train_instance.rotate_y(PI)
|
||||||
|
|
||||||
|
if cameras:
|
||||||
|
cameras.global_position = center_position
|
||||||
|
cameras.global_basis = train_instance.global_basis
|
||||||
|
|
||||||
func build_rails() -> void:
|
func build_rails() -> void:
|
||||||
var mat_wood = StandardMaterial3D.new()
|
var mat_wood = StandardMaterial3D.new()
|
||||||
mat_wood.albedo_color = Color(0.35, 0.2, 0.1)
|
mat_wood.albedo_color = Color(0.35, 0.2, 0.1)
|
||||||
|
|||||||
@@ -700,6 +700,7 @@ func init_snow(value: float = 0.0):
|
|||||||
RenderingServer.global_shader_parameter_set("global_snow_accumulation_speed", environment_config.snow_accumulation_speed)
|
RenderingServer.global_shader_parameter_set("global_snow_accumulation_speed", environment_config.snow_accumulation_speed)
|
||||||
RenderingServer.global_shader_parameter_set("global_snow_melt_speed", environment_config.snow_melt_speed)
|
RenderingServer.global_shader_parameter_set("global_snow_melt_speed", environment_config.snow_melt_speed)
|
||||||
RenderingServer.global_shader_parameter_set("global_snow_max_accumulation", environment_config.snow_max_accumulation)
|
RenderingServer.global_shader_parameter_set("global_snow_max_accumulation", environment_config.snow_max_accumulation)
|
||||||
|
RenderingServer.global_shader_parameter_set("global_snow_cap_enabled", 1.0 if environment_config.show_snow_accumulation_volume else 0.0)
|
||||||
RenderingServer.global_shader_parameter_set("global_snow_cap_height", environment_config.snow_cap_height)
|
RenderingServer.global_shader_parameter_set("global_snow_cap_height", environment_config.snow_cap_height)
|
||||||
RenderingServer.global_shader_parameter_set("global_snow_cap_flatness_start", environment_config.snow_cap_flatness_start)
|
RenderingServer.global_shader_parameter_set("global_snow_cap_flatness_start", environment_config.snow_cap_flatness_start)
|
||||||
RenderingServer.global_shader_parameter_set("global_snow_cap_flatness_end", environment_config.snow_cap_flatness_end)
|
RenderingServer.global_shader_parameter_set("global_snow_cap_flatness_end", environment_config.snow_cap_flatness_end)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ global uniform float global_snow_melt_speed = 0.1;
|
|||||||
global uniform float global_snow_threshold = 0.5;
|
global uniform float global_snow_threshold = 0.5;
|
||||||
global uniform vec4 global_snow_color = vec4(0.92, 0.96, 1.0, 1.0);
|
global uniform vec4 global_snow_color = vec4(0.92, 0.96, 1.0, 1.0);
|
||||||
global uniform float global_snow_max_accumulation = 0.72;
|
global uniform float global_snow_max_accumulation = 0.72;
|
||||||
|
global uniform float global_snow_cap_enabled = 1.0;
|
||||||
global uniform float global_snow_cap_height = 0.06;
|
global uniform float global_snow_cap_height = 0.06;
|
||||||
global uniform float global_snow_cap_flatness_start = 0.72;
|
global uniform float global_snow_cap_flatness_start = 0.72;
|
||||||
global uniform float global_snow_cap_flatness_end = 0.96;
|
global uniform float global_snow_cap_flatness_end = 0.96;
|
||||||
@@ -92,6 +93,7 @@ void vertex() {
|
|||||||
float snow_amount = get_snow_amount();
|
float snow_amount = get_snow_amount();
|
||||||
vec3 world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
vec3 world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
||||||
vec3 world_normal = normalize((MODEL_MATRIX * vec4(NORMAL, 0.0)).xyz);
|
vec3 world_normal = normalize((MODEL_MATRIX * vec4(NORMAL, 0.0)).xyz);
|
||||||
|
float snow_cap_enabled = step(0.5, global_snow_cap_enabled);
|
||||||
|
|
||||||
float flat_surface = smoothstep(
|
float flat_surface = smoothstep(
|
||||||
max(global_snow_threshold, global_snow_cap_flatness_start),
|
max(global_snow_threshold, global_snow_cap_flatness_start),
|
||||||
@@ -103,7 +105,7 @@ void vertex() {
|
|||||||
float cap_variation = mix(1.0 - global_snow_cap_noise_strength, 1.0 + global_snow_cap_noise_strength, cap_noise);
|
float cap_variation = mix(1.0 - global_snow_cap_noise_strength, 1.0 + global_snow_cap_noise_strength, cap_noise);
|
||||||
|
|
||||||
v_snow_amount = snow_amount;
|
v_snow_amount = snow_amount;
|
||||||
v_snow_cap_mask = flat_surface * accumulation_growth * cap_variation;
|
v_snow_cap_mask = flat_surface * accumulation_growth * cap_variation * snow_cap_enabled;
|
||||||
|
|
||||||
VERTEX += NORMAL * (global_snow_cap_height * snow_amount * v_snow_cap_mask);
|
VERTEX += NORMAL * (global_snow_cap_height * snow_amount * v_snow_cap_mask);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,6 +133,11 @@ extends Resource
|
|||||||
@export var godray_spawn_height: float = 5.0 #Y world position where god rays spawn
|
@export var godray_spawn_height: float = 5.0 #Y world position where god rays spawn
|
||||||
@export var godray_scale: Vector3 = Vector3(2.0, 6.0, 2.0) #Scale of the god ray mesh
|
@export var godray_scale: Vector3 = Vector3(2.0, 6.0, 2.0) #Scale of the god ray mesh
|
||||||
|
|
||||||
|
#Train start settings
|
||||||
|
@export_group("Train Start")
|
||||||
|
@export var train_start_from_random_position: bool = false #When enabled the train starts from a random offset on the rail curve instead of a stop
|
||||||
|
@export_range(0, 64, 1, "or_greater") var train_start_stop_index: int = 1 #Stop index used for the train start when random start is disabled
|
||||||
|
|
||||||
#Snow settings
|
#Snow settings
|
||||||
@export_group("Snow")
|
@export_group("Snow")
|
||||||
@export var snow_amount: float = 0.0 #Initial snow coverage amount (0.0 = none, 1.0 = full)
|
@export var snow_amount: float = 0.0 #Initial snow coverage amount (0.0 = none, 1.0 = full)
|
||||||
@@ -141,6 +146,7 @@ extends Resource
|
|||||||
@export var snow_threshold: float = 0.4 #Normal Y threshold for snow accumulation on surfaces
|
@export var snow_threshold: float = 0.4 #Normal Y threshold for snow accumulation on surfaces
|
||||||
@export var snow_accumulation_speed: float = 0.014 #Accumulation speed: 0.1 -> 10s, 0.05 -> 20s, 0.02 -> 50s, 0.012 -> ~83s
|
@export var snow_accumulation_speed: float = 0.014 #Accumulation speed: 0.1 -> 10s, 0.05 -> 20s, 0.02 -> 50s, 0.012 -> ~83s
|
||||||
@export var snow_melt_speed: float = 0.05 #Speed at which accumulated snow melts away
|
@export var snow_melt_speed: float = 0.05 #Speed at which accumulated snow melts away
|
||||||
|
@export var show_snow_accumulation_volume: bool = true #Enables vertex snow buildup; when false snow only changes surface color
|
||||||
@export var snow_max_accumulation: float = 0.25 #Maximum accumulated snow factor applied to coverage and thickness
|
@export var snow_max_accumulation: float = 0.25 #Maximum accumulated snow factor applied to coverage and thickness
|
||||||
@export var snow_color: Color = Color(0.9, 0.95, 1.0) #Albedo color of snow on surfaces
|
@export var snow_color: Color = Color(0.9, 0.95, 1.0) #Albedo color of snow on surfaces
|
||||||
@export var snow_cap_height: float = 0.03 #Maximum snow thickness extruded on flat surfaces
|
@export var snow_cap_height: float = 0.03 #Maximum snow thickness extruded on flat surfaces
|
||||||
|
|||||||
@@ -136,3 +136,7 @@ global_snow_max_accumulation={
|
|||||||
"type": "float",
|
"type": "float",
|
||||||
"value": 0.0
|
"value": 0.0
|
||||||
}
|
}
|
||||||
|
global_snow_cap_enabled={
|
||||||
|
"type": "bool",
|
||||||
|
"value": false
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user