155 lines
4.5 KiB
Rust
155 lines
4.5 KiB
Rust
use crate::core::geometry::{Normal3f, Point2f, Point3f, Vector3f};
|
|
use crate::utils::sampling::PiecewiseConstant2D;
|
|
use crate::{gvec_from_slice, gvec_with_capacity, Float, GVec, Ptr, Transform};
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone)]
|
|
pub struct TriangleMesh {
|
|
pub p: GVec<Point3f>,
|
|
pub n: GVec<Normal3f>,
|
|
pub s: GVec<Vector3f>,
|
|
pub uv: GVec<Point2f>,
|
|
pub vertex_indices: GVec<i32>,
|
|
pub face_indices: GVec<i32>,
|
|
pub n_triangles: u32,
|
|
pub n_vertices: u32,
|
|
pub reverse_orientation: bool,
|
|
pub transform_swaps_handedness: bool,
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone)]
|
|
pub struct BilinearPatchMesh {
|
|
pub p: GVec<Point3f>,
|
|
pub n: GVec<Normal3f>,
|
|
pub uv: GVec<Point2f>,
|
|
pub vertex_indices: GVec<i32>,
|
|
pub n_patches: u32,
|
|
pub n_vertices: u32,
|
|
pub reverse_orientation: bool,
|
|
pub transform_swaps_handedness: bool,
|
|
pub image_distribution: Ptr<PiecewiseConstant2D>,
|
|
}
|
|
|
|
|
|
impl TriangleMesh {
|
|
pub fn new(
|
|
render_from_object: &Transform,
|
|
reverse_orientation: bool,
|
|
vertex_indices: &[i32],
|
|
p: &[Point3f],
|
|
n: &[Normal3f],
|
|
s: &[Vector3f],
|
|
uv: &[Point2f],
|
|
face_indices: &[i32],
|
|
) -> Self {
|
|
let n_triangles = (vertex_indices.len() / 3) as u32;
|
|
let n_vertices = p.len() as u32;
|
|
|
|
let mut p_gvec = gvec_with_capacity(p.len());
|
|
for pt in p {
|
|
p_gvec.push(render_from_object.apply_to_point(*pt));
|
|
}
|
|
|
|
let mut n_gvec = gvec_with_capacity(n.len());
|
|
if !n.is_empty() {
|
|
assert_eq!(n_vertices as usize, n.len(), "Normal count mismatch");
|
|
for nn in n {
|
|
let mut transformed = render_from_object.apply_to_normal(*nn);
|
|
if reverse_orientation {
|
|
transformed = -transformed;
|
|
}
|
|
n_gvec.push(transformed);
|
|
}
|
|
}
|
|
|
|
let mut s_gvec = gvec_with_capacity(s.len());
|
|
if !s.is_empty() {
|
|
assert_eq!(n_vertices as usize, s.len(), "Tangent count mismatch");
|
|
for ss in s {
|
|
s_gvec.push(render_from_object.apply_to_vector(*ss));
|
|
}
|
|
}
|
|
|
|
assert!(
|
|
uv.is_empty() || uv.len() == n_vertices as usize,
|
|
"UV count mismatch"
|
|
);
|
|
assert!(
|
|
face_indices.is_empty() || face_indices.len() == n_triangles as usize,
|
|
"Face index count mismatch"
|
|
);
|
|
|
|
Self {
|
|
vertex_indices: gvec_from_slice(vertex_indices),
|
|
p: p_gvec,
|
|
n: n_gvec,
|
|
s: s_gvec,
|
|
uv: gvec_from_slice(uv),
|
|
face_indices: gvec_from_slice(face_indices),
|
|
n_triangles,
|
|
n_vertices,
|
|
reverse_orientation,
|
|
transform_swaps_handedness: render_from_object.swaps_handedness(),
|
|
}
|
|
}
|
|
|
|
pub fn positions(&self) -> &[Point3f] {
|
|
&self.p
|
|
}
|
|
pub fn indices(&self) -> &[i32] {
|
|
&self.vertex_indices
|
|
}
|
|
pub fn normals(&self) -> &[Normal3f] {
|
|
&self.n
|
|
}
|
|
pub fn uvs(&self) -> &[Point2f] {
|
|
&self.uv
|
|
}
|
|
}
|
|
|
|
impl BilinearPatchMesh {
|
|
pub fn new(
|
|
render_from_object: &Transform,
|
|
reverse_orientation: bool,
|
|
vertex_indices: &[i32],
|
|
p: &[Point3f],
|
|
n: &[Normal3f],
|
|
uv: &[Point2f],
|
|
image_distribution: Option<&PiecewiseConstant2D>,
|
|
) -> Self {
|
|
let n_patches = (vertex_indices.len() / 4) as u32;
|
|
let n_vertices = p.len() as u32;
|
|
|
|
let mut p_gvec = gvec_with_capacity(p.len());
|
|
for pt in p {
|
|
p_gvec.push(render_from_object.apply_to_point(*pt));
|
|
}
|
|
|
|
let mut n_gvec = gvec_with_capacity(n.len());
|
|
if !n.is_empty() {
|
|
assert_eq!(n_vertices as usize, n.len());
|
|
for nn in n {
|
|
let mut transformed = render_from_object.apply_to_normal(*nn);
|
|
if reverse_orientation {
|
|
transformed = -transformed;
|
|
}
|
|
n_gvec.push(transformed);
|
|
}
|
|
}
|
|
|
|
assert!(uv.is_empty() || uv.len() == n_vertices as usize);
|
|
|
|
Self {
|
|
vertex_indices: gvec_from_slice(vertex_indices),
|
|
p: p_gvec,
|
|
n: n_gvec,
|
|
uv: gvec_from_slice(uv),
|
|
image_distribution: Ptr::from(image_distribution),
|
|
n_patches,
|
|
n_vertices,
|
|
reverse_orientation,
|
|
transform_swaps_handedness: render_from_object.swaps_handedness(),
|
|
}
|
|
}
|
|
}
|