summaryrefslogtreecommitdiff
path: root/engine/src/file_format/wavefront
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/file_format/wavefront')
-rw-r--r--engine/src/file_format/wavefront/obj.rs174
1 files changed, 86 insertions, 88 deletions
diff --git a/engine/src/file_format/wavefront/obj.rs b/engine/src/file_format/wavefront/obj.rs
index d60b41d..884229c 100644
--- a/engine/src/file_format/wavefront/obj.rs
+++ b/engine/src/file_format/wavefront/obj.rs
@@ -14,14 +14,6 @@ use crate::util::try_option;
use crate::vector::{Vec2, Vec3};
use crate::vertex::{Builder as VertexBuilder, Vertex};
-/// The output from parsing the content of a Wavefront `.obj` using [`parse`].
-#[derive(Debug)]
-#[non_exhaustive]
-pub struct Obj
-{
- pub mesh: Mesh,
-}
-
/// Parses the content of a Wavefront `.obj`.
///
/// # Errors
@@ -107,26 +99,40 @@ pub fn parse(obj_content: &str) -> Result<Obj, Error>
})
.collect::<Result<Vec<[FaceVertex; 3]>, _>>()?;
- let vertices = faces
- .iter()
- .flatten()
- .map(|face_vertex| {
- face_vertex_to_vertex(
- face_vertex,
- Data {
- vertex_positions: &vertex_positions,
- texture_positions: &texture_positions,
- vertex_normals: &vertex_normals,
- },
- )
- })
- .collect::<Result<Vec<_>, Error>>()?;
-
Ok(Obj {
- mesh: Mesh::new(
+ vertex_positions,
+ vertex_normals,
+ texture_positions,
+ faces,
+ })
+}
+
+/// The output from parsing the content of a Wavefront `.obj` using [`parse`].
+#[derive(Debug)]
+#[non_exhaustive]
+pub struct Obj
+{
+ pub vertex_positions: Vec<Vec3<f32>>,
+ pub vertex_normals: Vec<Vec3<f32>>,
+ pub texture_positions: Vec<Vec2<f32>>,
+ pub faces: Vec<[FaceVertex; 3]>,
+}
+
+impl Obj
+{
+ pub fn to_mesh(&self) -> Result<Mesh, Error>
+ {
+ let vertices = self
+ .faces
+ .iter()
+ .flatten()
+ .map(|face_vertex| face_vertex.to_vertex(self))
+ .collect::<Result<Vec<_>, Error>>()?;
+
+ Ok(Mesh::new(
vertices,
Some(
- faces
+ self.faces
.iter()
.flatten()
.enumerate()
@@ -135,55 +141,67 @@ pub fn parse(obj_content: &str) -> Result<Obj, Error>
})
.collect::<Result<Vec<_>, _>>()?,
),
- ),
- })
+ ))
+ }
}
-struct Data<'a>
+#[derive(Debug)]
+pub struct FaceVertex
{
- vertex_positions: &'a [Vec3<f32>],
- texture_positions: &'a [Vec2<f32>],
- vertex_normals: &'a [Vec3<f32>],
+ pub position: u32,
+ pub texture: Option<u32>,
+ pub normal: Option<u32>,
}
-fn face_vertex_to_vertex(face_vertex: &FaceVertex, data: Data) -> Result<Vertex, Error>
+impl FaceVertex
{
- let vertex_pos = *data
- .vertex_positions
- .get(face_vertex.position as usize - 1)
- .ok_or(Error::FaceVertexPositionNotFound {
- vertex_pos_index: face_vertex.position,
- })?;
-
- let face_vertex_texture = face_vertex
- .texture
- .ok_or(Error::NoFaceVertexTextureNotSupported)?;
-
- let texture_pos = *data
- .texture_positions
- .get(face_vertex_texture as usize - 1)
- .ok_or(Error::FaceTexturePositionNotFound {
- texture_pos_index: face_vertex_texture,
- })?;
-
- let face_vertex_normal = face_vertex
- .normal
- .ok_or(Error::NoFaceVertexNormalNotSupported)?;
-
- let vertex_normal = *data
- .vertex_normals
- .get(face_vertex_normal as usize - 1)
- .ok_or(Error::FaceVertexNormalNotFound {
- vertex_normal_index: face_vertex_normal,
- })?;
-
- Ok(VertexBuilder::new()
- .pos(vertex_pos)
- .color(Color::WHITE_F32)
- .texture_coords(texture_pos)
- .normal(vertex_normal)
- .build()
- .unwrap())
+ /// Tries to convert this face vertex into a [`Vertex`].
+ pub fn to_vertex(&self, obj: &Obj) -> Result<Vertex, Error>
+ {
+ let vertex_pos = *obj.vertex_positions.get(self.position as usize - 1).ok_or(
+ Error::FaceVertexPositionNotFound { vertex_pos_index: self.position },
+ )?;
+
+ let face_vertex_texture =
+ self.texture.ok_or(Error::NoFaceVertexTextureNotSupported)?;
+
+ let texture_pos = *obj
+ .texture_positions
+ .get(face_vertex_texture as usize - 1)
+ .ok_or(Error::FaceTexturePositionNotFound {
+ texture_pos_index: face_vertex_texture,
+ })?;
+
+ let face_vertex_normal =
+ self.normal.ok_or(Error::NoFaceVertexNormalNotSupported)?;
+
+ let vertex_normal = *obj
+ .vertex_normals
+ .get(face_vertex_normal as usize - 1)
+ .ok_or(Error::FaceVertexNormalNotFound {
+ vertex_normal_index: face_vertex_normal,
+ })?;
+
+ Ok(VertexBuilder::new()
+ .pos(vertex_pos)
+ .color(Color::WHITE_F32)
+ .texture_coords(texture_pos)
+ .normal(vertex_normal)
+ .build()
+ .unwrap())
+ }
+}
+
+impl From<Triplet> for FaceVertex
+{
+ fn from(triplet: Triplet) -> Self
+ {
+ Self {
+ position: triplet.0,
+ texture: triplet.1,
+ normal: triplet.2,
+ }
+ }
}
#[derive(Debug, thiserror::Error)]
@@ -248,23 +266,3 @@ keyword! {
F,
}
}
-
-#[derive(Debug)]
-struct FaceVertex
-{
- position: u32,
- texture: Option<u32>,
- normal: Option<u32>,
-}
-
-impl From<Triplet> for FaceVertex
-{
- fn from(triplet: Triplet) -> Self
- {
- Self {
- position: triplet.0,
- texture: triplet.1,
- normal: triplet.2,
- }
- }
-}