diff options
Diffstat (limited to 'source/blender/blenlib/intern/math_geom.c')
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index ef04e5e9bce..d7880e40626 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2382,6 +2382,38 @@ void accumulate_vertex_normals(float n1[3], float n2[3], float n3[3], } } +/* Add weighted face normal component into normals of the face vertices. + Caller must pass pre-allocated vdiffs of nverts length. */ +void accumulate_vertex_normals_poly(float **vertnos, float polyno[3], + float **vertcos, float vdiffs[][3], int nverts) +{ + int i; + + /* calculate normalized edge directions for each edge in the poly */ + for (i = 0; i < nverts; i++) { + sub_v3_v3v3(vdiffs[i], vertcos[(i+1) % nverts], vertcos[i]); + normalize_v3(vdiffs[i]); + } + + /* accumulate angle weighted face normal */ + { + const float *prev_edge = vdiffs[nverts-1]; + int i; + + for(i=0; i<nverts; i++) { + const float *cur_edge = vdiffs[i]; + + /* calculate angle between the two poly edges incident on + this vertex */ + const float fac= saacos(-dot_v3v3(cur_edge, prev_edge)); + + /* accumulate */ + madd_v3_v3fl(vertnos[i], polyno, fac); + prev_edge = cur_edge; + } + } +} + /********************************* Tangents **********************************/ /* For normal map tangents we need to detect uv boundaries, and only average @@ -3038,3 +3070,26 @@ float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], fl return contrib; } + +/* evaluate if entire quad is a proper convex quad */ + int is_quad_convex_v3(const float *v1, const float *v2, const float *v3, const float *v4) + { + float nor[3], nor1[3], nor2[3], vec[4][2]; + int axis_a, axis_b; + + /* define projection, do both trias apart, quad is undefined! */ + normal_tri_v3(nor1, v1, v2, v3); + normal_tri_v3(nor2, v1, v3, v4); + add_v3_v3v3(nor, nor1, nor2); + + axis_dominant_v3(&axis_a, &axis_b, nor); + + vec[0][0]= v1[axis_a]; vec[0][1]= v1[axis_b]; + vec[1][0]= v2[axis_a]; vec[1][1]= v2[axis_b]; + + vec[2][0]= v3[axis_a]; vec[2][1]= v3[axis_b]; + vec[3][0]= v4[axis_a]; vec[3][1]= v4[axis_b]; + + /* linetests, the 2 diagonals have to instersect to be convex */ + return (isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0) ? 1 : 0; +} |