Add production bathymetric sonar slice

This commit is contained in:
chindit committed 2026-10-02 15:52:11 +02:00
1 parent a18e82eb44
commit 7613daee84
28 files changed
+1825 -87

No files matched your search

+115
View File
@@ -0,0 +1,115 @@
class_name SonarSampleBuffer
extends RefCounted
const SonarMaterial = preload("res://game/domain/sonar/sonar_material.gd")
const SonarSample = preload("res://game/domain/sonar/sonar_sample.gd")
var columns: int
var rows: int
var _positions := PackedVector3Array()
var _normals := PackedVector3Array()
var _intensities := PackedFloat32Array()
var _elevations_m := PackedFloat32Array()
var _materials := PackedInt32Array()
var _observed := PackedByteArray()
var _sealed := false
func _init(p_columns: int, p_rows: int) -> void:
columns = p_columns
rows = p_rows
var sample_count := maxi(columns, 0) * maxi(rows, 0)
_positions.resize(sample_count)
_normals.resize(sample_count)
_intensities.resize(sample_count)
_elevations_m.resize(sample_count)
_materials.resize(sample_count)
_observed.resize(sample_count)
for index in sample_count:
_normals[index] = Vector3.UP
_materials[index] = SonarMaterial.Value.UNKNOWN
func set_sample(row: int, column: int, sample: SonarSample) -> String:
if _sealed:
return "sonar sample buffer is sealed"
var index := _index_of(row, column)
if index < 0:
return "sonar sample coordinates are outside the buffer"
if sample == null:
return "sonar sample is missing"
var error := sample.validation_error()
if not error.is_empty():
return error
if not sample.observed:
return "cannot write an unobserved sonar sample"
if _observed[index] == 1:
return "sonar sample coordinates are duplicated"
_positions[index] = sample.position_m
_normals[index] = sample.normal.normalized()
_intensities[index] = sample.intensity
_elevations_m[index] = sample.elevation_m
_materials[index] = sample.material
_observed[index] = 1
return ""
func seal() -> String:
if columns < 2 or rows < 2:
return "sonar sample buffer dimensions must be at least 2 by 2"
_sealed = true
return ""
func is_sealed() -> bool:
return _sealed
func sample_count() -> int:
return columns * rows
func observed_count() -> int:
var count := 0
for value: int in _observed:
count += value
return count
func sample_at(row: int, column: int) -> SonarSample:
var index := _index_of(row, column)
if index < 0 or _observed[index] == 0:
return SonarSample.unknown()
return SonarSample.new(
_positions[index],
_normals[index],
_intensities[index],
_elevations_m[index],
_materials[index],
true
)
func validation_error() -> String:
if columns < 2 or rows < 2:
return "sonar sample buffer dimensions must be at least 2 by 2"
if not _sealed:
return "sonar sample buffer must be sealed before publication"
var expected_size := columns * rows
if (
_positions.size() != expected_size
or _normals.size() != expected_size
or _intensities.size() != expected_size
or _elevations_m.size() != expected_size
or _materials.size() != expected_size
or _observed.size() != expected_size
):
return "sonar sample buffer arrays are not aligned"
return ""
func _index_of(row: int, column: int) -> int:
if row < 0 or row >= rows or column < 0 or column >= columns:
return -1
return row * columns + column