diff options
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/rigidbody.c | 19 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 26 |
4 files changed, 44 insertions, 16 deletions
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index dab4235559a..99d0c5ed964 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2353,6 +2353,7 @@ static void dag_object_time_update_flags(Scene *scene, Object *ob) if (object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA; if ((ob->pose) && (ob->pose->flag & POSE_CONSTRAINTS_TIMEDEPEND)) ob->recalc |= OB_RECALC_DATA; + // XXX: scene here may not be the scene that contains the rigidbody world affecting this! if (ob->rigidbody_object && BKE_scene_check_rigidbody_active(scene)) ob->recalc |= OB_RECALC_OB; @@ -2440,7 +2441,11 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const s if (do_time) { /* now if DagNode were part of base, the node->lay could be checked... */ /* we do all now, since the scene_flush checks layers and clears recalc flags even */ - dag_object_time_update_flags(scene, ob); + + /* NOTE: "sce_iter" not "scene" so that rigidbodies in background scenes work + * (i.e. muting + rbw availability can be checked and tagged properly) [#33970] + */ + dag_object_time_update_flags(sce_iter, ob); } /* handled in next loop */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 0140152790c..4b940fa8274 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2141,7 +2141,8 @@ void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime) else { BKE_object_to_mat4(ob, ob->obmat); } - + + /* read values pushed into RBO from sim/cache... */ BKE_rigidbody_sync_transforms(scene, ob, ctime); /* solve constraints */ @@ -2617,6 +2618,11 @@ int BKE_object_parent_loop_check(const Object *par, const Object *ob) /* the main object update call, for object matrix, constraints, keys and displist (modifiers) */ /* requires flags to be set! */ + +/* WARNING: "scene" here may not be the scene object actually resides in. + * When dealing with background-sets, "scene" is actually the active scene. + * e.g. "scene" <-- set 1 <-- set 2 ("ob" lives here) <-- set 3 <-- ... <-- set n + */ void BKE_object_handle_update(Scene *scene, Object *ob) { if (ob->recalc & OB_RECALC_ALL) { diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 24355149926..055ada33867 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -1136,19 +1136,25 @@ void BKE_rigidbody_sync_transforms(Scene *scene, Object *ob, float ctime) { RigidBodyWorld *rbw = scene->rigidbody_world; RigidBodyOb *rbo = ob->rigidbody_object; + bool world_ok = true; /* keep original transform for kinematic and passive objects */ - if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE) + if ((rbo == NULL) || (rbo->flag & RBO_FLAG_KINEMATIC) || (rbo->type == RBO_TYPE_PASSIVE)) return; + + /* "scene" may not be the one where object + rigidbody sim actually reside + * due to the quirks of how background-sets eval works [#33970] + */ + if (rbw) { + /* 1) no cache exists before startframe */ + /* 2) keep original transform when simulation is muted */ + world_ok = (ctime > rbw->pointcache->startframe) && !(rbw->flag & RBW_FLAG_MUTED); + } /* use rigid body transform after cache start frame if objects is not being transformed */ - if (ctime > rbw->pointcache->startframe && !(ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) { + if (world_ok && !((ob->flag & SELECT) && (G.moving & G_TRANSFORM_OBJ))) { float mat[4][4], size_mat[4][4], size[3]; - /* keep original transform when the simulation is muted */ - if (rbw->flag & RBW_FLAG_MUTED) - return; - normalize_qt(rbo->orn); // RB_TODO investigate why quaternion isn't normalized at this point quat_to_mat4(mat, rbo->orn); copy_v3_v3(mat[3], rbo->pos); @@ -1165,6 +1171,7 @@ void BKE_rigidbody_sync_transforms(Scene *scene, Object *ob, float ctime) } } +/* Used when cancelling transforms - return rigidbody and object to initial states */ void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) { RigidBodyOb *rbo = ob->rigidbody_object; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 30550edc007..13e050f12b7 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1093,7 +1093,6 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen { Base *base; - scene->customdata_mask = scene_parent->customdata_mask; /* sets first, we allow per definition current scene to have @@ -1101,6 +1100,23 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen if (scene->set) scene_update_tagged_recursive(bmain, scene->set, scene_parent); + /* run rigidbody sim + * - calculate/read values from cache into RBO's, to get flushed + * later when objects are evaluated (if they're tagged for eval) + */ + // XXX: this position may still change, objects not being updated correctly before simulation is run + // NOTE: current position is so that rigidbody sim affects other objects + // FIXME: this now gets executed on every update, not just frame change now!!! + if (BKE_scene_check_rigidbody_active(scene)) { + /* we use frame time of parent (this is "scene" itself for top-level of sets recursion), + * as that is the active scene controlling all timing in file at the moment + */ + float ctime = BKE_scene_frame_get(scene_parent); + + /* however, "scene" contains the rigidbody world needed for eval... */ + BKE_rigidbody_do_simulation(scene, ctime); + } + /* scene objects */ for (base = scene->base.first; base; base = base->next) { Object *ob = base->object; @@ -1206,13 +1222,7 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) * such as Scene->World->MTex/Texture) can still get correctly overridden. */ BKE_animsys_evaluate_all_animation(bmain, sce, ctime); - /*...done with recusrive funcs */ - - /* run rigidbody sim */ - // XXX: this position may still change, objects not being updated correctly before simulation is run - // NOTE: current position is so that rigidbody sim affects other objects - if (BKE_scene_check_rigidbody_active(sce)) - BKE_rigidbody_do_simulation(sce, ctime); + /*...done with recursive funcs */ /* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later * when trying to find materials with drivers that need evaluating [#32017] |