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
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2019-06-24 15:57:52 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-06-24 19:46:36 +0300
commita5ff780065bf6768811bf459953a1a1eabe989c1 (patch)
tree484c17b31a114495164e2a2979b91c2a266b05fc /source
parent7d3a28d2d9a568f020ab57ca9504d3dccba18e5b (diff)
Fix T63828, T62005: copy/paste or append loses rigid body object
Previously settings were removed, now add to the rigid body world automatically even if it's a bit ill defined, since this is confusing for users. Fundamentally the concept of a rigid body world collection could be revised, and left only as an optional thing.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_rigidbody.h7
-rw-r--r--source/blender/blenkernel/intern/library.c28
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c76
-rw-r--r--source/blender/editors/physics/rigidbody_object.c38
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)