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:
parent
073a011f91
commit
7f98ba4725
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue