Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-01-17 06:20:23 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-01-17 06:20:23 +0400
commitbbe69705a52386ca5b6552d7187b0492b4b2b378 (patch)
tree48fb3e4b70c78b2a31f1c6a0a02e33b09b0113f5 /source/blender/blenkernel/intern/dynamicpaint.c
parent0e0d88605f0ce7422f278c399b913d394bc7f3ca (diff)
parent67b2985cceaf789e1b77d4f70864bf67ee9375c3 (diff)
svn merge ^/trunk/blender -r43420:43436
Diffstat (limited to 'source/blender/blenkernel/intern/dynamicpaint.c')
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c303
1 files changed, 160 insertions, 143 deletions
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index b7acede4b7b..944de316eb1 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -101,9 +101,10 @@ static int neighY[8] = {0,1,1, 1, 0,-1,-1,-1};
#define EFF_MOVEMENT_PER_FRAME 0.05f
/* initial wave time factor */
#define WAVE_TIME_FAC (1.0f/24.f)
-#define WAVE_INIT_SIZE 5.0f
+#define CANVAS_REL_SIZE 5.0f
/* drying limits */
#define MIN_WETNESS 0.001f
+#define MAX_WETNESS 5.0f
/* dissolve macro */
#define VALUE_DISSOLVE(VALUE, TIME, SCALE, LOG) (VALUE) = (LOG) ? (VALUE) * (pow(MIN_WETNESS,1.0f/(1.2f*((float)(TIME))/(SCALE)))) : (VALUE) - 1.0f/(TIME)*(SCALE)
@@ -422,15 +423,31 @@ static void blendColors(float t_color[3], float t_alpha, float s_color[3], float
result[3] = f_alpha;
}
-/* assumes source alpha > 0.0f or results NaN colors */
-static void mixColors(float *t_color, float t_alpha, float *s_color, float s_alpha)
+/* Mix two alpha weighed colors by a defined ratio. output is saved at a_color */
+static float mixColors(float a_color[3], float a_weight, float b_color[3], float b_weight, float ratio)
{
- float factor = (s_alpha<t_alpha) ? 1.0f : t_alpha/s_alpha;
+ float weight_ratio, factor;
+ if (b_weight) {
+ /* if first value has no weight just use b_color */
+ if (!a_weight) {
+ copy_v3_v3(a_color, b_color);
+ return b_weight*ratio;
+ }
+ weight_ratio = b_weight/(a_weight+b_weight);
+ }
+ else return a_weight*(1.0f-ratio);
- /* set initial color depending on existing alpha */
- interp_v3_v3v3(t_color, s_color, t_color, factor);
+ /* calculate final interpolation factor */
+ if (ratio<=0.5f) {
+ factor = weight_ratio*(ratio*2.0f);
+ }
+ else {
+ ratio = (ratio*2.0f - 1.0f);
+ factor = weight_ratio*(1.0f-ratio) + ratio;
+ }
/* mix final color */
- interp_v3_v3v3(t_color, t_color, s_color, s_alpha);
+ interp_v3_v3v3(a_color, a_color, b_color, factor);
+ return (1.0f-factor)*a_weight + factor*b_weight;
}
/* set "ignore cache" flag for all caches on this object */
@@ -617,6 +634,12 @@ static void boundInsert(Bounds3D *b, float point[3])
}
}
+float getSurfaceDimension(PaintSurfaceData *sData)
+{
+ Bounds3D *mb = &sData->bData->mesh_bounds;
+ return MAX3((mb->max[0]-mb->min[0]), (mb->max[1]-mb->min[1]), (mb->max[2]-mb->min[2]));
+}
+
static void freeGrid(PaintSurfaceData *data)
{
PaintBakeData *bData = data->bData;
@@ -959,17 +982,21 @@ struct DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSett
/* Set initial values */
surface->flags = MOD_DPAINT_ANTIALIAS | MOD_DPAINT_MULALPHA | MOD_DPAINT_DRY_LOG | MOD_DPAINT_DISSOLVE_LOG |
- MOD_DPAINT_ACTIVE | MOD_DPAINT_PREVIEW | MOD_DPAINT_OUT1;
+ MOD_DPAINT_ACTIVE | MOD_DPAINT_PREVIEW | MOD_DPAINT_OUT1 | MOD_DPAINT_USE_DRYING;
surface->effect = 0;
surface->effect_ui = 1;
surface->diss_speed = 250;
surface->dry_speed = 500;
+ surface->color_dry_threshold = 1.0f;
surface->depth_clamp = 0.0f;
surface->disp_factor = 1.0f;
surface->disp_type = MOD_DPAINT_DISP_DISPLACE;
surface->image_fileformat = MOD_DPAINT_IMGFORMAT_PNG;
+ surface->influence_scale = 1.0f;
+ surface->radius_scale = 1.0f;
+
surface->init_color[0] = 1.0f;
surface->init_color[1] = 1.0f;
surface->init_color[2] = 1.0f;
@@ -1508,7 +1535,7 @@ static int dynamicPaint_checkSurfaceData(DynamicPaintSurface *surface)
/* apply displacing vertex surface to the derived mesh */
-static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, DerivedMesh *result, int update_normals)
+static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, DerivedMesh *result)
{
PaintSurfaceData *sData = surface->data;
@@ -1531,10 +1558,6 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Deri
mvert[i].co[2] -= normal[2]*val;
}
}
- else return;
-
- if (update_normals)
- CDDM_calc_normals_mapping(result);
}
/*
@@ -1549,6 +1572,7 @@ static struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData
if(pmd->canvas && !(pmd->canvas->flags & MOD_DPAINT_BAKING)) {
DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
+ int update_normals = 0;
pmd->canvas->flags &= ~MOD_DPAINT_PREVIEW_READY;
/* loop through surfaces */
@@ -1742,14 +1766,20 @@ static struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData
normal_short_to_float_v3(normal, mvert[i].no);
madd_v3_v3fl(mvert[i].co, normal, wPoint[i].height);
}
- CDDM_calc_normals_mapping(result);
+ update_normals = 1;
}
/* displace */
- dynamicPaint_applySurfaceDisplace(surface, result, 1);
+ if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
+ dynamicPaint_applySurfaceDisplace(surface, result);
+ update_normals = 1;
+ }
}
}
}
+
+ if (update_normals)
+ CDDM_calc_normals_mapping(result);
}
/* make a copy of dm to use as brush data */
if (pmd->brush) {
@@ -2568,14 +2598,8 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char* filenam
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
PaintPoint *point = &((PaintPoint*)sData->type_data)[index];
- ibuf->rect_float[pos] = point->color[0];
- ibuf->rect_float[pos+1] = point->color[1];
- ibuf->rect_float[pos+2] = point->color[2];
- /* mix wet layer */
- if (point->e_alpha) mixColors(&ibuf->rect_float[pos], point->alpha, point->e_color, point->e_alpha);
-
- /* use highest alpha */
- ibuf->rect_float[pos+3] = (point->e_alpha > point->alpha) ? point->e_alpha : point->alpha;
+ /* blend wet and dry layers */
+ blendColors(point->color, point->alpha, point->e_color, point->e_alpha, &ibuf->rect_float[pos]);
/* Multiply color by alpha if enabled */
if (surface->flags & MOD_DPAINT_MULALPHA) {
@@ -2906,7 +2930,13 @@ static void dynamicPaint_updatePointData(DynamicPaintSurface *surface, unsigned
float paint[3], float influence, float depth, float vel_factor, float timescale)
{
PaintSurfaceData *sData = surface->data;
- float strength = influence * brush->alpha;
+ float strength;
+
+ /* apply influence scale */
+ influence *= surface->influence_scale;
+ depth *= surface->influence_scale;
+
+ strength = influence * brush->alpha;
CLAMP(strength, 0.0f, 1.0f);
/* Sample velocity colorband if required */
@@ -2985,12 +3015,12 @@ static void dynamicPaint_updatePointData(DynamicPaintSurface *surface, unsigned
}
/* checks whether surface and brush bounds intersect depending on brush type */
-static int meshBrush_boundsIntersect(Bounds3D *b1, Bounds3D *b2, DynamicPaintBrushSettings *brush)
+static int meshBrush_boundsIntersect(Bounds3D *b1, Bounds3D *b2, DynamicPaintBrushSettings *brush, float brush_radius)
{
if (brush->collision == MOD_DPAINT_COL_VOLUME)
return boundsIntersect(b1, b2);
else if (brush->collision == MOD_DPAINT_COL_DIST || brush->collision == MOD_DPAINT_COL_VOLDIST)
- return boundsIntersectDist(b1, b2, brush->paint_distance);
+ return boundsIntersectDist(b1, b2, brush_radius);
else return 1;
}
@@ -3117,6 +3147,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
{
BVHTreeFromMesh treeData = {0};
float avg_brushNor[3] = {0.0f};
+ float brush_radius = brush->paint_distance * surface->radius_scale;
int numOfVerts;
int ii;
Bounds3D mesh_bb = {0};
@@ -3155,7 +3186,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
}
/* check bounding box collision */
- if(grid && meshBrush_boundsIntersect(&grid->grid_bounds, &mesh_bb, brush))
+ if(grid && meshBrush_boundsIntersect(&grid->grid_bounds, &mesh_bb, brush, brush_radius))
/* Build a bvh tree from transformed vertices */
if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 8))
{
@@ -3167,7 +3198,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
int id;
/* check grid cell bounding box */
- if (!grid->s_num[c_index] || !meshBrush_boundsIntersect(&grid->bounds[c_index], &mesh_bb, brush))
+ if (!grid->s_num[c_index] || !meshBrush_boundsIntersect(&grid->bounds[c_index], &mesh_bb, brush, brush_radius))
continue;
/* loop through cell points and process brush */
@@ -3228,7 +3259,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
hit.index = -1;
hit.dist = 9999;
nearest.index = -1;
- nearest.dist = brush->paint_distance * brush->paint_distance; /* find_nearest uses squared distance */
+ nearest.dist = brush_radius * brush_radius; /* find_nearest uses squared distance */
/* Check volume collision */
if (brush->collision == MOD_DPAINT_COL_VOLUME || brush->collision == MOD_DPAINT_COL_VOLDIST)
@@ -3288,7 +3319,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
/* If pure distance proximity, find the nearest point on the mesh */
if (brush->collision != MOD_DPAINT_COL_DIST || !(brush->flags & MOD_DPAINT_PROX_PROJECT)) {
if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, mesh_faces_nearest_point_dp, &treeData) != -1) {
- proxDist = sqrt(nearest.dist);
+ proxDist = sqrtf(nearest.dist);
copy_v3_v3(hitCo, nearest.co);
hQuad = (nearest.no[0] == 1.0f);
face = nearest.index;
@@ -3308,7 +3339,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
proj_ray[2] = 1.0f;
}
hit.index = -1;
- hit.dist = brush->paint_distance;
+ hit.dist = brush_radius;
/* Do a face normal directional raycast, and use that distance */
if(BLI_bvhtree_ray_cast(treeData.tree, ray_start, proj_ray, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData) != -1)
@@ -3321,8 +3352,8 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
}
/* If a hit was found, calculate required values */
- if (proxDist >= 0.0f && proxDist <= brush->paint_distance) {
- proximity_factor = proxDist / brush->paint_distance;
+ if (proxDist >= 0.0f && proxDist <= brush_radius) {
+ proximity_factor = proxDist / brush_radius;
CLAMP(proximity_factor, 0.0f, 1.0f);
if (!inner_proximity)
proximity_factor = 1.0f - proximity_factor;
@@ -3508,8 +3539,8 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
int invalidParticles = 0;
int p = 0;
- float solidradius = (brush->flags & MOD_DPAINT_PART_RAD) ? psys->part->size : brush->particle_radius;
- float smooth = brush->particle_smooth;
+ float solidradius = surface->radius_scale*((brush->flags & MOD_DPAINT_PART_RAD) ? psys->part->size : brush->particle_radius);
+ float smooth = brush->particle_smooth*surface->radius_scale;
float range = solidradius + smooth;
float particle_timestep = 0.04f * part->timetweak;
@@ -3738,6 +3769,7 @@ static int dynamicPaint_paintSinglePoint(DynamicPaintSurface *surface, float *po
Object *brushOb, BrushMaterials *bMats, Scene *scene, float timescale)
{
int index;
+ float brush_radius = brush->paint_distance * surface->radius_scale;
PaintSurfaceData *sData = surface->data;
PaintBakeData *bData = sData->bData;
Vec3f brushVel;
@@ -3755,13 +3787,13 @@ static int dynamicPaint_paintSinglePoint(DynamicPaintSurface *surface, float *po
float colorband[4] = {0.0f};
float strength;
- if (distance>brush->paint_distance) continue;
+ if (distance > brush_radius) continue;
/* Smooth range or color ramp */
if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH ||
brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP) {
- strength = 1.0f - distance / brush->paint_distance;
+ strength = 1.0f - distance / brush_radius;
CLAMP(strength, 0.0f, 1.0f);
}
else strength = 1.0f;
@@ -3826,8 +3858,8 @@ static int dynamicPaint_paintSinglePoint(DynamicPaintSurface *surface, float *po
else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
/* get displace depth */
- float disp_intersect = (1.0f - sqrtf((brush->paint_distance-distance) / brush->paint_distance)) * brush->paint_distance;
- depth = (brush->paint_distance - disp_intersect) / bData->bNormal[index].normal_scale;
+ float disp_intersect = (1.0f - sqrtf((brush_radius-distance) / brush_radius)) * brush_radius;
+ depth = (brush_radius - disp_intersect) / bData->bNormal[index].normal_scale;
if (depth<0.0f) depth = 0.0f;
}
dynamicPaint_updatePointData(surface, index, brush, paintColor, strength, depth, velocity_val, timescale);
@@ -3930,7 +3962,7 @@ void surface_determineForceTargetPoints(PaintSurfaceData *sData, int index, floa
if (closest_id[1] != -1) {
float force_proj[3];
float tangent[3];
- float neigh_diff = acos(dot_v3v3(bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir));
+ float neigh_diff = acosf(dot_v3v3(bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir));
float force_intersect;
float temp;
@@ -4002,7 +4034,6 @@ static void dynamicPaint_doSmudge(DynamicPaintSurface *surface, DynamicPaintBrus
if (n_index != -1 && closest_d[i]>0.0f) {
float dir_dot = closest_d[i], dir_factor;
float speed_scale = eff_scale*smudge_str/bNeighs[n_index].dist;
- float mix;
PaintPoint *ePoint = &((PaintPoint*)sData->type_data)[sData->adj_data->n_target[n_index]];
/* just skip if angle is too extreme */
@@ -4012,13 +4043,11 @@ static void dynamicPaint_doSmudge(DynamicPaintSurface *surface, DynamicPaintBrus
if (dir_factor > brush->smudge_strength) dir_factor = brush->smudge_strength;
/* mix new color and alpha */
- mix = dir_factor*pPoint->alpha;
- if (mix) mixColors(ePoint->color, ePoint->alpha, pPoint->color, mix);
+ mixColors(ePoint->color, ePoint->alpha, pPoint->color, pPoint->alpha, dir_factor);
ePoint->alpha = ePoint->alpha*(1.0f-dir_factor) + pPoint->alpha*dir_factor;
/* smudge "wet layer" */
- mix = dir_factor*pPoint->e_alpha;
- if (mix) mixColors(ePoint->e_color, ePoint->e_alpha, pPoint->e_color, mix);
+ mixColors(ePoint->e_color, ePoint->e_alpha, pPoint->e_color, pPoint->e_alpha, dir_factor);
ePoint->e_alpha = ePoint->e_alpha*(1.0f-dir_factor) + pPoint->e_alpha*dir_factor;
pPoint->wetness *= (1.0f-dir_factor);
}
@@ -4035,7 +4064,7 @@ static int dynamicPaint_prepareEffectStep(DynamicPaintSurface *surface, Scene *s
{
double average_force = 0.0f;
float shrink_speed=0.0f, spread_speed=0.0f;
- float fastest_effect;
+ float fastest_effect, avg_dist;
int steps;
PaintSurfaceData *sData = surface->data;
PaintBakeData *bData = sData->bData;
@@ -4112,9 +4141,10 @@ static int dynamicPaint_prepareEffectStep(DynamicPaintSurface *surface, Scene *s
shrink_speed = surface->shrink_speed;
fastest_effect = MAX3(spread_speed, shrink_speed, average_force);
+ avg_dist = bData->average_dist*CANVAS_REL_SIZE/getSurfaceDimension(sData);
- steps = (int)ceil(1.5f*EFF_MOVEMENT_PER_FRAME*fastest_effect/bData->average_dist*timescale);
- CLAMP(steps, 1, 14);
+ steps = (int)ceil(1.5f*EFF_MOVEMENT_PER_FRAME*fastest_effect/avg_dist*timescale);
+ CLAMP(steps, 1, 20);
return steps;
}
@@ -4126,6 +4156,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
{
PaintSurfaceData *sData = surface->data;
BakeNeighPoint *bNeighs = sData->bData->bNeighs;
+ float distance_scale = getSurfaceDimension(sData)/CANVAS_REL_SIZE;
int index;
timescale /= steps;
@@ -4135,7 +4166,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
* Spread Effect
*/
if (surface->effect & MOD_DPAINT_EFFECT_DO_SPREAD) {
- float eff_scale = EFF_MOVEMENT_PER_FRAME*surface->spread_speed*timescale;
+ float eff_scale = distance_scale*EFF_MOVEMENT_PER_FRAME*surface->spread_speed*timescale;
/* Copy current surface to the previous points array to read unmodified values */
memcpy(prevPoint, sData->type_data, sData->total_points*sizeof(struct PaintPoint));
@@ -4145,7 +4176,6 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
{
int i;
int numOfNeighs = sData->adj_data->n_num[index];
- float totalAlpha = 0.0f;
PaintPoint *pPoint = &((PaintPoint*)sData->type_data)[index];
/* Only reads values from the surface copy (prevPoint[]),
@@ -4154,39 +4184,23 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
/* Loop through neighbouring points */
for (i=0; i<numOfNeighs; i++) {
int n_index = sData->adj_data->n_index[index]+i;
- float w_factor, alphaAdd = 0.0f;
+ float w_factor /* , p_alpha = pPoint->e_alpha */ /* UNUSED */;
PaintPoint *ePoint = &prevPoint[sData->adj_data->n_target[n_index]];
float speed_scale = (bNeighs[n_index].dist<eff_scale) ? 1.0f : eff_scale/bNeighs[n_index].dist;
- float color_mix = (MIN2(ePoint->wetness, pPoint->wetness))*0.25f*surface->color_spread_speed;
-
- totalAlpha += ePoint->e_alpha;
+ float color_mix = (MIN3(ePoint->wetness, pPoint->wetness, 1.0f))*0.25f*surface->color_spread_speed;
/* do color mixing */
- if (color_mix > MIN_WETNESS) mixColors(pPoint->e_color, pPoint->e_alpha, ePoint->e_color, color_mix);
-
- /* Check if neighbouring point has higher wetness,
- * if so, add it's wetness to this point as well*/
- if (ePoint->wetness <= pPoint->wetness) continue;
- w_factor = ePoint->wetness/numOfNeighs * (ePoint->wetness - pPoint->wetness) * speed_scale;
- if (w_factor <= MIN_WETNESS) continue;
-
- if (ePoint->e_alpha > pPoint->e_alpha) {
- alphaAdd = ePoint->e_alpha/numOfNeighs * (ePoint->wetness*ePoint->e_alpha - pPoint->wetness*pPoint->e_alpha) * speed_scale;
- }
-
- /* mix new color */
- mixColors(pPoint->e_color, pPoint->e_alpha, ePoint->e_color, w_factor);
+ if (color_mix) mixColors(pPoint->e_color, pPoint->e_alpha, ePoint->e_color, ePoint->e_alpha, color_mix);
- pPoint->e_alpha += alphaAdd;
- pPoint->wetness += w_factor;
+ /* Only continue if surrounding point has higher wetness */
+ if (ePoint->wetness<pPoint->wetness || ePoint->wetness<MIN_WETNESS) continue;
- if (pPoint->e_alpha > 1.0f) pPoint->e_alpha = 1.0f;
- }
+ w_factor = 1.0f/numOfNeighs * MIN2(ePoint->wetness, 1.0f) * speed_scale;
+ CLAMP(w_factor, 0.0f, 1.0f);
- /* For antialiasing sake, don't let alpha go much higher than average alpha of neighbours */
- if (pPoint->e_alpha > (totalAlpha/numOfNeighs+0.25f)) {
- pPoint->e_alpha = (totalAlpha/numOfNeighs+0.25f);
- if (pPoint->e_alpha>1.0f) pPoint->e_alpha = 1.0f;
+ /* mix new wetness and color */
+ pPoint->wetness = (1.0f-w_factor)*pPoint->wetness + w_factor*ePoint->wetness;
+ pPoint->e_alpha = mixColors(pPoint->e_color, pPoint->e_alpha, ePoint->e_color, ePoint->e_alpha, w_factor);
}
}
}
@@ -4195,7 +4209,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
* Shrink Effect
*/
if (surface->effect & MOD_DPAINT_EFFECT_DO_SHRINK) {
- float eff_scale = EFF_MOVEMENT_PER_FRAME*surface->shrink_speed*timescale;
+ float eff_scale = distance_scale*EFF_MOVEMENT_PER_FRAME*surface->shrink_speed*timescale;
/* Copy current surface to the previous points array to read unmodified values */
memcpy(prevPoint, sData->type_data, sData->total_points*sizeof(struct PaintPoint));
@@ -4245,7 +4259,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
*/
if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP && force)
{
- float eff_scale = EFF_MOVEMENT_PER_FRAME*timescale/2.0f;
+ float eff_scale = distance_scale*EFF_MOVEMENT_PER_FRAME*timescale/2.0f;
/* Copy current surface to the previous points array to read unmodified values */
memcpy(prevPoint, sData->type_data, sData->total_points*sizeof(struct PaintPoint));
@@ -4258,8 +4272,9 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
float closest_d[2];
/* adjust drip speed depending on wetness */
- float w_factor = pPoint_prev->wetness*0.5f - 0.025f;
+ float w_factor = pPoint_prev->wetness - 0.025f;
if (w_factor <= 0) continue;
+ CLAMP(w_factor, 0.0f, 1.0f);
/* get force affect points */
surface_determineForceTargetPoints(sData, index, &force[index*4], closest_d, closest_id);
@@ -4268,41 +4283,38 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
for (i=0; i<2; i++) {
int n_index = closest_id[i];
if (n_index != -1 && closest_d[i]>0.0f) {
- float dir_dot = closest_d[i], dir_factor;
+ float dir_dot = closest_d[i], dir_factor, a_factor;
float speed_scale = eff_scale*force[index*4+3]/bNeighs[n_index].dist;
PaintPoint *ePoint = &((PaintPoint*)sData->type_data)[sData->adj_data->n_target[n_index]];
+ float e_wet = ePoint->wetness;
/* just skip if angle is too extreme */
if (dir_dot <= 0.0f) continue;
- dir_factor = dir_dot * speed_scale * w_factor;
- if (dir_factor > (0.5f/steps)) dir_factor = (0.5f/steps);
-
- /* mix new color */
- if (dir_factor) mixColors(ePoint->e_color, ePoint->e_alpha, pPoint->e_color, dir_factor);
+ dir_factor = dir_dot * MIN2(speed_scale, 1.0f) * w_factor;
+ if (dir_factor > 0.5f) dir_factor = 0.5f;
- ePoint->e_alpha += dir_factor;
+ /* mix new wetness*/
ePoint->wetness += dir_factor;
- if (ePoint->e_alpha > 1.0f) ePoint->e_alpha = 1.0f;
+ CLAMP(ePoint->wetness, 0.0f, MAX_WETNESS);
+
+ /* mix new color */
+ a_factor = dir_factor / pPoint_prev->wetness;
+ CLAMP(a_factor, 0.0f, 1.0f);
+ mixColors(ePoint->e_color, ePoint->e_alpha, pPoint_prev->e_color, pPoint_prev->e_alpha, a_factor);
+ /* dripping is supposed to preserve alpha level */
+ if (pPoint_prev->e_alpha > ePoint->e_alpha) {
+ ePoint->e_alpha += a_factor * pPoint_prev->e_alpha;
+ if (ePoint->e_alpha > pPoint_prev->e_alpha)
+ ePoint->e_alpha = pPoint_prev->e_alpha;
+ }
- /* and decrease paint wetness on current point */
- pPoint->wetness -= dir_factor;
+ /* decrease paint wetness on current point */
+ pPoint->wetness -= (ePoint->wetness - e_wet);
+ CLAMP(pPoint->wetness, 0.0f, MAX_WETNESS);
}
}
}
-
- /* Keep values within acceptable range */
- #pragma omp parallel for schedule(static)
- for (index = 0; index < sData->total_points; index++)
- {
- PaintPoint *cPoint = &((PaintPoint*)sData->type_data)[index];
-
- if (cPoint->e_alpha > 1.0f) cPoint->e_alpha=1.0f;
- if (cPoint->wetness > 2.0f) cPoint->wetness=2.0f;
-
- if (cPoint->e_alpha < 0.0f) cPoint->e_alpha=0.0f;
- if (cPoint->wetness < 0.0f) cPoint->wetness=0.0f;
- }
}
}
@@ -4317,7 +4329,7 @@ void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescale)
double average_dist = 0.0f;
Bounds3D *mb = &sData->bData->mesh_bounds;
float canvas_size = MAX3((mb->max[0]-mb->min[0]), (mb->max[1]-mb->min[1]), (mb->max[2]-mb->min[2]));
- float wave_scale = WAVE_INIT_SIZE/canvas_size;
+ float wave_scale = CANVAS_REL_SIZE/canvas_size;
/* allocate memory */
PaintWavePoint *prevPoint = MEM_mallocN(sData->total_points*sizeof(PaintWavePoint), "Temp previous points for wave simulation");
@@ -4430,48 +4442,53 @@ static void dynamicPaint_surfacePreStep(DynamicPaintSurface *surface, float time
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
PaintPoint *pPoint = &((PaintPoint*)sData->type_data)[index];
/* drying */
- if (pPoint->wetness >= MIN_WETNESS) {
- int i;
- float dry_ratio, f_color[4];
- float p_wetness = pPoint->wetness;
- VALUE_DISSOLVE(pPoint->wetness, surface->dry_speed, timescale, (surface->flags & MOD_DPAINT_DRY_LOG));
- if (pPoint->wetness<0.0f) pPoint->wetness=0.0f;
- dry_ratio = pPoint->wetness/p_wetness;
+ if (surface->flags & MOD_DPAINT_USE_DRYING) {
+ if (pPoint->wetness >= MIN_WETNESS) {
+ int i;
+ float dry_ratio, f_color[4];
+ float p_wetness = pPoint->wetness;
+ VALUE_DISSOLVE(pPoint->wetness, surface->dry_speed, timescale, (surface->flags & MOD_DPAINT_DRY_LOG));
+ if (pPoint->wetness<0.0f) pPoint->wetness=0.0f;
- /*
- * Slowly "shift" paint from wet layer to dry layer as it drys:
- */
- /* make sure alpha values are within proper range */
- CLAMP(pPoint->alpha, 0.0f, 1.0f);
- CLAMP(pPoint->e_alpha, 0.0f, 1.0f);
-
- /* get current final blended color of these layers */
- blendColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha, f_color);
- /* reduce wet layer alpha by dry factor */
- pPoint->e_alpha *= dry_ratio;
-
- /* now calculate new alpha for dry layer that keeps final blended color unchanged */
- pPoint->alpha = (f_color[3] - pPoint->e_alpha)/(1.0f-pPoint->e_alpha);
- /* for each rgb component, calculate a new dry layer color that keeps the final blend color
- * with these new alpha values. (wet layer color doesnt change)*/
- if (pPoint->alpha) {
- for (i=0; i<3; i++) {
- pPoint->color[i] = (f_color[i]*f_color[3] - pPoint->e_color[i]*pPoint->e_alpha)/(pPoint->alpha*(1.0f-pPoint->e_alpha));
+ if (pPoint->wetness < surface->color_dry_threshold) {
+ dry_ratio = pPoint->wetness/p_wetness;
+
+ /*
+ * Slowly "shift" paint from wet layer to dry layer as it drys:
+ */
+ /* make sure alpha values are within proper range */
+ CLAMP(pPoint->alpha, 0.0f, 1.0f);
+ CLAMP(pPoint->e_alpha, 0.0f, 1.0f);
+
+ /* get current final blended color of these layers */
+ blendColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha, f_color);
+ /* reduce wet layer alpha by dry factor */
+ pPoint->e_alpha *= dry_ratio;
+
+ /* now calculate new alpha for dry layer that keeps final blended color unchanged */
+ pPoint->alpha = (f_color[3] - pPoint->e_alpha)/(1.0f-pPoint->e_alpha);
+ /* for each rgb component, calculate a new dry layer color that keeps the final blend color
+ * with these new alpha values. (wet layer color doesnt change)*/
+ if (pPoint->alpha) {
+ for (i=0; i<3; i++) {
+ pPoint->color[i] = (f_color[i]*f_color[3] - pPoint->e_color[i]*pPoint->e_alpha)/(pPoint->alpha*(1.0f-pPoint->e_alpha));
+ }
+ }
}
- }
- pPoint->state = DPAINT_PAINT_WET;
- }
- /* in case of just dryed paint, just mix it to the dry layer and mark it empty */
- else if (pPoint->state > 0) {
- float f_color[4];
- blendColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha, f_color);
- copy_v3_v3(pPoint->color, f_color);
- pPoint->alpha = f_color[3];
- /* clear wet layer */
- pPoint->wetness = 0.0f;
- pPoint->e_alpha = 0.0f;
- pPoint->state = DPAINT_PAINT_DRY;
+ pPoint->state = DPAINT_PAINT_WET;
+ }
+ /* in case of just dryed paint, just mix it to the dry layer and mark it empty */
+ else if (pPoint->state > 0) {
+ float f_color[4];
+ blendColors(pPoint->color, pPoint->alpha, pPoint->e_color, pPoint->e_alpha, f_color);
+ copy_v3_v3(pPoint->color, f_color);
+ pPoint->alpha = f_color[3];
+ /* clear wet layer */
+ pPoint->wetness = 0.0f;
+ pPoint->e_alpha = 0.0f;
+ pPoint->state = DPAINT_PAINT_DRY;
+ }
}
if (surface->flags & MOD_DPAINT_DISSOLVE) {
@@ -4919,7 +4936,7 @@ int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Scene *scene, Obje
/* apply previous displace on derivedmesh if incremental surface */
if (surface->flags & MOD_DPAINT_DISP_INCREMENTAL)
- dynamicPaint_applySurfaceDisplace(surface, surface->canvas->dm, 0);
+ dynamicPaint_applySurfaceDisplace(surface, surface->canvas->dm);
/* update bake data */
dynamicPaint_generateBakeData(surface, scene, cObject);