Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_rigidbody.h1
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c37
-rw-r--r--source/blender/blenkernel/intern/scene.c17
3 files changed, 41 insertions, 14 deletions
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
index 12779a697b6..bab961bcbd2 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -91,6 +91,7 @@ void BKE_rigidbody_remove_constraint(struct Scene *scene, struct Object *ob);
void BKE_rigidbody_aftertrans_update(struct Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle);
void BKE_rigidbody_sync_transforms(struct RigidBodyWorld *rbw, struct Object *ob, float ctime);
void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw);
+void BKE_rigidbody_rebuild_world(struct Scene *scene, float ctime);
void BKE_rigidbody_do_simulation(struct Scene *scene, float ctime);
#endif /* __BKE_RIGIDBODY_H__ */
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index d3a457ac2ed..025522fad25 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -1220,10 +1220,10 @@ void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
/* ------------------ */
-/* Run RigidBody simulation for the specified physics world */
-void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
+/* 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)
{
- float timestep;
RigidBodyWorld *rbw = scene->rigidbody_world;
PointCache *cache;
PTCacheID pid;
@@ -1233,16 +1233,12 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
cache = rbw->pointcache;
- rbw->flag &= ~RBW_FLAG_FRAME_UPDATE;
-
/* 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_countlist(&rbw->group->gobject)) {
cache->flag |= PTCACHE_OUTDATED;
}
- if (ctime <= startframe) {
- rbw->ltime = startframe;
- /* reset and rebuild simulation if necessary */
+ 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);
@@ -1250,12 +1246,27 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
cache->last_exact = 0;
cache->flag &= ~PTCACHE_REDO_NEEDED;
}
- return;
}
- /* rebuild world if it's outdated on second frame */
- else if (ctime == startframe + 1 && rbw->ltime == startframe && cache->flag & PTCACHE_OUTDATED) {
- BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
- rigidbody_update_simulation(scene, rbw, true);
+}
+
+/* Run RigidBody simulation for the specified physics world */
+void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
+{
+ float timestep;
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+ PointCache *cache;
+ PTCacheID pid;
+ int startframe, endframe;
+
+ BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
+ BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
+ cache = rbw->pointcache;
+
+ rbw->flag &= ~RBW_FLAG_FRAME_UPDATE;
+
+ if (ctime <= startframe) {
+ rbw->ltime = startframe;
+ return;
}
/* make sure we don't go out of cache frame range */
else if (ctime > endframe) {
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 83b2648ee50..9479e3e2e0e 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1090,6 +1090,15 @@ static void scene_flag_rbw_recursive(Scene *scene)
scene->rigidbody_world->flag |= RBW_FLAG_FRAME_UPDATE;
}
+static void scene_rebuild_rbw_recursive(Scene *scene, float ctime)
+{
+ if (scene->set)
+ scene_rebuild_rbw_recursive(scene->set, ctime);
+
+ if (BKE_scene_check_rigidbody_active(scene))
+ BKE_rigidbody_rebuild_world(scene, ctime);
+}
+
static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scene_parent)
{
Base *base;
@@ -1112,7 +1121,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
* 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);
}
@@ -1195,6 +1204,12 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
{
float ctime = BKE_scene_frame_get(sce);
Scene *sce_iter;
+
+ /* rebuild rigid body worlds before doing the actual frame update
+ * this needs to be done on start frame but animation playback usually starts one frame later
+ * we need to do it here to avoid rebuilding the world on every simulation change, which can be very expensive
+ */
+ scene_rebuild_rbw_recursive(sce, ctime);
/* keep this first */
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_PRE);