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