diff options
author | Luca Rood <dev@lucarood.com> | 2017-01-11 20:15:54 +0300 |
---|---|---|
committer | Luca Rood <dev@lucarood.com> | 2017-01-11 22:55:13 +0300 |
commit | c910beaa2133989150cdafa556ca11ddc9fffc92 (patch) | |
tree | 7cbdfb275a7bd1e37a21c9654c8f56d1edb026c9 | |
parent | 0507b3e4c41ff058c00b7a45d937d82939b4e0d5 (diff) |
Split interp_weights_face_v3 into specific functions for tris and quads
This splits `interp_weights_face_v3` into `interp_weights_tri_v3` and
`interp_weights_quad_v3`, in order to properly handle three sided polygons
without needing a useless extra index in your weight array. This also
improves clarity and consistency with other math_geom functions, thus
reducing potential future errors.
Reviewed By: mont29
Differential Revision: https://developer.blender.org/D2461
-rw-r--r-- | source/blender/blenkernel/intern/collision.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/dynamicpaint.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/smoke.c | 9 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_geom.h | 6 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 51 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 15 | ||||
-rw-r--r-- | source/blender/render/intern/source/occlusion.c | 9 |
7 files changed, 52 insertions, 48 deletions
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 18ca1407ba0..ee25be36855 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1014,7 +1014,7 @@ static bool cloth_points_collision_response_static(ClothModifierData *clmd, Coll } BLI_INLINE bool cloth_point_face_collision_params(const float p1[3], const float p2[3], const float v0[3], const float v1[3], const float v2[3], - float r_nor[3], float *r_lambda, float r_w[4]) + float r_nor[3], float *r_lambda, float r_w[3]) { float edge1[3], edge2[3], p2face[3], p1p2[3], v0p2[3]; float nor_v0p2, nor_p1p2; @@ -1026,7 +1026,7 @@ BLI_INLINE bool cloth_point_face_collision_params(const float p1[3], const float nor_v0p2 = dot_v3v3(v0p2, r_nor); madd_v3_v3v3fl(p2face, p2, r_nor, -nor_v0p2); - interp_weights_face_v3(r_w, v0, v1, v2, NULL, p2face); + interp_weights_tri_v3(r_w, v0, v1, v2, p2face); sub_v3_v3v3(p1p2, p2, p1); sub_v3_v3v3(v0p2, p2, v0); @@ -1085,7 +1085,7 @@ static CollPair *cloth_point_collpair( const float *co1 = mverts[bp1].co, *co2 = mverts[bp2].co, *co3 = mverts[bp3].co; float lambda /*, distance1 */, distance2; float facenor[3], v1p1[3], v1p2[3]; - float w[4]; + float w[3]; if (!cloth_point_face_collision_params(p1, p2, co1, co2, co3, facenor, &lambda, w)) return collpair; diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 4d9e314afc4..1d198e36e05 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -3739,7 +3739,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex( /* velocity brush, only do on main sample */ if (brush->flags & MOD_DPAINT_USES_VELOCITY && ss == 0 && brushVelocity) { - float weights[4]; + float weights[3]; float brushPointVelocity[3]; float velocity[3]; @@ -3748,7 +3748,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex( const int v3 = mloop[mlooptri[hitTri].tri[2]].v; /* calculate barycentric weights for hit point */ - interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, hitCoord); + interp_weights_tri_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, hitCoord); /* simple check based on brush surface velocity, * todo: perhaps implement something that handles volume movement as well */ diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index e8970d416e9..d0ef5cfc092 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -758,15 +758,14 @@ static void obstacles_from_derivedmesh_task_cb(void *userdata, const int z) /* find the nearest point on the mesh */ if (BLI_bvhtree_find_nearest(data->tree->tree, ray_start, &nearest, data->tree->nearest_callback, data->tree) != -1) { const MLoopTri *lt = &data->looptri[nearest.index]; - float weights[4]; + float weights[3]; int v1, v2, v3; /* calculate barycentric weights for nearest point */ v1 = data->mloop[lt->tri[0]].v; v2 = data->mloop[lt->tri[1]].v; v3 = data->mloop[lt->tri[2]].v; - interp_weights_face_v3( - weights, data->mvert[v1].co, data->mvert[v2].co, data->mvert[v3].co, NULL, nearest.co); + interp_weights_tri_v3(weights, data->mvert[v1].co, data->mvert[v2].co, data->mvert[v3].co, nearest.co); // DG TODO if (data->has_velocity) @@ -1454,7 +1453,7 @@ static void sample_derivedmesh( /* find the nearest point on the mesh */ if (BLI_bvhtree_find_nearest(treeData->tree, ray_start, &nearest, treeData->nearest_callback, treeData) != -1) { - float weights[4]; + float weights[3]; int v1, v2, v3, f_index = nearest.index; float n1[3], n2[3], n3[3], hit_normal[3]; @@ -1471,7 +1470,7 @@ static void sample_derivedmesh( v1 = mloop[mlooptri[f_index].tri[0]].v; v2 = mloop[mlooptri[f_index].tri[1]].v; v3 = mloop[mlooptri[f_index].tri[2]].v; - interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); + interp_weights_tri_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, nearest.co); if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && velocity_map) { /* apply normal directional velocity */ diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index b5007b29f4c..d33c2cb3279 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -323,10 +323,8 @@ bool clip_segment_v3_plane_n( float r_p1[3], float r_p2[3]); /****************************** Interpolation ********************************/ - -/* tri or quad, d can be NULL */ -void interp_weights_face_v3(float w[4], - const float a[3], const float b[3], const float c[3], const float d[3], const float p[3]); +void interp_weights_tri_v3(float w[3], const float a[3], const float b[3], const float c[3], const float p[3]); +void interp_weights_quad_v3(float w[4], const float a[3], const float b[3], const float c[3], const float d[3], const float p[3]); void interp_weights_poly_v3(float w[], float v[][3], const int n, const float co[3]); void interp_weights_poly_v2(float w[], float v[][2], const int n, const float co[2]); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 76dac5487f2..74ede1e7559 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2950,7 +2950,15 @@ static bool barycentric_weights(const float v1[3], const float v2[3], const floa } } -void interp_weights_face_v3(float w[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float co[3]) +void interp_weights_tri_v3(float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3]) +{ + float n[3]; + + normal_tri_v3(n, v1, v2, v3); + barycentric_weights(v1, v2, v3, co, n, w); +} + +void interp_weights_quad_v3(float w[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float co[3]) { float w2[3]; @@ -2963,7 +2971,7 @@ void interp_weights_face_v3(float w[4], const float v1[3], const float v2[3], co w[1] = 1.0f; else if (equals_v3v3(co, v3)) w[2] = 1.0f; - else if (v4 && equals_v3v3(co, v4)) + else if (equals_v3v3(co, v4)) w[3] = 1.0f; else { /* otherwise compute barycentric interpolation weights */ @@ -2971,35 +2979,24 @@ void interp_weights_face_v3(float w[4], const float v1[3], const float v2[3], co bool degenerate; sub_v3_v3v3(n1, v1, v3); - if (v4) { - sub_v3_v3v3(n2, v2, v4); - } - else { - sub_v3_v3v3(n2, v2, v3); - } + sub_v3_v3v3(n2, v2, v4); cross_v3_v3v3(n, n1, n2); - /* OpenGL seems to split this way, so we do too */ - if (v4) { - degenerate = barycentric_weights(v1, v2, v4, co, n, w); - SWAP(float, w[2], w[3]); - - if (degenerate || (w[0] < 0.0f)) { - /* if w[1] is negative, co is on the other side of the v1-v3 edge, - * so we interpolate using the other triangle */ - degenerate = barycentric_weights(v2, v3, v4, co, n, w2); - - if (!degenerate) { - w[0] = 0.0f; - w[1] = w2[0]; - w[2] = w2[1]; - w[3] = w2[2]; - } + degenerate = barycentric_weights(v1, v2, v4, co, n, w); + SWAP(float, w[2], w[3]); + + if (degenerate || (w[0] < 0.0f)) { + /* if w[1] is negative, co is on the other side of the v1-v3 edge, + * so we interpolate using the other triangle */ + degenerate = barycentric_weights(v2, v3, v4, co, n, w2); + + if (!degenerate) { + w[0] = 0.0f; + w[1] = w2[0]; + w[2] = w2[1]; + w[3] = w2[2]; } } - else { - barycentric_weights(v1, v2, v3, co, n, w); - } } } diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 86961cdd169..263ea3d4ef2 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -5569,12 +5569,17 @@ static void calculate_speedvectors(Render *re, ObjectInstanceRen *obi, float *ve /* interpolate speed vectors from strand surface */ face= mesh->face[*index]; - co1= mesh->co[face[0]]; - co2= mesh->co[face[1]]; - co3= mesh->co[face[2]]; - co4= (face[3])? mesh->co[face[3]]: NULL; + co1 = mesh->co[face[0]]; + co2 = mesh->co[face[1]]; + co3 = mesh->co[face[2]]; - interp_weights_face_v3(w, co1, co2, co3, co4, strand->vert->co); + if (face[3]) { + co4 = mesh->co[face[3]]; + interp_weights_quad_v3(w, co1, co2, co3, co4, strand->vert->co); + } + else { + interp_weights_tri_v3(w, co1, co2, co3, strand->vert->co); + } zero_v4(speed); madd_v4_v4fl(speed, winspeed[face[0]], w[0]); diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index ddcd2e84520..cd93898d846 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -1190,9 +1190,14 @@ static void sample_occ_surface(ShadeInput *shi) co1 = mesh->co[face[0]]; co2 = mesh->co[face[1]]; co3 = mesh->co[face[2]]; - co4 = (face[3]) ? mesh->co[face[3]] : NULL; - interp_weights_face_v3(w, co1, co2, co3, co4, strand->vert->co); + if (face[3]) { + co4 = mesh->co[face[3]]; + interp_weights_quad_v3(w, co1, co2, co3, co4, strand->vert->co); + } + else { + interp_weights_tri_v3(w, co1, co2, co3, strand->vert->co); + } zero_v3(shi->ao); zero_v3(shi->env); |