aboutsummaryrefslogtreecommitdiff
path: root/crates/render-core/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/render-core/src')
-rw-r--r--crates/render-core/src/lib.rs39
-rw-r--r--crates/render-core/src/tests.rs32
2 files changed, 68 insertions, 3 deletions
diff --git a/crates/render-core/src/lib.rs b/crates/render-core/src/lib.rs
index 8e0b5e8..ddb93fb 100644
--- a/crates/render-core/src/lib.rs
+++ b/crates/render-core/src/lib.rs
@@ -1,8 +1,14 @@
use msh_core::Model;
#[derive(Clone, Debug)]
+pub struct RenderVertex {
+ pub position: [f32; 3],
+ pub uv0: [f32; 2],
+}
+
+#[derive(Clone, Debug)]
pub struct RenderMesh {
- pub vertices: Vec<[f32; 3]>,
+ pub vertices: Vec<RenderVertex>,
pub batch_count: usize,
}
@@ -18,6 +24,7 @@ impl RenderMesh {
pub fn build_render_mesh(model: &Model, lod: usize, group: usize) -> RenderMesh {
let mut vertices = Vec::new();
let mut batch_count = 0usize;
+ let uv0 = model.uv0.as_ref();
for node_index in 0..model.node_count {
let Some(slot_idx) = model.slot_index(node_index, lod, group) else {
@@ -48,7 +55,15 @@ pub fn build_render_mesh(model: &Model, lod: usize, group: usize) -> RenderMesh
let Some(pos) = model.positions.get(final_idx) else {
continue;
};
- vertices.push(*pos);
+ let uv = uv0
+ .and_then(|uvs| uvs.get(final_idx))
+ .copied()
+ .map(|packed| [packed[0] as f32 / 1024.0, packed[1] as f32 / 1024.0])
+ .unwrap_or([0.0, 0.0]);
+ vertices.push(RenderVertex {
+ position: *pos,
+ uv0: uv,
+ });
}
batch_count += 1;
}
@@ -80,5 +95,25 @@ pub fn compute_bounds(vertices: &[[f32; 3]]) -> Option<([f32; 3], [f32; 3])> {
Some((min_v, max_v))
}
+pub fn compute_bounds_for_mesh(vertices: &[RenderVertex]) -> Option<([f32; 3], [f32; 3])> {
+ let mut iter = vertices.iter();
+ let first = iter.next()?;
+ let mut min_v = first.position;
+ let mut max_v = first.position;
+
+ for v in iter {
+ for i in 0..3 {
+ if v.position[i] < min_v[i] {
+ min_v[i] = v.position[i];
+ }
+ if v.position[i] > max_v[i] {
+ max_v[i] = v.position[i];
+ }
+ }
+ }
+
+ Some((min_v, max_v))
+}
+
#[cfg(test)]
mod tests;
diff --git a/crates/render-core/src/tests.rs b/crates/render-core/src/tests.rs
index 9c5eb5d..22103c6 100644
--- a/crates/render-core/src/tests.rs
+++ b/crates/render-core/src/tests.rs
@@ -74,9 +74,17 @@ fn build_render_mesh_for_real_models() {
if !mesh.vertices.is_empty() {
meshes_non_empty += 1;
}
- if compute_bounds(&mesh.vertices).is_some() {
+ if compute_bounds_for_mesh(&mesh.vertices).is_some() {
bounds_non_empty += 1;
}
+ for vertex in &mesh.vertices {
+ assert!(
+ vertex.uv0[0].is_finite() && vertex.uv0[1].is_finite(),
+ "UV must be finite for '{}' in {}",
+ entry.meta.name,
+ archive_path.display()
+ );
+ }
}
}
@@ -99,3 +107,25 @@ fn compute_bounds_handles_empty_and_non_empty() {
assert_eq!(bounds.0, [-2.0, -1.0, 0.5]);
assert_eq!(bounds.1, [1.0, 5.0, 9.0]);
}
+
+#[test]
+fn compute_bounds_for_mesh_handles_empty_and_non_empty() {
+ assert!(compute_bounds_for_mesh(&[]).is_none());
+ let bounds = compute_bounds_for_mesh(&[
+ RenderVertex {
+ position: [1.0, 2.0, 3.0],
+ uv0: [0.0, 0.0],
+ },
+ RenderVertex {
+ position: [-2.0, 5.0, 0.5],
+ uv0: [0.2, 0.3],
+ },
+ RenderVertex {
+ position: [0.0, -1.0, 9.0],
+ uv0: [1.0, 1.0],
+ },
+ ])
+ .expect("bounds expected");
+ assert_eq!(bounds.0, [-2.0, -1.0, 0.5]);
+ assert_eq!(bounds.1, [1.0, 5.0, 9.0]);
+}