Proper fix for rigidbody collections's objects missing rb data.

We cannot let those data be generated on-the-fly in RBW evaluation
anymore, since those would be added to CoW eval object and never ported
back to orig objects.

We *could* get orig objects in eval code, of course, but as in
constratints, this is not really threadsafe and future proof, depsgraph
evaluation should really write back to orig data as little as possible.

So instead, add code to ensure required data is generated to objects
when their collection is added to rigidbody world.

Note that we *may* want to clean that up once collection is no more used
by RB? On the other hand, people might want to keep those data around to
be able to switch between different setups easily... So think it's OK to
keep them at least for now.
This commit is contained in:
Bastien Montagne 2018-12-10 15:01:32 +01:00
parent 073a011f91
commit 7f98ba4725
5 changed files with 74 additions and 5 deletions

View File

@ -66,6 +66,10 @@ struct RigidBodyWorld *BKE_rigidbody_create_world(struct Scene *scene);
struct RigidBodyOb *BKE_rigidbody_create_object(struct Scene *scene, struct Object *ob, short type);
struct RigidBodyCon *BKE_rigidbody_create_constraint(struct Scene *scene, struct Object *ob, short type);
/* Ensure newly set collections' objects all have required data. */
void BKE_rigidbody_objects_collection_validate(struct Scene *scene, struct RigidBodyWorld *rbw);
void BKE_rigidbody_constraints_collection_validate(struct Scene *scene, struct RigidBodyWorld *rbw);
/* copy */
struct RigidBodyWorld *BKE_rigidbody_world_copy(struct RigidBodyWorld *rbw, const int flag);
void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw);

View File

@ -1069,6 +1069,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 +1100,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,6 +1145,35 @@ 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;
}
}
/* ************************************** */
/* Utilities API */
@ -1395,7 +1426,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 +1460,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 +1480,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 +1501,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;
}

View File

@ -83,6 +83,7 @@
#include "BKE_paint.h"
#include "BKE_pointcache.h"
#include "BKE_report.h"
#include "BKE_rigidbody.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
@ -2490,5 +2491,17 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
dir[0] = -dir[0];
}
}
/* Ensure we get valid rigidbody object/constraint data in relevant collections' objects. */
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
RigidBodyWorld *rbw = scene->rigidbody_world;
if (rbw == NULL) {
continue;
}
BKE_rigidbody_objects_collection_validate(scene, rbw);
BKE_rigidbody_constraints_collection_validate(scene, rbw);
}
}
}

View File

@ -89,7 +89,6 @@ bool ED_rigidbody_constraint_add(Main *bmain, Scene *scene, Object *ob, int type
}
/* make rigidbody constraint settings */
ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, type);
ob->rigidbody_constraint->flag |= RBC_FLAG_NEEDS_VALIDATE;
/* add constraint to rigid body constraint group */
BKE_collection_object_add(bmain, rbw->constraints, ob);

View File

@ -149,6 +149,22 @@ static void rna_RigidBodyWorld_split_impulse_set(PointerRNA *ptr, bool value)
#endif
}
static void rna_RigidBodyWorld_objects_collection_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
RigidBodyWorld *rbw = (RigidBodyWorld *)ptr->data;
BKE_rigidbody_objects_collection_validate(scene, rbw);
rna_RigidBodyWorld_reset(bmain, scene, ptr);
}
static void rna_RigidBodyWorld_constraints_collection_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
RigidBodyWorld *rbw = (RigidBodyWorld *)ptr->data;
BKE_rigidbody_constraints_collection_validate(scene, rbw);
rna_RigidBodyWorld_reset(bmain, scene, ptr);
}
/* ******************************** */
static void rna_RigidBodyOb_reset(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
@ -773,13 +789,13 @@ static void rna_def_rigidbody_world(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "group");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_ui_text(prop, "Collection", "Collection containing objects participating in this simulation");
RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset");
RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_objects_collection_update");
prop = RNA_def_property(srna, "constraints", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Collection");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_ui_text(prop, "Constraints", "Collection containing rigid body constraint objects");
RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset");
RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_constraints_collection_update");
/* booleans */
prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);