diff options
-rw-r--r-- | source/blender/blenkernel/BKE_rigidbody.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 28 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/rigidbody.c | 76 | ||||
-rw-r--r-- | source/blender/editors/physics/rigidbody_object.c | 38 |
4 files changed, 92 insertions, 57 deletions
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h index c940e646d95..cc3f5bbb42e 100644 --- a/source/blender/blenkernel/BKE_rigidbody.h +++ b/source/blender/blenkernel/BKE_rigidbody.h @@ -32,6 +32,7 @@ struct Collection; struct Depsgraph; struct Main; struct Object; +struct ReportList; struct Scene; /* -------------- */ @@ -94,6 +95,12 @@ void BKE_rigidbody_calc_center_of_mass(struct Object *ob, float r_center[3]); /* Utilities */ struct RigidBodyWorld *BKE_rigidbody_get_world(struct Scene *scene); +bool BKE_rigidbody_add_object(struct Main *bmain, + struct Scene *scene, + struct Object *ob, + int type, + struct ReportList *reports); +void BKE_rigidbody_ensure_local_object(struct Main *bmain, struct Object *ob); void BKE_rigidbody_remove_object(struct Main *bmain, struct Scene *scene, struct Object *ob); void BKE_rigidbody_remove_constraint(struct Scene *scene, struct Object *ob); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 5e54344c80e..974c6d6e0a6 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -57,6 +57,7 @@ #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_lightprobe_types.h" +#include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_speaker_types.h" @@ -2038,6 +2039,10 @@ void BKE_library_make_local(Main *bmain, id_clear_lib_data_ex(bmain, id, true); BKE_id_expand_local(bmain, id); id->tag &= ~LIB_TAG_DOIT; + + if (GS(id->name) == ID_OB) { + BKE_rigidbody_ensure_local_object(bmain, (Object *)id); + } } else { /* In this specific case, we do want to make ID local even if it has no local usage yet... @@ -2053,6 +2058,10 @@ void BKE_library_make_local(Main *bmain, } if (id->newid) { + if (GS(id->newid->name) == ID_OB) { + BKE_rigidbody_ensure_local_object(bmain, (Object *)id->newid); + } + /* Reuse already allocated LinkNode (transferring it from todo_ids to copied_ids). */ BLI_linklist_prepend_nlink(&copied_ids, id, it); } @@ -2178,25 +2187,6 @@ void BKE_library_make_local(Main *bmain, } } - /* Reset rigid body objects. */ - for (LinkNode *it = copied_ids; it; it = it->next) { - ID *id = it->link; - if (GS(id->name) == ID_OB) { - Object *ob = (Object *)id; - - /* If there was ever any rigidbody settings in the object, we reset it. */ - if (ob->rigidbody_object) { - for (Scene *scene_iter = bmain->scenes.first; scene_iter; - scene_iter = scene_iter->id.next) { - if (scene_iter->rigidbody_world) { - BKE_rigidbody_remove_object(bmain, scene_iter, ob); - } - } - BKE_rigidbody_free_object(ob, NULL); - } - } - } - #ifdef DEBUG_TIME printf("Hack: Forcefully rebuild armature object poses: Done.\n"); TIMEIT_VALUE_PRINT(make_local); diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index d4d753eb685..012f5f18910 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -56,6 +56,7 @@ #include "BKE_mesh_runtime.h" #include "BKE_object.h" #include "BKE_pointcache.h" +#include "BKE_report.h" #include "BKE_rigidbody.h" #include "BKE_scene.h" #ifdef WITH_BULLET @@ -1296,7 +1297,76 @@ RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene) return scene->rigidbody_world; } -void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob) +static bool rigidbody_add_object_to_scene(Main *bmain, Scene *scene, Object *ob) +{ + /* Add rigid body world and group if they don't exist for convenience */ + RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); + if (rbw == NULL) { + rbw = BKE_rigidbody_create_world(scene); + if (rbw == NULL) { + return false; + } + + BKE_rigidbody_validate_sim_world(scene, rbw, false); + scene->rigidbody_world = rbw; + } + + if (rbw->group == NULL) { + rbw->group = BKE_collection_add(bmain, NULL, "RigidBodyWorld"); + id_fake_user_set(&rbw->group->id); + } + + /* Add object to rigid body group. */ + BKE_collection_object_add(bmain, rbw->group, ob); + BKE_rigidbody_cache_reset(rbw); + + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&rbw->group->id, ID_RECALC_COPY_ON_WRITE); + + return true; +} + +void BKE_rigidbody_ensure_local_object(Main *bmain, Object *ob) +{ + if (ob->rigidbody_object == NULL) { + return; + } + + /* Add newly local object to scene. */ + for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { + if (BKE_scene_object_find(scene, ob)) { + rigidbody_add_object_to_scene(bmain, scene, ob); + } + } +} + +bool BKE_rigidbody_add_object(Main *bmain, Scene *scene, Object *ob, int type, ReportList *reports) +{ + if (ob->type != OB_MESH) { + BKE_report(reports, RPT_ERROR, "Can't add Rigid Body to non mesh object"); + return false; + } + + /* Add object to rigid body world in scene. */ + if (!rigidbody_add_object_to_scene(bmain, scene, ob)) { + BKE_report(reports, RPT_ERROR, "Can't create Rigid Body world"); + return false; + } + + /* make rigidbody object settings */ + if (ob->rigidbody_object == NULL) { + ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, type); + } + ob->rigidbody_object->type = type; + ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE; + + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); + + return true; +} + +void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob) { RigidBodyWorld *rbw = scene->rigidbody_world; RigidBodyCon *rbc; @@ -1343,6 +1413,10 @@ void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob) /* flag cache as outdated */ BKE_rigidbody_cache_reset(rbw); + + /* Dependency graph update */ + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); } void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob) diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c index ed6d31dfd9b..aa323dc53eb 100644 --- a/source/blender/editors/physics/rigidbody_object.c +++ b/source/blender/editors/physics/rigidbody_object.c @@ -86,43 +86,7 @@ static bool ED_operator_rigidbody_add_poll(bContext *C) bool ED_rigidbody_object_add(Main *bmain, Scene *scene, Object *ob, int type, ReportList *reports) { - RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); - - if (ob->type != OB_MESH) { - BKE_report(reports, RPT_ERROR, "Can't add Rigid Body to non mesh object"); - return false; - } - - /* Add rigid body world and group if they don't exist for convenience */ - if (rbw == NULL) { - rbw = BKE_rigidbody_create_world(scene); - if (rbw == NULL) { - BKE_report(reports, RPT_ERROR, "Can't create Rigid Body world"); - return false; - } - BKE_rigidbody_validate_sim_world(scene, rbw, false); - scene->rigidbody_world = rbw; - } - if (rbw->group == NULL) { - rbw->group = BKE_collection_add(bmain, NULL, "RigidBodyWorld"); - id_fake_user_set(&rbw->group->id); - } - - /* make rigidbody object settings */ - if (ob->rigidbody_object == NULL) { - ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, type); - } - ob->rigidbody_object->type = type; - ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE; - - /* add object to rigid body group */ - BKE_collection_object_add(bmain, rbw->group, ob); - - DEG_relations_tag_update(bmain); - DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); - DEG_id_tag_update(&rbw->group->id, ID_RECALC_COPY_ON_WRITE); - - return true; + return BKE_rigidbody_add_object(bmain, scene, ob, type, reports); } void ED_rigidbody_object_remove(Main *bmain, Scene *scene, Object *ob) |