| 363 | use super::{AttribDefinition, AttributeStorage, BgeoAttributeType, BgeoFile, BgeoHeader}; |
| 364 | |
| 365 | pub fn bgeo_parser<'a>() |
| 366 | -> impl Parser<&'a [u8], Output = BgeoFile, Error = BgeoParserError<&'a [u8]>> { |
| 367 | move |input: &'a [u8]| -> IResult<&'a [u8], BgeoFile, BgeoParserError<&'a [u8]>> { |
| 368 | // Parse file header and attribute definitions |
| 369 | let (input, header) = parse_header(input)?; |
| 370 | let (input, named_attribute_definitions) = |
| 371 | count(parse_attr_def, header.num_point_attrib as usize).parse(input)?; |
| 372 | |
| 373 | // Add the "position" attribute which should always be present |
| 374 | let special_attribute_definitions = { |
| 375 | let mut special_attribute_definitions = Vec::new(); |
| 376 | special_attribute_definitions.push(AttribDefinition { |
| 377 | name: String::from("position"), |
| 378 | size: 3, |
| 379 | attr_type: BgeoAttributeType::Vector, |
| 380 | default_values: vec![0, 0, 0], |
| 381 | }); |
| 382 | // TODO: This additional float value appears between positions and ids in splishsplash BGEO files |
| 383 | // Not sure what this is exactly |
| 384 | special_attribute_definitions.push(AttribDefinition { |
| 385 | name: String::from("unknown"), |
| 386 | size: 1, |
| 387 | attr_type: BgeoAttributeType::Float, |
| 388 | default_values: vec![0], |
| 389 | }); |
| 390 | special_attribute_definitions |
| 391 | }; |
| 392 | |
| 393 | // Parse the point attribute data |
| 394 | let (input, (mut special_attribute_data, attribute_data)) = parse_points( |
| 395 | input, |
| 396 | header.num_points as usize, |
| 397 | special_attribute_definitions.as_slice(), |
| 398 | named_attribute_definitions.as_slice(), |
| 399 | )?; |
| 400 | |
| 401 | assert_eq!(special_attribute_data.len(), 2); |
| 402 | |
| 403 | let weights = special_attribute_data.pop().unwrap(); |
| 404 | let positions = special_attribute_data.pop().unwrap(); |
| 405 | |
| 406 | let file = BgeoFile { |
| 407 | header, |
| 408 | positions, |
| 409 | weights, |
| 410 | attribute_definitions: named_attribute_definitions, |
| 411 | attribute_data, |
| 412 | }; |
| 413 | |
| 414 | Ok((input, file)) |
| 415 | } |
| 416 | } |
| 417 | |
| 418 | /// Parses the BGEO format magic bytes |
| 419 | fn parse_magic_bytes(input: &[u8]) -> IResult<&[u8], &[u8], BgeoParserError<&[u8]>> { |