style cleanup
[blender.git] / source / blender / rigidbody / rb_bullet_api.cpp
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 rb_bullet_api.cpp
29  *  \ingroup RigidBody
30  *  \brief Rigid Body API implementation for Bullet
31  */
32
33 /*
34 Bullet Continuous Collision Detection and Physics Library
35 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
36
37 This software is provided 'as-is', without any express or implied warranty.
38 In no event will the authors be held liable for any damages arising from the use of this software.
39 Permission is granted to anyone to use this software for any purpose, 
40 including commercial applications, and to alter it and redistribute it freely, 
41 subject to the following restrictions:
42
43 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
44 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
45 3. This notice may not be removed or altered from any source distribution.
46 */
47  
48 /* This file defines the "RigidBody interface" for the 
49  * Bullet Physics Engine. This API is designed to be used
50  * from C-code in Blender as part of the Rigid Body simulation
51  * system.
52  *
53  * It is based on the Bullet C-API, but is heavily modified to 
54  * give access to more data types and to offer a nicer interface.
55  *
56  * -- Joshua Leung, June 2010
57  */
58
59 #include <stdio.h>
60  
61 #include "RBI_api.h"
62
63 #include "BLI_math.h"
64
65 #include "btBulletDynamicsCommon.h"
66
67 #include "LinearMath/btVector3.h"
68 #include "LinearMath/btScalar.h"        
69 #include "LinearMath/btMatrix3x3.h"
70 #include "LinearMath/btTransform.h"
71 #include "LinearMath/btConvexHullComputer.h"
72
73 #include "BulletCollision/Gimpact/btGImpactShape.h"
74 #include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"
75 #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
76
77 struct rbDynamicsWorld {
78         btDiscreteDynamicsWorld *dynamicsWorld;
79         btDefaultCollisionConfiguration *collisionConfiguration;
80         btDispatcher *dispatcher;
81         btBroadphaseInterface *pairCache;
82         btConstraintSolver *constraintSolver;
83         btOverlapFilterCallback *filterCallback;
84 };
85 struct rbRigidBody {
86         btRigidBody *body;
87         int col_groups;
88 };
89
90 struct rbCollisionShape {
91         btCollisionShape *cshape;
92         btTriangleMesh *mesh;
93 };
94
95 struct rbFilterCallback : public btOverlapFilterCallback
96 {
97         virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
98         {
99                 rbRigidBody *rb0 = (rbRigidBody *)((btRigidBody *)proxy0->m_clientObject)->getUserPointer();
100                 rbRigidBody *rb1 = (rbRigidBody *)((btRigidBody *)proxy1->m_clientObject)->getUserPointer();
101                 
102                 bool collides;
103                 collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
104                 collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
105                 collides = collides && (rb0->col_groups & rb1->col_groups);
106                 
107                 return collides;
108         }
109 };
110
111 static inline void copy_v3_btvec3(float vec[3], const btVector3 &btvec)
112 {
113         vec[0] = (float)btvec[0];
114         vec[1] = (float)btvec[1];
115         vec[2] = (float)btvec[2];
116 }
117 static inline void copy_quat_btquat(float quat[3], const btQuaternion &btquat)
118 {
119         quat[0] = btquat.getW();
120         quat[1] = btquat.getX();
121         quat[2] = btquat.getY();
122         quat[3] = btquat.getZ();
123 }
124
125 /* ********************************** */
126 /* Dynamics World Methods */
127
128 /* Setup ---------------------------- */
129
130 rbDynamicsWorld *RB_dworld_new(const float gravity[3])
131 {
132         rbDynamicsWorld *world = new rbDynamicsWorld;
133         
134         /* collision detection/handling */
135         world->collisionConfiguration = new btDefaultCollisionConfiguration();
136         
137         world->dispatcher = new btCollisionDispatcher(world->collisionConfiguration);
138         btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher *)world->dispatcher); // XXX: experimental
139         
140         world->pairCache = new btDbvtBroadphase();
141         
142         world->filterCallback = new rbFilterCallback();
143         world->pairCache->getOverlappingPairCache()->setOverlapFilterCallback(world->filterCallback);
144
145         /* constraint solving */
146         world->constraintSolver = new btSequentialImpulseConstraintSolver();
147
148         /* world */
149         world->dynamicsWorld = new btDiscreteDynamicsWorld(world->dispatcher,
150                                                            world->pairCache,
151                                                            world->constraintSolver,
152                                                            world->collisionConfiguration);
153
154         RB_dworld_set_gravity(world, gravity);
155         
156         return world;
157 }
158
159 void RB_dworld_delete(rbDynamicsWorld *world)
160 {
161         /* bullet doesn't like if we free these in a different order */
162         delete world->dynamicsWorld;
163         delete world->constraintSolver;
164         delete world->pairCache;
165         delete world->dispatcher;
166         delete world->collisionConfiguration;
167         delete world->filterCallback;
168         delete world;
169 }
170
171 /* Settings ------------------------- */
172
173 /* Gravity */
174 void RB_dworld_get_gravity(rbDynamicsWorld *world, float g_out[3])
175 {
176         copy_v3_btvec3(g_out, world->dynamicsWorld->getGravity());
177 }
178
179 void RB_dworld_set_gravity(rbDynamicsWorld *world, const float g_in[3])
180 {
181         world->dynamicsWorld->setGravity(btVector3(g_in[0], g_in[1], g_in[2]));
182 }
183
184 /* Constraint Solver */
185 void RB_dworld_set_solver_iterations(rbDynamicsWorld *world, int num_solver_iterations)
186 {
187         btContactSolverInfo& info = world->dynamicsWorld->getSolverInfo();
188         
189         info.m_numIterations = num_solver_iterations;
190 }
191
192 /* Split Impulse */
193 void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse)
194 {
195         btContactSolverInfo& info = world->dynamicsWorld->getSolverInfo();
196         
197         info.m_splitImpulse = split_impulse;
198 }
199
200 /* Simulation ----------------------- */
201
202 void RB_dworld_step_simulation(rbDynamicsWorld *world, float timeStep, int maxSubSteps, float timeSubStep)
203 {
204         world->dynamicsWorld->stepSimulation(timeStep, maxSubSteps, timeSubStep);
205 }
206
207 /* Export -------------------------- */
208
209 /* Exports entire dynamics world to Bullet's "*.bullet" binary format
210  * which is similar to Blender's SDNA system...
211  * < rbDynamicsWorld: dynamics world to write to file
212  * < filename: assumed to be a valid filename, with .bullet extension 
213  */
214 void RB_dworld_export(rbDynamicsWorld *world, const char *filename)
215 {
216         //create a large enough buffer. There is no method to pre-calculate the buffer size yet.
217         int maxSerializeBufferSize = 1024 * 1024 * 5;
218         
219         btDefaultSerializer *serializer = new btDefaultSerializer(maxSerializeBufferSize);
220         world->dynamicsWorld->serialize(serializer);
221         
222         FILE *file = fopen(filename, "wb");
223         fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file);
224         fclose(file);
225 }
226
227 /* ********************************** */
228 /* Rigid Body Methods */
229
230 /* Setup ---------------------------- */
231
232 void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *object, int col_groups)
233 {
234         btRigidBody *body = object->body;
235         object->col_groups = col_groups;
236         
237         world->dynamicsWorld->addRigidBody(body);
238 }
239
240 void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *object)
241 {
242         btRigidBody *body = object->body;
243         
244         world->dynamicsWorld->removeRigidBody(body);
245 }
246
247 /* ............ */
248
249 rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4])
250 {
251         rbRigidBody *object = new rbRigidBody;
252         /* current transform */
253         btTransform trans;
254         trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
255         trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
256         
257         /* create motionstate, which is necessary for interpolation (includes reverse playback) */
258         btDefaultMotionState *motionState = new btDefaultMotionState(trans);
259         
260         /* make rigidbody */
261         btRigidBody::btRigidBodyConstructionInfo rbInfo(1.0f, motionState, shape->cshape);
262         
263         object->body = new btRigidBody(rbInfo);
264         
265         object->body->setUserPointer(object);
266         
267         return object;
268 }
269
270 void RB_body_delete(rbRigidBody *object)
271 {
272         btRigidBody *body = object->body;
273         
274         /* motion state */
275         btMotionState *ms = body->getMotionState();
276         if (ms)
277                 delete ms;
278         
279         /* collision shape is done elsewhere... */
280         
281         /* body itself */
282         
283         /* manually remove constraint refs of the rigid body, normally this happens when removing constraints from the world
284          * but since we delete everything when the world is rebult, we need to do it manually here */
285         for (int i = body->getNumConstraintRefs() - 1; i >= 0; i--) {
286                 btTypedConstraint *con = body->getConstraintRef(i);
287                 body->removeConstraintRef(con);
288         }
289         
290         delete body;
291         delete object;
292 }
293
294 /* Settings ------------------------- */
295
296 void RB_body_set_collision_shape(rbRigidBody *object, rbCollisionShape *shape)
297 {
298         btRigidBody *body = object->body;
299         
300         /* set new collision shape */
301         body->setCollisionShape(shape->cshape);
302         
303         /* recalculate inertia, since that depends on the collision shape... */
304         RB_body_set_mass(object, RB_body_get_mass(object));
305 }
306
307 /* ............ */
308
309 float RB_body_get_mass(rbRigidBody *object)
310 {
311         btRigidBody *body = object->body;
312         
313         /* there isn't really a mass setting, but rather 'inverse mass'  
314          * which we convert back to mass by taking the reciprocal again 
315          */
316         float value = (float)body->getInvMass();
317         
318         if (value)
319                 value = 1.0 / value;
320                 
321         return value;
322 }
323
324 void RB_body_set_mass(rbRigidBody *object, float value)
325 {
326         btRigidBody *body = object->body;
327         btVector3 localInertia(0, 0, 0);
328         
329         /* calculate new inertia if non-zero mass */
330         if (value) {
331                 btCollisionShape *shape = body->getCollisionShape();
332                 shape->calculateLocalInertia(value, localInertia);
333         }
334         
335         body->setMassProps(value, localInertia);
336         body->updateInertiaTensor();
337 }
338
339
340 float RB_body_get_friction(rbRigidBody *object)
341 {
342         btRigidBody *body = object->body;
343         return body->getFriction();
344 }
345
346 void RB_body_set_friction(rbRigidBody *object, float value)
347 {
348         btRigidBody *body = object->body;
349         body->setFriction(value);
350 }
351
352
353 float RB_body_get_restitution(rbRigidBody *object)
354 {
355         btRigidBody *body = object->body;
356         return body->getRestitution();
357 }
358
359 void RB_body_set_restitution(rbRigidBody *object, float value)
360 {
361         btRigidBody *body = object->body;
362         body->setRestitution(value);
363 }
364
365
366 float RB_body_get_linear_damping(rbRigidBody *object)
367 {
368         btRigidBody *body = object->body;
369         return body->getLinearDamping();
370 }
371
372 void RB_body_set_linear_damping(rbRigidBody *object, float value)
373 {
374         RB_body_set_damping(object, value, RB_body_get_linear_damping(object));
375 }
376
377 float RB_body_get_angular_damping(rbRigidBody *object)
378 {
379         btRigidBody *body = object->body;
380         return body->getAngularDamping();
381 }
382
383 void RB_body_set_angular_damping(rbRigidBody *object, float value)
384 {
385         RB_body_set_damping(object, RB_body_get_linear_damping(object), value);
386 }
387
388 void RB_body_set_damping(rbRigidBody *object, float linear, float angular)
389 {
390         btRigidBody *body = object->body;
391         body->setDamping(linear, angular);
392 }
393
394
395 float RB_body_get_linear_sleep_thresh(rbRigidBody *object)
396 {
397         btRigidBody *body = object->body;
398         return body->getLinearSleepingThreshold();
399 }
400
401 void RB_body_set_linear_sleep_thresh(rbRigidBody *object, float value)
402 {
403         RB_body_set_sleep_thresh(object, value, RB_body_get_angular_sleep_thresh(object));
404 }
405
406 float RB_body_get_angular_sleep_thresh(rbRigidBody *object)
407 {
408         btRigidBody *body = object->body;
409         return body->getAngularSleepingThreshold();
410 }
411
412 void RB_body_set_angular_sleep_thresh(rbRigidBody *object, float value)
413 {
414         RB_body_set_sleep_thresh(object, RB_body_get_linear_sleep_thresh(object), value);
415 }
416
417 void RB_body_set_sleep_thresh(rbRigidBody *object, float linear, float angular)
418 {
419         btRigidBody *body = object->body;
420         body->setSleepingThresholds(linear, angular);
421 }
422
423 /* ............ */
424
425 void RB_body_get_linear_velocity(rbRigidBody *object, float v_out[3])
426 {
427         btRigidBody *body = object->body;
428         
429         copy_v3_btvec3(v_out, body->getLinearVelocity());
430 }
431
432 void RB_body_set_linear_velocity(rbRigidBody *object, const float v_in[3])
433 {
434         btRigidBody *body = object->body;
435         
436         body->setLinearVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
437 }
438
439
440 void RB_body_get_angular_velocity(rbRigidBody *object, float v_out[3])
441 {
442         btRigidBody *body = object->body;
443         
444         copy_v3_btvec3(v_out, body->getAngularVelocity());
445 }
446
447 void RB_body_set_angular_velocity(rbRigidBody *object, const float v_in[3])
448 {
449         btRigidBody *body = object->body;
450         
451         body->setAngularVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
452 }
453
454 void RB_body_set_linear_factor(rbRigidBody *object, float x, float y, float z)
455 {
456         btRigidBody *body = object->body;
457         body->setLinearFactor(btVector3(x, y, z));
458 }
459
460 void RB_body_set_angular_factor(rbRigidBody *object, float x, float y, float z)
461 {
462         btRigidBody *body = object->body;
463         body->setAngularFactor(btVector3(x, y, z));
464 }
465
466 /* ............ */
467
468 void RB_body_set_kinematic_state(rbRigidBody *object, int kinematic)
469 {
470         btRigidBody *body = object->body;
471         if (kinematic)
472                 body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
473         else
474                 body->setCollisionFlags(body->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT);
475 }
476
477 /* ............ */
478
479 void RB_body_set_activation_state(rbRigidBody *object, int use_deactivation)
480 {
481         btRigidBody *body = object->body;
482         if (use_deactivation)
483                 body->forceActivationState(ACTIVE_TAG);
484         else
485                 body->setActivationState(DISABLE_DEACTIVATION);
486 }
487 void RB_body_activate(rbRigidBody *object)
488 {
489         btRigidBody *body = object->body;
490         body->setActivationState(ACTIVE_TAG);
491 }
492 void RB_body_deactivate(rbRigidBody *object)
493 {
494         btRigidBody *body = object->body;
495         body->setActivationState(ISLAND_SLEEPING);
496 }
497
498 /* ............ */
499
500
501
502 /* Simulation ----------------------- */
503
504 /* The transform matrices Blender uses are OpenGL-style matrices, 
505  * while Bullet uses the Right-Handed coordinate system style instead.
506  */
507
508 void RB_body_get_transform_matrix(rbRigidBody *object, float m_out[4][4])
509 {
510         btRigidBody *body = object->body;
511         btMotionState *ms = body->getMotionState();
512         
513         btTransform trans;
514         ms->getWorldTransform(trans);
515         
516         trans.getOpenGLMatrix((btScalar *)m_out);
517 }
518
519 void RB_body_set_loc_rot(rbRigidBody *object, const float loc[3], const float rot[4])
520 {
521         btRigidBody *body = object->body;
522         btMotionState *ms = body->getMotionState();
523         
524         /* set transform matrix */
525         btTransform trans;
526         trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
527         trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
528         
529         ms->setWorldTransform(trans);
530 }
531
532 void RB_body_set_scale(rbRigidBody *object, const float scale[3])
533 {
534         btRigidBody *body = object->body;
535         
536         /* apply scaling factor from matrix above to the collision shape */
537         btCollisionShape *cshape = body->getCollisionShape();
538         if (cshape) {
539                 cshape->setLocalScaling(btVector3(scale[0], scale[1], scale[2]));
540                 
541                 /* GIimpact shapes have to be updated to take scaling into account */
542                 if (cshape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
543                         ((btGImpactMeshShape *)cshape)->updateBound();
544         }
545 }
546
547 /* ............ */
548 /* Read-only state info about status of simulation */
549
550 void RB_body_get_position(rbRigidBody *object, float v_out[3])
551 {
552         btRigidBody *body = object->body;
553         
554         copy_v3_btvec3(v_out, body->getWorldTransform().getOrigin());
555 }
556
557 void RB_body_get_orientation(rbRigidBody *object, float v_out[4])
558 {
559         btRigidBody *body = object->body;
560         
561         copy_quat_btquat(v_out, body->getWorldTransform().getRotation());
562 }
563
564 /* ............ */
565 /* Overrides for simulation */
566
567 void RB_body_apply_central_force(rbRigidBody *object, const float v_in[3])
568 {
569         btRigidBody *body = object->body;
570         
571         body->applyCentralForce(btVector3(v_in[0], v_in[1], v_in[2]));
572 }
573
574 /* ********************************** */
575 /* Collision Shape Methods */
576
577 /* Setup (Standard Shapes) ----------- */
578
579 rbCollisionShape *RB_shape_new_box(float x, float y, float z)
580 {
581         rbCollisionShape *shape = new rbCollisionShape;
582         shape->cshape = new btBoxShape(btVector3(x, y, z));
583         shape->mesh = NULL;
584         return shape;
585 }
586
587 rbCollisionShape *RB_shape_new_sphere(float radius)
588 {
589         rbCollisionShape *shape = new rbCollisionShape;
590         shape->cshape = new btSphereShape(radius);
591         shape->mesh = NULL;
592         return shape;
593 }
594
595 rbCollisionShape *RB_shape_new_capsule(float radius, float height)
596 {
597         rbCollisionShape *shape = new rbCollisionShape;
598         shape->cshape = new btCapsuleShapeZ(radius, height);
599         shape->mesh = NULL;
600         return shape;
601 }
602
603 rbCollisionShape *RB_shape_new_cone(float radius, float height)
604 {
605         rbCollisionShape *shape = new rbCollisionShape;
606         shape->cshape = new btConeShapeZ(radius, height);
607         shape->mesh = NULL;
608         return shape;
609 }
610
611 rbCollisionShape *RB_shape_new_cylinder(float radius, float height)
612 {
613         rbCollisionShape *shape = new rbCollisionShape;
614         shape->cshape = new btCylinderShapeZ(btVector3(radius, radius, height));
615         shape->mesh = NULL;
616         return shape;
617 }
618
619 /* Setup (Convex Hull) ------------ */
620
621 rbCollisionShape *RB_shape_new_convex_hull(float *verts, int stride, int count, float margin, bool *can_embed)
622 {
623         btConvexHullComputer hull_computer = btConvexHullComputer();
624         
625         // try to embed the margin, if that fails don't shrink the hull
626         if (hull_computer.compute(verts, stride, count, margin, 0.0f) < 0.0f) {
627                 hull_computer.compute(verts, stride, count, 0.0f, 0.0f);
628                 *can_embed = false;
629         }
630         
631         rbCollisionShape *shape = new rbCollisionShape;
632         btConvexHullShape *hull_shape = new btConvexHullShape(&(hull_computer.vertices[0].getX()), hull_computer.vertices.size());
633         
634         shape->cshape = hull_shape;
635         shape->mesh = NULL;
636         return shape;
637 }
638
639 /* Setup (Triangle Mesh) ---------- */
640
641 /* Need to call rbTriMeshNewData() followed by rbTriMeshAddTriangle() several times 
642  * to set up the mesh buffer BEFORE calling rbShapeNewTriMesh(). Otherwise,
643  * we get nasty crashes...
644  */
645
646 rbMeshData *RB_trimesh_data_new()
647 {
648         // XXX: welding threshold?
649         return (rbMeshData *) new btTriangleMesh(true, false);
650 }
651  
652 void RB_trimesh_add_triangle(rbMeshData *mesh, const float v1[3], const float v2[3], const float v3[3])
653 {
654         btTriangleMesh *meshData = reinterpret_cast<btTriangleMesh*>(mesh);
655         
656         /* cast vertices to usable forms for Bt-API */
657         btVector3 vtx1((btScalar)v1[0], (btScalar)v1[1], (btScalar)v1[2]);
658         btVector3 vtx2((btScalar)v2[0], (btScalar)v2[1], (btScalar)v2[2]);
659         btVector3 vtx3((btScalar)v3[0], (btScalar)v3[1], (btScalar)v3[2]);
660         
661         /* add to the mesh 
662          *      - remove duplicated verts is enabled
663          */
664         meshData->addTriangle(vtx1, vtx2, vtx3, false);
665 }
666  
667 rbCollisionShape *RB_shape_new_trimesh(rbMeshData *mesh)
668 {
669         rbCollisionShape *shape = new rbCollisionShape;
670         btTriangleMesh *tmesh = reinterpret_cast<btTriangleMesh*>(mesh);
671         
672         /* triangle-mesh we create is a BVH wrapper for triangle mesh data (for faster lookups) */
673         // RB_TODO perhaps we need to allow saving out this for performance when rebuilding?
674         btBvhTriangleMeshShape *unscaledShape = new btBvhTriangleMeshShape(tmesh, true, true);
675         
676         shape->cshape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f));
677         shape->mesh = tmesh;
678         return shape;
679 }
680
681 rbCollisionShape *RB_shape_new_gimpact_mesh(rbMeshData *mesh)
682 {
683         rbCollisionShape *shape = new rbCollisionShape;
684         /* interpret mesh buffer as btTriangleIndexVertexArray (i.e. an impl of btStridingMeshInterface) */
685         btTriangleMesh *tmesh = reinterpret_cast<btTriangleMesh*>(mesh);
686         
687         btGImpactMeshShape *gimpactShape = new btGImpactMeshShape(tmesh);
688         gimpactShape->updateBound(); // TODO: add this to the update collision margin call?
689         
690         shape->cshape = gimpactShape;
691         shape->mesh = tmesh;
692         return shape;
693 }
694
695 /* Cleanup --------------------------- */
696
697 void RB_shape_delete(rbCollisionShape *shape)
698 {
699         if (shape->cshape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
700                 btBvhTriangleMeshShape *child_shape = ((btScaledBvhTriangleMeshShape *)shape->cshape)->getChildShape();
701                 if (child_shape)
702                         delete child_shape;
703         }
704         if (shape->mesh)
705                 delete shape->mesh;
706         delete shape->cshape;
707         delete shape;
708 }
709
710 /* Settings --------------------------- */
711
712 float RB_shape_get_margin(rbCollisionShape *shape)
713 {
714         return shape->cshape->getMargin();
715 }
716
717 void RB_shape_set_margin(rbCollisionShape *shape, float value)
718 {
719         shape->cshape->setMargin(value);
720 }
721
722 /* ********************************** */
723 /* Constraints */
724
725 /* Setup ----------------------------- */
726
727 void RB_dworld_add_constraint(rbDynamicsWorld *world, rbConstraint *con, int disable_collisions)
728 {
729         btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
730         
731         world->dynamicsWorld->addConstraint(constraint, disable_collisions);
732 }
733
734 void RB_dworld_remove_constraint(rbDynamicsWorld *world, rbConstraint *con)
735 {
736         btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
737         
738         world->dynamicsWorld->removeConstraint(constraint);
739 }
740
741 /* ............ */
742
743 static void make_constraint_transforms(btTransform &transform1, btTransform &transform2, btRigidBody *body1, btRigidBody *body2, float pivot[3], float orn[4])
744 {
745         btTransform pivot_transform = btTransform();
746         pivot_transform.setOrigin(btVector3(pivot[0], pivot[1], pivot[2]));
747         pivot_transform.setRotation(btQuaternion(orn[1], orn[2], orn[3], orn[0]));
748         
749         transform1 = body1->getWorldTransform().inverse() * pivot_transform;
750         transform2 = body2->getWorldTransform().inverse() * pivot_transform;
751 }
752
753 rbConstraint *RB_constraint_new_point(float pivot[3], rbRigidBody *rb1, rbRigidBody *rb2)
754 {
755         btRigidBody *body1 = rb1->body;
756         btRigidBody *body2 = rb2->body;
757         
758         btVector3 pivot1 = body1->getWorldTransform().inverse() * btVector3(pivot[0], pivot[1], pivot[2]);
759         btVector3 pivot2 = body2->getWorldTransform().inverse() * btVector3(pivot[0], pivot[1], pivot[2]);
760         
761         btTypedConstraint *con = new btPoint2PointConstraint(*body1, *body2, pivot1, pivot2);
762         
763         return (rbConstraint *)con;
764 }
765
766 rbConstraint *RB_constraint_new_fixed(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
767 {
768         btRigidBody *body1 = rb1->body;
769         btRigidBody *body2 = rb2->body;
770         btTransform transform1;
771         btTransform transform2;
772         
773         make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
774         
775         btGeneric6DofConstraint *con = new btGeneric6DofConstraint(*body1, *body2, transform1, transform2, true);
776         
777         /* lock all axes */
778         for (int i = 0; i < 6; i++)
779                 con->setLimit(i, 0, 0);
780         
781         return (rbConstraint *)con;
782 }
783
784 rbConstraint *RB_constraint_new_hinge(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
785 {
786         btRigidBody *body1 = rb1->body;
787         btRigidBody *body2 = rb2->body;
788         btTransform transform1;
789         btTransform transform2;
790         
791         make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
792         
793         btHingeConstraint *con = new btHingeConstraint(*body1, *body2, transform1, transform2);
794         
795         return (rbConstraint *)con;
796 }
797
798 rbConstraint *RB_constraint_new_slider(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
799 {
800         btRigidBody *body1 = rb1->body;
801         btRigidBody *body2 = rb2->body;
802         btTransform transform1;
803         btTransform transform2;
804         
805         make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
806         
807         btSliderConstraint *con = new btSliderConstraint(*body1, *body2, transform1, transform2, true);
808         
809         return (rbConstraint *)con;
810 }
811
812 rbConstraint *RB_constraint_new_piston(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
813 {
814         btRigidBody *body1 = rb1->body;
815         btRigidBody *body2 = rb2->body;
816         btTransform transform1;
817         btTransform transform2;
818         
819         make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
820         
821         btSliderConstraint *con = new btSliderConstraint(*body1, *body2, transform1, transform2, true);
822         con->setUpperAngLimit(-1.0f); // unlock rotation axis
823         
824         return (rbConstraint *)con;
825 }
826
827 rbConstraint *RB_constraint_new_6dof(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
828 {
829         btRigidBody *body1 = rb1->body;
830         btRigidBody *body2 = rb2->body;
831         btTransform transform1;
832         btTransform transform2;
833         
834         make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
835         
836         btTypedConstraint *con = new btGeneric6DofConstraint(*body1, *body2, transform1, transform2, true);
837         
838         return (rbConstraint *)con;
839 }
840
841 rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
842 {
843         btRigidBody *body1 = rb1->body;
844         btRigidBody *body2 = rb2->body;
845         btTransform transform1;
846         btTransform transform2;
847         
848         make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
849         
850         btTypedConstraint *con = new btGeneric6DofSpringConstraint(*body1, *body2, transform1, transform2, true);
851         
852         return (rbConstraint *)con;
853 }
854
855 /* Cleanup ----------------------------- */
856
857 void RB_constraint_delete(rbConstraint *con)
858 {
859         btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
860         delete constraint;
861 }
862
863 /* Settings ------------------------- */
864
865 void RB_constraint_set_enabled(rbConstraint *con, int enabled)
866 {
867         btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
868         
869         constraint->setEnabled(enabled);
870 }
871
872 void RB_constraint_set_limits_hinge(rbConstraint *con, float lower, float upper)
873 {
874         btHingeConstraint *constraint = reinterpret_cast<btHingeConstraint*>(con);
875         
876         // RB_TODO expose these
877         float softness = 0.9f;
878         float bias_factor = 0.3f;
879         float relaxation_factor = 1.0f;
880         
881         constraint->setLimit(lower, upper, softness, bias_factor, relaxation_factor);
882 }
883
884 void RB_constraint_set_limits_slider(rbConstraint *con, float lower, float upper)
885 {
886         btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint*>(con);
887         
888         constraint->setLowerLinLimit(lower);
889         constraint->setUpperLinLimit(upper);
890 }
891
892 void RB_constraint_set_limits_piston(rbConstraint *con, float lin_lower, float lin_upper, float ang_lower, float ang_upper)
893 {
894         btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint*>(con);
895         
896         constraint->setLowerLinLimit(lin_lower);
897         constraint->setUpperLinLimit(lin_upper);
898         constraint->setLowerAngLimit(ang_lower);
899         constraint->setUpperAngLimit(ang_upper);
900 }
901
902 void RB_constraint_set_limits_6dof(rbConstraint *con, float axis, float lower, float upper)
903 {
904         btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint*>(con);
905         
906         constraint->setLimit(axis, lower, upper);
907 }
908
909 void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, float axis, float stiffness)
910 {
911         btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
912         
913         constraint->setStiffness(axis, stiffness);
914 }
915
916 void RB_constraint_set_damping_6dof_spring(rbConstraint *con, float axis, float damping)
917 {
918         btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
919         
920         constraint->setDamping(axis, damping);
921 }
922
923 void RB_constraint_set_spring_6dof_spring(rbConstraint *con, float axis, int enable)
924 {
925         btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
926         
927         constraint->enableSpring(axis, enable);
928 }
929
930 void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con)
931 {
932         btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
933         
934         constraint->setEquilibriumPoint();
935 }
936
937 void RB_constraint_set_solver_iterations(rbConstraint *con, int num_solver_iterations)
938 {
939         btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
940         
941         constraint->setOverrideNumSolverIterations(num_solver_iterations);
942 }
943
944 void RB_constraint_set_breaking_threshold(rbConstraint *con, float threshold)
945 {
946         btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint*>(con);
947         
948         constraint->setBreakingImpulseThreshold(threshold);
949 }
950
951 /* ********************************** */