From 600072065851962b9ead2c7a9e40b9032fbeebec Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sun, 17 Dec 2023 18:58:48 -0500 Subject: [PATCH] Fix tangent reading/writing --- src/model.rs | 39 ++++++++++++++++---------------- src/model_file_operations.rs | 32 ++++++++++++++++++++++++++ src/model_vertex_declarations.rs | 4 ++-- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/src/model.rs b/src/model.rs index 3fbd707..5f76fd3 100755 --- a/src/model.rs +++ b/src/model.rs @@ -272,8 +272,8 @@ pub struct Vertex { pub uv0: [f32; 2], pub uv1: [f32; 2], pub normal: [f32; 3], - pub tangent1: [u8; 4], - pub tangent2: [u8; 4], + pub bitangent: [f32; 4], + //pub bitangent1: [f32; 4], // TODO: need to figure out what the heck this could be pub color: [f32; 4], pub bone_weight: [f32; 4], @@ -365,8 +365,7 @@ impl MDL { uv0: [0.0; 2], uv1: [0.0; 2], normal: [0.0; 3], - tangent1: [0u8; 4], - tangent2: [0u8; 4], + bitangent: [0.0; 4], color: [0.0; 4], bone_weight: [0.0; 4], bone_id: [0u8; 4], @@ -455,23 +454,23 @@ impl MDL { } } } - VertexUsage::Tangent2 => { + VertexUsage::BiTangent => { match element.vertex_type { VertexType::ByteFloat4 => { - vertices[k as usize].tangent2 = MDL::read_uint(&mut cursor).unwrap(); + vertices[k as usize].bitangent = MDL::read_tangent(&mut cursor).unwrap(); } _ => { - panic!("Unexpected vertex type for tangent2: {:#?}", element.vertex_type); + panic!("Unexpected vertex type for bitangent: {:#?}", element.vertex_type); } } } - VertexUsage::Tangent1 => { + VertexUsage::Tangent => { match element.vertex_type { - VertexType::ByteFloat4 => { - vertices[k as usize].tangent1 = MDL::read_uint(&mut cursor).unwrap(); - } + /*VertexType::ByteFloat4 => { + vertices[k as usize].bitangent0 = MDL::read_tangent(&mut cursor).unwrap(); + }*/ _ => { - panic!("Unexpected vertex type for tangent1: {:#?}", element.vertex_type); + panic!("Unexpected vertex type for tangent: {:#?}", element.vertex_type); } } } @@ -752,23 +751,23 @@ impl MDL { } } } - VertexUsage::Tangent2 => { + VertexUsage::BiTangent => { match element.vertex_type { VertexType::ByteFloat4 => { - MDL::write_uint(&mut cursor, &vert.tangent2).ok()?; + MDL::write_tangent(&mut cursor, &vert.bitangent).ok()?; } _ => { - panic!("Unexpected vertex type for tangent2: {:#?}", element.vertex_type); + panic!("Unexpected vertex type for bitangent: {:#?}", element.vertex_type); } } } - VertexUsage::Tangent1 => { + VertexUsage::Tangent => { match element.vertex_type { - VertexType::ByteFloat4 => { - MDL::write_uint(&mut cursor, &vert.tangent1).ok()?; - } + /*VertexType::ByteFloat4 => { + MDL::write_tangent(&mut cursor, &vert.binormal).ok()?; + }*/ _ => { - panic!("Unexpected vertex type for tangent1: {:#?}", element.vertex_type); + panic!("Unexpected vertex type for tangent: {:#?}", element.vertex_type); } } } diff --git a/src/model_file_operations.rs b/src/model_file_operations.rs index 213ccaa..182c595 100644 --- a/src/model_file_operations.rs +++ b/src/model_file_operations.rs @@ -28,6 +28,23 @@ impl MDL { (vec[3] * MAX_BYTE_FLOAT).round() as u8]) } + pub(crate) fn read_tangent(cursor: &mut Cursor) -> Option<[f32; 4]> { + Some([ + (f32::from(cursor.read_le::().ok()?) * 2.0 / MAX_BYTE_FLOAT - 1.0), + (f32::from(cursor.read_le::().ok()?) * 2.0 / MAX_BYTE_FLOAT - 1.0), + (f32::from(cursor.read_le::().ok()?) * 2.0 / MAX_BYTE_FLOAT - 1.0), + if (f32::from(cursor.read_le::().ok()?) * 2.0 / MAX_BYTE_FLOAT - 1.0) == 1.0 { 1.0 } else { -1.0 } + ]) + } + + pub(crate) fn write_tangent(cursor: &mut T, vec: &[f32; 4]) -> BinResult<()> { + cursor.write_le::<[u8; 4]>(&[ + ((vec[0] + 1.0) * (MAX_BYTE_FLOAT / 2.0)).round() as u8, + ((vec[1] + 1.0) * (MAX_BYTE_FLOAT / 2.0)).round() as u8, + ((vec[2] + 1.0) * (MAX_BYTE_FLOAT / 2.0)).round() as u8, + if vec[3] > 0.0 { 255 } else { 0 }]) // SqEx uses 0 as -1, not 1 + } + pub(crate) fn read_half4(cursor: &mut Cursor) -> Option<[f32; 4]> { Some([ f16::from_bits(cursor.read_le::().ok()?).to_f32(), @@ -156,6 +173,21 @@ mod tests { assert_eq!(MDL::read_single4(&mut read_cursor).unwrap(), a); } + #[test] + fn tangent() { + let a = [1.0, 0.5, -0.5, 1.0]; + + let mut v = vec![]; + let mut cursor = Cursor::new(&mut v); + + MDL::write_tangent(&mut cursor, &a).unwrap(); + + let mut read_cursor = Cursor::new(v.as_slice()); + let tangent = MDL::read_tangent(&mut read_cursor).unwrap(); + assert_delta!(tangent, a, 0.001); + } + + #[test] fn pad_slice() { let a = [3.0, 0.0, -1.0]; diff --git a/src/model_vertex_declarations.rs b/src/model_vertex_declarations.rs index 2730b24..8a0935b 100644 --- a/src/model_vertex_declarations.rs +++ b/src/model_vertex_declarations.rs @@ -29,8 +29,8 @@ pub enum VertexUsage { BlendIndices = 2, Normal = 3, UV = 4, - Tangent2 = 5, - Tangent1 = 6, + Tangent = 5, + BiTangent = 6, Color = 7, }