mesh_generation/mesh/
polymesh.rs1use nalgebra::base::{Vector3, Vector2};
2use std::fs::File;
3use std::io::prelude::*;
4
5pub struct PolyMesh {
6 pub num_vertices: u32,
7 pub vertices: Vec<Vector3<f64>>,
8 pub vertices_array: Vec<u32>,
9 pub st: Vec<Vector2<f64>>,
10 pub normals: Vec<Vector3<f64>>,
11 pub num_faces: u32,
12 pub face_array: Vec<u32>,
13}
14
15const DEFAULT_WIDTH: u32 = 40;
16const DEFAULT_HEIGHT: u32 = 40;
17
18impl PolyMesh {
19
20 pub fn new(
23 subdivision_width: Option<u32>,
24 subdivision_height: Option<u32>,
25 height: Option<u32>,
26 width: Option<u32>,
27 ) -> Self {
28 let subdivision_width = subdivision_width.unwrap_or(DEFAULT_WIDTH);
29 let subdivision_height = subdivision_height.unwrap_or(DEFAULT_HEIGHT);
30
31 let num_vertices = (subdivision_width + 1) * (subdivision_height + 1);
32 let vertices = vec![Vector3::<f64>::new(0.0, 0.0, 0.0); num_vertices as usize];
33 let st = vec![Vector2::<f64>::new(0.0, 0.0); num_vertices as usize];
34 let num_faces = subdivision_width * subdivision_height;
35 let face_array = vec![4 as u32; num_faces as usize];
36 let vertices_array = vec![0 as u32; 4*num_faces as usize];
37 let normals = vec![Vector3::<f64>::new(0.0, 1.0, 0.0); num_vertices as usize];
38 println!("Vertices: {} Faces: {}", num_vertices, num_faces);
39 let mut mesh = PolyMesh {
41 num_vertices,
42 vertices,
43 vertices_array,
44 st,
45 normals,
46 num_faces,
47 face_array,
48 };
49
50 let height = height.unwrap_or(1) as f64;
52 let width = width.unwrap_or(1) as f64;
53 let invsubdivision_width = 1.0 / subdivision_width as f64;
54 let invsubdivision_height = 1.0 / subdivision_height as f64;
55 println!("Height: {} Inverse: {} Width:{} Inverse:{}", subdivision_height, invsubdivision_height, subdivision_width, invsubdivision_width);
56 for j in 0..(subdivision_height+1) {
57 for i in 0..(subdivision_width+1) {
58 mesh.vertices[(j * (subdivision_width + 1) + i) as usize] = Vector3::<f64>::new(width * (i as f64 * invsubdivision_width - 0.5), 0.0, height * (j as f64 * invsubdivision_height - 0.5));
59 mesh.st[(j * (subdivision_width + 1) + i) as usize] = Vector2::<f64>::new(i as f64 * invsubdivision_width, j as f64 * invsubdivision_height);
60 }
61 }
62
63 let mut k = 0;
64 for j in 0..subdivision_height {
65 for i in 0..subdivision_height {
66 mesh.vertices_array[k] = j * (subdivision_width + 1) + i;
67 mesh.vertices_array[k + 1] = j * (subdivision_width + 1) + i + 1;
68 mesh.vertices_array[k + 2] = (j + 1) * (subdivision_width + 1) + i + 1;
69 mesh.vertices_array[k + 3] = (j + 1) * (subdivision_width + 1) + i;
70 k += 4;
71 }
72 }
73 mesh
74 }
75
76 pub fn export_to_obj(&self, filename: &str) {
78 let file_handle = File::create(filename);
79 if let Ok(mut file) = file_handle {
80 for i in 0..self.num_vertices {
81 file.write_all(format!("v {} {} {}\n", self.vertices[i as usize].x, self.vertices[i as usize].y, self.vertices[i as usize].z).as_bytes()).expect("write failed");
82 }
83 for i in 0..self.num_vertices {
84 file.write_all(format!("vt {} {}\n", self.st[i as usize].x, self.st[i as usize].y).as_bytes()).expect("write failed");
85 }
86 for i in 0..self.num_vertices {
87 file.write_all(format!("vn {} {} {}\n", self.normals[i as usize].x, self.normals[i as usize].y, self.normals[i as usize].z).as_bytes()).expect("write failed");
88 }
89 let mut k:u32 = 0;
90 for i in 0..self.num_faces {
91 file.write_all(b"f ").expect("write failed");
92 for j in 0..self.face_array[i as usize] {
93 let obj_index: u32 = self.vertices_array[(k + j) as usize] + 1;
94 let end = if j == (self.face_array[i as usize] -1) { "" } else {" "};
95 file.write_all(format!("{}/{}/{}{}", obj_index, obj_index, obj_index, end).as_bytes()).expect("write failed");
96 }
97 file.write_all(b"\n").expect("write failed");
98 k+=self.face_array[i as usize];
99 }
100 }
101 }
102
103 pub fn calculate_normals(&mut self) {
105 let mut off: usize = 0;
106 for k in 0..self.num_faces {
107 let nverts = self.face_array[k as usize] as usize;
108 let vector_a = self.vertices[(self.vertices_array[off]) as usize];
109 let vector_b = self.vertices[(self.vertices_array[off+ 1]) as usize];
110 let vector_c = self.vertices[(self.vertices_array[off + nverts - 1]) as usize];
111
112 let tangent = vector_b - vector_a;
113 let bitangent = vector_c - vector_a;
114
115 self.normals[self.vertices_array[off] as usize] = bitangent.cross(&tangent).normalize();
116 off += nverts;
117 }
118 }
119
120 pub fn displace_with_noise_map(&mut self, noise_map: Vec<f64>, image_width: u32, image_height: u32) {
122 let image_width = image_width as f64;
123 let image_height = image_height as f64;
124 for i in 0..self.num_vertices {
125 let st = self.st[i as usize];
126 let x = min(st.x * image_width, image_width - 1.0);
127 let y = min(st.y * image_height, image_height - 1.0);
128 self.vertices[i as usize].y = 2.0 * noise_map[(y * image_width + x) as usize] - 1.0;
129 }
130 }
131}
132
133fn min(a: f64, b: f64) -> f64 {
134 if b < a {
135 b
136 } else {
137 a
138 }
139}