Fix for bug #8029: heat weighting clamps values below a threshold,

which could give discontinuities, now it does a blend instead.
This commit is contained in:
Brecht Van Lommel 2008-01-29 19:19:21 +00:00
parent 0f8baa98ad
commit e75067e7af

@ -380,7 +380,8 @@ float laplacian_system_get_solution(int v)
Ilya Baran and Jovan Popovic, SIGGRAPH 2007 */ Ilya Baran and Jovan Popovic, SIGGRAPH 2007 */
#define C_WEIGHT 1.0f #define C_WEIGHT 1.0f
#define WEIGHT_LIMIT 0.05f #define WEIGHT_LIMIT_START 0.05f
#define WEIGHT_LIMIT_END 0.025f
#define DISTANCE_EPSILON 1e-4f #define DISTANCE_EPSILON 1e-4f
/* Raytracing for vertex to bone visibility */ /* Raytracing for vertex to bone visibility */
@ -601,6 +602,21 @@ static void heat_laplacian_create(LaplacianSystem *sys)
heat_set_H(sys, a); heat_set_H(sys, a);
} }
static float heat_limit_weight(float weight)
{
float t;
if(weight < WEIGHT_LIMIT_END) {
return 0.0f;
}
else if(weight < WEIGHT_LIMIT_START) {
t= (weight - WEIGHT_LIMIT_END)/(WEIGHT_LIMIT_START - WEIGHT_LIMIT_END);
return t*WEIGHT_LIMIT_START;
}
else
return weight;
}
void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected) void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected)
{ {
LaplacianSystem *sys; LaplacianSystem *sys;
@ -673,8 +689,9 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones,
WEIGHT_ADD); WEIGHT_ADD);
} }
else { else {
if(solution > WEIGHT_LIMIT) weight= heat_limit_weight(solution);
add_vert_to_defgroup(ob, dgrouplist[j], a, solution, if(weight > 0.0f)
add_vert_to_defgroup(ob, dgrouplist[j], a, weight,
WEIGHT_REPLACE); WEIGHT_REPLACE);
else else
remove_vert_defgroup(ob, dgrouplist[j], a); remove_vert_defgroup(ob, dgrouplist[j], a);
@ -688,9 +705,10 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones,
solution, WEIGHT_ADD); solution, WEIGHT_ADD);
} }
else { else {
if(solution > WEIGHT_LIMIT) weight= heat_limit_weight(solution);
if(weight > 0.0f)
add_vert_to_defgroup(ob, dgroupflip[j], vertsflipped[a], add_vert_to_defgroup(ob, dgroupflip[j], vertsflipped[a],
solution, WEIGHT_REPLACE); weight, WEIGHT_REPLACE);
else else
remove_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]); remove_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]);
} }
@ -708,12 +726,14 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones,
if(bbone && lastsegment) { if(bbone && lastsegment) {
for(a=0; a<me->totvert; a++) { for(a=0; a<me->totvert; a++) {
weight= get_vert_defgroup(ob, dgrouplist[j], a); weight= get_vert_defgroup(ob, dgrouplist[j], a);
if(weight > 0.0f && weight <= WEIGHT_LIMIT) weight= heat_limit_weight(weight);
if(weight <= 0.0f)
remove_vert_defgroup(ob, dgrouplist[j], a); remove_vert_defgroup(ob, dgrouplist[j], a);
if(vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0) { if(vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0) {
weight= get_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]); weight= get_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]);
if(weight > 0.0f && weight <= WEIGHT_LIMIT) weight= heat_limit_weight(weight);
if(weight <= 0.0f)
remove_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]); remove_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]);
} }
} }