plasma_prp/core/
scene_node.rs1use std::io::Read;
9
10use anyhow::Result;
11
12use crate::resource::prp::PlasmaRead;
13
14use super::uoid::{Uoid, read_key_uoid};
15
16#[derive(Debug, Clone)]
20pub struct SceneNodeData {
21 pub self_key: Option<Uoid>,
22 pub scene_objects: Vec<Option<Uoid>>,
23 pub pool_objects: Vec<Option<Uoid>>,
24}
25
26impl SceneNodeData {
27 pub fn read(reader: &mut impl Read) -> Result<Self> {
29 let self_key = read_key_uoid(reader)?;
31
32 let num_scene_objects = reader.read_u32()?;
34 let mut scene_objects = Vec::with_capacity(num_scene_objects as usize);
35 for _ in 0..num_scene_objects {
36 scene_objects.push(read_key_uoid(reader)?);
37 }
38
39 let num_pool = reader.read_u32()?;
41 let mut pool_objects = Vec::with_capacity(num_pool as usize);
42 for _ in 0..num_pool {
43 pool_objects.push(read_key_uoid(reader)?);
44 }
45
46 Ok(Self {
47 self_key,
48 scene_objects,
49 pool_objects,
50 })
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 use crate::core::class_index::ClassIndex;
58 use crate::resource::prp::PrpPage;
59 use std::io::Cursor;
60 use std::path::Path;
61
62 #[test]
63 fn test_parse_cleft_scene_node() {
64 let path = Path::new("../../Plasma/staging/client/dat/Cleft_District_Cleft.prp");
65 if !path.exists() {
66 eprintln!("Skipping test: {:?} not found", path);
67 return;
68 }
69
70 let page = PrpPage::from_file(path).unwrap();
71 let node_keys: Vec<_> = page.keys_of_type(ClassIndex::PL_SCENE_NODE);
72
73 assert!(!node_keys.is_empty(), "Should have at least one scene node");
74
75 for key in &node_keys {
76 if let Some(data) = page.object_data(key) {
77 let mut cursor = Cursor::new(data);
78 let _ = cursor.read_i16().unwrap();
79
80 let node = SceneNodeData::read(&mut cursor).unwrap();
81 eprintln!(
82 "SceneNode '{}': {} scene objects, {} pool objects",
83 key.object_name,
84 node.scene_objects.len(),
85 node.pool_objects.len()
86 );
87 assert!(
88 !node.scene_objects.is_empty(),
89 "Cleft scene node should have scene objects"
90 );
91 }
92 }
93 }
94}