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.c270
1 files changed, 141 insertions, 129 deletions
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 03fa4ec3cf2..91dd1e3dbaa 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -76,8 +76,10 @@
/* Freeing Methods --------------------- */
-#ifndef WITH_BULLET
+#ifdef WITH_BULLET
+static void rigidbody_update_ob_array(RigidBodyWorld *rbw);
+#else
static void RB_dworld_remove_constraint(void *UNUSED(world), void *UNUSED(con)) {}
static void RB_dworld_remove_body(void *UNUSED(world), void *UNUSED(body)) {}
static void RB_dworld_delete(void *UNUSED(world)) {}
@@ -88,13 +90,17 @@ static void RB_constraint_delete(void *UNUSED(con)) {}
#endif
/* Free rigidbody world */
-void BKE_rigidbody_free_world(RigidBodyWorld *rbw)
+void BKE_rigidbody_free_world(Scene *scene)
{
+ bool is_orig = (scene->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0;
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+ scene->rigidbody_world = NULL;
+
/* sanity check */
if (!rbw)
return;
- if (rbw->physics_world) {
+ if (is_orig && rbw->shared->physics_world) {
/* free physics references, we assume that all physics objects in will have been added to the world */
if (rbw->constraints) {
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, object)
@@ -102,7 +108,7 @@ void BKE_rigidbody_free_world(RigidBodyWorld *rbw)
if (object->rigidbody_constraint) {
RigidBodyCon *rbc = object->rigidbody_constraint;
if (rbc->physics_constraint) {
- RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+ RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
}
}
}
@@ -112,24 +118,23 @@ void BKE_rigidbody_free_world(RigidBodyWorld *rbw)
if (rbw->group) {
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
{
- if (object->rigidbody_object) {
- RigidBodyOb *rbo = object->rigidbody_object;
- if (rbo->physics_object) {
- RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
- }
- }
+ BKE_rigidbody_free_object(object, rbw);
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
/* free dynamics world */
- RB_dworld_delete(rbw->physics_world);
+ RB_dworld_delete(rbw->shared->physics_world);
}
if (rbw->objects)
free(rbw->objects);
- /* free cache */
- BKE_ptcache_free_list(&(rbw->ptcaches));
- rbw->pointcache = NULL;
+ if (is_orig) {
+ /* free cache */
+ BKE_ptcache_free_list(&(rbw->shared->ptcaches));
+ rbw->shared->pointcache = NULL;
+
+ MEM_freeN(rbw->shared);
+ }
/* free effector weights */
if (rbw->effector_weights)
@@ -140,8 +145,9 @@ void BKE_rigidbody_free_world(RigidBodyWorld *rbw)
}
/* Free RigidBody settings and sim instances */
-void BKE_rigidbody_free_object(Object *ob)
+void BKE_rigidbody_free_object(Object *ob, RigidBodyWorld *rbw)
{
+ bool is_orig = (ob->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0;
RigidBodyOb *rbo = (ob) ? ob->rigidbody_object : NULL;
/* sanity check */
@@ -149,14 +155,26 @@ void BKE_rigidbody_free_object(Object *ob)
return;
/* free physics references */
- if (rbo->physics_object) {
- RB_body_delete(rbo->physics_object);
- rbo->physics_object = NULL;
- }
+ if (is_orig) {
+ if (rbo->shared->physics_object) {
+ BLI_assert(rbw);
+ if (rbw) {
+ /* 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);
+ }
+
+ RB_body_delete(rbo->shared->physics_object);
+ rbo->shared->physics_object = NULL;
+ }
+
+ if (rbo->shared->physics_shape) {
+ RB_shape_delete(rbo->shared->physics_shape);
+ rbo->shared->physics_shape = NULL;
+ }
- if (rbo->physics_shape) {
- RB_shape_delete(rbo->physics_shape);
- rbo->physics_shape = NULL;
+ MEM_freeN(rbo->shared);
}
/* free data itself */
@@ -193,7 +211,7 @@ void BKE_rigidbody_free_constraint(Object *ob)
* be added to relevant groups later...
*/
-RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int UNUSED(flag))
+RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int flag)
{
RigidBodyOb *rboN = NULL;
@@ -201,12 +219,13 @@ RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int UNUSED(flag))
/* just duplicate the whole struct first (to catch all the settings) */
rboN = MEM_dupallocN(ob->rigidbody_object);
+ if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ /* This is a regular copy, and not a CoW copy for depsgraph evaluation */
+ rboN->shared = MEM_callocN(sizeof(*rboN->shared), "RigidBodyOb_Shared");
+ }
+
/* tag object as needing to be verified */
rboN->flag |= RBO_FLAG_NEEDS_VALIDATE;
-
- /* clear out all the fields which need to be revalidated later */
- rboN->physics_object = NULL;
- rboN->physics_shape = NULL;
}
/* return new copy of settings */
@@ -387,7 +406,7 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
return;
/* don't create a new shape if we already have one and don't want to rebuild it */
- if (rbo->physics_shape && !rebuild)
+ if (rbo->shared->physics_shape && !rebuild)
return;
/* if automatically determining dimensions, use the Object's boundbox
@@ -451,15 +470,16 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
break;
}
/* use box shape if we can't fall back to old shape */
- if (new_shape == NULL && rbo->physics_shape == NULL) {
+ if (new_shape == NULL && rbo->shared->physics_shape == NULL) {
new_shape = RB_shape_new_box(size[0], size[1], size[2]);
}
/* assign new collision shape if creation was successful */
if (new_shape) {
- if (rbo->physics_shape)
- RB_shape_delete(rbo->physics_shape);
- rbo->physics_shape = new_shape;
- RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo));
+ if (rbo->shared->physics_shape) {
+ RB_shape_delete(rbo->shared->physics_shape);
+ }
+ rbo->shared->physics_shape = new_shape;
+ RB_shape_set_margin(rbo->shared->physics_shape, RBO_GET_MARGIN(rbo));
}
}
@@ -650,48 +670,48 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
/* make sure collision shape exists */
/* FIXME we shouldn't always have to rebuild collision shapes when rebuilding objects, but it's needed for constraints to update correctly */
- if (rbo->physics_shape == NULL || rebuild)
+ if (rbo->shared->physics_shape == NULL || rebuild)
rigidbody_validate_sim_shape(ob, true);
- if (rbo->physics_object && rebuild == false) {
- RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
+ if (rbo->shared->physics_object) {
+ RB_dworld_remove_body(rbw->shared->physics_world, rbo->shared->physics_object);
}
- if (!rbo->physics_object || rebuild) {
+ if (!rbo->shared->physics_object || rebuild) {
/* remove rigid body if it already exists before creating a new one */
- if (rbo->physics_object) {
- RB_body_delete(rbo->physics_object);
+ if (rbo->shared->physics_object) {
+ RB_body_delete(rbo->shared->physics_object);
}
mat4_to_loc_quat(loc, rot, ob->obmat);
- rbo->physics_object = RB_body_new(rbo->physics_shape, loc, rot);
+ rbo->shared->physics_object = RB_body_new(rbo->shared->physics_shape, loc, rot);
- RB_body_set_friction(rbo->physics_object, rbo->friction);
- RB_body_set_restitution(rbo->physics_object, rbo->restitution);
+ RB_body_set_friction(rbo->shared->physics_object, rbo->friction);
+ RB_body_set_restitution(rbo->shared->physics_object, rbo->restitution);
- RB_body_set_damping(rbo->physics_object, rbo->lin_damping, rbo->ang_damping);
- RB_body_set_sleep_thresh(rbo->physics_object, rbo->lin_sleep_thresh, rbo->ang_sleep_thresh);
- RB_body_set_activation_state(rbo->physics_object, rbo->flag & RBO_FLAG_USE_DEACTIVATION);
+ RB_body_set_damping(rbo->shared->physics_object, rbo->lin_damping, rbo->ang_damping);
+ RB_body_set_sleep_thresh(rbo->shared->physics_object, rbo->lin_sleep_thresh, rbo->ang_sleep_thresh);
+ RB_body_set_activation_state(rbo->shared->physics_object, rbo->flag & RBO_FLAG_USE_DEACTIVATION);
if (rbo->type == RBO_TYPE_PASSIVE || rbo->flag & RBO_FLAG_START_DEACTIVATED)
- RB_body_deactivate(rbo->physics_object);
+ RB_body_deactivate(rbo->shared->physics_object);
- RB_body_set_linear_factor(rbo->physics_object,
+ RB_body_set_linear_factor(rbo->shared->physics_object,
(ob->protectflag & OB_LOCK_LOCX) == 0,
(ob->protectflag & OB_LOCK_LOCY) == 0,
(ob->protectflag & OB_LOCK_LOCZ) == 0);
- RB_body_set_angular_factor(rbo->physics_object,
+ RB_body_set_angular_factor(rbo->shared->physics_object,
(ob->protectflag & OB_LOCK_ROTX) == 0,
(ob->protectflag & OB_LOCK_ROTY) == 0,
(ob->protectflag & OB_LOCK_ROTZ) == 0);
- RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
- RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
+ RB_body_set_mass(rbo->shared->physics_object, RBO_GET_MASS(rbo));
+ RB_body_set_kinematic_state(rbo->shared->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
}
- if (rbw && rbw->physics_world)
- RB_dworld_add_body(rbw->physics_world, rbo->physics_object, rbo->col_groups);
+ if (rbw && rbw->shared->physics_world)
+ RB_dworld_add_body(rbw->shared->physics_world, rbo->shared->physics_object, rbo->col_groups);
}
/* --------------------- */
@@ -755,7 +775,7 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b
if (ELEM(NULL, rbc->ob1, rbc->ob1->rigidbody_object, rbc->ob2, rbc->ob2->rigidbody_object)) {
if (rbc->physics_constraint) {
- RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+ RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
RB_constraint_delete(rbc->physics_constraint);
rbc->physics_constraint = NULL;
}
@@ -763,11 +783,11 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b
}
if (rbc->physics_constraint && rebuild == false) {
- RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+ RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
}
if (rbc->physics_constraint == NULL || rebuild) {
- rbRigidBody *rb1 = rbc->ob1->rigidbody_object->physics_object;
- rbRigidBody *rb2 = rbc->ob2->rigidbody_object->physics_object;
+ rbRigidBody *rb1 = rbc->ob1->rigidbody_object->shared->physics_object;
+ rbRigidBody *rb2 = rbc->ob2->rigidbody_object->shared->physics_object;
/* remove constraint if it already exists before creating a new one */
if (rbc->physics_constraint) {
@@ -882,8 +902,8 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b
RB_constraint_set_solver_iterations(rbc->physics_constraint, -1);
}
- if (rbw && rbw->physics_world && rbc->physics_constraint) {
- RB_dworld_add_constraint(rbw->physics_world, rbc->physics_constraint, rbc->flag & RBC_FLAG_DISABLE_COLLISIONS);
+ if (rbw && rbw->shared->physics_world && rbc->physics_constraint) {
+ RB_dworld_add_constraint(rbw->shared->physics_world, rbc->physics_constraint, rbc->flag & RBC_FLAG_DISABLE_COLLISIONS);
}
}
@@ -898,14 +918,14 @@ void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool re
return;
/* create new sim world */
- if (rebuild || rbw->physics_world == NULL) {
- if (rbw->physics_world)
- RB_dworld_delete(rbw->physics_world);
- rbw->physics_world = RB_dworld_new(scene->physics_settings.gravity);
+ if (rebuild || rbw->shared->physics_world == NULL) {
+ if (rbw->shared->physics_world)
+ RB_dworld_delete(rbw->shared->physics_world);
+ rbw->shared->physics_world = RB_dworld_new(scene->physics_settings.gravity);
}
- RB_dworld_set_solver_iterations(rbw->physics_world, rbw->num_solver_iterations);
- RB_dworld_set_split_impulse(rbw->physics_world, rbw->flag & RBW_FLAG_USE_SPLIT_IMPULSE);
+ RB_dworld_set_solver_iterations(rbw->shared->physics_world, rbw->num_solver_iterations);
+ RB_dworld_set_split_impulse(rbw->shared->physics_world, rbw->flag & RBW_FLAG_USE_SPLIT_IMPULSE);
}
/* ************************************** */
@@ -926,6 +946,7 @@ RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
/* create a new sim world */
rbw = MEM_callocN(sizeof(RigidBodyWorld), "RigidBodyWorld");
+ rbw->shared = MEM_callocN(sizeof(*rbw->shared), "RigidBodyWorld_Shared");
/* set default settings */
rbw->effector_weights = BKE_add_effector_weights(NULL);
@@ -937,8 +958,8 @@ RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
rbw->steps_per_second = 60; /* Bullet default (60 Hz) */
rbw->num_solver_iterations = 10; /* 10 is bullet default */
- rbw->pointcache = BKE_ptcache_add(&(rbw->ptcaches));
- rbw->pointcache->step = 1;
+ rbw->shared->pointcache = BKE_ptcache_add(&(rbw->shared->ptcaches));
+ rbw->shared->pointcache->step = 1;
/* return this sim world */
return rbw;
@@ -956,12 +977,16 @@ RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag)
id_us_plus((ID *)rbw_copy->constraints);
}
- /* XXX Never copy caches here? */
- rbw_copy->pointcache = BKE_ptcache_copy_list(&rbw_copy->ptcaches, &rbw->ptcaches, flag & ~LIB_ID_COPY_CACHES);
+ if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ /* This is a regular copy, and not a CoW copy for depsgraph evaluation */
+ rbw_copy->shared = MEM_callocN(sizeof(*rbw_copy->shared), "RigidBodyWorld_Shared");
+ BKE_ptcache_copy_list(&rbw_copy->shared->ptcaches, &rbw->shared->ptcaches, LIB_ID_COPY_CACHES);
+ rbw_copy->shared->pointcache = rbw_copy->shared->ptcaches.first;
+ }
rbw_copy->objects = NULL;
- rbw_copy->physics_world = NULL;
rbw_copy->numbodies = 0;
+ rigidbody_update_ob_array(rbw_copy);
return rbw_copy;
}
@@ -1003,6 +1028,7 @@ RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
/* create new settings data, and link it up */
rbo = MEM_callocN(sizeof(RigidBodyOb), "RigidBodyOb");
+ rbo->shared = MEM_callocN(sizeof(*rbo->shared), "RigidBodyOb_Shared");
/* set default settings */
rbo->type = type;
@@ -1128,14 +1154,10 @@ RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene)
void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob)
{
RigidBodyWorld *rbw = scene->rigidbody_world;
- RigidBodyOb *rbo = ob->rigidbody_object;
RigidBodyCon *rbc;
int i;
if (rbw) {
- /* remove from rigidbody world, free object won't do this */
- if (rbw->physics_world && rbo->physics_object)
- RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
/* remove object from array */
if (rbw && rbw->objects) {
@@ -1164,7 +1186,7 @@ void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob)
}
/* remove object's settings */
- BKE_rigidbody_free_object(ob);
+ BKE_rigidbody_free_object(ob, rbw);
/* flag cache as outdated */
BKE_rigidbody_cache_reset(rbw);
@@ -1176,8 +1198,8 @@ void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
RigidBodyCon *rbc = ob->rigidbody_constraint;
/* remove from rigidbody world, free object won't do this */
- if (rbw && rbw->physics_world && rbc->physics_constraint) {
- RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+ if (rbw && 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);
@@ -1193,6 +1215,12 @@ void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
/* Update object array and rigid body count so they're in sync with the rigid body group */
static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
{
+ if (rbw->group == NULL) {
+ rbw->numbodies = 0;
+ rbw->objects = realloc(rbw->objects, 0);
+ return;
+ }
+
int n = 0;
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
{
@@ -1229,7 +1257,7 @@ static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw)
}
/* update gravity, since this RNA setting is not part of RigidBody settings */
- RB_dworld_set_gravity(rbw->physics_world, adj_gravity);
+ RB_dworld_set_gravity(rbw->shared->physics_world, adj_gravity);
/* update object array in case there are changes */
rigidbody_update_ob_array(rbw);
@@ -1242,7 +1270,7 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Scene *scene, RigidBod
float scale[3];
/* only update if rigid body exists */
- if (rbo->physics_object == NULL)
+ if (rbo->shared->physics_object == NULL)
return;
if (rbo->shape == RB_SHAPE_TRIMESH && rbo->flag & RBO_FLAG_USE_DEFORM) {
@@ -1252,28 +1280,28 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Scene *scene, RigidBod
int totvert = mesh->totvert;
BoundBox *bb = BKE_object_boundbox_get(ob);
- RB_shape_trimesh_update(rbo->physics_shape, (float *)mvert, totvert, sizeof(MVert), bb->vec[0], bb->vec[6]);
+ RB_shape_trimesh_update(rbo->shared->physics_shape, (float *)mvert, totvert, sizeof(MVert), bb->vec[0], bb->vec[6]);
}
}
mat4_decompose(loc, rot, scale, ob->obmat);
/* update scale for all objects */
- RB_body_set_scale(rbo->physics_object, scale);
+ RB_body_set_scale(rbo->shared->physics_object, scale);
/* compensate for embedded convex hull collision margin */
if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && rbo->shape == RB_SHAPE_CONVEXH)
- RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo) * MIN3(scale[0], scale[1], scale[2]));
+ RB_shape_set_margin(rbo->shared->physics_shape, RBO_GET_MARGIN(rbo) * MIN3(scale[0], scale[1], scale[2]));
/* make transformed objects temporarily kinmatic so that they can be moved by the user during simulation */
if (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ) {
- RB_body_set_kinematic_state(rbo->physics_object, true);
- RB_body_set_mass(rbo->physics_object, 0.0f);
+ RB_body_set_kinematic_state(rbo->shared->physics_object, true);
+ RB_body_set_mass(rbo->shared->physics_object, 0.0f);
}
/* update rigid body location and rotation for kinematic bodies */
if (rbo->flag & RBO_FLAG_KINEMATIC || (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
- RB_body_activate(rbo->physics_object);
- RB_body_set_loc_rot(rbo->physics_object, loc, rot);
+ RB_body_activate(rbo->shared->physics_object);
+ RB_body_set_loc_rot(rbo->shared->physics_object, loc, rot);
}
/* update influence of effectors - but don't do it on an effector */
/* only dynamic bodies need effector update */
@@ -1290,8 +1318,8 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Scene *scene, RigidBod
/* create dummy 'point' which represents last known position of object as result of sim */
// XXX: this can create some inaccuracies with sim position, but is probably better than using unsimulated vals?
- RB_body_get_position(rbo->physics_object, eff_loc);
- RB_body_get_linear_velocity(rbo->physics_object, eff_vel);
+ RB_body_get_position(rbo->shared->physics_object, eff_loc);
+ RB_body_get_linear_velocity(rbo->shared->physics_object, eff_vel);
pd_point_from_loc(scene, eff_loc, eff_vel, 0, &epoint);
@@ -1303,8 +1331,8 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Scene *scene, RigidBod
printf("\tapplying force (%f,%f,%f) to '%s'\n", eff_force[0], eff_force[1], eff_force[2], ob->id.name + 2);
/* activate object in case it is deactivated */
if (!is_zero_v3(eff_force))
- RB_body_activate(rbo->physics_object);
- RB_body_apply_central_force(rbo->physics_object, eff_force);
+ RB_body_activate(rbo->shared->physics_object);
+ RB_body_apply_central_force(rbo->shared->physics_object, eff_force);
}
else if (G.f & G_DEBUG)
printf("\tno forces to apply to '%s'\n", ob->id.name + 2);
@@ -1342,7 +1370,7 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph, Scene *scene, Rigi
{
RigidBodyCon *rbc = ob->rigidbody_constraint;
if (rbc && rbc->physics_constraint) {
- RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+ RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
RB_constraint_delete(rbc->physics_constraint);
rbc->physics_constraint = NULL;
}
@@ -1374,6 +1402,9 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph, Scene *scene, Rigi
/* refresh object... */
if (rebuild) {
/* World has been rebuilt so rebuild object */
+ /* TODO(Sybren): rigidbody_validate_sim_object() can call rigidbody_validate_sim_shape(),
+ * but neither resets the RBO_FLAG_NEEDS_RESHAPE flag nor calls RB_body_set_collision_shape().
+ * This results in the collision shape being created twice, which is unnecessary. */
rigidbody_validate_sim_object(rbw, ob, true);
}
else if (rbo->flag & RBO_FLAG_NEEDS_VALIDATE) {
@@ -1385,7 +1416,7 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph, Scene *scene, Rigi
rigidbody_validate_sim_shape(ob, true);
/* now tell RB sim about it */
// 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->physics_object, rbo->physics_shape);
+ RB_body_set_collision_shape(rbo->shared->physics_object, rbo->shared->physics_shape);
}
rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE);
}
@@ -1441,11 +1472,11 @@ static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBod
RigidBodyOb *rbo = ob->rigidbody_object;
/* Reset kinematic state for transformed objects. */
if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) {
- RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
- RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
+ RB_body_set_kinematic_state(rbo->shared->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
+ RB_body_set_mass(rbo->shared->physics_object, RBO_GET_MASS(rbo));
/* Deactivate passive objects so they don't interfere with deactivation of active objects. */
if (rbo->type == RBO_TYPE_PASSIVE)
- RB_body_deactivate(rbo->physics_object);
+ RB_body_deactivate(rbo->shared->physics_object);
}
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
@@ -1453,7 +1484,7 @@ static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBod
bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime)
{
- return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0 && ctime > rbw->pointcache->startframe);
+ return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0 && ctime > rbw->shared->pointcache->startframe);
}
/* Sync rigid body and object transformations */
@@ -1543,11 +1574,11 @@ void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], flo
copy_qt_qt(ob->quat, quat);
}
- if (rbo->physics_object) {
+ if (rbo->shared->physics_object) {
/* allow passive objects to return to original transform */
if (rbo->type == RBO_TYPE_PASSIVE)
- RB_body_set_kinematic_state(rbo->physics_object, true);
- RB_body_set_loc_rot(rbo->physics_object, rbo->pos, rbo->orn);
+ RB_body_set_kinematic_state(rbo->shared->physics_object, true);
+ RB_body_set_loc_rot(rbo->shared->physics_object, rbo->pos, rbo->orn);
}
// RB_TODO update rigid body physics object's loc/rot for dynamic objects here as well (needs to be done outside bullet's update loop)
}
@@ -1555,7 +1586,7 @@ void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], flo
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
{
if (rbw) {
- rbw->pointcache->flag |= PTCACHE_OUTDATED;
+ rbw->shared->pointcache->flag |= PTCACHE_OUTDATED;
}
}
@@ -1572,7 +1603,7 @@ void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime
BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
- cache = rbw->pointcache;
+ cache = rbw->shared->pointcache;
/* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */
int n = 0;
@@ -1583,7 +1614,7 @@ void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
- if (rbw->physics_world == NULL || rbw->numbodies != n) {
+ if (rbw->shared->physics_world == NULL || rbw->numbodies != n) {
cache->flag |= PTCACHE_OUTDATED;
}
@@ -1609,7 +1640,7 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
- cache = rbw->pointcache;
+ cache = rbw->shared->pointcache;
if (ctime <= startframe) {
rbw->ltime = startframe;
@@ -1621,7 +1652,7 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
}
/* don't try to run the simulation if we don't have a world yet but allow reading baked cache */
- if (rbw->physics_world == NULL && !(cache->flag & PTCACHE_BAKED))
+ if (rbw->shared->physics_world == NULL && !(cache->flag & PTCACHE_BAKED))
return;
else if (rbw->objects == NULL)
rigidbody_update_ob_array(rbw);
@@ -1636,6 +1667,12 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
return;
}
+ if (!DEG_is_active(depsgraph)) {
+ /* When the depsgraph is inactive we should neither write to the cache
+ * nor run the simulation. */
+ return;
+ }
+
/* advance simulation, we can only step one frame forward */
if (compare_ff_relative(ctime, rbw->ltime + 1, FLT_EPSILON, 64)) {
/* write cache for first frame when on second frame */
@@ -1649,7 +1686,7 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
/* calculate how much time elapsed since last step in seconds */
timestep = 1.0f / (float)FPS * (ctime - rbw->ltime) * rbw->time_scale;
/* step simulation by the requested timestep, steps per second are adjusted to take time scale into account */
- RB_dworld_step_simulation(rbw->physics_world, timestep, INT_MAX, 1.0f / (float)rbw->steps_per_second * min_ff(rbw->time_scale, 1.0f));
+ RB_dworld_step_simulation(rbw->shared->physics_world, timestep, INT_MAX, 1.0f / (float)rbw->steps_per_second * min_ff(rbw->time_scale, 1.0f));
rigidbody_update_simulation_post_step(depsgraph, rbw);
@@ -1698,25 +1735,6 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
#endif /* WITH_BULLET */
-/* Copy the pointcache from the evaluated to the original scene.
- * This allows the re-evaluation of the original scene to use the
- * physics cache.
- */
-static void rigidbody_copy_cache_to_orig(Scene *scene_eval)
-{
- if ((scene_eval->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0) {
- /* Scene is already an original, this function is a no-op. */
- return;
- }
-
- Scene *scene_orig = (Scene *)DEG_get_original_id(&scene_eval->id);
- RigidBodyWorld *rbw_orig = scene_orig->rigidbody_world;
- RigidBodyWorld *rbw_eval = scene_eval->rigidbody_world;
-
- BKE_ptcache_free_list(&rbw_orig->ptcaches);
- rbw_orig->pointcache = BKE_ptcache_copy_list(&rbw_orig->ptcaches, &rbw_eval->ptcaches, LIB_ID_COPY_CACHES);
-}
-
/* -------------------- */
/* Depsgraph evaluation */
@@ -1743,12 +1761,6 @@ void BKE_rigidbody_eval_simulation(Depsgraph *depsgraph,
return;
}
BKE_rigidbody_do_simulation(depsgraph, scene, ctime);
-
- /* Make sure re-evaluation can use the cache from this simulation */
- if (!DEG_is_active(depsgraph)) {
- return;
- }
- rigidbody_copy_cache_to_orig(scene);
}
void BKE_rigidbody_object_sync_transforms(Depsgraph *depsgraph,