Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/effect.c
| Show First 20 Lines • Show All 264 Lines • ▼ Show 20 Lines | |||||
| void BKE_effector_relations_free(ListBase *lb) | void BKE_effector_relations_free(ListBase *lb) | ||||
| { | { | ||||
| if (lb) { | if (lb) { | ||||
| BLI_freelistN(lb); | BLI_freelistN(lb); | ||||
| MEM_freeN(lb); | MEM_freeN(lb); | ||||
| } | } | ||||
| } | } | ||||
| /* Check that the force field isn't disabled via its flags. */ | |||||
| static bool is_effector_enabled(PartDeflect *pd, bool use_rotation) | |||||
| { | |||||
| switch (pd->forcefield) { | |||||
| case PFIELD_BOID: | |||||
| case PFIELD_GUIDE: | |||||
| return true; | |||||
| case PFIELD_TEXTURE: | |||||
| return (pd->flag & PFIELD_DO_LOCATION) != 0 && pd->tex != NULL; | |||||
| default: | |||||
| if (use_rotation) { | |||||
| return (pd->flag & (PFIELD_DO_LOCATION | PFIELD_DO_ROTATION)) != 0; | |||||
| } | |||||
| else { | |||||
| return (pd->flag & PFIELD_DO_LOCATION) != 0; | |||||
| } | |||||
| } | |||||
| } | |||||
| /* Check that the force field won't have zero effect due to strength settings. */ | |||||
| static bool is_effector_nonzero_strength(PartDeflect *pd) | |||||
| { | |||||
| if (pd->f_strength != 0.0f) { | |||||
| return true; | |||||
| } | |||||
| if (pd->forcefield == PFIELD_TEXTURE) { | |||||
| return false; | |||||
| } | |||||
| if (pd->f_noise > 0.0f || pd->f_flow != 0.0f) { | |||||
| return true; | |||||
| } | |||||
| switch (pd->forcefield) { | |||||
| case PFIELD_BOID: | |||||
| case PFIELD_GUIDE: | |||||
| return true; | |||||
| case PFIELD_VORTEX: | |||||
| return pd->shape != PFIELD_SHAPE_POINT; | |||||
| case PFIELD_DRAG: | |||||
| return pd->f_damp != 0.0f; | |||||
| default: | |||||
| return false; | |||||
| } | |||||
| } | |||||
| /* Check if the force field will affect its user. */ | |||||
| static bool is_effector_relevant(PartDeflect *pd, EffectorWeights *weights, bool use_rotation) | |||||
| { | |||||
| return (weights->weight[pd->forcefield] != 0.0f) && is_effector_enabled(pd, use_rotation) && | |||||
| is_effector_nonzero_strength(pd); | |||||
| } | |||||
| /* Create effective list of effectors from relations built beforehand. */ | /* Create effective list of effectors from relations built beforehand. */ | ||||
| ListBase *BKE_effectors_create(Depsgraph *depsgraph, | ListBase *BKE_effectors_create(Depsgraph *depsgraph, | ||||
| Object *ob_src, | Object *ob_src, | ||||
| ParticleSystem *psys_src, | ParticleSystem *psys_src, | ||||
| EffectorWeights *weights) | EffectorWeights *weights, | ||||
| bool use_rotation) | |||||
| { | { | ||||
| Scene *scene = DEG_get_evaluated_scene(depsgraph); | Scene *scene = DEG_get_evaluated_scene(depsgraph); | ||||
| ListBase *relations = DEG_get_effector_relations(depsgraph, weights->group); | ListBase *relations = DEG_get_effector_relations(depsgraph, weights->group); | ||||
| ListBase *effectors = NULL; | ListBase *effectors = NULL; | ||||
| if (!relations) { | if (!relations) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| LISTBASE_FOREACH (EffectorRelation *, relation, relations) { | LISTBASE_FOREACH (EffectorRelation *, relation, relations) { | ||||
| /* Get evaluated object. */ | /* Get evaluated object. */ | ||||
| Object *ob = (Object *)DEG_get_evaluated_id(depsgraph, &relation->ob->id); | Object *ob = (Object *)DEG_get_evaluated_id(depsgraph, &relation->ob->id); | ||||
| if (relation->psys) { | if (relation->psys) { | ||||
| /* Get evaluated particle system. */ | /* Get evaluated particle system. */ | ||||
| ParticleSystem *psys = BLI_findstring( | ParticleSystem *psys = BLI_findstring( | ||||
| &ob->particlesystem, relation->psys->name, offsetof(ParticleSystem, name)); | &ob->particlesystem, relation->psys->name, offsetof(ParticleSystem, name)); | ||||
| ParticleSettings *part = psys->part; | ParticleSettings *part = psys->part; | ||||
| if (psys == psys_src && (part->flag & PART_SELF_EFFECT) == 0) { | if (psys == psys_src && (part->flag & PART_SELF_EFFECT) == 0) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| PartDeflect *pd = (relation->pd == relation->psys->part->pd) ? part->pd : part->pd2; | PartDeflect *pd = (relation->pd == relation->psys->part->pd) ? part->pd : part->pd2; | ||||
| if (weights->weight[pd->forcefield] == 0.0f) { | |||||
| if (!is_effector_relevant(pd, weights, use_rotation)) { | |||||
| continue; | continue; | ||||
| } | } | ||||
| add_effector_evaluation(&effectors, depsgraph, scene, ob, psys, pd); | add_effector_evaluation(&effectors, depsgraph, scene, ob, psys, pd); | ||||
| } | } | ||||
| else { | else { | ||||
| /* Object effector. */ | /* Object effector. */ | ||||
| if (ob == ob_src) { | if (ob == ob_src) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (weights->weight[ob->pd->forcefield] == 0.0f) { | if (!is_effector_relevant(ob->pd, weights, use_rotation)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (ob->pd->shape == PFIELD_SHAPE_POINTS && BKE_object_get_evaluated_mesh(ob) == NULL) { | if (ob->pd->shape == PFIELD_SHAPE_POINTS && BKE_object_get_evaluated_mesh(ob) == NULL) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| add_effector_evaluation(&effectors, depsgraph, scene, ob, NULL, ob->pd); | add_effector_evaluation(&effectors, depsgraph, scene, ob, NULL, ob->pd); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 576 Lines • ▼ Show 20 Lines | else { | ||||
| zero_v3(force); | zero_v3(force); | ||||
| } | } | ||||
| if (eff->pd->flag & PFIELD_TEX_2D) { | if (eff->pd->flag & PFIELD_TEX_2D) { | ||||
| float fac = -dot_v3v3(force, efd->nor); | float fac = -dot_v3v3(force, efd->nor); | ||||
| madd_v3_v3fl(force, efd->nor, fac); | madd_v3_v3fl(force, efd->nor, fac); | ||||
| } | } | ||||
| if (eff->pd->flag & PFIELD_DO_LOCATION) { | |||||
| add_v3_v3(total_force, force); | add_v3_v3(total_force, force); | ||||
| } | } | ||||
| } | |||||
| static void do_physical_effector(EffectorCache *eff, | static void do_physical_effector(EffectorCache *eff, | ||||
| EffectorData *efd, | EffectorData *efd, | ||||
| EffectedPoint *point, | EffectedPoint *point, | ||||
| float *total_force) | float *total_force) | ||||
| { | { | ||||
| PartDeflect *pd = eff->pd; | PartDeflect *pd = eff->pd; | ||||
| RNG *rng = pd->rng; | RNG *rng = pd->rng; | ||||
| float force[3] = {0, 0, 0}; | float force[3] = {0, 0, 0}; | ||||
| float temp[3]; | float temp[3]; | ||||
| float fac; | float fac; | ||||
| float strength = pd->f_strength; | float strength = pd->f_strength; | ||||
| float damp = pd->f_damp; | float damp = pd->f_damp; | ||||
| float noise_factor = pd->f_noise; | float noise_factor = pd->f_noise; | ||||
| float flow_falloff = efd->falloff; | |||||
| if (noise_factor > 0.0f) { | if (noise_factor > 0.0f) { | ||||
| strength += wind_func(rng, noise_factor); | strength += wind_func(rng, noise_factor); | ||||
| if (ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG)) { | if (ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG)) { | ||||
| damp += wind_func(rng, noise_factor); | damp += wind_func(rng, noise_factor); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | case PFIELD_DRAG: | ||||
| strength = MIN2(strength, 2.0f); | strength = MIN2(strength, 2.0f); | ||||
| damp = MIN2(damp, 2.0f); | damp = MIN2(damp, 2.0f); | ||||
| mul_v3_fl(force, -efd->falloff * fac * (strength * fac + damp)); | mul_v3_fl(force, -efd->falloff * fac * (strength * fac + damp)); | ||||
| break; | break; | ||||
| case PFIELD_FLUIDFLOW: | case PFIELD_FLUIDFLOW: | ||||
| zero_v3(force); | zero_v3(force); | ||||
| flow_falloff = 0; | |||||
| #ifdef WITH_FLUID | #ifdef WITH_FLUID | ||||
| if (pd->f_source) { | if (pd->f_source) { | ||||
| float density; | float density; | ||||
| if ((density = BKE_fluid_get_velocity_at(pd->f_source, point->loc, force)) >= 0.0f) { | if ((density = BKE_fluid_get_velocity_at(pd->f_source, point->loc, force)) >= 0.0f) { | ||||
| float influence = strength * efd->falloff; | float influence = strength * efd->falloff; | ||||
| if (pd->flag & PFIELD_SMOKE_DENSITY) { | if (pd->flag & PFIELD_SMOKE_DENSITY) { | ||||
| influence *= density; | influence *= density; | ||||
| } | } | ||||
| mul_v3_fl(force, influence); | mul_v3_fl(force, influence); | ||||
| /* apply flow */ | flow_falloff = influence; | ||||
| madd_v3_v3fl(total_force, point->vel, -pd->f_flow * influence); | |||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| break; | break; | ||||
| } | } | ||||
| if (pd->flag & PFIELD_DO_LOCATION) { | if (pd->flag & PFIELD_DO_LOCATION) { | ||||
| madd_v3_v3fl(total_force, force, 1.0f / point->vel_to_sec); | madd_v3_v3fl(total_force, force, 1.0f / point->vel_to_sec); | ||||
| if (ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG, PFIELD_FLUIDFLOW) == 0 && | if (!ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG) && pd->f_flow != 0.0f) { | ||||
| pd->f_flow != 0.0f) { | madd_v3_v3fl(total_force, point->vel, -pd->f_flow * flow_falloff); | ||||
| madd_v3_v3fl(total_force, point->vel, -pd->f_flow * efd->falloff); | |||||
| } | } | ||||
| } | } | ||||
| if (pd->flag & PFIELD_DO_ROTATION && point->ave && point->rot) { | if (pd->flag & PFIELD_DO_ROTATION && point->ave && point->rot) { | ||||
| float xvec[3] = {1.0f, 0.0f, 0.0f}; | float xvec[3] = {1.0f, 0.0f, 0.0f}; | ||||
| float dave[3]; | float dave[3]; | ||||
| mul_qt_v3(point->rot, xvec); | mul_qt_v3(point->rot, xvec); | ||||
| cross_v3_v3v3(dave, xvec, force); | cross_v3_v3v3(dave, xvec, force); | ||||
| ▲ Show 20 Lines • Show All 292 Lines • Show Last 20 Lines | |||||