fix [#35406] Hair puff brush bug
- puff was interpolating hair that made longer strands cirl up. - also fixed problem with puff-volume option, it was over-accumulating so unselected parts of the hair would have too much offset applied.
This commit is contained in:
@@ -2963,14 +2963,20 @@ static void brush_puff(PEData *data, int point_index)
|
||||
KEY_K;
|
||||
float mat[4][4], imat[4][4];
|
||||
|
||||
float lastco[3], rootco[3] = {0.0f, 0.0f, 0.0f}, co[3], nor[3], kco[3], dco[3], ofs[3] = {0.0f, 0.0f, 0.0f}, fac=0.0f, length=0.0f;
|
||||
int puff_volume = 0;
|
||||
int change= 0;
|
||||
float onor_prev[3]; /* previous normal (particle-space) */
|
||||
float ofs_prev[3]; /* accumulate offset for puff_volume (particle-space) */
|
||||
float co_root[3], no_root[3]; /* root location and normal (global-space) */
|
||||
float co_prev[3], co[3]; /* track key coords as we loop (global-space) */
|
||||
float fac = 0.0f, length_accum = 0.0f;
|
||||
bool puff_volume = false;
|
||||
bool change = false;
|
||||
|
||||
zero_v3(ofs_prev);
|
||||
|
||||
{
|
||||
ParticleEditSettings *pset= PE_settings(data->scene);
|
||||
ParticleBrushData *brush= &pset->brush[pset->brushtype];
|
||||
puff_volume = brush->flag & PE_BRUSH_DATA_PUFF_VOLUME;
|
||||
puff_volume = (brush->flag & PE_BRUSH_DATA_PUFF_VOLUME) != 0;
|
||||
}
|
||||
|
||||
if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
|
||||
@@ -2983,6 +2989,8 @@ static void brush_puff(PEData *data, int point_index)
|
||||
}
|
||||
|
||||
LOOP_KEYS {
|
||||
float kco[3];
|
||||
|
||||
if (k==0) {
|
||||
/* find root coordinate and normal on emitter */
|
||||
copy_v3_v3(co, key->co);
|
||||
@@ -2992,12 +3000,16 @@ static void brush_puff(PEData *data, int point_index)
|
||||
point_index= BLI_kdtree_find_nearest(edit->emitter_field, kco, NULL, NULL);
|
||||
if (point_index == -1) return;
|
||||
|
||||
copy_v3_v3(rootco, co);
|
||||
copy_v3_v3(nor, &edit->emitter_cosnos[point_index*6+3]);
|
||||
mul_mat3_m4_v3(data->ob->obmat, nor); /* normal into worldspace */
|
||||
copy_v3_v3(co_root, co);
|
||||
copy_v3_v3(no_root, &edit->emitter_cosnos[point_index * 6 + 3]);
|
||||
mul_mat3_m4_v3(data->ob->obmat, no_root); /* normal into global-space */
|
||||
normalize_v3(no_root);
|
||||
|
||||
normalize_v3(nor);
|
||||
length= 0.0f;
|
||||
if (puff_volume) {
|
||||
copy_v3_v3(onor_prev, no_root);
|
||||
mul_mat3_m4_v3(imat, onor_prev); /* global-space into particle space */
|
||||
normalize_v3(onor_prev);
|
||||
}
|
||||
|
||||
fac= (float)pow((double)(1.0f - data->dist / data->rad), (double)data->pufffac);
|
||||
fac *= 0.025f;
|
||||
@@ -3007,16 +3019,23 @@ static void brush_puff(PEData *data, int point_index)
|
||||
else {
|
||||
/* compute position as if hair was standing up straight.
|
||||
* */
|
||||
copy_v3_v3(lastco, co);
|
||||
float length;
|
||||
copy_v3_v3(co_prev, co);
|
||||
copy_v3_v3(co, key->co);
|
||||
mul_m4_v3(mat, co);
|
||||
length += len_v3v3(lastco, co);
|
||||
length = len_v3v3(co_prev, co);
|
||||
length_accum += length;
|
||||
|
||||
if ((data->select==0 || (key->flag & PEK_SELECT)) && !(key->flag & PEK_HIDE)) {
|
||||
madd_v3_v3v3fl(kco, rootco, nor, length);
|
||||
float dco[3]; /* delta temp var */
|
||||
|
||||
madd_v3_v3v3fl(kco, co_root, no_root, length_accum);
|
||||
|
||||
/* blend between the current and straight position */
|
||||
sub_v3_v3v3(dco, kco, co);
|
||||
madd_v3_v3fl(co, dco, fac);
|
||||
/* keep the same distance from the root or we get glitches [#35406] */
|
||||
dist_ensure_v3_v3fl(co, co_root, length_accum);
|
||||
|
||||
/* re-use dco to compare before and after translation and add to the offset */
|
||||
copy_v3_v3(dco, key->co);
|
||||
@@ -3026,11 +3045,9 @@ static void brush_puff(PEData *data, int point_index)
|
||||
if (puff_volume) {
|
||||
/* accumulate the total distance moved to apply to unselected
|
||||
* keys that come after */
|
||||
ofs[0] += key->co[0] - dco[0];
|
||||
ofs[1] += key->co[1] - dco[1];
|
||||
ofs[2] += key->co[2] - dco[2];
|
||||
sub_v3_v3v3(ofs_prev, key->co, dco);
|
||||
}
|
||||
change = 1;
|
||||
change = true;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -3040,7 +3057,7 @@ static void brush_puff(PEData *data, int point_index)
|
||||
add_v3_v3(key->co, ofs);
|
||||
#else
|
||||
/* translate (not rotate) the rest of the hair if its not selected */
|
||||
if (ofs[0] || ofs[1] || ofs[2]) {
|
||||
{
|
||||
#if 0 /* kindof works but looks worse then whats below */
|
||||
|
||||
/* Move the unselected point on a vector based on the
|
||||
@@ -3070,11 +3087,18 @@ static void brush_puff(PEData *data, int point_index)
|
||||
mul_mat3_m4_v3(data->ob->obmat, onor); /* normal into worldspace */
|
||||
mul_mat3_m4_v3(imat, onor); /* worldspace into particle space */
|
||||
normalize_v3(onor);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(onor, onor_prev);
|
||||
}
|
||||
|
||||
if (!is_zero_v3(ofs_prev)) {
|
||||
mul_v3_fl(onor, len_v3(ofs_prev));
|
||||
|
||||
mul_v3_fl(onor, len_v3(ofs));
|
||||
add_v3_v3(key->co, onor);
|
||||
}
|
||||
|
||||
copy_v3_v3(onor_prev, onor);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user