mirror of
https://github.com/stickynotememo/wolf_renderer.git
synced 2026-07-30 06:46:03 +10:00
Setup ear clipping interface
This commit is contained in:
+1
-1
@@ -59,7 +59,7 @@ fn main() {
|
|||||||
(0, 1), (1, 2), (2, 0)
|
(0, 1), (1, 2), (2, 0)
|
||||||
],
|
],
|
||||||
vec![
|
vec![
|
||||||
(0, 1, 2)
|
vec![0, 1, 2]
|
||||||
])];
|
])];
|
||||||
|
|
||||||
let mut dt = Duration::ZERO;
|
let mut dt = Duration::ZERO;
|
||||||
|
|||||||
+43
-11
@@ -21,41 +21,73 @@ pub struct Object {
|
|||||||
pub edges: Vec<(Point3D, Point3D)>,
|
pub edges: Vec<(Point3D, Point3D)>,
|
||||||
pub edge_indices: Vec<(usize, usize)>,
|
pub edge_indices: Vec<(usize, usize)>,
|
||||||
|
|
||||||
pub faces: Vec<(Point3D, Point3D, Point3D)>,
|
pub triangles: Vec<(Point3D, Point3D, Point3D)>,
|
||||||
pub face_indices: Vec<(usize, usize, usize)>,
|
pub triangle_indices: Vec<(usize, usize, usize)>,
|
||||||
|
|
||||||
|
pub faces: Vec<Vec<Point3D>>,
|
||||||
|
pub face_indices: Vec<Vec<usize>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object {
|
impl Object {
|
||||||
/// Takes a vector of vertices and a vector of indices for each of the `edge_indices` and
|
/// Takes a vector of vertices and a vector of indices for each of the `edge_indices` and
|
||||||
/// `face_indices` parameters. These indices index the `vertices` array and represent the
|
/// `triangle_indices` parameters. These indices index the `vertices` array and represent the
|
||||||
/// endpoints of the line segment (in the case of an edge) or the vertices of the triangle
|
/// endpoints of the line segment (in the case of an edge) or the vertices of the triangle
|
||||||
/// (in the case of a face)
|
/// (in the case of a triangle)
|
||||||
|
|
||||||
|
// TODO: use [Yoke](https://crates.io/crates/yoke)
|
||||||
pub fn new(vertices: Vec<Point3D>,
|
pub fn new(vertices: Vec<Point3D>,
|
||||||
edge_indices: Vec<(usize, usize)>,
|
edge_indices: Vec<(usize, usize)>,
|
||||||
face_indices: Vec<(usize, usize, usize)>) -> Self {
|
face_indices: Vec<Vec<usize>>) -> Self {
|
||||||
|
|
||||||
|
let mut ret = Self {
|
||||||
|
vertices,
|
||||||
|
|
||||||
|
edges: vec![],
|
||||||
|
edge_indices,
|
||||||
|
|
||||||
|
triangles: vec![],
|
||||||
|
triangle_indices: vec![],
|
||||||
|
|
||||||
|
faces: vec![vec![]],
|
||||||
|
face_indices
|
||||||
|
};
|
||||||
|
|
||||||
let mut ret = Self {vertices, edges: vec![], edge_indices, faces: vec![], face_indices};
|
|
||||||
for (i_start, i_end) in ret.edge_indices.iter() {
|
for (i_start, i_end) in ret.edge_indices.iter() {
|
||||||
ret.edges.push((ret.vertices[*i_start].clone(), ret.vertices[*i_end].clone()));
|
ret.edges.push((ret.vertices[*i_start].clone(), ret.vertices[*i_end].clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i_one, i_two, i_three /* The three vertices of the triangle */) in ret.face_indices.iter() {
|
for (i_one, i_two, i_three /* The three vertices of the triangle */) in ret.triangle_indices.iter() {
|
||||||
ret.faces.push((ret.vertices[*i_one].clone(), ret.vertices[*i_two].clone(), ret.vertices[*i_three].clone()));
|
ret.triangles.push((ret.vertices[*i_one].clone(), ret.vertices[*i_two].clone(), ret.vertices[*i_three].clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates the `edges` and `faces` to correspond to updated vertices.
|
fn ear_clip(polygon: &Vec<Point3D>) -> Vec<(Point3D, Point3D, Point3D)> {
|
||||||
|
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Updates the `edges` and `faces` to correspond to updated vertices.
|
||||||
|
/// Triangulates based on the faces array.
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self) {
|
||||||
|
// OPTIMISATION: Do we need to re-initalise self.{edges, faces, triangles} every execution?
|
||||||
self.edges = vec![];
|
self.edges = vec![];
|
||||||
for (i_start, i_end) in self.edge_indices.iter() {
|
for (i_start, i_end) in self.edge_indices.iter() {
|
||||||
self.edges.push((self.vertices[*i_start].clone(), self.vertices[*i_end].clone()));
|
self.edges.push((self.vertices[*i_start].clone(), self.vertices[*i_end].clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.faces = vec![];
|
self.faces = vec![];
|
||||||
for (i_one, i_two, i_three /* The three vertices of the triangle */) in self.face_indices.iter() {
|
for polygon_indices in self.face_indices.iter() {
|
||||||
self.faces.push((self.vertices[*i_one].clone(), self.vertices[*i_two].clone(), self.vertices[*i_three].clone()));
|
self.faces.push(polygon_indices.iter().map(|indice| self.vertices[*indice]).collect());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.triangles = vec![];
|
||||||
|
for face in self.faces.iter() {
|
||||||
|
self.triangles.append(&mut Self::ear_clip(&face));
|
||||||
|
}
|
||||||
|
for (i_one, i_two, i_three /* The three vertices of the triangle */) in self.triangle_indices.iter() {
|
||||||
|
self.triangles.push((self.vertices[*i_one].clone(), self.vertices[*i_two].clone(), self.vertices[*i_three].clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -63,7 +63,7 @@ pub fn render(scene: &Scene, buf: &mut [u32]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (p0, p1, p2) in &obj.faces {
|
for (p0, p1, p2) in &obj.triangles {
|
||||||
|
|
||||||
let (p0, p1, p2) = (p0.to_screen_coordinates(), p1.to_screen_coordinates(), p2.to_screen_coordinates());
|
let (p0, p1, p2) = (p0.to_screen_coordinates(), p1.to_screen_coordinates(), p2.to_screen_coordinates());
|
||||||
// Finds the leftmost and rightmost points on the triangle and only iterates over them.
|
// Finds the leftmost and rightmost points on the triangle and only iterates over them.
|
||||||
@@ -74,12 +74,12 @@ pub fn render(scene: &Scene, buf: &mut [u32]) {
|
|||||||
for y in vertical_range.clone() {
|
for y in vertical_range.clone() {
|
||||||
let p = Point2D{x: x as f64, y: y as f64};
|
let p = Point2D{x: x as f64, y: y as f64};
|
||||||
|
|
||||||
let area = 0.5 *(-p1.y*p2.x + p0.y*(-p1.x + p2.x) + p0.x*(p1.y - p2.y) + p1.x*p2.y);
|
// adapted from https://stackoverflow.com/a/14382692
|
||||||
let s = 1.0/(2.0*area)*(p0.y*p2.x - p0.x*p2.y + (p2.y - p0.y)*p.x + (p0.x - p2.x)*p.y);
|
let area = 0.5 * (-p1.y * p2.x + p0.y * (-p1.x + p2.x) + p0.x * (p1.y - p2.y) + p1.x * p2.y);
|
||||||
let t = 1.0/(2.0*area)*(p0.x*p1.y - p0.y*p1.x + (p0.y - p1.y)*p.x + (p1.x - p0.x)*p.y);
|
let s = 1.0/(2.0 * area) * (p0.y * p2.x - p0.x * p2.y + (p2.y - p0.y) * p.x + (p0.x - p2.x) * p.y);
|
||||||
|
let t = 1.0/(2.0 * area) * (p0.x * p1.y - p0.y * p1.x + (p0.y - p1.y) * p.x + (p1.x - p0.x) * p.y);
|
||||||
|
|
||||||
if s > 0.0 && t > 0.0 && 1.0 - s - t > 0.0 {
|
if s > 0.0 && t > 0.0 && 1.0 - s - t > 0.0 {
|
||||||
// dbg!(p);
|
|
||||||
*index_buffer(buf, p) = to_rgb((255, 255, 255));
|
*index_buffer(buf, p) = to_rgb((255, 255, 255));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user