Terrain des sites de plongée : champ de hauteur authoré, Banc du Vigilant, formes variées et rendu sous-marin #4
No files matched your search
@@ -130,10 +130,6 @@ func _start_dive() -> void:
|
|||||||
if definition == null:
|
if definition == null:
|
||||||
push_error("dive site definition %s cannot be loaded" % _selected_site_path)
|
push_error("dive site definition %s cannot be loaded" % _selected_site_path)
|
||||||
return
|
return
|
||||||
var definition_error := definition.validation_error()
|
|
||||||
if not definition_error.is_empty():
|
|
||||||
push_error("dive site %s is invalid: %s" % [_selected_site_path, definition_error])
|
|
||||||
return
|
|
||||||
var world_scene := load(DIVE_WORLD_SCENE_PATH) as PackedScene
|
var world_scene := load(DIVE_WORLD_SCENE_PATH) as PackedScene
|
||||||
if world_scene == null:
|
if world_scene == null:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -59,6 +59,11 @@ func maximum_elevation_m() -> float:
|
|||||||
return _maximum_elevation_m
|
return _maximum_elevation_m
|
||||||
|
|
||||||
|
|
||||||
|
## Row-major elevations (index = row * columns + column), the HeightMapShape3D layout.
|
||||||
|
func elevations_m() -> PackedFloat32Array:
|
||||||
|
return _data.elevations_m
|
||||||
|
|
||||||
|
|
||||||
func elevation_at_cell(column: int, row: int) -> float:
|
func elevation_at_cell(column: int, row: int) -> float:
|
||||||
return _data.elevations_m[_data.index_of(_clamp_column(column), _clamp_row(row))]
|
return _data.elevations_m[_data.index_of(_clamp_column(column), _clamp_row(row))]
|
||||||
|
|
||||||
|
|||||||
@@ -116,12 +116,7 @@ func _build_collision() -> void:
|
|||||||
var shape := HeightMapShape3D.new()
|
var shape := HeightMapShape3D.new()
|
||||||
shape.map_width = _field.columns()
|
shape.map_width = _field.columns()
|
||||||
shape.map_depth = _field.rows()
|
shape.map_depth = _field.rows()
|
||||||
var heights := PackedFloat32Array()
|
shape.map_data = _field.elevations_m()
|
||||||
heights.resize(_field.columns() * _field.rows())
|
|
||||||
for row in _field.rows():
|
|
||||||
for column in _field.columns():
|
|
||||||
heights[row * _field.columns() + column] = _field.elevation_at_cell(column, row)
|
|
||||||
shape.map_data = heights
|
|
||||||
_collision = CollisionShape3D.new()
|
_collision = CollisionShape3D.new()
|
||||||
_collision.name = "Collision"
|
_collision.name = "Collision"
|
||||||
_collision.shape = shape
|
_collision.shape = shape
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ var _placeholder_count := 0
|
|||||||
func configure(definition: DiveSiteDefinition) -> String:
|
func configure(definition: DiveSiteDefinition) -> String:
|
||||||
if definition == null:
|
if definition == null:
|
||||||
return "dive site definition is missing"
|
return "dive site definition is missing"
|
||||||
var error := definition.validation_error()
|
var field := definition.height_field()
|
||||||
if not error.is_empty():
|
if field == null:
|
||||||
return error
|
return "dive site definition is invalid"
|
||||||
var terrain_error := _terrain.configure(definition.height_field())
|
var terrain_error := _terrain.configure(field)
|
||||||
if not terrain_error.is_empty():
|
if not terrain_error.is_empty():
|
||||||
return terrain_error
|
return terrain_error
|
||||||
_definition = definition
|
_definition = definition
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const SitePlacement = preload("res://game/domain/sites/site_placement.gd")
|
|||||||
const SiteRoute = preload("res://game/domain/sites/site_route.gd")
|
const SiteRoute = preload("res://game/domain/sites/site_route.gd")
|
||||||
const DiveSiteDefinition = preload("res://game/domain/sites/dive_site_definition.gd")
|
const DiveSiteDefinition = preload("res://game/domain/sites/dive_site_definition.gd")
|
||||||
|
|
||||||
const TEST_COUNT := 38
|
const TEST_COUNT := 39
|
||||||
|
|
||||||
var _failures: Array[String] = []
|
var _failures: Array[String] = []
|
||||||
|
|
||||||
@@ -83,10 +83,12 @@ func _test_terrain_data_validation() -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _test_height_field_sampling() -> void:
|
func _test_height_field_sampling() -> void:
|
||||||
var field := TerrainHeightField.from_data(_make_terrain(3, 4))
|
var data := _make_terrain(3, 4)
|
||||||
|
var field := TerrainHeightField.from_data(data)
|
||||||
_expect(field != null, "valid data yields a field")
|
_expect(field != null, "valid data yields a field")
|
||||||
if field == null:
|
if field == null:
|
||||||
return
|
return
|
||||||
|
_expect(field.elevations_m() == data.elevations_m, "elevations are exposed in row-major data order")
|
||||||
_expect(field.bounds_m().is_equal_approx(Rect2(-10.0, 100.0, 4.0, 6.0)), "bounds cover (columns-1) by (rows-1) cells")
|
_expect(field.bounds_m().is_equal_approx(Rect2(-10.0, 100.0, 4.0, 6.0)), "bounds cover (columns-1) by (rows-1) cells")
|
||||||
_expect(field.cell_world_position(2, 3).is_equal_approx(Vector3(-6.0, -26.0, 106.0)), "cell position follows origin and cell size")
|
_expect(field.cell_world_position(2, 3).is_equal_approx(Vector3(-6.0, -26.0, 106.0)), "cell position follows origin and cell size")
|
||||||
_expect(is_equal_approx(field.elevation_at(-10.0, 100.0), -20.0), "elevation at a vertex is exact")
|
_expect(is_equal_approx(field.elevation_at(-10.0, 100.0), -20.0), "elevation at a vertex is exact")
|
||||||
|
|||||||
Reference in new issue
Block a user