Cleaned up DataTree API and finished Instance parsing.
This commit is contained in:
parent
f5dd8f7a14
commit
d8cdf4d189
|
@ -60,43 +60,65 @@ impl AssemblyBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_object(&mut self, name: &str, obj: Object) {
|
pub fn add_object(&mut self, name: &str, obj: Object) {
|
||||||
|
// Make sure the name hasn't already been used.
|
||||||
|
if self.name_exists(name) {
|
||||||
|
panic!("Attempted to add object to assembly with a name that already exists.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add object
|
||||||
self.object_map.insert(name.to_string(), self.objects.len());
|
self.object_map.insert(name.to_string(), self.objects.len());
|
||||||
self.objects.push(obj);
|
self.objects.push(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_assembly(&mut self, name: &str, asmb: Assembly) {
|
pub fn add_assembly(&mut self, name: &str, asmb: Assembly) {
|
||||||
|
// Make sure the name hasn't already been used.
|
||||||
|
if self.name_exists(name) {
|
||||||
|
panic!("Attempted to add assembly to another assembly with a name that already \
|
||||||
|
exists.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add assembly
|
||||||
self.assembly_map.insert(name.to_string(), self.assemblies.len());
|
self.assembly_map.insert(name.to_string(), self.assemblies.len());
|
||||||
self.assemblies.push(asmb);
|
self.assemblies.push(asmb);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_object_instance(&mut self, name: &str, xforms: Option<&[Matrix4x4]>) {
|
pub fn add_instance(&mut self, name: &str, xforms: Option<&[Matrix4x4]>) {
|
||||||
let instance = Instance {
|
// Make sure name exists
|
||||||
instance_type: InstanceType::Object,
|
if !self.name_exists(name) {
|
||||||
data_index: self.object_map[name],
|
panic!("Attempted to add instance with a name that doesn't exist.");
|
||||||
id: self.instances.len(),
|
}
|
||||||
transform_indices: xforms.map(|xf| (self.xforms.len(), self.xforms.len() + xf.len())),
|
|
||||||
|
// Create instance
|
||||||
|
let instance = if self.object_map.contains_key(name) {
|
||||||
|
Instance {
|
||||||
|
instance_type: InstanceType::Object,
|
||||||
|
data_index: self.object_map[name],
|
||||||
|
id: self.instances.len(),
|
||||||
|
transform_indices: xforms.map(|xf| {
|
||||||
|
(self.xforms.len(), self.xforms.len() + xf.len())
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Instance {
|
||||||
|
instance_type: InstanceType::Assembly,
|
||||||
|
data_index: self.assembly_map[name],
|
||||||
|
id: self.instances.len(),
|
||||||
|
transform_indices: xforms.map(|xf| {
|
||||||
|
(self.xforms.len(), self.xforms.len() + xf.len())
|
||||||
|
}),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.instances.push(instance);
|
self.instances.push(instance);
|
||||||
|
|
||||||
|
// Store transforms
|
||||||
if let Some(xf) = xforms {
|
if let Some(xf) = xforms {
|
||||||
self.xforms.extend(xf);
|
self.xforms.extend(xf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_assembly_instance(&mut self, name: &str, xforms: Option<&[Matrix4x4]>) {
|
pub fn name_exists(&self, name: &str) -> bool {
|
||||||
let instance = Instance {
|
self.object_map.contains_key(name) || self.assembly_map.contains_key(name)
|
||||||
instance_type: InstanceType::Assembly,
|
|
||||||
data_index: self.object_map[name],
|
|
||||||
id: self.instances.len(),
|
|
||||||
transform_indices: xforms.map(|xf| (self.xforms.len(), self.xforms.len() + xf.len())),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.instances.push(instance);
|
|
||||||
|
|
||||||
if let Some(xf) = xforms {
|
|
||||||
self.xforms.extend(xf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(mut self) -> Assembly {
|
pub fn build(mut self) -> Assembly {
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
use std::cmp::Eq;
|
use std::cmp::Eq;
|
||||||
|
use std::iter::{Iterator, Filter};
|
||||||
|
use std::slice;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub enum DataTree<'a> {
|
pub enum DataTree<'a> {
|
||||||
|
@ -70,50 +72,57 @@ impl<'a> DataTree<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_first_child_with_type_name(&'a self, type_name: &str) -> Option<&'a DataTree> {
|
pub fn iter_children(&'a self) -> slice::Iter<'a, DataTree<'a>> {
|
||||||
if let &DataTree::Internal { ref children, .. } = self {
|
if let &DataTree::Internal{ref children, ..} = self {
|
||||||
for child in children.iter() {
|
children.iter()
|
||||||
match child {
|
|
||||||
&DataTree::Internal { type_name: tn, .. } => {
|
|
||||||
if tn == type_name {
|
|
||||||
return Some(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&DataTree::Leaf { type_name: tn, .. } => {
|
|
||||||
if tn == type_name {
|
|
||||||
return Some(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return None;
|
|
||||||
} else {
|
} else {
|
||||||
return None;
|
[].iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn count_children_with_type_name(&self, type_name: &str) -> usize {
|
pub fn iter_children_with_type(&'a self, type_name: &'static str) -> DataTreeFilterIter<'a> {
|
||||||
if let &DataTree::Internal { ref children, .. } = self {
|
if let &DataTree::Internal{ref children, ..} = self {
|
||||||
let mut count = 0;
|
DataTreeFilterIter {
|
||||||
for child in children.iter() {
|
type_name: type_name,
|
||||||
match child {
|
iter: children.iter(),
|
||||||
&DataTree::Internal { type_name: tn, .. } => {
|
|
||||||
if tn == type_name {
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&DataTree::Leaf { type_name: tn, .. } => {
|
|
||||||
if tn == type_name {
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return count;
|
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
DataTreeFilterIter {
|
||||||
|
type_name: type_name,
|
||||||
|
iter: [].iter(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter_internal_children_with_type(&'a self,
|
||||||
|
type_name: &'static str)
|
||||||
|
-> DataTreeFilterInternalIter<'a> {
|
||||||
|
if let &DataTree::Internal{ref children, ..} = self {
|
||||||
|
DataTreeFilterInternalIter {
|
||||||
|
type_name: type_name,
|
||||||
|
iter: children.iter(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DataTreeFilterInternalIter {
|
||||||
|
type_name: type_name,
|
||||||
|
iter: [].iter(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter_leaf_children_with_type(&'a self,
|
||||||
|
type_name: &'static str)
|
||||||
|
-> DataTreeFilterLeafIter<'a> {
|
||||||
|
if let &DataTree::Internal{ref children, ..} = self {
|
||||||
|
DataTreeFilterLeafIter {
|
||||||
|
type_name: type_name,
|
||||||
|
iter: children.iter(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DataTreeFilterLeafIter {
|
||||||
|
type_name: type_name,
|
||||||
|
iter: [].iter(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +143,103 @@ impl<'a> DataTree<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// An iterator over the children of a DataTree node that filters out the
|
||||||
|
/// children not matching a specified type name.
|
||||||
|
pub struct DataTreeFilterIter<'a> {
|
||||||
|
type_name: &'a str,
|
||||||
|
iter: slice::Iter<'a, DataTree<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for DataTreeFilterIter<'a> {
|
||||||
|
type Item = &'a DataTree<'a>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<&'a DataTree<'a>> {
|
||||||
|
loop {
|
||||||
|
if let Some(dt) = self.iter.next() {
|
||||||
|
if dt.type_name() == self.type_name {
|
||||||
|
return Some(dt);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// An iterator over the children of a DataTree node that filters out the
|
||||||
|
/// children that aren't internal nodes and that don't match a specified
|
||||||
|
/// type name.
|
||||||
|
pub struct DataTreeFilterInternalIter<'a> {
|
||||||
|
type_name: &'a str,
|
||||||
|
iter: slice::Iter<'a, DataTree<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for DataTreeFilterInternalIter<'a> {
|
||||||
|
type Item = (&'a str, Option<&'a str>, &'a Vec<DataTree<'a>>);
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<(&'a str, Option<&'a str>, &'a Vec<DataTree<'a>>)> {
|
||||||
|
loop {
|
||||||
|
match self.iter.next() {
|
||||||
|
Some(&DataTree::Internal{type_name: type_name, ident: ident, children: ref children}) => {
|
||||||
|
if type_name == self.type_name {
|
||||||
|
return Some((type_name, ident, children));
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(&DataTree::Leaf{..}) => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
None => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// An iterator over the children of a DataTree node that filters out the
|
||||||
|
/// children that aren't internal nodes and that don't match a specified
|
||||||
|
/// type name.
|
||||||
|
pub struct DataTreeFilterLeafIter<'a> {
|
||||||
|
type_name: &'a str,
|
||||||
|
iter: slice::Iter<'a, DataTree<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for DataTreeFilterLeafIter<'a> {
|
||||||
|
type Item = (&'a str, &'a str);
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<(&'a str, &'a str)> {
|
||||||
|
loop {
|
||||||
|
match self.iter.next() {
|
||||||
|
Some(&DataTree::Internal{..}) => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(&DataTree::Leaf{type_name: type_name, contents: contents}) => {
|
||||||
|
if type_name == self.type_name {
|
||||||
|
return Some((type_name, contents));
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
pub enum ParseError {
|
pub enum ParseError {
|
||||||
MissingOpener(usize),
|
MissingOpener(usize),
|
||||||
|
@ -537,4 +643,49 @@ mod tests {
|
||||||
assert_eq!(i, None);
|
assert_eq!(i, None);
|
||||||
assert_eq!(c.len(), 0);
|
assert_eq!(c.len(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn iter_1() {
|
||||||
|
let dt = DataTree::from_str(r#"
|
||||||
|
A {}
|
||||||
|
B {}
|
||||||
|
A []
|
||||||
|
A {}
|
||||||
|
B {}
|
||||||
|
"#)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut i = dt.iter_children_with_type("A");
|
||||||
|
assert_eq!(i.count(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn iter_2() {
|
||||||
|
let dt = DataTree::from_str(r#"
|
||||||
|
A {}
|
||||||
|
B {}
|
||||||
|
A []
|
||||||
|
A {}
|
||||||
|
B {}
|
||||||
|
"#)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut i = dt.iter_internal_children_with_type("A");
|
||||||
|
assert_eq!(i.count(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn iter_3() {
|
||||||
|
let dt = DataTree::from_str(r#"
|
||||||
|
A []
|
||||||
|
B {}
|
||||||
|
A {}
|
||||||
|
A []
|
||||||
|
B {}
|
||||||
|
"#)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut i = dt.iter_leaf_children_with_type("A");
|
||||||
|
assert_eq!(i.count(), 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,45 +25,47 @@ pub enum PsyParseError {
|
||||||
/// a renderer.
|
/// a renderer.
|
||||||
pub fn parse_scene(tree: &DataTree) -> Result<Renderer, PsyParseError> {
|
pub fn parse_scene(tree: &DataTree) -> Result<Renderer, PsyParseError> {
|
||||||
// Verify we have the right number of each section
|
// Verify we have the right number of each section
|
||||||
if tree.count_children_with_type_name("Output") != 1 {
|
if tree.iter_children_with_type("Output").count() != 1 {
|
||||||
let count = tree.count_children_with_type_name("Output");
|
let count = tree.iter_children_with_type("Output").count();
|
||||||
return Err(PsyParseError::SectionWrongCount("Output", count));
|
return Err(PsyParseError::SectionWrongCount("Output", count));
|
||||||
}
|
}
|
||||||
if tree.count_children_with_type_name("RenderSettings") != 1 {
|
if tree.iter_children_with_type("RenderSettings").count() != 1 {
|
||||||
let count = tree.count_children_with_type_name("RenderSettings");
|
let count = tree.iter_children_with_type("RenderSettings").count();
|
||||||
return Err(PsyParseError::SectionWrongCount("RenderSettings", count));
|
return Err(PsyParseError::SectionWrongCount("RenderSettings", count));
|
||||||
}
|
}
|
||||||
if tree.count_children_with_type_name("Camera") != 1 {
|
if tree.iter_children_with_type("Camera").count() != 1 {
|
||||||
let count = tree.count_children_with_type_name("Camera");
|
let count = tree.iter_children_with_type("Camera").count();
|
||||||
return Err(PsyParseError::SectionWrongCount("Camera", count));
|
return Err(PsyParseError::SectionWrongCount("Camera", count));
|
||||||
}
|
}
|
||||||
if tree.count_children_with_type_name("World") != 1 {
|
if tree.iter_children_with_type("World").count() != 1 {
|
||||||
let count = tree.count_children_with_type_name("World");
|
let count = tree.iter_children_with_type("World").count();
|
||||||
return Err(PsyParseError::SectionWrongCount("World", count));
|
return Err(PsyParseError::SectionWrongCount("World", count));
|
||||||
}
|
}
|
||||||
if tree.count_children_with_type_name("Assembly") != 1 {
|
if tree.iter_children_with_type("Assembly").count() != 1 {
|
||||||
let count = tree.count_children_with_type_name("Assembly");
|
let count = tree.iter_children_with_type("Assembly").count();
|
||||||
return Err(PsyParseError::SectionWrongCount("Root Assembly", count));
|
return Err(PsyParseError::SectionWrongCount("Root Assembly", count));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse output info
|
// Parse output info
|
||||||
let output_info = try!(parse_output_info(tree.get_first_child_with_type_name("Output")
|
let output_info = try!(parse_output_info(tree.iter_children_with_type("Output")
|
||||||
|
.nth(0)
|
||||||
.unwrap()));
|
.unwrap()));
|
||||||
|
|
||||||
// Parse render settings
|
// Parse render settings
|
||||||
let render_settings = try!(parse_render_settings(tree.get_first_child_with_type_name("Rende\
|
let render_settings = try!(parse_render_settings(tree.iter_children_with_type("Rende\
|
||||||
rSett\
|
rSett\
|
||||||
ings")
|
ings")
|
||||||
|
.nth(0)
|
||||||
.unwrap()));
|
.unwrap()));
|
||||||
|
|
||||||
// Parse camera
|
// Parse camera
|
||||||
let camera = try!(parse_camera(tree.get_first_child_with_type_name("Camera").unwrap()));
|
let camera = try!(parse_camera(tree.iter_children_with_type("Camera").nth(0).unwrap()));
|
||||||
|
|
||||||
// Parse world
|
// Parse world
|
||||||
let world = try!(parse_world(tree.get_first_child_with_type_name("World").unwrap()));
|
let world = try!(parse_world(tree.iter_children_with_type("World").nth(0).unwrap()));
|
||||||
|
|
||||||
// Parse root scene assembly
|
// Parse root scene assembly
|
||||||
let assembly = try!(parse_assembly(tree.get_first_child_with_type_name("Assembly").unwrap()));
|
let assembly = try!(parse_assembly(tree.iter_children_with_type("Assembly").nth(0).unwrap()));
|
||||||
|
|
||||||
// Put scene together
|
// Put scene together
|
||||||
let scene_name = if let &DataTree::Internal{ident, ..} = tree {
|
let scene_name = if let &DataTree::Internal{ident, ..} = tree {
|
||||||
|
@ -257,16 +259,17 @@ fn parse_world(tree: &DataTree) -> Result<(f32, f32, f32), PsyParseError> {
|
||||||
|
|
||||||
// Parse background shader
|
// Parse background shader
|
||||||
let bgs = {
|
let bgs = {
|
||||||
if tree.count_children_with_type_name("BackgroundShader") != 1 {
|
if tree.iter_children_with_type("BackgroundShader").count() != 1 {
|
||||||
return Err(PsyParseError::UnknownError);
|
return Err(PsyParseError::UnknownError);
|
||||||
}
|
}
|
||||||
tree.get_first_child_with_type_name("BackgroundShader").unwrap()
|
tree.iter_children_with_type("BackgroundShader").nth(0).unwrap()
|
||||||
};
|
};
|
||||||
let bgs_type = {
|
let bgs_type = {
|
||||||
if bgs.count_children_with_type_name("Type") != 1 {
|
if bgs.iter_children_with_type("Type").count() != 1 {
|
||||||
return Err(PsyParseError::UnknownError);
|
return Err(PsyParseError::UnknownError);
|
||||||
}
|
}
|
||||||
if let &DataTree::Leaf{contents, ..} = bgs.get_first_child_with_type_name("Type")
|
if let &DataTree::Leaf{contents, ..} = bgs.iter_children_with_type("Type")
|
||||||
|
.nth(0)
|
||||||
.unwrap() {
|
.unwrap() {
|
||||||
contents.trim()
|
contents.trim()
|
||||||
} else {
|
} else {
|
||||||
|
@ -275,8 +278,8 @@ fn parse_world(tree: &DataTree) -> Result<(f32, f32, f32), PsyParseError> {
|
||||||
};
|
};
|
||||||
match bgs_type {
|
match bgs_type {
|
||||||
"Color" => {
|
"Color" => {
|
||||||
if let Some(&DataTree::Leaf{contents, ..}) =
|
if let Some(&DataTree::Leaf{contents, ..}) = bgs.iter_children_with_type("Color")
|
||||||
bgs.get_first_child_with_type_name("Color") {
|
.nth(0) {
|
||||||
if let IResult::Done(_, color) = closure!(tuple!(ws_f32,
|
if let IResult::Done(_, color) = closure!(tuple!(ws_f32,
|
||||||
ws_f32,
|
ws_f32,
|
||||||
ws_f32))(contents.trim()
|
ws_f32))(contents.trim()
|
||||||
|
@ -303,7 +306,7 @@ fn parse_world(tree: &DataTree) -> Result<(f32, f32, f32), PsyParseError> {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn parse_matrix(contents: &str) -> Result<Matrix4x4, PsyParseError> {
|
pub fn parse_matrix(contents: &str) -> Result<Matrix4x4, PsyParseError> {
|
||||||
if let IResult::Done(_, ns) = closure!(terminated!(tuple!(ws_f32,
|
if let IResult::Done(_, ns) = closure!(terminated!(tuple!(ws_f32,
|
||||||
ws_f32,
|
ws_f32,
|
||||||
ws_f32,
|
ws_f32,
|
||||||
|
|
|
@ -7,7 +7,7 @@ use nom::IResult;
|
||||||
|
|
||||||
use super::DataTree;
|
use super::DataTree;
|
||||||
use super::basics::{ws_u32, ws_f32};
|
use super::basics::{ws_u32, ws_f32};
|
||||||
use super::psy::PsyParseError;
|
use super::psy::{parse_matrix, PsyParseError};
|
||||||
|
|
||||||
use math::Matrix4x4;
|
use math::Matrix4x4;
|
||||||
use camera::Camera;
|
use camera::Camera;
|
||||||
|
@ -17,8 +17,8 @@ use assembly::{Assembly, AssemblyBuilder};
|
||||||
pub fn parse_assembly(tree: &DataTree) -> Result<Assembly, PsyParseError> {
|
pub fn parse_assembly(tree: &DataTree) -> Result<Assembly, PsyParseError> {
|
||||||
let mut builder = AssemblyBuilder::new();
|
let mut builder = AssemblyBuilder::new();
|
||||||
|
|
||||||
if let &DataTree::Internal{ref children, ..} = tree {
|
if tree.is_internal() {
|
||||||
for child in children {
|
for child in tree.iter_children() {
|
||||||
match child.type_name() {
|
match child.type_name() {
|
||||||
// Sub-Assembly
|
// Sub-Assembly
|
||||||
"Assembly" => {
|
"Assembly" => {
|
||||||
|
@ -26,9 +26,48 @@ pub fn parse_assembly(tree: &DataTree) -> Result<Assembly, PsyParseError> {
|
||||||
builder.add_assembly(ident, try!(parse_assembly(&child)));
|
builder.add_assembly(ident, try!(parse_assembly(&child)));
|
||||||
} else {
|
} else {
|
||||||
// TODO: error condition of some kind, because no ident
|
// TODO: error condition of some kind, because no ident
|
||||||
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Instance
|
||||||
|
"Instance" => {
|
||||||
|
// Pre-conditions
|
||||||
|
if !child.is_internal() {
|
||||||
|
// TODO: proper error
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get data name
|
||||||
|
let name = {
|
||||||
|
if child.iter_leaf_children_with_type("Data").count() != 1 {
|
||||||
|
// TODO: proper error message
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
child.iter_leaf_children_with_type("Data").nth(0).unwrap().1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get xforms
|
||||||
|
let mut xforms = Vec::new();
|
||||||
|
for (_, contents) in child.iter_leaf_children_with_type("Transform") {
|
||||||
|
xforms.push(try!(parse_matrix(contents)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add instance
|
||||||
|
if builder.name_exists(name) {
|
||||||
|
builder.add_instance(name, Some(&xforms));
|
||||||
|
} else {
|
||||||
|
// TODO: proper error message
|
||||||
|
panic!("Attempted to add instance for data with a name that doesn't \
|
||||||
|
exist.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MeshSurface
|
||||||
|
"MeshSurface" => {
|
||||||
|
// TODO: call mesh surface parsing function once it's written
|
||||||
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
// TODO: some kind of error, because not a known type name
|
// TODO: some kind of error, because not a known type name
|
||||||
}
|
}
|
||||||
|
@ -68,34 +107,6 @@ pub fn parse_assembly(tree: &DataTree) -> Result<Assembly, PsyParseError> {
|
||||||
// assembly->add_object(child.name, parse_rectangle_light(child));
|
// assembly->add_object(child.name, parse_rectangle_light(child));
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// // Instance
|
|
||||||
// else if (child.type == "Instance") {
|
|
||||||
// // Parse
|
|
||||||
// std::string name = "";
|
|
||||||
// std::vector<Transform> xforms;
|
|
||||||
// const SurfaceShader *shader = nullptr;
|
|
||||||
// for (const auto& child2: child.children) {
|
|
||||||
// if (child2.type == "Transform") {
|
|
||||||
// xforms.emplace_back(parse_matrix(child2.leaf_contents));
|
|
||||||
// } else if (child2.type == "Data") {
|
|
||||||
// name = child2.leaf_contents;
|
|
||||||
// } else if (child2.type == "SurfaceShaderBind") {
|
|
||||||
// shader = assembly->get_surface_shader(child2.leaf_contents);
|
|
||||||
// if (shader == nullptr) {
|
|
||||||
// std::cout << "ERROR: attempted to bind surface shader that doesn't exist." << std::endl;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Add instance
|
|
||||||
// if (assembly->object_map.count(name) != 0) {
|
|
||||||
// assembly->create_object_instance(name, xforms, shader);
|
|
||||||
// } else if (assembly->assembly_map.count(name) != 0) {
|
|
||||||
// assembly->create_assembly_instance(name, xforms, shader);
|
|
||||||
// } else {
|
|
||||||
// std::cout << "ERROR: attempted to add instace for data that doesn't exist." << std::endl;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user