Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / rigidbody.c
index 9ca8c834bb98a4b3a23a314aead805478ac8bc9c..4e6d6cf097166ea935bd62a60fe89ddbd518fb3d 100644 (file)
@@ -61,6 +61,7 @@
 #include "BKE_layer.h"
 #include "BKE_library.h"
 #include "BKE_library_query.h"
+#include "BKE_main.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_runtime.h"
 #include "BKE_object.h"
@@ -642,7 +643,7 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
 /**
  * Create physics sim representation of object given RigidBody settings
  *
- * \param rebuild Even if an instance already exists, replace it
+ * \param rebuild: Even if an instance already exists, replace it
  */
 static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool rebuild)
 {
@@ -770,7 +771,7 @@ static void rigidbody_constraint_set_limits(
 /**
  * Create physics sim representation of constraint given rigid body constraint settings
  *
- * \param rebuild Even if an instance already exists, replace it
+ * \param rebuild: Even if an instance already exists, replace it
  */
 static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, bool rebuild)
 {
@@ -1069,6 +1070,7 @@ RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
 
        /* flag cache as outdated */
        BKE_rigidbody_cache_reset(rbw);
+       rbo->flag |= (RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE);
 
        /* return this object */
        return rbo;
@@ -1099,6 +1101,7 @@ RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short ty
 
        rbc->flag |= RBC_FLAG_ENABLED;
        rbc->flag |= RBC_FLAG_DISABLE_COLLISIONS;
+       rbc->flag |= RBC_FLAG_NEEDS_VALIDATE;
 
        rbc->spring_type = RBC_SPRING_TYPE2;
 
@@ -1143,12 +1146,58 @@ RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short ty
        return rbc;
 }
 
+void BKE_rigidbody_objects_collection_validate(Scene *scene, RigidBodyWorld *rbw)
+{
+       if (rbw->group != NULL) {
+               FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
+               {
+                       if (object->type != OB_MESH || object->rigidbody_object != NULL) {
+                               continue;
+                       }
+                       object->rigidbody_object = BKE_rigidbody_create_object(scene, object, RBO_TYPE_ACTIVE);
+               }
+               FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+       }
+}
+
+void BKE_rigidbody_constraints_collection_validate(Scene *scene, RigidBodyWorld *rbw)
+{
+       if (rbw->constraints != NULL) {
+               FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, object)
+               {
+                       if (object->rigidbody_constraint != NULL) {
+                               continue;
+                       }
+                       object->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, object, RBC_TYPE_FIXED);
+               }
+               FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+       }
+}
+
+void BKE_rigidbody_main_collection_object_add(Main *bmain, Collection *collection, Object *object)
+{
+       for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
+               RigidBodyWorld *rbw = scene->rigidbody_world;
+
+               if (rbw == NULL) {
+                       continue;
+               }
+
+               if (rbw->group == collection && object->type == OB_MESH && object->rigidbody_object == NULL) {
+                       object->rigidbody_object = BKE_rigidbody_create_object(scene, object, RBO_TYPE_ACTIVE);
+               }
+               if (rbw->constraints == collection && object->rigidbody_constraint == NULL) {
+                       object->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, object, RBC_TYPE_FIXED);
+               }
+       }
+}
+
 /* ************************************** */
 /* Utilities API */
 
 /* Get RigidBody world for the given scene, creating one if needed
  *
- * \param scene Scene to find active Rigid Body world for
+ * \param scene: Scene to find active Rigid Body world for
  */
 RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene)
 {
@@ -1358,7 +1407,7 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Scene *scene, RigidBod
 /**
  * Updates and validates world, bodies and shapes.
  *
- * \param rebuild Rebuild entire simulation
+ * \param rebuild: Rebuild entire simulation
  */
 static void rigidbody_update_simulation(Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, bool rebuild)
 {
@@ -1395,7 +1444,10 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph, Scene *scene, Rigi
                        /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
                        BKE_object_where_is_calc(depsgraph, scene, ob);
 
+                       /* TODO remove this whole block once we are sure we never get NULL rbo here anymore. */
+                       /* This cannot be done in CoW evaluation context anymore... */
                        if (rbo == NULL) {
+                               BLI_assert(!"CoW object part of RBW object collection without RB object data, should not happen.\n");
                                /* Since this object is included in the sim group but doesn't have
                                 * rigid body settings (perhaps it was added manually), add!
                                 * - assume object to be active? That is the default for newly added settings...
@@ -1426,8 +1478,8 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph, Scene *scene, Rigi
                                        // XXX: we assume that this can only get applied for active/passive shapes that will be included as rigidbodies
                                        RB_body_set_collision_shape(rbo->shared->physics_object, rbo->shared->physics_shape);
                                }
-                               rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE);
                        }
+                       rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE);
 
                        /* update simulation object... */
                        rigidbody_update_sim_ob(depsgraph, scene, rbw, ob, rbo);
@@ -1446,7 +1498,10 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph, Scene *scene, Rigi
                /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
                BKE_object_where_is_calc(depsgraph, scene, ob);
 
+               /* TODO remove this whole block once we are sure we never get NULL rbo here anymore. */
+               /* This cannot be done in CoW evaluation context anymore... */
                if (rbc == NULL) {
+                       BLI_assert(!"CoW object part of RBW constraints collection without RB constraint data, should not happen.\n");
                        /* Since this object is included in the group but doesn't have
                         * constraint settings (perhaps it was added manually), add!
                         */
@@ -1464,8 +1519,8 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph, Scene *scene, Rigi
                        else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) {
                                rigidbody_validate_sim_constraint(rbw, ob, false);
                        }
-                       rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE;
                }
+               rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE;
        }
        FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
 }
@@ -1735,6 +1790,9 @@ bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) { return
 void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
 void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime) {}
 void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime) {}
+void BKE_rigidbody_objects_collection_validate(Scene *scene, RigidBodyWorld *rbw) {}
+void BKE_rigidbody_constraints_collection_validate(Scene *scene, RigidBodyWorld *rbw) {}
+void BKE_rigidbody_main_collection_object_add(Main *bmain, Collection *collection, Object *object) {}
 
 #if defined(__GNUC__) || defined(__clang__)
 #  pragma GCC diagnostic pop