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
This commit is contained in:
parent
0507b3e4c4
commit
c910beaa21
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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]);
|
||||
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)) {
|
||||
/* 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];
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue