2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2013 Blender Foundation
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): Joshua Leung, Sergej Reich
25 * ***** END GPL LICENSE BLOCK *****
30 * \brief Blender-side interface and methods for dealing with Rigid Body simulations
40 #include "MEM_guardedalloc.h"
42 #include "BLI_blenlib.h"
50 #include "DNA_collection_types.h"
51 #include "DNA_mesh_types.h"
52 #include "DNA_meshdata_types.h"
53 #include "DNA_object_types.h"
54 #include "DNA_object_force_types.h"
55 #include "DNA_rigidbody_types.h"
56 #include "DNA_scene_types.h"
58 #include "BKE_collection.h"
59 #include "BKE_effect.h"
60 #include "BKE_global.h"
61 #include "BKE_layer.h"
62 #include "BKE_library.h"
63 #include "BKE_library_query.h"
66 #include "BKE_mesh_runtime.h"
67 #include "BKE_object.h"
68 #include "BKE_pointcache.h"
69 #include "BKE_rigidbody.h"
70 #include "BKE_scene.h"
72 #include "DEG_depsgraph.h"
73 #include "DEG_depsgraph_query.h"
75 /* ************************************** */
76 /* Memory Management */
78 /* Freeing Methods --------------------- */
81 static void rigidbody_update_ob_array(RigidBodyWorld *rbw);
84 static void RB_dworld_remove_constraint(void *UNUSED(world), void *UNUSED(con)) {}
85 static void RB_dworld_remove_body(void *UNUSED(world), void *UNUSED(body)) {}
86 static void RB_dworld_delete(void *UNUSED(world)) {}
87 static void RB_body_delete(void *UNUSED(body)) {}
88 static void RB_shape_delete(void *UNUSED(shape)) {}
89 static void RB_constraint_delete(void *UNUSED(con)) {}
93 /* Free rigidbody world */
94 void BKE_rigidbody_free_world(Scene *scene)
96 bool is_orig = (scene->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0;
97 RigidBodyWorld *rbw = scene->rigidbody_world;
98 scene->rigidbody_world = NULL;
104 if (is_orig && rbw->shared->physics_world) {
105 /* free physics references, we assume that all physics objects in will have been added to the world */
106 if (rbw->constraints) {
107 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, object)
109 if (object->rigidbody_constraint) {
110 RigidBodyCon *rbc = object->rigidbody_constraint;
111 if (rbc->physics_constraint) {
112 RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
116 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
120 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
122 BKE_rigidbody_free_object(object, rbw);
124 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
126 /* free dynamics world */
127 RB_dworld_delete(rbw->shared->physics_world);
134 BKE_ptcache_free_list(&(rbw->shared->ptcaches));
135 rbw->shared->pointcache = NULL;
137 MEM_freeN(rbw->shared);
140 /* free effector weights */
141 if (rbw->effector_weights)
142 MEM_freeN(rbw->effector_weights);
144 /* free rigidbody world itself */
148 /* Free RigidBody settings and sim instances */
149 void BKE_rigidbody_free_object(Object *ob, RigidBodyWorld *rbw)
151 bool is_orig = (ob->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0;
152 RigidBodyOb *rbo = ob->rigidbody_object;
158 /* free physics references */
160 if (rbo->shared->physics_object) {
163 /* We can only remove the body from the world if the world is known.
164 * The world is generally only unknown if it's an evaluated copy of
165 * an object that's being freed, in which case this code isn't run anyway. */
166 RB_dworld_remove_body(rbw->shared->physics_world, rbo->shared->physics_object);
169 RB_body_delete(rbo->shared->physics_object);
170 rbo->shared->physics_object = NULL;
173 if (rbo->shared->physics_shape) {
174 RB_shape_delete(rbo->shared->physics_shape);
175 rbo->shared->physics_shape = NULL;
178 MEM_freeN(rbo->shared);
181 /* free data itself */
183 ob->rigidbody_object = NULL;
186 /* Free RigidBody constraint and sim instance */
187 void BKE_rigidbody_free_constraint(Object *ob)
189 RigidBodyCon *rbc = (ob) ? ob->rigidbody_constraint : NULL;
195 /* free physics reference */
196 if (rbc->physics_constraint) {
197 RB_constraint_delete(rbc->physics_constraint);
198 rbc->physics_constraint = NULL;
201 /* free data itself */
203 ob->rigidbody_constraint = NULL;
208 /* Copying Methods --------------------- */
210 /* These just copy the data, clearing out references to physics objects.
211 * Anything that uses them MUST verify that the copied object will
212 * be added to relevant groups later...
215 RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int flag)
217 RigidBodyOb *rboN = NULL;
219 if (ob->rigidbody_object) {
220 /* just duplicate the whole struct first (to catch all the settings) */
221 rboN = MEM_dupallocN(ob->rigidbody_object);
223 if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
224 /* This is a regular copy, and not a CoW copy for depsgraph evaluation */
225 rboN->shared = MEM_callocN(sizeof(*rboN->shared), "RigidBodyOb_Shared");
228 /* tag object as needing to be verified */
229 rboN->flag |= RBO_FLAG_NEEDS_VALIDATE;
232 /* return new copy of settings */
236 RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int UNUSED(flag))
238 RigidBodyCon *rbcN = NULL;
240 if (ob->rigidbody_constraint) {
241 /* just duplicate the whole struct first (to catch all the settings) */
242 rbcN = MEM_dupallocN(ob->rigidbody_constraint);
244 /* tag object as needing to be verified */
245 rbcN->flag |= RBC_FLAG_NEEDS_VALIDATE;
247 /* clear out all the fields which need to be revalidated later */
248 rbcN->physics_constraint = NULL;
251 /* return new copy of settings */
255 /* ************************************** */
256 /* Setup Utilities - Validate Sim Instances */
258 /* get the appropriate evaluated mesh based on rigid body mesh source */
259 static Mesh *rigidbody_get_mesh(Object *ob)
261 switch (ob->rigidbody_object->mesh_source) {
262 case RBO_MESH_DEFORM:
263 return ob->runtime.mesh_deform_eval;
265 return ob->runtime.mesh_eval;
267 /* This mesh may be used for computing looptris, which should be done
268 * on the original; otherwise every time the CoW is recreated it will
269 * have to be recomputed. */
270 BLI_assert(ob->rigidbody_object->mesh_source == RBO_MESH_BASE);
271 return ob->runtime.mesh_orig;
274 /* Just return something sensible so that at least Blender won't crash. */
275 BLI_assert(!"Unknown mesh source");
276 return ob->runtime.mesh_eval;
279 /* create collision shape of mesh - convex hull */
280 static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob, float margin, bool *can_embed)
282 rbCollisionShape *shape = NULL;
287 if (ob->type == OB_MESH && ob->data) {
288 mesh = rigidbody_get_mesh(ob);
289 mvert = (mesh) ? mesh->mvert : NULL;
290 totvert = (mesh) ? mesh->totvert : 0;
293 printf("ERROR: cannot make Convex Hull collision shape for non-Mesh object\n");
297 shape = RB_shape_new_convex_hull((float *)mvert, sizeof(MVert), totvert, margin, can_embed);
300 printf("ERROR: no vertices to define Convex Hull collision shape with\n");
306 /* create collision shape of mesh - triangulated mesh
307 * returns NULL if creation fails.
309 static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
311 rbCollisionShape *shape = NULL;
313 if (ob->type == OB_MESH) {
316 const MLoopTri *looptri;
321 mesh = rigidbody_get_mesh(ob);
323 /* ensure mesh validity, then grab data */
328 totvert = mesh->totvert;
329 looptri = BKE_mesh_runtime_looptri_ensure(mesh);
330 tottri = mesh->runtime.looptris.len;
333 /* sanity checking - potential case when no data will be present */
334 if ((totvert == 0) || (tottri == 0)) {
335 printf("WARNING: no geometry data converted for Mesh Collision Shape (ob = %s)\n", ob->id.name + 2);
341 /* init mesh data for collision shape */
342 mdata = RB_trimesh_data_new(tottri, totvert);
344 RB_trimesh_add_vertices(mdata, (float *)mvert, totvert, sizeof(MVert));
346 /* loop over all faces, adding them as triangles to the collision shape
347 * (so for some faces, more than triangle will get added)
349 if (mvert && looptri) {
350 for (i = 0; i < tottri; i++) {
351 /* add first triangle - verts 1,2,3 */
352 const MLoopTri *lt = &looptri[i];
355 vtri[0] = mloop[lt->tri[0]].v;
356 vtri[1] = mloop[lt->tri[1]].v;
357 vtri[2] = mloop[lt->tri[2]].v;
359 RB_trimesh_add_triangle_indices(mdata, i, UNPACK3(vtri));
363 RB_trimesh_finish(mdata);
365 /* construct collision shape
367 * These have been chosen to get better speed/accuracy tradeoffs with regards
368 * to limitations of each:
369 * - BVH-Triangle Mesh: for passive objects only. Despite having greater
370 * speed/accuracy, they cannot be used for moving objects.
371 * - GImpact Mesh: for active objects. These are slower and less stable,
372 * but are more flexible for general usage.
374 if (ob->rigidbody_object->type == RBO_TYPE_PASSIVE) {
375 shape = RB_shape_new_trimesh(mdata);
378 shape = RB_shape_new_gimpact_mesh(mdata);
383 printf("ERROR: cannot make Triangular Mesh collision shape for non-Mesh object\n");
389 /* Create new physics sim collision shape for object and store it,
390 * or remove the existing one first and replace...
392 static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
394 RigidBodyOb *rbo = ob->rigidbody_object;
395 rbCollisionShape *new_shape = NULL;
397 float size[3] = {1.0f, 1.0f, 1.0f};
400 float capsule_height;
401 float hull_margin = 0.0f;
402 bool can_embed = true;
409 /* don't create a new shape if we already have one and don't want to rebuild it */
410 if (rbo->shared->physics_shape && !rebuild)
413 /* if automatically determining dimensions, use the Object's boundbox
414 * - assume that all quadrics are standing upright on local z-axis
415 * - assume even distribution of mass around the Object's pivot
416 * (i.e. Object pivot is centralized in boundbox)
418 // XXX: all dimensions are auto-determined now... later can add stored settings for this
419 /* get object dimensions without scaling */
420 bb = BKE_object_boundbox_get(ob);
422 size[0] = (bb->vec[4][0] - bb->vec[0][0]);
423 size[1] = (bb->vec[2][1] - bb->vec[0][1]);
424 size[2] = (bb->vec[1][2] - bb->vec[0][2]);
426 mul_v3_fl(size, 0.5f);
428 if (ELEM(rbo->shape, RB_SHAPE_CAPSULE, RB_SHAPE_CYLINDER, RB_SHAPE_CONE)) {
429 /* take radius as largest x/y dimension, and height as z-dimension */
430 radius = MAX2(size[0], size[1]);
433 else if (rbo->shape == RB_SHAPE_SPHERE) {
434 /* take radius to the largest dimension to try and encompass everything */
435 radius = MAX3(size[0], size[1], size[2]);
438 /* create new shape */
439 switch (rbo->shape) {
441 new_shape = RB_shape_new_box(size[0], size[1], size[2]);
444 case RB_SHAPE_SPHERE:
445 new_shape = RB_shape_new_sphere(radius);
448 case RB_SHAPE_CAPSULE:
449 capsule_height = (height - radius) * 2.0f;
450 new_shape = RB_shape_new_capsule(radius, (capsule_height > 0.0f) ? capsule_height : 0.0f);
452 case RB_SHAPE_CYLINDER:
453 new_shape = RB_shape_new_cylinder(radius, height);
456 new_shape = RB_shape_new_cone(radius, height * 2.0f);
459 case RB_SHAPE_CONVEXH:
460 /* try to emged collision margin */
461 has_volume = (MIN3(size[0], size[1], size[2]) > 0.0f);
463 if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && has_volume)
465 new_shape = rigidbody_get_shape_convexhull_from_mesh(ob, hull_margin, &can_embed);
466 if (!(rbo->flag & RBO_FLAG_USE_MARGIN))
467 rbo->margin = (can_embed && has_volume) ? 0.04f : 0.0f; /* RB_TODO ideally we shouldn't directly change the margin here */
469 case RB_SHAPE_TRIMESH:
470 new_shape = rigidbody_get_shape_trimesh_from_mesh(ob);
473 /* use box shape if we can't fall back to old shape */
474 if (new_shape == NULL && rbo->shared->physics_shape == NULL) {
475 new_shape = RB_shape_new_box(size[0], size[1], size[2]);
477 /* assign new collision shape if creation was successful */
479 if (rbo->shared->physics_shape) {
480 RB_shape_delete(rbo->shared->physics_shape);
482 rbo->shared->physics_shape = new_shape;
483 RB_shape_set_margin(rbo->shared->physics_shape, RBO_GET_MARGIN(rbo));
487 /* --------------------- */
489 /* helper function to calculate volume of rigidbody object */
490 // TODO: allow a parameter to specify method used to calculate this?
491 void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
493 RigidBodyOb *rbo = ob->rigidbody_object;
495 float size[3] = {1.0f, 1.0f, 1.0f};
501 /* if automatically determining dimensions, use the Object's boundbox
502 * - assume that all quadrics are standing upright on local z-axis
503 * - assume even distribution of mass around the Object's pivot
504 * (i.e. Object pivot is centralized in boundbox)
505 * - boundbox gives full width
507 // XXX: all dimensions are auto-determined now... later can add stored settings for this
508 BKE_object_dimensions_get(ob, size);
510 if (ELEM(rbo->shape, RB_SHAPE_CAPSULE, RB_SHAPE_CYLINDER, RB_SHAPE_CONE)) {
511 /* take radius as largest x/y dimension, and height as z-dimension */
512 radius = MAX2(size[0], size[1]) * 0.5f;
515 else if (rbo->shape == RB_SHAPE_SPHERE) {
516 /* take radius to the largest dimension to try and encompass everything */
517 radius = max_fff(size[0], size[1], size[2]) * 0.5f;
520 /* calculate volume as appropriate */
521 switch (rbo->shape) {
523 volume = size[0] * size[1] * size[2];
526 case RB_SHAPE_SPHERE:
527 volume = 4.0f / 3.0f * (float)M_PI * radius * radius * radius;
530 /* for now, assume that capsule is close enough to a cylinder... */
531 case RB_SHAPE_CAPSULE:
532 case RB_SHAPE_CYLINDER:
533 volume = (float)M_PI * radius * radius * height;
537 volume = (float)M_PI / 3.0f * radius * radius * height;
540 case RB_SHAPE_CONVEXH:
541 case RB_SHAPE_TRIMESH:
543 if (ob->type == OB_MESH) {
544 Mesh *mesh = rigidbody_get_mesh(ob);
546 const MLoopTri *lt = NULL;
547 int totvert, tottri = 0;
548 const MLoop *mloop = NULL;
550 /* ensure mesh validity, then grab data */
555 totvert = mesh->totvert;
556 lt = BKE_mesh_runtime_looptri_ensure(mesh);
557 tottri = mesh->runtime.looptris.len;
560 if (totvert > 0 && tottri > 0) {
561 BKE_mesh_calc_volume(mvert, totvert, lt, tottri, mloop, &volume, NULL);
565 /* rough estimate from boundbox as fallback */
566 /* XXX could implement other types of geometry here (curves, etc.) */
567 volume = size[0] * size[1] * size[2];
573 /* return the volume calculated */
574 if (r_vol) *r_vol = volume;
577 void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
579 RigidBodyOb *rbo = ob->rigidbody_object;
581 float size[3] = {1.0f, 1.0f, 1.0f};
586 /* if automatically determining dimensions, use the Object's boundbox
587 * - assume that all quadrics are standing upright on local z-axis
588 * - assume even distribution of mass around the Object's pivot
589 * (i.e. Object pivot is centralized in boundbox)
590 * - boundbox gives full width
592 // XXX: all dimensions are auto-determined now... later can add stored settings for this
593 BKE_object_dimensions_get(ob, size);
595 /* calculate volume as appropriate */
596 switch (rbo->shape) {
598 case RB_SHAPE_SPHERE:
599 case RB_SHAPE_CAPSULE:
600 case RB_SHAPE_CYLINDER:
604 /* take radius as largest x/y dimension, and height as z-dimension */
606 /* cone is geometrically centered on the median,
607 * center of mass is 1/4 up from the base
609 r_center[2] = -0.25f * height;
612 case RB_SHAPE_CONVEXH:
613 case RB_SHAPE_TRIMESH:
615 if (ob->type == OB_MESH) {
616 Mesh *mesh = rigidbody_get_mesh(ob);
618 const MLoopTri *looptri;
622 /* ensure mesh validity, then grab data */
627 totvert = mesh->totvert;
628 looptri = BKE_mesh_runtime_looptri_ensure(mesh);
629 tottri = mesh->runtime.looptris.len;
632 if (totvert > 0 && tottri > 0) {
633 BKE_mesh_calc_volume(mvert, totvert, looptri, tottri, mloop, NULL, r_center);
641 /* --------------------- */
644 * Create physics sim representation of object given RigidBody settings
646 * \param rebuild: Even if an instance already exists, replace it
648 static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool rebuild)
650 RigidBodyOb *rbo = (ob) ? ob->rigidbody_object : NULL;
655 * - object doesn't have RigidBody info already: then why is it here?
660 /* make sure collision shape exists */
661 /* FIXME we shouldn't always have to rebuild collision shapes when rebuilding objects, but it's needed for constraints to update correctly */
662 if (rbo->shared->physics_shape == NULL || rebuild)
663 rigidbody_validate_sim_shape(ob, true);
665 if (rbo->shared->physics_object) {
666 RB_dworld_remove_body(rbw->shared->physics_world, rbo->shared->physics_object);
668 if (!rbo->shared->physics_object || rebuild) {
669 /* remove rigid body if it already exists before creating a new one */
670 if (rbo->shared->physics_object) {
671 RB_body_delete(rbo->shared->physics_object);
674 mat4_to_loc_quat(loc, rot, ob->obmat);
676 rbo->shared->physics_object = RB_body_new(rbo->shared->physics_shape, loc, rot);
678 RB_body_set_friction(rbo->shared->physics_object, rbo->friction);
679 RB_body_set_restitution(rbo->shared->physics_object, rbo->restitution);
681 RB_body_set_damping(rbo->shared->physics_object, rbo->lin_damping, rbo->ang_damping);
682 RB_body_set_sleep_thresh(rbo->shared->physics_object, rbo->lin_sleep_thresh, rbo->ang_sleep_thresh);
683 RB_body_set_activation_state(rbo->shared->physics_object, rbo->flag & RBO_FLAG_USE_DEACTIVATION);
685 if (rbo->type == RBO_TYPE_PASSIVE || rbo->flag & RBO_FLAG_START_DEACTIVATED)
686 RB_body_deactivate(rbo->shared->physics_object);
689 RB_body_set_linear_factor(rbo->shared->physics_object,
690 (ob->protectflag & OB_LOCK_LOCX) == 0,
691 (ob->protectflag & OB_LOCK_LOCY) == 0,
692 (ob->protectflag & OB_LOCK_LOCZ) == 0);
693 RB_body_set_angular_factor(rbo->shared->physics_object,
694 (ob->protectflag & OB_LOCK_ROTX) == 0,
695 (ob->protectflag & OB_LOCK_ROTY) == 0,
696 (ob->protectflag & OB_LOCK_ROTZ) == 0);
698 RB_body_set_mass(rbo->shared->physics_object, RBO_GET_MASS(rbo));
699 RB_body_set_kinematic_state(rbo->shared->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
702 if (rbw && rbw->shared->physics_world)
703 RB_dworld_add_body(rbw->shared->physics_world, rbo->shared->physics_object, rbo->col_groups);
706 /* --------------------- */
708 static void rigidbody_constraint_init_spring(
709 RigidBodyCon *rbc, void (*set_spring)(rbConstraint *, int, int),
710 void (*set_stiffness)(rbConstraint *, int, float), void (*set_damping)(rbConstraint *, int, float))
712 set_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->flag & RBC_FLAG_USE_SPRING_X);
713 set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_stiffness_x);
714 set_damping(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_damping_x);
716 set_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->flag & RBC_FLAG_USE_SPRING_Y);
717 set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_stiffness_y);
718 set_damping(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_damping_y);
720 set_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->flag & RBC_FLAG_USE_SPRING_Z);
721 set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z);
722 set_damping(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z);
724 set_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->flag & RBC_FLAG_USE_SPRING_ANG_X);
725 set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_stiffness_ang_x);
726 set_damping(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_damping_ang_x);
728 set_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y);
729 set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_stiffness_ang_y);
730 set_damping(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_damping_ang_y);
732 set_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z);
733 set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_stiffness_ang_z);
734 set_damping(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z);
737 static void rigidbody_constraint_set_limits(
738 RigidBodyCon *rbc, void (*set_limits)(rbConstraint *, int, float, float))
740 if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
741 set_limits(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->limit_lin_x_lower, rbc->limit_lin_x_upper);
743 set_limits(rbc->physics_constraint, RB_LIMIT_LIN_X, 0.0f, -1.0f);
745 if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Y)
746 set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->limit_lin_y_lower, rbc->limit_lin_y_upper);
748 set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Y, 0.0f, -1.0f);
750 if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Z)
751 set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->limit_lin_z_lower, rbc->limit_lin_z_upper);
753 set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Z, 0.0f, -1.0f);
755 if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_X)
756 set_limits(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->limit_ang_x_lower, rbc->limit_ang_x_upper);
758 set_limits(rbc->physics_constraint, RB_LIMIT_ANG_X, 0.0f, -1.0f);
760 if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Y)
761 set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->limit_ang_y_lower, rbc->limit_ang_y_upper);
763 set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Y, 0.0f, -1.0f);
765 if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Z)
766 set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->limit_ang_z_lower, rbc->limit_ang_z_upper);
768 set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Z, 0.0f, -1.0f);
772 * Create physics sim representation of constraint given rigid body constraint settings
774 * \param rebuild: Even if an instance already exists, replace it
776 static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, bool rebuild)
778 RigidBodyCon *rbc = (ob) ? ob->rigidbody_constraint : NULL;
787 * - object should have a rigid body constraint
788 * - rigid body constraint should have at least one constrained object
794 if (ELEM(NULL, rbc->ob1, rbc->ob1->rigidbody_object, rbc->ob2, rbc->ob2->rigidbody_object)) {
795 if (rbc->physics_constraint) {
796 RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
797 RB_constraint_delete(rbc->physics_constraint);
798 rbc->physics_constraint = NULL;
803 if (rbc->physics_constraint && rebuild == false) {
804 RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
806 if (rbc->physics_constraint == NULL || rebuild) {
807 rbRigidBody *rb1 = rbc->ob1->rigidbody_object->shared->physics_object;
808 rbRigidBody *rb2 = rbc->ob2->rigidbody_object->shared->physics_object;
810 /* remove constraint if it already exists before creating a new one */
811 if (rbc->physics_constraint) {
812 RB_constraint_delete(rbc->physics_constraint);
813 rbc->physics_constraint = NULL;
816 mat4_to_loc_quat(loc, rot, ob->obmat);
821 rbc->physics_constraint = RB_constraint_new_point(loc, rb1, rb2);
824 rbc->physics_constraint = RB_constraint_new_fixed(loc, rot, rb1, rb2);
827 rbc->physics_constraint = RB_constraint_new_hinge(loc, rot, rb1, rb2);
828 if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Z) {
829 RB_constraint_set_limits_hinge(rbc->physics_constraint, rbc->limit_ang_z_lower, rbc->limit_ang_z_upper);
832 RB_constraint_set_limits_hinge(rbc->physics_constraint, 0.0f, -1.0f);
834 case RBC_TYPE_SLIDER:
835 rbc->physics_constraint = RB_constraint_new_slider(loc, rot, rb1, rb2);
836 if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
837 RB_constraint_set_limits_slider(rbc->physics_constraint, rbc->limit_lin_x_lower, rbc->limit_lin_x_upper);
839 RB_constraint_set_limits_slider(rbc->physics_constraint, 0.0f, -1.0f);
841 case RBC_TYPE_PISTON:
842 rbc->physics_constraint = RB_constraint_new_piston(loc, rot, rb1, rb2);
843 if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X) {
844 lin_lower = rbc->limit_lin_x_lower;
845 lin_upper = rbc->limit_lin_x_upper;
851 if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_X) {
852 ang_lower = rbc->limit_ang_x_lower;
853 ang_upper = rbc->limit_ang_x_upper;
859 RB_constraint_set_limits_piston(rbc->physics_constraint, lin_lower, lin_upper, ang_lower, ang_upper);
861 case RBC_TYPE_6DOF_SPRING:
862 if (rbc->spring_type == RBC_SPRING_TYPE2) {
863 rbc->physics_constraint = RB_constraint_new_6dof_spring2(loc, rot, rb1, rb2);
865 rigidbody_constraint_init_spring(rbc, RB_constraint_set_spring_6dof_spring2, RB_constraint_set_stiffness_6dof_spring2, RB_constraint_set_damping_6dof_spring2);
867 RB_constraint_set_equilibrium_6dof_spring2(rbc->physics_constraint);
869 rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof_spring2);
872 rbc->physics_constraint = RB_constraint_new_6dof_spring(loc, rot, rb1, rb2);
874 rigidbody_constraint_init_spring(rbc, RB_constraint_set_spring_6dof_spring, RB_constraint_set_stiffness_6dof_spring, RB_constraint_set_damping_6dof_spring);
876 RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint);
878 rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof);
882 rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2);
884 rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof);
887 rbc->physics_constraint = RB_constraint_new_motor(loc, rot, rb1, rb2);
889 RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
890 RB_constraint_set_max_impulse_motor(rbc->physics_constraint, rbc->motor_lin_max_impulse, rbc->motor_ang_max_impulse);
891 RB_constraint_set_target_velocity_motor(rbc->physics_constraint, rbc->motor_lin_target_velocity, rbc->motor_ang_target_velocity);
895 else { /* can't create constraint without both rigid bodies */
899 RB_constraint_set_enabled(rbc->physics_constraint, rbc->flag & RBC_FLAG_ENABLED);
901 if (rbc->flag & RBC_FLAG_USE_BREAKING)
902 RB_constraint_set_breaking_threshold(rbc->physics_constraint, rbc->breaking_threshold);
904 RB_constraint_set_breaking_threshold(rbc->physics_constraint, FLT_MAX);
906 if (rbc->flag & RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS)
907 RB_constraint_set_solver_iterations(rbc->physics_constraint, rbc->num_solver_iterations);
909 RB_constraint_set_solver_iterations(rbc->physics_constraint, -1);
912 if (rbw && rbw->shared->physics_world && rbc->physics_constraint) {
913 RB_dworld_add_constraint(rbw->shared->physics_world, rbc->physics_constraint, rbc->flag & RBC_FLAG_DISABLE_COLLISIONS);
917 /* --------------------- */
919 /* Create physics sim world given RigidBody world settings */
920 // NOTE: this does NOT update object references that the scene uses, in case those aren't ready yet!
921 void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild)
927 /* create new sim world */
928 if (rebuild || rbw->shared->physics_world == NULL) {
929 if (rbw->shared->physics_world)
930 RB_dworld_delete(rbw->shared->physics_world);
931 rbw->shared->physics_world = RB_dworld_new(scene->physics_settings.gravity);
934 RB_dworld_set_solver_iterations(rbw->shared->physics_world, rbw->num_solver_iterations);
935 RB_dworld_set_split_impulse(rbw->shared->physics_world, rbw->flag & RBW_FLAG_USE_SPLIT_IMPULSE);
938 /* ************************************** */
939 /* Setup Utilities - Create Settings Blocks */
941 /* Set up RigidBody world */
942 RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
944 /* try to get whatever RigidBody world that might be representing this already */
948 * - there must be a valid scene to add world to
949 * - there mustn't be a sim world using this group already
954 /* create a new sim world */
955 rbw = MEM_callocN(sizeof(RigidBodyWorld), "RigidBodyWorld");
956 rbw->shared = MEM_callocN(sizeof(*rbw->shared), "RigidBodyWorld_Shared");
958 /* set default settings */
959 rbw->effector_weights = BKE_effector_add_weights(NULL);
963 rbw->time_scale = 1.0f;
965 rbw->steps_per_second = 60; /* Bullet default (60 Hz) */
966 rbw->num_solver_iterations = 10; /* 10 is bullet default */
968 rbw->shared->pointcache = BKE_ptcache_add(&(rbw->shared->ptcaches));
969 rbw->shared->pointcache->step = 1;
971 /* return this sim world */
975 RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag)
977 RigidBodyWorld *rbw_copy = MEM_dupallocN(rbw);
979 if (rbw->effector_weights) {
980 rbw_copy->effector_weights = MEM_dupallocN(rbw->effector_weights);
982 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
983 id_us_plus((ID *)rbw_copy->group);
984 id_us_plus((ID *)rbw_copy->constraints);
987 if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
988 /* This is a regular copy, and not a CoW copy for depsgraph evaluation */
989 rbw_copy->shared = MEM_callocN(sizeof(*rbw_copy->shared), "RigidBodyWorld_Shared");
990 BKE_ptcache_copy_list(&rbw_copy->shared->ptcaches, &rbw->shared->ptcaches, LIB_ID_COPY_CACHES);
991 rbw_copy->shared->pointcache = rbw_copy->shared->ptcaches.first;
994 rbw_copy->objects = NULL;
995 rbw_copy->numbodies = 0;
996 rigidbody_update_ob_array(rbw_copy);
1001 void BKE_rigidbody_world_groups_relink(RigidBodyWorld *rbw)
1003 ID_NEW_REMAP(rbw->group);
1004 ID_NEW_REMAP(rbw->constraints);
1005 ID_NEW_REMAP(rbw->effector_weights->group);
1008 void BKE_rigidbody_world_id_loop(RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata)
1010 func(rbw, (ID **)&rbw->group, userdata, IDWALK_CB_NOP);
1011 func(rbw, (ID **)&rbw->constraints, userdata, IDWALK_CB_NOP);
1012 func(rbw, (ID **)&rbw->effector_weights->group, userdata, IDWALK_CB_NOP);
1016 for (i = 0; i < rbw->numbodies; i++) {
1017 func(rbw, (ID **)&rbw->objects[i], userdata, IDWALK_CB_NOP);
1022 /* Add rigid body settings to the specified object */
1023 RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
1026 RigidBodyWorld *rbw = scene->rigidbody_world;
1029 * - rigidbody world must exist
1030 * - object must exist
1031 * - cannot add rigid body if it already exists
1033 if (ob == NULL || (ob->rigidbody_object != NULL))
1036 /* create new settings data, and link it up */
1037 rbo = MEM_callocN(sizeof(RigidBodyOb), "RigidBodyOb");
1038 rbo->shared = MEM_callocN(sizeof(*rbo->shared), "RigidBodyOb_Shared");
1040 /* set default settings */
1045 rbo->friction = 0.5f; /* best when non-zero. 0.5 is Bullet default */
1046 rbo->restitution = 0.0f; /* best when zero. 0.0 is Bullet default */
1048 rbo->margin = 0.04f; /* 0.04 (in meters) is Bullet default */
1050 rbo->lin_sleep_thresh = 0.4f; /* 0.4 is half of Bullet default */
1051 rbo->ang_sleep_thresh = 0.5f; /* 0.5 is half of Bullet default */
1053 rbo->lin_damping = 0.04f;
1054 rbo->ang_damping = 0.1f;
1056 rbo->col_groups = 1;
1058 /* use triangle meshes for passive objects
1059 * use convex hulls for active objects since dynamic triangle meshes are very unstable
1061 if (type == RBO_TYPE_ACTIVE)
1062 rbo->shape = RB_SHAPE_CONVEXH;
1064 rbo->shape = RB_SHAPE_TRIMESH;
1066 rbo->mesh_source = RBO_MESH_DEFORM;
1068 /* set initial transform */
1069 mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
1071 /* flag cache as outdated */
1072 BKE_rigidbody_cache_reset(rbw);
1073 rbo->flag |= (RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE);
1075 /* return this object */
1079 /* Add rigid body constraint to the specified object */
1080 RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type)
1083 RigidBodyWorld *rbw = scene->rigidbody_world;
1086 * - rigidbody world must exist
1087 * - object must exist
1088 * - cannot add constraint if it already exists
1090 if (ob == NULL || (ob->rigidbody_constraint != NULL))
1093 /* create new settings data, and link it up */
1094 rbc = MEM_callocN(sizeof(RigidBodyCon), "RigidBodyCon");
1096 /* set default settings */
1102 rbc->flag |= RBC_FLAG_ENABLED;
1103 rbc->flag |= RBC_FLAG_DISABLE_COLLISIONS;
1104 rbc->flag |= RBC_FLAG_NEEDS_VALIDATE;
1106 rbc->spring_type = RBC_SPRING_TYPE2;
1108 rbc->breaking_threshold = 10.0f; /* no good default here, just use 10 for now */
1109 rbc->num_solver_iterations = 10; /* 10 is Bullet default */
1111 rbc->limit_lin_x_lower = -1.0f;
1112 rbc->limit_lin_x_upper = 1.0f;
1113 rbc->limit_lin_y_lower = -1.0f;
1114 rbc->limit_lin_y_upper = 1.0f;
1115 rbc->limit_lin_z_lower = -1.0f;
1116 rbc->limit_lin_z_upper = 1.0f;
1117 rbc->limit_ang_x_lower = -M_PI_4;
1118 rbc->limit_ang_x_upper = M_PI_4;
1119 rbc->limit_ang_y_lower = -M_PI_4;
1120 rbc->limit_ang_y_upper = M_PI_4;
1121 rbc->limit_ang_z_lower = -M_PI_4;
1122 rbc->limit_ang_z_upper = M_PI_4;
1124 rbc->spring_damping_x = 0.5f;
1125 rbc->spring_damping_y = 0.5f;
1126 rbc->spring_damping_z = 0.5f;
1127 rbc->spring_damping_ang_x = 0.5f;
1128 rbc->spring_damping_ang_y = 0.5f;
1129 rbc->spring_damping_ang_z = 0.5f;
1130 rbc->spring_stiffness_x = 10.0f;
1131 rbc->spring_stiffness_y = 10.0f;
1132 rbc->spring_stiffness_z = 10.0f;
1133 rbc->spring_stiffness_ang_x = 10.0f;
1134 rbc->spring_stiffness_ang_y = 10.0f;
1135 rbc->spring_stiffness_ang_z = 10.0f;
1137 rbc->motor_lin_max_impulse = 1.0f;
1138 rbc->motor_lin_target_velocity = 1.0f;
1139 rbc->motor_ang_max_impulse = 1.0f;
1140 rbc->motor_ang_target_velocity = 1.0f;
1142 /* flag cache as outdated */
1143 BKE_rigidbody_cache_reset(rbw);
1145 /* return this object */
1149 void BKE_rigidbody_objects_collection_validate(Scene *scene, RigidBodyWorld *rbw)
1151 if (rbw->group != NULL) {
1152 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
1154 if (object->type != OB_MESH || object->rigidbody_object != NULL) {
1157 object->rigidbody_object = BKE_rigidbody_create_object(scene, object, RBO_TYPE_ACTIVE);
1159 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1163 void BKE_rigidbody_constraints_collection_validate(Scene *scene, RigidBodyWorld *rbw)
1165 if (rbw->constraints != NULL) {
1166 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, object)
1168 if (object->rigidbody_constraint != NULL) {
1171 object->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, object, RBC_TYPE_FIXED);
1173 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1177 void BKE_rigidbody_main_collection_object_add(Main *bmain, Collection *collection, Object *object)
1179 for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
1180 RigidBodyWorld *rbw = scene->rigidbody_world;
1186 if (rbw->group == collection && object->type == OB_MESH && object->rigidbody_object == NULL) {
1187 object->rigidbody_object = BKE_rigidbody_create_object(scene, object, RBO_TYPE_ACTIVE);
1189 if (rbw->constraints == collection && object->rigidbody_constraint == NULL) {
1190 object->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, object, RBC_TYPE_FIXED);
1195 /* ************************************** */
1198 /* Get RigidBody world for the given scene, creating one if needed
1200 * \param scene: Scene to find active Rigid Body world for
1202 RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene)
1208 return scene->rigidbody_world;
1211 void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob)
1213 RigidBodyWorld *rbw = scene->rigidbody_world;
1219 /* remove object from array */
1220 if (rbw && rbw->objects) {
1221 for (i = 0; i < rbw->numbodies; i++) {
1222 if (rbw->objects[i] == ob) {
1223 rbw->objects[i] = NULL;
1229 /* remove object from rigid body constraints */
1230 if (rbw->constraints) {
1231 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, obt)
1233 if (obt && obt->rigidbody_constraint) {
1234 rbc = obt->rigidbody_constraint;
1235 if (ELEM(ob, rbc->ob1, rbc->ob2)) {
1236 BKE_rigidbody_remove_constraint(scene, obt);
1240 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1242 BKE_collection_object_remove(bmain, rbw->group, ob, false);
1245 /* remove object's settings */
1246 BKE_rigidbody_free_object(ob, rbw);
1248 /* flag cache as outdated */
1249 BKE_rigidbody_cache_reset(rbw);
1252 void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
1254 RigidBodyWorld *rbw = scene->rigidbody_world;
1255 RigidBodyCon *rbc = ob->rigidbody_constraint;
1257 /* remove from rigidbody world, free object won't do this */
1258 if (rbw && rbw->shared->physics_world && rbc->physics_constraint) {
1259 RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
1261 /* remove object's settings */
1262 BKE_rigidbody_free_constraint(ob);
1264 /* flag cache as outdated */
1265 BKE_rigidbody_cache_reset(rbw);
1269 /* ************************************** */
1270 /* Simulation Interface - Bullet */
1272 /* Update object array and rigid body count so they're in sync with the rigid body group */
1273 static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
1275 if (rbw->group == NULL) {
1277 rbw->objects = realloc(rbw->objects, 0);
1282 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
1287 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1289 if (rbw->numbodies != n) {
1291 rbw->objects = realloc(rbw->objects, sizeof(Object *) * rbw->numbodies);
1295 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
1297 rbw->objects[i] = object;
1300 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1303 static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw)
1305 float adj_gravity[3];
1307 /* adjust gravity to take effector weights into account */
1308 if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
1309 copy_v3_v3(adj_gravity, scene->physics_settings.gravity);
1310 mul_v3_fl(adj_gravity, rbw->effector_weights->global_gravity * rbw->effector_weights->weight[0]);
1313 zero_v3(adj_gravity);
1316 /* update gravity, since this RNA setting is not part of RigidBody settings */
1317 RB_dworld_set_gravity(rbw->shared->physics_world, adj_gravity);
1319 /* update object array in case there are changes */
1320 rigidbody_update_ob_array(rbw);
1323 static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo)
1329 /* only update if rigid body exists */
1330 if (rbo->shared->physics_object == NULL)
1333 if (rbo->shape == RB_SHAPE_TRIMESH && rbo->flag & RBO_FLAG_USE_DEFORM) {
1334 Mesh *mesh = ob->runtime.mesh_deform_eval;
1336 MVert *mvert = mesh->mvert;
1337 int totvert = mesh->totvert;
1338 BoundBox *bb = BKE_object_boundbox_get(ob);
1340 RB_shape_trimesh_update(rbo->shared->physics_shape, (float *)mvert, totvert, sizeof(MVert), bb->vec[0], bb->vec[6]);
1344 mat4_decompose(loc, rot, scale, ob->obmat);
1346 /* update scale for all objects */
1347 RB_body_set_scale(rbo->shared->physics_object, scale);
1348 /* compensate for embedded convex hull collision margin */
1349 if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && rbo->shape == RB_SHAPE_CONVEXH)
1350 RB_shape_set_margin(rbo->shared->physics_shape, RBO_GET_MARGIN(rbo) * MIN3(scale[0], scale[1], scale[2]));
1352 /* make transformed objects temporarily kinmatic so that they can be moved by the user during simulation */
1353 if (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ) {
1354 RB_body_set_kinematic_state(rbo->shared->physics_object, true);
1355 RB_body_set_mass(rbo->shared->physics_object, 0.0f);
1358 /* update rigid body location and rotation for kinematic bodies */
1359 if (rbo->flag & RBO_FLAG_KINEMATIC || (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
1360 RB_body_activate(rbo->shared->physics_object);
1361 RB_body_set_loc_rot(rbo->shared->physics_object, loc, rot);
1363 /* update influence of effectors - but don't do it on an effector */
1364 /* only dynamic bodies need effector update */
1365 else if (rbo->type == RBO_TYPE_ACTIVE && ((ob->pd == NULL) || (ob->pd->forcefield == PFIELD_NULL))) {
1366 EffectorWeights *effector_weights = rbw->effector_weights;
1367 EffectedPoint epoint;
1368 ListBase *effectors;
1370 /* get effectors present in the group specified by effector_weights */
1371 effectors = BKE_effectors_create(depsgraph, ob, NULL, effector_weights);
1373 float eff_force[3] = {0.0f, 0.0f, 0.0f};
1374 float eff_loc[3], eff_vel[3];
1376 /* create dummy 'point' which represents last known position of object as result of sim */
1377 // XXX: this can create some inaccuracies with sim position, but is probably better than using unsimulated vals?
1378 RB_body_get_position(rbo->shared->physics_object, eff_loc);
1379 RB_body_get_linear_velocity(rbo->shared->physics_object, eff_vel);
1381 pd_point_from_loc(scene, eff_loc, eff_vel, 0, &epoint);
1383 /* calculate net force of effectors, and apply to sim object
1384 * - we use 'central force' since apply force requires a "relative position" which we don't have...
1386 BKE_effectors_apply(effectors, NULL, effector_weights, &epoint, eff_force, NULL);
1388 printf("\tapplying force (%f,%f,%f) to '%s'\n", eff_force[0], eff_force[1], eff_force[2], ob->id.name + 2);
1389 /* activate object in case it is deactivated */
1390 if (!is_zero_v3(eff_force))
1391 RB_body_activate(rbo->shared->physics_object);
1392 RB_body_apply_central_force(rbo->shared->physics_object, eff_force);
1394 else if (G.f & G_DEBUG)
1395 printf("\tno forces to apply to '%s'\n", ob->id.name + 2);
1398 BKE_effectors_free(effectors);
1400 /* NOTE: passive objects don't need to be updated since they don't move */
1402 /* NOTE: no other settings need to be explicitly updated here,
1403 * since RNA setters take care of the rest :)
1408 * Updates and validates world, bodies and shapes.
1410 * \param rebuild: Rebuild entire simulation
1412 static void rigidbody_update_simulation(Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, bool rebuild)
1416 BKE_rigidbody_validate_sim_world(scene, rbw, true);
1417 rigidbody_update_sim_world(scene, rbw);
1419 /* XXX TODO For rebuild: remove all constraints first.
1420 * Otherwise we can end up deleting objects that are still
1421 * referenced by constraints, corrupting bullet's internal list.
1423 * Memory management needs redesign here, this is just a dirty workaround.
1425 if (rebuild && rbw->constraints) {
1426 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, ob)
1428 RigidBodyCon *rbc = ob->rigidbody_constraint;
1429 if (rbc && rbc->physics_constraint) {
1430 RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
1431 RB_constraint_delete(rbc->physics_constraint);
1432 rbc->physics_constraint = NULL;
1435 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1438 /* update objects */
1439 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, ob)
1441 if (ob->type == OB_MESH) {
1442 /* validate that we've got valid object set up here... */
1443 RigidBodyOb *rbo = ob->rigidbody_object;
1444 /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
1445 BKE_object_where_is_calc(depsgraph, scene, ob);
1447 /* TODO remove this whole block once we are sure we never get NULL rbo here anymore. */
1448 /* This cannot be done in CoW evaluation context anymore... */
1450 BLI_assert(!"CoW object part of RBW object collection without RB object data, should not happen.\n");
1451 /* Since this object is included in the sim group but doesn't have
1452 * rigid body settings (perhaps it was added manually), add!
1453 * - assume object to be active? That is the default for newly added settings...
1455 ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, RBO_TYPE_ACTIVE);
1456 rigidbody_validate_sim_object(rbw, ob, true);
1458 rbo = ob->rigidbody_object;
1461 /* perform simulation data updates as tagged */
1462 /* refresh object... */
1464 /* World has been rebuilt so rebuild object */
1465 /* TODO(Sybren): rigidbody_validate_sim_object() can call rigidbody_validate_sim_shape(),
1466 * but neither resets the RBO_FLAG_NEEDS_RESHAPE flag nor calls RB_body_set_collision_shape().
1467 * This results in the collision shape being created twice, which is unnecessary. */
1468 rigidbody_validate_sim_object(rbw, ob, true);
1470 else if (rbo->flag & RBO_FLAG_NEEDS_VALIDATE) {
1471 rigidbody_validate_sim_object(rbw, ob, false);
1473 /* refresh shape... */
1474 if (rbo->flag & RBO_FLAG_NEEDS_RESHAPE) {
1475 /* mesh/shape data changed, so force shape refresh */
1476 rigidbody_validate_sim_shape(ob, true);
1477 /* now tell RB sim about it */
1478 // XXX: we assume that this can only get applied for active/passive shapes that will be included as rigidbodies
1479 RB_body_set_collision_shape(rbo->shared->physics_object, rbo->shared->physics_shape);
1482 rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE);
1484 /* update simulation object... */
1485 rigidbody_update_sim_ob(depsgraph, scene, rbw, ob, rbo);
1488 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1490 /* update constraints */
1491 if (rbw->constraints == NULL) /* no constraints, move on */
1494 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, ob)
1496 /* validate that we've got valid object set up here... */
1497 RigidBodyCon *rbc = ob->rigidbody_constraint;
1498 /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
1499 BKE_object_where_is_calc(depsgraph, scene, ob);
1501 /* TODO remove this whole block once we are sure we never get NULL rbo here anymore. */
1502 /* This cannot be done in CoW evaluation context anymore... */
1504 BLI_assert(!"CoW object part of RBW constraints collection without RB constraint data, should not happen.\n");
1505 /* Since this object is included in the group but doesn't have
1506 * constraint settings (perhaps it was added manually), add!
1508 ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED);
1509 rigidbody_validate_sim_constraint(rbw, ob, true);
1511 rbc = ob->rigidbody_constraint;
1514 /* perform simulation data updates as tagged */
1516 /* World has been rebuilt so rebuild constraint */
1517 rigidbody_validate_sim_constraint(rbw, ob, true);
1519 else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) {
1520 rigidbody_validate_sim_constraint(rbw, ob, false);
1523 rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE;
1525 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1528 static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBodyWorld *rbw)
1530 ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
1532 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, ob)
1534 Base *base = BKE_view_layer_base_find(view_layer, ob);
1535 RigidBodyOb *rbo = ob->rigidbody_object;
1536 /* Reset kinematic state for transformed objects. */
1537 if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) {
1538 RB_body_set_kinematic_state(rbo->shared->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
1539 RB_body_set_mass(rbo->shared->physics_object, RBO_GET_MASS(rbo));
1540 /* Deactivate passive objects so they don't interfere with deactivation of active objects. */
1541 if (rbo->type == RBO_TYPE_PASSIVE)
1542 RB_body_deactivate(rbo->shared->physics_object);
1545 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1548 bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime)
1550 return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0 && ctime > rbw->shared->pointcache->startframe);
1553 /* Sync rigid body and object transformations */
1554 void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
1556 RigidBodyOb *rbo = ob->rigidbody_object;
1558 /* keep original transform for kinematic and passive objects */
1559 if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE)
1562 /* use rigid body transform after cache start frame if objects is not being transformed */
1563 if (BKE_rigidbody_check_sim_running(rbw, ctime) && !(ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
1564 float mat[4][4], size_mat[4][4], size[3];
1566 normalize_qt(rbo->orn); // RB_TODO investigate why quaternion isn't normalized at this point
1567 quat_to_mat4(mat, rbo->orn);
1568 copy_v3_v3(mat[3], rbo->pos);
1570 mat4_to_size(size, ob->obmat);
1571 size_to_mat4(size_mat, size);
1572 mul_m4_m4m4(mat, mat, size_mat);
1574 copy_m4_m4(ob->obmat, mat);
1576 /* otherwise set rigid body transform to current obmat */
1578 mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
1582 /* Used when canceling transforms - return rigidbody and object to initial states */
1583 void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
1585 RigidBodyOb *rbo = ob->rigidbody_object;
1586 bool correct_delta = !(rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE);
1588 /* return rigid body and object to their initial states */
1589 copy_v3_v3(rbo->pos, ob->loc);
1590 copy_v3_v3(ob->loc, loc);
1592 if (correct_delta) {
1593 add_v3_v3(rbo->pos, ob->dloc);
1596 if (ob->rotmode > 0) {
1598 eulO_to_quat(qt, ob->rot, ob->rotmode);
1600 if (correct_delta) {
1602 eulO_to_quat(dquat, ob->drot, ob->rotmode);
1604 mul_qt_qtqt(rbo->orn, dquat, qt);
1607 copy_qt_qt(rbo->orn, qt);
1610 copy_v3_v3(ob->rot, rot);
1612 else if (ob->rotmode == ROT_MODE_AXISANGLE) {
1614 axis_angle_to_quat(qt, ob->rotAxis, ob->rotAngle);
1616 if (correct_delta) {
1618 axis_angle_to_quat(dquat, ob->drotAxis, ob->drotAngle);
1620 mul_qt_qtqt(rbo->orn, dquat, qt);
1623 copy_qt_qt(rbo->orn, qt);
1626 copy_v3_v3(ob->rotAxis, rotAxis);
1627 ob->rotAngle = rotAngle;
1630 if (correct_delta) {
1631 mul_qt_qtqt(rbo->orn, ob->dquat, ob->quat);
1634 copy_qt_qt(rbo->orn, ob->quat);
1637 copy_qt_qt(ob->quat, quat);
1640 if (rbo->shared->physics_object) {
1641 /* allow passive objects to return to original transform */
1642 if (rbo->type == RBO_TYPE_PASSIVE)
1643 RB_body_set_kinematic_state(rbo->shared->physics_object, true);
1644 RB_body_set_loc_rot(rbo->shared->physics_object, rbo->pos, rbo->orn);
1646 // 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)
1649 void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
1652 rbw->shared->pointcache->flag |= PTCACHE_OUTDATED;
1656 /* ------------------ */
1658 /* Rebuild rigid body world */
1659 /* NOTE: this needs to be called before frame update to work correctly */
1660 void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime)
1662 RigidBodyWorld *rbw = scene->rigidbody_world;
1665 int startframe, endframe;
1667 BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
1668 BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
1669 cache = rbw->shared->pointcache;
1671 /* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */
1673 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
1678 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1680 if (rbw->shared->physics_world == NULL || rbw->numbodies != n) {
1681 cache->flag |= PTCACHE_OUTDATED;
1684 if (ctime == startframe + 1 && rbw->ltime == startframe) {
1685 if (cache->flag & PTCACHE_OUTDATED) {
1686 BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
1687 rigidbody_update_simulation(depsgraph, scene, rbw, true);
1688 BKE_ptcache_validate(cache, (int)ctime);
1689 cache->last_exact = 0;
1690 cache->flag &= ~PTCACHE_REDO_NEEDED;
1695 /* Run RigidBody simulation for the specified physics world */
1696 void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime)
1699 RigidBodyWorld *rbw = scene->rigidbody_world;
1702 int startframe, endframe;
1704 BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
1705 BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
1706 cache = rbw->shared->pointcache;
1708 if (ctime <= startframe) {
1709 rbw->ltime = startframe;
1712 /* make sure we don't go out of cache frame range */
1713 else if (ctime > endframe) {
1717 /* don't try to run the simulation if we don't have a world yet but allow reading baked cache */
1718 if (rbw->shared->physics_world == NULL && !(cache->flag & PTCACHE_BAKED))
1720 else if (rbw->objects == NULL)
1721 rigidbody_update_ob_array(rbw);
1723 /* try to read from cache */
1724 // RB_TODO deal with interpolated, old and baked results
1725 bool can_simulate = (ctime == rbw->ltime + 1) && !(cache->flag & PTCACHE_BAKED);
1727 if (BKE_ptcache_read(&pid, ctime, can_simulate) == PTCACHE_READ_EXACT) {
1728 BKE_ptcache_validate(cache, (int)ctime);
1733 if (!DEG_is_active(depsgraph)) {
1734 /* When the depsgraph is inactive we should neither write to the cache
1735 * nor run the simulation. */
1739 /* advance simulation, we can only step one frame forward */
1740 if (compare_ff_relative(ctime, rbw->ltime + 1, FLT_EPSILON, 64)) {
1741 /* write cache for first frame when on second frame */
1742 if (rbw->ltime == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) {
1743 BKE_ptcache_write(&pid, startframe);
1746 /* update and validate simulation */
1747 rigidbody_update_simulation(depsgraph, scene, rbw, false);
1749 /* calculate how much time elapsed since last step in seconds */
1750 timestep = 1.0f / (float)FPS * (ctime - rbw->ltime) * rbw->time_scale;
1751 /* step simulation by the requested timestep, steps per second are adjusted to take time scale into account */
1752 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));
1754 rigidbody_update_simulation_post_step(depsgraph, rbw);
1756 /* write cache for current frame */
1757 BKE_ptcache_validate(cache, (int)ctime);
1758 BKE_ptcache_write(&pid, (unsigned int)ctime);
1763 /* ************************************** */
1765 #else /* WITH_BULLET */
1768 #if defined(__GNUC__) || defined(__clang__)
1769 # pragma GCC diagnostic push
1770 # pragma GCC diagnostic ignored "-Wunused-parameter"
1773 struct RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int flag) { return NULL; }
1774 struct RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int flag) { return NULL; }
1775 void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild) {}
1776 void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) { if (r_vol) *r_vol = 0.0f; }
1777 void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3]) { zero_v3(r_center); }
1778 struct RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene) { return NULL; }
1779 struct RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag) { return NULL; }
1780 void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw) {}
1781 void BKE_rigidbody_world_id_loop(struct RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata) {}
1782 struct RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type) { return NULL; }
1783 struct RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type) { return NULL; }
1784 struct RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene) { return NULL; }
1785 void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob) {}
1786 void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob) {}
1787 void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) {}
1788 void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {}
1789 bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) { return false; }
1790 void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
1791 void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime) {}
1792 void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime) {}
1793 void BKE_rigidbody_objects_collection_validate(Scene *scene, RigidBodyWorld *rbw) {}
1794 void BKE_rigidbody_constraints_collection_validate(Scene *scene, RigidBodyWorld *rbw) {}
1796 #if defined(__GNUC__) || defined(__clang__)
1797 # pragma GCC diagnostic pop
1800 #endif /* WITH_BULLET */
1804 /* -------------------- */
1805 /* Depsgraph evaluation */
1807 void BKE_rigidbody_rebuild_sim(Depsgraph *depsgraph,
1810 float ctime = DEG_get_ctime(depsgraph);
1811 DEG_debug_print_eval_time(depsgraph, __func__, scene->id.name, scene, ctime);
1812 /* rebuild sim data (i.e. after resetting to start of timeline) */
1813 if (BKE_scene_check_rigidbody_active(scene)) {
1814 BKE_rigidbody_rebuild_world(depsgraph, scene, ctime);
1818 void BKE_rigidbody_eval_simulation(Depsgraph *depsgraph,
1821 float ctime = DEG_get_ctime(depsgraph);
1822 DEG_debug_print_eval_time(depsgraph, __func__, scene->id.name, scene, ctime);
1824 /* evaluate rigidbody sim */
1825 if (!BKE_scene_check_rigidbody_active(scene)) {
1828 BKE_rigidbody_do_simulation(depsgraph, scene, ctime);
1831 void BKE_rigidbody_object_sync_transforms(Depsgraph *depsgraph,
1835 RigidBodyWorld *rbw = scene->rigidbody_world;
1836 float ctime = DEG_get_ctime(depsgraph);
1837 DEG_debug_print_eval_time(depsgraph, __func__, ob->id.name, ob, ctime);
1838 /* read values pushed into RBO from sim/cache... */
1839 BKE_rigidbody_sync_transforms(rbw, ob, ctime);