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:
authorSergej Reich <sergej.reich@googlemail.com>2013-03-03 10:09:45 +0400
committerSergej Reich <sergej.reich@googlemail.com>2013-03-03 10:09:45 +0400
commit5ff6a5c6abe36b1521d310b0f7e0f6dfd3afa1f3 (patch)
treee92f2e41d0d7f694cca0150f794490ac4b24e72c /source/blender/blenkernel/intern/rigidbody.c
parentb390192b7024d26f421bdc93e63e8603dab18cf2 (diff)
rigidbody: Fix inconsistency with world rebuilding
The rigid body world could be rebuilt on start frame and one frame after start frame. The latter was necessary sice animation playback usually doesn't start at start frame. This lead to different simulations depending on which frame the simulaton was rebuilt when animation was involved. Now we only rebuild the world on start frame. This is actually tricky to do since, as mentioned above, animation playback starts on second frame. To work around this we rebuild the world before the actual update. The alternative would be to rebuld the world on every simulation change (like the other simulations do it) but this is an expensive operation and would be too slow.
Diffstat (limited to 'source/blender/blenkernel/intern/rigidbody.c')
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c37
1 files changed, 24 insertions, 13 deletions
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) {