diff options
Diffstat (limited to 'source/blender/blenkernel/intern/rigidbody.c')
-rw-r--r-- | source/blender/blenkernel/intern/rigidbody.c | 183 |
1 files changed, 91 insertions, 92 deletions
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 56e65b6f2c5..011971b6677 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -55,9 +55,9 @@ #include "DNA_scene_types.h" #include "BKE_cdderivedmesh.h" -#include "BKE_depsgraph.h" #include "BKE_effect.h" #include "BKE_global.h" +#include "BKE_group.h" #include "BKE_library.h" #include "BKE_library_query.h" #include "BKE_mesh.h" @@ -91,26 +91,30 @@ void BKE_rigidbody_free_world(RigidBodyWorld *rbw) if (rbw->physics_world) { /* free physics references, we assume that all physics objects in will have been added to the world */ - GroupObject *go; if (rbw->constraints) { - for (go = rbw->constraints->gobject.first; go; go = go->next) { - if (go->ob && go->ob->rigidbody_constraint) { - RigidBodyCon *rbc = go->ob->rigidbody_constraint; - - if (rbc->physics_constraint) + FOREACH_GROUP_OBJECT(rbw->constraints, object) + { + if (object->rigidbody_constraint) { + RigidBodyCon *rbc = object->rigidbody_constraint; + if (rbc->physics_constraint) { RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint); + } } } + FOREACH_GROUP_OBJECT_END } - if (rbw->group) { - for (go = rbw->group->gobject.first; go; go = go->next) { - if (go->ob && go->ob->rigidbody_object) { - RigidBodyOb *rbo = go->ob->rigidbody_object; - if (rbo->physics_object) + if (rbw->group) { + FOREACH_GROUP_OBJECT(rbw->group, object) + { + if (object->rigidbody_object) { + RigidBodyOb *rbo = object->rigidbody_object; + if (rbo->physics_object) { RB_dworld_remove_body(rbw->physics_world, rbo->physics_object); + } } } + FOREACH_GROUP_OBJECT_END } /* free dynamics world */ RB_dworld_delete(rbw->physics_world); @@ -1125,7 +1129,6 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob) RigidBodyWorld *rbw = scene->rigidbody_world; RigidBodyOb *rbo = ob->rigidbody_object; RigidBodyCon *rbc; - GroupObject *go; int i; if (rbw) { @@ -1145,8 +1148,8 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob) /* remove object from rigid body constraints */ if (rbw->constraints) { - for (go = rbw->constraints->gobject.first; go; go = go->next) { - Object *obt = go->ob; + FOREACH_GROUP_OBJECT(rbw->constraints, obt) + { if (obt && obt->rigidbody_constraint) { rbc = obt->rigidbody_constraint; if (ELEM(ob, rbc->ob1, rbc->ob2)) { @@ -1154,6 +1157,7 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob) } } } + FOREACH_GROUP_OBJECT_END } } @@ -1187,20 +1191,22 @@ void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob) /* Update object array and rigid body count so they're in sync with the rigid body group */ static void rigidbody_update_ob_array(RigidBodyWorld *rbw) { - GroupObject *go; int i, n; - n = BLI_listbase_count(&rbw->group->gobject); + n = BLI_listbase_count(&rbw->group->view_layer->object_bases); if (rbw->numbodies != n) { rbw->numbodies = n; rbw->objects = realloc(rbw->objects, sizeof(Object *) * rbw->numbodies); } - for (go = rbw->group->gobject.first, i = 0; go; go = go->next, i++) { - Object *ob = go->ob; - rbw->objects[i] = ob; + i = 0; + FOREACH_GROUP_OBJECT(rbw->group, object) + { + rbw->objects[i] = object; + i++; } + FOREACH_GROUP_OBJECT_END } static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw) @@ -1223,7 +1229,7 @@ static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw) rigidbody_update_ob_array(rbw); } -static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo) +static void rigidbody_update_sim_ob(const struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo) { float loc[3]; float rot[4]; @@ -1271,7 +1277,7 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o ListBase *effectors; /* get effectors present in the group specified by effector_weights */ - effectors = pdInitEffectors(scene, ob, NULL, effector_weights, true); + effectors = pdInitEffectors(eval_ctx, scene, ob, NULL, effector_weights, true); if (effectors) { float eff_force[3] = {0.0f, 0.0f, 0.0f}; float eff_loc[3], eff_vel[3]; @@ -1312,10 +1318,8 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o * * \param rebuild Rebuild entire simulation */ -static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool rebuild) +static void rigidbody_update_simulation(const struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, bool rebuild) { - GroupObject *go; - /* update world */ if (rebuild) BKE_rigidbody_validate_sim_world(scene, rbw, true); @@ -1328,28 +1332,26 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool * Memory management needs redesign here, this is just a dirty workaround. */ if (rebuild && rbw->constraints) { - for (go = rbw->constraints->gobject.first; go; go = go->next) { - Object *ob = go->ob; - if (ob) { - RigidBodyCon *rbc = ob->rigidbody_constraint; - if (rbc && rbc->physics_constraint) { - RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint); - RB_constraint_delete(rbc->physics_constraint); - rbc->physics_constraint = NULL; - } + FOREACH_GROUP_OBJECT(rbw->constraints, ob) + { + RigidBodyCon *rbc = ob->rigidbody_constraint; + if (rbc && rbc->physics_constraint) { + RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint); + RB_constraint_delete(rbc->physics_constraint); + rbc->physics_constraint = NULL; } } + FOREACH_GROUP_OBJECT_END } /* update objects */ - for (go = rbw->group->gobject.first; go; go = go->next) { - Object *ob = go->ob; - - if (ob && ob->type == OB_MESH) { + FOREACH_GROUP_OBJECT(rbw->group, ob) + { + if (ob->type == OB_MESH) { /* validate that we've got valid object set up here... */ RigidBodyOb *rbo = ob->rigidbody_object; /* update transformation matrix of the object so we don't get a frame of lag for simple animations */ - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(eval_ctx, scene, ob); if (rbo == NULL) { /* Since this object is included in the sim group but doesn't have @@ -1383,65 +1385,62 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool } /* update simulation object... */ - rigidbody_update_sim_ob(scene, rbw, ob, rbo); + rigidbody_update_sim_ob(eval_ctx, scene, rbw, ob, rbo); } } + FOREACH_GROUP_OBJECT_END /* update constraints */ if (rbw->constraints == NULL) /* no constraints, move on */ return; - for (go = rbw->constraints->gobject.first; go; go = go->next) { - Object *ob = go->ob; - if (ob) { - /* validate that we've got valid object set up here... */ - RigidBodyCon *rbc = ob->rigidbody_constraint; - /* update transformation matrix of the object so we don't get a frame of lag for simple animations */ - BKE_object_where_is_calc(scene, ob); + FOREACH_GROUP_OBJECT(rbw->constraints, ob) + { + /* validate that we've got valid object set up here... */ + RigidBodyCon *rbc = ob->rigidbody_constraint; + /* update transformation matrix of the object so we don't get a frame of lag for simple animations */ + BKE_object_where_is_calc(eval_ctx, scene, ob); - if (rbc == NULL) { - /* Since this object is included in the group but doesn't have - * constraint settings (perhaps it was added manually), add! - */ - ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED); - rigidbody_validate_sim_constraint(rbw, ob, true); + if (rbc == NULL) { + /* Since this object is included in the group but doesn't have + * constraint settings (perhaps it was added manually), add! + */ + ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED); + rigidbody_validate_sim_constraint(rbw, ob, true); - rbc = ob->rigidbody_constraint; + rbc = ob->rigidbody_constraint; + } + else { + /* perform simulation data updates as tagged */ + if (rebuild) { + /* World has been rebuilt so rebuild constraint */ + rigidbody_validate_sim_constraint(rbw, ob, true); } - else { - /* perform simulation data updates as tagged */ - if (rebuild) { - /* World has been rebuilt so rebuild constraint */ - rigidbody_validate_sim_constraint(rbw, ob, true); - } - else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) { - rigidbody_validate_sim_constraint(rbw, ob, false); - } - rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE; + else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) { + rigidbody_validate_sim_constraint(rbw, ob, false); } + rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE; } } + FOREACH_GROUP_OBJECT_END } static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw) { - GroupObject *go; - - for (go = rbw->group->gobject.first; go; go = go->next) { - Object *ob = go->ob; - - if (ob) { - RigidBodyOb *rbo = ob->rigidbody_object; - /* reset kinematic state for transformed objects */ - if (rbo && (ob->flag & SELECT) && (G.moving & G_TRANSFORM_OBJ)) { - RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED); - RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo)); - /* deactivate passive objects so they don't interfere with deactivation of active objects */ - if (rbo->type == RBO_TYPE_PASSIVE) - RB_body_deactivate(rbo->physics_object); - } + FOREACH_GROUP_BASE(rbw->group, base) + { + Object *ob = base->object; + RigidBodyOb *rbo = ob->rigidbody_object; + /* Reset kinematic state for transformed objects. */ + if (rbo && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) { + RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED); + RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo)); + /* Deactivate passive objects so they don't interfere with deactivation of active objects. */ + if (rbo->type == RBO_TYPE_PASSIVE) + RB_body_deactivate(rbo->physics_object); } } + FOREACH_GROUP_BASE_END } bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) @@ -1556,7 +1555,7 @@ void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) /* Rebuild rigid body world */ /* NOTE: this needs to be called before frame update to work correctly */ -void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) +void BKE_rigidbody_rebuild_world(const struct EvaluationContext *eval_ctx, Scene *scene, float ctime) { RigidBodyWorld *rbw = scene->rigidbody_world; PointCache *cache; @@ -1568,14 +1567,14 @@ void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) cache = rbw->pointcache; /* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */ - if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&rbw->group->gobject)) { + if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&rbw->group->view_layer->object_bases)) { cache->flag |= PTCACHE_OUTDATED; } if (ctime == startframe + 1 && rbw->ltime == startframe) { if (cache->flag & PTCACHE_OUTDATED) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); - rigidbody_update_simulation(scene, rbw, true); + rigidbody_update_simulation(eval_ctx, scene, rbw, true); BKE_ptcache_validate(cache, (int)ctime); cache->last_exact = 0; cache->flag &= ~PTCACHE_REDO_NEEDED; @@ -1584,7 +1583,7 @@ void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) } /* Run RigidBody simulation for the specified physics world */ -void BKE_rigidbody_do_simulation(Scene *scene, float ctime) +void BKE_rigidbody_do_simulation(const struct EvaluationContext *eval_ctx, Scene *scene, float ctime) { float timestep; RigidBodyWorld *rbw = scene->rigidbody_world; @@ -1622,14 +1621,14 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime) } /* advance simulation, we can only step one frame forward */ - if (can_simulate) { + if (ctime == rbw->ltime + 1) { /* write cache for first frame when on second frame */ if (rbw->ltime == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) { BKE_ptcache_write(&pid, startframe); } /* update and validate simulation */ - rigidbody_update_simulation(scene, rbw, false); + rigidbody_update_simulation(eval_ctx, scene, rbw, false); /* calculate how much time elapsed since last step in seconds */ timestep = 1.0f / (float)FPS * (ctime - rbw->ltime) * rbw->time_scale; @@ -1673,8 +1672,8 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {} bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) { return false; } void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {} -void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) {} -void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {} +void BKE_rigidbody_rebuild_world(const struct EvaluationContext *eval_ctx, Scene *scene, float ctime) {} +void BKE_rigidbody_do_simulation(const struct EvaluationContext *eval_ctx, Scene *scene, float ctime) {} #ifdef __GNUC__ # pragma GCC diagnostic pop @@ -1685,7 +1684,7 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {} /* -------------------- */ /* Depsgraph evaluation */ -void BKE_rigidbody_rebuild_sim(EvaluationContext *UNUSED(eval_ctx), +void BKE_rigidbody_rebuild_sim(const struct EvaluationContext *eval_ctx, Scene *scene) { float ctime = BKE_scene_frame_get(scene); @@ -1696,11 +1695,11 @@ void BKE_rigidbody_rebuild_sim(EvaluationContext *UNUSED(eval_ctx), /* rebuild sim data (i.e. after resetting to start of timeline) */ if (BKE_scene_check_rigidbody_active(scene)) { - BKE_rigidbody_rebuild_world(scene, ctime); + BKE_rigidbody_rebuild_world(eval_ctx, scene, ctime); } } -void BKE_rigidbody_eval_simulation(EvaluationContext *UNUSED(eval_ctx), +void BKE_rigidbody_eval_simulation(const struct EvaluationContext *eval_ctx, Scene *scene) { float ctime = BKE_scene_frame_get(scene); @@ -1711,11 +1710,11 @@ void BKE_rigidbody_eval_simulation(EvaluationContext *UNUSED(eval_ctx), /* evaluate rigidbody sim */ if (BKE_scene_check_rigidbody_active(scene)) { - BKE_rigidbody_do_simulation(scene, ctime); + BKE_rigidbody_do_simulation(eval_ctx, scene, ctime); } } -void BKE_rigidbody_object_sync_transforms(EvaluationContext *UNUSED(eval_ctx), +void BKE_rigidbody_object_sync_transforms(const struct EvaluationContext *UNUSED(eval_ctx), Scene *scene, Object *ob) { |