Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/rigidbody.c
| Show First 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
| #include "DNA_group_types.h" | #include "DNA_group_types.h" | ||||
| #include "DNA_meshdata_types.h" | #include "DNA_meshdata_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "DNA_object_force_types.h" | #include "DNA_object_force_types.h" | ||||
| #include "DNA_rigidbody_types.h" | #include "DNA_rigidbody_types.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "BKE_cdderivedmesh.h" | #include "BKE_cdderivedmesh.h" | ||||
| #include "BKE_collection.h" | |||||
| #include "BKE_effect.h" | #include "BKE_effect.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_group.h" | |||||
| #include "BKE_library.h" | #include "BKE_library.h" | ||||
| #include "BKE_library_query.h" | #include "BKE_library_query.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| #include "BKE_pointcache.h" | #include "BKE_pointcache.h" | ||||
| #include "BKE_rigidbody.h" | #include "BKE_rigidbody.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| Show All 20 Lines | |||||
| { | { | ||||
| /* sanity check */ | /* sanity check */ | ||||
| if (!rbw) | if (!rbw) | ||||
| return; | return; | ||||
| if (rbw->physics_world) { | if (rbw->physics_world) { | ||||
| /* free physics references, we assume that all physics objects in will have been added to the world */ | /* free physics references, we assume that all physics objects in will have been added to the world */ | ||||
| if (rbw->constraints) { | if (rbw->constraints) { | ||||
| FOREACH_GROUP_OBJECT_BEGIN(rbw->constraints, object) | FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, object) | ||||
| { | { | ||||
| if (object->rigidbody_constraint) { | if (object->rigidbody_constraint) { | ||||
| RigidBodyCon *rbc = object->rigidbody_constraint; | RigidBodyCon *rbc = object->rigidbody_constraint; | ||||
| if (rbc->physics_constraint) { | if (rbc->physics_constraint) { | ||||
| RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint); | RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| FOREACH_GROUP_OBJECT_END; | FOREACH_COLLECTION_OBJECT_RECURSIVE_END; | ||||
| } | } | ||||
| if (rbw->group) { | if (rbw->group) { | ||||
| FOREACH_GROUP_OBJECT_BEGIN(rbw->group, object) | FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object) | ||||
| { | { | ||||
| if (object->rigidbody_object) { | if (object->rigidbody_object) { | ||||
| RigidBodyOb *rbo = object->rigidbody_object; | RigidBodyOb *rbo = object->rigidbody_object; | ||||
| if (rbo->physics_object) { | if (rbo->physics_object) { | ||||
| RB_dworld_remove_body(rbw->physics_world, rbo->physics_object); | RB_dworld_remove_body(rbw->physics_world, rbo->physics_object); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| FOREACH_GROUP_OBJECT_END; | FOREACH_COLLECTION_OBJECT_RECURSIVE_END; | ||||
| } | } | ||||
| /* free dynamics world */ | /* free dynamics world */ | ||||
| RB_dworld_delete(rbw->physics_world); | RB_dworld_delete(rbw->physics_world); | ||||
| } | } | ||||
| if (rbw->objects) | if (rbw->objects) | ||||
| free(rbw->objects); | free(rbw->objects); | ||||
| /* free cache */ | /* free cache */ | ||||
| ▲ Show 20 Lines • Show All 1,023 Lines • ▼ Show 20 Lines | if (rbw && rbw->objects) { | ||||
| rbw->objects[i] = NULL; | rbw->objects[i] = NULL; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* remove object from rigid body constraints */ | /* remove object from rigid body constraints */ | ||||
| if (rbw->constraints) { | if (rbw->constraints) { | ||||
| FOREACH_GROUP_OBJECT_BEGIN(rbw->constraints, obt) | FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, obt) | ||||
| { | { | ||||
| if (obt && obt->rigidbody_constraint) { | if (obt && obt->rigidbody_constraint) { | ||||
| rbc = obt->rigidbody_constraint; | rbc = obt->rigidbody_constraint; | ||||
| if (ELEM(ob, rbc->ob1, rbc->ob2)) { | if (ELEM(ob, rbc->ob1, rbc->ob2)) { | ||||
| BKE_rigidbody_remove_constraint(scene, obt); | BKE_rigidbody_remove_constraint(scene, obt); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| FOREACH_GROUP_OBJECT_END; | FOREACH_COLLECTION_OBJECT_RECURSIVE_END; | ||||
| } | } | ||||
| } | } | ||||
| /* remove object's settings */ | /* remove object's settings */ | ||||
| BKE_rigidbody_free_object(ob); | BKE_rigidbody_free_object(ob); | ||||
| /* flag cache as outdated */ | /* flag cache as outdated */ | ||||
| BKE_rigidbody_cache_reset(rbw); | BKE_rigidbody_cache_reset(rbw); | ||||
| Show All 17 Lines | |||||
| /* ************************************** */ | /* ************************************** */ | ||||
| /* Simulation Interface - Bullet */ | /* Simulation Interface - Bullet */ | ||||
| /* Update object array and rigid body count so they're in sync with the rigid body group */ | /* 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) | static void rigidbody_update_ob_array(RigidBodyWorld *rbw) | ||||
| { | { | ||||
| const ListBase objects = BKE_collection_object_cache_get(rbw->group); | |||||
| int i, n; | int i, n; | ||||
| n = BLI_listbase_count(&rbw->group->view_layer->object_bases); | n = BLI_listbase_count(&objects); | ||||
| if (rbw->numbodies != n) { | if (rbw->numbodies != n) { | ||||
| rbw->numbodies = n; | rbw->numbodies = n; | ||||
| rbw->objects = realloc(rbw->objects, sizeof(Object *) * rbw->numbodies); | rbw->objects = realloc(rbw->objects, sizeof(Object *) * rbw->numbodies); | ||||
| } | } | ||||
| i = 0; | i = 0; | ||||
| FOREACH_GROUP_OBJECT_BEGIN(rbw->group, object) | FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object) | ||||
| { | { | ||||
| rbw->objects[i] = object; | rbw->objects[i] = object; | ||||
| i++; | i++; | ||||
| } | } | ||||
| FOREACH_GROUP_OBJECT_END; | FOREACH_COLLECTION_OBJECT_RECURSIVE_END; | ||||
| } | } | ||||
| static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw) | static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw) | ||||
| { | { | ||||
| float adj_gravity[3]; | float adj_gravity[3]; | ||||
| /* adjust gravity to take effector weights into account */ | /* adjust gravity to take effector weights into account */ | ||||
| if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { | if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { | ||||
| ▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | static void rigidbody_update_simulation(struct Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, bool rebuild) | ||||
| /* XXX TODO For rebuild: remove all constraints first. | /* XXX TODO For rebuild: remove all constraints first. | ||||
| * Otherwise we can end up deleting objects that are still | * Otherwise we can end up deleting objects that are still | ||||
| * referenced by constraints, corrupting bullet's internal list. | * referenced by constraints, corrupting bullet's internal list. | ||||
| * | * | ||||
| * Memory management needs redesign here, this is just a dirty workaround. | * Memory management needs redesign here, this is just a dirty workaround. | ||||
| */ | */ | ||||
| if (rebuild && rbw->constraints) { | if (rebuild && rbw->constraints) { | ||||
| FOREACH_GROUP_OBJECT_BEGIN(rbw->constraints, ob) | FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, ob) | ||||
| { | { | ||||
| RigidBodyCon *rbc = ob->rigidbody_constraint; | RigidBodyCon *rbc = ob->rigidbody_constraint; | ||||
| if (rbc && rbc->physics_constraint) { | if (rbc && rbc->physics_constraint) { | ||||
| RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint); | RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint); | ||||
| RB_constraint_delete(rbc->physics_constraint); | RB_constraint_delete(rbc->physics_constraint); | ||||
| rbc->physics_constraint = NULL; | rbc->physics_constraint = NULL; | ||||
| } | } | ||||
| } | } | ||||
| FOREACH_GROUP_OBJECT_END; | FOREACH_COLLECTION_OBJECT_RECURSIVE_END; | ||||
| } | } | ||||
| /* update objects */ | /* update objects */ | ||||
| FOREACH_GROUP_OBJECT_BEGIN(rbw->group, ob) | FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, ob) | ||||
| { | { | ||||
| if (ob->type == OB_MESH) { | if (ob->type == OB_MESH) { | ||||
| /* validate that we've got valid object set up here... */ | /* validate that we've got valid object set up here... */ | ||||
| RigidBodyOb *rbo = ob->rigidbody_object; | RigidBodyOb *rbo = ob->rigidbody_object; | ||||
| /* update transformation matrix of the object so we don't get a frame of lag for simple animations */ | /* 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); | BKE_object_where_is_calc(depsgraph, scene, ob); | ||||
| if (rbo == NULL) { | if (rbo == NULL) { | ||||
| Show All 26 Lines | if (ob->type == OB_MESH) { | ||||
| } | } | ||||
| rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE); | rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE); | ||||
| } | } | ||||
| /* update simulation object... */ | /* update simulation object... */ | ||||
| rigidbody_update_sim_ob(depsgraph, scene, rbw, ob, rbo); | rigidbody_update_sim_ob(depsgraph, scene, rbw, ob, rbo); | ||||
| } | } | ||||
| } | } | ||||
| FOREACH_GROUP_OBJECT_END; | FOREACH_COLLECTION_OBJECT_RECURSIVE_END; | ||||
| /* update constraints */ | /* update constraints */ | ||||
| if (rbw->constraints == NULL) /* no constraints, move on */ | if (rbw->constraints == NULL) /* no constraints, move on */ | ||||
| return; | return; | ||||
| FOREACH_GROUP_OBJECT_BEGIN(rbw->constraints, ob) | FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, ob) | ||||
| { | { | ||||
| /* validate that we've got valid object set up here... */ | /* validate that we've got valid object set up here... */ | ||||
| RigidBodyCon *rbc = ob->rigidbody_constraint; | RigidBodyCon *rbc = ob->rigidbody_constraint; | ||||
| /* update transformation matrix of the object so we don't get a frame of lag for simple animations */ | /* 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); | BKE_object_where_is_calc(depsgraph, scene, ob); | ||||
| if (rbc == NULL) { | if (rbc == NULL) { | ||||
| /* Since this object is included in the group but doesn't have | /* Since this object is included in the group but doesn't have | ||||
| Show All 11 Lines | else { | ||||
| rigidbody_validate_sim_constraint(rbw, ob, true); | rigidbody_validate_sim_constraint(rbw, ob, true); | ||||
| } | } | ||||
| else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) { | else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) { | ||||
| rigidbody_validate_sim_constraint(rbw, ob, false); | rigidbody_validate_sim_constraint(rbw, ob, false); | ||||
| } | } | ||||
| rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE; | rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE; | ||||
| } | } | ||||
| } | } | ||||
| FOREACH_GROUP_OBJECT_END; | FOREACH_COLLECTION_OBJECT_RECURSIVE_END; | ||||
| } | } | ||||
| static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw) | static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw) | ||||
| { | { | ||||
| FOREACH_GROUP_BASE_BEGIN(rbw->group, base) | FOREACH_COLLECTION_BASE_RECURSIVE_BEGIN(rbw->group, base) | ||||
| { | { | ||||
| Object *ob = base->object; | Object *ob = base->object; | ||||
| RigidBodyOb *rbo = ob->rigidbody_object; | RigidBodyOb *rbo = ob->rigidbody_object; | ||||
| /* Reset kinematic state for transformed objects. */ | /* Reset kinematic state for transformed objects. */ | ||||
| if (rbo && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) { | if (rbo && (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_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_mass(rbo->physics_object, RBO_GET_MASS(rbo)); | ||||
| /* Deactivate passive objects so they don't interfere with deactivation of active objects. */ | /* Deactivate passive objects so they don't interfere with deactivation of active objects. */ | ||||
| if (rbo->type == RBO_TYPE_PASSIVE) | if (rbo->type == RBO_TYPE_PASSIVE) | ||||
| RB_body_deactivate(rbo->physics_object); | RB_body_deactivate(rbo->physics_object); | ||||
| } | } | ||||
| } | } | ||||
| FOREACH_GROUP_BASE_END | FOREACH_COLLECTION_BASE_RECURSIVE_END | ||||
| } | } | ||||
| bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) | 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->pointcache->startframe); | ||||
| } | } | ||||
| /* Sync rigid body and object transformations */ | /* Sync rigid body and object transformations */ | ||||
| ▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | void BKE_rigidbody_rebuild_world(struct Depsgraph *depsgraph, Scene *scene, float ctime) | ||||
| PTCacheID pid; | PTCacheID pid; | ||||
| int startframe, endframe; | int startframe, endframe; | ||||
| BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw); | BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw); | ||||
| BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL); | BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL); | ||||
| cache = rbw->pointcache; | cache = rbw->pointcache; | ||||
| /* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */ | /* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */ | ||||
| if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&rbw->group->view_layer->object_bases)) { | const ListBase objects = BKE_collection_object_cache_get(rbw->group); | ||||
| if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&objects)) { | |||||
| cache->flag |= PTCACHE_OUTDATED; | cache->flag |= PTCACHE_OUTDATED; | ||||
| } | } | ||||
| if (ctime == startframe + 1 && rbw->ltime == startframe) { | if (ctime == startframe + 1 && rbw->ltime == startframe) { | ||||
| if (cache->flag & PTCACHE_OUTDATED) { | if (cache->flag & PTCACHE_OUTDATED) { | ||||
| BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); | BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); | ||||
| rigidbody_update_simulation(depsgraph, scene, rbw, true); | rigidbody_update_simulation(depsgraph, scene, rbw, true); | ||||
| BKE_ptcache_validate(cache, (int)ctime); | BKE_ptcache_validate(cache, (int)ctime); | ||||
| ▲ Show 20 Lines • Show All 140 Lines • Show Last 20 Lines | |||||