Blender  V3.3
rigidbody.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2013 Blender Foundation. All rights reserved. */
3 
9 #include <float.h>
10 #include <limits.h>
11 #include <math.h>
12 #include <stddef.h>
13 #include <stdio.h>
14 #include <string.h>
15 
16 #include "CLG_log.h"
17 
18 #include "MEM_guardedalloc.h"
19 
20 #include "BLI_listbase.h"
21 #include "BLI_math.h"
22 
23 #ifdef WITH_BULLET
24 # include "RBI_api.h"
25 #endif
26 
27 #include "DNA_ID.h"
28 #include "DNA_collection_types.h"
29 #include "DNA_mesh_types.h"
30 #include "DNA_meshdata_types.h"
31 #include "DNA_object_force_types.h"
32 #include "DNA_object_types.h"
33 #include "DNA_rigidbody_types.h"
34 #include "DNA_scene_types.h"
35 
36 #include "BKE_collection.h"
37 #include "BKE_effect.h"
38 #include "BKE_global.h"
39 #include "BKE_layer.h"
40 #include "BKE_main.h"
41 #include "BKE_mesh.h"
42 #include "BKE_mesh_runtime.h"
43 #include "BKE_object.h"
44 #include "BKE_pointcache.h"
45 #include "BKE_report.h"
46 #include "BKE_rigidbody.h"
47 #include "BKE_scene.h"
48 #ifdef WITH_BULLET
49 # include "BKE_lib_id.h"
50 # include "BKE_lib_query.h"
51 #endif
52 
53 #include "DEG_depsgraph.h"
54 #include "DEG_depsgraph_query.h"
55 
56 #ifdef WITH_BULLET
57 static CLG_LogRef LOG = {"bke.rigidbody"};
58 #endif
59 
60 /* ************************************** */
61 /* Memory Management */
62 
63 /* Freeing Methods --------------------- */
64 
65 #ifdef WITH_BULLET
66 static void rigidbody_update_ob_array(RigidBodyWorld *rbw);
67 
68 #else
69 static void RB_dworld_remove_constraint(void *UNUSED(world), void *UNUSED(con))
70 {
71 }
72 static void RB_dworld_remove_body(void *UNUSED(world), void *UNUSED(body))
73 {
74 }
75 static void RB_dworld_delete(void *UNUSED(world))
76 {
77 }
78 static void RB_body_delete(void *UNUSED(body))
79 {
80 }
81 static void RB_shape_delete(void *UNUSED(shape))
82 {
83 }
84 static void RB_constraint_delete(void *UNUSED(con))
85 {
86 }
87 
88 #endif
89 
91 {
92  bool is_orig = (scene->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0;
95 
96  /* sanity check */
97  if (!rbw) {
98  return;
99  }
100 
101  if (is_orig && rbw->shared->physics_world) {
102  /* Free physics references,
103  * we assume that all physics objects in will have been added to the world. */
104  if (rbw->constraints) {
106  if (object->rigidbody_constraint) {
107  RigidBodyCon *rbc = object->rigidbody_constraint;
108  if (rbc->physics_constraint) {
110  }
111  }
112  }
114  }
115 
116  if (rbw->group) {
118  BKE_rigidbody_free_object(object, rbw);
119  }
121  }
122  /* free dynamics world */
124  }
125  if (rbw->objects) {
126  free(rbw->objects);
127  }
128 
129  if (is_orig) {
130  /* free cache */
132  rbw->shared->pointcache = NULL;
133 
134  MEM_freeN(rbw->shared);
135  }
136 
137  /* free effector weights */
138  if (rbw->effector_weights) {
140  }
141 
142  /* free rigidbody world itself */
143  MEM_freeN(rbw);
144 }
145 
147 {
148  bool is_orig = (ob->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0;
149  RigidBodyOb *rbo = ob->rigidbody_object;
150 
151  /* sanity check */
152  if (rbo == NULL) {
153  return;
154  }
155 
156  /* free physics references */
157  if (is_orig) {
158  if (rbo->shared->physics_object) {
159  if (rbw != NULL && rbw->shared->physics_world != NULL) {
160  /* We can only remove the body from the world if the world is known.
161  * The world is generally only unknown if it's an evaluated copy of
162  * an object that's being freed, in which case this code isn't run anyway. */
164  }
165  else {
166  /* We have no access to 'owner' RBW when deleting the object ID itself... No choice bu to
167  * loop over all scenes then. */
168  for (Scene *scene = G_MAIN->scenes.first; scene != NULL; scene = scene->id.next) {
169  RigidBodyWorld *scene_rbw = scene->rigidbody_world;
170  if (scene_rbw != NULL && scene_rbw->shared->physics_world != NULL) {
172  }
173  }
174  }
175 
177  rbo->shared->physics_object = NULL;
178  }
179 
180  if (rbo->shared->physics_shape) {
182  rbo->shared->physics_shape = NULL;
183  }
184 
185  MEM_freeN(rbo->shared);
186  }
187 
188  /* free data itself */
189  MEM_freeN(rbo);
190  ob->rigidbody_object = NULL;
191 }
192 
194 {
195  RigidBodyCon *rbc = (ob) ? ob->rigidbody_constraint : NULL;
196 
197  /* sanity check */
198  if (rbc == NULL) {
199  return;
200  }
201 
202  /* free physics reference */
203  if (rbc->physics_constraint) {
205  rbc->physics_constraint = NULL;
206  }
207 
208  /* free data itself */
209  MEM_freeN(rbc);
211 }
212 
214 {
215  /* Check if the object will have its transform changed by the rigidbody simulation. */
216 
217  /* True if the shape of this object's parent is of type compound */
218  bool obCompoundParent = (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
220 
221  RigidBodyOb *rbo = ob->rigidbody_object;
222  if (rbo == NULL || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE ||
223  obCompoundParent) {
224  return false;
225  }
226 
227  return true;
228 }
229 
230 #ifdef WITH_BULLET
231 
232 /* Copying Methods --------------------- */
233 
234 /* These just copy the data, clearing out references to physics objects.
235  * Anything that uses them MUST verify that the copied object will
236  * be added to relevant groups later...
237  */
238 
239 static RigidBodyOb *rigidbody_copy_object(const Object *ob, const int flag)
240 {
241  RigidBodyOb *rboN = NULL;
242 
243  if (ob->rigidbody_object) {
244  const bool is_orig = (flag & LIB_ID_COPY_SET_COPIED_ON_WRITE) == 0;
245 
246  /* just duplicate the whole struct first (to catch all the settings) */
247  rboN = MEM_dupallocN(ob->rigidbody_object);
248 
249  if (is_orig) {
250  /* This is a regular copy, and not a CoW copy for depsgraph evaluation */
251  rboN->shared = MEM_callocN(sizeof(*rboN->shared), "RigidBodyOb_Shared");
252  }
253 
254  /* tag object as needing to be verified */
255  rboN->flag |= RBO_FLAG_NEEDS_VALIDATE;
256  }
257 
258  /* return new copy of settings */
259  return rboN;
260 }
261 
262 static RigidBodyCon *rigidbody_copy_constraint(const Object *ob, const int UNUSED(flag))
263 {
264  RigidBodyCon *rbcN = NULL;
265 
266  if (ob->rigidbody_constraint) {
267  /* just duplicate the whole struct first (to catch all the settings) */
269 
270  /* tag object as needing to be verified */
271  rbcN->flag |= RBC_FLAG_NEEDS_VALIDATE;
272 
273  /* clear out all the fields which need to be revalidated later */
274  rbcN->physics_constraint = NULL;
275  }
276 
277  /* return new copy of settings */
278  return rbcN;
279 }
280 
281 void BKE_rigidbody_object_copy(Main *bmain, Object *ob_dst, const Object *ob_src, const int flag)
282 {
283  ob_dst->rigidbody_object = rigidbody_copy_object(ob_src, flag);
284  ob_dst->rigidbody_constraint = rigidbody_copy_constraint(ob_src, flag);
285 
287  return;
288  }
289 
290  /* We have to ensure that duplicated object ends up in relevant rigidbody collections...
291  * Otherwise duplicating the RB data itself is meaningless. */
292  LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
293  RigidBodyWorld *rigidbody_world = scene->rigidbody_world;
294 
295  if (rigidbody_world != NULL) {
296  bool need_objects_update = false;
297  bool need_constraints_update = false;
298 
299  if (ob_dst->rigidbody_object) {
300  if (BKE_collection_has_object(rigidbody_world->group, ob_src)) {
301  BKE_collection_object_add(bmain, rigidbody_world->group, ob_dst);
302  need_objects_update = true;
303  }
304  }
305  if (ob_dst->rigidbody_constraint) {
306  if (BKE_collection_has_object(rigidbody_world->constraints, ob_src)) {
307  BKE_collection_object_add(bmain, rigidbody_world->constraints, ob_dst);
308  need_constraints_update = true;
309  }
310  }
311 
312  if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0 &&
313  (need_objects_update || need_constraints_update)) {
314  BKE_rigidbody_cache_reset(rigidbody_world);
315 
317  if (need_objects_update) {
318  DEG_id_tag_update(&rigidbody_world->group->id, ID_RECALC_COPY_ON_WRITE);
319  }
320  if (need_constraints_update) {
322  }
324  }
325  }
326  }
327 }
328 
329 /* ************************************** */
330 /* Setup Utilities - Validate Sim Instances */
331 
332 /* get the appropriate evaluated mesh based on rigid body mesh source */
333 static Mesh *rigidbody_get_mesh(Object *ob)
334 {
335  BLI_assert(ob->type == OB_MESH);
336 
337  switch (ob->rigidbody_object->mesh_source) {
338  case RBO_MESH_DEFORM:
339  return ob->runtime.mesh_deform_eval;
340  case RBO_MESH_FINAL:
342  case RBO_MESH_BASE:
343  /* This mesh may be used for computing looptris, which should be done
344  * on the original; otherwise every time the CoW is recreated it will
345  * have to be recomputed. */
347  return (Mesh *)ob->runtime.data_orig;
348  }
349 
350  /* Just return something sensible so that at least Blender won't crash. */
351  BLI_assert_msg(0, "Unknown mesh source");
353 }
354 
355 /* create collision shape of mesh - convex hull */
356 static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob,
357  float margin,
358  bool *can_embed)
359 {
360  rbCollisionShape *shape = NULL;
361  Mesh *mesh = NULL;
362  MVert *mvert = NULL;
363  int totvert = 0;
364 
365  if (ob->type == OB_MESH && ob->data) {
366  mesh = rigidbody_get_mesh(ob);
367  mvert = (mesh) ? mesh->mvert : NULL;
368  totvert = (mesh) ? mesh->totvert : 0;
369  }
370  else {
371  CLOG_ERROR(&LOG, "cannot make Convex Hull collision shape for non-Mesh object");
372  }
373 
374  if (totvert) {
375  shape = RB_shape_new_convex_hull((float *)mvert, sizeof(MVert), totvert, margin, can_embed);
376  }
377  else {
378  CLOG_ERROR(&LOG, "no vertices to define Convex Hull collision shape with");
379  }
380 
381  return shape;
382 }
383 
384 /* create collision shape of mesh - triangulated mesh
385  * returns NULL if creation fails.
386  */
387 static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
388 {
389  rbCollisionShape *shape = NULL;
390 
391  if (ob->type == OB_MESH) {
392  Mesh *mesh = NULL;
393  MVert *mvert;
394  const MLoopTri *looptri;
395  int totvert;
396  int tottri;
397  const MLoop *mloop;
398 
399  mesh = rigidbody_get_mesh(ob);
400 
401  /* ensure mesh validity, then grab data */
402  if (mesh == NULL) {
403  return NULL;
404  }
405 
406  mvert = mesh->mvert;
407  totvert = mesh->totvert;
409  tottri = mesh->runtime.looptris.len;
410  mloop = mesh->mloop;
411 
412  /* sanity checking - potential case when no data will be present */
413  if ((totvert == 0) || (tottri == 0)) {
414  CLOG_WARN(
415  &LOG, "no geometry data converted for Mesh Collision Shape (ob = %s)", ob->id.name + 2);
416  }
417  else {
418  rbMeshData *mdata;
419  int i;
420 
421  /* init mesh data for collision shape */
422  mdata = RB_trimesh_data_new(tottri, totvert);
423 
424  RB_trimesh_add_vertices(mdata, (float *)mvert, totvert, sizeof(MVert));
425 
426  /* loop over all faces, adding them as triangles to the collision shape
427  * (so for some faces, more than triangle will get added)
428  */
429  if (mvert && looptri) {
430  for (i = 0; i < tottri; i++) {
431  /* add first triangle - verts 1,2,3 */
432  const MLoopTri *lt = &looptri[i];
433  int vtri[3];
434 
435  vtri[0] = mloop[lt->tri[0]].v;
436  vtri[1] = mloop[lt->tri[1]].v;
437  vtri[2] = mloop[lt->tri[2]].v;
438 
439  RB_trimesh_add_triangle_indices(mdata, i, UNPACK3(vtri));
440  }
441  }
442 
443  RB_trimesh_finish(mdata);
444 
445  /* construct collision shape
446  *
447  * These have been chosen to get better speed/accuracy tradeoffs with regards
448  * to limitations of each:
449  * - BVH-Triangle Mesh: for passive objects only. Despite having greater
450  * speed/accuracy, they cannot be used for moving objects.
451  * - GImpact Mesh: for active objects. These are slower and less stable,
452  * but are more flexible for general usage.
453  */
454  if (ob->rigidbody_object->type == RBO_TYPE_PASSIVE) {
455  shape = RB_shape_new_trimesh(mdata);
456  }
457  else {
458  shape = RB_shape_new_gimpact_mesh(mdata);
459  }
460  }
461  }
462  else {
463  CLOG_ERROR(&LOG, "cannot make Triangular Mesh collision shape for non-Mesh object");
464  }
465 
466  return shape;
467 }
468 
469 /* Helper function to create physics collision shape for object.
470  * Returns a new collision shape.
471  */
472 static rbCollisionShape *rigidbody_validate_sim_shape_helper(RigidBodyWorld *rbw, Object *ob)
473 {
474  RigidBodyOb *rbo = ob->rigidbody_object;
475  rbCollisionShape *new_shape = NULL;
476  float size[3] = {1.0f, 1.0f, 1.0f};
477  float radius = 1.0f;
478  float height = 1.0f;
479  float capsule_height;
480  float hull_margin = 0.0f;
481  bool can_embed = true;
482  bool has_volume;
483 
484  /* sanity check */
485  if (rbo == NULL) {
486  return NULL;
487  }
488 
489  /* if automatically determining dimensions, use the Object's boundbox
490  * - assume that all quadrics are standing upright on local z-axis
491  * - assume even distribution of mass around the Object's pivot
492  * (i.e. Object pivot is centralized in boundbox)
493  */
494  /* XXX: all dimensions are auto-determined now... later can add stored settings for this */
495  /* get object dimensions without scaling */
496  const BoundBox *bb = BKE_object_boundbox_get(ob);
497  if (bb) {
498  size[0] = (bb->vec[4][0] - bb->vec[0][0]);
499  size[1] = (bb->vec[2][1] - bb->vec[0][1]);
500  size[2] = (bb->vec[1][2] - bb->vec[0][2]);
501  }
502  mul_v3_fl(size, 0.5f);
503 
505  /* take radius as largest x/y dimension, and height as z-dimension */
506  radius = MAX2(size[0], size[1]);
507  height = size[2];
508  }
509  else if (rbo->shape == RB_SHAPE_SPHERE) {
510  /* take radius to the largest dimension to try and encompass everything */
511  radius = MAX3(size[0], size[1], size[2]);
512  }
513 
514  /* create new shape */
515  switch (rbo->shape) {
516  case RB_SHAPE_BOX:
517  new_shape = RB_shape_new_box(size[0], size[1], size[2]);
518  break;
519 
520  case RB_SHAPE_SPHERE:
521  new_shape = RB_shape_new_sphere(radius);
522  break;
523 
524  case RB_SHAPE_CAPSULE:
525  capsule_height = (height - radius) * 2.0f;
526  new_shape = RB_shape_new_capsule(radius, (capsule_height > 0.0f) ? capsule_height : 0.0f);
527  break;
528  case RB_SHAPE_CYLINDER:
529  new_shape = RB_shape_new_cylinder(radius, height);
530  break;
531  case RB_SHAPE_CONE:
532  new_shape = RB_shape_new_cone(radius, height * 2.0f);
533  break;
534 
535  case RB_SHAPE_CONVEXH:
536  /* try to embed collision margin */
537  has_volume = (MIN3(size[0], size[1], size[2]) > 0.0f);
538 
539  if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && has_volume) {
540  hull_margin = 0.04f;
541  }
542  new_shape = rigidbody_get_shape_convexhull_from_mesh(ob, hull_margin, &can_embed);
543  if (!(rbo->flag & RBO_FLAG_USE_MARGIN)) {
544  rbo->margin = (can_embed && has_volume) ?
545  0.04f :
546  0.0f; /* RB_TODO ideally we shouldn't directly change the margin here */
547  }
548  break;
549  case RB_SHAPE_TRIMESH:
550  new_shape = rigidbody_get_shape_trimesh_from_mesh(ob);
551  break;
552  case RB_SHAPE_COMPOUND:
553  new_shape = RB_shape_new_compound();
554  rbCollisionShape *childShape = NULL;
555  float loc[3], rot[4];
556  float mat[4][4];
557  /* Add children to the compound shape */
559  if (childObject->parent == ob) {
560  childShape = rigidbody_validate_sim_shape_helper(rbw, childObject);
561  if (childShape) {
562  BKE_object_matrix_local_get(childObject, mat);
563  mat4_to_loc_quat(loc, rot, mat);
564  RB_compound_add_child_shape(new_shape, childShape, loc, rot);
565  }
566  }
567  }
569 
570  break;
571  }
572  /* use box shape if it failed to create new shape */
573  if (new_shape == NULL) {
574  new_shape = RB_shape_new_box(size[0], size[1], size[2]);
575  }
576  if (new_shape) {
577  RB_shape_set_margin(new_shape, RBO_GET_MARGIN(rbo));
578  }
579 
580  return new_shape;
581 }
582 
583 /* Create new physics sim collision shape for object and store it,
584  * or remove the existing one first and replace...
585  */
586 static void rigidbody_validate_sim_shape(RigidBodyWorld *rbw, Object *ob, bool rebuild)
587 {
588  RigidBodyOb *rbo = ob->rigidbody_object;
589  rbCollisionShape *new_shape = NULL;
590 
591  /* sanity check */
592  if (rbo == NULL) {
593  return;
594  }
595 
596  /* don't create a new shape if we already have one and don't want to rebuild it */
597  if (rbo->shared->physics_shape && !rebuild) {
598  return;
599  }
600 
601  /* Also don't create a shape if this object is parent of a compound shape */
602  if (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
604  return;
605  }
606 
607  new_shape = rigidbody_validate_sim_shape_helper(rbw, ob);
608 
609  /* assign new collision shape if creation was successful */
610  if (new_shape) {
611  if (rbo->shared->physics_shape) {
613  }
614  rbo->shared->physics_shape = new_shape;
615  }
616 }
617 
618 /* --------------------- */
619 
620 void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
621 {
622  RigidBodyOb *rbo = ob->rigidbody_object;
623 
624  float size[3] = {1.0f, 1.0f, 1.0f};
625  float radius = 1.0f;
626  float height = 1.0f;
627 
628  float volume = 0.0f;
629 
630  /* if automatically determining dimensions, use the Object's boundbox
631  * - assume that all quadrics are standing upright on local z-axis
632  * - assume even distribution of mass around the Object's pivot
633  * (i.e. Object pivot is centralized in boundbox)
634  * - boundbox gives full width
635  */
636  /* XXX: all dimensions are auto-determined now... later can add stored settings for this */
638 
640  /* take radius as largest x/y dimension, and height as z-dimension */
641  radius = MAX2(size[0], size[1]) * 0.5f;
642  height = size[2];
643  }
644  else if (rbo->shape == RB_SHAPE_SPHERE) {
645  /* take radius to the largest dimension to try and encompass everything */
646  radius = max_fff(size[0], size[1], size[2]) * 0.5f;
647  }
648 
649  /* Calculate volume as appropriate. */
650  switch (rbo->shape) {
651  case RB_SHAPE_BOX:
652  volume = size[0] * size[1] * size[2];
653  break;
654 
655  case RB_SHAPE_SPHERE:
656  volume = 4.0f / 3.0f * (float)M_PI * radius * radius * radius;
657  break;
658 
659  /* for now, assume that capsule is close enough to a cylinder... */
660  case RB_SHAPE_CAPSULE:
661  case RB_SHAPE_CYLINDER:
662  volume = (float)M_PI * radius * radius * height;
663  break;
664 
665  case RB_SHAPE_CONE:
666  volume = (float)M_PI / 3.0f * radius * radius * height;
667  break;
668 
669  case RB_SHAPE_CONVEXH:
670  case RB_SHAPE_TRIMESH: {
671  if (ob->type == OB_MESH) {
672  Mesh *mesh = rigidbody_get_mesh(ob);
673  MVert *mvert;
674  const MLoopTri *lt = NULL;
675  int totvert, tottri = 0;
676  const MLoop *mloop = NULL;
677 
678  /* ensure mesh validity, then grab data */
679  if (mesh == NULL) {
680  return;
681  }
682 
683  mvert = mesh->mvert;
684  totvert = mesh->totvert;
686  tottri = mesh->runtime.looptris.len;
687  mloop = mesh->mloop;
688 
689  if (totvert > 0 && tottri > 0) {
690  BKE_mesh_calc_volume(mvert, totvert, lt, tottri, mloop, &volume, NULL);
691  const float volume_scale = mat4_to_volume_scale(ob->obmat);
692  volume *= fabsf(volume_scale);
693  }
694  }
695  else {
696  /* rough estimate from boundbox as fallback */
697  /* XXX could implement other types of geometry here (curves, etc.) */
698  volume = size[0] * size[1] * size[2];
699  }
700  break;
701  }
702  }
703 
704  /* return the volume calculated */
705  if (r_vol) {
706  *r_vol = volume;
707  }
708 }
709 
710 void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
711 {
712  RigidBodyOb *rbo = ob->rigidbody_object;
713 
714  float size[3] = {1.0f, 1.0f, 1.0f};
715  float height = 1.0f;
716 
717  zero_v3(r_center);
718 
719  /* if automatically determining dimensions, use the Object's boundbox
720  * - assume that all quadrics are standing upright on local z-axis
721  * - assume even distribution of mass around the Object's pivot
722  * (i.e. Object pivot is centralized in boundbox)
723  * - boundbox gives full width
724  */
725  /* XXX: all dimensions are auto-determined now... later can add stored settings for this. */
727 
728  /* Calculate volume as appropriate. */
729  switch (rbo->shape) {
730  case RB_SHAPE_BOX:
731  case RB_SHAPE_SPHERE:
732  case RB_SHAPE_CAPSULE:
733  case RB_SHAPE_CYLINDER:
734  break;
735 
736  case RB_SHAPE_CONE:
737  /* take radius as largest x/y dimension, and height as z-dimension */
738  height = size[2];
739  /* cone is geometrically centered on the median,
740  * center of mass is 1/4 up from the base
741  */
742  r_center[2] = -0.25f * height;
743  break;
744 
745  case RB_SHAPE_CONVEXH:
746  case RB_SHAPE_TRIMESH: {
747  if (ob->type == OB_MESH) {
748  Mesh *mesh = rigidbody_get_mesh(ob);
749  MVert *mvert;
750  const MLoopTri *looptri;
751  int totvert, tottri;
752  const MLoop *mloop;
753 
754  /* ensure mesh validity, then grab data */
755  if (mesh == NULL) {
756  return;
757  }
758 
759  mvert = mesh->mvert;
760  totvert = mesh->totvert;
762  tottri = mesh->runtime.looptris.len;
763  mloop = mesh->mloop;
764 
765  if (totvert > 0 && tottri > 0) {
766  BKE_mesh_calc_volume(mvert, totvert, looptri, tottri, mloop, NULL, r_center);
767  }
768  }
769  break;
770  }
771  }
772 }
773 
774 /* --------------------- */
775 
781 static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool rebuild)
782 {
783  RigidBodyOb *rbo = (ob) ? ob->rigidbody_object : NULL;
784  float loc[3];
785  float rot[4];
786 
787  /* sanity checks:
788  * - object doesn't have RigidBody info already: then why is it here?
789  */
790  if (rbo == NULL) {
791  return;
792  }
793 
794  /* make sure collision shape exists */
795  /* FIXME we shouldn't always have to rebuild collision shapes when rebuilding objects,
796  * but it's needed for constraints to update correctly. */
797  if (rbo->shared->physics_shape == NULL || rebuild) {
798  rigidbody_validate_sim_shape(rbw, ob, true);
799  }
800 
801  if (rbo->shared->physics_object && !rebuild) {
802  /* Don't remove body on rebuild as it has already been removed when deleting and rebuilding the
803  * world. */
805  }
806  if (!rbo->shared->physics_object || rebuild) {
807  /* remove rigid body if it already exists before creating a new one */
808  if (rbo->shared->physics_object) {
810  rbo->shared->physics_object = NULL;
811  }
812  /* Don't create rigid body object if the parent is a compound shape */
813  if (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
815  return;
816  }
817 
818  mat4_to_loc_quat(loc, rot, ob->obmat);
819 
821 
824 
830 
831  if (rbo->type == RBO_TYPE_PASSIVE || rbo->flag & RBO_FLAG_START_DEACTIVATED) {
833  }
834 
836  (ob->protectflag & OB_LOCK_LOCX) == 0,
837  (ob->protectflag & OB_LOCK_LOCY) == 0,
838  (ob->protectflag & OB_LOCK_LOCZ) == 0);
840  (ob->protectflag & OB_LOCK_ROTX) == 0,
841  (ob->protectflag & OB_LOCK_ROTY) == 0,
842  (ob->protectflag & OB_LOCK_ROTZ) == 0);
843 
846  rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
847  }
848 
849  if (rbw && rbw->shared->physics_world && rbo->shared->physics_object) {
851  }
852 }
853 
854 /* --------------------- */
855 
856 static void rigidbody_constraint_init_spring(RigidBodyCon *rbc,
857  void (*set_spring)(rbConstraint *, int, int),
858  void (*set_stiffness)(rbConstraint *, int, float),
859  void (*set_damping)(rbConstraint *, int, float))
860 {
862  set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_stiffness_x);
863  set_damping(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_damping_x);
864 
866  set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_stiffness_y);
867  set_damping(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_damping_y);
868 
870  set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z);
871  set_damping(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z);
872 
874  set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_stiffness_ang_x);
875  set_damping(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_damping_ang_x);
876 
878  set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_stiffness_ang_y);
879  set_damping(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_damping_ang_y);
880 
882  set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_stiffness_ang_z);
883  set_damping(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z);
884 }
885 
886 static void rigidbody_constraint_set_limits(RigidBodyCon *rbc,
887  void (*set_limits)(rbConstraint *, int, float, float))
888 {
889  if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X) {
890  set_limits(
892  }
893  else {
894  set_limits(rbc->physics_constraint, RB_LIMIT_LIN_X, 0.0f, -1.0f);
895  }
896 
897  if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Y) {
898  set_limits(
900  }
901  else {
902  set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Y, 0.0f, -1.0f);
903  }
904 
905  if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Z) {
906  set_limits(
908  }
909  else {
910  set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Z, 0.0f, -1.0f);
911  }
912 
913  if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_X) {
914  set_limits(
916  }
917  else {
918  set_limits(rbc->physics_constraint, RB_LIMIT_ANG_X, 0.0f, -1.0f);
919  }
920 
921  if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Y) {
922  set_limits(
924  }
925  else {
926  set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Y, 0.0f, -1.0f);
927  }
928 
929  if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Z) {
930  set_limits(
932  }
933  else {
934  set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Z, 0.0f, -1.0f);
935  }
936 }
937 
943 static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, bool rebuild)
944 {
945  RigidBodyCon *rbc = (ob) ? ob->rigidbody_constraint : NULL;
946  float loc[3];
947  float rot[4];
948  float lin_lower;
949  float lin_upper;
950  float ang_lower;
951  float ang_upper;
952 
953  /* sanity checks:
954  * - object should have a rigid body constraint
955  * - rigid body constraint should have at least one constrained object
956  */
957  if (rbc == NULL) {
958  return;
959  }
960 
961  if (ELEM(NULL, rbc->ob1, rbc->ob1->rigidbody_object, rbc->ob2, rbc->ob2->rigidbody_object)) {
962  if (rbc->physics_constraint) {
965  rbc->physics_constraint = NULL;
966  }
967  return;
968  }
969 
970  if (rbc->physics_constraint && rebuild == false) {
972  }
973  if (rbc->physics_constraint == NULL || rebuild) {
976 
977  /* remove constraint if it already exists before creating a new one */
978  if (rbc->physics_constraint) {
980  rbc->physics_constraint = NULL;
981  }
982 
983  mat4_to_loc_quat(loc, rot, ob->obmat);
984 
985  if (rb1 && rb2) {
986  switch (rbc->type) {
987  case RBC_TYPE_POINT:
988  rbc->physics_constraint = RB_constraint_new_point(loc, rb1, rb2);
989  break;
990  case RBC_TYPE_FIXED:
991  rbc->physics_constraint = RB_constraint_new_fixed(loc, rot, rb1, rb2);
992  break;
993  case RBC_TYPE_HINGE:
994  rbc->physics_constraint = RB_constraint_new_hinge(loc, rot, rb1, rb2);
995  if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Z) {
998  }
999  else {
1001  }
1002  break;
1003  case RBC_TYPE_SLIDER:
1004  rbc->physics_constraint = RB_constraint_new_slider(loc, rot, rb1, rb2);
1005  if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X) {
1008  }
1009  else {
1011  }
1012  break;
1013  case RBC_TYPE_PISTON:
1014  rbc->physics_constraint = RB_constraint_new_piston(loc, rot, rb1, rb2);
1015  if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X) {
1016  lin_lower = rbc->limit_lin_x_lower;
1017  lin_upper = rbc->limit_lin_x_upper;
1018  }
1019  else {
1020  lin_lower = 0.0f;
1021  lin_upper = -1.0f;
1022  }
1023  if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_X) {
1024  ang_lower = rbc->limit_ang_x_lower;
1025  ang_upper = rbc->limit_ang_x_upper;
1026  }
1027  else {
1028  ang_lower = 0.0f;
1029  ang_upper = -1.0f;
1030  }
1032  rbc->physics_constraint, lin_lower, lin_upper, ang_lower, ang_upper);
1033  break;
1034  case RBC_TYPE_6DOF_SPRING:
1035  if (rbc->spring_type == RBC_SPRING_TYPE2) {
1036  rbc->physics_constraint = RB_constraint_new_6dof_spring2(loc, rot, rb1, rb2);
1037 
1038  rigidbody_constraint_init_spring(rbc,
1042 
1044 
1045  rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof_spring2);
1046  }
1047  else {
1048  rbc->physics_constraint = RB_constraint_new_6dof_spring(loc, rot, rb1, rb2);
1049 
1050  rigidbody_constraint_init_spring(rbc,
1054 
1056 
1057  rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof);
1058  }
1059  break;
1060  case RBC_TYPE_6DOF:
1061  rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2);
1062 
1063  rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof);
1064  break;
1065  case RBC_TYPE_MOTOR:
1066  rbc->physics_constraint = RB_constraint_new_motor(loc, rot, rb1, rb2);
1067 
1070  rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
1076  break;
1077  }
1078  }
1079  else { /* can't create constraint without both rigid bodies */
1080  return;
1081  }
1082 
1083  /* When 'rbc->type' is unknown. */
1084  if (rbc->physics_constraint == NULL) {
1085  return;
1086  }
1087 
1089 
1090  if (rbc->flag & RBC_FLAG_USE_BREAKING) {
1092  }
1093  else {
1095  }
1096 
1099  }
1100  else {
1102  }
1103  }
1104 
1105  if (rbw && rbw->shared->physics_world && rbc->physics_constraint) {
1107  rbc->physics_constraint,
1109  }
1110 }
1111 
1112 /* --------------------- */
1113 
1115 {
1116  /* sanity checks */
1117  if (rbw == NULL) {
1118  return;
1119  }
1120 
1121  /* create new sim world */
1122  if (rebuild || rbw->shared->physics_world == NULL) {
1123  if (rbw->shared->physics_world) {
1125  }
1127  }
1128 
1131 }
1132 
1133 /* ************************************** */
1134 /* Setup Utilities - Create Settings Blocks */
1135 
1137 {
1138  /* try to get whatever RigidBody world that might be representing this already */
1139  RigidBodyWorld *rbw;
1140 
1141  /* sanity checks
1142  * - there must be a valid scene to add world to
1143  * - there mustn't be a sim world using this group already
1144  */
1145  if (scene == NULL) {
1146  return NULL;
1147  }
1148 
1149  /* create a new sim world */
1150  rbw = MEM_callocN(sizeof(RigidBodyWorld), "RigidBodyWorld");
1151  rbw->shared = MEM_callocN(sizeof(*rbw->shared), "RigidBodyWorld_Shared");
1152 
1153  /* set default settings */
1155 
1156  rbw->ltime = PSFRA;
1157 
1158  rbw->time_scale = 1.0f;
1159 
1160  /* Most high quality Bullet example files has an internal framerate of 240hz.
1161  * The blender default scene has a frame rate of 24, so take 10 substeps (24fps * 10).
1162  */
1163  rbw->substeps_per_frame = 10;
1164  rbw->num_solver_iterations = 10; /* 10 is bullet default */
1165 
1166  rbw->shared->pointcache = BKE_ptcache_add(&(rbw->shared->ptcaches));
1167  rbw->shared->pointcache->step = 1;
1168 
1169  /* return this sim world */
1170  return rbw;
1171 }
1172 
1174 {
1175  RigidBodyWorld *rbw_copy = MEM_dupallocN(rbw);
1176 
1177  if (rbw->effector_weights) {
1179  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
1180  id_us_plus((ID *)rbw->effector_weights->group);
1181  }
1182  }
1183  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
1184  id_us_plus((ID *)rbw_copy->group);
1185  id_us_plus((ID *)rbw_copy->constraints);
1186  }
1187 
1188  if ((flag & LIB_ID_COPY_SET_COPIED_ON_WRITE) == 0) {
1189  /* This is a regular copy, and not a CoW copy for depsgraph evaluation. */
1190  rbw_copy->shared = MEM_callocN(sizeof(*rbw_copy->shared), "RigidBodyWorld_Shared");
1192  rbw_copy->shared->pointcache = rbw_copy->shared->ptcaches.first;
1193  }
1194 
1195  rbw_copy->objects = NULL;
1196  rbw_copy->numbodies = 0;
1197  rigidbody_update_ob_array(rbw_copy);
1198 
1199  return rbw_copy;
1200 }
1201 
1203 {
1204  ID_NEW_REMAP(rbw->group);
1205  ID_NEW_REMAP(rbw->constraints);
1207 }
1208 
1209 void BKE_rigidbody_world_id_loop(RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata)
1210 {
1211  func(rbw, (ID **)&rbw->group, userdata, IDWALK_CB_USER);
1212  func(rbw, (ID **)&rbw->constraints, userdata, IDWALK_CB_USER);
1213  func(rbw, (ID **)&rbw->effector_weights->group, userdata, IDWALK_CB_USER);
1214 
1215  if (rbw->objects) {
1216  int i;
1217  for (i = 0; i < rbw->numbodies; i++) {
1218  func(rbw, (ID **)&rbw->objects[i], userdata, IDWALK_CB_NOP);
1219  }
1220  }
1221 }
1222 
1224 {
1225  RigidBodyOb *rbo;
1227 
1228  /* sanity checks
1229  * - rigidbody world must exist
1230  * - object must exist
1231  * - cannot add rigid body if it already exists
1232  */
1233  if (ob == NULL) {
1234  return NULL;
1235  }
1236  if (ob->rigidbody_object != NULL) {
1237  return ob->rigidbody_object;
1238  }
1239 
1240  /* create new settings data, and link it up */
1241  rbo = MEM_callocN(sizeof(RigidBodyOb), "RigidBodyOb");
1242  rbo->shared = MEM_callocN(sizeof(*rbo->shared), "RigidBodyOb_Shared");
1243 
1244  /* set default settings */
1245  rbo->type = type;
1246 
1247  rbo->mass = 1.0f;
1248 
1249  rbo->friction = 0.5f; /* best when non-zero. 0.5 is Bullet default */
1250  rbo->restitution = 0.0f; /* best when zero. 0.0 is Bullet default */
1251 
1252  rbo->margin = 0.04f; /* 0.04 (in meters) is Bullet default */
1253 
1254  rbo->lin_sleep_thresh = 0.4f; /* 0.4 is half of Bullet default */
1255  rbo->ang_sleep_thresh = 0.5f; /* 0.5 is half of Bullet default */
1256 
1257  rbo->lin_damping = 0.04f;
1258  rbo->ang_damping = 0.1f;
1259 
1260  rbo->col_groups = 1;
1261 
1262  /* use triangle meshes for passive objects
1263  * use convex hulls for active objects since dynamic triangle meshes are very unstable
1264  */
1265  if (type == RBO_TYPE_ACTIVE) {
1266  rbo->shape = RB_SHAPE_CONVEXH;
1267  }
1268  else {
1269  rbo->shape = RB_SHAPE_TRIMESH;
1270  }
1271 
1273 
1274  /* set initial transform */
1275  mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
1276 
1277  /* flag cache as outdated */
1280 
1281  /* return this object */
1282  return rbo;
1283 }
1284 
1286 {
1287  RigidBodyCon *rbc;
1289 
1290  /* sanity checks
1291  * - rigidbody world must exist
1292  * - object must exist
1293  * - cannot add constraint if it already exists
1294  */
1295  if (ob == NULL || (ob->rigidbody_constraint != NULL)) {
1296  return NULL;
1297  }
1298 
1299  /* create new settings data, and link it up */
1300  rbc = MEM_callocN(sizeof(RigidBodyCon), "RigidBodyCon");
1301 
1302  /* set default settings */
1303  rbc->type = type;
1304 
1305  rbc->ob1 = NULL;
1306  rbc->ob2 = NULL;
1307 
1308  rbc->flag |= RBC_FLAG_ENABLED;
1310  rbc->flag |= RBC_FLAG_NEEDS_VALIDATE;
1311 
1313 
1314  rbc->breaking_threshold = 10.0f; /* no good default here, just use 10 for now */
1315  rbc->num_solver_iterations = 10; /* 10 is Bullet default */
1316 
1317  rbc->limit_lin_x_lower = -1.0f;
1318  rbc->limit_lin_x_upper = 1.0f;
1319  rbc->limit_lin_y_lower = -1.0f;
1320  rbc->limit_lin_y_upper = 1.0f;
1321  rbc->limit_lin_z_lower = -1.0f;
1322  rbc->limit_lin_z_upper = 1.0f;
1323  rbc->limit_ang_x_lower = -M_PI_4;
1324  rbc->limit_ang_x_upper = M_PI_4;
1325  rbc->limit_ang_y_lower = -M_PI_4;
1326  rbc->limit_ang_y_upper = M_PI_4;
1327  rbc->limit_ang_z_lower = -M_PI_4;
1328  rbc->limit_ang_z_upper = M_PI_4;
1329 
1330  rbc->spring_damping_x = 0.5f;
1331  rbc->spring_damping_y = 0.5f;
1332  rbc->spring_damping_z = 0.5f;
1333  rbc->spring_damping_ang_x = 0.5f;
1334  rbc->spring_damping_ang_y = 0.5f;
1335  rbc->spring_damping_ang_z = 0.5f;
1336  rbc->spring_stiffness_x = 10.0f;
1337  rbc->spring_stiffness_y = 10.0f;
1338  rbc->spring_stiffness_z = 10.0f;
1339  rbc->spring_stiffness_ang_x = 10.0f;
1340  rbc->spring_stiffness_ang_y = 10.0f;
1341  rbc->spring_stiffness_ang_z = 10.0f;
1342 
1343  rbc->motor_lin_max_impulse = 1.0f;
1344  rbc->motor_lin_target_velocity = 1.0f;
1345  rbc->motor_ang_max_impulse = 1.0f;
1346  rbc->motor_ang_target_velocity = 1.0f;
1347 
1348  /* flag cache as outdated */
1350 
1351  /* return this object */
1352  return rbc;
1353 }
1354 
1356 {
1357  if (rbw->group != NULL) {
1359  if (object->type != OB_MESH || object->rigidbody_object != NULL) {
1360  continue;
1361  }
1362  object->rigidbody_object = BKE_rigidbody_create_object(scene, object, RBO_TYPE_ACTIVE);
1363  DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM);
1364  }
1366  DEG_relations_tag_update(bmain);
1367  }
1368 }
1369 
1371 {
1372  if (rbw->constraints != NULL) {
1374  if (object->rigidbody_constraint != NULL) {
1375  continue;
1376  }
1377  object->rigidbody_constraint = BKE_rigidbody_create_constraint(
1378  scene, object, RBC_TYPE_FIXED);
1379  }
1381  }
1382 }
1383 
1384 void BKE_rigidbody_main_collection_object_add(Main *bmain, Collection *collection, Object *object)
1385 {
1386  for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
1388 
1389  if (rbw == NULL) {
1390  continue;
1391  }
1392 
1393  if (rbw->group == collection && object->type == OB_MESH && object->rigidbody_object == NULL) {
1394  object->rigidbody_object = BKE_rigidbody_create_object(scene, object, RBO_TYPE_ACTIVE);
1395  }
1396  if (rbw->constraints == collection && object->rigidbody_constraint == NULL) {
1397  object->rigidbody_constraint = BKE_rigidbody_create_constraint(
1398  scene, object, RBC_TYPE_FIXED);
1399  }
1400  }
1401 }
1402 
1403 /* ************************************** */
1404 /* Utilities API */
1405 
1407 {
1408  /* sanity check */
1409  if (scene == NULL) {
1410  return NULL;
1411  }
1412 
1413  return scene->rigidbody_world;
1414 }
1415 
1416 static bool rigidbody_add_object_to_scene(Main *bmain, Scene *scene, Object *ob)
1417 {
1418  /* Add rigid body world and group if they don't exist for convenience */
1420  if (rbw == NULL) {
1422  if (rbw == NULL) {
1423  return false;
1424  }
1425 
1427  scene->rigidbody_world = rbw;
1428  }
1429 
1430  if (rbw->group == NULL) {
1431  rbw->group = BKE_collection_add(bmain, NULL, "RigidBodyWorld");
1432  id_us_plus(&rbw->group->id);
1433  }
1434 
1435  /* Add object to rigid body group. */
1436  BKE_collection_object_add(bmain, rbw->group, ob);
1438 
1439  DEG_relations_tag_update(bmain);
1441 
1442  return true;
1443 }
1444 
1445 static bool rigidbody_add_constraint_to_scene(Main *bmain, Scene *scene, Object *ob)
1446 {
1447  /* Add rigid body world and group if they don't exist for convenience */
1449  if (rbw == NULL) {
1451  if (rbw == NULL) {
1452  return false;
1453  }
1454 
1456  scene->rigidbody_world = rbw;
1457  }
1458 
1459  if (rbw->constraints == NULL) {
1460  rbw->constraints = BKE_collection_add(bmain, NULL, "RigidBodyConstraints");
1461  id_us_plus(&rbw->constraints->id);
1462  }
1463 
1464  /* Add object to rigid body group. */
1465  BKE_collection_object_add(bmain, rbw->constraints, ob);
1467 
1468  DEG_relations_tag_update(bmain);
1470 
1471  return true;
1472 }
1473 
1475 {
1476  if (ob->rigidbody_object != NULL) {
1477  /* Add newly local object to scene. */
1478  for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
1479  if (BKE_scene_object_find(scene, ob)) {
1480  rigidbody_add_object_to_scene(bmain, scene, ob);
1481  }
1482  }
1483  }
1484  if (ob->rigidbody_constraint != NULL) {
1485  /* Add newly local object to scene. */
1486  for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
1487  if (BKE_scene_object_find(scene, ob)) {
1488  rigidbody_add_constraint_to_scene(bmain, scene, ob);
1489  }
1490  }
1491  }
1492 }
1493 
1494 bool BKE_rigidbody_add_object(Main *bmain, Scene *scene, Object *ob, int type, ReportList *reports)
1495 {
1496  if (ob->type != OB_MESH) {
1497  BKE_report(reports, RPT_ERROR, "Can't add Rigid Body to non mesh object");
1498  return false;
1499  }
1500 
1501  /* Add object to rigid body world in scene. */
1502  if (!rigidbody_add_object_to_scene(bmain, scene, ob)) {
1503  BKE_report(reports, RPT_ERROR, "Can't create Rigid Body world");
1504  return false;
1505  }
1506 
1507  /* make rigidbody object settings */
1508  if (ob->rigidbody_object == NULL) {
1510  }
1511  ob->rigidbody_object->type = type;
1513 
1514  DEG_relations_tag_update(bmain);
1516 
1517  return true;
1518 }
1519 
1520 void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob, const bool free_us)
1521 {
1523  RigidBodyCon *rbc;
1524  int i;
1525 
1526  if (rbw) {
1527 
1528  /* remove object from array */
1529  if (rbw->objects) {
1530  for (i = 0; i < rbw->numbodies; i++) {
1531  if (rbw->objects[i] == ob) {
1532  rbw->objects[i] = NULL;
1533  break;
1534  }
1535  }
1536  }
1537 
1538  /* remove object from rigid body constraints */
1539  if (rbw->constraints) {
1541  if (obt && obt->rigidbody_constraint) {
1542  rbc = obt->rigidbody_constraint;
1543  if (rbc->ob1 == ob) {
1544  rbc->ob1 = NULL;
1546  }
1547  if (rbc->ob2 == ob) {
1548  rbc->ob2 = NULL;
1550  }
1551  }
1552  }
1554  }
1555 
1556  /* Relying on usercount of the object should be OK, and it is much cheaper than looping in all
1557  * collections to check whether the object is already in another one... */
1558  if (ID_REAL_USERS(&ob->id) == 1) {
1559  /* Some users seems to find it funny to use a view-layer instancing collection
1560  * as RBW collection... Despite this being a bad (ab)use of the system, avoid losing objects
1561  * when we remove them from RB simulation. */
1563  }
1564  BKE_collection_object_remove(bmain, rbw->group, ob, free_us);
1565 
1566  /* flag cache as outdated */
1568  /* Reset cache as the object order probably changed after freeing the object. */
1569  PTCacheID pid;
1570  BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
1572  }
1573 
1574  /* remove object's settings */
1575  BKE_rigidbody_free_object(ob, rbw);
1576 
1577  /* Dependency graph update */
1578  DEG_relations_tag_update(bmain);
1580 }
1581 
1582 void BKE_rigidbody_remove_constraint(Main *bmain, Scene *scene, Object *ob, const bool free_us)
1583 {
1586 
1587  if (rbw != NULL) {
1588  /* Remove from RBW constraints collection. */
1589  if (rbw->constraints != NULL) {
1590  BKE_collection_object_remove(bmain, rbw->constraints, ob, free_us);
1592  }
1593 
1594  /* remove from rigidbody world, free object won't do this */
1595  if (rbw->shared->physics_world && rbc->physics_constraint) {
1597  }
1598  }
1599 
1600  /* remove object's settings */
1602 
1603  /* flag cache as outdated */
1605 }
1606 
1607 /* ************************************** */
1608 /* Simulation Interface - Bullet */
1609 
1610 /* Update object array and rigid body count so they're in sync with the rigid body group */
1611 static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
1612 {
1613  if (rbw->group == NULL) {
1614  rbw->numbodies = 0;
1615  rbw->objects = realloc(rbw->objects, 0);
1616  return;
1617  }
1618 
1619  int n = 0;
1621  (void)object;
1622  /* Ignore if this object is the direct child of an object with a compound shape */
1623  if (object->parent == NULL || object->parent->rigidbody_object == NULL ||
1625  n++;
1626  }
1627  }
1629 
1630  if (rbw->numbodies != n) {
1631  rbw->numbodies = n;
1632  rbw->objects = realloc(rbw->objects, sizeof(Object *) * rbw->numbodies);
1633  }
1634 
1635  int i = 0;
1637  /* Ignore if this object is the direct child of an object with a compound shape */
1638  if (object->parent == NULL || object->parent->rigidbody_object == NULL ||
1640  rbw->objects[i] = object;
1641  i++;
1642  }
1643  }
1645 }
1646 
1647 static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw)
1648 {
1649  float adj_gravity[3];
1650 
1651  /* adjust gravity to take effector weights into account */
1653  copy_v3_v3(adj_gravity, scene->physics_settings.gravity);
1654  mul_v3_fl(adj_gravity,
1656  }
1657  else {
1658  zero_v3(adj_gravity);
1659  }
1660 
1661  /* update gravity, since this RNA setting is not part of RigidBody settings */
1662  RB_dworld_set_gravity(rbw->shared->physics_world, adj_gravity);
1663 
1664  /* update object array in case there are changes */
1665  rigidbody_update_ob_array(rbw);
1666 }
1667 
1668 static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Object *ob, RigidBodyOb *rbo)
1669 {
1670  /* only update if rigid body exists */
1671  if (rbo->shared->physics_object == NULL) {
1672  return;
1673  }
1674 
1676  Base *base = BKE_view_layer_base_find(view_layer, ob);
1677  const bool is_selected = base ? (base->flag & BASE_SELECTED) != 0 : false;
1678 
1679  if (rbo->shape == RB_SHAPE_TRIMESH && rbo->flag & RBO_FLAG_USE_DEFORM) {
1681  if (mesh) {
1682  MVert *mvert = mesh->mvert;
1683  int totvert = mesh->totvert;
1684  const BoundBox *bb = BKE_object_boundbox_get(ob);
1685 
1687  (float *)mvert,
1688  totvert,
1689  sizeof(MVert),
1690  bb->vec[0],
1691  bb->vec[6]);
1692  }
1693  }
1694 
1695  if (!(rbo->flag & RBO_FLAG_KINEMATIC)) {
1696  /* update scale for all non kinematic objects */
1697  float new_scale[3], old_scale[3];
1698  mat4_to_size(new_scale, ob->obmat);
1699  RB_body_get_scale(rbo->shared->physics_object, old_scale);
1700 
1701  /* Avoid updating collision shape AABBs if scale didn't change. */
1702  if (!compare_size_v3v3(old_scale, new_scale, 0.001f)) {
1703  RB_body_set_scale(rbo->shared->physics_object, new_scale);
1704  /* compensate for embedded convex hull collision margin */
1705  if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && rbo->shape == RB_SHAPE_CONVEXH) {
1707  RBO_GET_MARGIN(rbo) * MIN3(new_scale[0], new_scale[1], new_scale[2]));
1708  }
1709  }
1710  }
1711 
1712  /* Make transformed objects temporarily kinmatic
1713  * so that they can be moved by the user during simulation. */
1714  if (is_selected && (G.moving & G_TRANSFORM_OBJ)) {
1716  RB_body_set_mass(rbo->shared->physics_object, 0.0f);
1717  }
1718 
1719  /* NOTE: no other settings need to be explicitly updated here,
1720  * since RNA setters take care of the rest :)
1721  */
1722 }
1723 
1729 static void rigidbody_update_simulation(Depsgraph *depsgraph,
1730  Scene *scene,
1731  RigidBodyWorld *rbw,
1732  bool rebuild)
1733 {
1734  /* update world */
1735  /* Note physics_world can get NULL when undoing the deletion of the last object in it (see
1736  * T70667). */
1737  if (rebuild || rbw->shared->physics_world == NULL) {
1738  BKE_rigidbody_validate_sim_world(scene, rbw, rebuild);
1739  /* We have rebuilt the world so we need to make sure the rest is rebuilt as well. */
1740  rebuild = true;
1741  }
1742 
1743  rigidbody_update_sim_world(scene, rbw);
1744 
1745  /* XXX TODO: For rebuild: remove all constraints first.
1746  * Otherwise we can end up deleting objects that are still
1747  * referenced by constraints, corrupting bullet's internal list.
1748  *
1749  * Memory management needs redesign here, this is just a dirty workaround.
1750  */
1751  if (rebuild && rbw->constraints) {
1754  if (rbc && rbc->physics_constraint) {
1757  rbc->physics_constraint = NULL;
1758  }
1759  }
1761  }
1762 
1763  /* update objects */
1765  if (ob->type == OB_MESH) {
1766  /* validate that we've got valid object set up here... */
1767  RigidBodyOb *rbo = ob->rigidbody_object;
1768 
1769  /* TODO: remove this whole block once we are sure we never get NULL rbo here anymore. */
1770  /* This cannot be done in CoW evaluation context anymore... */
1771  if (rbo == NULL) {
1772  BLI_assert_msg(0,
1773  "CoW object part of RBW object collection without RB object data, "
1774  "should not happen.\n");
1775  /* Since this object is included in the sim group but doesn't have
1776  * rigid body settings (perhaps it was added manually), add!
1777  * - assume object to be active? That is the default for newly added settings...
1778  */
1780  rigidbody_validate_sim_object(rbw, ob, true);
1781 
1782  rbo = ob->rigidbody_object;
1783  }
1784  else {
1785  /* perform simulation data updates as tagged */
1786  /* refresh object... */
1787  if (rebuild) {
1788  /* World has been rebuilt so rebuild object */
1789  /* TODO(Sybren): rigidbody_validate_sim_object() can call rigidbody_validate_sim_shape(),
1790  * but neither resets the RBO_FLAG_NEEDS_RESHAPE flag nor
1791  * calls RB_body_set_collision_shape().
1792  * This results in the collision shape being created twice, which is unnecessary. */
1793  rigidbody_validate_sim_object(rbw, ob, true);
1794  }
1795  else if (rbo->flag & RBO_FLAG_NEEDS_VALIDATE) {
1796  rigidbody_validate_sim_object(rbw, ob, false);
1797  }
1798  /* refresh shape... */
1799  if (rbo->flag & RBO_FLAG_NEEDS_RESHAPE) {
1800  /* mesh/shape data changed, so force shape refresh */
1801  rigidbody_validate_sim_shape(rbw, ob, true);
1802  /* now tell RB sim about it */
1803  /* XXX: we assume that this can only get applied for active/passive shapes
1804  * that will be included as rigidbodies. */
1805  if (rbo->shared->physics_object != NULL && rbo->shared->physics_shape != NULL) {
1807  }
1808  }
1809  }
1811 
1812  /* update simulation object... */
1813  rigidbody_update_sim_ob(depsgraph, ob, rbo);
1814  }
1815  }
1817 
1818  /* update constraints */
1819  if (rbw->constraints == NULL) { /* no constraints, move on */
1820  return;
1821  }
1822 
1824  /* validate that we've got valid object set up here... */
1826 
1827  /* TODO: remove this whole block once we are sure we never get NULL rbo here anymore. */
1828  /* This cannot be done in CoW evaluation context anymore... */
1829  if (rbc == NULL) {
1830  BLI_assert_msg(0,
1831  "CoW object part of RBW constraints collection without RB constraint data, "
1832  "should not happen.\n");
1833  /* Since this object is included in the group but doesn't have
1834  * constraint settings (perhaps it was added manually), add!
1835  */
1837  rigidbody_validate_sim_constraint(rbw, ob, true);
1838 
1839  rbc = ob->rigidbody_constraint;
1840  }
1841  else {
1842  /* perform simulation data updates as tagged */
1843  if (rebuild) {
1844  /* World has been rebuilt so rebuild constraint */
1845  rigidbody_validate_sim_constraint(rbw, ob, true);
1846  }
1847  else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) {
1848  rigidbody_validate_sim_constraint(rbw, ob, false);
1849  }
1850  }
1851  rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE;
1852  }
1854 }
1855 
1856 typedef struct KinematicSubstepData {
1857  RigidBodyOb *rbo;
1858  float old_pos[3];
1859  float new_pos[3];
1860  float old_rot[4];
1861  float new_rot[4];
1862  bool scale_changed;
1863  float old_scale[3];
1864  float new_scale[3];
1865 } KinematicSubstepData;
1866 
1867 static ListBase rigidbody_create_substep_data(RigidBodyWorld *rbw)
1868 {
1869  /* Objects that we want to update substep location/rotation for. */
1870  ListBase substep_targets = {NULL, NULL};
1871 
1873  RigidBodyOb *rbo = ob->rigidbody_object;
1874  /* only update if rigid body exists */
1875  if (!rbo || rbo->shared->physics_object == NULL) {
1876  continue;
1877  }
1878 
1879  if (rbo->flag & RBO_FLAG_KINEMATIC) {
1880  float loc[3], rot[4], scale[3];
1881 
1882  KinematicSubstepData *data = MEM_callocN(sizeof(KinematicSubstepData),
1883  "RigidBody Substep data");
1884 
1885  data->rbo = rbo;
1886 
1889  RB_body_get_scale(rbo->shared->physics_object, scale);
1890 
1891  copy_v3_v3(data->old_pos, loc);
1892  copy_v4_v4(data->old_rot, rot);
1893  copy_v3_v3(data->old_scale, scale);
1894 
1895  mat4_decompose(loc, rot, scale, ob->obmat);
1896 
1897  copy_v3_v3(data->new_pos, loc);
1898  copy_v4_v4(data->new_rot, rot);
1899  copy_v3_v3(data->new_scale, scale);
1900 
1901  data->scale_changed = !compare_size_v3v3(data->old_scale, data->new_scale, 0.001f);
1902 
1903  LinkData *ob_link = BLI_genericNodeN(data);
1904  BLI_addtail(&substep_targets, ob_link);
1905  }
1906  }
1908 
1909  return substep_targets;
1910 }
1911 
1912 static void rigidbody_update_kinematic_obj_substep(ListBase *substep_targets, float interp_fac)
1913 {
1914  LISTBASE_FOREACH (LinkData *, link, substep_targets) {
1915  KinematicSubstepData *data = link->data;
1916  RigidBodyOb *rbo = data->rbo;
1917 
1918  float loc[3], rot[4];
1919 
1920  interp_v3_v3v3(loc, data->old_pos, data->new_pos, interp_fac);
1921  interp_qt_qtqt(rot, data->old_rot, data->new_rot, interp_fac);
1922 
1925 
1926  if (!data->scale_changed) {
1927  /* Avoid having to rebuild the collision shape AABBs if scale didn't change. */
1928  continue;
1929  }
1930 
1931  float scale[3];
1932 
1933  interp_v3_v3v3(scale, data->old_scale, data->new_scale, interp_fac);
1934 
1935  RB_body_set_scale(rbo->shared->physics_object, scale);
1936 
1937  /* compensate for embedded convex hull collision margin */
1938  if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && rbo->shape == RB_SHAPE_CONVEXH) {
1940  RBO_GET_MARGIN(rbo) * MIN3(scale[0], scale[1], scale[2]));
1941  }
1942  }
1943 }
1944 
1945 static void rigidbody_update_external_forces(Depsgraph *depsgraph,
1946  Scene *scene,
1947  RigidBodyWorld *rbw)
1948 {
1950  /* only update if rigid body exists */
1951  RigidBodyOb *rbo = ob->rigidbody_object;
1952  if (ob->type != OB_MESH || rbo->shared->physics_object == NULL) {
1953  continue;
1954  }
1955 
1956  /* update influence of effectors - but don't do it on an effector */
1957  /* only dynamic bodies need effector update */
1958  if (rbo->type == RBO_TYPE_ACTIVE &&
1959  ((ob->pd == NULL) || (ob->pd->forcefield == PFIELD_NULL))) {
1960  EffectorWeights *effector_weights = rbw->effector_weights;
1961  EffectedPoint epoint;
1962  ListBase *effectors;
1963 
1964  /* get effectors present in the group specified by effector_weights */
1965  effectors = BKE_effectors_create(depsgraph, ob, NULL, effector_weights, false);
1966  if (effectors) {
1967  float eff_force[3] = {0.0f, 0.0f, 0.0f};
1968  float eff_loc[3], eff_vel[3];
1969 
1970  /* create dummy 'point' which represents last known position of object as result of sim
1971  */
1972  /* XXX: this can create some inaccuracies with sim position,
1973  * but is probably better than using un-simulated values? */
1974  RB_body_get_position(rbo->shared->physics_object, eff_loc);
1976 
1977  pd_point_from_loc(scene, eff_loc, eff_vel, 0, &epoint);
1978 
1979  /* Calculate net force of effectors, and apply to sim object:
1980  * - we use 'central force' since apply force requires a "relative position"
1981  * which we don't have... */
1982  BKE_effectors_apply(effectors, NULL, effector_weights, &epoint, eff_force, NULL, NULL);
1983  if (G.f & G_DEBUG) {
1984  printf("\tapplying force (%f,%f,%f) to '%s'\n",
1985  eff_force[0],
1986  eff_force[1],
1987  eff_force[2],
1988  ob->id.name + 2);
1989  }
1990  /* activate object in case it is deactivated */
1991  if (!is_zero_v3(eff_force)) {
1993  }
1995  }
1996  else if (G.f & G_DEBUG) {
1997  printf("\tno forces to apply to '%s'\n", ob->id.name + 2);
1998  }
1999 
2000  /* cleanup */
2001  BKE_effectors_free(effectors);
2002  }
2003  /* NOTE: passive objects don't need to be updated since they don't move */
2004  }
2006 }
2007 
2008 static void rigidbody_free_substep_data(ListBase *substep_targets)
2009 {
2010  LISTBASE_FOREACH (LinkData *, link, substep_targets) {
2011  KinematicSubstepData *data = link->data;
2012  MEM_freeN(data);
2013  }
2014 
2015  BLI_freelistN(substep_targets);
2016 }
2017 static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBodyWorld *rbw)
2018 {
2020 
2022  Base *base = BKE_view_layer_base_find(view_layer, ob);
2023  RigidBodyOb *rbo = ob->rigidbody_object;
2024  /* Reset kinematic state for transformed objects. */
2025  if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ) &&
2026  rbo->shared->physics_object) {
2028  rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
2030  /* Deactivate passive objects so they don't interfere with deactivation of active objects. */
2031  if (rbo->type == RBO_TYPE_PASSIVE) {
2033  }
2034  }
2035  }
2037 }
2038 
2039 bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime)
2040 {
2041  return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0 && ctime > rbw->shared->pointcache->startframe);
2042 }
2043 
2044 void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
2045 {
2047  /* Don't sync transforms for objects that are not affected/changed by the simulation. */
2048  return;
2049  }
2050 
2051  RigidBodyOb *rbo = ob->rigidbody_object;
2052 
2053  /* use rigid body transform after cache start frame if objects is not being transformed */
2054  if (BKE_rigidbody_check_sim_running(rbw, ctime) &&
2055  !(ob->base_flag & BASE_SELECTED && G.moving & G_TRANSFORM_OBJ)) {
2056  float mat[4][4], size_mat[4][4], size[3];
2057 
2058  normalize_qt(rbo->orn); /* RB_TODO investigate why quaternion isn't normalized at this point */
2059  quat_to_mat4(mat, rbo->orn);
2060  copy_v3_v3(mat[3], rbo->pos);
2061 
2062  mat4_to_size(size, ob->obmat);
2063  size_to_mat4(size_mat, size);
2064  mul_m4_m4m4(mat, mat, size_mat);
2065 
2066  copy_m4_m4(ob->obmat, mat);
2067  }
2068  /* otherwise set rigid body transform to current obmat */
2069  else {
2070  mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
2071  }
2072 }
2073 
2075  Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
2076 {
2077  bool correct_delta = BKE_rigidbody_is_affected_by_simulation(ob);
2078  RigidBodyOb *rbo = ob->rigidbody_object;
2079 
2080  /* return rigid body and object to their initial states */
2081  copy_v3_v3(rbo->pos, ob->loc);
2082  copy_v3_v3(ob->loc, loc);
2083 
2084  if (correct_delta) {
2085  add_v3_v3(rbo->pos, ob->dloc);
2086  }
2087 
2088  if (ob->rotmode > 0) {
2089  float qt[4];
2090  eulO_to_quat(qt, ob->rot, ob->rotmode);
2091 
2092  if (correct_delta) {
2093  float dquat[4];
2094  eulO_to_quat(dquat, ob->drot, ob->rotmode);
2095 
2096  mul_qt_qtqt(rbo->orn, dquat, qt);
2097  }
2098  else {
2099  copy_qt_qt(rbo->orn, qt);
2100  }
2101 
2102  copy_v3_v3(ob->rot, rot);
2103  }
2104  else if (ob->rotmode == ROT_MODE_AXISANGLE) {
2105  float qt[4];
2106  axis_angle_to_quat(qt, ob->rotAxis, ob->rotAngle);
2107 
2108  if (correct_delta) {
2109  float dquat[4];
2110  axis_angle_to_quat(dquat, ob->drotAxis, ob->drotAngle);
2111 
2112  mul_qt_qtqt(rbo->orn, dquat, qt);
2113  }
2114  else {
2115  copy_qt_qt(rbo->orn, qt);
2116  }
2117 
2118  copy_v3_v3(ob->rotAxis, rotAxis);
2119  ob->rotAngle = rotAngle;
2120  }
2121  else {
2122  if (correct_delta) {
2123  mul_qt_qtqt(rbo->orn, ob->dquat, ob->quat);
2124  }
2125  else {
2126  copy_qt_qt(rbo->orn, ob->quat);
2127  }
2128 
2129  copy_qt_qt(ob->quat, quat);
2130  }
2131 
2132  if (rbo->shared->physics_object) {
2133  /* allow passive objects to return to original transform */
2134  if (rbo->type == RBO_TYPE_PASSIVE) {
2136  }
2137  RB_body_set_loc_rot(rbo->shared->physics_object, rbo->pos, rbo->orn);
2138  }
2139  /* RB_TODO update rigid body physics object's loc/rot for dynamic objects here as well
2140  * (needs to be done outside bullet's update loop). */
2141 }
2142 
2144 {
2145  if (rbw) {
2147  }
2148 }
2149 
2150 /* ------------------ */
2151 
2153 {
2155  PointCache *cache;
2156  PTCacheID pid;
2157  int startframe, endframe;
2158 
2159  BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
2160  BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
2161  cache = rbw->shared->pointcache;
2162 
2163  /* Flag cache as outdated if we don't have a world or number of objects
2164  * in the simulation has changed. */
2165  int n = 0;
2167  (void)object;
2168  /* Ignore if this object is the direct child of an object with a compound shape */
2169  if (object->parent == NULL || object->parent->rigidbody_object == NULL ||
2171  n++;
2172  }
2173  }
2175 
2176  if (rbw->shared->physics_world == NULL || rbw->numbodies != n) {
2177  cache->flag |= PTCACHE_OUTDATED;
2178  }
2179 
2180  if (ctime == startframe + 1 && rbw->ltime == startframe) {
2181  if (cache->flag & PTCACHE_OUTDATED) {
2183  rigidbody_update_simulation(depsgraph, scene, rbw, true);
2184  BKE_ptcache_validate(cache, (int)ctime);
2185  cache->last_exact = 0;
2186  cache->flag &= ~PTCACHE_REDO_NEEDED;
2187  }
2188  }
2189 }
2190 
2192 {
2194  PointCache *cache;
2195  PTCacheID pid;
2196  int startframe, endframe;
2197 
2198  BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
2199  BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
2200  cache = rbw->shared->pointcache;
2201 
2202  if (ctime <= startframe) {
2203  rbw->ltime = startframe;
2204  return;
2205  }
2206  /* make sure we don't go out of cache frame range */
2207  if (ctime > endframe) {
2208  ctime = endframe;
2209  }
2210 
2211  /* don't try to run the simulation if we don't have a world yet but allow reading baked cache */
2212  if (rbw->shared->physics_world == NULL && !(cache->flag & PTCACHE_BAKED)) {
2213  return;
2214  }
2215  if (rbw->objects == NULL) {
2216  rigidbody_update_ob_array(rbw);
2217  }
2218 
2219  /* try to read from cache */
2220  /* RB_TODO deal with interpolated, old and baked results */
2221  bool can_simulate = (ctime == rbw->ltime + 1) && !(cache->flag & PTCACHE_BAKED);
2222 
2223  if (BKE_ptcache_read(&pid, ctime, can_simulate) == PTCACHE_READ_EXACT) {
2224  BKE_ptcache_validate(cache, (int)ctime);
2225  rbw->ltime = ctime;
2226  return;
2227  }
2228 
2229  if (!DEG_is_active(depsgraph)) {
2230  /* When the depsgraph is inactive we should neither write to the cache
2231  * nor run the simulation. */
2232  return;
2233  }
2234 
2235  /* advance simulation, we can only step one frame forward */
2236  if (compare_ff_relative(ctime, rbw->ltime + 1, FLT_EPSILON, 64)) {
2237  /* write cache for first frame when on second frame */
2238  if (rbw->ltime == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) {
2239  BKE_ptcache_write(&pid, startframe);
2240  }
2241 
2242  const float frame_diff = ctime - rbw->ltime;
2243  /* calculate how much time elapsed since last step in seconds */
2244  const float timestep = 1.0f / (float)FPS * frame_diff * rbw->time_scale;
2245 
2246  const float substep = timestep / rbw->substeps_per_frame;
2247 
2248  ListBase kinematic_substep_targets = rigidbody_create_substep_data(rbw);
2249 
2250  const float interp_step = 1.0f / rbw->substeps_per_frame;
2251  float cur_interp_val = interp_step;
2252 
2253  /* update and validate simulation */
2254  rigidbody_update_simulation(depsgraph, scene, rbw, false);
2255 
2256  for (int i = 0; i < rbw->substeps_per_frame; i++) {
2257  rigidbody_update_external_forces(depsgraph, scene, rbw);
2258  rigidbody_update_kinematic_obj_substep(&kinematic_substep_targets, cur_interp_val);
2259  RB_dworld_step_simulation(rbw->shared->physics_world, substep, 0, substep);
2260  cur_interp_val += interp_step;
2261  }
2262  rigidbody_free_substep_data(&kinematic_substep_targets);
2263 
2264  rigidbody_update_simulation_post_step(depsgraph, rbw);
2265 
2266  /* write cache for current frame */
2267  BKE_ptcache_validate(cache, (int)ctime);
2268  BKE_ptcache_write(&pid, (unsigned int)ctime);
2269 
2270  rbw->ltime = ctime;
2271  }
2272 }
2273 /* ************************************** */
2274 
2275 #else /* WITH_BULLET */
2276 
2277 /* stubs */
2278 # if defined(__GNUC__) || defined(__clang__)
2279 # pragma GCC diagnostic push
2280 # pragma GCC diagnostic ignored "-Wunused-parameter"
2281 # endif
2282 
2283 void BKE_rigidbody_object_copy(Main *bmain, Object *ob_dst, const Object *ob_src, const int flag)
2284 {
2285 }
2287 {
2288 }
2289 
2290 void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
2291 {
2292  if (r_vol) {
2293  *r_vol = 0.0f;
2294  }
2295 }
2296 void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
2297 {
2298  zero_v3(r_center);
2299 }
2301 {
2302  return NULL;
2303 }
2305 {
2306  return NULL;
2307 }
2309 {
2310 }
2312  RigidbodyWorldIDFunc func,
2313  void *userdata)
2314 {
2315 }
2317 {
2318  return NULL;
2319 }
2321 {
2322  return NULL;
2323 }
2325 {
2326  return NULL;
2327 }
2328 
2330 {
2331 }
2332 
2333 bool BKE_rigidbody_add_object(Main *bmain, Scene *scene, Object *ob, int type, ReportList *reports)
2334 {
2335  BKE_report(reports, RPT_ERROR, "Compiled without Bullet physics engine");
2336  return false;
2337 }
2338 
2339 void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob, const bool free_us)
2340 {
2341 }
2342 void BKE_rigidbody_remove_constraint(Main *bmain, Scene *scene, Object *ob, const bool free_us)
2343 {
2344 }
2346 {
2347 }
2349  Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
2350 {
2351 }
2353 {
2354  return false;
2355 }
2357 {
2358 }
2360 {
2361 }
2363 {
2364 }
2366 {
2367 }
2369 {
2370 }
2372 {
2373 }
2374 
2375 # if defined(__GNUC__) || defined(__clang__)
2376 # pragma GCC diagnostic pop
2377 # endif
2378 
2379 #endif /* WITH_BULLET */
2380 
2381 /* -------------------- */
2382 /* Depsgraph evaluation */
2383 
2385 {
2386  float ctime = DEG_get_ctime(depsgraph);
2387  DEG_debug_print_eval_time(depsgraph, __func__, scene->id.name, scene, ctime);
2388  /* rebuild sim data (i.e. after resetting to start of timeline) */
2391  }
2392 }
2393 
2395 {
2396  float ctime = DEG_get_ctime(depsgraph);
2397  DEG_debug_print_eval_time(depsgraph, __func__, scene->id.name, scene, ctime);
2398 
2399  /* evaluate rigidbody sim */
2401  return;
2402  }
2404 }
2405 
2407 {
2409  float ctime = DEG_get_ctime(depsgraph);
2410  DEG_debug_print_eval_time(depsgraph, __func__, ob->id.name, ob, ctime);
2411  /* read values pushed into RBO from sim/cache... */
2412  BKE_rigidbody_sync_transforms(rbw, ob, ctime);
2413 }
typedef float(TangentPoint)[2]
struct Collection * BKE_collection_add(struct Main *bmain, struct Collection *parent, const char *name)
Definition: collection.c:425
#define FOREACH_COLLECTION_OBJECT_RECURSIVE_END
bool BKE_collection_object_add(struct Main *bmain, struct Collection *collection, struct Object *ob)
Definition: collection.c:1125
bool BKE_collection_has_object(struct Collection *collection, const struct Object *ob)
bool BKE_collection_object_remove(struct Main *bmain, struct Collection *collection, struct Object *object, bool free_us)
Definition: collection.c:1170
#define FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(_collection, _object)
void BKE_effectors_free(struct ListBase *lb)
Definition: effect.c:369
void BKE_effectors_apply(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *wind_force, float *impulse)
Definition: effect.c:1114
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
Definition: effect.c:58
void pd_point_from_loc(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point)
Definition: effect.c:419
struct ListBase * BKE_effectors_create(struct Depsgraph *depsgraph, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights, bool use_rotation)
Definition: effect.c:314
#define G_MAIN
Definition: BKE_global.h:267
@ G_DEBUG
Definition: BKE_global.h:174
@ G_TRANSFORM_OBJ
Definition: BKE_global.h:247
struct Base * BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob)
Definition: layer.c:379
@ LIB_ID_COPY_CACHES
Definition: BKE_lib_id.h:152
@ LIB_ID_COPY_SET_COPIED_ON_WRITE
Definition: BKE_lib_id.h:143
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:126
@ LIB_ID_CREATE_NO_MAIN
Definition: BKE_lib_id.h:122
@ LIB_ID_CREATE_NO_DEG_TAG
Definition: BKE_lib_id.h:133
@ LIB_ID_COPY_RIGID_BODY_NO_COLLECTION_HANDLING
Definition: BKE_lib_id.h:177
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:33
void BKE_mesh_calc_volume(const struct MVert *mverts, int mverts_num, const struct MLoopTri *mlooptri, int looptri_num, const struct MLoop *mloop, float *r_volume, float r_center[3])
const struct MLoopTri * BKE_mesh_runtime_looptri_ensure(const struct Mesh *mesh)
General operations, lookup, etc. for blender objects.
void BKE_object_dimensions_get(struct Object *ob, float r_vec[3])
Definition: object.cc:3786
struct Mesh * BKE_object_get_evaluated_mesh(const struct Object *object)
const struct BoundBox * BKE_object_boundbox_get(struct Object *ob)
Definition: object.cc:3684
void BKE_object_matrix_local_get(struct Object *ob, float r_mat[4][4])
Definition: object.cc:3093
void BKE_ptcache_id_time(PTCacheID *pid, struct Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
Definition: pointcache.c:2773
void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, struct Object *ob, struct RigidBodyWorld *rbw)
Definition: pointcache.c:1054
struct PointCache * BKE_ptcache_copy_list(struct ListBase *ptcaches_new, const struct ListBase *ptcaches_old, int flag)
void BKE_ptcache_validate(struct PointCache *cache, int framenr)
Definition: pointcache.c:3789
int BKE_ptcache_id_reset(struct Scene *scene, PTCacheID *id, int mode)
Definition: pointcache.c:2870
struct PointCache * BKE_ptcache_add(struct ListBase *ptcaches)
Definition: pointcache.c:3014
int BKE_ptcache_read(PTCacheID *pid, float cfra, bool no_extrapolate_old)
Definition: pointcache.c:2280
int BKE_ptcache_write(PTCacheID *pid, unsigned int cfra)
Definition: pointcache.c:2540
void BKE_ptcache_free_list(struct ListBase *ptcaches)
Definition: pointcache.c:3052
#define PTCACHE_RESET_OUTDATED
#define PTCACHE_READ_EXACT
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
API for Blender-side Rigid Body stuff.
#define RBO_GET_MASS(rbo)
#define RBO_GET_MARGIN(rbo)
void(* RigidbodyWorldIDFunc)(struct RigidBodyWorld *rbw, struct ID **idpoin, void *userdata, int cb_flag)
Definition: BKE_rigidbody.h:58
bool BKE_scene_check_rigidbody_active(const struct Scene *scene)
bool BKE_scene_object_find(struct Scene *scene, struct Object *ob)
Definition: scene.cc:2053
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:102
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
struct LinkData * BLI_genericNodeN(void *data)
Definition: listbase.c:842
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
MINLINE float max_fff(float a, float b, float c)
#define M_PI
Definition: BLI_math_base.h:20
#define M_PI_4
Definition: BLI_math_base.h:26
MINLINE int compare_ff_relative(float a, float b, float max_diff, int max_ulps)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat[4][4])
Definition: math_matrix.c:2253
void size_to_mat4(float R[4][4], const float size[3])
Definition: math_matrix.c:2111
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
void mat4_to_loc_quat(float loc[3], float quat[4], const float wmat[4][4])
Definition: math_matrix.c:2235
void mat4_to_size(float size[3], const float M[4][4])
Definition: math_matrix.c:2138
float mat4_to_volume_scale(const float M[4][4])
Definition: math_matrix.c:2171
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t)
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
float normalize_qt(float q[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
Definition: math_rotation.c:46
void eulO_to_quat(float quat[4], const float eul[3], short order)
void copy_qt_qt(float q[4], const float a[4])
Definition: math_rotation.c:33
void quat_to_mat4(float mat[4][4], const float q[4])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
Definition: math_vector.c:29
MINLINE bool compare_size_v3v3(const float a[3], const float b[3], float limit) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
#define MAX3(a, b, c)
#define MIN3(a, b, c)
#define UNUSED(x)
#define UNPACK3(a)
#define MAX2(a, b)
#define ELEM(...)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:190
#define CLOG_WARN(clg_ref,...)
Definition: CLG_log.h:189
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
bool DEG_is_active(const struct Depsgraph *depsgraph)
Definition: depsgraph.cc:312
void DEG_debug_print_eval_time(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address, float time)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
float DEG_get_ctime(const Depsgraph *graph)
struct ViewLayer * DEG_get_input_view_layer(const Depsgraph *graph)
ID and Library types, which are fundamental for sdna.
#define ID_NEW_REMAP(a)
Definition: DNA_ID.h:621
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:771
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ LIB_TAG_COPIED_ON_WRITE
Definition: DNA_ID.h:720
#define ID_REAL_USERS(id)
Definition: DNA_ID.h:553
@ ROT_MODE_AXISANGLE
Object groups, one object can be in many groups at once.
@ BASE_SELECTED
Object is a sort of wrapper for general info.
@ OB_MESH
@ OB_LOCK_ROTZ
@ OB_LOCK_ROTX
@ OB_LOCK_LOCY
@ OB_LOCK_LOCZ
@ OB_LOCK_ROTY
@ OB_LOCK_LOCX
@ PTCACHE_BAKED
@ PTCACHE_OUTDATED
@ PTCACHE_REDO_NEEDED
Types and defines for representing Rigid Body entities.
@ RBO_TYPE_ACTIVE
@ RBO_TYPE_PASSIVE
@ RBW_FLAG_MUTED
@ RBW_FLAG_USE_SPLIT_IMPULSE
@ RBO_MESH_DEFORM
@ RBO_MESH_FINAL
@ RBO_MESH_BASE
@ RBC_TYPE_POINT
@ RBC_TYPE_HINGE
@ RBC_TYPE_FIXED
@ RBC_TYPE_SLIDER
@ RBC_TYPE_MOTOR
@ RBC_TYPE_6DOF_SPRING
@ RBC_TYPE_PISTON
@ RBC_TYPE_6DOF
@ RBO_FLAG_USE_MARGIN
@ RBO_FLAG_START_DEACTIVATED
@ RBO_FLAG_KINEMATIC
@ RBO_FLAG_USE_DEFORM
@ RBO_FLAG_NEEDS_VALIDATE
@ RBO_FLAG_USE_DEACTIVATION
@ RBO_FLAG_NEEDS_RESHAPE
@ RBO_FLAG_DISABLED
@ RBC_FLAG_NEEDS_VALIDATE
@ RBC_FLAG_USE_MOTOR_ANG
@ RBC_FLAG_USE_SPRING_Y
@ RBC_FLAG_USE_SPRING_ANG_Y
@ RBC_FLAG_USE_SPRING_ANG_X
@ RBC_FLAG_USE_LIMIT_ANG_X
@ RBC_FLAG_USE_LIMIT_LIN_Y
@ RBC_FLAG_USE_LIMIT_ANG_Y
@ RBC_FLAG_USE_MOTOR_LIN
@ RBC_FLAG_DISABLE_COLLISIONS
@ RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS
@ RBC_FLAG_USE_BREAKING
@ RBC_FLAG_ENABLED
@ RBC_FLAG_USE_SPRING_Z
@ RBC_FLAG_USE_LIMIT_LIN_X
@ RBC_FLAG_USE_SPRING_ANG_Z
@ RBC_FLAG_USE_SPRING_X
@ RBC_FLAG_USE_LIMIT_LIN_Z
@ RBC_FLAG_USE_LIMIT_ANG_Z
@ RB_SHAPE_CAPSULE
@ RB_SHAPE_CONVEXH
@ RB_SHAPE_COMPOUND
@ RB_SHAPE_BOX
@ RB_SHAPE_TRIMESH
@ RB_SHAPE_SPHERE
@ RB_SHAPE_CYLINDER
@ RB_SHAPE_CONE
@ RBC_SPRING_TYPE2
#define PSFRA
#define PHYS_GLOBAL_GRAVITY
#define FPS
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
Rigid Body API for interfacing with external Physics Engines.
#define RB_LIMIT_LIN_Y
Definition: RBI_api.h:310
#define RB_LIMIT_LIN_X
Definition: RBI_api.h:309
#define RB_LIMIT_LIN_Z
Definition: RBI_api.h:311
#define RB_LIMIT_ANG_X
Definition: RBI_api.h:312
#define RB_LIMIT_ANG_Z
Definition: RBI_api.h:314
#define RB_LIMIT_ANG_Y
Definition: RBI_api.h:313
struct rbConstraint rbConstraint
Definition: RBI_api.h:43
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Scene scene
World world
const Depsgraph * depsgraph
SyclQueue void void size_t num_bytes void
#define rot(x, k)
#define LOG(severity)
Definition: log.h:36
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define G(x, y, z)
#define fabsf(x)
Definition: metal/compat.h:219
void RB_constraint_set_max_impulse_motor(rbConstraint *con, float max_impulse_lin, float max_impulse_ang)
rbConstraint * RB_constraint_new_point(float pivot[3], rbRigidBody *rb1, rbRigidBody *rb2)
void RB_dworld_set_solver_iterations(rbDynamicsWorld *world, int num_solver_iterations)
void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *object, int col_groups)
void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse)
rbCollisionShape * RB_shape_new_convex_hull(float *verts, int stride, int count, float margin, bool *can_embed)
rbCollisionShape * RB_shape_new_cone(float radius, float height)
rbCollisionShape * RB_shape_new_compound()
void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness)
void RB_body_set_restitution(rbRigidBody *object, float value)
void RB_body_set_friction(rbRigidBody *object, float value)
void RB_body_set_mass(rbRigidBody *object, float value)
void RB_body_set_activation_state(rbRigidBody *object, int use_deactivation)
rbCollisionShape * RB_shape_new_box(float x, float y, float z)
void RB_shape_trimesh_update(rbCollisionShape *shape, float *vertices, int num_verts, int vert_stride, const float min[3], const float max[3])
void RB_dworld_add_constraint(rbDynamicsWorld *world, rbConstraint *con, int disable_collisions)
void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping)
rbConstraint * RB_constraint_new_motor(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
rbConstraint * RB_constraint_new_piston(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
void RB_body_get_linear_velocity(rbRigidBody *object, float v_out[3])
void RB_constraint_set_enabled(rbConstraint *con, int enabled)
rbConstraint * RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
void RB_constraint_set_stiffness_6dof_spring2(rbConstraint *con, int axis, float stiffness)
void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con)
void RB_body_apply_central_force(rbRigidBody *object, const float v_in[3])
void RB_constraint_set_limits_slider(rbConstraint *con, float lower, float upper)
rbCollisionShape * RB_shape_new_sphere(float radius)
void RB_constraint_set_breaking_threshold(rbConstraint *con, float threshold)
rbConstraint * RB_constraint_new_hinge(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
rbConstraint * RB_constraint_new_fixed(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
rbDynamicsWorld * RB_dworld_new(const float gravity[3])
void RB_constraint_set_enable_motor(rbConstraint *con, int enable_lin, int enable_ang)
void RB_body_get_orientation(rbRigidBody *object, float v_out[4])
void RB_dworld_set_gravity(rbDynamicsWorld *world, const float g_in[3])
void RB_compound_add_child_shape(rbCollisionShape *parentShape, rbCollisionShape *shape, const float loc[3], const float rot[4])
rbCollisionShape * RB_shape_new_gimpact_mesh(rbMeshData *mesh)
void RB_trimesh_add_triangle_indices(rbMeshData *mesh, int num, int index0, int index1, int index2)
void RB_trimesh_add_vertices(rbMeshData *mesh, float *vertices, int num_verts, int vert_stride)
void RB_constraint_set_limits_6dof_spring2(rbConstraint *con, int axis, float lower, float upper)
void RB_constraint_set_solver_iterations(rbConstraint *con, int num_solver_iterations)
void RB_constraint_set_damping_6dof_spring2(rbConstraint *con, int axis, float damping)
void RB_body_set_collision_shape(rbRigidBody *object, rbCollisionShape *shape)
void RB_body_set_scale(rbRigidBody *object, const float scale[3])
void RB_body_set_damping(rbRigidBody *object, float linear, float angular)
void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable)
void RB_shape_set_margin(rbCollisionShape *shape, float value)
void RB_body_deactivate(rbRigidBody *object)
rbRigidBody * RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4])
void RB_body_set_kinematic_state(rbRigidBody *object, int kinematic)
void RB_trimesh_finish(rbMeshData *mesh)
void RB_body_get_position(rbRigidBody *object, float v_out[3])
rbCollisionShape * RB_shape_new_cylinder(float radius, float height)
rbConstraint * RB_constraint_new_6dof_spring2(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
void RB_constraint_set_limits_piston(rbConstraint *con, float lin_lower, float lin_upper, float ang_lower, float ang_upper)
void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, float upper)
void RB_body_set_loc_rot(rbRigidBody *object, const float loc[3], const float rot[4])
void RB_constraint_set_limits_hinge(rbConstraint *con, float lower, float upper)
rbMeshData * RB_trimesh_data_new(int num_tris, int num_verts)
void RB_constraint_set_target_velocity_motor(rbConstraint *con, float velocity_lin, float velocity_ang)
rbCollisionShape * RB_shape_new_trimesh(rbMeshData *mesh)
void RB_body_activate(rbRigidBody *object)
void RB_body_set_linear_factor(rbRigidBody *object, float x, float y, float z)
void RB_body_set_sleep_thresh(rbRigidBody *object, float linear, float angular)
rbConstraint * RB_constraint_new_slider(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
void RB_dworld_step_simulation(rbDynamicsWorld *world, float timeStep, int maxSubSteps, float timeSubStep)
void RB_constraint_set_equilibrium_6dof_spring2(rbConstraint *con)
void RB_body_get_scale(rbRigidBody *object, float v_out[3])
rbConstraint * RB_constraint_new_6dof(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
void RB_constraint_set_spring_6dof_spring2(rbConstraint *con, int axis, int enable)
rbCollisionShape * RB_shape_new_capsule(float radius, float height)
void RB_body_set_angular_factor(rbRigidBody *object, float x, float y, float z)
struct RigidBodyWorld * BKE_rigidbody_get_world(Scene *scene)
Definition: rigidbody.c:2324
void BKE_rigidbody_free_world(Scene *scene)
Definition: rigidbody.c:90
void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild)
Definition: rigidbody.c:2286
void BKE_rigidbody_object_sync_transforms(Depsgraph *depsgraph, Scene *scene, Object *ob)
Definition: rigidbody.c:2406
void BKE_rigidbody_objects_collection_validate(Main *bmain, Scene *scene, RigidBodyWorld *rbw)
Definition: rigidbody.c:2365
void BKE_rigidbody_remove_constraint(Main *bmain, Scene *scene, Object *ob, const bool free_us)
Definition: rigidbody.c:2342
static void RB_dworld_remove_constraint(void *UNUSED(world), void *UNUSED(con))
Definition: rigidbody.c:69
void BKE_rigidbody_main_collection_object_add(Main *bmain, Collection *collection, Object *object)
Definition: rigidbody.c:2371
void BKE_rigidbody_object_copy(Main *bmain, Object *ob_dst, const Object *ob_src, const int flag)
Definition: rigidbody.c:2283
void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
Definition: rigidbody.c:2345
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
Definition: rigidbody.c:2356
void BKE_rigidbody_free_constraint(Object *ob)
Definition: rigidbody.c:193
void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
Definition: rigidbody.c:2296
static void RB_dworld_delete(void *UNUSED(world))
Definition: rigidbody.c:75
void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob, const bool free_us)
Definition: rigidbody.c:2339
void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime)
Definition: rigidbody.c:2359
bool BKE_rigidbody_add_object(Main *bmain, Scene *scene, Object *ob, int type, ReportList *reports)
Definition: rigidbody.c:2333
void BKE_rigidbody_eval_simulation(Depsgraph *depsgraph, Scene *scene)
Definition: rigidbody.c:2394
static void RB_body_delete(void *UNUSED(body))
Definition: rigidbody.c:78
bool BKE_rigidbody_is_affected_by_simulation(Object *ob)
Definition: rigidbody.c:213
static void RB_shape_delete(void *UNUSED(shape))
Definition: rigidbody.c:81
void BKE_rigidbody_world_id_loop(struct RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata)
Definition: rigidbody.c:2311
static void RB_constraint_delete(void *UNUSED(con))
Definition: rigidbody.c:84
void BKE_rigidbody_ensure_local_object(Main *bmain, Object *ob)
Definition: rigidbody.c:2329
bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime)
Definition: rigidbody.c:2352
void BKE_rigidbody_free_object(Object *ob, RigidBodyWorld *rbw)
Definition: rigidbody.c:146
void BKE_rigidbody_rebuild_sim(Depsgraph *depsgraph, Scene *scene)
Definition: rigidbody.c:2384
struct RigidBodyWorld * BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag)
Definition: rigidbody.c:2304
void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw)
Definition: rigidbody.c:2308
struct RigidBodyCon * BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type)
Definition: rigidbody.c:2320
static void RB_dworld_remove_body(void *UNUSED(world), void *UNUSED(body))
Definition: rigidbody.c:72
struct RigidBodyOb * BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
Definition: rigidbody.c:2316
void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime)
Definition: rigidbody.c:2362
void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
Definition: rigidbody.c:2290
void BKE_rigidbody_constraints_collection_validate(Scene *scene, RigidBodyWorld *rbw)
Definition: rigidbody.c:2368
struct RigidBodyWorld * BKE_rigidbody_create_world(Scene *scene)
Definition: rigidbody.c:2300
void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
Definition: rigidbody.c:2348
short flag
float vec[8][3]
struct Collection * group
Definition: DNA_ID.h:368
int tag
Definition: DNA_ID.h:387
void * next
Definition: DNA_ID.h:369
char name[66]
Definition: DNA_ID.h:378
void * first
Definition: DNA_listBase.h:31
unsigned int tri[3]
unsigned int v
Definition: BKE_main.h:121
ListBase scenes
Definition: BKE_main.h:168
struct MLoopTri_Store looptris
struct MVert * mvert
int totvert
struct MLoop * mloop
Mesh_Runtime runtime
struct Mesh * mesh_deform_eval
struct ID * data_orig
short base_flag
float drot[3]
float dquat[4]
struct RigidBodyOb * rigidbody_object
float loc[3]
struct PartDeflect * pd
float dloc[3]
float rot[3]
Object_Runtime runtime
float drotAxis[3]
float obmat[4][4]
float quat[4]
short rotmode
float rotAngle
float rotAxis[3]
float drotAngle
short protectflag
struct Object * parent
struct RigidBodyCon * rigidbody_constraint
void * data
struct Object * ob1
float motor_lin_target_velocity
float motor_ang_target_velocity
struct Object * ob2
struct RigidBodyOb_Shared * shared
struct PointCache * pointcache
struct Collection * constraints
struct Collection * group
struct RigidBodyWorld_Shared * shared
struct Object ** objects
struct EffectorWeights * effector_weights
struct Collection * master_collection
struct PhysicsSettings physics_settings
struct RigidBodyWorld * rigidbody_world