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:
authorSebastian Parborg <darkdefende@gmail.com>2020-09-02 19:26:37 +0300
committerSebastian Parborg <darkdefende@gmail.com>2020-09-02 19:35:16 +0300
commitf20f82ce3ee55c12adcec024e0133e71183e07b3 (patch)
treeb1fbbdbc22d743315eaeaac62e0a5ea60ae6aff5
parent9b1f726248afcbc415846526a03acbd92d3235d0 (diff)
Fix segfaults when deleting objects with upstream bullet lib
Blender tried to free objects twice from the bullet world sometime. First we would implicity remove all objects when recreating the bullet world and then explicity try to remove them again from the now empty world. This would wouldn't crash older bullet versions, but the recent versions will as we will try to free objects that no longer exists in the bullet world. Also clear the cache on deletion as the object order changes. Fix T77181: The cache clearing will fix this issue.
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 00b993296d0..7eab716d805 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -174,7 +174,7 @@ void BKE_rigidbody_free_object(Object *ob, RigidBodyWorld *rbw)
/* free physics references */
if (is_orig) {
if (rbo->shared->physics_object) {
- if (rbw != NULL) {
+ if (rbw != NULL && rbw->shared->physics_world != NULL) {
/* We can only remove the body from the world if the world is known.
* The world is generally only unknown if it's an evaluated copy of
* an object that's being freed, in which case this code isn't run anyway. */
@@ -185,7 +185,7 @@ void BKE_rigidbody_free_object(Object *ob, RigidBodyWorld *rbw)
* loop over all scenes then. */
for (Scene *scene = G_MAIN->scenes.first; scene != NULL; scene = scene->id.next) {
RigidBodyWorld *scene_rbw = scene->rigidbody_world;
- if (scene_rbw != NULL) {
+ if (scene_rbw != NULL && scene_rbw->shared->physics_world != NULL) {
RB_dworld_remove_body(scene_rbw->shared->physics_world, rbo->shared->physics_object);
}
}
@@ -816,7 +816,9 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
rigidbody_validate_sim_shape(rbw, ob, true);
}
- if (rbo->shared->physics_object) {
+ if (rbo->shared->physics_object && !rebuild) {
+ /* Don't remove body on rebuild as it has already been removed when deleting and rebuilding the
+ * world. */
RB_dworld_remove_body(rbw->shared->physics_world, rbo->shared->physics_object);
}
if (!rbo->shared->physics_object || rebuild) {
@@ -1559,6 +1561,10 @@ void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob, const bo
/* flag cache as outdated */
BKE_rigidbody_cache_reset(rbw);
+ /* Reset cache as the object order probably changed after freeing the object. */
+ PTCacheID pid;
+ BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
+ BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
/* Dependency graph update */
DEG_relations_tag_update(bmain);
@@ -1771,6 +1777,8 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph,
* T70667). */
if (rebuild || rbw->shared->physics_world == NULL) {
BKE_rigidbody_validate_sim_world(scene, rbw, rebuild);
+ /* We have rebuilt the world so we need to make sure the rest is rebuilt as well. */
+ rebuild = true;
}
rigidbody_update_sim_world(scene, rbw);