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:
Diffstat (limited to 'source/blender/blenkernel/intern/rigidbody.c')
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 514f000d73d..c57808f3dee 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -51,6 +51,7 @@
#include "BKE_collection.h"
#include "BKE_effect.h"
+#include "BKE_global.h"
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
@@ -61,7 +62,6 @@
#include "BKE_rigidbody.h"
#include "BKE_scene.h"
#ifdef WITH_BULLET
-# include "BKE_global.h"
# include "BKE_library.h"
# include "BKE_library_query.h"
#endif
@@ -174,13 +174,22 @@ void BKE_rigidbody_free_object(Object *ob, RigidBodyWorld *rbw)
/* free physics references */
if (is_orig) {
if (rbo->shared->physics_object) {
- BLI_assert(rbw);
- if (rbw) {
+ if (rbw != 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. */
RB_dworld_remove_body(rbw->shared->physics_world, rbo->shared->physics_object);
}
+ else {
+ /* We have no access to 'owner' RBW when deleting the object ID itself... No choice bu to
+ * 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) {
+ RB_dworld_remove_body(scene_rbw->shared->physics_world, rbo->shared->physics_object);
+ }
+ }
+ }
RB_body_delete(rbo->shared->physics_object);
rbo->shared->physics_object = NULL;
@@ -1415,7 +1424,7 @@ bool BKE_rigidbody_add_object(Main *bmain, Scene *scene, Object *ob, int type, R
return true;
}
-void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob)
+void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob, const bool free_us)
{
RigidBodyWorld *rbw = scene->rigidbody_world;
RigidBodyCon *rbc;
@@ -1438,8 +1447,13 @@ void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob)
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, obt) {
if (obt && obt->rigidbody_constraint) {
rbc = obt->rigidbody_constraint;
- if (ELEM(ob, rbc->ob1, rbc->ob2)) {
- BKE_rigidbody_remove_constraint(scene, obt);
+ if (rbc->ob1 == ob) {
+ rbc->ob1 = NULL;
+ DEG_id_tag_update(&obt->id, ID_RECALC_COPY_ON_WRITE);
+ }
+ if (rbc->ob2 == ob) {
+ rbc->ob2 = NULL;
+ DEG_id_tag_update(&obt->id, ID_RECALC_COPY_ON_WRITE);
}
}
}
@@ -1454,7 +1468,7 @@ void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob)
* when we remove them from RB simulation. */
BKE_collection_object_add(bmain, scene->master_collection, ob);
}
- BKE_collection_object_remove(bmain, rbw->group, ob, false);
+ BKE_collection_object_remove(bmain, rbw->group, ob, free_us);
}
/* remove object's settings */
@@ -1468,15 +1482,24 @@ void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob)
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
}
-void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
+void BKE_rigidbody_remove_constraint(Main *bmain, Scene *scene, Object *ob, const bool free_us)
{
RigidBodyWorld *rbw = scene->rigidbody_world;
RigidBodyCon *rbc = ob->rigidbody_constraint;
- /* remove from rigidbody world, free object won't do this */
- if (rbw && rbw->shared->physics_world && rbc->physics_constraint) {
- RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
+ if (rbw != NULL) {
+ /* Remove from RBW constraints collection. */
+ if (rbw->constraints != NULL) {
+ BKE_collection_object_remove(bmain, rbw->constraints, ob, free_us);
+ DEG_id_tag_update(&rbw->constraints->id, ID_RECALC_COPY_ON_WRITE);
+ }
+
+ /* remove from rigidbody world, free object won't do this */
+ if (rbw->shared->physics_world && rbc->physics_constraint) {
+ RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
+ }
}
+
/* remove object's settings */
BKE_rigidbody_free_constraint(ob);
@@ -1657,9 +1680,12 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph,
float ctime = DEG_get_ctime(depsgraph);
/* update world */
- if (rebuild) {
- BKE_rigidbody_validate_sim_world(scene, rbw, true);
+ /* Note physics_world can get NULL when undoing the deletion of the last object in it (see
+ * T70667). */
+ if (rebuild || rbw->shared->physics_world == NULL) {
+ BKE_rigidbody_validate_sim_world(scene, rbw, rebuild);
}
+
rigidbody_update_sim_world(scene, rbw);
/* XXX TODO For rebuild: remove all constraints first.
@@ -2086,10 +2112,10 @@ bool BKE_rigidbody_add_object(Main *bmain, Scene *scene, Object *ob, int type, R
return false;
}
-void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob)
+void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob, const bool free_us)
{
}
-void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
+void BKE_rigidbody_remove_constraint(Main *bmain, Scene *scene, Object *ob, const bool free_us)
{
}
void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)