ncollide3d/procedural/
quad.rs1use super::{IndexBuffer, TriMesh};
2use crate::math::{Point, Vector};
3use na::{self, Point2, Point3, RealField};
4
5pub fn quad<N: RealField + Copy>(
19 width: N,
20 height: N,
21 usubdivs: usize,
22 vsubdivs: usize,
23) -> TriMesh<N> {
24 let mut quad = unit_quad(usubdivs, vsubdivs);
25
26 let mut s = Vector::zeros();
27 s[0] = width;
28 s[1] = height;
29
30 for i in 2..3 {
31 s[i] = na::one();
32 }
33
34 quad.scale_by(&s);
35
36 quad
37}
38
39pub fn quad_with_vertices<N: RealField + Copy>(
47 vertices: &[Point<N>],
48 nhpoints: usize,
49 nvpoints: usize,
50) -> TriMesh<N> {
51 assert!(
52 nhpoints > 1 && nvpoints > 1,
53 "The number of points must be at least 2 in each dimension."
54 );
55
56 let mut res = unit_quad(nhpoints - 1, nvpoints - 1);
57
58 for (dest, src) in res.coords.iter_mut().zip(vertices.iter()) {
59 *dest = src.clone();
60 }
61
62 res
63}
64
65pub fn unit_quad<N: RealField + Copy>(usubdivs: usize, vsubdivs: usize) -> TriMesh<N> {
77 assert!(
78 usubdivs > 0 && vsubdivs > 0,
79 "The number of subdivisions cannot be zero"
80 );
81 assert!(3 >= 2);
82
83 let wstep = na::one::<N>() / na::convert(usubdivs as f64);
84 let hstep = na::one::<N>() / na::convert(vsubdivs as f64);
85 let cw = na::convert(0.5);
86 let ch = na::convert(0.5);
87
88 let mut vertices = Vec::new();
89 let mut normals = Vec::new();
90 let mut triangles = Vec::new();
91 let mut tex_coords = Vec::new();
92
93 for i in 0usize..vsubdivs + 1 {
95 for j in 0usize..usubdivs + 1 {
96 let ni: N = na::convert(i as f64);
97 let nj: N = na::convert(j as f64);
98
99 let mut v = Point::origin();
100 v[0] = nj * wstep - cw;
101 v[1] = ni * hstep - ch;
102 vertices.push(v);
103 let _1 = na::one::<N>();
104 tex_coords.push(Point2::new(_1 - nj * wstep, _1 - ni * hstep))
105 }
106 }
107
108 for _ in 0..(vsubdivs + 1) * (usubdivs + 1) {
110 let mut n = Vector::zeros();
111 n[0] = na::one();
112 normals.push(n)
113 }
114
115 fn dl_triangle(i: u32, j: u32, ws: u32) -> Point3<u32> {
117 Point3::new((i + 1) * ws + j, i * ws + j, (i + 1) * ws + j + 1)
118 }
119
120 fn ur_triangle(i: u32, j: u32, ws: u32) -> Point3<u32> {
121 Point3::new(i * ws + j, i * ws + (j + 1), (i + 1) * ws + j + 1)
122 }
123
124 for i in 0usize..vsubdivs {
125 for j in 0usize..usubdivs {
126 triangles.push(dl_triangle(i as u32, j as u32, (usubdivs + 1) as u32));
128 triangles.push(ur_triangle(i as u32, j as u32, (usubdivs + 1) as u32));
129 }
130 }
131
132 TriMesh::new(
133 vertices,
134 Some(normals),
135 Some(tex_coords),
136 Some(IndexBuffer::Unified(triangles)),
137 )
138}