static void do_huecorrect(bNode *node, float *out, float *in) { float hsv[3], f; rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2); /* adjust hue, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(node->storage, 0, hsv[0]); hsv[0] += f-0.5f; /* adjust saturation, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(node->storage, 1, hsv[0]); hsv[1] *= (f * 2.f); /* adjust value, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(node->storage, 2, hsv[0]); hsv[2] *= (f * 2.f); hsv[0] = hsv[0] - floor(hsv[0]); /* mod 1.0 */ CLAMP(hsv[1], 0.f, 1.f); /* convert back to rgb */ hsv_to_rgb(hsv[0], hsv[1], hsv[2], out, out+1, out+2); out[3]= in[3]; }
static void do_huecorrect_fac(bNode *node, float *out, float *in, float *fac) { float hsv[3], rgb[3], f; const float mfac = 1.f-*fac; rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2); /* adjust hue, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(node->storage, 0, hsv[0]); hsv[0] += f-0.5f; /* adjust saturation, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(node->storage, 1, hsv[0]); hsv[1] *= (f * 2.f); /* adjust value, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(node->storage, 2, hsv[0]); hsv[2] *= (f * 2.f); hsv[0] = hsv[0] - floor(hsv[0]); /* mod 1.0 */ CLAMP(hsv[1], 0.f, 1.f); /* convert back to rgb */ hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); out[0]= mfac*in[0] + *fac*rgb[0]; out[1]= mfac*in[1] + *fac*rgb[1]; out[2]= mfac*in[2] + *fac*rgb[2]; out[3]= in[3]; }
void HueSaturationValueCorrectOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float hsv[4], f; this->m_inputProgram->readSampled(hsv, x, y, sampler); /* adjust hue, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(this->m_curveMapping, 0, hsv[0]); hsv[0] += f - 0.5f; /* adjust saturation, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(this->m_curveMapping, 1, hsv[0]); hsv[1] *= (f * 2.0f); /* adjust value, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(this->m_curveMapping, 2, hsv[0]); hsv[2] *= (f * 2.0f); hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */ CLAMP(hsv[1], 0.0f, 1.0f); output[0] = hsv[0]; output[1] = hsv[1]; output[2] = hsv[2]; output[3] = hsv[3]; }
static void hue_correct_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, float *mask_rect_float, void *data_v) { CurveMapping *curve_mapping = (CurveMapping *) data_v; int x, y; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { int pixel_index = (y * width + x) * 4; float pixel[3], result[3], mask[3] = {1.0f, 1.0f, 1.0f}; float hsv[3], f; if (rect_float) copy_v3_v3(pixel, rect_float + pixel_index); else rgb_uchar_to_float(pixel, rect + pixel_index); rgb_to_hsv(pixel[0], pixel[1], pixel[2], hsv, hsv + 1, hsv + 2); /* adjust hue, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(curve_mapping, 0, hsv[0]); hsv[0] += f - 0.5f; /* adjust saturation, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(curve_mapping, 1, hsv[0]); hsv[1] *= (f * 2.0f); /* adjust value, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(curve_mapping, 2, hsv[0]); hsv[2] *= (f * 2.f); hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */ CLAMP(hsv[1], 0.0f, 1.0f); /* convert back to rgb */ hsv_to_rgb(hsv[0], hsv[1], hsv[2], result, result + 1, result + 2); if (mask_rect_float) copy_v3_v3(mask, mask_rect_float + pixel_index); else if (mask_rect) rgb_uchar_to_float(mask, mask_rect + pixel_index); result[0] = pixel[0] * (1.0f - mask[0]) + result[0] * mask[0]; result[1] = pixel[1] * (1.0f - mask[1]) + result[1] * mask[1]; result[2] = pixel[2] * (1.0f - mask[2]) + result[2] * mask[2]; if (rect_float) copy_v3_v3(rect_float + pixel_index, result); else rgb_float_to_uchar(rect + pixel_index, result); } } }
static PyObject *Freestyle_evaluateCurveMappingF(PyObject *self, PyObject *args) { BPy_StructRNA *py_srna; CurveMapping *cumap; int cur; float value; if (!(PyArg_ParseTuple(args, "O!if", &pyrna_struct_Type, &py_srna, &cur, &value))) return NULL; if (!RNA_struct_is_a(py_srna->ptr.type, &RNA_CurveMapping)) { PyErr_SetString(PyExc_TypeError, "1st argument is not a CurveMapping object"); return NULL; } if (cur < 0 || cur > 3) { PyErr_SetString(PyExc_ValueError, "2nd argument is out of range"); return NULL; } cumap = (CurveMapping *)py_srna->ptr.data; curvemapping_initialize(cumap); /* disable extrapolation if enabled */ if ((cumap->cm[cur].flag & CUMA_EXTEND_EXTRAPOLATE)) { cumap->cm[cur].flag &= ~(CUMA_EXTEND_EXTRAPOLATE); curvemapping_changed(cumap, 0); } return PyFloat_FromDouble(curvemapping_evaluateF(cumap, cur, value)); }
void TimeNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const { SetValueOperation *operation = new SetValueOperation(); bNode *node = this->getbNode(); /* stack order output: fac */ float fac = 0.0f; const int framenumber = context.getFramenumber(); if (framenumber < node->custom1) { fac = 0.0f; } else if (framenumber > node->custom2) { fac = 1.0f; } else if (node->custom1 < node->custom2) { fac = (context.getFramenumber() - node->custom1) / (float)(node->custom2 - node->custom1); } curvemapping_initialize((CurveMapping *)node->storage); fac = curvemapping_evaluateF((CurveMapping *)node->storage, 0, fac); operation->setValue(clamp_f(fac, 0.0f, 1.0f)); converter.addOperation(operation); converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket()); }
void TimeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { SetValueOperation *operation = new SetValueOperation(); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); bNode *node = this->getbNode(); /* stack order output: fac */ float fac = 0.0f; const int framenumber = context->getFramenumber(); if (framenumber < node->custom1) { fac = 0.0f; } else if (framenumber > node->custom2) { fac = 1.0f; } else if (node->custom1 < node->custom2) { fac = (context->getFramenumber() - node->custom1) / (float)(node->custom2 - node->custom1); } curvemapping_initialize((CurveMapping *)node->storage); fac = curvemapping_evaluateF((CurveMapping *)node->storage, 0, fac); operation->setValue(CLAMPIS(fac, 0.0f, 1.0f)); graph->addOperation(operation); }
static float do_clump_level(float result[3], const float co[3], const float par_co[3], float time, float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve) { float clump = 0.0f; if (clumpcurve) { clump = pa_clump * (1.0f - clamp_f(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f)); interp_v3_v3v3(result, co, par_co, clump); } else if (clumpfac != 0.0f) { float cpow; if (clumppow < 0.0f) cpow = 1.0f + clumppow; else cpow = 1.0f + 9.0f * clumppow; if (clumpfac < 0.0f) /* clump roots instead of tips */ clump = -clumpfac * pa_clump * (float)pow(1.0 - (double)time, (double)cpow); else clump = clumpfac * pa_clump * (float)pow((double)time, (double)cpow); interp_v3_v3v3(result, co, par_co, clump); } return clump; }
/* same as above but can return negative values if the curve enables * used for sculpt only */ float BKE_brush_curve_strength(Brush *br, float p, const float len) { if (p >= len) p = 1.0f; else p = p / len; return curvemapping_evaluateF(br->curve, 0, p); }
/* Uses the brush curve control to find a strength value between 0 and 1 */ float brush_curve_strength_clamp(Brush *br, float p, const float len) { if(p >= len) return 0; else p= p/len; p= curvemapping_evaluateF(br->curve, 0, p); if(p < 0.0f) p= 0.0f; else if(p > 1.0f) p= 1.0f; return p; }
/* Uses the brush curve control to find a strength value */ float BKE_brush_curve_strength(Brush *br, float p, const float len) { float strength; if (p >= len) return 0; else p = p / len; strength = curvemapping_evaluateF(br->curve, 0, p); return strength; }
static void time_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(in), short UNUSED(thread)) { /* stack order output: fac */ float fac= 0.0f; if (node->custom1 < node->custom2) fac = (p->cfra - node->custom1)/(float)(node->custom2-node->custom1); fac = curvemapping_evaluateF(node->storage, 0, fac); out[0] = CLAMPIS(fac, 0.0f, 1.0f); }
static void node_composit_exec_curves_time(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) { RenderData *rd= data; /* stack order output: fac */ float fac= 0.0f; if (node->custom1 < node->custom2) fac= (rd->cfra - node->custom1)/(float)(node->custom2-node->custom1); fac= curvemapping_evaluateF(node->storage, 0, fac); out[0]->vec[0]= CLAMPIS(fac, 0.0f, 1.0f); }
/* Maps new_w weights in place, using either one of the predefined functions, or a custom curve. * Return values are in new_w. * If indices is not NULL, it must be a table of same length as org_w and new_w, mapping to the real * vertex index (in case the weight tables do not cover the whole vertices...). * cmap might be NULL, in which case curve mapping mode will return unmodified data. */ void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cmap, RNG *rng) { int i; /* Return immediately, if we have nothing to do! */ /* Also security checks... */ if (((falloff_type == MOD_WVG_MAPPING_CURVE) && (cmap == NULL)) || !ELEM(falloff_type, MOD_WVG_MAPPING_CURVE, MOD_WVG_MAPPING_SHARP, MOD_WVG_MAPPING_SMOOTH, MOD_WVG_MAPPING_ROOT, MOD_WVG_MAPPING_SPHERE, MOD_WVG_MAPPING_RANDOM, MOD_WVG_MAPPING_STEP)) { return; } if (cmap && falloff_type == MOD_WVG_MAPPING_CURVE) { curvemapping_initialize(cmap); } /* Map each weight (vertex) to its new value, accordingly to the chosen mode. */ for (i = 0; i < num; ++i) { float fac = new_w[i]; /* Code borrowed from the warp modifier. */ /* Closely matches PROP_SMOOTH and similar. */ switch (falloff_type) { case MOD_WVG_MAPPING_CURVE: fac = curvemapping_evaluateF(cmap, 0, fac); break; case MOD_WVG_MAPPING_SHARP: fac = fac * fac; break; case MOD_WVG_MAPPING_SMOOTH: fac = 3.0f * fac * fac - 2.0f * fac * fac * fac; break; case MOD_WVG_MAPPING_ROOT: fac = sqrtf(fac); break; case MOD_WVG_MAPPING_SPHERE: fac = sqrtf(2 * fac - fac * fac); break; case MOD_WVG_MAPPING_RANDOM: fac = BLI_rng_get_float(rng) * fac; break; case MOD_WVG_MAPPING_STEP: fac = (fac >= 0.5f) ? 1.0f : 0.0f; break; } new_w[i] = fac; } }
static float curvemapping_integrate_clamped(CurveMapping *curve, float start, float end, float step) { float integral = 0.0f; float x = start; while (x < end) { float y = curvemapping_evaluateF(curve, 0, x); y = clamp_f(y, 0.0f, 1.0f); /* TODO(sergey): Clamp last step to end. */ integral += y * step; x += step; } return integral; }
static void accum_density(void *userdata, int index, float squared_dist) { PointDensityRangeData *pdr = (PointDensityRangeData *)userdata; const float dist = (pdr->squared_radius - squared_dist) / pdr->squared_radius * 0.5f; float density = 0.0f; if (pdr->point_data_used & POINT_DATA_VEL) { pdr->vec[0] += pdr->point_data[index*3 + 0]; // * density; pdr->vec[1] += pdr->point_data[index*3 + 1]; // * density; pdr->vec[2] += pdr->point_data[index*3 + 2]; // * density; } if (pdr->point_data_used & POINT_DATA_LIFE) { *pdr->age += pdr->point_data[pdr->offset + index]; // * density; } if (pdr->falloff_type == TEX_PD_FALLOFF_STD) density = dist; else if (pdr->falloff_type == TEX_PD_FALLOFF_SMOOTH) density = 3.0f*dist*dist - 2.0f*dist*dist*dist; else if (pdr->falloff_type == TEX_PD_FALLOFF_SOFT) density = pow(dist, pdr->softness); else if (pdr->falloff_type == TEX_PD_FALLOFF_CONSTANT) density = pdr->squared_radius; else if (pdr->falloff_type == TEX_PD_FALLOFF_ROOT) density = sqrtf(dist); else if (pdr->falloff_type == TEX_PD_FALLOFF_PARTICLE_AGE) { if (pdr->point_data_used & POINT_DATA_LIFE) density = dist*MIN2(pdr->point_data[pdr->offset + index], 1.0f); else density = dist; } else if (pdr->falloff_type == TEX_PD_FALLOFF_PARTICLE_VEL) { if (pdr->point_data_used & POINT_DATA_VEL) density = dist*len_v3(pdr->point_data + index*3)*pdr->velscale; else density = dist; } if (pdr->density_curve && dist != 0.0f) { curvemapping_initialize(pdr->density_curve); density = curvemapping_evaluateF(pdr->density_curve, 0, density/dist)*dist; } *pdr->density += density; }
static void do_rough_curve(const float loc[3], float mat[4][4], float time, float fac, float size, CurveMapping *roughcurve, ParticleKey *state) { float rough[3]; float rco[3]; if (!roughcurve) return; fac *= clamp_f(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f); copy_v3_v3(rco, loc); mul_v3_fl(rco, time); rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2); rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2); rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2); madd_v3_v3fl(state->co, mat[0], fac * rough[0]); madd_v3_v3fl(state->co, mat[1], fac * rough[1]); madd_v3_v3fl(state->co, mat[2], fac * rough[2]); }
/* RGB case, no black/white points, no premult */ void curvemapping_evaluateRGBF(CurveMapping *cumap, float vecout[3], const float vecin[3]) { vecout[0] = curvemapping_evaluateF(cumap, 0, curvemapping_evaluateF(cumap, 3, vecin[0])); vecout[1] = curvemapping_evaluateF(cumap, 1, curvemapping_evaluateF(cumap, 3, vecin[1])); vecout[2] = curvemapping_evaluateF(cumap, 2, curvemapping_evaluateF(cumap, 3, vecin[2])); }
/* vector case */ void curvemapping_evaluate3F(CurveMapping *cumap, float *vecout, const float *vecin) { vecout[0]= curvemapping_evaluateF(cumap, 0, vecin[0]); vecout[1]= curvemapping_evaluateF(cumap, 1, vecin[1]); vecout[2]= curvemapping_evaluateF(cumap, 2, vecin[2]); }
static void warpModifier_do(WarpModifierData *wmd, const ModifierEvalContext *ctx, Mesh *mesh, float (*vertexCos)[3], int numVerts) { Object *ob = ctx->object; float obinv[4][4]; float mat_from[4][4]; float mat_from_inv[4][4]; float mat_to[4][4]; float mat_unit[4][4]; float mat_final[4][4]; float tmat[4][4]; const float falloff_radius_sq = SQUARE(wmd->falloff_radius); float strength = wmd->strength; float fac = 1.0f, weight; int i; int defgrp_index; MDeformVert *dvert, *dv = NULL; float(*tex_co)[3] = NULL; if (!(wmd->object_from && wmd->object_to)) { return; } MOD_get_vgroup(ob, mesh, wmd->defgrp_name, &dvert, &defgrp_index); if (dvert == NULL) { defgrp_index = -1; } if (wmd->curfalloff == NULL) { /* should never happen, but bad lib linking could cause it */ wmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); } if (wmd->curfalloff) { curvemapping_initialize(wmd->curfalloff); } invert_m4_m4(obinv, ob->obmat); mul_m4_m4m4(mat_from, obinv, wmd->object_from->obmat); mul_m4_m4m4(mat_to, obinv, wmd->object_to->obmat); invert_m4_m4(tmat, mat_from); // swap? mul_m4_m4m4(mat_final, tmat, mat_to); invert_m4_m4(mat_from_inv, mat_from); unit_m4(mat_unit); if (strength < 0.0f) { float loc[3]; strength = -strength; /* inverted location is not useful, just use the negative */ copy_v3_v3(loc, mat_final[3]); invert_m4(mat_final); negate_v3_v3(mat_final[3], loc); } weight = strength; Tex *tex_target = wmd->texture; if (mesh != NULL && tex_target != NULL) { tex_co = MEM_malloc_arrayN(numVerts, sizeof(*tex_co), "warpModifier_do tex_co"); MOD_get_texture_coords((MappingInfoModifierData *)wmd, ctx, ob, mesh, vertexCos, tex_co); MOD_init_texture((MappingInfoModifierData *)wmd, ctx); } for (i = 0; i < numVerts; i++) { float *co = vertexCos[i]; if (wmd->falloff_type == eWarp_Falloff_None || ((fac = len_squared_v3v3(co, mat_from[3])) < falloff_radius_sq && (fac = (wmd->falloff_radius - sqrtf(fac)) / wmd->falloff_radius))) { /* skip if no vert group found */ if (defgrp_index != -1) { dv = &dvert[i]; weight = defvert_find_weight(dv, defgrp_index) * strength; if (weight <= 0.0f) { continue; } } /* closely match PROP_SMOOTH and similar */ switch (wmd->falloff_type) { case eWarp_Falloff_None: fac = 1.0f; break; case eWarp_Falloff_Curve: fac = curvemapping_evaluateF(wmd->curfalloff, 0, fac); break; case eWarp_Falloff_Sharp: fac = fac * fac; break; case eWarp_Falloff_Smooth: fac = 3.0f * fac * fac - 2.0f * fac * fac * fac; break; case eWarp_Falloff_Root: fac = sqrtf(fac); break; case eWarp_Falloff_Linear: /* pass */ break; case eWarp_Falloff_Const: fac = 1.0f; break; case eWarp_Falloff_Sphere: fac = sqrtf(2 * fac - fac * fac); break; case eWarp_Falloff_InvSquare: fac = fac * (2.0f - fac); break; } fac *= weight; if (tex_co) { struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); TexResult texres; texres.nor = NULL; BKE_texture_get_value(scene, tex_target, tex_co[i], &texres, false); fac *= texres.tin; } if (fac != 0.0f) { /* into the 'from' objects space */ mul_m4_v3(mat_from_inv, co); if (fac == 1.0f) { mul_m4_v3(mat_final, co); } else { if (wmd->flag & MOD_WARP_VOLUME_PRESERVE) { /* interpolate the matrix for nicer locations */ blend_m4_m4m4(tmat, mat_unit, mat_final, fac); mul_m4_v3(tmat, co); } else { float tvec[3]; mul_v3_m4v3(tvec, mat_final, co); interp_v3_v3v3(co, co, tvec, fac); } } /* out of the 'from' objects space */ mul_m4_v3(mat_from, co); } } } if (tex_co) { MEM_freeN(tex_co); } }
static void warpModifier_do(WarpModifierData *wmd, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { float obinv[4][4]; float mat_from[4][4]; float mat_from_inv[4][4]; float mat_to[4][4]; float mat_unit[4][4]; float mat_final[4][4]; float tmat[4][4]; float strength = wmd->strength; float fac = 1.0f, weight; int i; int defgrp_index; MDeformVert *dvert, *dv = NULL; float (*tex_co)[3] = NULL; if (!(wmd->object_from && wmd->object_to)) return; modifier_get_vgroup(ob, dm, wmd->defgrp_name, &dvert, &defgrp_index); if (wmd->curfalloff == NULL) /* should never happen, but bad lib linking could cause it */ wmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); if (wmd->curfalloff) { curvemapping_initialize(wmd->curfalloff); } invert_m4_m4(obinv, ob->obmat); mul_m4_m4m4(mat_from, obinv, wmd->object_from->obmat); mul_m4_m4m4(mat_to, obinv, wmd->object_to->obmat); invert_m4_m4(tmat, mat_from); // swap? mul_m4_m4m4(mat_final, tmat, mat_to); invert_m4_m4(mat_from_inv, mat_from); unit_m4(mat_unit); if (strength < 0.0f) { float loc[3]; strength = -strength; /* inverted location is not useful, just use the negative */ copy_v3_v3(loc, mat_final[3]); invert_m4(mat_final); negate_v3_v3(mat_final[3], loc); } weight = strength; if (wmd->texture) { tex_co = MEM_mallocN(sizeof(*tex_co) * numVerts, "warpModifier_do tex_co"); get_texture_coords((MappingInfoModifierData *)wmd, ob, dm, vertexCos, tex_co, numVerts); modifier_init_texture(wmd->modifier.scene, wmd->texture); } for (i = 0; i < numVerts; i++) { float *co = vertexCos[i]; if (wmd->falloff_type == eWarp_Falloff_None || ((fac = len_v3v3(co, mat_from[3])) < wmd->falloff_radius && (fac = (wmd->falloff_radius - fac) / wmd->falloff_radius))) { /* skip if no vert group found */ if (dvert && defgrp_index != -1) { dv = &dvert[i]; if (dv) { weight = defvert_find_weight(dv, defgrp_index) * strength; if (weight <= 0.0f) /* Should never occure... */ continue; } } /* closely match PROP_SMOOTH and similar */ switch (wmd->falloff_type) { case eWarp_Falloff_None: fac = 1.0f; break; case eWarp_Falloff_Curve: fac = curvemapping_evaluateF(wmd->curfalloff, 0, fac); break; case eWarp_Falloff_Sharp: fac = fac * fac; break; case eWarp_Falloff_Smooth: fac = 3.0f * fac * fac - 2.0f * fac * fac * fac; break; case eWarp_Falloff_Root: fac = (float)sqrt(fac); break; case eWarp_Falloff_Linear: /* pass */ break; case eWarp_Falloff_Const: fac = 1.0f; break; case eWarp_Falloff_Sphere: fac = (float)sqrt(2 * fac - fac * fac); break; } fac *= weight; if (tex_co) { TexResult texres; texres.nor = NULL; get_texture_value(wmd->modifier.scene, wmd->texture, tex_co[i], &texres, false); fac *= texres.tin; } /* into the 'from' objects space */ mul_m4_v3(mat_from_inv, co); if (fac >= 1.0f) { mul_m4_v3(mat_final, co); } else if (fac > 0.0f) { if (wmd->flag & MOD_WARP_VOLUME_PRESERVE) { /* interpolate the matrix for nicer locations */ blend_m4_m4m4(tmat, mat_unit, mat_final, fac); mul_m4_v3(tmat, co); } else { float tvec[3]; mul_v3_m4v3(tvec, mat_final, co); interp_v3_v3v3(co, co, tvec, fac); } } /* out of the 'from' objects space */ mul_m4_v3(mat_from, co); } } if (tex_co) MEM_freeN(tex_co); }
static float hook_falloff( const struct HookData_cb *hd, const float len_sq) { BLI_assert(hd->falloff_sq); if (len_sq > hd->falloff_sq) { return 0.0f; } else if (len_sq > 0.0f) { float fac; if (hd->falloff_type == eHook_Falloff_Const) { fac = 1.0f; goto finally; } else if (hd->falloff_type == eHook_Falloff_InvSquare) { /* avoid sqrt below */ fac = 1.0f - (len_sq / hd->falloff_sq); goto finally; } fac = 1.0f - (sqrtf(len_sq) / hd->falloff); /* closely match PROP_SMOOTH and similar */ switch (hd->falloff_type) { #if 0 case eHook_Falloff_None: fac = 1.0f; break; #endif case eHook_Falloff_Curve: fac = curvemapping_evaluateF(hd->curfalloff, 0, fac); break; case eHook_Falloff_Sharp: fac = fac * fac; break; case eHook_Falloff_Smooth: fac = 3.0f * fac * fac - 2.0f * fac * fac * fac; break; case eHook_Falloff_Root: fac = sqrtf(fac); break; case eHook_Falloff_Linear: /* pass */ break; #if 0 case eHook_Falloff_Const: fac = 1.0f; break; #endif case eHook_Falloff_Sphere: fac = sqrtf(2 * fac - fac * fac); break; #if 0 case eHook_Falloff_InvSquare: fac = fac * (2.0f - fac); break; #endif } finally: return fac * hd->fac_orig; } else { return hd->fac_orig; } }