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