vtr_roundtrip/
vtr_roundtrip.rs1use std::io::Cursor;
22
23use vertra::camera::Camera;
24use vertra::geometry::Geometry;
25use vertra::objects::Object;
26use vertra::transform::Transform;
27use vertra::vtr;
28use vertra::world::World;
29
30fn main() {
31 let camera = Camera::new()
34 .with_position([0.0, 5.0, -12.0])
35 .with_rotation(90.0, -20.0);
36
37 let mut world = World::new();
38
39 let root_id = world.spawn_object(
41 Object {
42 name: "Root".to_string(),
43 str_id: "root".to_string(),
44 geometry: Some(Geometry::Cube { size: 1.0 }),
45 color: [1.0, 0.4, 0.4, 1.0],
46 transform: Transform::from_position(0.0, 0.0, 0.0),
47 ..Default::default()
48 },
49 None,
50 );
51
52 let child_id = world.spawn_object(
54 Object {
55 name: "Child".to_string(),
56 str_id: "child".to_string(),
57 geometry: Some(Geometry::Sphere {
58 radius: 0.5,
59 subdivisions: 16,
60 }),
61 color: [0.4, 0.8, 0.4, 1.0],
62 transform: Transform::from_position(3.0, 0.0, 0.0),
63 ..Default::default()
64 },
65 Some(root_id),
66 );
67
68 world.spawn_object(
70 Object {
71 name: "Grandchild".to_string(),
72 str_id: "grandchild".to_string(),
73 geometry: Some(Geometry::Pyramid {
74 base_size: 0.8,
75 height: 1.2,
76 }),
77 color: [0.4, 0.4, 1.0, 1.0],
78 transform: Transform::from_position(2.0, 0.0, 0.0),
79 ..Default::default()
80 },
81 Some(child_id),
82 );
83
84 println!("Original scene: {} object(s)", world.objects.len());
85
86 let mut buf: Vec<u8> = Vec::new();
89 vtr::write(&mut buf, &camera, &world).expect("serialization failed");
90 println!("Serialized to {} byte(s)", buf.len());
91
92 let header = vtr::read_header(&mut Cursor::new(&buf)).expect("header read failed");
95 println!(
96 "Header: format v{}, engine v{}, {} object(s)",
97 header.format_version,
98 header.engine_version_string(),
99 header.object_count,
100 );
101
102 assert_eq!(header.object_count as usize, world.objects.len());
103
104 let loaded = vtr::read(&mut Cursor::new(&buf)).expect("deserialization failed");
107 println!("Loaded scene: {} object(s)", loaded.world.objects.len());
108
109 assert_eq!(
112 loaded.world.objects.len(),
113 world.objects.len(),
114 "object count mismatch"
115 );
116
117 for str_id in ["root", "child", "grandchild"] {
119 let orig_id = world.get_id(str_id).expect("str_id missing in original");
120 let load_id = loaded
121 .world
122 .get_id(str_id)
123 .expect("str_id missing after round-trip");
124
125 let orig = &world.objects[&orig_id];
126 let load = &loaded.world.objects[&load_id];
127
128 assert_eq!(orig.name, load.name, "name mismatch for {str_id}");
129 assert_eq!(orig.color, load.color, "color mismatch for {str_id}");
130 assert_eq!(
131 orig.transform.position, load.transform.position,
132 "position mismatch for {str_id}"
133 );
134 assert_eq!(
135 orig.geometry, load.geometry,
136 "geometry mismatch for {str_id}"
137 );
138
139 println!(" ✓ {str_id:12} name={:?}", load.name);
140 }
141
142 assert_eq!(camera.eye, loaded.camera.eye, "camera eye mismatch");
144 assert_eq!(camera.fov, loaded.camera.fov, "camera fov mismatch");
145 println!(" ✓ camera");
146
147 println!("\nRound-trip verified ✓");
148}
149