feat(render): compose terrain with preview root
Docs Deploy / Build and Deploy MkDocs (push) Successful in 38s
Test / Lint (push) Failing after 2m6s
Test / Test (push) Skipped
Test / Render parity (push) Skipped

This commit is contained in:
2026-07-18 10:21:43 +04:00
parent 46851518fe
commit 8ac6a11100
7 changed files with 357 additions and 108 deletions
+22
View File
@@ -30,6 +30,7 @@ pub struct TerrainWorld {
grid: RuntimeGrid,
adjacency: Vec<Vec<ArealId>>,
surfaces: Vec<RuntimeTriangle>,
source_mesh: Option<LandMeshDocument>,
}
/// Surface hit.
@@ -232,6 +233,7 @@ impl TerrainWorld {
grid,
adjacency,
surfaces: Vec::new(),
source_mesh: None,
})
}
@@ -244,6 +246,7 @@ impl TerrainWorld {
pub fn from_land_msh(mesh: &LandMeshDocument) -> Result<Self, TerrainError> {
Ok(Self {
surfaces: build_surfaces(mesh)?,
source_mesh: Some(mesh.clone()),
..Self::default()
})
}
@@ -260,6 +263,7 @@ impl TerrainWorld {
) -> Result<Self, TerrainError> {
let mut world = Self::from_land_map(map)?;
world.surfaces = build_surfaces(mesh)?;
world.source_mesh = Some(mesh.clone());
Ok(world)
}
@@ -275,6 +279,24 @@ impl TerrainWorld {
self.surfaces.len()
}
/// Returns the validated source mesh retained for renderer integration.
///
/// Runtime collision queries use their own compact triangle representation;
/// keeping this document preserves the original geometry and UV streams for
/// rendering without asking the application layer to decode an archive again.
#[must_use]
pub fn source_mesh(&self) -> Option<&LandMeshDocument> {
self.source_mesh.as_ref()
}
/// Returns source terrain positions without exposing parser ownership to apps.
#[must_use]
pub fn source_positions(&self) -> Option<&[[f32; 3]]> {
self.source_mesh
.as_ref()
.map(|mesh| mesh.positions.as_slice())
}
fn locate_by_candidates(
&self,
position: [f32; 3],