Skip to content

Commit

Permalink
Added Scene Graph Serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
AideTechBot authored and Neo-Zhixing committed Mar 7, 2023
1 parent 2851ece commit 61a4c8a
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 2 deletions.
76 changes: 75 additions & 1 deletion src/dot_vox_data.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{Color, Layer, Material, Model, SceneNode};
use crate::{Color, Dict, Layer, Material, Model, SceneNode};
use std::io::{self, Write};

/// Container for `.vox` file data.
Expand Down Expand Up @@ -27,6 +27,7 @@ impl DotVoxData {
// Write out all of the children of MAIN first to get the number of bytes.
let mut children_buffer = Vec::new();
self.write_models(&mut children_buffer)?;
self.write_scene_graph(&mut children_buffer)?;
self.write_palette_chunk(&mut children_buffer)?;
let num_main_children_bytes = children_buffer.len() as u32;

Expand Down Expand Up @@ -75,6 +76,79 @@ impl DotVoxData {
Self::write_leaf_chunk(writer, "XYZI", &xyzi_chunk)
}

fn write_string(buffer: &mut Vec<u8>, str: &String) {
buffer.extend_from_slice(&((str.len() as u32).to_le_bytes()));
buffer.extend_from_slice(&str.as_bytes());
}

fn write_dict(buffer: &mut Vec<u8>, dict: &Dict) {
buffer.extend_from_slice(&((dict.len() as u32).to_le_bytes()));
for (key, value) in dict.iter() {
Self::write_string(buffer, key);
Self::write_string(buffer, value);
}
}

fn write_scene_graph<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
for (i, node) in self.scenes.iter().enumerate() {
Self::write_scene_node(writer, node, i as u32)?;
}

Ok(())
}

fn write_scene_node<W: Write>(
writer: &mut W,
node: &SceneNode,
i: u32,
) -> Result<(), io::Error> {
let id;
let mut node_chunk = Vec::new();
match node {
SceneNode::Group {
attributes,
children,
} => {
id = "nGRP";
node_chunk.extend_from_slice(&(i as u32).to_le_bytes());
Self::write_dict(&mut node_chunk, &attributes);
node_chunk.extend_from_slice(&((children.len() as u32).to_le_bytes()));
for child in children {
node_chunk.extend_from_slice(&child.to_le_bytes());
}
}
SceneNode::Transform {
frames,
child,
layer_id,
attributes,
} => {
id = "nTRN";
node_chunk.extend_from_slice(&(i as u32).to_le_bytes());
Self::write_dict(&mut node_chunk, &attributes);
node_chunk.extend_from_slice(&child.to_le_bytes());
node_chunk.extend_from_slice(&u32::MAX.to_le_bytes());
node_chunk.extend_from_slice(&layer_id.to_le_bytes());
node_chunk.extend_from_slice(&(frames.len() as u32).to_le_bytes());
for frame in frames {
Self::write_dict(&mut node_chunk, &frame.attributes);
}
}
SceneNode::Shape { attributes, models } => {
id = "nSHP";
node_chunk.extend_from_slice(&(i as u32).to_le_bytes());
Self::write_dict(&mut node_chunk, &attributes);
node_chunk.extend_from_slice(&(models.len() as u32).to_le_bytes());
for model in models {
node_chunk.extend_from_slice(&model.model_id.to_le_bytes());
Self::write_dict(&mut node_chunk, &model.attributes);
}
}
}

Self::write_leaf_chunk(writer, id, &node_chunk)
}

fn write_palette_chunk<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
let mut chunk = Vec::new();
for color in self.palette.iter() {
Expand Down
2 changes: 1 addition & 1 deletion src/scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ impl From<Position> for (i32, i32, i32) {
/// interpolated across the sequence of Frames using their positions.
pub struct Frame {
/// The raw attributes as parsed from the .vox
attributes: Dict,
pub attributes: Dict,
}

impl Frame {
Expand Down

0 comments on commit 61a4c8a

Please sign in to comment.