Add production bathymetric sonar slice
This commit is contained in:
1 parent
a18e82eb44
commit
7613daee84
28 files changed
+1825
-87
No files matched your search
@@ -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
|
||||
Reference in new issue
Block a user