Split interp_weights_face_v3 into specific functions for tris and quads
authorLuca Rood <dev@lucarood.com>
Wed, 11 Jan 2017 17:15:54 +0000 (15:15 -0200)
committerLuca Rood <dev@lucarood.com>
Wed, 11 Jan 2017 19:55:13 +0000 (17:55 -0200)
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

source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/dynamicpaint.c
source/blender/blenkernel/intern/smoke.c
source/blender/blenlib/BLI_math_geom.h
source/blender/blenlib/intern/math_geom.c
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/occlusion.c

index 18ca1407ba06b7f6d5d8062866f964d0d0ddda1a..ee25be368555533097de01492c034b3a5dbb916b 100644 (file)
@@ -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;
index 4d9e314afc4015587961aa39b9973119621b85bc..1d198e36e058d9d2439bcb34272d4bc48a178818 100644 (file)
@@ -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 */
index e8970d416e94f641bf0254c690e04ae921ace225..d0ef5cfc0928ef3939fb5b2f071a82a0b4fd7542 100644 (file)
@@ -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 */
index b5007b29f4c3e7ecc59dab5e6664755e603f76bf..d33c2cb3279e92f41e6d0fc35174aa5beda8b9a2 100644 (file)
@@ -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]);
 
index 76dac5487f279b7131563b87258d047c1d4957ed..74ede1e7559920b4f0be5130af4d1866da93ec9b 100644 (file)
@@ -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);
-               }
        }
 }
 
index 86961cdd169867ed23dc542f324872fea219c1e6..263ea3d4ef26676886a88bb6f58c81d5820a9e9c 100644 (file)
@@ -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]);
index ddcd2e8452059cf73b9d0a2e20d3dc5a2ce78be6..cd93898d8465dcc1a502162e08c81344b275ccb7 100644 (file)
@@ -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);