Skip to content

Commit 2a245f4

Browse files
committed
WIP normal weighting
1 parent 366d5e8 commit 2a245f4

File tree

1 file changed

+24
-15
lines changed

1 file changed

+24
-15
lines changed

core/src/geom/mesh.rs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use core::{
77
};
88

99
use crate::{
10-
math::{Linear, Mat4, Point3},
10+
math::{Linear, Mat4, Point3, degs},
1111
render::Model,
1212
};
1313

@@ -35,6 +35,13 @@ pub struct Builder<Attrib = (), Basis = Model> {
3535
pub mesh: Mesh<Attrib, Basis>,
3636
}
3737

38+
#[derive(Copy, Clone, Eq, PartialEq)]
39+
pub enum Weight {
40+
Equal,
41+
Area,
42+
Angle,
43+
}
44+
3845
//
3946
// Inherent impls
4047
//
@@ -205,27 +212,29 @@ impl<A> Builder<A> {
205212
pub fn with_vertex_normals(self) -> Builder<Normal3> {
206213
let Mesh { verts, faces } = self.mesh;
207214

208-
// Compute weighted face normals...
209-
let face_normals = faces.iter().map(|tri| {
210-
// TODO If n-gonal faces are supported some day, the cross
211-
// product is not proportional to area anymore
212-
let [a, b, c] = tri.map(|i| verts[i].pos).0;
213-
(b - a).cross(&(c - a)).to()
214-
});
215-
// ...initialize vertex normals to zero...
215+
// Initialize vertex normals to zero...
216216
let mut verts: Vec<_> = verts
217-
.iter()
217+
.into_iter()
218218
.map(|v| vertex(v.pos, Normal3::zero()))
219219
.collect();
220220
// ...accumulate normals...
221-
for (&Tri(vs), n) in zip(&faces, face_normals) {
222-
for i in vs {
223-
verts[i].attrib += n;
224-
}
221+
for tri in &faces {
222+
let [i, j, k] = tri.0;
223+
let [ab, ac] = tri.map(|i| verts[i]).tangents();
224+
let bc = ac - ab;
225+
let n = ab.cross(&ac).to().normalize_approx();
226+
let a_a = ab.angle(&ac);
227+
let a_b = (-ab).angle(&bc);
228+
let a_c = degs(180.0) - a_a - a_b;
229+
230+
// Angle unit does not matter, the normals get normalized anyway
231+
verts[i].attrib += n; //a_a.to_rads() * n;
232+
verts[j].attrib += n; //a_b.to_rads() * n;
233+
verts[k].attrib += n; //a_c.to_rads() * n;
225234
}
226235
// ...and normalize to unit length.
227236
for v in &mut verts {
228-
v.attrib = v.attrib.normalize();
237+
v.attrib = v.attrib.normalize_or_zero();
229238
}
230239

231240
// No need to sanity check again

0 commit comments

Comments
 (0)