Finally generating correct normals
Have to detect and correct inverted normals during calculation since the winding order of the generated truncated icosahedrons is inconsistent.
This commit is contained in:
parent
f5a032c222
commit
e0fc3c1917
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
|||||||
{"positions":[[-0.8506508,0.0,0.5257311],[0.0,0.5257311,0.8506508],[-0.5257311,0.8506508,0.0],[0.5257311,0.8506508,0.0],[0.0,0.5257311,-0.8506508],[-0.8506508,0.0,-0.5257311],[0.8506508,0.0,0.5257311],[0.0,-0.5257311,0.8506508],[-0.5257311,-0.8506508,0.0],[0.0,-0.5257311,-0.8506508],[0.8506508,0.0,-0.5257311],[0.5257311,-0.8506508,0.0]],"cells":[[0,1,2],[1,3,2],[3,4,2],[4,5,2],[5,0,2],[1,6,3],[0,7,1],[5,8,0],[4,9,5],[3,10,4],[6,7,11],[7,8,11],[8,9,11],[9,10,11],[10,6,11],[6,1,7],[7,0,8],[8,5,9],[9,4,10],[10,3,6]]}
|
{"positions":[[-0.8506508,0.0,0.5257311],[0.0,0.5257311,0.8506508],[-0.5257311,0.8506508,0.0],[0.5257311,0.8506508,0.0],[0.0,0.5257311,-0.8506508],[-0.8506508,0.0,-0.5257311],[0.8506508,0.0,0.5257311],[0.0,-0.5257311,0.8506508],[-0.5257311,-0.8506508,0.0],[0.0,-0.5257311,-0.8506508],[0.8506508,0.0,-0.5257311],[0.5257311,-0.8506508,0.0]],"cells":[[0,1,2],[1,3,2],[3,4,2],[4,5,2],[5,0,2],[1,6,3],[0,7,1],[5,8,0],[4,9,5],[3,10,4],[6,7,11],[7,8,11],[8,9,11],[9,10,11],[10,6,11],[6,1,7],[7,0,8],[8,5,9],[9,4,10],[10,3,6]],"normals":[[-0.85065085,0.0,0.52573115],[0.0,0.52573115,0.85065085],[-0.52573115,0.85065085,0.0],[0.52573115,0.85065085,0.0],[0.0,0.52573115,-0.85065085],[-0.85065085,0.0,-0.52573115],[0.85065085,0.0,0.52573115],[0.0,-0.52573115,0.85065085],[-0.5257311,-0.8506508,0.0],[0.0,-0.52573115,-0.85065085],[0.85065085,0.0,-0.52573115],[0.52573115,-0.85065085,0.0]],"faces":[]}
|
@ -1 +1 @@
|
|||||||
{"positions":[[-0.809017,0.5,0.309017],[-0.309017,0.809017,0.5],[-0.5257311,0.8506508,0.0],[-0.5,0.309017,0.809017],[-0.8506508,0.0,0.5257311],[0.0,0.5257311,0.8506508],[0.0,1.0,0.0],[0.309017,0.809017,0.5],[0.5257311,0.8506508,0.0],[-0.309017,0.809017,-0.5],[0.309017,0.809017,-0.5],[0.0,0.5257311,-0.8506508],[-0.809017,0.5,-0.309017],[-0.5,0.309017,-0.809017],[-0.8506508,0.0,-0.5257311],[-1.0,0.0,0.0],[0.809017,0.5,0.309017],[0.5,0.309017,0.809017],[0.8506508,0.0,0.5257311],[0.0,0.0,1.0],[-0.5,-0.309017,0.809017],[0.0,-0.5257311,0.8506508],[-0.809017,-0.5,0.309017],[-0.809017,-0.5,-0.309017],[-0.5257311,-0.8506508,0.0],[-0.5,-0.309017,-0.809017],[0.0,0.0,-1.0],[0.0,-0.5257311,-0.8506508],[0.5,0.309017,-0.809017],[0.809017,0.5,-0.309017],[0.8506508,0.0,-0.5257311],[0.809017,-0.5,0.309017],[0.309017,-0.809017,0.5],[0.5257311,-0.8506508,0.0],[0.5,-0.309017,0.809017],[0.0,-1.0,0.0],[-0.309017,-0.809017,0.5],[0.309017,-0.809017,-0.5],[-0.309017,-0.809017,-0.5],[0.809017,-0.5,-0.309017],[0.5,-0.309017,-0.809017],[1.0,0.0,0.0]],"cells":[[0,1,2],[0,3,1],[4,3,0],[3,5,1],[1,6,2],[1,7,6],[5,7,1],[7,8,6],[6,9,2],[6,10,9],[8,10,6],[10,11,9],[9,12,2],[9,13,12],[11,13,9],[13,14,12],[12,0,2],[12,15,0],[14,15,12],[15,4,0],[7,16,8],[7,17,16],[5,17,7],[17,18,16],[3,19,5],[3,20,19],[4,20,3],[20,21,19],[15,22,4],[15,23,22],[14,23,15],[23,24,22],[13,25,14],[13,26,25],[11,26,13],[26,27,25],[10,28,11],[10,29,28],[8,29,10],[29,30,28],[31,32,33],[31,34,32],[18,34,31],[34,21,32],[32,35,33],[32,36,35],[21,36,32],[36,24,35],[35,37,33],[35,38,37],[24,38,35],[38,27,37],[37,39,33],[37,40,39],[27,40,37],[40,30,39],[39,31,33],[39,41,31],[30,41,39],[41,18,31],[34,19,21],[34,17,19],[18,17,34],[17,5,19],[36,22,24],[36,20,22],[21,20,36],[20,4,22],[38,25,27],[38,23,25],[24,23,38],[23,14,25],[40,28,30],[40,26,28],[27,26,40],[26,11,28],[41,16,18],[41,29,16],[30,29,41],[29,8,16]]}
|
{"positions":[[-0.809017,0.5,0.309017],[-0.309017,0.809017,0.5],[-0.5257311,0.8506508,0.0],[-0.5,0.309017,0.809017],[-0.8506508,0.0,0.5257311],[0.0,0.5257311,0.8506508],[0.0,1.0,0.0],[0.309017,0.809017,0.5],[0.5257311,0.8506508,0.0],[-0.309017,0.809017,-0.5],[0.309017,0.809017,-0.5],[0.0,0.5257311,-0.8506508],[-0.809017,0.5,-0.309017],[-0.5,0.309017,-0.809017],[-0.8506508,0.0,-0.5257311],[-1.0,0.0,0.0],[0.809017,0.5,0.309017],[0.5,0.309017,0.809017],[0.8506508,0.0,0.5257311],[0.0,0.0,1.0],[-0.5,-0.309017,0.809017],[0.0,-0.5257311,0.8506508],[-0.809017,-0.5,0.309017],[-0.809017,-0.5,-0.309017],[-0.5257311,-0.8506508,0.0],[-0.5,-0.309017,-0.809017],[0.0,0.0,-1.0],[0.0,-0.5257311,-0.8506508],[0.5,0.309017,-0.809017],[0.809017,0.5,-0.309017],[0.8506508,0.0,-0.5257311],[0.809017,-0.5,0.309017],[0.309017,-0.809017,0.5],[0.5257311,-0.8506508,0.0],[0.5,-0.309017,0.809017],[0.0,-1.0,0.0],[-0.309017,-0.809017,0.5],[0.309017,-0.809017,-0.5],[-0.309017,-0.809017,-0.5],[0.809017,-0.5,-0.309017],[0.5,-0.309017,-0.809017],[1.0,0.0,0.0]],"cells":[[0,1,2],[0,3,1],[4,3,0],[3,5,1],[1,6,2],[1,7,6],[5,7,1],[7,8,6],[6,9,2],[6,10,9],[8,10,6],[10,11,9],[9,12,2],[9,13,12],[11,13,9],[13,14,12],[12,0,2],[12,15,0],[14,15,12],[15,4,0],[7,16,8],[7,17,16],[5,17,7],[17,18,16],[3,19,5],[3,20,19],[4,20,3],[20,21,19],[15,22,4],[15,23,22],[14,23,15],[23,24,22],[13,25,14],[13,26,25],[11,26,13],[26,27,25],[10,28,11],[10,29,28],[8,29,10],[29,30,28],[31,32,33],[31,34,32],[18,34,31],[34,21,32],[32,35,33],[32,36,35],[21,36,32],[36,24,35],[35,37,33],[35,38,37],[24,38,35],[38,27,37],[37,39,33],[37,40,39],[27,40,37],[40,30,39],[39,31,33],[39,41,31],[30,41,39],[41,18,31],[34,19,21],[34,17,19],[18,17,34],[17,5,19],[36,22,24],[36,20,22],[21,20,36],[20,4,22],[38,25,27],[38,23,25],[24,23,38],[23,14,25],[40,28,30],[40,26,28],[27,26,40],[26,11,28],[41,16,18],[41,29,16],[30,29,41],[29,8,16]],"normals":[[-0.809017,0.5,0.309017],[-0.309017,0.809017,0.50000006],[-0.52573115,0.8506508,0.0],[-0.50000006,0.309017,0.809017],[-0.8506508,0.0,0.52573115],[-2.8343692e-9,0.52573115,0.8506508],[0.0,1.0,-2.2313862e-9],[0.309017,0.809017,0.5],[0.52573115,0.8506508,0.0],[-0.309017,0.809017,-0.5],[0.309017,0.809017,-0.5],[2.8343692e-9,0.52573115,-0.8506508],[-0.809017,0.5,-0.309017],[-0.5,0.309017,-0.809017],[-0.8506508,0.0,-0.52573115],[-1.0,-2.2313862e-9,0.0],[0.809017,0.50000006,0.309017],[0.5,0.309017,0.809017],[0.8506508,0.0,0.52573115],[2.2313862e-9,0.0,1.0],[-0.5,-0.309017,0.809017],[0.0,-0.52573115,0.8506508],[-0.809017,-0.5,0.309017],[-0.809017,-0.5,-0.309017],[-0.52573115,-0.8506508,0.0],[-0.5,-0.309017,-0.809017],[6.694158e-9,0.0,-1.0],[2.8343692e-9,-0.52573115,-0.8506508],[0.5,0.309017,-0.809017],[0.809017,0.50000006,-0.309017],[0.8506508,-2.8343692e-9,-0.52573115],[0.809017,-0.5,0.309017],[0.309017,-0.809017,0.50000006],[0.52573115,-0.8506508,0.0],[0.50000006,-0.309017,0.809017],[0.0,-1.0,-2.2313862e-9],[-0.309017,-0.809017,0.5],[0.309017,-0.809017,-0.5],[-0.309017,-0.809017,-0.5],[0.809017,-0.5,-0.309017],[0.5,-0.309017,-0.809017],[1.0,2.2313862e-9,0.0]],"faces":[]}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
157
src/main.rs
157
src/main.rs
@ -3,6 +3,7 @@ extern crate cgmath;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::ops::AddAssign;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use cgmath::prelude::*;
|
use cgmath::prelude::*;
|
||||||
@ -46,8 +47,10 @@ struct ArraySerializedVector(Vector3<f32>);
|
|||||||
struct Polyhedron {
|
struct Polyhedron {
|
||||||
positions: Vec<ArraySerializedVector>,
|
positions: Vec<ArraySerializedVector>,
|
||||||
cells: Vec<Triangle>,
|
cells: Vec<Triangle>,
|
||||||
|
normals: Vec<ArraySerializedVector>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
added_vert_cache: HashMap<(i32, i32, i32), usize>,
|
added_vert_cache: HashMap<(i32, i32, i32), usize>,
|
||||||
|
faces: Vec<Vec<usize>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for ArraySerializedVector {
|
impl Serialize for ArraySerializedVector {
|
||||||
@ -64,12 +67,20 @@ impl Serialize for ArraySerializedVector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AddAssign for ArraySerializedVector {
|
||||||
|
fn add_assign(&mut self, other: Self) {
|
||||||
|
*self = Self(self.0 + other.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Polyhedron {
|
impl Polyhedron {
|
||||||
fn new() -> Polyhedron {
|
fn new() -> Polyhedron {
|
||||||
Polyhedron {
|
Polyhedron {
|
||||||
positions: vec![],
|
positions: vec![],
|
||||||
cells: vec![],
|
cells: vec![],
|
||||||
|
normals: vec![],
|
||||||
added_vert_cache: HashMap::new(),
|
added_vert_cache: HashMap::new(),
|
||||||
|
faces: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +110,9 @@ impl Polyhedron {
|
|||||||
Triangle::new(8, 6, 7),
|
Triangle::new(8, 6, 7),
|
||||||
Triangle::new(9, 8, 1),
|
Triangle::new(9, 8, 1),
|
||||||
],
|
],
|
||||||
|
normals: vec![],
|
||||||
added_vert_cache: HashMap::new(),
|
added_vert_cache: HashMap::new(),
|
||||||
|
faces: vec![],
|
||||||
};
|
};
|
||||||
base_isocahedron.add_position(Vector3::new(-1.0, t, 0.0));
|
base_isocahedron.add_position(Vector3::new(-1.0, t, 0.0));
|
||||||
base_isocahedron.add_position(Vector3::new(1.0, t, 0.0));
|
base_isocahedron.add_position(Vector3::new(1.0, t, 0.0));
|
||||||
@ -119,11 +132,11 @@ impl Polyhedron {
|
|||||||
subdivided
|
subdivided
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_dual_isocahedron(radius: f32, detail: usize) -> Polyhedron {
|
fn new_truncated_isocahedron(radius: f32, detail: usize) -> Polyhedron {
|
||||||
let isocahedron = Polyhedron::new_isocahedron(radius, detail);
|
let isocahedron = Polyhedron::new_isocahedron(radius, detail);
|
||||||
let mut dual_isocahedron = Polyhedron::new();
|
let mut truncated_isocahedron = Polyhedron::new();
|
||||||
dual_isocahedron.dual(isocahedron);
|
truncated_isocahedron.truncated(isocahedron);
|
||||||
dual_isocahedron
|
truncated_isocahedron
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subdivide(&mut self, other: Polyhedron, radius: f32, detail: usize) {
|
fn subdivide(&mut self, other: Polyhedron, radius: f32, detail: usize) {
|
||||||
@ -192,19 +205,22 @@ impl Polyhedron {
|
|||||||
return *added_vert_index;
|
return *added_vert_index;
|
||||||
} else {
|
} else {
|
||||||
self.positions.push(ArraySerializedVector(vertex));
|
self.positions.push(ArraySerializedVector(vertex));
|
||||||
|
self.normals
|
||||||
|
.push(ArraySerializedVector(Vector3::new(0.0, 0.0, 0.0)));
|
||||||
let added_index = self.positions.len() - 1;
|
let added_index = self.positions.len() - 1;
|
||||||
self.added_vert_cache.insert(vertex_key, added_index);
|
self.added_vert_cache.insert(vertex_key, added_index);
|
||||||
return added_index;
|
return added_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dual(&mut self, other: Polyhedron) {
|
fn truncated(&mut self, other: Polyhedron) {
|
||||||
let vert_to_faces = other.vert_to_faces();
|
let vert_to_faces = other.vert_to_faces();
|
||||||
let original_vert_count = other.positions.len();
|
let original_vert_count = other.positions.len();
|
||||||
let triangle_centroids = other.triangle_centroids();
|
let triangle_centroids = other.triangle_centroids();
|
||||||
let mut mid_centroid_cache: HashMap<(usize, usize), Vector3<f32>> = HashMap::new();
|
let mut mid_centroid_cache: HashMap<(usize, usize, usize), Vector3<f32>> = HashMap::new();
|
||||||
let mut hex_count = 0;
|
let mut hex_count = 0;
|
||||||
let mut pent_count = 0;
|
let mut pent_count = 0;
|
||||||
|
let mut count = 0;
|
||||||
for i in 0..original_vert_count {
|
for i in 0..original_vert_count {
|
||||||
let faces = &vert_to_faces[&i];
|
let faces = &vert_to_faces[&i];
|
||||||
if faces.len() == 6 {
|
if faces.len() == 6 {
|
||||||
@ -215,7 +231,9 @@ impl Polyhedron {
|
|||||||
|
|
||||||
let center_point = find_center_of_triangles(faces, &triangle_centroids);
|
let center_point = find_center_of_triangles(faces, &triangle_centroids);
|
||||||
|
|
||||||
for face_index in faces {
|
let mut new_face = Vec::new();
|
||||||
|
|
||||||
|
for face_index in faces.iter().rev() {
|
||||||
let triangle = &other.cells[*face_index];
|
let triangle = &other.cells[*face_index];
|
||||||
let other_verts: Vec<usize> = vec![triangle.a, triangle.b, triangle.c]
|
let other_verts: Vec<usize> = vec![triangle.a, triangle.b, triangle.c]
|
||||||
.drain(..)
|
.drain(..)
|
||||||
@ -225,15 +243,19 @@ impl Polyhedron {
|
|||||||
|
|
||||||
let centroid = triangle_centroids[face_index];
|
let centroid = triangle_centroids[face_index];
|
||||||
let mid_b_centroid = other.calculate_mid_centroid(
|
let mid_b_centroid = other.calculate_mid_centroid(
|
||||||
|
sorted_triangle.a,
|
||||||
sorted_triangle.b,
|
sorted_triangle.b,
|
||||||
faces,
|
faces,
|
||||||
|
*face_index,
|
||||||
centroid,
|
centroid,
|
||||||
&triangle_centroids,
|
&triangle_centroids,
|
||||||
&mut mid_centroid_cache,
|
&mut mid_centroid_cache,
|
||||||
);
|
);
|
||||||
let mid_c_centroid = other.calculate_mid_centroid(
|
let mid_c_centroid = other.calculate_mid_centroid(
|
||||||
|
sorted_triangle.a,
|
||||||
sorted_triangle.c,
|
sorted_triangle.c,
|
||||||
faces,
|
faces,
|
||||||
|
*face_index,
|
||||||
centroid,
|
centroid,
|
||||||
&triangle_centroids,
|
&triangle_centroids,
|
||||||
&mut mid_centroid_cache,
|
&mut mid_centroid_cache,
|
||||||
@ -246,15 +268,18 @@ impl Polyhedron {
|
|||||||
|
|
||||||
self.cells.push(Triangle::new(
|
self.cells.push(Triangle::new(
|
||||||
center_point_index,
|
center_point_index,
|
||||||
|
mid_c_centroid_index,
|
||||||
centroid_index,
|
centroid_index,
|
||||||
mid_b_centroid_index,
|
|
||||||
));
|
));
|
||||||
|
new_face.push(self.cells.len() - 1);
|
||||||
self.cells.push(Triangle::new(
|
self.cells.push(Triangle::new(
|
||||||
center_point_index,
|
center_point_index,
|
||||||
centroid_index,
|
centroid_index,
|
||||||
mid_c_centroid_index,
|
mid_b_centroid_index,
|
||||||
));
|
));
|
||||||
|
new_face.push(self.cells.len() - 1);
|
||||||
}
|
}
|
||||||
|
self.faces.push(new_face);
|
||||||
}
|
}
|
||||||
println!("hexagons: {}", hex_count);
|
println!("hexagons: {}", hex_count);
|
||||||
println!("pentagons: {}", pent_count);
|
println!("pentagons: {}", pent_count);
|
||||||
@ -299,35 +324,124 @@ impl Polyhedron {
|
|||||||
|
|
||||||
fn calculate_mid_centroid(
|
fn calculate_mid_centroid(
|
||||||
&self,
|
&self,
|
||||||
|
spoke_vertex_index: usize,
|
||||||
vertex_index: usize,
|
vertex_index: usize,
|
||||||
faces: &Vec<usize>,
|
faces: &Vec<usize>,
|
||||||
|
current_face_index: usize,
|
||||||
centroid: Vector3<f32>,
|
centroid: Vector3<f32>,
|
||||||
triangle_centroids: &HashMap<usize, Vector3<f32>>,
|
triangle_centroids: &HashMap<usize, Vector3<f32>>,
|
||||||
mid_centroid_cache: &mut HashMap<(usize, usize), Vector3<f32>>,
|
mid_centroid_cache: &mut HashMap<(usize, usize, usize), Vector3<f32>>,
|
||||||
) -> Vector3<f32> {
|
) -> Vector3<f32> {
|
||||||
let adj_face_index = self.find_adjacent_face(vertex_index, faces).unwrap();
|
let adj_face_index = self
|
||||||
|
.find_adjacent_face(spoke_vertex_index, vertex_index, faces, current_face_index)
|
||||||
|
.unwrap();
|
||||||
let adj_centroid = triangle_centroids[&adj_face_index];
|
let adj_centroid = triangle_centroids[&adj_face_index];
|
||||||
if let Some(mid_centroid) = mid_centroid_cache.get(&(vertex_index, adj_face_index)) {
|
if let Some(mid_centroid) =
|
||||||
|
mid_centroid_cache.get(&(spoke_vertex_index, vertex_index, adj_face_index))
|
||||||
|
{
|
||||||
return *mid_centroid;
|
return *mid_centroid;
|
||||||
} else {
|
} else {
|
||||||
let mid_centroid = centroid.clone().lerp(adj_centroid, 0.5);
|
let mid_centroid = centroid.clone().lerp(adj_centroid, 0.5);
|
||||||
mid_centroid_cache.insert((vertex_index, adj_face_index), mid_centroid);
|
mid_centroid_cache.insert(
|
||||||
|
(spoke_vertex_index, vertex_index, adj_face_index),
|
||||||
|
mid_centroid,
|
||||||
|
);
|
||||||
return mid_centroid;
|
return mid_centroid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_adjacent_face(&self, vertex_index: usize, faces: &Vec<usize>) -> Option<usize> {
|
fn find_adjacent_face(
|
||||||
|
&self,
|
||||||
|
spoke_vertex_index: usize,
|
||||||
|
vertex_index: usize,
|
||||||
|
faces: &Vec<usize>,
|
||||||
|
current_face_index: usize,
|
||||||
|
) -> Option<usize> {
|
||||||
for face_index in faces {
|
for face_index in faces {
|
||||||
|
if *face_index == current_face_index {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let triangle = &self.cells[*face_index];
|
let triangle = &self.cells[*face_index];
|
||||||
if triangle.a == vertex_index
|
if (triangle.a == spoke_vertex_index
|
||||||
|| triangle.b == vertex_index
|
|| triangle.b == spoke_vertex_index
|
||||||
|| triangle.c == vertex_index
|
|| triangle.c == spoke_vertex_index)
|
||||||
|
&& (triangle.a == vertex_index
|
||||||
|
|| triangle.b == vertex_index
|
||||||
|
|| triangle.c == vertex_index)
|
||||||
{
|
{
|
||||||
return Some(*face_index);
|
return Some(*face_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compute_triangle_normals(&mut self) {
|
||||||
|
let origin = Vector3::new(0.0, 0.0, 0.0);
|
||||||
|
for i in 0..self.cells.len() {
|
||||||
|
let vertex_a = &self.positions[self.cells[i].a].0;
|
||||||
|
let vertex_b = &self.positions[self.cells[i].b].0;
|
||||||
|
let vertex_c = &self.positions[self.cells[i].c].0;
|
||||||
|
|
||||||
|
let e1 = vertex_a - vertex_b;
|
||||||
|
let e2 = vertex_c - vertex_b;
|
||||||
|
let mut no = e1.cross(e2);
|
||||||
|
|
||||||
|
// detect and correct inverted normal
|
||||||
|
let dist = vertex_b - origin;
|
||||||
|
if no.dot(dist) < 0.0 {
|
||||||
|
no *= -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let normal_a = self.normals[self.cells[i].a].0 + no;
|
||||||
|
let normal_b = self.normals[self.cells[i].b].0 + no;
|
||||||
|
let normal_c = self.normals[self.cells[i].c].0 + no;
|
||||||
|
|
||||||
|
self.normals[self.cells[i].a] = ArraySerializedVector(normal_a);
|
||||||
|
self.normals[self.cells[i].b] = ArraySerializedVector(normal_b);
|
||||||
|
self.normals[self.cells[i].c] = ArraySerializedVector(normal_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
for normal in self.normals.iter_mut() {
|
||||||
|
*normal = ArraySerializedVector(normal.0.normalize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_face_normals(&mut self) {
|
||||||
|
let origin = Vector3::new(0.0, 0.0, 0.0);
|
||||||
|
for i in 0..self.faces.len() {
|
||||||
|
let first_cell = &self.cells[self.faces[i][0]];
|
||||||
|
|
||||||
|
let vertex_a = &self.positions[first_cell.a].0;
|
||||||
|
let vertex_b = &self.positions[first_cell.b].0;
|
||||||
|
let vertex_c = &self.positions[first_cell.c].0;
|
||||||
|
|
||||||
|
let e1 = vertex_a - vertex_b;
|
||||||
|
let e2 = vertex_c - vertex_b;
|
||||||
|
let mut normal = e1.cross(e2);
|
||||||
|
|
||||||
|
// detect and correct inverted normal
|
||||||
|
let dist = vertex_b - origin;
|
||||||
|
if normal.dot(dist) < 0.0 {
|
||||||
|
normal *= -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for c in 0..self.faces[i].len() {
|
||||||
|
let face_cell = &self.cells[self.faces[i][c]];
|
||||||
|
|
||||||
|
let normal_a = self.normals[face_cell.a].0 + normal;
|
||||||
|
let normal_b = self.normals[face_cell.b].0 + normal;
|
||||||
|
let normal_c = self.normals[face_cell.c].0 + normal;
|
||||||
|
|
||||||
|
self.normals[face_cell.a] = ArraySerializedVector(normal_a);
|
||||||
|
self.normals[face_cell.b] = ArraySerializedVector(normal_b);
|
||||||
|
self.normals[face_cell.c] = ArraySerializedVector(normal_c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for normal in self.normals.iter_mut() {
|
||||||
|
*normal = ArraySerializedVector(normal.0.normalize());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_centroid(pa: Vector3<f32>, pb: Vector3<f32>, pc: Vector3<f32>) -> Vector3<f32> {
|
fn calculate_centroid(pa: Vector3<f32>, pb: Vector3<f32>, pc: Vector3<f32>) -> Vector3<f32> {
|
||||||
@ -356,7 +470,8 @@ fn generate_icosahedron_files(dir: &str, param_list: Vec<(f32, usize)>) {
|
|||||||
);
|
);
|
||||||
let filename = Path::new(dir).join(format!("icosahedron_r{}_d{}.json", param.0, param.1));
|
let filename = Path::new(dir).join(format!("icosahedron_r{}_d{}.json", param.0, param.1));
|
||||||
let mut file = File::create(filename).expect("Can't create file");
|
let mut file = File::create(filename).expect("Can't create file");
|
||||||
let icosahedron = Polyhedron::new_isocahedron(param.0, param.1);
|
let mut icosahedron = Polyhedron::new_isocahedron(param.0, param.1);
|
||||||
|
icosahedron.compute_triangle_normals();
|
||||||
println!("triangles: {}", icosahedron.cells.len());
|
println!("triangles: {}", icosahedron.cells.len());
|
||||||
println!("vertices: {}", icosahedron.positions.len());
|
println!("vertices: {}", icosahedron.positions.len());
|
||||||
let icosahedron_json = serde_json::to_string(&icosahedron).expect("Problem serializing");
|
let icosahedron_json = serde_json::to_string(&icosahedron).expect("Problem serializing");
|
||||||
@ -373,7 +488,9 @@ fn generate_hexsphere_files(dir: &str, param_list: Vec<(f32, usize)>) {
|
|||||||
);
|
);
|
||||||
let filename = Path::new(dir).join(format!("hexsphere_r{}_d{}.json", param.0, param.1));
|
let filename = Path::new(dir).join(format!("hexsphere_r{}_d{}.json", param.0, param.1));
|
||||||
let mut file = File::create(filename).expect("Can't create file");
|
let mut file = File::create(filename).expect("Can't create file");
|
||||||
let hexsphere = Polyhedron::new_dual_isocahedron(param.0, param.1);
|
let mut hexsphere = Polyhedron::new_truncated_isocahedron(param.0, param.1);
|
||||||
|
hexsphere.compute_triangle_normals();
|
||||||
|
// hexsphere.compute_face_normals();
|
||||||
println!("triangles: {}", hexsphere.cells.len());
|
println!("triangles: {}", hexsphere.cells.len());
|
||||||
println!("vertices: {}", hexsphere.positions.len());
|
println!("vertices: {}", hexsphere.positions.len());
|
||||||
let hexsphere_json = serde_json::to_string(&hexsphere).expect("Problem serializing");
|
let hexsphere_json = serde_json::to_string(&hexsphere).expect("Problem serializing");
|
||||||
@ -394,6 +511,8 @@ fn main() {
|
|||||||
(1.0, 5),
|
(1.0, 5),
|
||||||
(1.0, 6),
|
(1.0, 6),
|
||||||
(1.0, 7),
|
(1.0, 7),
|
||||||
|
// (1.0, 8),
|
||||||
|
// (1.0, 9),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
generate_icosahedron_files(
|
generate_icosahedron_files(
|
||||||
|
Loading…
Reference in New Issue
Block a user