diff options
Diffstat (limited to 'source/blender/blenkernel/intern/softbody.c')
-rw-r--r-- | source/blender/blenkernel/intern/softbody.c | 185 |
1 files changed, 76 insertions, 109 deletions
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index cf5ce374e4c..c552bfeb0dc 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -71,9 +71,11 @@ variables on the UI for now #include "BLI_ghash.h" #include "BLI_threads.h" +#include "BKE_collection.h" #include "BKE_curve.h" #include "BKE_effect.h" #include "BKE_global.h" +#include "BKE_layer.h" #include "BKE_modifier.h" #include "BKE_softbody.h" #include "BKE_pointcache.h" @@ -81,6 +83,9 @@ variables on the UI for now #include "BKE_mesh.h" #include "BKE_scene.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + #include "PIL_time.h" /* callbacks for errors and interrupts and some goo */ @@ -134,7 +139,7 @@ typedef struct SB_thread_context { float timenow; int ifirst; int ilast; - ListBase *do_effector; + ListBase *effectors; int do_deflector; float fieldfactor; float windfactor; @@ -510,37 +515,24 @@ static void ccd_build_deflector_hash_single(GHash *hash, Object *ob) } /** - * \note group overrides scene when not NULL. + * \note collection overrides scene when not NULL. */ -static void ccd_build_deflector_hash(Scene *scene, Group *group, Object *vertexowner, GHash *hash) +static void ccd_build_deflector_hash(Depsgraph *depsgraph, Collection *collection, Object *vertexowner, GHash *hash) { - Object *ob; - if (!hash) return; - if (group) { - /* Explicit collision group */ - for (GroupObject *go = group->gobject.first; go; go = go->next) { - ob = go->ob; + /* Explicit collision collection. */ + Base *base = BKE_collection_or_layer_objects(depsgraph, NULL, NULL, collection); - if (ob == vertexowner || ob->type != OB_MESH) + for (; base; base = base->next) { + /* Only proceed for mesh object in same layer. */ + if (base->object->type == OB_MESH) { + Object *ob = base->object; + if (ob == vertexowner) { + /* If vertexowner is given we don't want to check collision with owner object. */ continue; - - ccd_build_deflector_hash_single(hash, ob); - } - } - else { - for (Base *base = scene->base.first; base; base = base->next) { - /*Only proceed for mesh object in same layer */ - if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) { - ob= base->object; - if ((vertexowner) && (ob == vertexowner)) { - /* if vertexowner is given we don't want to check collision with owner object */ - continue; - } - - ccd_build_deflector_hash_single(hash, ob); } + ccd_build_deflector_hash_single(hash, ob); } } } @@ -556,39 +548,27 @@ static void ccd_update_deflector_hash_single(GHash *hash, Object *ob) } /** - * \note group overrides scene when not NULL. + * \note collection overrides scene when not NULL. */ -static void ccd_update_deflector_hash(Scene *scene, Group *group, Object *vertexowner, GHash *hash) +static void ccd_update_deflector_hash(Depsgraph *depsgraph, Collection *collection, Object *vertexowner, GHash *hash) { - Object *ob; - if ((!hash) || (!vertexowner)) return; - if (group) { - /* Explicit collision group */ - for (GroupObject *go = group->gobject.first; go; go = go->next) { - ob = go->ob; + /* Explicit collision collection. */ + Base *base = BKE_collection_or_layer_objects(depsgraph, NULL, NULL, collection); - if (ob == vertexowner || ob->type != OB_MESH) + for (; base; base = base->next) { + /* Only proceed for mesh object in same layer. */ + if (base->object->type == OB_MESH) { + Object *ob = base->object; + if (ob == vertexowner) { + /* If vertexowner is given we don't want to check collision with owner object. */ continue; + } ccd_update_deflector_hash_single(hash, ob); } } - else { - for (Base *base = scene->base.first; base; base = base->next) { - /*Only proceed for mesh object in same layer */ - if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) { - ob= base->object; - if (ob == vertexowner) { - /* if vertexowner is given we don't want to check collision with owner object */ - continue; - } - - ccd_update_deflector_hash_single(hash, ob); - } - } - } } @@ -977,31 +957,23 @@ static void free_softbody_intern(SoftBody *sb) /* +++ dependency information functions*/ /** - * \note group overrides scene when not NULL. + * \note collection overrides scene when not NULL. */ -static bool are_there_deflectors(Scene *scene, Group *group, unsigned int layer) +static bool are_there_deflectors(Base *first_base) { - if (group) { - for (GroupObject *go = group->gobject.first; go; go = go->next) { - if (go->ob->pd && go->ob->pd->deflect) + for (Base *base = first_base; base; base = base->next) { + if (base->object->pd) { + if (base->object->pd->deflect) return 1; } } - else { - for (Base *base = scene->base.first; base; base= base->next) { - if ( (base->lay & layer) && base->object->pd) { - if (base->object->pd->deflect) - return 1; - } - } - } return 0; } -static int query_external_colliders(Scene *scene, Group *group, Object *me) +static int query_external_colliders(Depsgraph *depsgraph, Collection *collection) { - return(are_there_deflectors(scene, group, me->lay)); + return(are_there_deflectors(BKE_collection_or_layer_objects(depsgraph, NULL, NULL, collection))); } /* --- dependency information functions*/ @@ -1472,7 +1444,7 @@ static int sb_detect_edge_collisionCached(float edge_v1[3], float edge_v2[3], fl return deflected; } -static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, int ifirst, int ilast, struct ListBase *do_effector) +static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, int ifirst, int ilast, struct ListBase *effectors) { SoftBody *sb = ob->soft; int a; @@ -1506,14 +1478,14 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, float vel[3], sp[3], pr[3], force[3]; float f, windfactor = 0.25f; /*see if we have wind*/ - if (do_effector) { + if (effectors) { EffectedPoint epoint; float speed[3] = {0.0f, 0.0f, 0.0f}; float pos[3]; mid_v3_v3v3(pos, sb->bpoint[bs->v1].pos, sb->bpoint[bs->v2].pos); mid_v3_v3v3(vel, sb->bpoint[bs->v1].vec, sb->bpoint[bs->v2].vec); pd_point_from_soft(scene, pos, vel, -1, &epoint); - pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed); + BKE_effectors_apply(effectors, NULL, sb->effector_weights, &epoint, force, speed); mul_v3_fl(speed, windfactor); add_v3_v3(vel, speed); @@ -1546,32 +1518,30 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, } -static void scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow) +static void scan_for_ext_spring_forces(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float timenow) { SoftBody *sb = ob->soft; - ListBase *do_effector = NULL; - do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights, true); - _scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector); - pdEndEffectors(&do_effector); + ListBase *effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, sb->effector_weights); + _scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, effectors); + BKE_effectors_free(effectors); } static void *exec_scan_for_ext_spring_forces(void *data) { SB_thread_context *pctx = (SB_thread_context*)data; - _scan_for_ext_spring_forces(pctx->scene, pctx->ob, pctx->timenow, pctx->ifirst, pctx->ilast, pctx->do_effector); + _scan_for_ext_spring_forces(pctx->scene, pctx->ob, pctx->timenow, pctx->ifirst, pctx->ilast, pctx->effectors); return NULL; } -static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow, int totsprings, int *UNUSED(ptr_to_break_func(void))) +static void sb_sfesf_threads_run(struct Depsgraph *depsgraph, Scene *scene, struct Object *ob, float timenow, int totsprings, int *UNUSED(ptr_to_break_func(void))) { - ListBase *do_effector = NULL; ListBase threads; SB_thread_context *sb_threads; int i, totthread, left, dec; int lowsprings =100; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */ - do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights, true); + ListBase *effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, ob->soft->effector_weights); /* figure the number of threads while preventing pretty pointless threading overhead */ totthread= BKE_scene_num_threads(scene); @@ -1596,7 +1566,7 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow, } else sb_threads[i].ifirst = 0; - sb_threads[i].do_effector = do_effector; + sb_threads[i].effectors = effectors; sb_threads[i].do_deflector = false;// not used here sb_threads[i].fieldfactor = 0.0f;// not used here sb_threads[i].windfactor = 0.0f;// not used here @@ -1616,7 +1586,7 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow, /* clean up */ MEM_freeN(sb_threads); - pdEndEffectors(&do_effector); + BKE_effectors_free(effectors); } @@ -1969,7 +1939,7 @@ static void sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, floa /* since this is definitely the most CPU consuming task here .. try to spread it */ /* core function _softbody_calc_forces_slice_in_a_thread */ /* result is int to be able to flag user break */ -static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, float forcetime, float timenow, int ifirst, int ilast, int *UNUSED(ptr_to_break_func(void)), ListBase *do_effector, int do_deflector, float fieldfactor, float windfactor) +static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, float forcetime, float timenow, int ifirst, int ilast, int *UNUSED(ptr_to_break_func(void)), ListBase *effectors, int do_deflector, float fieldfactor, float windfactor) { float iks; int bb, do_selfcollision, do_springcollision, do_aero; @@ -2088,14 +2058,14 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo } /* particle field & vortex */ - if (do_effector) { + if (effectors) { EffectedPoint epoint; float kd; float force[3] = {0.0f, 0.0f, 0.0f}; float speed[3] = {0.0f, 0.0f, 0.0f}; float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */ pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint); - pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed); + BKE_effectors_apply(effectors, NULL, sb->effector_weights, &epoint, force, speed); /* apply forcefield*/ mul_v3_fl(force, fieldfactor* eval_sb_fric_force_scale); @@ -2170,11 +2140,11 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo static void *exec_softbody_calc_forces(void *data) { SB_thread_context *pctx = (SB_thread_context*)data; - _softbody_calc_forces_slice_in_a_thread(pctx->scene, pctx->ob, pctx->forcetime, pctx->timenow, pctx->ifirst, pctx->ilast, NULL, pctx->do_effector, pctx->do_deflector, pctx->fieldfactor, pctx->windfactor); + _softbody_calc_forces_slice_in_a_thread(pctx->scene, pctx->ob, pctx->forcetime, pctx->timenow, pctx->ifirst, pctx->ilast, NULL, pctx->effectors, pctx->do_deflector, pctx->fieldfactor, pctx->windfactor); return NULL; } -static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float timenow, int totpoint, int *UNUSED(ptr_to_break_func(void)), struct ListBase *do_effector, int do_deflector, float fieldfactor, float windfactor) +static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float timenow, int totpoint, int *UNUSED(ptr_to_break_func(void)), struct ListBase *effectors, int do_deflector, float fieldfactor, float windfactor) { ListBase threads; SB_thread_context *sb_threads; @@ -2206,7 +2176,7 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t } else sb_threads[i].ifirst = 0; - sb_threads[i].do_effector = do_effector; + sb_threads[i].effectors = effectors; sb_threads[i].do_deflector = do_deflector; sb_threads[i].fieldfactor = fieldfactor; sb_threads[i].windfactor = windfactor; @@ -2229,14 +2199,13 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t MEM_freeN(sb_threads); } -static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, float timenow) +static void softbody_calc_forcesEx(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float forcetime, float timenow) { /* rule we never alter free variables :bp->vec bp->pos in here ! * this will ruin adaptive stepsize AKA heun! (BM) */ SoftBody *sb= ob->soft; /* is supposed to be there */ /*BodyPoint *bproot;*/ /* UNUSED */ - ListBase *do_effector = NULL; /* float gravity; */ /* UNUSED */ /* float iks; */ float fieldfactor = -1.0f, windfactor = 0.25; @@ -2245,7 +2214,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl /* gravity = sb->grav * sb_grav_force_scale(ob); */ /* UNUSED */ /* check conditions for various options */ - do_deflector= query_external_colliders(scene, sb->collision_group, ob); + do_deflector= query_external_colliders(depsgraph, sb->collision_group); /* do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF)); */ /* UNUSED */ do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL); do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES)); @@ -2254,31 +2223,31 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl /* bproot= sb->bpoint; */ /* need this for proper spring addressing */ /* UNUSED */ if (do_springcollision || do_aero) - sb_sfesf_threads_run(scene, ob, timenow, sb->totspring, NULL); + sb_sfesf_threads_run(depsgraph, scene, ob, timenow, sb->totspring, NULL); /* after spring scan because it uses Effoctors too */ - do_effector= pdInitEffectors(scene, ob, NULL, sb->effector_weights, true); + ListBase *effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, sb->effector_weights); if (do_deflector) { float defforce[3]; do_deflector = sb_detect_aabb_collisionCached(defforce, ob->lay, ob, timenow); } - sb_cf_threads_run(scene, ob, forcetime, timenow, sb->totpoint, NULL, do_effector, do_deflector, fieldfactor, windfactor); + sb_cf_threads_run(scene, ob, forcetime, timenow, sb->totpoint, NULL, effectors, do_deflector, fieldfactor, windfactor); /* finally add forces caused by face collision */ if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob, timenow); /* finish matrix and solve */ - pdEndEffectors(&do_effector); + BKE_effectors_free(effectors); } -static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, float timenow) +static void softbody_calc_forces(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float forcetime, float timenow) { /* redirection to the new threaded Version */ if (!(G.debug_value & 0x10)) { // 16 - softbody_calc_forcesEx(scene, ob, forcetime, timenow); + softbody_calc_forcesEx(depsgraph, scene, ob, forcetime, timenow); return; } else { @@ -2297,7 +2266,6 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa BodyPoint *bp; /* BodyPoint *bproot; */ /* UNUSED */ BodySpring *bs; - ListBase *do_effector = NULL; float iks, ks, kd, gravity[3] = {0.0f, 0.0f, 0.0f}; float fieldfactor = -1.0f, windfactor = 0.25f; float tune = sb->ballstiff; @@ -2309,7 +2277,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa } /* check conditions for various options */ - do_deflector= query_external_colliders(scene, sb->collision_group, ob); + do_deflector= query_external_colliders(depsgraph, sb->collision_group); do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF)); do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL); do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES)); @@ -2317,9 +2285,9 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */ /* bproot= sb->bpoint; */ /* need this for proper spring addressing */ /* UNUSED */ - if (do_springcollision || do_aero) scan_for_ext_spring_forces(scene, ob, timenow); + if (do_springcollision || do_aero) scan_for_ext_spring_forces(depsgraph, scene, ob, timenow); /* after spring scan because it uses Effoctors too */ - do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights, true); + ListBase *effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, ob->soft->effector_weights); if (do_deflector) { float defforce[3]; @@ -2422,13 +2390,13 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa /* particle field & vortex */ - if (do_effector) { + if (effectors) { EffectedPoint epoint; float force[3] = {0.0f, 0.0f, 0.0f}; float speed[3] = {0.0f, 0.0f, 0.0f}; float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */ pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint); - pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed); + BKE_effectors_apply(effectors, NULL, sb->effector_weights, &epoint, force, speed); /* apply forcefield*/ mul_v3_fl(force, fieldfactor* eval_sb_fric_force_scale); @@ -2520,7 +2488,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa /* finally add forces caused by face collision */ if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob, timenow); - pdEndEffectors(&do_effector); + BKE_effectors_free(effectors); } } @@ -3506,7 +3474,7 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int } } -static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime) +static void softbody_step(struct Depsgraph *depsgraph, Scene *scene, Object *ob, SoftBody *sb, float dtime) { /* the simulator */ float forcetime; @@ -3520,11 +3488,11 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime) */ if (dtime < 0 || dtime > 10.5f) return; - ccd_update_deflector_hash(scene, sb->collision_group, ob, sb->scratch->colliderhash); + ccd_update_deflector_hash(depsgraph, sb->collision_group, ob, sb->scratch->colliderhash); if (sb->scratch->needstobuildcollider) { - if (query_external_colliders(scene, sb->collision_group, ob)) { - ccd_build_deflector_hash(scene, sb->collision_group, ob, sb->scratch->colliderhash); + if (query_external_colliders(depsgraph, sb->collision_group)) { + ccd_build_deflector_hash(depsgraph, sb->collision_group, ob, sb->scratch->colliderhash); } sb->scratch->needstobuildcollider=0; } @@ -3554,12 +3522,12 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime) sb->scratch->flag &= ~SBF_DOFUZZY; /* do predictive euler step */ - softbody_calc_forces(scene, ob, forcetime, timedone/dtime); + softbody_calc_forces(depsgraph, scene, ob, forcetime, timedone/dtime); softbody_apply_forces(ob, forcetime, 1, NULL, mid_flags); /* crop new slope values to do averaged slope step */ - softbody_calc_forces(scene, ob, forcetime, timedone/dtime); + softbody_calc_forces(depsgraph, scene, ob, forcetime, timedone/dtime); softbody_apply_forces(ob, forcetime, 2, &err, mid_flags); softbody_apply_goalsnap(ob); @@ -3640,7 +3608,7 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime) } /* simulates one step. framenr is in frames */ -void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], int numVerts) +void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], int numVerts) { SoftBody *sb= ob->soft; PointCache *cache; @@ -3648,7 +3616,6 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i float dtime, timescale; int framedelta, framenr, startframe, endframe; int cache_result; - cache= sb->pointcache; framenr= (int)cfra; @@ -3717,7 +3684,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i } /* try to read from cache */ - bool can_simulate = (framenr == sb->last_frame+1) && !(cache->flag & PTCACHE_BAKED); + bool can_simulate = (framenr == sb->last_frame + 1) && !(cache->flag & PTCACHE_BAKED); cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe, can_simulate); @@ -3757,7 +3724,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i dtime = framedelta*timescale; /* do simulation */ - softbody_step(scene, ob, sb, dtime); + softbody_step(depsgraph, scene, ob, sb, dtime); softbody_to_object(ob, vertexCos, numVerts, 0); |