Bullet Collision Detection & Physics Library
Bullet-C-API.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 
16 /*
17  Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's.
18  Work in progress, functionality will be added on demand.
19 
20  If possible, use the richer Bullet C++ API, by including <src/btBulletDynamicsCommon.h>
21 */
22 
23 #include "Bullet-C-Api.h"
24 #include "btBulletDynamicsCommon.h"
26 
27 
28 
29 #include "LinearMath/btVector3.h"
30 #include "LinearMath/btScalar.h"
31 #include "LinearMath/btMatrix3x3.h"
32 #include "LinearMath/btTransform.h"
35 
46 
47 
48 /*
49  Create and Delete a Physics SDK
50 */
51 
53 {
54 
55 // btDispatcher* m_dispatcher;
56 // btOverlappingPairCache* m_pairCache;
57 // btConstraintSolver* m_constraintSolver
58 
61 
62 
63  //todo: version, hardware/optimization settings etc?
65  :m_worldAabbMin(-1000,-1000,-1000),
66  m_worldAabbMax(1000,1000,1000)
67  {
68 
69  }
70 
71 
72 };
73 
74 plPhysicsSdkHandle plNewBulletSdk()
75 {
76  void* mem = btAlignedAlloc(sizeof(btPhysicsSdk),16);
77  return (plPhysicsSdkHandle)new (mem)btPhysicsSdk;
78 }
79 
80 void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk)
81 {
82  btPhysicsSdk* phys = reinterpret_cast<btPhysicsSdk*>(physicsSdk);
83  btAlignedFree(phys);
84 }
85 
86 
87 /* Dynamics World */
88 plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdkHandle)
89 {
90  btPhysicsSdk* physicsSdk = reinterpret_cast<btPhysicsSdk*>(physicsSdkHandle);
91  void* mem = btAlignedAlloc(sizeof(btDefaultCollisionConfiguration),16);
92  btDefaultCollisionConfiguration* collisionConfiguration = new (mem)btDefaultCollisionConfiguration();
93  mem = btAlignedAlloc(sizeof(btCollisionDispatcher),16);
94  btDispatcher* dispatcher = new (mem)btCollisionDispatcher(collisionConfiguration);
95  mem = btAlignedAlloc(sizeof(btAxisSweep3),16);
96  btBroadphaseInterface* pairCache = new (mem)btAxisSweep3(physicsSdk->m_worldAabbMin,physicsSdk->m_worldAabbMax);
98  btConstraintSolver* constraintSolver = new(mem) btSequentialImpulseConstraintSolver();
99 
100  mem = btAlignedAlloc(sizeof(btDiscreteDynamicsWorld),16);
101  return (plDynamicsWorldHandle) new (mem)btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration);
102 }
103 void plDeleteDynamicsWorld(plDynamicsWorldHandle world)
104 {
105  //todo: also clean up the other allocations, axisSweep, pairCache,dispatcher,constraintSolver,collisionConfiguration
106  btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
107  btAlignedFree(dynamicsWorld);
108 }
109 
110 void plStepSimulation(plDynamicsWorldHandle world, plReal timeStep)
111 {
112  btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
113  btAssert(dynamicsWorld);
114  dynamicsWorld->stepSimulation(timeStep);
115 }
116 
117 void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object)
118 {
119  btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
120  btAssert(dynamicsWorld);
121  btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
122  btAssert(body);
123 
124  dynamicsWorld->addRigidBody(body);
125 }
126 
127 void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object)
128 {
129  btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
130  btAssert(dynamicsWorld);
131  btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
132  btAssert(body);
133 
134  dynamicsWorld->removeRigidBody(body);
135 }
136 
137 /* Rigid Body */
138 
139 plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape )
140 {
141  btTransform trans;
142  trans.setIdentity();
143  btVector3 localInertia(0,0,0);
144  btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);
145  btAssert(shape);
146  if (mass)
147  {
148  shape->calculateLocalInertia(mass,localInertia);
149  }
150  void* mem = btAlignedAlloc(sizeof(btRigidBody),16);
151  btRigidBody::btRigidBodyConstructionInfo rbci(mass, 0,shape,localInertia);
152  btRigidBody* body = new (mem)btRigidBody(rbci);
153  body->setWorldTransform(trans);
154  body->setUserPointer(user_data);
155  return (plRigidBodyHandle) body;
156 }
157 
158 void plDeleteRigidBody(plRigidBodyHandle cbody)
159 {
160  btRigidBody* body = reinterpret_cast< btRigidBody* >(cbody);
161  btAssert(body);
162  btAlignedFree( body);
163 }
164 
165 
166 /* Collision Shape definition */
167 
168 plCollisionShapeHandle plNewSphereShape(plReal radius)
169 {
170  void* mem = btAlignedAlloc(sizeof(btSphereShape),16);
171  return (plCollisionShapeHandle) new (mem)btSphereShape(radius);
172 
173 }
174 
175 plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z)
176 {
177  void* mem = btAlignedAlloc(sizeof(btBoxShape),16);
178  return (plCollisionShapeHandle) new (mem)btBoxShape(btVector3(x,y,z));
179 }
180 
181 plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height)
182 {
183  //capsule is convex hull of 2 spheres, so use btMultiSphereShape
184 
185  const int numSpheres = 2;
186  btVector3 positions[numSpheres] = {btVector3(0,height,0),btVector3(0,-height,0)};
187  btScalar radi[numSpheres] = {radius,radius};
188  void* mem = btAlignedAlloc(sizeof(btMultiSphereShape),16);
189  return (plCollisionShapeHandle) new (mem)btMultiSphereShape(positions,radi,numSpheres);
190 }
191 plCollisionShapeHandle plNewConeShape(plReal radius, plReal height)
192 {
193  void* mem = btAlignedAlloc(sizeof(btConeShape),16);
194  return (plCollisionShapeHandle) new (mem)btConeShape(radius,height);
195 }
196 
197 plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height)
198 {
199  void* mem = btAlignedAlloc(sizeof(btCylinderShape),16);
200  return (plCollisionShapeHandle) new (mem)btCylinderShape(btVector3(radius,height,radius));
201 }
202 
203 /* Convex Meshes */
204 plCollisionShapeHandle plNewConvexHullShape()
205 {
206  void* mem = btAlignedAlloc(sizeof(btConvexHullShape),16);
207  return (plCollisionShapeHandle) new (mem)btConvexHullShape();
208 }
209 
210 
211 /* Concave static triangle meshes */
212 plMeshInterfaceHandle plNewMeshInterface()
213 {
214  return 0;
215 }
216 
217 plCollisionShapeHandle plNewCompoundShape()
218 {
219  void* mem = btAlignedAlloc(sizeof(btCompoundShape),16);
220  return (plCollisionShapeHandle) new (mem)btCompoundShape();
221 }
222 
223 void plAddChildShape(plCollisionShapeHandle compoundShapeHandle,plCollisionShapeHandle childShapeHandle, plVector3 childPos,plQuaternion childOrn)
224 {
225  btCollisionShape* colShape = reinterpret_cast<btCollisionShape*>(compoundShapeHandle);
227  btCompoundShape* compoundShape = reinterpret_cast<btCompoundShape*>(colShape);
228  btCollisionShape* childShape = reinterpret_cast<btCollisionShape*>(childShapeHandle);
229  btTransform localTrans;
230  localTrans.setIdentity();
231  localTrans.setOrigin(btVector3(childPos[0],childPos[1],childPos[2]));
232  localTrans.setRotation(btQuaternion(childOrn[0],childOrn[1],childOrn[2],childOrn[3]));
233  compoundShape->addChildShape(localTrans,childShape);
234 }
235 
236 void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient)
237 {
238  btQuaternion orn;
239  orn.setEuler(yaw,pitch,roll);
240  orient[0] = orn.getX();
241  orient[1] = orn.getY();
242  orient[2] = orn.getZ();
243  orient[3] = orn.getW();
244 
245 }
246 
247 
248 // extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2);
249 // extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);
250 
251 
252 void plAddVertex(plCollisionShapeHandle cshape, plReal x,plReal y,plReal z)
253 {
254  btCollisionShape* colShape = reinterpret_cast<btCollisionShape*>( cshape);
255  (void)colShape;
257  btConvexHullShape* convexHullShape = reinterpret_cast<btConvexHullShape*>( cshape);
258  convexHullShape->addPoint(btVector3(x,y,z));
259 
260 }
261 
262 void plDeleteShape(plCollisionShapeHandle cshape)
263 {
264  btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);
265  btAssert(shape);
266  btAlignedFree(shape);
267 }
268 void plSetScaling(plCollisionShapeHandle cshape, plVector3 cscaling)
269 {
270  btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);
271  btAssert(shape);
272  btVector3 scaling(cscaling[0],cscaling[1],cscaling[2]);
273  shape->setLocalScaling(scaling);
274 }
275 
276 
277 
278 void plSetPosition(plRigidBodyHandle object, const plVector3 position)
279 {
280  btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
281  btAssert(body);
282  btVector3 pos(position[0],position[1],position[2]);
283  btTransform worldTrans = body->getWorldTransform();
284  worldTrans.setOrigin(pos);
285  body->setWorldTransform(worldTrans);
286 }
287 
288 void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation)
289 {
290  btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
291  btAssert(body);
292  btQuaternion orn(orientation[0],orientation[1],orientation[2],orientation[3]);
293  btTransform worldTrans = body->getWorldTransform();
294  worldTrans.setRotation(orn);
295  body->setWorldTransform(worldTrans);
296 }
297 
298 void plSetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix)
299 {
300  btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
301  btAssert(body);
302  btTransform& worldTrans = body->getWorldTransform();
303  worldTrans.setFromOpenGLMatrix(matrix);
304 }
305 
306 void plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix)
307 {
308  btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
309  btAssert(body);
310  body->getWorldTransform().getOpenGLMatrix(matrix);
311 
312 }
313 
314 void plGetPosition(plRigidBodyHandle object,plVector3 position)
315 {
316  btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
317  btAssert(body);
318  const btVector3& pos = body->getWorldTransform().getOrigin();
319  position[0] = pos.getX();
320  position[1] = pos.getY();
321  position[2] = pos.getZ();
322 }
323 
324 void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation)
325 {
326  btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
327  btAssert(body);
328  const btQuaternion& orn = body->getWorldTransform().getRotation();
329  orientation[0] = orn.getX();
330  orientation[1] = orn.getY();
331  orientation[2] = orn.getZ();
332  orientation[3] = orn.getW();
333 }
334 
335 
336 
337 //plRigidBodyHandle plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal);
338 
339 // extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal);
340 
341 double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3])
342 {
343  btVector3 vp(p1[0], p1[1], p1[2]);
344  btTriangleShape trishapeA(vp,
345  btVector3(p2[0], p2[1], p2[2]),
346  btVector3(p3[0], p3[1], p3[2]));
347  trishapeA.setMargin(0.000001f);
348  btVector3 vq(q1[0], q1[1], q1[2]);
349  btTriangleShape trishapeB(vq,
350  btVector3(q2[0], q2[1], q2[2]),
351  btVector3(q3[0], q3[1], q3[2]));
352  trishapeB.setMargin(0.000001f);
353 
354  // btVoronoiSimplexSolver sGjkSimplexSolver;
355  // btGjkEpaPenetrationDepthSolver penSolverPtr;
356 
357  static btSimplexSolverInterface sGjkSimplexSolver;
358  sGjkSimplexSolver.reset();
359 
360  static btGjkEpaPenetrationDepthSolver Solver0;
361  static btMinkowskiPenetrationDepthSolver Solver1;
362 
363  btConvexPenetrationDepthSolver* Solver = NULL;
364 
365  Solver = &Solver1;
366 
367  btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver);
368 
369  convexConvex.m_catchDegeneracies = 1;
370 
371  // btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,0);
372 
373  btPointCollector gjkOutput;
375 
376 
377  btTransform tr;
378  tr.setIdentity();
379 
380  input.m_transformA = tr;
381  input.m_transformB = tr;
382 
383  convexConvex.getClosestPoints(input, gjkOutput, 0);
384 
385 
386  if (gjkOutput.m_hasResult)
387  {
388 
389  pb[0] = pa[0] = gjkOutput.m_pointInWorld[0];
390  pb[1] = pa[1] = gjkOutput.m_pointInWorld[1];
391  pb[2] = pa[2] = gjkOutput.m_pointInWorld[2];
392 
393  pb[0]+= gjkOutput.m_normalOnBInWorld[0] * gjkOutput.m_distance;
394  pb[1]+= gjkOutput.m_normalOnBInWorld[1] * gjkOutput.m_distance;
395  pb[2]+= gjkOutput.m_normalOnBInWorld[2] * gjkOutput.m_distance;
396 
397  normal[0] = gjkOutput.m_normalOnBInWorld[0];
398  normal[1] = gjkOutput.m_normalOnBInWorld[1];
399  normal[2] = gjkOutput.m_normalOnBInWorld[2];
400 
401  return gjkOutput.m_distance;
402  }
403  return -1.0f;
404 }
405 
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height)
plCollisionShapeHandle plNewConvexHullShape()
int getShapeType() const
btQuaternion getRotation() const
Return a quaternion representing the rotation.
Definition: btTransform.h:122
The btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase.
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const =0
void plSetScaling(plCollisionShapeHandle cshape, plVector3 cscaling)
void getOpenGLMatrix(btScalar *m) const
Fill an array representation.
Definition: btTransform.h:139
plCollisionShapeHandle plNewConeShape(plReal radius, plReal height)
ConvexPenetrationDepthSolver provides an interface for penetration depth calculation.
btVector3 m_worldAabbMax
float plReal
Definition: Bullet-C-Api.h:31
The btMultiSphereShape represents the convex hull of a collection of spheres.
double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3])
btDiscreteDynamicsWorld provides discrete rigid body simulation those classes replace the obsolete Cc...
void setIdentity()
Set this transformation to the identity.
Definition: btTransform.h:172
#define btAssert(x)
Definition: btScalar.h:101
The btDynamicsWorld is the interface class for several dynamics implementation, basic, discrete, parallel, and continuous etc.
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
const btScalar & getW() const
Definition: btQuaternion.h:561
btCollisionDispatcher supports algorithms that handle ConvexConvex and ConvexConcave collision pairs...
The btSphereShape implements an implicit sphere, centered around a local origin with radius...
Definition: btSphereShape.h:22
void plGetOrientation(plRigidBodyHandle object, plQuaternion orientation)
const btScalar & getY() const
Return the y value.
Definition: btQuadWord.h:104
plPhysicsSdkHandle plNewBulletSdk()
Create and Delete a Physics SDK.
plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height)
const btScalar & getX() const
Return the x value.
Definition: btQuadWord.h:102
void plDeleteShape(plCollisionShapeHandle cshape)
plRigidBodyHandle plCreateRigidBody(void *user_data, float mass, plCollisionShapeHandle cshape)
plReal plVector3[3]
Definition: Bullet-C-Api.h:34
const btScalar & getZ() const
Return the z value.
Definition: btVector3.h:565
virtual void addRigidBody(btRigidBody *body)=0
void plSetOpenGLMatrix(plRigidBodyHandle object, plReal *matrix)
btCollisionConfiguration allows to configure Bullet collision detection stack allocator, pool memory allocators
void plGetOpenGLMatrix(plRigidBodyHandle object, plReal *matrix)
btTransform & getWorldTransform()
virtual void setMargin(btScalar margin)
void plGetPosition(plRigidBodyHandle object, plVector3 position)
void plAddVertex(plCollisionShapeHandle cshape, plReal x, plReal y, plReal z)
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:117
#define btSimplexSolverInterface
The btConeShape implements a cone shape primitive, centered around the origin and aligned with the Y ...
Definition: btConeShape.h:23
void setFromOpenGLMatrix(const btScalar *m)
Set from an array.
Definition: btTransform.h:131
void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation)
virtual void removeRigidBody(btRigidBody *body)=0
void plDeleteRigidBody(plRigidBodyHandle cbody)
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:563
btVector3 m_pointInWorld
#define btAlignedFree(ptr)
plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdkHandle)
void setRotation(const btQuaternion &q)
Set the rotational element by btQuaternion.
Definition: btTransform.h:165
void setUserPointer(void *userPointer)
users can point to their objects, userPointer is not used by Bullet
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:561
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:59
MinkowskiPenetrationDepthSolver implements bruteforce penetration depth estimation.
void plStepSimulation(plDynamicsWorldHandle world, plReal timeStep)
The btRigidBodyConstructionInfo structure provides information to create a rigid body.
Definition: btRigidBody.h:116
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs...
void setWorldTransform(const btTransform &worldTrans)
plCollisionShapeHandle plNewCompoundShape()
plCollisionShapeHandle plNewSphereShape(plReal radius)
virtual void setLocalScaling(const btVector3 &scaling)=0
The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (...
The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by ...
Definition: btBoxShape.h:26
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
void plAddChildShape(plCollisionShapeHandle compoundShapeHandle, plCollisionShapeHandle childShapeHandle, plVector3 childPos, plQuaternion childOrn)
virtual int stepSimulation(btScalar timeStep, int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))=0
stepSimulation proceeds the simulation over 'timeStep', units in preferably in seconds.
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object)
void plSetEuler(plReal yaw, plReal pitch, plReal roll, plQuaternion orient)
EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to calculate the penetration depth be...
btGjkPairDetector uses GJK to implement the btDiscreteCollisionDetectorInterface
The btCylinderShape class implements a cylinder shape primitive, centered around the origin...
void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk)
#define btAlignedAlloc(size, alignment)
void addPoint(const btVector3 &point, bool recalculateLocalAabb=true)
The btConvexHullShape implements an implicit convex hull of an array of vertices. ...
plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z)
btVector3 m_worldAabbMin
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
Definition: btQuaternion.h:48
The btCompoundShape allows to store multiple other btCollisionShapes This allows for moving concave c...
void setEuler(const btScalar &yaw, const btScalar &pitch, const btScalar &roll)
Set the quaternion using Euler angles.
Definition: btQuaternion.h:117
plMeshInterfaceHandle plNewMeshInterface()
plReal plQuaternion[4]
Definition: Bullet-C-Api.h:35
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:69
void plSetPosition(plRigidBodyHandle object, const plVector3 position)
void plDeleteDynamicsWorld(plDynamicsWorldHandle world)
void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object)
btVector3 m_normalOnBInWorld
const btScalar & getZ() const
Return the z value.
Definition: btQuadWord.h:106
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:266
virtual void getClosestPoints(const ClosestPointInput &input, Result &output, class btIDebugDraw *debugDraw, bool swapResults=false)