Cleanup: style
[blender.git] / source / blender / blenkernel / intern / rigidbody.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2013 Blender Foundation
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Joshua Leung, Sergej Reich
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file rigidbody.c
29  *  \ingroup blenkernel
30  *  \brief Blender-side interface and methods for dealing with Rigid Body simulations
31  */
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <stddef.h>
36 #include <float.h>
37 #include <math.h>
38 #include <limits.h>
39
40 #include "MEM_guardedalloc.h"
41
42 #include "BLI_blenlib.h"
43 #include "BLI_math.h"
44
45 #ifdef WITH_BULLET
46 #  include "RBI_api.h"
47 #endif
48
49 #include "DNA_ID.h"
50 #include "DNA_group_types.h"
51 #include "DNA_meshdata_types.h"
52 #include "DNA_object_types.h"
53 #include "DNA_object_force_types.h"
54 #include "DNA_rigidbody_types.h"
55 #include "DNA_scene_types.h"
56
57 #include "BKE_cdderivedmesh.h"
58 #include "BKE_collection.h"
59 #include "BKE_effect.h"
60 #include "BKE_global.h"
61 #include "BKE_library.h"
62 #include "BKE_library_query.h"
63 #include "BKE_mesh.h"
64 #include "BKE_object.h"
65 #include "BKE_pointcache.h"
66 #include "BKE_rigidbody.h"
67 #include "BKE_scene.h"
68
69 #include "DEG_depsgraph.h"
70 #include "DEG_depsgraph_query.h"
71
72 /* ************************************** */
73 /* Memory Management */
74
75 /* Freeing Methods --------------------- */
76
77 #ifndef WITH_BULLET
78
79 static void RB_dworld_remove_constraint(void *UNUSED(world), void *UNUSED(con)) {}
80 static void RB_dworld_remove_body(void *UNUSED(world), void *UNUSED(body)) {}
81 static void RB_dworld_delete(void *UNUSED(world)) {}
82 static void RB_body_delete(void *UNUSED(body)) {}
83 static void RB_shape_delete(void *UNUSED(shape)) {}
84 static void RB_constraint_delete(void *UNUSED(con)) {}
85
86 #endif
87
88 /* Free rigidbody world */
89 void BKE_rigidbody_free_world(RigidBodyWorld *rbw)
90 {
91         /* sanity check */
92         if (!rbw)
93                 return;
94
95         if (rbw->physics_world) {
96                 /* free physics references, we assume that all physics objects in will have been added to the world */
97                 if (rbw->constraints) {
98                         FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, object)
99                         {
100                                 if (object->rigidbody_constraint) {
101                                         RigidBodyCon *rbc = object->rigidbody_constraint;
102                                         if (rbc->physics_constraint) {
103                                                 RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
104                                         }
105                                 }
106                         }
107                         FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
108                 }
109
110                 if (rbw->group) {
111                         FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
112                         {
113                                 if (object->rigidbody_object) {
114                                         RigidBodyOb *rbo = object->rigidbody_object;
115                                         if (rbo->physics_object) {
116                                                 RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
117                                         }
118                                 }
119                         }
120                         FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
121                 }
122                 /* free dynamics world */
123                 RB_dworld_delete(rbw->physics_world);
124         }
125         if (rbw->objects)
126                 free(rbw->objects);
127
128         /* free cache */
129         BKE_ptcache_free_list(&(rbw->ptcaches));
130         rbw->pointcache = NULL;
131
132         /* free effector weights */
133         if (rbw->effector_weights)
134                 MEM_freeN(rbw->effector_weights);
135
136         /* free rigidbody world itself */
137         MEM_freeN(rbw);
138 }
139
140 /* Free RigidBody settings and sim instances */
141 void BKE_rigidbody_free_object(Object *ob)
142 {
143         RigidBodyOb *rbo = (ob) ? ob->rigidbody_object : NULL;
144
145         /* sanity check */
146         if (rbo == NULL)
147                 return;
148
149         /* free physics references */
150         if (rbo->physics_object) {
151                 RB_body_delete(rbo->physics_object);
152                 rbo->physics_object = NULL;
153         }
154
155         if (rbo->physics_shape) {
156                 RB_shape_delete(rbo->physics_shape);
157                 rbo->physics_shape = NULL;
158         }
159
160         /* free data itself */
161         MEM_freeN(rbo);
162         ob->rigidbody_object = NULL;
163 }
164
165 /* Free RigidBody constraint and sim instance */
166 void BKE_rigidbody_free_constraint(Object *ob)
167 {
168         RigidBodyCon *rbc = (ob) ? ob->rigidbody_constraint : NULL;
169
170         /* sanity check */
171         if (rbc == NULL)
172                 return;
173
174         /* free physics reference */
175         if (rbc->physics_constraint) {
176                 RB_constraint_delete(rbc->physics_constraint);
177                 rbc->physics_constraint = NULL;
178         }
179
180         /* free data itself */
181         MEM_freeN(rbc);
182         ob->rigidbody_constraint = NULL;
183 }
184
185 #ifdef WITH_BULLET
186
187 /* Copying Methods --------------------- */
188
189 /* These just copy the data, clearing out references to physics objects.
190  * Anything that uses them MUST verify that the copied object will
191  * be added to relevant groups later...
192  */
193
194 RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int UNUSED(flag))
195 {
196         RigidBodyOb *rboN = NULL;
197
198         if (ob->rigidbody_object) {
199                 /* just duplicate the whole struct first (to catch all the settings) */
200                 rboN = MEM_dupallocN(ob->rigidbody_object);
201
202                 /* tag object as needing to be verified */
203                 rboN->flag |= RBO_FLAG_NEEDS_VALIDATE;
204
205                 /* clear out all the fields which need to be revalidated later */
206                 rboN->physics_object = NULL;
207                 rboN->physics_shape = NULL;
208         }
209
210         /* return new copy of settings */
211         return rboN;
212 }
213
214 RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int UNUSED(flag))
215 {
216         RigidBodyCon *rbcN = NULL;
217
218         if (ob->rigidbody_constraint) {
219                 /* just duplicate the whole struct first (to catch all the settings) */
220                 rbcN = MEM_dupallocN(ob->rigidbody_constraint);
221
222                 /* tag object as needing to be verified */
223                 rbcN->flag |= RBC_FLAG_NEEDS_VALIDATE;
224
225                 /* clear out all the fields which need to be revalidated later */
226                 rbcN->physics_constraint = NULL;
227         }
228
229         /* return new copy of settings */
230         return rbcN;
231 }
232
233 /* ************************************** */
234 /* Setup Utilities - Validate Sim Instances */
235
236 /* get the appropriate DerivedMesh based on rigid body mesh source */
237 static DerivedMesh *rigidbody_get_mesh(Object *ob)
238 {
239         if (ob->rigidbody_object->mesh_source == RBO_MESH_DEFORM) {
240                 return ob->derivedDeform;
241         }
242         else if (ob->rigidbody_object->mesh_source == RBO_MESH_FINAL) {
243                 return ob->derivedFinal;
244         }
245         else {
246                 return CDDM_from_mesh(ob->data);
247         }
248 }
249
250 /* create collision shape of mesh - convex hull */
251 static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob, float margin, bool *can_embed)
252 {
253         rbCollisionShape *shape = NULL;
254         DerivedMesh *dm = NULL;
255         MVert *mvert = NULL;
256         int totvert = 0;
257
258         if (ob->type == OB_MESH && ob->data) {
259                 dm = rigidbody_get_mesh(ob);
260                 mvert   = (dm) ? dm->getVertArray(dm) : NULL;
261                 totvert = (dm) ? dm->getNumVerts(dm) : 0;
262         }
263         else {
264                 printf("ERROR: cannot make Convex Hull collision shape for non-Mesh object\n");
265         }
266
267         if (totvert) {
268                 shape = RB_shape_new_convex_hull((float *)mvert, sizeof(MVert), totvert, margin, can_embed);
269         }
270         else {
271                 printf("ERROR: no vertices to define Convex Hull collision shape with\n");
272         }
273
274         if (dm && ob->rigidbody_object->mesh_source == RBO_MESH_BASE)
275                 dm->release(dm);
276
277         return shape;
278 }
279
280 /* create collision shape of mesh - triangulated mesh
281  * returns NULL if creation fails.
282  */
283 static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
284 {
285         rbCollisionShape *shape = NULL;
286
287         if (ob->type == OB_MESH) {
288                 DerivedMesh *dm = NULL;
289                 MVert *mvert;
290                 const MLoopTri *looptri;
291                 int totvert;
292                 int tottri;
293                 const MLoop *mloop;
294                 
295                 dm = rigidbody_get_mesh(ob);
296
297                 /* ensure mesh validity, then grab data */
298                 if (dm == NULL)
299                         return NULL;
300
301                 mvert   = dm->getVertArray(dm);
302                 totvert = dm->getNumVerts(dm);
303                 looptri = dm->getLoopTriArray(dm);
304                 tottri = dm->getNumLoopTri(dm);
305                 mloop = dm->getLoopArray(dm);
306
307                 /* sanity checking - potential case when no data will be present */
308                 if ((totvert == 0) || (tottri == 0)) {
309                         printf("WARNING: no geometry data converted for Mesh Collision Shape (ob = %s)\n", ob->id.name + 2);
310                 }
311                 else {
312                         rbMeshData *mdata;
313                         int i;
314
315                         /* init mesh data for collision shape */
316                         mdata = RB_trimesh_data_new(tottri, totvert);
317                         
318                         RB_trimesh_add_vertices(mdata, (float *)mvert, totvert, sizeof(MVert));
319
320                         /* loop over all faces, adding them as triangles to the collision shape
321                          * (so for some faces, more than triangle will get added)
322                          */
323                         if (mvert && looptri) {
324                                 for (i = 0; i < tottri; i++) {
325                                         /* add first triangle - verts 1,2,3 */
326                                         const MLoopTri *lt = &looptri[i];
327                                         int vtri[3];
328
329                                         vtri[0] = mloop[lt->tri[0]].v;
330                                         vtri[1] = mloop[lt->tri[1]].v;
331                                         vtri[2] = mloop[lt->tri[2]].v;
332
333                                         RB_trimesh_add_triangle_indices(mdata, i, UNPACK3(vtri));
334                                 }
335                         }
336                         
337                         RB_trimesh_finish(mdata);
338
339                         /* construct collision shape
340                          *
341                          * These have been chosen to get better speed/accuracy tradeoffs with regards
342                          * to limitations of each:
343                          *    - BVH-Triangle Mesh: for passive objects only. Despite having greater
344                          *                         speed/accuracy, they cannot be used for moving objects.
345                          *    - GImpact Mesh:      for active objects. These are slower and less stable,
346                          *                         but are more flexible for general usage.
347                          */
348                         if (ob->rigidbody_object->type == RBO_TYPE_PASSIVE) {
349                                 shape = RB_shape_new_trimesh(mdata);
350                         }
351                         else {
352                                 shape = RB_shape_new_gimpact_mesh(mdata);
353                         }
354                 }
355
356                 /* cleanup temp data */
357                 if (ob->rigidbody_object->mesh_source == RBO_MESH_BASE) {
358                         dm->release(dm);
359                 }
360         }
361         else {
362                 printf("ERROR: cannot make Triangular Mesh collision shape for non-Mesh object\n");
363         }
364
365         return shape;
366 }
367
368 /* Create new physics sim collision shape for object and store it,
369  * or remove the existing one first and replace...
370  */
371 static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
372 {
373         RigidBodyOb *rbo = ob->rigidbody_object;
374         rbCollisionShape *new_shape = NULL;
375         BoundBox *bb = NULL;
376         float size[3] = {1.0f, 1.0f, 1.0f};
377         float radius = 1.0f;
378         float height = 1.0f;
379         float capsule_height;
380         float hull_margin = 0.0f;
381         bool can_embed = true;
382         bool has_volume;
383
384         /* sanity check */
385         if (rbo == NULL)
386                 return;
387
388         /* don't create a new shape if we already have one and don't want to rebuild it */
389         if (rbo->physics_shape && !rebuild)
390                 return;
391
392         /* if automatically determining dimensions, use the Object's boundbox
393          *      - assume that all quadrics are standing upright on local z-axis
394          *      - assume even distribution of mass around the Object's pivot
395          *        (i.e. Object pivot is centralized in boundbox)
396          */
397         // XXX: all dimensions are auto-determined now... later can add stored settings for this
398         /* get object dimensions without scaling */
399         bb = BKE_object_boundbox_get(ob);
400         if (bb) {
401                 size[0] = (bb->vec[4][0] - bb->vec[0][0]);
402                 size[1] = (bb->vec[2][1] - bb->vec[0][1]);
403                 size[2] = (bb->vec[1][2] - bb->vec[0][2]);
404         }
405         mul_v3_fl(size, 0.5f);
406
407         if (ELEM(rbo->shape, RB_SHAPE_CAPSULE, RB_SHAPE_CYLINDER, RB_SHAPE_CONE)) {
408                 /* take radius as largest x/y dimension, and height as z-dimension */
409                 radius = MAX2(size[0], size[1]);
410                 height = size[2];
411         }
412         else if (rbo->shape == RB_SHAPE_SPHERE) {
413                 /* take radius to the largest dimension to try and encompass everything */
414                 radius = MAX3(size[0], size[1], size[2]);
415         }
416
417         /* create new shape */
418         switch (rbo->shape) {
419                 case RB_SHAPE_BOX:
420                         new_shape = RB_shape_new_box(size[0], size[1], size[2]);
421                         break;
422
423                 case RB_SHAPE_SPHERE:
424                         new_shape = RB_shape_new_sphere(radius);
425                         break;
426
427                 case RB_SHAPE_CAPSULE:
428                         capsule_height = (height - radius) * 2.0f;
429                         new_shape = RB_shape_new_capsule(radius, (capsule_height > 0.0f) ? capsule_height : 0.0f);
430                         break;
431                 case RB_SHAPE_CYLINDER:
432                         new_shape = RB_shape_new_cylinder(radius, height);
433                         break;
434                 case RB_SHAPE_CONE:
435                         new_shape = RB_shape_new_cone(radius, height * 2.0f);
436                         break;
437
438                 case RB_SHAPE_CONVEXH:
439                         /* try to emged collision margin */
440                         has_volume = (MIN3(size[0], size[1], size[2]) > 0.0f);
441
442                         if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && has_volume)
443                                 hull_margin = 0.04f;
444                         new_shape = rigidbody_get_shape_convexhull_from_mesh(ob, hull_margin, &can_embed);
445                         if (!(rbo->flag & RBO_FLAG_USE_MARGIN))
446                                 rbo->margin = (can_embed && has_volume) ? 0.04f : 0.0f;  /* RB_TODO ideally we shouldn't directly change the margin here */
447                         break;
448                 case RB_SHAPE_TRIMESH:
449                         new_shape = rigidbody_get_shape_trimesh_from_mesh(ob);
450                         break;
451         }
452         /* use box shape if we can't fall back to old shape */
453         if (new_shape == NULL && rbo->physics_shape == NULL) {
454                 new_shape = RB_shape_new_box(size[0], size[1], size[2]);
455         }
456         /* assign new collision shape if creation was successful */
457         if (new_shape) {
458                 if (rbo->physics_shape)
459                         RB_shape_delete(rbo->physics_shape);
460                 rbo->physics_shape = new_shape;
461                 RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo));
462         }
463 }
464
465 /* --------------------- */
466
467 /* helper function to calculate volume of rigidbody object */
468 // TODO: allow a parameter to specify method used to calculate this?
469 void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
470 {
471         RigidBodyOb *rbo = ob->rigidbody_object;
472
473         float size[3]  = {1.0f, 1.0f, 1.0f};
474         float radius = 1.0f;
475         float height = 1.0f;
476
477         float volume = 0.0f;
478
479         /* if automatically determining dimensions, use the Object's boundbox
480          *      - assume that all quadrics are standing upright on local z-axis
481          *      - assume even distribution of mass around the Object's pivot
482          *        (i.e. Object pivot is centralized in boundbox)
483          *      - boundbox gives full width
484          */
485         // XXX: all dimensions are auto-determined now... later can add stored settings for this
486         BKE_object_dimensions_get(ob, size);
487
488         if (ELEM(rbo->shape, RB_SHAPE_CAPSULE, RB_SHAPE_CYLINDER, RB_SHAPE_CONE)) {
489                 /* take radius as largest x/y dimension, and height as z-dimension */
490                 radius = MAX2(size[0], size[1]) * 0.5f;
491                 height = size[2];
492         }
493         else if (rbo->shape == RB_SHAPE_SPHERE) {
494                 /* take radius to the largest dimension to try and encompass everything */
495                 radius = max_fff(size[0], size[1], size[2]) * 0.5f;
496         }
497
498         /* calculate volume as appropriate  */
499         switch (rbo->shape) {
500                 case RB_SHAPE_BOX:
501                         volume = size[0] * size[1] * size[2];
502                         break;
503
504                 case RB_SHAPE_SPHERE:
505                         volume = 4.0f / 3.0f * (float)M_PI * radius * radius * radius;
506                         break;
507
508                 /* for now, assume that capsule is close enough to a cylinder... */
509                 case RB_SHAPE_CAPSULE:
510                 case RB_SHAPE_CYLINDER:
511                         volume = (float)M_PI * radius * radius * height;
512                         break;
513
514                 case RB_SHAPE_CONE:
515                         volume = (float)M_PI / 3.0f * radius * radius * height;
516                         break;
517
518                 case RB_SHAPE_CONVEXH:
519                 case RB_SHAPE_TRIMESH:
520                 {
521                         if (ob->type == OB_MESH) {
522                                 DerivedMesh *dm = rigidbody_get_mesh(ob);
523                                 MVert *mvert;
524                                 const MLoopTri *lt = NULL;
525                                 int totvert, tottri = 0;
526                                 const MLoop *mloop = NULL;
527                                 
528                                 /* ensure mesh validity, then grab data */
529                                 if (dm == NULL)
530                                         return;
531                         
532                                 mvert   = dm->getVertArray(dm);
533                                 totvert = dm->getNumVerts(dm);
534                                 lt = dm->getLoopTriArray(dm);
535                                 tottri = dm->getNumLoopTri(dm);
536                                 mloop = dm->getLoopArray(dm);
537                                 
538                                 if (totvert > 0 && tottri > 0) {
539                                         BKE_mesh_calc_volume(mvert, totvert, lt, tottri, mloop, &volume, NULL);
540                                 }
541                                 
542                                 /* cleanup temp data */
543                                 if (ob->rigidbody_object->mesh_source == RBO_MESH_BASE) {
544                                         dm->release(dm);
545                                 }
546                         }
547                         else {
548                                 /* rough estimate from boundbox as fallback */
549                                 /* XXX could implement other types of geometry here (curves, etc.) */
550                                 volume = size[0] * size[1] * size[2];
551                         }
552                         break;
553                 }
554
555 #if 0 // XXX: not defined yet
556                 case RB_SHAPE_COMPOUND:
557                         volume = 0.0f;
558                         break;
559 #endif
560         }
561
562         /* return the volume calculated */
563         if (r_vol) *r_vol = volume;
564 }
565
566 void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
567 {
568         RigidBodyOb *rbo = ob->rigidbody_object;
569
570         float size[3]  = {1.0f, 1.0f, 1.0f};
571         float height = 1.0f;
572
573         zero_v3(r_center);
574
575         /* if automatically determining dimensions, use the Object's boundbox
576          *      - assume that all quadrics are standing upright on local z-axis
577          *      - assume even distribution of mass around the Object's pivot
578          *        (i.e. Object pivot is centralized in boundbox)
579          *      - boundbox gives full width
580          */
581         // XXX: all dimensions are auto-determined now... later can add stored settings for this
582         BKE_object_dimensions_get(ob, size);
583
584         /* calculate volume as appropriate  */
585         switch (rbo->shape) {
586                 case RB_SHAPE_BOX:
587                 case RB_SHAPE_SPHERE:
588                 case RB_SHAPE_CAPSULE:
589                 case RB_SHAPE_CYLINDER:
590                         break;
591
592                 case RB_SHAPE_CONE:
593                         /* take radius as largest x/y dimension, and height as z-dimension */
594                         height = size[2];
595                         /* cone is geometrically centered on the median,
596                          * center of mass is 1/4 up from the base
597                          */
598                         r_center[2] = -0.25f * height;
599                         break;
600
601                 case RB_SHAPE_CONVEXH:
602                 case RB_SHAPE_TRIMESH:
603                 {
604                         if (ob->type == OB_MESH) {
605                                 DerivedMesh *dm = rigidbody_get_mesh(ob);
606                                 MVert *mvert;
607                                 const MLoopTri *looptri;
608                                 int totvert, tottri;
609                                 const MLoop *mloop;
610                                 
611                                 /* ensure mesh validity, then grab data */
612                                 if (dm == NULL)
613                                         return;
614                         
615                                 mvert   = dm->getVertArray(dm);
616                                 totvert = dm->getNumVerts(dm);
617                                 looptri = dm->getLoopTriArray(dm);
618                                 tottri = dm->getNumLoopTri(dm);
619                                 mloop = dm->getLoopArray(dm);
620                                 
621                                 if (totvert > 0 && tottri > 0) {
622                                         BKE_mesh_calc_volume(mvert, totvert, looptri, tottri, mloop, NULL, r_center);
623                                 }
624                                 
625                                 /* cleanup temp data */
626                                 if (ob->rigidbody_object->mesh_source == RBO_MESH_BASE) {
627                                         dm->release(dm);
628                                 }
629                         }
630                         break;
631                 }
632
633 #if 0 // XXX: not defined yet
634                 case RB_SHAPE_COMPOUND:
635                         volume = 0.0f;
636                         break;
637 #endif
638         }
639 }
640
641 /* --------------------- */
642
643 /**
644  * Create physics sim representation of object given RigidBody settings
645  *
646  * \param rebuild Even if an instance already exists, replace it
647  */
648 static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool rebuild)
649 {
650         RigidBodyOb *rbo = (ob) ? ob->rigidbody_object : NULL;
651         float loc[3];
652         float rot[4];
653
654         /* sanity checks:
655          *      - object doesn't have RigidBody info already: then why is it here?
656          */
657         if (rbo == NULL)
658                 return;
659
660         /* make sure collision shape exists */
661         /* FIXME we shouldn't always have to rebuild collision shapes when rebuilding objects, but it's needed for constraints to update correctly */
662         if (rbo->physics_shape == NULL || rebuild)
663                 rigidbody_validate_sim_shape(ob, true);
664
665         if (rbo->physics_object && rebuild == false) {
666                 RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
667         }
668         if (!rbo->physics_object || rebuild) {
669                 /* remove rigid body if it already exists before creating a new one */
670                 if (rbo->physics_object) {
671                         RB_body_delete(rbo->physics_object);
672                 }
673
674                 mat4_to_loc_quat(loc, rot, ob->obmat);
675
676                 rbo->physics_object = RB_body_new(rbo->physics_shape, loc, rot);
677
678                 RB_body_set_friction(rbo->physics_object, rbo->friction);
679                 RB_body_set_restitution(rbo->physics_object, rbo->restitution);
680
681                 RB_body_set_damping(rbo->physics_object, rbo->lin_damping, rbo->ang_damping);
682                 RB_body_set_sleep_thresh(rbo->physics_object, rbo->lin_sleep_thresh, rbo->ang_sleep_thresh);
683                 RB_body_set_activation_state(rbo->physics_object, rbo->flag & RBO_FLAG_USE_DEACTIVATION);
684
685                 if (rbo->type == RBO_TYPE_PASSIVE || rbo->flag & RBO_FLAG_START_DEACTIVATED)
686                         RB_body_deactivate(rbo->physics_object);
687
688
689                 RB_body_set_linear_factor(rbo->physics_object,
690                                           (ob->protectflag & OB_LOCK_LOCX) == 0,
691                                           (ob->protectflag & OB_LOCK_LOCY) == 0,
692                                           (ob->protectflag & OB_LOCK_LOCZ) == 0);
693                 RB_body_set_angular_factor(rbo->physics_object,
694                                            (ob->protectflag & OB_LOCK_ROTX) == 0,
695                                            (ob->protectflag & OB_LOCK_ROTY) == 0,
696                                            (ob->protectflag & OB_LOCK_ROTZ) == 0);
697
698                 RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
699                 RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
700         }
701
702         if (rbw && rbw->physics_world)
703                 RB_dworld_add_body(rbw->physics_world, rbo->physics_object, rbo->col_groups);
704 }
705
706 /* --------------------- */
707
708 static void rigidbody_constraint_set_limits(
709         RigidBodyCon *rbc, void (*set_limits)(rbConstraint *, int, float, float))
710 {
711         if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
712                 set_limits(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->limit_lin_x_lower, rbc->limit_lin_x_upper);
713         else
714                 set_limits(rbc->physics_constraint, RB_LIMIT_LIN_X, 0.0f, -1.0f);
715
716         if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Y)
717                 set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->limit_lin_y_lower, rbc->limit_lin_y_upper);
718         else
719                 set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Y, 0.0f, -1.0f);
720
721         if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Z)
722                 set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->limit_lin_z_lower, rbc->limit_lin_z_upper);
723         else
724                 set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Z, 0.0f, -1.0f);
725
726         if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_X)
727                 set_limits(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->limit_ang_x_lower, rbc->limit_ang_x_upper);
728         else
729                 set_limits(rbc->physics_constraint, RB_LIMIT_ANG_X, 0.0f, -1.0f);
730
731         if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Y)
732                 set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->limit_ang_y_lower, rbc->limit_ang_y_upper);
733         else
734                 set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Y, 0.0f, -1.0f);
735
736         if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Z)
737                 set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->limit_ang_z_lower, rbc->limit_ang_z_upper);
738         else
739                 set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Z, 0.0f, -1.0f);
740 }
741
742 /**
743  * Create physics sim representation of constraint given rigid body constraint settings
744  *
745  * \param rebuild Even if an instance already exists, replace it
746  */
747 static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, bool rebuild)
748 {
749         RigidBodyCon *rbc = (ob) ? ob->rigidbody_constraint : NULL;
750         float loc[3];
751         float rot[4];
752         float lin_lower;
753         float lin_upper;
754         float ang_lower;
755         float ang_upper;
756
757         /* sanity checks:
758          *      - object should have a rigid body constraint
759          *  - rigid body constraint should have at least one constrained object
760          */
761         if (rbc == NULL) {
762                 return;
763         }
764
765         if (ELEM(NULL, rbc->ob1, rbc->ob1->rigidbody_object, rbc->ob2, rbc->ob2->rigidbody_object)) {
766                 if (rbc->physics_constraint) {
767                         RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
768                         RB_constraint_delete(rbc->physics_constraint);
769                         rbc->physics_constraint = NULL;
770                 }
771                 return;
772         }
773
774         if (rbc->physics_constraint && rebuild == false) {
775                 RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
776         }
777         if (rbc->physics_constraint == NULL || rebuild) {
778                 rbRigidBody *rb1 = rbc->ob1->rigidbody_object->physics_object;
779                 rbRigidBody *rb2 = rbc->ob2->rigidbody_object->physics_object;
780
781                 /* remove constraint if it already exists before creating a new one */
782                 if (rbc->physics_constraint) {
783                         RB_constraint_delete(rbc->physics_constraint);
784                         rbc->physics_constraint = NULL;
785                 }
786
787                 mat4_to_loc_quat(loc, rot, ob->obmat);
788
789                 if (rb1 && rb2) {
790                         switch (rbc->type) {
791                                 case RBC_TYPE_POINT:
792                                         rbc->physics_constraint = RB_constraint_new_point(loc, rb1, rb2);
793                                         break;
794                                 case RBC_TYPE_FIXED:
795                                         rbc->physics_constraint = RB_constraint_new_fixed(loc, rot, rb1, rb2);
796                                         break;
797                                 case RBC_TYPE_HINGE:
798                                         rbc->physics_constraint = RB_constraint_new_hinge(loc, rot, rb1, rb2);
799                                         if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Z) {
800                                                 RB_constraint_set_limits_hinge(rbc->physics_constraint, rbc->limit_ang_z_lower, rbc->limit_ang_z_upper);
801                                         }
802                                         else
803                                                 RB_constraint_set_limits_hinge(rbc->physics_constraint, 0.0f, -1.0f);
804                                         break;
805                                 case RBC_TYPE_SLIDER:
806                                         rbc->physics_constraint = RB_constraint_new_slider(loc, rot, rb1, rb2);
807                                         if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
808                                                 RB_constraint_set_limits_slider(rbc->physics_constraint, rbc->limit_lin_x_lower, rbc->limit_lin_x_upper);
809                                         else
810                                                 RB_constraint_set_limits_slider(rbc->physics_constraint, 0.0f, -1.0f);
811                                         break;
812                                 case RBC_TYPE_PISTON:
813                                         rbc->physics_constraint = RB_constraint_new_piston(loc, rot, rb1, rb2);
814                                         if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X) {
815                                                 lin_lower = rbc->limit_lin_x_lower;
816                                                 lin_upper = rbc->limit_lin_x_upper;
817                                         }
818                                         else {
819                                                 lin_lower = 0.0f;
820                                                 lin_upper = -1.0f;
821                                         }
822                                         if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_X) {
823                                                 ang_lower = rbc->limit_ang_x_lower;
824                                                 ang_upper = rbc->limit_ang_x_upper;
825                                         }
826                                         else {
827                                                 ang_lower = 0.0f;
828                                                 ang_upper = -1.0f;
829                                         }
830                                         RB_constraint_set_limits_piston(rbc->physics_constraint, lin_lower, lin_upper, ang_lower, ang_upper);
831                                         break;
832                                 case RBC_TYPE_6DOF_SPRING:
833                                         rbc->physics_constraint = RB_constraint_new_6dof_spring(loc, rot, rb1, rb2);
834
835                                         RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->flag & RBC_FLAG_USE_SPRING_X);
836                                         RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_stiffness_x);
837                                         RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_damping_x);
838
839                                         RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->flag & RBC_FLAG_USE_SPRING_Y);
840                                         RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_stiffness_y);
841                                         RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_damping_y);
842
843                                         RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->flag & RBC_FLAG_USE_SPRING_Z);
844                                         RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z);
845                                         RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z);
846
847                                         RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->flag & RBC_FLAG_USE_SPRING_ANG_X);
848                                         RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_stiffness_ang_x);
849                                         RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_damping_ang_x);
850
851                                         RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y);
852                                         RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_stiffness_ang_y);
853                                         RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_damping_ang_y);
854
855                                         RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z);
856                                         RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_stiffness_ang_z);
857                                         RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z);
858
859                                         RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint);
860
861                                         rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof_spring);
862                                         break;
863                                 case RBC_TYPE_6DOF:
864                                         rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2);
865
866                                         rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof);
867                                         break;
868                                 case RBC_TYPE_MOTOR:
869                                         rbc->physics_constraint = RB_constraint_new_motor(loc, rot, rb1, rb2);
870
871                                         RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
872                                         RB_constraint_set_max_impulse_motor(rbc->physics_constraint, rbc->motor_lin_max_impulse, rbc->motor_ang_max_impulse);
873                                         RB_constraint_set_target_velocity_motor(rbc->physics_constraint, rbc->motor_lin_target_velocity, rbc->motor_ang_target_velocity);
874                                         break;
875                         }
876                 }
877                 else { /* can't create constraint without both rigid bodies */
878                         return;
879                 }
880
881                 RB_constraint_set_enabled(rbc->physics_constraint, rbc->flag & RBC_FLAG_ENABLED);
882
883                 if (rbc->flag & RBC_FLAG_USE_BREAKING)
884                         RB_constraint_set_breaking_threshold(rbc->physics_constraint, rbc->breaking_threshold);
885                 else
886                         RB_constraint_set_breaking_threshold(rbc->physics_constraint, FLT_MAX);
887
888                 if (rbc->flag & RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS)
889                         RB_constraint_set_solver_iterations(rbc->physics_constraint, rbc->num_solver_iterations);
890                 else
891                         RB_constraint_set_solver_iterations(rbc->physics_constraint, -1);
892         }
893
894         if (rbw && rbw->physics_world && rbc->physics_constraint) {
895                 RB_dworld_add_constraint(rbw->physics_world, rbc->physics_constraint, rbc->flag & RBC_FLAG_DISABLE_COLLISIONS);
896         }
897 }
898
899 /* --------------------- */
900
901 /* Create physics sim world given RigidBody world settings */
902 // NOTE: this does NOT update object references that the scene uses, in case those aren't ready yet!
903 void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild)
904 {
905         /* sanity checks */
906         if (rbw == NULL)
907                 return;
908
909         /* create new sim world */
910         if (rebuild || rbw->physics_world == NULL) {
911                 if (rbw->physics_world)
912                         RB_dworld_delete(rbw->physics_world);
913                 rbw->physics_world = RB_dworld_new(scene->physics_settings.gravity);
914         }
915
916         RB_dworld_set_solver_iterations(rbw->physics_world, rbw->num_solver_iterations);
917         RB_dworld_set_split_impulse(rbw->physics_world, rbw->flag & RBW_FLAG_USE_SPLIT_IMPULSE);
918 }
919
920 /* ************************************** */
921 /* Setup Utilities - Create Settings Blocks */
922
923 /* Set up RigidBody world */
924 RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
925 {
926         /* try to get whatever RigidBody world that might be representing this already */
927         RigidBodyWorld *rbw;
928
929         /* sanity checks
930          *      - there must be a valid scene to add world to
931          *      - there mustn't be a sim world using this group already
932          */
933         if (scene == NULL)
934                 return NULL;
935
936         /* create a new sim world */
937         rbw = MEM_callocN(sizeof(RigidBodyWorld), "RigidBodyWorld");
938
939         /* set default settings */
940         rbw->effector_weights = BKE_add_effector_weights(NULL);
941
942         rbw->ltime = PSFRA;
943
944         rbw->time_scale = 1.0f;
945
946         rbw->steps_per_second = 60; /* Bullet default (60 Hz) */
947         rbw->num_solver_iterations = 10; /* 10 is bullet default */
948
949         rbw->pointcache = BKE_ptcache_add(&(rbw->ptcaches));
950         rbw->pointcache->step = 1;
951
952         /* return this sim world */
953         return rbw;
954 }
955
956 RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag)
957 {
958         RigidBodyWorld *rbw_copy = MEM_dupallocN(rbw);
959
960         if (rbw->effector_weights) {
961                 rbw_copy->effector_weights = MEM_dupallocN(rbw->effector_weights);
962         }
963         if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
964                 id_us_plus((ID *)rbw_copy->group);
965                 id_us_plus((ID *)rbw_copy->constraints);
966         }
967
968         /* XXX Never copy caches here? */
969         rbw_copy->pointcache = BKE_ptcache_copy_list(&rbw_copy->ptcaches, &rbw->ptcaches, flag & ~LIB_ID_COPY_CACHES);
970
971         rbw_copy->objects = NULL;
972         rbw_copy->physics_world = NULL;
973         rbw_copy->numbodies = 0;
974
975         return rbw_copy;
976 }
977
978 void BKE_rigidbody_world_groups_relink(RigidBodyWorld *rbw)
979 {
980         ID_NEW_REMAP(rbw->group);
981         ID_NEW_REMAP(rbw->constraints);
982         ID_NEW_REMAP(rbw->effector_weights->group);
983 }
984
985 void BKE_rigidbody_world_id_loop(RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata)
986 {
987         func(rbw, (ID **)&rbw->group, userdata, IDWALK_CB_NOP);
988         func(rbw, (ID **)&rbw->constraints, userdata, IDWALK_CB_NOP);
989         func(rbw, (ID **)&rbw->effector_weights->group, userdata, IDWALK_CB_NOP);
990
991         if (rbw->objects) {
992                 int i;
993                 for (i = 0; i < rbw->numbodies; i++) {
994                         func(rbw, (ID **)&rbw->objects[i], userdata, IDWALK_CB_NOP);
995                 }
996         }
997 }
998
999 /* Add rigid body settings to the specified object */
1000 RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
1001 {
1002         RigidBodyOb *rbo;
1003         RigidBodyWorld *rbw = scene->rigidbody_world;
1004
1005         /* sanity checks
1006          *      - rigidbody world must exist
1007          *      - object must exist
1008          *      - cannot add rigid body if it already exists
1009          */
1010         if (ob == NULL || (ob->rigidbody_object != NULL))
1011                 return NULL;
1012
1013         /* create new settings data, and link it up */
1014         rbo = MEM_callocN(sizeof(RigidBodyOb), "RigidBodyOb");
1015
1016         /* set default settings */
1017         rbo->type = type;
1018
1019         rbo->mass = 1.0f;
1020
1021         rbo->friction = 0.5f; /* best when non-zero. 0.5 is Bullet default */
1022         rbo->restitution = 0.0f; /* best when zero. 0.0 is Bullet default */
1023
1024         rbo->margin = 0.04f; /* 0.04 (in meters) is Bullet default */
1025
1026         rbo->lin_sleep_thresh = 0.4f; /* 0.4 is half of Bullet default */
1027         rbo->ang_sleep_thresh = 0.5f; /* 0.5 is half of Bullet default */
1028
1029         rbo->lin_damping = 0.04f;
1030         rbo->ang_damping = 0.1f;
1031
1032         rbo->col_groups = 1;
1033
1034         /* use triangle meshes for passive objects
1035          * use convex hulls for active objects since dynamic triangle meshes are very unstable
1036          */
1037         if (type == RBO_TYPE_ACTIVE)
1038                 rbo->shape = RB_SHAPE_CONVEXH;
1039         else
1040                 rbo->shape = RB_SHAPE_TRIMESH;
1041
1042         rbo->mesh_source = RBO_MESH_DEFORM;
1043
1044         /* set initial transform */
1045         mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
1046
1047         /* flag cache as outdated */
1048         BKE_rigidbody_cache_reset(rbw);
1049
1050         /* return this object */
1051         return rbo;
1052 }
1053
1054 /* Add rigid body constraint to the specified object */
1055 RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type)
1056 {
1057         RigidBodyCon *rbc;
1058         RigidBodyWorld *rbw = scene->rigidbody_world;
1059
1060         /* sanity checks
1061          *      - rigidbody world must exist
1062          *      - object must exist
1063          *      - cannot add constraint if it already exists
1064          */
1065         if (ob == NULL || (ob->rigidbody_constraint != NULL))
1066                 return NULL;
1067
1068         /* create new settings data, and link it up */
1069         rbc = MEM_callocN(sizeof(RigidBodyCon), "RigidBodyCon");
1070
1071         /* set default settings */
1072         rbc->type = type;
1073
1074         rbc->ob1 = NULL;
1075         rbc->ob2 = NULL;
1076
1077         rbc->flag |= RBC_FLAG_ENABLED;
1078         rbc->flag |= RBC_FLAG_DISABLE_COLLISIONS;
1079
1080         rbc->breaking_threshold = 10.0f; /* no good default here, just use 10 for now */
1081         rbc->num_solver_iterations = 10; /* 10 is Bullet default */
1082
1083         rbc->limit_lin_x_lower = -1.0f;
1084         rbc->limit_lin_x_upper = 1.0f;
1085         rbc->limit_lin_y_lower = -1.0f;
1086         rbc->limit_lin_y_upper = 1.0f;
1087         rbc->limit_lin_z_lower = -1.0f;
1088         rbc->limit_lin_z_upper = 1.0f;
1089         rbc->limit_ang_x_lower = -M_PI_4;
1090         rbc->limit_ang_x_upper = M_PI_4;
1091         rbc->limit_ang_y_lower = -M_PI_4;
1092         rbc->limit_ang_y_upper = M_PI_4;
1093         rbc->limit_ang_z_lower = -M_PI_4;
1094         rbc->limit_ang_z_upper = M_PI_4;
1095
1096         rbc->spring_damping_x = 0.5f;
1097         rbc->spring_damping_y = 0.5f;
1098         rbc->spring_damping_z = 0.5f;
1099         rbc->spring_damping_ang_x = 0.5f;
1100         rbc->spring_damping_ang_y = 0.5f;
1101         rbc->spring_damping_ang_z = 0.5f;
1102         rbc->spring_stiffness_x = 10.0f;
1103         rbc->spring_stiffness_y = 10.0f;
1104         rbc->spring_stiffness_z = 10.0f;
1105         rbc->spring_stiffness_ang_x = 10.0f;
1106         rbc->spring_stiffness_ang_y = 10.0f;
1107         rbc->spring_stiffness_ang_z = 10.0f;
1108
1109         rbc->motor_lin_max_impulse = 1.0f;
1110         rbc->motor_lin_target_velocity = 1.0f;
1111         rbc->motor_ang_max_impulse = 1.0f;
1112         rbc->motor_ang_target_velocity = 1.0f;
1113
1114         /* flag cache as outdated */
1115         BKE_rigidbody_cache_reset(rbw);
1116
1117         /* return this object */
1118         return rbc;
1119 }
1120
1121 /* ************************************** */
1122 /* Utilities API */
1123
1124 /* Get RigidBody world for the given scene, creating one if needed
1125  *
1126  * \param scene Scene to find active Rigid Body world for
1127  */
1128 RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene)
1129 {
1130         /* sanity check */
1131         if (scene == NULL)
1132                 return NULL;
1133
1134         return scene->rigidbody_world;
1135 }
1136
1137 void BKE_rigidbody_remove_object(Scene *scene, Object *ob)
1138 {
1139         RigidBodyWorld *rbw = scene->rigidbody_world;
1140         RigidBodyOb *rbo = ob->rigidbody_object;
1141         RigidBodyCon *rbc;
1142         int i;
1143
1144         if (rbw) {
1145                 /* remove from rigidbody world, free object won't do this */
1146                 if (rbw->physics_world && rbo->physics_object)
1147                         RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
1148
1149                 /* remove object from array */
1150                 if (rbw && rbw->objects) {
1151                         for (i = 0; i < rbw->numbodies; i++) {
1152                                 if (rbw->objects[i] == ob) {
1153                                         rbw->objects[i] = NULL;
1154                                         break;
1155                                 }
1156                         }
1157                 }
1158
1159                 /* remove object from rigid body constraints */
1160                 if (rbw->constraints) {
1161                         FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, obt)
1162                         {
1163                                 if (obt && obt->rigidbody_constraint) {
1164                                         rbc = obt->rigidbody_constraint;
1165                                         if (ELEM(ob, rbc->ob1, rbc->ob2)) {
1166                                                 BKE_rigidbody_remove_constraint(scene, obt);
1167                                         }
1168                                 }
1169                         }
1170                         FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1171                 }
1172         }
1173
1174         /* remove object's settings */
1175         BKE_rigidbody_free_object(ob);
1176
1177         /* flag cache as outdated */
1178         BKE_rigidbody_cache_reset(rbw);
1179 }
1180
1181 void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
1182 {
1183         RigidBodyWorld *rbw = scene->rigidbody_world;
1184         RigidBodyCon *rbc = ob->rigidbody_constraint;
1185
1186         /* remove from rigidbody world, free object won't do this */
1187         if (rbw && rbw->physics_world && rbc->physics_constraint) {
1188                 RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
1189         }
1190         /* remove object's settings */
1191         BKE_rigidbody_free_constraint(ob);
1192
1193         /* flag cache as outdated */
1194         BKE_rigidbody_cache_reset(rbw);
1195 }
1196
1197
1198 /* ************************************** */
1199 /* Simulation Interface - Bullet */
1200
1201 /* Update object array and rigid body count so they're in sync with the rigid body group */
1202 static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
1203 {
1204         const ListBase objects = BKE_collection_object_cache_get(rbw->group);
1205         int i, n;
1206
1207         n = BLI_listbase_count(&objects);
1208
1209         if (rbw->numbodies != n) {
1210                 rbw->numbodies = n;
1211                 rbw->objects = realloc(rbw->objects, sizeof(Object *) * rbw->numbodies);
1212         }
1213
1214         i = 0;
1215         FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
1216         {
1217                 rbw->objects[i] = object;
1218                 i++;
1219         }
1220         FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1221 }
1222
1223 static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw)
1224 {
1225         float adj_gravity[3];
1226
1227         /* adjust gravity to take effector weights into account */
1228         if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
1229                 copy_v3_v3(adj_gravity, scene->physics_settings.gravity);
1230                 mul_v3_fl(adj_gravity, rbw->effector_weights->global_gravity * rbw->effector_weights->weight[0]);
1231         }
1232         else {
1233                 zero_v3(adj_gravity);
1234         }
1235
1236         /* update gravity, since this RNA setting is not part of RigidBody settings */
1237         RB_dworld_set_gravity(rbw->physics_world, adj_gravity);
1238
1239         /* update object array in case there are changes */
1240         rigidbody_update_ob_array(rbw);
1241 }
1242
1243 static void rigidbody_update_sim_ob(struct Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo)
1244 {
1245         float loc[3];
1246         float rot[4];
1247         float scale[3];
1248
1249         /* only update if rigid body exists */
1250         if (rbo->physics_object == NULL)
1251                 return;
1252
1253         if (rbo->shape == RB_SHAPE_TRIMESH && rbo->flag & RBO_FLAG_USE_DEFORM) {
1254                 DerivedMesh *dm = ob->derivedDeform;
1255                 if (dm) {
1256                         MVert *mvert = dm->getVertArray(dm);
1257                         int totvert = dm->getNumVerts(dm);
1258                         BoundBox *bb = BKE_object_boundbox_get(ob);
1259
1260                         RB_shape_trimesh_update(rbo->physics_shape, (float *)mvert, totvert, sizeof(MVert), bb->vec[0], bb->vec[6]);
1261                 }
1262         }
1263
1264         mat4_decompose(loc, rot, scale, ob->obmat);
1265
1266         /* update scale for all objects */
1267         RB_body_set_scale(rbo->physics_object, scale);
1268         /* compensate for embedded convex hull collision margin */
1269         if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && rbo->shape == RB_SHAPE_CONVEXH)
1270                 RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo) * MIN3(scale[0], scale[1], scale[2]));
1271
1272         /* make transformed objects temporarily kinmatic so that they can be moved by the user during simulation */
1273         if (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ) {
1274                 RB_body_set_kinematic_state(rbo->physics_object, true);
1275                 RB_body_set_mass(rbo->physics_object, 0.0f);
1276         }
1277
1278         /* update rigid body location and rotation for kinematic bodies */
1279         if (rbo->flag & RBO_FLAG_KINEMATIC || (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
1280                 RB_body_activate(rbo->physics_object);
1281                 RB_body_set_loc_rot(rbo->physics_object, loc, rot);
1282         }
1283         /* update influence of effectors - but don't do it on an effector */
1284         /* only dynamic bodies need effector update */
1285         else if (rbo->type == RBO_TYPE_ACTIVE && ((ob->pd == NULL) || (ob->pd->forcefield == PFIELD_NULL))) {
1286                 EffectorWeights *effector_weights = rbw->effector_weights;
1287                 EffectedPoint epoint;
1288                 ListBase *effectors;
1289
1290                 /* get effectors present in the group specified by effector_weights */
1291                 effectors = pdInitEffectors(depsgraph, scene, ob, NULL, effector_weights, true);
1292                 if (effectors) {
1293                         float eff_force[3] = {0.0f, 0.0f, 0.0f};
1294                         float eff_loc[3], eff_vel[3];
1295
1296                         /* create dummy 'point' which represents last known position of object as result of sim */
1297                         // XXX: this can create some inaccuracies with sim position, but is probably better than using unsimulated vals?
1298                         RB_body_get_position(rbo->physics_object, eff_loc);
1299                         RB_body_get_linear_velocity(rbo->physics_object, eff_vel);
1300
1301                         pd_point_from_loc(scene, eff_loc, eff_vel, 0, &epoint);
1302
1303                         /* calculate net force of effectors, and apply to sim object
1304                          *      - we use 'central force' since apply force requires a "relative position" which we don't have...
1305                          */
1306                         pdDoEffectors(effectors, NULL, effector_weights, &epoint, eff_force, NULL);
1307                         if (G.f & G_DEBUG)
1308                                 printf("\tapplying force (%f,%f,%f) to '%s'\n", eff_force[0], eff_force[1], eff_force[2], ob->id.name + 2);
1309                         /* activate object in case it is deactivated */
1310                         if (!is_zero_v3(eff_force))
1311                                 RB_body_activate(rbo->physics_object);
1312                         RB_body_apply_central_force(rbo->physics_object, eff_force);
1313                 }
1314                 else if (G.f & G_DEBUG)
1315                         printf("\tno forces to apply to '%s'\n", ob->id.name + 2);
1316
1317                 /* cleanup */
1318                 pdEndEffectors(&effectors);
1319         }
1320         /* NOTE: passive objects don't need to be updated since they don't move */
1321
1322         /* NOTE: no other settings need to be explicitly updated here,
1323          * since RNA setters take care of the rest :)
1324          */
1325 }
1326
1327 /**
1328  * Updates and validates world, bodies and shapes.
1329  *
1330  * \param rebuild Rebuild entire simulation
1331  */
1332 static void rigidbody_update_simulation(struct Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, bool rebuild)
1333 {
1334         /* update world */
1335         if (rebuild)
1336                 BKE_rigidbody_validate_sim_world(scene, rbw, true);
1337         rigidbody_update_sim_world(scene, rbw);
1338
1339         /* XXX TODO For rebuild: remove all constraints first.
1340          * Otherwise we can end up deleting objects that are still
1341          * referenced by constraints, corrupting bullet's internal list.
1342          * 
1343          * Memory management needs redesign here, this is just a dirty workaround.
1344          */
1345         if (rebuild && rbw->constraints) {
1346                 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, ob)
1347                 {
1348                         RigidBodyCon *rbc = ob->rigidbody_constraint;
1349                         if (rbc && rbc->physics_constraint) {
1350                                 RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
1351                                 RB_constraint_delete(rbc->physics_constraint);
1352                                 rbc->physics_constraint = NULL;
1353                         }
1354                 }
1355                 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1356         }
1357
1358         /* update objects */
1359         FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, ob)
1360         {
1361                 if (ob->type == OB_MESH) {
1362                         /* validate that we've got valid object set up here... */
1363                         RigidBodyOb *rbo = ob->rigidbody_object;
1364                         /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
1365                         BKE_object_where_is_calc(depsgraph, scene, ob);
1366
1367                         if (rbo == NULL) {
1368                                 /* Since this object is included in the sim group but doesn't have
1369                                  * rigid body settings (perhaps it was added manually), add!
1370                                  *      - assume object to be active? That is the default for newly added settings...
1371                                  */
1372                                 ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, RBO_TYPE_ACTIVE);
1373                                 rigidbody_validate_sim_object(rbw, ob, true);
1374
1375                                 rbo = ob->rigidbody_object;
1376                         }
1377                         else {
1378                                 /* perform simulation data updates as tagged */
1379                                 /* refresh object... */
1380                                 if (rebuild) {
1381                                         /* World has been rebuilt so rebuild object */
1382                                         rigidbody_validate_sim_object(rbw, ob, true);
1383                                 }
1384                                 else if (rbo->flag & RBO_FLAG_NEEDS_VALIDATE) {
1385                                         rigidbody_validate_sim_object(rbw, ob, false);
1386                                 }
1387                                 /* refresh shape... */
1388                                 if (rbo->flag & RBO_FLAG_NEEDS_RESHAPE) {
1389                                         /* mesh/shape data changed, so force shape refresh */
1390                                         rigidbody_validate_sim_shape(ob, true);
1391                                         /* now tell RB sim about it */
1392                                         // XXX: we assume that this can only get applied for active/passive shapes that will be included as rigidbodies
1393                                         RB_body_set_collision_shape(rbo->physics_object, rbo->physics_shape);
1394                                 }
1395                                 rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE);
1396                         }
1397
1398                         /* update simulation object... */
1399                         rigidbody_update_sim_ob(depsgraph, scene, rbw, ob, rbo);
1400                 }
1401         }
1402         FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1403         
1404         /* update constraints */
1405         if (rbw->constraints == NULL) /* no constraints, move on */
1406                 return;
1407
1408         FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, ob)
1409         {
1410                 /* validate that we've got valid object set up here... */
1411                 RigidBodyCon *rbc = ob->rigidbody_constraint;
1412                 /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
1413                 BKE_object_where_is_calc(depsgraph, scene, ob);
1414
1415                 if (rbc == NULL) {
1416                         /* Since this object is included in the group but doesn't have
1417                          * constraint settings (perhaps it was added manually), add!
1418                          */
1419                         ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED);
1420                         rigidbody_validate_sim_constraint(rbw, ob, true);
1421
1422                         rbc = ob->rigidbody_constraint;
1423                 }
1424                 else {
1425                         /* perform simulation data updates as tagged */
1426                         if (rebuild) {
1427                                 /* World has been rebuilt so rebuild constraint */
1428                                 rigidbody_validate_sim_constraint(rbw, ob, true);
1429                         }
1430                         else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) {
1431                                 rigidbody_validate_sim_constraint(rbw, ob, false);
1432                         }
1433                         rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE;
1434                 }
1435         }
1436         FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
1437 }
1438
1439 static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw)
1440 {
1441         FOREACH_COLLECTION_BASE_RECURSIVE_BEGIN(rbw->group, base)
1442         {
1443                 Object *ob = base->object;
1444                 RigidBodyOb *rbo = ob->rigidbody_object;
1445                 /* Reset kinematic state for transformed objects. */
1446                 if (rbo && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) {
1447                         RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
1448                         RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
1449                         /* Deactivate passive objects so they don't interfere with deactivation of active objects. */
1450                         if (rbo->type == RBO_TYPE_PASSIVE)
1451                                 RB_body_deactivate(rbo->physics_object);
1452                 }
1453         }
1454         FOREACH_COLLECTION_BASE_RECURSIVE_END
1455 }
1456
1457 bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime)
1458 {
1459         return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0 && ctime > rbw->pointcache->startframe);
1460 }
1461
1462 /* Sync rigid body and object transformations */
1463 void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
1464 {
1465         RigidBodyOb *rbo = ob->rigidbody_object;
1466
1467         /* keep original transform for kinematic and passive objects */
1468         if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE)
1469                 return;
1470
1471         /* use rigid body transform after cache start frame if objects is not being transformed */
1472         if (BKE_rigidbody_check_sim_running(rbw, ctime) && !(ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
1473                 float mat[4][4], size_mat[4][4], size[3];
1474
1475                 normalize_qt(rbo->orn); // RB_TODO investigate why quaternion isn't normalized at this point
1476                 quat_to_mat4(mat, rbo->orn);
1477                 copy_v3_v3(mat[3], rbo->pos);
1478
1479                 mat4_to_size(size, ob->obmat);
1480                 size_to_mat4(size_mat, size);
1481                 mul_m4_m4m4(mat, mat, size_mat);
1482
1483                 copy_m4_m4(ob->obmat, mat);
1484         }
1485         /* otherwise set rigid body transform to current obmat */
1486         else {
1487                 mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
1488         }
1489 }
1490
1491 /* Used when canceling transforms - return rigidbody and object to initial states */
1492 void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
1493 {
1494         RigidBodyOb *rbo = ob->rigidbody_object;
1495         bool correct_delta = !(rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE);
1496
1497         /* return rigid body and object to their initial states */
1498         copy_v3_v3(rbo->pos, ob->loc);
1499         copy_v3_v3(ob->loc, loc);
1500
1501         if (correct_delta) {
1502                 add_v3_v3(rbo->pos, ob->dloc);
1503         }
1504
1505         if (ob->rotmode > 0) {
1506                 float qt[4];
1507                 eulO_to_quat(qt, ob->rot, ob->rotmode);
1508
1509                 if (correct_delta) {
1510                         float dquat[4];
1511                         eulO_to_quat(dquat, ob->drot, ob->rotmode);
1512
1513                         mul_qt_qtqt(rbo->orn, dquat, qt);
1514                 }
1515                 else {
1516                         copy_qt_qt(rbo->orn, qt);
1517                 }
1518
1519                 copy_v3_v3(ob->rot, rot);
1520         }
1521         else if (ob->rotmode == ROT_MODE_AXISANGLE) {
1522                 float qt[4];
1523                 axis_angle_to_quat(qt, ob->rotAxis, ob->rotAngle);
1524
1525                 if (correct_delta) {
1526                         float dquat[4];
1527                         axis_angle_to_quat(dquat, ob->drotAxis, ob->drotAngle);
1528
1529                         mul_qt_qtqt(rbo->orn, dquat, qt);
1530                 }
1531                 else {
1532                         copy_qt_qt(rbo->orn, qt);
1533                 }
1534
1535                 copy_v3_v3(ob->rotAxis, rotAxis);
1536                 ob->rotAngle = rotAngle;
1537         }
1538         else {
1539                 if (correct_delta) {
1540                         mul_qt_qtqt(rbo->orn, ob->dquat, ob->quat);
1541                 }
1542                 else {
1543                         copy_qt_qt(rbo->orn, ob->quat);
1544                 }
1545
1546                 copy_qt_qt(ob->quat, quat);
1547         }
1548
1549         if (rbo->physics_object) {
1550                 /* allow passive objects to return to original transform */
1551                 if (rbo->type == RBO_TYPE_PASSIVE)
1552                         RB_body_set_kinematic_state(rbo->physics_object, true);
1553                 RB_body_set_loc_rot(rbo->physics_object, rbo->pos, rbo->orn);
1554         }
1555         // RB_TODO update rigid body physics object's loc/rot for dynamic objects here as well (needs to be done outside bullet's update loop)
1556 }
1557
1558 void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
1559 {
1560         if (rbw) {
1561                 rbw->pointcache->flag |= PTCACHE_OUTDATED;
1562         }
1563 }
1564
1565 /* ------------------ */
1566
1567 /* Rebuild rigid body world */
1568 /* NOTE: this needs to be called before frame update to work correctly */
1569 void BKE_rigidbody_rebuild_world(struct Depsgraph *depsgraph, Scene *scene, float ctime)
1570 {
1571         RigidBodyWorld *rbw = scene->rigidbody_world;
1572         PointCache *cache;
1573         PTCacheID pid;
1574         int startframe, endframe;
1575
1576         BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
1577         BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
1578         cache = rbw->pointcache;
1579
1580         /* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */
1581         const ListBase objects = BKE_collection_object_cache_get(rbw->group);
1582         if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&objects)) {
1583                 cache->flag |= PTCACHE_OUTDATED;
1584         }
1585
1586         if (ctime == startframe + 1 && rbw->ltime == startframe) {
1587                 if (cache->flag & PTCACHE_OUTDATED) {
1588                         BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
1589                         rigidbody_update_simulation(depsgraph, scene, rbw, true);
1590                         BKE_ptcache_validate(cache, (int)ctime);
1591                         cache->last_exact = 0;
1592                         cache->flag &= ~PTCACHE_REDO_NEEDED;
1593                 }
1594         }
1595 }
1596
1597 /* Run RigidBody simulation for the specified physics world */
1598 void BKE_rigidbody_do_simulation(struct Depsgraph *depsgraph, Scene *scene, float ctime)
1599 {
1600         float timestep;
1601         RigidBodyWorld *rbw = scene->rigidbody_world;
1602         PointCache *cache;
1603         PTCacheID pid;
1604         int startframe, endframe;
1605
1606         BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
1607         BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
1608         cache = rbw->pointcache;
1609
1610         if (ctime <= startframe) {
1611                 rbw->ltime = startframe;
1612                 return;
1613         }
1614         /* make sure we don't go out of cache frame range */
1615         else if (ctime > endframe) {
1616                 ctime = endframe;
1617         }
1618
1619         /* don't try to run the simulation if we don't have a world yet but allow reading baked cache */
1620         if (rbw->physics_world == NULL && !(cache->flag & PTCACHE_BAKED))
1621                 return;
1622         else if (rbw->objects == NULL)
1623                 rigidbody_update_ob_array(rbw);
1624
1625         /* try to read from cache */
1626         // RB_TODO deal with interpolated, old and baked results
1627         bool can_simulate = (ctime == rbw->ltime + 1) && !(cache->flag & PTCACHE_BAKED);
1628
1629         if (BKE_ptcache_read(&pid, ctime, can_simulate) == PTCACHE_READ_EXACT) {
1630                 BKE_ptcache_validate(cache, (int)ctime);
1631                 rbw->ltime = ctime;
1632                 return;
1633         }
1634
1635         /* advance simulation, we can only step one frame forward */
1636         if (ctime == rbw->ltime + 1) {
1637                 /* write cache for first frame when on second frame */
1638                 if (rbw->ltime == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) {
1639                         BKE_ptcache_write(&pid, startframe);
1640                 }
1641
1642                 /* update and validate simulation */
1643                 rigidbody_update_simulation(depsgraph, scene, rbw, false);
1644
1645                 /* calculate how much time elapsed since last step in seconds */
1646                 timestep = 1.0f / (float)FPS * (ctime - rbw->ltime) * rbw->time_scale;
1647                 /* step simulation by the requested timestep, steps per second are adjusted to take time scale into account */
1648                 RB_dworld_step_simulation(rbw->physics_world, timestep, INT_MAX, 1.0f / (float)rbw->steps_per_second * min_ff(rbw->time_scale, 1.0f));
1649
1650                 rigidbody_update_simulation_post_step(rbw);
1651
1652                 /* write cache for current frame */
1653                 BKE_ptcache_validate(cache, (int)ctime);
1654                 BKE_ptcache_write(&pid, (unsigned int)ctime);
1655
1656                 rbw->ltime = ctime;
1657         }
1658 }
1659 /* ************************************** */
1660
1661 #else  /* WITH_BULLET */
1662
1663 /* stubs */
1664 #if defined(__GNUC__) || defined(__clang__)
1665 #  pragma GCC diagnostic push
1666 #  pragma GCC diagnostic ignored "-Wunused-parameter"
1667 #endif
1668
1669 struct RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int flag) { return NULL; }
1670 struct RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int flag) { return NULL; }
1671 void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild) {}
1672 void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) { if (r_vol) *r_vol = 0.0f; }
1673 void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3]) { zero_v3(r_center); }
1674 struct RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene) { return NULL; }
1675 struct RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag) { return NULL; }
1676 void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw) {}
1677 void BKE_rigidbody_world_id_loop(struct RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata) {}
1678 struct RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type) { return NULL; }
1679 struct RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type) { return NULL; }
1680 struct RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene) { return NULL; }
1681 void BKE_rigidbody_remove_object(Scene *scene, Object *ob) {}
1682 void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob) {}
1683 void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) {}
1684 void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {}
1685 bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) { return false; }
1686 void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
1687 void BKE_rigidbody_rebuild_world(struct Depsgraph *depsgraph, Scene *scene, float ctime) {}
1688 void BKE_rigidbody_do_simulation(struct Depsgraph *depsgraph, Scene *scene, float ctime) {}
1689
1690 #if defined(__GNUC__) || defined(__clang__)
1691 #  pragma GCC diagnostic pop
1692 #endif
1693
1694 #endif  /* WITH_BULLET */
1695
1696 /* -------------------- */
1697 /* Depsgraph evaluation */
1698
1699 void BKE_rigidbody_rebuild_sim(struct Depsgraph *depsgraph,
1700                                Scene *scene)
1701 {
1702         float ctime = DEG_get_ctime(depsgraph);
1703         DEG_debug_print_eval_time(depsgraph, __func__, scene->id.name, scene, ctime);
1704         /* rebuild sim data (i.e. after resetting to start of timeline) */
1705         if (BKE_scene_check_rigidbody_active(scene)) {
1706                 BKE_rigidbody_rebuild_world(depsgraph, scene, ctime);
1707         }
1708 }
1709
1710 void BKE_rigidbody_eval_simulation(struct Depsgraph *depsgraph,
1711                                    Scene *scene)
1712 {
1713         float ctime = DEG_get_ctime(depsgraph);
1714         DEG_debug_print_eval_time(depsgraph, __func__, scene->id.name, scene, ctime);
1715         /* evaluate rigidbody sim */
1716         if (BKE_scene_check_rigidbody_active(scene)) {
1717                 BKE_rigidbody_do_simulation(depsgraph, scene, ctime);
1718         }
1719 }
1720
1721 void BKE_rigidbody_object_sync_transforms(struct Depsgraph *depsgraph,
1722                                           Scene *scene,
1723                                           Object *ob)
1724 {
1725         RigidBodyWorld *rbw = scene->rigidbody_world;
1726         float ctime = DEG_get_ctime(depsgraph);
1727         DEG_debug_print_eval_time(depsgraph, __func__, ob->id.name, ob, ctime);
1728         /* read values pushed into RBO from sim/cache... */
1729         BKE_rigidbody_sync_transforms(rbw, ob, ctime);
1730 }