aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/fparkan-game/src/main.rs36
-rw-r--r--docs/tomes/05-render.md9
2 files changed, 44 insertions, 1 deletions
diff --git a/apps/fparkan-game/src/main.rs b/apps/fparkan-game/src/main.rs
index 3549b11..b199805 100644
--- a/apps/fparkan-game/src/main.rs
+++ b/apps/fparkan-game/src/main.rs
@@ -35,6 +35,8 @@ use fparkan_runtime::{
MissionAssets, MissionObjectDraft, MissionRequest,
};
use fparkan_vfs::DirectoryVfs;
+#[cfg(test)]
+use fparkan_world::OriginalObjectId;
use fparkan_world::WorldSnapshot;
use std::path::PathBuf;
use std::sync::Arc;
@@ -167,7 +169,9 @@ fn render_snapshot_with_assets(
draws.push(RenderSnapshotDraw {
id: DrawId(draw_id),
phase: RenderPhase::Opaque,
- object_id: None,
+ object_id: mission_drafts
+ .and_then(|drafts| drafts.get(index))
+ .and_then(|draft| draft.original_id),
mesh,
material_slots: vec![material],
material_index: 0,
@@ -428,6 +432,36 @@ mod tests {
);
}
+ #[test]
+ fn render_snapshot_preserves_mission_original_object_id() -> Result<(), String> {
+ let snapshot = WorldSnapshot {
+ tick: Tick(1),
+ objects: vec![ObjectHandle {
+ generation: 1,
+ slot: 0,
+ }],
+ events: Vec::new(),
+ hash: StateHash([0; 32]),
+ };
+ let drafts = vec![MissionObjectDraft {
+ original_id: Some(OriginalObjectId(42)),
+ resource_name_raw: Vec::new(),
+ identity_or_clan_raw: 0,
+ position: [0.0; 3],
+ orientation_raw: [0.0; 3],
+ scale: [1.0; 3],
+ visual_ids: Vec::new(),
+ properties: Vec::new(),
+ }];
+
+ let commands = render_snapshot_commands_with_assets(&snapshot, None, Some(&drafts))?;
+ let RenderCommand::Draw(draw) = &commands.commands[1] else {
+ return Err("expected draw".to_string());
+ };
+ assert_eq!(draw.object_id, Some(OriginalObjectId(42)));
+ Ok(())
+ }
+
fn prepared_visual(id: u64, material: u64) -> PreparedVisual {
PreparedVisual {
id: AssetId::new(id),
diff --git a/docs/tomes/05-render.md b/docs/tomes/05-render.md
index 85fc231..44ffac7 100644
--- a/docs/tomes/05-render.md
+++ b/docs/tomes/05-render.md
@@ -925,6 +925,15 @@ matrix convention are not yet proven. This preserves authored values without
inventing transform math; the app still uses planning backend and triangle
ranges, so it is not a full renderer claim.
+### Mission original-ID render provenance
+
+Each backend-neutral draw now retains the `OriginalObjectId` preserved by the
+TMA loader for its source mission object. This gives capture and diagnostics a
+stable link from a draw back to its original object record, including every
+visual component emitted for that object. The bridge deliberately leaves the
+value absent when no mission draft exists; it does not infer an original ID
+from a runtime slot or draw order.
+
`Land.msh` использует отдельный geometry-only bridge: validated `TerrainFace28`
сохраняет source triangle order, а его positions и packed UV0 попадают в тот же
static vertex/index upload path. Для текущего диагностического viewer XZ bounds