diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_rigidbody.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pointcache.c | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/rigidbody.c | 270 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 3 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 47 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 29 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 7 | ||||
-rw-r--r-- | source/blender/editors/physics/rigidbody_world.c | 7 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_rigidbody_types.h | 37 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_rigidbody.c | 71 |
11 files changed, 284 insertions, 203 deletions
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h index b7d27cc7101..1fa8106d63b 100644 --- a/source/blender/blenkernel/BKE_rigidbody.h +++ b/source/blender/blenkernel/BKE_rigidbody.h @@ -44,8 +44,8 @@ struct Object; /* -------------- */ /* Memory Management */ -void BKE_rigidbody_free_world(struct RigidBodyWorld *rbw); -void BKE_rigidbody_free_object(struct Object *ob); +void BKE_rigidbody_free_world(struct Scene *scene); +void BKE_rigidbody_free_object(struct Object *ob, struct RigidBodyWorld *rbw); void BKE_rigidbody_free_constraint(struct Object *ob); /* ...... */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 210e6f096b8..8295fccc810 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -449,7 +449,7 @@ void BKE_object_free(Object *ob) BKE_constraints_free_ex(&ob->constraints, false); free_partdeflect(ob->pd); - BKE_rigidbody_free_object(ob); + BKE_rigidbody_free_object(ob, NULL); BKE_rigidbody_free_constraint(ob); if (ob->soft) { diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 3e8e6a69dd8..a8c6091124a 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1295,8 +1295,8 @@ static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int UNUS if (rbo->type == RBO_TYPE_ACTIVE) { #ifdef WITH_BULLET - RB_body_get_position(rbo->physics_object, rbo->pos); - RB_body_get_orientation(rbo->physics_object, rbo->orn); + RB_body_get_position(rbo->shared->physics_object, rbo->pos); + RB_body_get_orientation(rbo->shared->physics_object, rbo->orn); #endif PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, rbo->pos); PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, rbo->orn); @@ -1619,9 +1619,9 @@ void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, Object *ob, RigidBodyWorld *r pid->ob= ob; pid->calldata= rbw; pid->type= PTCACHE_TYPE_RIGIDBODY; - pid->cache= rbw->pointcache; - pid->cache_ptr= &rbw->pointcache; - pid->ptcaches= &rbw->ptcaches; + pid->cache= rbw->shared->pointcache; + pid->cache_ptr= &rbw->shared->pointcache; + pid->ptcaches= &rbw->shared->ptcaches; pid->totpoint= pid->totwrite= ptcache_rigidbody_totpoint; pid->error = ptcache_rigidbody_error; 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, diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 35429496662..a38384f8f2b 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -461,8 +461,7 @@ void BKE_scene_free_ex(Scene *sce, const bool do_id_user) } if (sce->rigidbody_world) { - BKE_rigidbody_free_world(sce->rigidbody_world); - sce->rigidbody_world = NULL; + BKE_rigidbody_free_world(sce); } if (sce->r.avicodecdata) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9166caff5e0..c94a565216a 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5476,12 +5476,8 @@ static void direct_link_object(FileData *fd, Object *ob) ob->rigidbody_object = newdataadr(fd, ob->rigidbody_object); if (ob->rigidbody_object) { RigidBodyOb *rbo = ob->rigidbody_object; - - /* must nullify the references to physics sim objects, since they no-longer exist - * (and will need to be recalculated) - */ - rbo->physics_object = NULL; - rbo->physics_shape = NULL; + /* Allocate runtime-only struct */ + rbo->shared = MEM_callocN(sizeof(*rbo->shared), "RigidBodyObShared"); } ob->rigidbody_constraint = newdataadr(fd, ob->rigidbody_constraint); if (ob->rigidbody_constraint) @@ -6280,10 +6276,34 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->rigidbody_world = newdataadr(fd, sce->rigidbody_world); rbw = sce->rigidbody_world; if (rbw) { - /* must nullify the reference to physics sim object, since it no-longer exist - * (and will need to be recalculated) - */ - rbw->physics_world = NULL; + rbw->shared = newdataadr(fd, rbw->shared); + + if (rbw->shared == NULL) { + /* Link deprecated caches if they exist, so we can use them for versioning. + * We should only do this when rbw->shared == NULL, because those pointers + * are always set (for compatibility with older Blenders). We mustn't link + * the same pointcache twice. */ + direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, false); + + /* make sure simulation starts from the beginning after loading file */ + if (rbw->pointcache) { + rbw->ltime = (float)rbw->pointcache->startframe; + } + } + else { + /* must nullify the reference to physics sim object, since it no-longer exist + * (and will need to be recalculated) + */ + rbw->shared->physics_world = NULL; + + /* link caches */ + direct_link_pointcache_list(fd, &rbw->shared->ptcaches, &rbw->shared->pointcache, false); + + /* make sure simulation starts from the beginning after loading file */ + if (rbw->shared->pointcache) { + rbw->ltime = (float)rbw->shared->pointcache->startframe; + } + } rbw->objects = NULL; rbw->numbodies = 0; @@ -6291,13 +6311,6 @@ static void direct_link_scene(FileData *fd, Scene *sce) rbw->effector_weights = newdataadr(fd, rbw->effector_weights); if (!rbw->effector_weights) rbw->effector_weights = BKE_add_effector_weights(NULL); - - /* link cache */ - direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, false); - /* make sure simulation starts from the beginning after loading file */ - if (rbw->pointcache) { - rbw->ltime = (float)rbw->pointcache->startframe; - } } sce->preview = direct_link_preview_image(fd, sce->preview); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 06017668c02..3fa059989a3 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -49,6 +49,7 @@ #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_particle_types.h" +#include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_view3d_types.h" @@ -65,6 +66,7 @@ #include "BKE_main.h" #include "BKE_mesh.h" #include "BKE_node.h" +#include "BKE_pointcache.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" @@ -1530,5 +1532,32 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) scene->toolsettings->manipulator_flag = SCE_MANIP_TRANSLATE | SCE_MANIP_ROTATE | SCE_MANIP_SCALE; } } + + if (!DNA_struct_elem_find(fd->filesdna, "RigidBodyWorld", "RigidBodyWorld_Shared", "*shared")) { + for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { + RigidBodyWorld *rbw = scene->rigidbody_world; + + if (rbw == NULL) { + continue; + } + + if (rbw->shared == NULL) { + rbw->shared = MEM_callocN(sizeof(*rbw->shared), "RigidBodyWorld_Shared"); + } + + /* Move shared pointers from deprecated location to current location */ + rbw->shared->pointcache = rbw->pointcache; + rbw->shared->ptcaches = rbw->ptcaches; + + rbw->pointcache = NULL; + BLI_listbase_clear(&rbw->ptcaches); + + if (rbw->shared->pointcache == NULL) { + rbw->shared->pointcache = BKE_ptcache_add(&(rbw->shared->ptcaches)); + } + + } + } + } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 1a33b9440b5..5402114c8f8 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2646,9 +2646,14 @@ static void write_scene(WriteData *wd, Scene *sce) /* writing RigidBodyWorld data to the blend file */ if (sce->rigidbody_world) { + /* Set deprecated pointers to prevent crashes of older Blenders */ + sce->rigidbody_world->pointcache = sce->rigidbody_world->shared->pointcache; + sce->rigidbody_world->ptcaches = sce->rigidbody_world->shared->ptcaches; writestruct(wd, DATA, RigidBodyWorld, 1, sce->rigidbody_world); + + writestruct(wd, DATA, RigidBodyWorld_Shared, 1, sce->rigidbody_world->shared); writestruct(wd, DATA, EffectorWeights, 1, sce->rigidbody_world->effector_weights); - write_pointcaches(wd, &(sce->rigidbody_world->ptcaches)); + write_pointcaches(wd, &(sce->rigidbody_world->shared->ptcaches)); } write_previews(wd, sce->preview); diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c index 8d5258a7522..52a20ed7cf7 100644 --- a/source/blender/editors/physics/rigidbody_world.c +++ b/source/blender/editors/physics/rigidbody_world.c @@ -114,8 +114,7 @@ static int rigidbody_world_remove_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BKE_rigidbody_free_world(rbw); - scene->rigidbody_world = NULL; + BKE_rigidbody_free_world(scene); /* done */ return OPERATOR_FINISHED; @@ -152,14 +151,14 @@ static int rigidbody_world_export_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "No Rigid Body World to export"); return OPERATOR_CANCELLED; } - if (rbw->physics_world == NULL) { + if (rbw->shared->physics_world == NULL) { BKE_report(op->reports, RPT_ERROR, "Rigid Body World has no associated physics data to export"); return OPERATOR_CANCELLED; } RNA_string_get(op->ptr, "filepath", path); #ifdef WITH_BULLET - RB_dworld_export(rbw->physics_world, path); + RB_dworld_export(rbw->shared->physics_world, path); #endif return OPERATOR_FINISHED; } diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blender/makesdna/DNA_rigidbody_types.h index 5a7e7c92380..b7d422e7bdf 100644 --- a/source/blender/makesdna/DNA_rigidbody_types.h +++ b/source/blender/makesdna/DNA_rigidbody_types.h @@ -42,6 +42,16 @@ struct EffectorWeights; /* ******************************** */ /* RigidBody World */ +/* Container for data shared by original and evaluated copies of RigidBodyWorld */ +typedef struct RigidBodyWorld_Shared { + /* cache */ + struct PointCache *pointcache; + struct ListBase ptcaches; + + /* References to Physics Sim objects. Exist at runtime only ---------------------- */ + void *physics_world; /* Physics sim world (i.e. btDiscreteDynamicsWorld) */ +} RigidBodyWorld_Shared; + /* RigidBodyWorld (rbw) * * Represents a "simulation scene" existing within the parent scene. @@ -58,9 +68,9 @@ typedef struct RigidBodyWorld { int pad; float ltime; /* last frame world was evaluated for (internal) */ - /* cache */ - struct PointCache *pointcache; - struct ListBase ptcaches; + struct RigidBodyWorld_Shared *shared; /* This pointer is shared between all evaluated copies */ + struct PointCache *pointcache DNA_DEPRECATED; /* Moved to shared->pointcache */ + struct ListBase ptcaches DNA_DEPRECATED; /* Moved to shared->ptcaches */ int numbodies; /* number of objects in rigid body group */ short steps_per_second; /* number of simulation steps thaken per second */ @@ -68,9 +78,6 @@ typedef struct RigidBodyWorld { int flag; /* (eRigidBodyWorld_Flag) settings for this RigidBodyWorld */ float time_scale; /* used to speed up or slow down the simulation */ - - /* References to Physics Sim objects. Exist at runtime only ---------------------- */ - void *physics_world; /* Physics sim world (i.e. btDiscreteDynamicsWorld) */ } RigidBodyWorld; /* Flags for RigidBodyWorld */ @@ -86,6 +93,18 @@ typedef enum eRigidBodyWorld_Flag { /* ******************************** */ /* RigidBody Object */ +/* Container for data that is shared among CoW copies. + * + * This is placed in a separate struct so that, for example, the physics_shape + * pointer can be replaced without having to update all CoW copies. */ +# +# +typedef struct RigidBodyOb_Shared { + /* References to Physics Sim objects. Exist at runtime only */ + void *physics_object; /* Physics object representation (i.e. btRigidBody) */ + void *physics_shape; /* Collision shape used by physics sim (i.e. btCollisionShape) */ +} RigidBodyOb_Shared; + /* RigidBodyObject (rbo) * * Represents an object participating in a RigidBody sim. @@ -93,10 +112,6 @@ typedef enum eRigidBodyWorld_Flag { * participating in a sim. */ typedef struct RigidBodyOb { - /* References to Physics Sim objects. Exist at runtime only */ - void *physics_object; /* Physics object representation (i.e. btRigidBody) */ - void *physics_shape; /* Collision shape used by physics sim (i.e. btCollisionShape) */ - /* General Settings for this RigidBodyOb */ short type; /* (eRigidBodyOb_Type) role of RigidBody in sim */ short shape; /* (eRigidBody_Shape) collision shape to use */ @@ -123,6 +138,8 @@ typedef struct RigidBodyOb { float orn[4]; /* rigid body orientation */ float pos[3]; /* rigid body position */ float pad1; + + struct RigidBodyOb_Shared *shared; /* This pointer is shared between all evaluated copies */ } RigidBodyOb; diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c index 60a1783f118..9c3b1fe3063 100644 --- a/source/blender/makesrna/intern/rna_rigidbody.c +++ b/source/blender/makesrna/intern/rna_rigidbody.c @@ -124,8 +124,8 @@ static void rna_RigidBodyWorld_num_solver_iterations_set(PointerRNA *ptr, int va rbw->num_solver_iterations = value; #ifdef WITH_BULLET - if (rbw->physics_world) { - RB_dworld_set_solver_iterations(rbw->physics_world, value); + if (rbw->shared->physics_world) { + RB_dworld_set_solver_iterations(rbw->shared->physics_world, value); } #endif } @@ -137,8 +137,8 @@ static void rna_RigidBodyWorld_split_impulse_set(PointerRNA *ptr, int value) RB_FLAG_SET(rbw->flag, value, RBW_FLAG_USE_SPLIT_IMPULSE); #ifdef WITH_BULLET - if (rbw->physics_world) { - RB_dworld_set_split_impulse(rbw->physics_world, value); + if (rbw->shared->physics_world) { + RB_dworld_set_split_impulse(rbw->shared->physics_world, value); } #endif } @@ -167,7 +167,7 @@ static void rna_RigidBodyOb_shape_reset(Main *UNUSED(bmain), Scene *scene, Point RigidBodyOb *rbo = (RigidBodyOb *)ptr->data; BKE_rigidbody_cache_reset(rbw); - if (rbo->physics_shape) + if (rbo->shared->physics_shape) rbo->flag |= RBO_FLAG_NEEDS_RESHAPE; } @@ -201,9 +201,9 @@ static void rna_RigidBodyOb_disabled_set(PointerRNA *ptr, int value) #ifdef WITH_BULLET /* update kinematic state if necessary - only needed for active bodies */ - if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { - RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo)); - RB_body_set_kinematic_state(rbo->physics_object, !value); + if ((rbo->shared->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { + RB_body_set_mass(rbo->shared->physics_object, RBO_GET_MASS(rbo)); + RB_body_set_kinematic_state(rbo->shared->physics_object, !value); rbo->flag |= RBO_FLAG_NEEDS_VALIDATE; } #endif @@ -217,8 +217,8 @@ static void rna_RigidBodyOb_mass_set(PointerRNA *ptr, float value) #ifdef WITH_BULLET /* only active bodies need mass update */ - if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { - RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo)); + if ((rbo->shared->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { + RB_body_set_mass(rbo->shared->physics_object, RBO_GET_MASS(rbo)); } #endif } @@ -230,8 +230,8 @@ static void rna_RigidBodyOb_friction_set(PointerRNA *ptr, float value) rbo->friction = value; #ifdef WITH_BULLET - if (rbo->physics_object) { - RB_body_set_friction(rbo->physics_object, value); + if (rbo->shared->physics_object) { + RB_body_set_friction(rbo->shared->physics_object, value); } #endif } @@ -242,8 +242,8 @@ static void rna_RigidBodyOb_restitution_set(PointerRNA *ptr, float value) rbo->restitution = value; #ifdef WITH_BULLET - if (rbo->physics_object) { - RB_body_set_restitution(rbo->physics_object, value); + if (rbo->shared->physics_object) { + RB_body_set_restitution(rbo->shared->physics_object, value); } #endif } @@ -255,8 +255,8 @@ static void rna_RigidBodyOb_collision_margin_set(PointerRNA *ptr, float value) rbo->margin = value; #ifdef WITH_BULLET - if (rbo->physics_shape) { - RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo)); + if (rbo->shared->physics_shape) { + RB_shape_set_margin(rbo->shared->physics_shape, RBO_GET_MARGIN(rbo)); } #endif } @@ -283,9 +283,9 @@ static void rna_RigidBodyOb_kinematic_state_set(PointerRNA *ptr, int value) #ifdef WITH_BULLET /* update kinematic state if necessary */ - if (rbo->physics_object) { - RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo)); - RB_body_set_kinematic_state(rbo->physics_object, value); + if (rbo->shared->physics_object) { + RB_body_set_mass(rbo->shared->physics_object, RBO_GET_MASS(rbo)); + RB_body_set_kinematic_state(rbo->shared->physics_object, value); rbo->flag |= RBO_FLAG_NEEDS_VALIDATE; } #endif @@ -299,8 +299,8 @@ static void rna_RigidBodyOb_activation_state_set(PointerRNA *ptr, int value) #ifdef WITH_BULLET /* update activation state if necessary - only active bodies can be deactivated */ - if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { - RB_body_set_activation_state(rbo->physics_object, value); + if ((rbo->shared->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { + RB_body_set_activation_state(rbo->shared->physics_object, value); } #endif } @@ -313,8 +313,8 @@ static void rna_RigidBodyOb_linear_sleepThresh_set(PointerRNA *ptr, float value) #ifdef WITH_BULLET /* only active bodies need sleep threshold update */ - if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { - RB_body_set_linear_sleep_thresh(rbo->physics_object, value); + if ((rbo->shared->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { + RB_body_set_linear_sleep_thresh(rbo->shared->physics_object, value); } #endif } @@ -327,8 +327,8 @@ static void rna_RigidBodyOb_angular_sleepThresh_set(PointerRNA *ptr, float value #ifdef WITH_BULLET /* only active bodies need sleep threshold update */ - if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { - RB_body_set_angular_sleep_thresh(rbo->physics_object, value); + if ((rbo->shared->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { + RB_body_set_angular_sleep_thresh(rbo->shared->physics_object, value); } #endif } @@ -341,8 +341,8 @@ static void rna_RigidBodyOb_linear_damping_set(PointerRNA *ptr, float value) #ifdef WITH_BULLET /* only active bodies need damping update */ - if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { - RB_body_set_linear_damping(rbo->physics_object, value); + if ((rbo->shared->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { + RB_body_set_linear_damping(rbo->shared->physics_object, value); } #endif } @@ -355,8 +355,8 @@ static void rna_RigidBodyOb_angular_damping_set(PointerRNA *ptr, float value) #ifdef WITH_BULLET /* only active bodies need damping update */ - if ((rbo->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { - RB_body_set_angular_damping(rbo->physics_object, value); + if ((rbo->shared->physics_object) && (rbo->type == RBO_TYPE_ACTIVE)) { + RB_body_set_angular_damping(rbo->shared->physics_object, value); } #endif } @@ -706,8 +706,8 @@ static void rna_RigidBodyWorld_convex_sweep_test( #ifdef WITH_BULLET RigidBodyOb *rob = object->rigidbody_object; - if (rbw->physics_world != NULL && rob->physics_object != NULL) { - RB_world_convex_sweep_test(rbw->physics_world, rob->physics_object, ray_start, ray_end, + if (rbw->shared->physics_world != NULL && rob->shared->physics_object != NULL) { + RB_world_convex_sweep_test(rbw->shared->physics_world, rob->shared->physics_object, ray_start, ray_end, r_location, r_hitpoint, r_normal, r_hit); if (*r_hit == -2) { BKE_report(reports, RPT_ERROR, @@ -723,6 +723,13 @@ static void rna_RigidBodyWorld_convex_sweep_test( #endif } +static PointerRNA rna_RigidBodyWorld_PointCache_get(PointerRNA *ptr) +{ + RigidBodyWorld *rbw = ptr->data; + return rna_pointer_inherit_refine(ptr, &RNA_PointCache, rbw->shared->pointcache); +} + + #else static void rna_def_rigidbody_world(BlenderRNA *brna) @@ -801,7 +808,7 @@ static void rna_def_rigidbody_world(BlenderRNA *brna) /* cache */ prop = RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_pointer_sdna(prop, NULL, "pointcache"); + RNA_def_property_pointer_funcs(prop, "rna_RigidBodyWorld_PointCache_get", NULL, NULL, NULL); RNA_def_property_struct_type(prop, "PointCache"); RNA_def_property_ui_text(prop, "Point Cache", ""); |