Files

120 lines
3.8 KiB
GDScript

class_name SonarScan
extends RefCounted
const SonarScanState = preload("res://game/domain/sonar/sonar_scan_state.gd")
const SonarSampleBuffer = preload("res://game/domain/sonar/sonar_sample_buffer.gd")
const SonarContact = preload("res://game/domain/sonar/sonar_contact.gd")
var scan_id: StringName
var session_id: StringName
var sensor_transform: Transform3D
var minimum_range_m: float
var maximum_range_m: float
var horizontal_opening_radians: float
var vertical_opening_radians: float
var reveal_duration_seconds: float
var recovery_duration_seconds: float
var samples: SonarSampleBuffer
var contacts: Array[SonarContact]
var minimum_elevation_m: float
var maximum_elevation_m: float
var state: SonarScanState.Value
var reveal_progress: float
func _init(
p_scan_id: StringName,
p_session_id: StringName,
p_sensor_transform: Transform3D,
p_minimum_range_m: float,
p_maximum_range_m: float,
p_horizontal_opening_radians: float,
p_vertical_opening_radians: float,
p_reveal_duration_seconds: float,
p_recovery_duration_seconds: float,
p_samples: SonarSampleBuffer,
p_contacts: Array[SonarContact],
p_minimum_elevation_m: float,
p_maximum_elevation_m: float,
p_state: SonarScanState.Value,
p_reveal_progress: float
) -> void:
scan_id = p_scan_id
session_id = p_session_id
sensor_transform = p_sensor_transform
minimum_range_m = p_minimum_range_m
maximum_range_m = p_maximum_range_m
horizontal_opening_radians = p_horizontal_opening_radians
vertical_opening_radians = p_vertical_opening_radians
reveal_duration_seconds = p_reveal_duration_seconds
recovery_duration_seconds = p_recovery_duration_seconds
samples = p_samples
contacts = p_contacts.duplicate()
minimum_elevation_m = p_minimum_elevation_m
maximum_elevation_m = p_maximum_elevation_m
state = p_state
reveal_progress = p_reveal_progress
func with_phase(next_state: SonarScanState.Value, next_progress: float) -> SonarScan:
return new(
scan_id,
session_id,
sensor_transform,
minimum_range_m,
maximum_range_m,
horizontal_opening_radians,
vertical_opening_radians,
reveal_duration_seconds,
recovery_duration_seconds,
samples,
contacts,
minimum_elevation_m,
maximum_elevation_m,
next_state,
next_progress
)
func validation_error() -> String:
if scan_id.is_empty() or session_id.is_empty():
return "sonar scan identifiers must not be empty"
if not is_finite(minimum_range_m) or minimum_range_m < 0.0:
return "sonar minimum range is invalid"
if not is_finite(maximum_range_m) or maximum_range_m <= minimum_range_m:
return "sonar maximum range must exceed minimum range"
if (
not is_finite(horizontal_opening_radians)
or horizontal_opening_radians <= 0.0
or horizontal_opening_radians >= PI
):
return "sonar horizontal opening is invalid"
if (
not is_finite(vertical_opening_radians)
or vertical_opening_radians <= 0.0
or vertical_opening_radians >= PI
):
return "sonar vertical opening is invalid"
if reveal_duration_seconds <= 0.0 or recovery_duration_seconds < 0.0:
return "sonar phase durations are invalid"
if samples == null:
return "sonar sample buffer is missing"
var buffer_error := samples.validation_error()
if not buffer_error.is_empty():
return buffer_error
for contact: SonarContact in contacts:
if contact == null:
return "sonar contact is missing"
var contact_error := contact.validation_error()
if not contact_error.is_empty():
return contact_error
if not is_finite(minimum_elevation_m) or not is_finite(maximum_elevation_m):
return "sonar elevation scale is not finite"
if maximum_elevation_m <= minimum_elevation_m:
return "sonar elevation scale is empty"
if not SonarScanState.is_valid(state):
return "sonar scan state is invalid"
if not is_finite(reveal_progress) or reveal_progress < 0.0 or reveal_progress > 1.0:
return "sonar reveal progress must be between 0 and 1"
return ""