120 lines
3.8 KiB
GDScript
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 ""
|