UI: add back Data-block 'show_hidden_files_datablocks' name
[blender.git] / intern / rigidbody / rb_bullet_api.cpp
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
20 /** \file
21  * \ingroup RigidBody
22  * \brief Rigid Body API implementation for Bullet
23  */
24
25 /*
26  * Bullet Continuous Collision Detection and Physics Library
27  * Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
28  *
29  * This software is provided 'as-is', without any express or implied warranty. In no event will the
30  * authors be held liable for any damages arising from the use of this software. Permission is
31  * granted to anyone to use this software for any purpose, including commercial applications, and
32  * to alter it and redistribute it freely, subject to the following restrictions:
33  *
34  * 1. The origin of this software must not be misrepresented; you must not claim that you wrote the
35  *    original software. If you use this software in a product, an acknowledgment in the product
36  *    documentation would be appreciated but is not required.
37  * 2. Altered source versions must be plainly marked as such, and must not be misrepresented as
38  *    being the original software.
39  * 3. This notice may not be removed or altered from any source distribution.
40  */
41
42 /* This file defines the "RigidBody interface" for the
43  * Bullet Physics Engine. This API is designed to be used
44  * from C-code in Blender as part of the Rigid Body simulation
45  * system.
46  *
47  * It is based on the Bullet C-API, but is heavily modified to
48  * give access to more data types and to offer a nicer interface.
49  *
50  * -- Joshua Leung, June 2010
51  */
52
53 #include <stdio.h>
54 #include <errno.h>
55
56 #include "RBI_api.h"
57
58 #include "btBulletDynamicsCommon.h"
59
60 #include "LinearMath/btVector3.h"
61 #include "LinearMath/btScalar.h"
62 #include "LinearMath/btMatrix3x3.h"
63 #include "LinearMath/btTransform.h"
64 #include "LinearMath/btConvexHullComputer.h"
65
66 #include "BulletCollision/Gimpact/btGImpactShape.h"
67 #include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"
68 #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
69
70 struct rbDynamicsWorld {
71   btDiscreteDynamicsWorld *dynamicsWorld;
72   btDefaultCollisionConfiguration *collisionConfiguration;
73   btDispatcher *dispatcher;
74   btBroadphaseInterface *pairCache;
75   btConstraintSolver *constraintSolver;
76   btOverlapFilterCallback *filterCallback;
77 };
78 struct rbRigidBody {
79   btRigidBody *body;
80   int col_groups;
81 };
82
83 struct rbVert {
84   float x, y, z;
85 };
86 struct rbTri {
87   int v0, v1, v2;
88 };
89
90 struct rbMeshData {
91   btTriangleIndexVertexArray *index_array;
92   rbVert *vertices;
93   rbTri *triangles;
94   int num_vertices;
95   int num_triangles;
96 };
97
98 struct rbCollisionShape {
99   btCollisionShape *cshape;
100   rbMeshData *mesh;
101 };
102
103 struct rbFilterCallback : public btOverlapFilterCallback {
104   virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
105   {
106     rbRigidBody *rb0 = (rbRigidBody *)((btRigidBody *)proxy0->m_clientObject)->getUserPointer();
107     rbRigidBody *rb1 = (rbRigidBody *)((btRigidBody *)proxy1->m_clientObject)->getUserPointer();
108
109     bool collides;
110     collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
111     collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
112     collides = collides && (rb0->col_groups & rb1->col_groups);
113
114     return collides;
115   }
116 };
117
118 static inline void copy_v3_btvec3(float vec[3], const btVector3 &btvec)
119 {
120   vec[0] = (float)btvec[0];
121   vec[1] = (float)btvec[1];
122   vec[2] = (float)btvec[2];
123 }
124 static inline void copy_quat_btquat(float quat[4], const btQuaternion &btquat)
125 {
126   quat[0] = btquat.getW();
127   quat[1] = btquat.getX();
128   quat[2] = btquat.getY();
129   quat[3] = btquat.getZ();
130 }
131
132 /* ********************************** */
133 /* Dynamics World Methods */
134
135 /* Setup ---------------------------- */
136
137 rbDynamicsWorld *RB_dworld_new(const float gravity[3])
138 {
139   rbDynamicsWorld *world = new rbDynamicsWorld;
140
141   /* collision detection/handling */
142   world->collisionConfiguration = new btDefaultCollisionConfiguration();
143
144   world->dispatcher = new btCollisionDispatcher(world->collisionConfiguration);
145   btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher *)world->dispatcher);
146
147   world->pairCache = new btDbvtBroadphase();
148
149   world->filterCallback = new rbFilterCallback();
150   world->pairCache->getOverlappingPairCache()->setOverlapFilterCallback(world->filterCallback);
151
152   /* constraint solving */
153   world->constraintSolver = new btSequentialImpulseConstraintSolver();
154
155   /* world */
156   world->dynamicsWorld = new btDiscreteDynamicsWorld(
157       world->dispatcher, world->pairCache, world->constraintSolver, world->collisionConfiguration);
158
159   RB_dworld_set_gravity(world, gravity);
160
161   return world;
162 }
163
164 void RB_dworld_delete(rbDynamicsWorld *world)
165 {
166   /* bullet doesn't like if we free these in a different order */
167   delete world->dynamicsWorld;
168   delete world->constraintSolver;
169   delete world->pairCache;
170   delete world->dispatcher;
171   delete world->collisionConfiguration;
172   delete world->filterCallback;
173   delete world;
174 }
175
176 /* Settings ------------------------- */
177
178 /* Gravity */
179 void RB_dworld_get_gravity(rbDynamicsWorld *world, float g_out[3])
180 {
181   copy_v3_btvec3(g_out, world->dynamicsWorld->getGravity());
182 }
183
184 void RB_dworld_set_gravity(rbDynamicsWorld *world, const float g_in[3])
185 {
186   world->dynamicsWorld->setGravity(btVector3(g_in[0], g_in[1], g_in[2]));
187 }
188
189 /* Constraint Solver */
190 void RB_dworld_set_solver_iterations(rbDynamicsWorld *world, int num_solver_iterations)
191 {
192   btContactSolverInfo &info = world->dynamicsWorld->getSolverInfo();
193
194   info.m_numIterations = num_solver_iterations;
195 }
196
197 /* Split Impulse */
198 void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse)
199 {
200   btContactSolverInfo &info = world->dynamicsWorld->getSolverInfo();
201
202   info.m_splitImpulse = split_impulse;
203 }
204
205 /* Simulation ----------------------- */
206
207 void RB_dworld_step_simulation(rbDynamicsWorld *world,
208                                float timeStep,
209                                int maxSubSteps,
210                                float timeSubStep)
211 {
212   world->dynamicsWorld->stepSimulation(timeStep, maxSubSteps, timeSubStep);
213 }
214
215 /* Export -------------------------- */
216
217 /**
218  * Exports entire dynamics world to Bullet's "*.bullet" binary format
219  * which is similar to Blender's SDNA system.
220  *
221  * \param world Dynamics world to write to file
222  * \param filename Assumed to be a valid filename, with .bullet extension
223  */
224 void RB_dworld_export(rbDynamicsWorld *world, const char *filename)
225 {
226   // create a large enough buffer. There is no method to pre-calculate the buffer size yet.
227   int maxSerializeBufferSize = 1024 * 1024 * 5;
228
229   btDefaultSerializer *serializer = new btDefaultSerializer(maxSerializeBufferSize);
230   world->dynamicsWorld->serialize(serializer);
231
232   FILE *file = fopen(filename, "wb");
233   if (file) {
234     fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file);
235     fclose(file);
236   }
237   else {
238     fprintf(stderr, "RB_dworld_export: %s\n", strerror(errno));
239   }
240 }
241
242 /* ********************************** */
243 /* Rigid Body Methods */
244
245 /* Setup ---------------------------- */
246
247 void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *object, int col_groups)
248 {
249   btRigidBody *body = object->body;
250   object->col_groups = col_groups;
251
252   world->dynamicsWorld->addRigidBody(body);
253 }
254
255 void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *object)
256 {
257   btRigidBody *body = object->body;
258
259   world->dynamicsWorld->removeRigidBody(body);
260 }
261
262 /* Collision detection */
263
264 void RB_world_convex_sweep_test(rbDynamicsWorld *world,
265                                 rbRigidBody *object,
266                                 const float loc_start[3],
267                                 const float loc_end[3],
268                                 float v_location[3],
269                                 float v_hitpoint[3],
270                                 float v_normal[3],
271                                 int *r_hit)
272 {
273   btRigidBody *body = object->body;
274   btCollisionShape *collisionShape = body->getCollisionShape();
275   /* only convex shapes are supported, but user can specify a non convex shape */
276   if (collisionShape->isConvex()) {
277     btCollisionWorld::ClosestConvexResultCallback result(
278         btVector3(loc_start[0], loc_start[1], loc_start[2]),
279         btVector3(loc_end[0], loc_end[1], loc_end[2]));
280
281     btQuaternion obRot = body->getWorldTransform().getRotation();
282
283     btTransform rayFromTrans;
284     rayFromTrans.setIdentity();
285     rayFromTrans.setRotation(obRot);
286     rayFromTrans.setOrigin(btVector3(loc_start[0], loc_start[1], loc_start[2]));
287
288     btTransform rayToTrans;
289     rayToTrans.setIdentity();
290     rayToTrans.setRotation(obRot);
291     rayToTrans.setOrigin(btVector3(loc_end[0], loc_end[1], loc_end[2]));
292
293     world->dynamicsWorld->convexSweepTest(
294         (btConvexShape *)collisionShape, rayFromTrans, rayToTrans, result, 0);
295
296     if (result.hasHit()) {
297       *r_hit = 1;
298
299       v_location[0] = result.m_convexFromWorld[0] +
300                       (result.m_convexToWorld[0] - result.m_convexFromWorld[0]) *
301                           result.m_closestHitFraction;
302       v_location[1] = result.m_convexFromWorld[1] +
303                       (result.m_convexToWorld[1] - result.m_convexFromWorld[1]) *
304                           result.m_closestHitFraction;
305       v_location[2] = result.m_convexFromWorld[2] +
306                       (result.m_convexToWorld[2] - result.m_convexFromWorld[2]) *
307                           result.m_closestHitFraction;
308
309       v_hitpoint[0] = result.m_hitPointWorld[0];
310       v_hitpoint[1] = result.m_hitPointWorld[1];
311       v_hitpoint[2] = result.m_hitPointWorld[2];
312
313       v_normal[0] = result.m_hitNormalWorld[0];
314       v_normal[1] = result.m_hitNormalWorld[1];
315       v_normal[2] = result.m_hitNormalWorld[2];
316     }
317     else {
318       *r_hit = 0;
319     }
320   }
321   else {
322     /* we need to return a value if user passes non convex body, to report */
323     *r_hit = -2;
324   }
325 }
326
327 /* ............ */
328
329 rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4])
330 {
331   rbRigidBody *object = new rbRigidBody;
332   /* current transform */
333   btTransform trans;
334   trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
335   trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
336
337   /* create motionstate, which is necessary for interpolation (includes reverse playback) */
338   btDefaultMotionState *motionState = new btDefaultMotionState(trans);
339
340   /* make rigidbody */
341   btRigidBody::btRigidBodyConstructionInfo rbInfo(1.0f, motionState, shape->cshape);
342
343   object->body = new btRigidBody(rbInfo);
344
345   object->body->setUserPointer(object);
346
347   return object;
348 }
349
350 void RB_body_delete(rbRigidBody *object)
351 {
352   btRigidBody *body = object->body;
353
354   /* motion state */
355   btMotionState *ms = body->getMotionState();
356   if (ms)
357     delete ms;
358
359   /* collision shape is done elsewhere... */
360
361   /* body itself */
362
363   /* manually remove constraint refs of the rigid body, normally this happens when removing
364    * constraints from the world
365    * but since we delete everything when the world is rebult, we need to do it manually here */
366   for (int i = body->getNumConstraintRefs() - 1; i >= 0; i--) {
367     btTypedConstraint *con = body->getConstraintRef(i);
368     body->removeConstraintRef(con);
369   }
370
371   delete body;
372   delete object;
373 }
374
375 /* Settings ------------------------- */
376
377 void RB_body_set_collision_shape(rbRigidBody *object, rbCollisionShape *shape)
378 {
379   btRigidBody *body = object->body;
380
381   /* set new collision shape */
382   body->setCollisionShape(shape->cshape);
383
384   /* recalculate inertia, since that depends on the collision shape... */
385   RB_body_set_mass(object, RB_body_get_mass(object));
386 }
387
388 /* ............ */
389
390 float RB_body_get_mass(rbRigidBody *object)
391 {
392   btRigidBody *body = object->body;
393
394   /* there isn't really a mass setting, but rather 'inverse mass'
395    * which we convert back to mass by taking the reciprocal again
396    */
397   float value = (float)body->getInvMass();
398
399   if (value)
400     value = 1.0f / value;
401
402   return value;
403 }
404
405 void RB_body_set_mass(rbRigidBody *object, float value)
406 {
407   btRigidBody *body = object->body;
408   btVector3 localInertia(0, 0, 0);
409
410   /* calculate new inertia if non-zero mass */
411   if (value) {
412     btCollisionShape *shape = body->getCollisionShape();
413     shape->calculateLocalInertia(value, localInertia);
414   }
415
416   body->setMassProps(value, localInertia);
417   body->updateInertiaTensor();
418 }
419
420 float RB_body_get_friction(rbRigidBody *object)
421 {
422   btRigidBody *body = object->body;
423   return body->getFriction();
424 }
425
426 void RB_body_set_friction(rbRigidBody *object, float value)
427 {
428   btRigidBody *body = object->body;
429   body->setFriction(value);
430 }
431
432 float RB_body_get_restitution(rbRigidBody *object)
433 {
434   btRigidBody *body = object->body;
435   return body->getRestitution();
436 }
437
438 void RB_body_set_restitution(rbRigidBody *object, float value)
439 {
440   btRigidBody *body = object->body;
441   body->setRestitution(value);
442 }
443
444 float RB_body_get_linear_damping(rbRigidBody *object)
445 {
446   btRigidBody *body = object->body;
447   return body->getLinearDamping();
448 }
449
450 void RB_body_set_linear_damping(rbRigidBody *object, float value)
451 {
452   RB_body_set_damping(object, value, RB_body_get_linear_damping(object));
453 }
454
455 float RB_body_get_angular_damping(rbRigidBody *object)
456 {
457   btRigidBody *body = object->body;
458   return body->getAngularDamping();
459 }
460
461 void RB_body_set_angular_damping(rbRigidBody *object, float value)
462 {
463   RB_body_set_damping(object, RB_body_get_linear_damping(object), value);
464 }
465
466 void RB_body_set_damping(rbRigidBody *object, float linear, float angular)
467 {
468   btRigidBody *body = object->body;
469   body->setDamping(linear, angular);
470 }
471
472 float RB_body_get_linear_sleep_thresh(rbRigidBody *object)
473 {
474   btRigidBody *body = object->body;
475   return body->getLinearSleepingThreshold();
476 }
477
478 void RB_body_set_linear_sleep_thresh(rbRigidBody *object, float value)
479 {
480   RB_body_set_sleep_thresh(object, value, RB_body_get_angular_sleep_thresh(object));
481 }
482
483 float RB_body_get_angular_sleep_thresh(rbRigidBody *object)
484 {
485   btRigidBody *body = object->body;
486   return body->getAngularSleepingThreshold();
487 }
488
489 void RB_body_set_angular_sleep_thresh(rbRigidBody *object, float value)
490 {
491   RB_body_set_sleep_thresh(object, RB_body_get_linear_sleep_thresh(object), value);
492 }
493
494 void RB_body_set_sleep_thresh(rbRigidBody *object, float linear, float angular)
495 {
496   btRigidBody *body = object->body;
497   body->setSleepingThresholds(linear, angular);
498 }
499
500 /* ............ */
501
502 void RB_body_get_linear_velocity(rbRigidBody *object, float v_out[3])
503 {
504   btRigidBody *body = object->body;
505
506   copy_v3_btvec3(v_out, body->getLinearVelocity());
507 }
508
509 void RB_body_set_linear_velocity(rbRigidBody *object, const float v_in[3])
510 {
511   btRigidBody *body = object->body;
512
513   body->setLinearVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
514 }
515
516 void RB_body_get_angular_velocity(rbRigidBody *object, float v_out[3])
517 {
518   btRigidBody *body = object->body;
519
520   copy_v3_btvec3(v_out, body->getAngularVelocity());
521 }
522
523 void RB_body_set_angular_velocity(rbRigidBody *object, const float v_in[3])
524 {
525   btRigidBody *body = object->body;
526
527   body->setAngularVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
528 }
529
530 void RB_body_set_linear_factor(rbRigidBody *object, float x, float y, float z)
531 {
532   btRigidBody *body = object->body;
533   body->setLinearFactor(btVector3(x, y, z));
534 }
535
536 void RB_body_set_angular_factor(rbRigidBody *object, float x, float y, float z)
537 {
538   btRigidBody *body = object->body;
539   body->setAngularFactor(btVector3(x, y, z));
540 }
541
542 /* ............ */
543
544 void RB_body_set_kinematic_state(rbRigidBody *object, int kinematic)
545 {
546   btRigidBody *body = object->body;
547   if (kinematic)
548     body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
549   else
550     body->setCollisionFlags(body->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT);
551 }
552
553 /* ............ */
554
555 void RB_body_set_activation_state(rbRigidBody *object, int use_deactivation)
556 {
557   btRigidBody *body = object->body;
558   if (use_deactivation)
559     body->forceActivationState(ACTIVE_TAG);
560   else
561     body->setActivationState(DISABLE_DEACTIVATION);
562 }
563 void RB_body_activate(rbRigidBody *object)
564 {
565   btRigidBody *body = object->body;
566   body->setActivationState(ACTIVE_TAG);
567 }
568 void RB_body_deactivate(rbRigidBody *object)
569 {
570   btRigidBody *body = object->body;
571   body->setActivationState(ISLAND_SLEEPING);
572 }
573
574 /* ............ */
575
576 /* Simulation ----------------------- */
577
578 /* The transform matrices Blender uses are OpenGL-style matrices,
579  * while Bullet uses the Right-Handed coordinate system style instead.
580  */
581
582 void RB_body_get_transform_matrix(rbRigidBody *object, float m_out[4][4])
583 {
584   btRigidBody *body = object->body;
585   btMotionState *ms = body->getMotionState();
586
587   btTransform trans;
588   ms->getWorldTransform(trans);
589
590   trans.getOpenGLMatrix((btScalar *)m_out);
591 }
592
593 void RB_body_set_loc_rot(rbRigidBody *object, const float loc[3], const float rot[4])
594 {
595   btRigidBody *body = object->body;
596   btMotionState *ms = body->getMotionState();
597
598   /* set transform matrix */
599   btTransform trans;
600   trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
601   trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
602
603   ms->setWorldTransform(trans);
604 }
605
606 void RB_body_set_scale(rbRigidBody *object, const float scale[3])
607 {
608   btRigidBody *body = object->body;
609
610   /* apply scaling factor from matrix above to the collision shape */
611   btCollisionShape *cshape = body->getCollisionShape();
612   if (cshape) {
613     cshape->setLocalScaling(btVector3(scale[0], scale[1], scale[2]));
614
615     /* GIimpact shapes have to be updated to take scaling into account */
616     if (cshape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
617       ((btGImpactMeshShape *)cshape)->updateBound();
618   }
619 }
620
621 /* ............ */
622 /* Read-only state info about status of simulation */
623
624 void RB_body_get_position(rbRigidBody *object, float v_out[3])
625 {
626   btRigidBody *body = object->body;
627
628   copy_v3_btvec3(v_out, body->getWorldTransform().getOrigin());
629 }
630
631 void RB_body_get_orientation(rbRigidBody *object, float v_out[4])
632 {
633   btRigidBody *body = object->body;
634
635   copy_quat_btquat(v_out, body->getWorldTransform().getRotation());
636 }
637
638 /* ............ */
639 /* Overrides for simulation */
640
641 void RB_body_apply_central_force(rbRigidBody *object, const float v_in[3])
642 {
643   btRigidBody *body = object->body;
644
645   body->applyCentralForce(btVector3(v_in[0], v_in[1], v_in[2]));
646 }
647
648 /* ********************************** */
649 /* Collision Shape Methods */
650
651 /* Setup (Standard Shapes) ----------- */
652
653 rbCollisionShape *RB_shape_new_box(float x, float y, float z)
654 {
655   rbCollisionShape *shape = new rbCollisionShape;
656   shape->cshape = new btBoxShape(btVector3(x, y, z));
657   shape->mesh = NULL;
658   return shape;
659 }
660
661 rbCollisionShape *RB_shape_new_sphere(float radius)
662 {
663   rbCollisionShape *shape = new rbCollisionShape;
664   shape->cshape = new btSphereShape(radius);
665   shape->mesh = NULL;
666   return shape;
667 }
668
669 rbCollisionShape *RB_shape_new_capsule(float radius, float height)
670 {
671   rbCollisionShape *shape = new rbCollisionShape;
672   shape->cshape = new btCapsuleShapeZ(radius, height);
673   shape->mesh = NULL;
674   return shape;
675 }
676
677 rbCollisionShape *RB_shape_new_cone(float radius, float height)
678 {
679   rbCollisionShape *shape = new rbCollisionShape;
680   shape->cshape = new btConeShapeZ(radius, height);
681   shape->mesh = NULL;
682   return shape;
683 }
684
685 rbCollisionShape *RB_shape_new_cylinder(float radius, float height)
686 {
687   rbCollisionShape *shape = new rbCollisionShape;
688   shape->cshape = new btCylinderShapeZ(btVector3(radius, radius, height));
689   shape->mesh = NULL;
690   return shape;
691 }
692
693 /* Setup (Convex Hull) ------------ */
694
695 rbCollisionShape *RB_shape_new_convex_hull(
696     float *verts, int stride, int count, float margin, bool *can_embed)
697 {
698   btConvexHullComputer hull_computer = btConvexHullComputer();
699
700   // try to embed the margin, if that fails don't shrink the hull
701   if (hull_computer.compute(verts, stride, count, margin, 0.0f) < 0.0f) {
702     hull_computer.compute(verts, stride, count, 0.0f, 0.0f);
703     *can_embed = false;
704   }
705
706   rbCollisionShape *shape = new rbCollisionShape;
707   btConvexHullShape *hull_shape = new btConvexHullShape(&(hull_computer.vertices[0].getX()),
708                                                         hull_computer.vertices.size());
709
710   shape->cshape = hull_shape;
711   shape->mesh = NULL;
712   return shape;
713 }
714
715 /* Setup (Triangle Mesh) ---------- */
716
717 /* Need to call RB_trimesh_finish() after creating triangle mesh and adding vertices and triangles
718  */
719
720 rbMeshData *RB_trimesh_data_new(int num_tris, int num_verts)
721 {
722   rbMeshData *mesh = new rbMeshData;
723   mesh->vertices = new rbVert[num_verts];
724   mesh->triangles = new rbTri[num_tris];
725   mesh->num_vertices = num_verts;
726   mesh->num_triangles = num_tris;
727
728   return mesh;
729 }
730
731 static void RB_trimesh_data_delete(rbMeshData *mesh)
732 {
733   delete mesh->index_array;
734   delete[] mesh->vertices;
735   delete[] mesh->triangles;
736   delete mesh;
737 }
738
739 void RB_trimesh_add_vertices(rbMeshData *mesh, float *vertices, int num_verts, int vert_stride)
740 {
741   for (int i = 0; i < num_verts; i++) {
742     float *vert = (float *)(((char *)vertices + i * vert_stride));
743     mesh->vertices[i].x = vert[0];
744     mesh->vertices[i].y = vert[1];
745     mesh->vertices[i].z = vert[2];
746   }
747 }
748 void RB_trimesh_add_triangle_indices(rbMeshData *mesh, int num, int index0, int index1, int index2)
749 {
750   mesh->triangles[num].v0 = index0;
751   mesh->triangles[num].v1 = index1;
752   mesh->triangles[num].v2 = index2;
753 }
754
755 void RB_trimesh_finish(rbMeshData *mesh)
756 {
757   mesh->index_array = new btTriangleIndexVertexArray(mesh->num_triangles,
758                                                      (int *)mesh->triangles,
759                                                      sizeof(rbTri),
760                                                      mesh->num_vertices,
761                                                      (float *)mesh->vertices,
762                                                      sizeof(rbVert));
763 }
764
765 rbCollisionShape *RB_shape_new_trimesh(rbMeshData *mesh)
766 {
767   rbCollisionShape *shape = new rbCollisionShape;
768
769   /* triangle-mesh we create is a BVH wrapper for triangle mesh data (for faster lookups) */
770   // RB_TODO perhaps we need to allow saving out this for performance when rebuilding?
771   btBvhTriangleMeshShape *unscaledShape = new btBvhTriangleMeshShape(
772       mesh->index_array, true, true);
773
774   shape->cshape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f));
775   shape->mesh = mesh;
776   return shape;
777 }
778
779 void RB_shape_trimesh_update(rbCollisionShape *shape,
780                              float *vertices,
781                              int num_verts,
782                              int vert_stride,
783                              float min[3],
784                              float max[3])
785 {
786   if (shape->mesh == NULL || num_verts != shape->mesh->num_vertices)
787     return;
788
789   for (int i = 0; i < num_verts; i++) {
790     float *vert = (float *)(((char *)vertices + i * vert_stride));
791     shape->mesh->vertices[i].x = vert[0];
792     shape->mesh->vertices[i].y = vert[1];
793     shape->mesh->vertices[i].z = vert[2];
794   }
795
796   if (shape->cshape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
797     btScaledBvhTriangleMeshShape *scaled_shape = (btScaledBvhTriangleMeshShape *)shape->cshape;
798     btBvhTriangleMeshShape *mesh_shape = scaled_shape->getChildShape();
799     mesh_shape->refitTree(btVector3(min[0], min[1], min[2]), btVector3(max[0], max[1], max[2]));
800   }
801   else if (shape->cshape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) {
802     btGImpactMeshShape *mesh_shape = (btGImpactMeshShape *)shape->cshape;
803     mesh_shape->updateBound();
804   }
805 }
806
807 rbCollisionShape *RB_shape_new_gimpact_mesh(rbMeshData *mesh)
808 {
809   rbCollisionShape *shape = new rbCollisionShape;
810
811   btGImpactMeshShape *gimpactShape = new btGImpactMeshShape(mesh->index_array);
812   gimpactShape->updateBound();  // TODO: add this to the update collision margin call?
813
814   shape->cshape = gimpactShape;
815   shape->mesh = mesh;
816   return shape;
817 }
818
819 /* Cleanup --------------------------- */
820
821 void RB_shape_delete(rbCollisionShape *shape)
822 {
823   if (shape->cshape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
824     btBvhTriangleMeshShape *child_shape =
825         ((btScaledBvhTriangleMeshShape *)shape->cshape)->getChildShape();
826     if (child_shape)
827       delete child_shape;
828   }
829   if (shape->mesh)
830     RB_trimesh_data_delete(shape->mesh);
831   delete shape->cshape;
832   delete shape;
833 }
834
835 /* Settings --------------------------- */
836
837 float RB_shape_get_margin(rbCollisionShape *shape)
838 {
839   return shape->cshape->getMargin();
840 }
841
842 void RB_shape_set_margin(rbCollisionShape *shape, float value)
843 {
844   shape->cshape->setMargin(value);
845 }
846
847 /* ********************************** */
848 /* Constraints */
849
850 /* Setup ----------------------------- */
851
852 void RB_dworld_add_constraint(rbDynamicsWorld *world, rbConstraint *con, int disable_collisions)
853 {
854   btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
855
856   world->dynamicsWorld->addConstraint(constraint, disable_collisions);
857 }
858
859 void RB_dworld_remove_constraint(rbDynamicsWorld *world, rbConstraint *con)
860 {
861   btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
862
863   world->dynamicsWorld->removeConstraint(constraint);
864 }
865
866 /* ............ */
867
868 static void make_constraint_transforms(btTransform &transform1,
869                                        btTransform &transform2,
870                                        btRigidBody *body1,
871                                        btRigidBody *body2,
872                                        float pivot[3],
873                                        float orn[4])
874 {
875   btTransform pivot_transform = btTransform();
876   pivot_transform.setOrigin(btVector3(pivot[0], pivot[1], pivot[2]));
877   pivot_transform.setRotation(btQuaternion(orn[1], orn[2], orn[3], orn[0]));
878
879   transform1 = body1->getWorldTransform().inverse() * pivot_transform;
880   transform2 = body2->getWorldTransform().inverse() * pivot_transform;
881 }
882
883 rbConstraint *RB_constraint_new_point(float pivot[3], rbRigidBody *rb1, rbRigidBody *rb2)
884 {
885   btRigidBody *body1 = rb1->body;
886   btRigidBody *body2 = rb2->body;
887
888   btVector3 pivot1 = body1->getWorldTransform().inverse() *
889                      btVector3(pivot[0], pivot[1], pivot[2]);
890   btVector3 pivot2 = body2->getWorldTransform().inverse() *
891                      btVector3(pivot[0], pivot[1], pivot[2]);
892
893   btTypedConstraint *con = new btPoint2PointConstraint(*body1, *body2, pivot1, pivot2);
894
895   return (rbConstraint *)con;
896 }
897
898 rbConstraint *RB_constraint_new_fixed(float pivot[3],
899                                       float orn[4],
900                                       rbRigidBody *rb1,
901                                       rbRigidBody *rb2)
902 {
903   btRigidBody *body1 = rb1->body;
904   btRigidBody *body2 = rb2->body;
905   btTransform transform1;
906   btTransform transform2;
907
908   make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
909
910   btFixedConstraint *con = new btFixedConstraint(*body1, *body2, transform1, transform2);
911
912   return (rbConstraint *)con;
913 }
914
915 rbConstraint *RB_constraint_new_hinge(float pivot[3],
916                                       float orn[4],
917                                       rbRigidBody *rb1,
918                                       rbRigidBody *rb2)
919 {
920   btRigidBody *body1 = rb1->body;
921   btRigidBody *body2 = rb2->body;
922   btTransform transform1;
923   btTransform transform2;
924
925   make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
926
927   btHingeConstraint *con = new btHingeConstraint(*body1, *body2, transform1, transform2);
928
929   return (rbConstraint *)con;
930 }
931
932 rbConstraint *RB_constraint_new_slider(float pivot[3],
933                                        float orn[4],
934                                        rbRigidBody *rb1,
935                                        rbRigidBody *rb2)
936 {
937   btRigidBody *body1 = rb1->body;
938   btRigidBody *body2 = rb2->body;
939   btTransform transform1;
940   btTransform transform2;
941
942   make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
943
944   btSliderConstraint *con = new btSliderConstraint(*body1, *body2, transform1, transform2, true);
945
946   return (rbConstraint *)con;
947 }
948
949 rbConstraint *RB_constraint_new_piston(float pivot[3],
950                                        float orn[4],
951                                        rbRigidBody *rb1,
952                                        rbRigidBody *rb2)
953 {
954   btRigidBody *body1 = rb1->body;
955   btRigidBody *body2 = rb2->body;
956   btTransform transform1;
957   btTransform transform2;
958
959   make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
960
961   btSliderConstraint *con = new btSliderConstraint(*body1, *body2, transform1, transform2, true);
962   con->setUpperAngLimit(-1.0f);  // unlock rotation axis
963
964   return (rbConstraint *)con;
965 }
966
967 rbConstraint *RB_constraint_new_6dof(float pivot[3],
968                                      float orn[4],
969                                      rbRigidBody *rb1,
970                                      rbRigidBody *rb2)
971 {
972   btRigidBody *body1 = rb1->body;
973   btRigidBody *body2 = rb2->body;
974   btTransform transform1;
975   btTransform transform2;
976
977   make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
978
979   btTypedConstraint *con = new btGeneric6DofConstraint(
980       *body1, *body2, transform1, transform2, true);
981
982   return (rbConstraint *)con;
983 }
984
985 rbConstraint *RB_constraint_new_6dof_spring(float pivot[3],
986                                             float orn[4],
987                                             rbRigidBody *rb1,
988                                             rbRigidBody *rb2)
989 {
990   btRigidBody *body1 = rb1->body;
991   btRigidBody *body2 = rb2->body;
992   btTransform transform1;
993   btTransform transform2;
994
995   make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
996
997   btTypedConstraint *con = new btGeneric6DofSpringConstraint(
998       *body1, *body2, transform1, transform2, true);
999
1000   return (rbConstraint *)con;
1001 }
1002
1003 rbConstraint *RB_constraint_new_6dof_spring2(float pivot[3],
1004                                              float orn[4],
1005                                              rbRigidBody *rb1,
1006                                              rbRigidBody *rb2)
1007 {
1008   btRigidBody *body1 = rb1->body;
1009   btRigidBody *body2 = rb2->body;
1010   btTransform transform1;
1011   btTransform transform2;
1012
1013   make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
1014
1015   btTypedConstraint *con = new btGeneric6DofSpring2Constraint(
1016       *body1, *body2, transform1, transform2);
1017
1018   return (rbConstraint *)con;
1019 }
1020
1021 rbConstraint *RB_constraint_new_motor(float pivot[3],
1022                                       float orn[4],
1023                                       rbRigidBody *rb1,
1024                                       rbRigidBody *rb2)
1025 {
1026   btRigidBody *body1 = rb1->body;
1027   btRigidBody *body2 = rb2->body;
1028   btTransform transform1;
1029   btTransform transform2;
1030
1031   make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
1032
1033   btGeneric6DofConstraint *con = new btGeneric6DofConstraint(
1034       *body1, *body2, transform1, transform2, true);
1035
1036   /* unlock constraint axes */
1037   for (int i = 0; i < 6; i++) {
1038     con->setLimit(i, 0.0f, -1.0f);
1039   }
1040   /* unlock motor axes */
1041   con->getTranslationalLimitMotor()->m_upperLimit.setValue(-1.0f, -1.0f, -1.0f);
1042
1043   return (rbConstraint *)con;
1044 }
1045
1046 /* Cleanup ----------------------------- */
1047
1048 void RB_constraint_delete(rbConstraint *con)
1049 {
1050   btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
1051   delete constraint;
1052 }
1053
1054 /* Settings ------------------------- */
1055
1056 void RB_constraint_set_enabled(rbConstraint *con, int enabled)
1057 {
1058   btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
1059
1060   constraint->setEnabled(enabled);
1061 }
1062
1063 void RB_constraint_set_limits_hinge(rbConstraint *con, float lower, float upper)
1064 {
1065   btHingeConstraint *constraint = reinterpret_cast<btHingeConstraint *>(con);
1066
1067   // RB_TODO expose these
1068   float softness = 0.9f;
1069   float bias_factor = 0.3f;
1070   float relaxation_factor = 1.0f;
1071
1072   constraint->setLimit(lower, upper, softness, bias_factor, relaxation_factor);
1073 }
1074
1075 void RB_constraint_set_limits_slider(rbConstraint *con, float lower, float upper)
1076 {
1077   btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint *>(con);
1078
1079   constraint->setLowerLinLimit(lower);
1080   constraint->setUpperLinLimit(upper);
1081 }
1082
1083 void RB_constraint_set_limits_piston(
1084     rbConstraint *con, float lin_lower, float lin_upper, float ang_lower, float ang_upper)
1085 {
1086   btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint *>(con);
1087
1088   constraint->setLowerLinLimit(lin_lower);
1089   constraint->setUpperLinLimit(lin_upper);
1090   constraint->setLowerAngLimit(ang_lower);
1091   constraint->setUpperAngLimit(ang_upper);
1092 }
1093
1094 void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, float upper)
1095 {
1096   btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint *>(con);
1097
1098   constraint->setLimit(axis, lower, upper);
1099 }
1100
1101 void RB_constraint_set_limits_6dof_spring2(rbConstraint *con, int axis, float lower, float upper)
1102 {
1103   btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
1104       con);
1105
1106   constraint->setLimit(axis, lower, upper);
1107 }
1108
1109 void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness)
1110 {
1111   btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint *>(
1112       con);
1113
1114   constraint->setStiffness(axis, stiffness);
1115 }
1116
1117 void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping)
1118 {
1119   btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint *>(
1120       con);
1121
1122   // invert damping range so that 0 = no damping
1123   damping = (damping > 1.0f) ? 0.0f : 1.0f - damping;
1124
1125   constraint->setDamping(axis, damping);
1126 }
1127
1128 void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable)
1129 {
1130   btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint *>(
1131       con);
1132
1133   constraint->enableSpring(axis, enable);
1134 }
1135
1136 void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con)
1137 {
1138   btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint *>(
1139       con);
1140
1141   constraint->setEquilibriumPoint();
1142 }
1143
1144 void RB_constraint_set_stiffness_6dof_spring2(rbConstraint *con, int axis, float stiffness)
1145 {
1146   btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
1147       con);
1148
1149   constraint->setStiffness(axis, stiffness);
1150 }
1151
1152 void RB_constraint_set_damping_6dof_spring2(rbConstraint *con, int axis, float damping)
1153 {
1154   btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
1155       con);
1156
1157   constraint->setDamping(axis, damping);
1158 }
1159
1160 void RB_constraint_set_spring_6dof_spring2(rbConstraint *con, int axis, int enable)
1161 {
1162   btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
1163       con);
1164
1165   constraint->enableSpring(axis, enable);
1166 }
1167
1168 void RB_constraint_set_equilibrium_6dof_spring2(rbConstraint *con)
1169 {
1170   btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
1171       con);
1172
1173   constraint->setEquilibriumPoint();
1174 }
1175
1176 void RB_constraint_set_solver_iterations(rbConstraint *con, int num_solver_iterations)
1177 {
1178   btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
1179
1180   constraint->setOverrideNumSolverIterations(num_solver_iterations);
1181 }
1182
1183 void RB_constraint_set_breaking_threshold(rbConstraint *con, float threshold)
1184 {
1185   btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
1186
1187   constraint->setBreakingImpulseThreshold(threshold);
1188 }
1189
1190 void RB_constraint_set_enable_motor(rbConstraint *con, int enable_lin, int enable_ang)
1191 {
1192   btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint *>(con);
1193
1194   constraint->getTranslationalLimitMotor()->m_enableMotor[0] = enable_lin;
1195   constraint->getRotationalLimitMotor(0)->m_enableMotor = enable_ang;
1196 }
1197
1198 void RB_constraint_set_max_impulse_motor(rbConstraint *con,
1199                                          float max_impulse_lin,
1200                                          float max_impulse_ang)
1201 {
1202   btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint *>(con);
1203
1204   constraint->getTranslationalLimitMotor()->m_maxMotorForce.setX(max_impulse_lin);
1205   constraint->getRotationalLimitMotor(0)->m_maxMotorForce = max_impulse_ang;
1206 }
1207
1208 void RB_constraint_set_target_velocity_motor(rbConstraint *con,
1209                                              float velocity_lin,
1210                                              float velocity_ang)
1211 {
1212   btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint *>(con);
1213
1214   constraint->getTranslationalLimitMotor()->m_targetVelocity.setX(velocity_lin);
1215   constraint->getRotationalLimitMotor(0)->m_targetVelocity = velocity_ang;
1216 }
1217
1218 /* ********************************** */