feat(world): seabed flora and encrusting growth on rock
Quality Gate / Quality Gate (pull_request) Failing after 2m58s
Quality Gate / Quality Gate (pull_request) Failing after 2m58s
SeabedFloraActor scatters seagrass tufts on flat sand in the lit band and sea fans on rock between 15 and 60 m, deterministically from the site id, one MultiMesh per tile and kind, with procedural alpha-cut meshes and textures (SeabedFloraAssets), vertex sway and wrapped lighting, no collision and no sonar presence. Placement reads the field arrays directly and runs on the worker thread pool. The seabed shader grows turf algae on sunlit rock, coralline crusts in patches and encrusting sponges in the shade, fading out between 40 and 75 m. The water-column optics move to a shared shader include. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
122f3f5800
commit
0f9918224a
16 files changed
+585
-14
No files matched your search
@@ -10,6 +10,7 @@ const DiveSiteDefinition = preload("res://game/domain/sites/dive_site_definition
|
||||
const SitePlacement = preload("res://game/domain/sites/site_placement.gd")
|
||||
const DiveSite = preload("res://game/world/sites/dive_site.gd")
|
||||
const SeabedDetailTextures = preload("res://game/world/sites/seabed_detail_textures.gd")
|
||||
const SeabedFloraActor = preload("res://game/world/sites/seabed_flora_actor.gd")
|
||||
const SonarCaptureRequest = preload("res://game/application/sonar/sonar_capture_request.gd")
|
||||
const ReferenceBathymetryAcquisition = preload(
|
||||
"res://game/world/sonar/reference_bathymetry_acquisition.gd"
|
||||
@@ -19,7 +20,7 @@ const DIVE_SITE_SCENE = preload("res://game/world/sites/dive_site.tscn")
|
||||
const ZONE1_SITE_PATH := "res://content/sites/zone1_vigilant.tres"
|
||||
const SHOWCASE_SITE_PATH := "res://content/sites/terrain_showcase.tres"
|
||||
const GROOVE_PROBE_OFFSET_M := 25.0
|
||||
const TEST_COUNT := 44
|
||||
const TEST_COUNT := 49
|
||||
|
||||
var _failures: Array[String] = []
|
||||
|
||||
@@ -188,6 +189,27 @@ func _test_dive_site_scene() -> void:
|
||||
await physics_frame
|
||||
await physics_frame
|
||||
_expect(site.terrain().tile_count() > 0, "site builds its terrain tiles")
|
||||
var flora := site.flora()
|
||||
var grass_count := flora.instance_count(SeabedFloraActor.Kind.SEAGRASS)
|
||||
var fan_count := flora.instance_count(SeabedFloraActor.Kind.SEA_FAN)
|
||||
_expect(grass_count > 0 and fan_count > 0, "calibration site grows seagrass and sea fans (%d, %d)" % [grass_count, fan_count])
|
||||
var field_for_flora := definition.height_field()
|
||||
var grass_on_sand := true
|
||||
var grass_in_band := true
|
||||
for transform in flora.sample_transforms(SeabedFloraActor.Kind.SEAGRASS):
|
||||
var at := transform.origin
|
||||
grass_on_sand = grass_on_sand and field_for_flora.material_at(at.x, at.z) == SonarMaterial.Value.SAND
|
||||
grass_in_band = grass_in_band and -at.y < SeabedFloraActor.GRASS_DEPTH_NONE_M and absf(at.y - field_for_flora.elevation_at(at.x, at.z)) < 0.1
|
||||
_expect(grass_on_sand, "seagrass stands on sand")
|
||||
_expect(grass_in_band, "seagrass stays in the lit band and on the seabed")
|
||||
var fans_on_rock := true
|
||||
for transform in flora.sample_transforms(SeabedFloraActor.Kind.SEA_FAN):
|
||||
var at := transform.origin
|
||||
fans_on_rock = fans_on_rock and field_for_flora.material_at(at.x, at.z) == SonarMaterial.Value.ROCK
|
||||
_expect(fans_on_rock, "sea fans stand on rock")
|
||||
var first_pass := flora.sample_transforms(SeabedFloraActor.Kind.SEAGRASS)
|
||||
flora.configure(field_for_flora, hash(String(definition.site_id)))
|
||||
_expect(first_pass == flora.sample_transforms(SeabedFloraActor.Kind.SEAGRASS), "flora placement is deterministic for a seed")
|
||||
var water_column := site.get_node_or_null("WaterColumn") as FogVolume
|
||||
_expect(
|
||||
water_column != null and water_column.material is ShaderMaterial
|
||||
|
||||
Reference in new issue
Block a user