static void imapaint_tri_weights(Object *ob, const float v1[3], const float v2[3], const float v3[3], const float co[2], float w[3]) { float pv1[4], pv2[4], pv3[4], h[3], divw; float model[4][4], proj[4][4], wmat[3][3], invwmat[3][3]; GLint view[4]; /* compute barycentric coordinates */ /* get the needed opengl matrices */ glGetIntegerv(GL_VIEWPORT, view); glGetFloatv(GL_MODELVIEW_MATRIX, (float *)model); glGetFloatv(GL_PROJECTION_MATRIX, (float *)proj); view[0] = view[1] = 0; /* project the verts */ imapaint_project(ob, model, proj, v1, pv1); imapaint_project(ob, model, proj, v2, pv2); imapaint_project(ob, model, proj, v3, pv3); /* do inverse view mapping, see gluProject man page */ h[0] = (co[0] - view[0]) * 2.0f / view[2] - 1; h[1] = (co[1] - view[1]) * 2.0f / view[3] - 1; h[2] = 1.0f; /* solve for (w1,w2,w3)/perspdiv in: * h * perspdiv = Project * Model * (w1 * v1 + w2 * v2 + w3 * v3) */ wmat[0][0] = pv1[0]; wmat[1][0] = pv2[0]; wmat[2][0] = pv3[0]; wmat[0][1] = pv1[1]; wmat[1][1] = pv2[1]; wmat[2][1] = pv3[1]; wmat[0][2] = pv1[3]; wmat[1][2] = pv2[3]; wmat[2][2] = pv3[3]; invert_m3_m3(invwmat, wmat); mul_m3_v3(invwmat, h); copy_v3_v3(w, h); /* w is still divided by perspdiv, make it sum to one */ divw = w[0] + w[1] + w[2]; if (divw != 0.0f) { mul_v3_fl(w, 1.0f / divw); } }
static void imapaint_tri_weights(float matrix[4][4], GLint view[4], const float v1[3], const float v2[3], const float v3[3], const float co[2], float w[3]) { float pv1[4], pv2[4], pv3[4], h[3], divw; float wmat[3][3], invwmat[3][3]; /* compute barycentric coordinates */ /* project the verts */ imapaint_project(matrix, v1, pv1); imapaint_project(matrix, v2, pv2); imapaint_project(matrix, v3, pv3); /* do inverse view mapping, see gluProject man page */ h[0] = (co[0] - view[0]) * 2.0f / view[2] - 1.0f; h[1] = (co[1] - view[1]) * 2.0f / view[3] - 1.0f; h[2] = 1.0f; /* solve for (w1,w2,w3)/perspdiv in: * h * perspdiv = Project * Model * (w1 * v1 + w2 * v2 + w3 * v3) */ wmat[0][0] = pv1[0]; wmat[1][0] = pv2[0]; wmat[2][0] = pv3[0]; wmat[0][1] = pv1[1]; wmat[1][1] = pv2[1]; wmat[2][1] = pv3[1]; wmat[0][2] = pv1[3]; wmat[1][2] = pv2[3]; wmat[2][2] = pv3[3]; invert_m3_m3(invwmat, wmat); mul_m3_v3(invwmat, h); copy_v3_v3(w, h); /* w is still divided by perspdiv, make it sum to one */ divw = w[0] + w[1] + w[2]; if (divw != 0.0f) { mul_v3_fl(w, 1.0f / divw); } }