@@ -7,7 +7,7 @@ use core::{
77} ;
88
99use 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