114 lines
3.9 KiB
Rust
114 lines
3.9 KiB
Rust
use crate::core::shape::{CreateShape, ALL_TRIANGLE_MESHES};
|
|
use crate::core::texture::FloatTexture;
|
|
use crate::{Arena, FileLoc, ParameterDictionary};
|
|
use anyhow::{bail, Result};
|
|
use log::warn;
|
|
use shared::core::shape::Shape;
|
|
use shared::shapes::{TriangleMesh, TriangleShape};
|
|
use shared::{Ptr, Transform};
|
|
use std::collections::HashMap;
|
|
use std::sync::Arc;
|
|
|
|
impl CreateShape for TriangleShape {
|
|
fn create(
|
|
render_from_object: Transform,
|
|
_object_from_render: Transform,
|
|
reverse_orientation: bool,
|
|
parameters: ParameterDictionary,
|
|
_float_texture: &HashMap<String, Arc<FloatTexture>>,
|
|
_loc: FileLoc,
|
|
arena: &Arena,
|
|
) -> Result<Vec<Ptr<Shape>>> {
|
|
let mut vertex_indices = parameters.get_int_array("indices")?;
|
|
let p = parameters.get_point3f_array("P")?;
|
|
let mut uvs = parameters.get_point2f_array("uv")?;
|
|
let mut s = parameters.get_vector3f_array("S")?;
|
|
let mut n = parameters.get_normal3f_array("N")?;
|
|
|
|
if vertex_indices.is_empty() {
|
|
if p.len() == 3 {
|
|
} else {
|
|
bail!("Vertex indices \"indices\" must be provided with triangle mesh.");
|
|
}
|
|
} else if vertex_indices.len() % 3 != 0 {
|
|
let excess = vertex_indices.len() % 3;
|
|
warn!(
|
|
"Number of vertex indices {} not a multiple of 3. Discarding {} excess.",
|
|
vertex_indices.len(),
|
|
excess
|
|
);
|
|
let new_len = vertex_indices.len() - excess;
|
|
vertex_indices.truncate(new_len);
|
|
}
|
|
|
|
if p.is_empty() {
|
|
bail!("Vertex positions \"P\" must be provided with triangle mesh.");
|
|
}
|
|
|
|
if !uvs.is_empty() && uvs.len() != p.len() {
|
|
warn!("Number of \"uv\"s for triangle mesh must match \"P\"s. Discarding uvs.");
|
|
uvs.clear();
|
|
}
|
|
|
|
if !s.is_empty() && s.len() != p.len() {
|
|
warn!("Number of \"S\"s for triangle mesh must match \"P\"s. Discarding \"S\"s.");
|
|
s.clear();
|
|
}
|
|
|
|
if !n.is_empty() && n.len() != p.len() {
|
|
warn!("Number of \"N\"s for triangle mesh must match \"P\"s. Discarding \"N\"s.");
|
|
n.clear();
|
|
}
|
|
|
|
for &index in vertex_indices.iter() {
|
|
// Check for negative indices (if keeping i32) or out of bounds
|
|
if index < 0 || index as usize >= p.len() {
|
|
bail!(
|
|
"TriangleMesh has out-of-bounds vertex index {} ({} \"P\" values were given). Discarding this mesh.",
|
|
index,
|
|
p.len()
|
|
);
|
|
}
|
|
}
|
|
|
|
let mut face_indices = parameters.get_int_array("faceIndices")?;
|
|
let n_triangles = vertex_indices.len() / 3;
|
|
|
|
if !face_indices.is_empty() && face_indices.len() != n_triangles {
|
|
warn!(
|
|
"Number of face indices {} does not match number of triangles {}. Discarding face indices.",
|
|
face_indices.len(),
|
|
n_triangles
|
|
);
|
|
face_indices.clear();
|
|
}
|
|
|
|
let host = TriangleMesh::new(
|
|
&render_from_object,
|
|
reverse_orientation,
|
|
&vertex_indices,
|
|
&p,
|
|
&n,
|
|
&s,
|
|
&uvs,
|
|
&face_indices,
|
|
);
|
|
|
|
let host_arc = Arc::new(host);
|
|
let mut global_store = ALL_TRIANGLE_MESHES.lock();
|
|
// let mesh_index = global_store.len() as u32;
|
|
global_store.push(host_arc.clone());
|
|
drop(global_store);
|
|
let n_patches = host_arc.n_triangles;
|
|
let mesh_ptr = arena.alloc_arc(host_arc);
|
|
let mut shapes = Vec::with_capacity(n_patches as usize);
|
|
for i in 0..n_patches {
|
|
shapes.push(arena.alloc(Shape::Triangle(TriangleShape {
|
|
mesh: mesh_ptr,
|
|
tri_index: i as i32,
|
|
})));
|
|
}
|
|
|
|
Ok(shapes)
|
|
}
|
|
}
|