importer/fbx: more WIP. fix inexact reading

This commit is contained in:
2023-11-06 04:06:06 +02:00
parent aa394d2283
commit 8f19a5fee2
+128 -37
View File
@@ -12,10 +12,10 @@ struct FbxProperty {
} }
#[derive(Debug)] #[derive(Debug)]
struct FbxRecordNode { struct FbxNode {
name: String, name: String,
properties: Vec<FbxProperty>, properties: Vec<FbxProperty>,
children: Vec<FbxRecordNode>, children: Vec<FbxNode>,
} }
struct FbxRecordIterator<R: Read + Seek> { struct FbxRecordIterator<R: Read + Seek> {
@@ -31,7 +31,7 @@ impl<R: Read + Seek> FbxRecordIterator<R> {
} }
impl<R: Read + Seek> Iterator for FbxRecordIterator<R> { impl<R: Read + Seek> Iterator for FbxRecordIterator<R> {
type Item = FbxRecordNode; type Item = FbxNode;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let mut children = Vec::new(); let mut children = Vec::new();
@@ -41,22 +41,23 @@ impl<R: Read + Seek> Iterator for FbxRecordIterator<R> {
let mut num_properties = [0; 4]; let mut num_properties = [0; 4];
let mut property_list_len = [0; 4]; let mut property_list_len = [0; 4];
let mut name_len = [0; 1]; let mut name_len = [0; 1];
self.reader.read(&mut end_offset).unwrap(); self.reader.read_exact(&mut end_offset).unwrap();
self.reader.read(&mut num_properties).unwrap(); self.reader.read_exact(&mut num_properties).unwrap();
self.reader.read(&mut property_list_len).unwrap(); self.reader.read_exact(&mut property_list_len).unwrap();
self.reader.read(&mut name_len).unwrap(); self.reader.read_exact(&mut name_len).unwrap();
let end_offset = u32::from_le_bytes(end_offset); let end_offset = u32::from_le_bytes(end_offset);
let num_properties = u32::from_le_bytes(num_properties); let num_properties = u32::from_le_bytes(num_properties);
let property_list_len = u32::from_le_bytes(property_list_len); let property_list_len = u32::from_le_bytes(property_list_len);
let name_len = u8::from_le_bytes(name_len); let name_len = u8::from_le_bytes(name_len);
let name = String::from_utf8(self.reader.by_ref().take(name_len as _).bytes().map(|b| b.unwrap()).collect()).unwrap();
if name_len == 0 { if name_len == 0 {
return None; return None;
} }
println!("Name: {}", name); let name = String::from_utf8(self.reader.by_ref().take(name_len as _).bytes().map(|b| b.unwrap()).collect()).unwrap();
// println!("Name: {}", name);
// self.reader.seek_relative(property_list_len as _).unwrap(); // skip the properties // self.reader.seek_relative(property_list_len as _).unwrap(); // skip the properties
let properties = parse_properties(self.reader.by_ref(), num_properties, property_list_len); let properties = parse_properties(self.reader.by_ref(), num_properties, property_list_len);
@@ -69,7 +70,7 @@ impl<R: Read + Seek> Iterator for FbxRecordIterator<R> {
} }
} }
Some(FbxRecordNode{ Some(FbxNode{
name, name,
properties, properties,
children children
@@ -117,7 +118,7 @@ impl TypeCode {
b'S' => TypeCode::String, b'S' => TypeCode::String,
b'R' => TypeCode::Raw, b'R' => TypeCode::Raw,
_ => { panic!("Invalid property TypeCode") } _ => { panic!("Invalid property TypeCode: {}", std::str::from_utf8(&[byte]).unwrap()) }
} }
} }
} }
@@ -140,78 +141,168 @@ fn parse_properties<R: Read + Seek>(reader: &mut BufReader<R>, num_properties: u
let value = match TypeCode::from_byte(type_code) { let value = match TypeCode::from_byte(type_code) {
TypeCode::Short => { TypeCode::Short => {
let mut value = [0; 2]; let mut value = [0; 2];
reader.read(&mut value).unwrap(); reader.read_exact(&mut value).unwrap();
let value = i16::from_le_bytes(value); let value = i16::from_le_bytes(value);
println!("Short: {}", value); // println!("Short: {}", value);
}, },
TypeCode::Bool => { TypeCode::Bool => {
let mut value = [0; 1]; let mut value = [0; 1];
reader.read(&mut value).unwrap(); reader.read_exact(&mut value).unwrap();
let value = (u8::from_le_bytes(value) & 1) != 0; let value = (u8::from_le_bytes(value) & 1) != 0;
println!("Bool: {}", value); // println!("Bool: {}", value);
}, },
TypeCode::Int => { TypeCode::Int => {
let mut value = [0; 4]; let mut value = [0; 4];
reader.read(&mut value).unwrap(); reader.read_exact(&mut value).unwrap();
let value = i32::from_le_bytes(value); let value = i32::from_le_bytes(value);
println!("Int: {}", value); // println!("Int: {}", value);
}, },
TypeCode::Float => { TypeCode::Float => {
let mut value = [0; 4]; let mut value = [0; 4];
reader.read(&mut value).unwrap(); reader.read_exact(&mut value).unwrap();
let value = f32::from_le_bytes(value); let value = f32::from_le_bytes(value);
println!("Float: {}", value); // println!("Float: {}", value);
}, },
TypeCode::Double => { TypeCode::Double => {
let mut value = [0; 8]; let mut value = [0; 8];
reader.read(&mut value).unwrap(); reader.read_exact(&mut value).unwrap();
let value = f64::from_le_bytes(value); let value = f64::from_le_bytes(value);
println!("Double: {}", value); // println!("Double: {}", value);
}, },
TypeCode::Long => { TypeCode::Long => {
let mut value = [0; 8]; let mut value = [0; 8];
reader.read(&mut value).unwrap(); reader.read_exact(&mut value).unwrap();
let value = i64::from_le_bytes(value); let value = i64::from_le_bytes(value);
println!("Long: {}", value); // println!("Long: {}", value);
}, },
// TODO: these are more complicated and could be compressed // TODO: these are more complicated and could be compressed
TypeCode::FloatArray => { TypeCode::FloatArray => {
println!("FloatArray"); let mut len = [0; 4];
let mut encoding = [0; 4];
let mut compressed_len = [0; 4];
reader.read_exact(&mut len).unwrap();
reader.read_exact(&mut encoding).unwrap();
reader.read_exact(&mut compressed_len).unwrap();
let len = i32::from_le_bytes(len);
let encoding = i32::from_le_bytes(encoding);
let compressed_len = i32::from_le_bytes(compressed_len);
if encoding == 0 {
let mut value = vec![0; len as usize * std::mem::size_of::<f32>()];
reader.read_exact(&mut value).unwrap();
// println!("FloatArray: {:?}", value);
} else {
let mut value = vec![0; compressed_len as _];
reader.read_exact(&mut value).unwrap();
// println!("Compressed FloatArray: {:?}", value);
}
}, },
TypeCode::DoubleArray => { TypeCode::DoubleArray => {
println!("DoubleArray"); let mut len = [0; 4];
let mut encoding = [0; 4];
let mut compressed_len = [0; 4];
reader.read_exact(&mut len).unwrap();
reader.read_exact(&mut encoding).unwrap();
reader.read_exact(&mut compressed_len).unwrap();
let len = i32::from_le_bytes(len);
let encoding = i32::from_le_bytes(encoding);
let compressed_len = i32::from_le_bytes(compressed_len);
if encoding == 0 {
let mut value = vec![0; len as usize * std::mem::size_of::<f64>()];
reader.read_exact(&mut value).unwrap();
// println!("DoubleArray: {:?}", value);
} else {
let mut value = vec![0; compressed_len as _];
reader.read_exact(&mut value).unwrap();
// println!("Compressed DoubleArray: {:?}", value);
}
}, },
TypeCode::LongArray => { TypeCode::LongArray => {
println!("LongArray"); let mut len = [0; 4];
let mut encoding = [0; 4];
let mut compressed_len = [0; 4];
reader.read_exact(&mut len).unwrap();
reader.read_exact(&mut encoding).unwrap();
reader.read_exact(&mut compressed_len).unwrap();
let len = i32::from_le_bytes(len);
let encoding = i32::from_le_bytes(encoding);
let compressed_len = i32::from_le_bytes(compressed_len);
if encoding == 0 {
let mut value = vec![0; len as usize * std::mem::size_of::<i64>()];
reader.read_exact(&mut value).unwrap();
// println!("LongArray: {:?}", value);
} else {
let mut value = vec![0; compressed_len as _];
reader.read_exact(&mut value).unwrap();
// println!("Compressed LongArray: {:?}", value);
}
}, },
TypeCode::IntArray => { TypeCode::IntArray => {
println!("IntArray"); let mut len = [0; 4];
let mut encoding = [0; 4];
let mut compressed_len = [0; 4];
reader.read_exact(&mut len).unwrap();
reader.read_exact(&mut encoding).unwrap();
reader.read_exact(&mut compressed_len).unwrap();
let len = i32::from_le_bytes(len);
let encoding = i32::from_le_bytes(encoding);
let compressed_len = i32::from_le_bytes(compressed_len);
if encoding == 0 {
let mut value = vec![0; len as usize * std::mem::size_of::<i32>()];
reader.read_exact(&mut value).unwrap();
// println!("IntArray: {:?}", value);
} else {
let mut value = vec![0; compressed_len as _];
reader.read_exact(&mut value).unwrap();
// println!("Compressed IntArray: {:?}", value);
}
}, },
TypeCode::BoolArray => { TypeCode::BoolArray => {
println!("BoolArray"); let mut len = [0; 4];
let mut encoding = [0; 4];
let mut compressed_len = [0; 4];
reader.read_exact(&mut len).unwrap();
reader.read_exact(&mut encoding).unwrap();
reader.read_exact(&mut compressed_len).unwrap();
let len = i32::from_le_bytes(len);
let encoding = i32::from_le_bytes(encoding);
let compressed_len = i32::from_le_bytes(compressed_len);
if encoding == 0 {
let mut value = vec![0; len as usize * std::mem::size_of::<u8>()];
reader.read_exact(&mut value).unwrap();
// println!("BoolArray: {:?}", value);
} else {
let mut value = vec![0; compressed_len as _];
reader.read_exact(&mut value).unwrap();
// println!("Compressed BoolArray: {:?}", value);
}
}, },
TypeCode::String => { TypeCode::String => {
let mut len = [0; 4]; let mut len = [0; 4];
reader.read(&mut len).unwrap(); reader.read_exact(&mut len).unwrap();
let len = i32::from_le_bytes(len); let len = i32::from_le_bytes(len);
let mut value = vec![0; len as _]; let mut value = vec![0; len as _];
reader.read(&mut value).unwrap(); reader.read_exact(&mut value).unwrap();
let value = String::from_utf8(value).unwrap(); let value = String::from_utf8(value).unwrap();
println!("String: {}", value); // println!("String: {}", value);
}, },
TypeCode::Raw => { TypeCode::Raw => {
let mut len = [0; 4]; let mut len = [0; 4];
reader.read(&mut len).unwrap(); reader.read_exact(&mut len).unwrap();
let len = i32::from_le_bytes(len); let len = i32::from_le_bytes(len);
let mut value = vec![0; len as _]; let mut value = vec![0; len as _];
reader.read(&mut value).unwrap(); reader.read_exact(&mut value).unwrap();
println!("Raw: {:?}", value); // println!("Raw: {:?}", value);
}, },
}; };
@@ -234,6 +325,7 @@ fn parse_binary_fbx(mut file: std::fs::File) -> Result<Object, Box<dyn std::erro
file.seek(std::io::SeekFrom::Current(6))?; // skip the rest of the header file.seek(std::io::SeekFrom::Current(6))?; // skip the rest of the header
let now = std::time::Instant::now();
let fbx_nodes = FbxRecordIterator::new(BufReader::new(file)); let fbx_nodes = FbxRecordIterator::new(BufReader::new(file));
// skip the first record node because it's the header extension node // skip the first record node because it's the header extension node
@@ -241,6 +333,8 @@ fn parse_binary_fbx(mut file: std::fs::File) -> Result<Object, Box<dyn std::erro
for node in fbx_nodes { for node in fbx_nodes {
// println!("node: {:?}", node); // println!("node: {:?}", node);
} }
let elapsed = now.elapsed();
info!("Loaded in {} ms", elapsed.as_millis());
todo!(); todo!();
// Ok(Object { // Ok(Object {
@@ -258,15 +352,12 @@ pub fn load_fbx(mut file: std::fs::File) -> Result<Object, Box<dyn std::error::E
let mut magic: [u8; 21] = [0; 21]; let mut magic: [u8; 21] = [0; 21];
let _ = file.read_exact(&mut magic); let _ = file.read_exact(&mut magic);
let now = std::time::Instant::now();
let obj = if is_binary(&magic) { let obj = if is_binary(&magic) {
parse_binary_fbx(file)? parse_binary_fbx(file)?
} else { } else {
file.seek(std::io::SeekFrom::Start(0))?; file.seek(std::io::SeekFrom::Start(0))?;
parse_ascii_fbx()? parse_ascii_fbx()?
}; };
let elapsed = now.elapsed();
info!("Loaded in {} ms", elapsed.as_millis());
Ok(obj) Ok(obj)
} }