Blender V4.5
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 <cerrno>
39#include <cstdio>
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 bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const override
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{
127
128 /* collision detection/handling */
129 world->collisionConfiguration = new btDefaultCollisionConfiguration();
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
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 */
166
168{
169 copy_v3_btvec3(g_out, world->dynamicsWorld->getGravity());
170}
171
172void RB_dworld_set_gravity(rbDynamicsWorld *world, const float g_in[3])
173{
174 world->dynamicsWorld->setGravity(btVector3(g_in[0], g_in[1], g_in[2]));
175}
176
177/* Constraint Solver */
178
180{
181 btContactSolverInfo &info = world->dynamicsWorld->getSolverInfo();
182
183 info.m_numIterations = num_solver_iterations;
184}
185
186/* Split Impulse */
187
189{
190 btContactSolverInfo &info = world->dynamicsWorld->getSolverInfo();
191
192 info.m_splitImpulse = split_impulse;
193}
194
195/* Simulation ----------------------- */
196
198 float timeStep,
199 int maxSubSteps,
200 float timeSubStep)
201{
202 world->dynamicsWorld->stepSimulation(timeStep, maxSubSteps, timeSubStep);
203}
204
205/* Export -------------------------- */
206
207void RB_dworld_export(rbDynamicsWorld *world, const char *filename)
208{
209 // create a large enough buffer. There is no method to pre-calculate the buffer size yet.
210 int maxSerializeBufferSize = 1024 * 1024 * 5;
211
212 btDefaultSerializer *serializer = new btDefaultSerializer(maxSerializeBufferSize);
213 world->dynamicsWorld->serialize(serializer);
214
215 FILE *file = fopen(filename, "wb");
216 if (file) {
217 fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file);
218 fclose(file);
219 }
220 else {
221 fprintf(stderr, "RB_dworld_export: %s\n", strerror(errno));
222 }
223}
224
225/* ********************************** */
226/* Rigid Body Methods */
227
228/* Setup ---------------------------- */
229
231{
232 btRigidBody *body = object->body;
233 object->col_groups = col_groups;
234
235 world->dynamicsWorld->addRigidBody(body);
236}
237
239{
240 btRigidBody *body = object->body;
241
242 world->dynamicsWorld->removeRigidBody(body);
243}
244
245/* Collision detection */
246
248 rbRigidBody *object,
249 const float loc_start[3],
250 const float loc_end[3],
251 float v_location[3],
252 float v_hitpoint[3],
253 float v_normal[3],
254 int *r_hit)
255{
256 btRigidBody *body = object->body;
257 btCollisionShape *collisionShape = body->getCollisionShape();
258 /* only convex shapes are supported, but user can specify a non convex shape */
259 if (collisionShape->isConvex()) {
261 btVector3(loc_start[0], loc_start[1], loc_start[2]),
262 btVector3(loc_end[0], loc_end[1], loc_end[2]));
263
264 btQuaternion obRot = body->getWorldTransform().getRotation();
265
266 btTransform rayFromTrans;
267 rayFromTrans.setIdentity();
268 rayFromTrans.setRotation(obRot);
269 rayFromTrans.setOrigin(btVector3(loc_start[0], loc_start[1], loc_start[2]));
270
271 btTransform rayToTrans;
272 rayToTrans.setIdentity();
273 rayToTrans.setRotation(obRot);
274 rayToTrans.setOrigin(btVector3(loc_end[0], loc_end[1], loc_end[2]));
275
276 world->dynamicsWorld->convexSweepTest(
277 (btConvexShape *)collisionShape, rayFromTrans, rayToTrans, result, 0);
278
279 if (result.hasHit()) {
280 *r_hit = 1;
281
282 v_location[0] = result.m_convexFromWorld[0] +
283 (result.m_convexToWorld[0] - result.m_convexFromWorld[0]) *
284 result.m_closestHitFraction;
285 v_location[1] = result.m_convexFromWorld[1] +
286 (result.m_convexToWorld[1] - result.m_convexFromWorld[1]) *
287 result.m_closestHitFraction;
288 v_location[2] = result.m_convexFromWorld[2] +
289 (result.m_convexToWorld[2] - result.m_convexFromWorld[2]) *
290 result.m_closestHitFraction;
291
292 v_hitpoint[0] = result.m_hitPointWorld[0];
293 v_hitpoint[1] = result.m_hitPointWorld[1];
294 v_hitpoint[2] = result.m_hitPointWorld[2];
295
296 v_normal[0] = result.m_hitNormalWorld[0];
297 v_normal[1] = result.m_hitNormalWorld[1];
298 v_normal[2] = result.m_hitNormalWorld[2];
299 }
300 else {
301 *r_hit = 0;
302 }
303 }
304 else {
305 /* we need to return a value if user passes non convex body, to report */
306 *r_hit = -2;
307 }
308}
309
310/* ............ */
311
312rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4])
313{
314 rbRigidBody *object = new rbRigidBody;
315 /* current transform */
316 btTransform trans;
317 trans.setIdentity();
318 trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
319 trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
320
321 /* create motionstate, which is necessary for interpolation (includes reverse playback) */
322 btDefaultMotionState *motionState = new btDefaultMotionState(trans);
323
324 /* make rigidbody */
325 btRigidBody::btRigidBodyConstructionInfo rbInfo(1.0f, motionState, shape->cshape);
326
327 object->body = new btRigidBody(rbInfo);
328
329 object->body->setUserPointer(object);
330
331 return object;
332}
333
335{
336 btRigidBody *body = object->body;
337
338 /* motion state */
339 btMotionState *ms = body->getMotionState();
340
341 delete ms;
342
343 /* collision shape is done elsewhere... */
344
345 /* body itself */
346
347 /* manually remove constraint refs of the rigid body, normally this happens when removing
348 * constraints from the world
349 * but since we delete everything when the world is rebult, we need to do it manually here */
350 for (int i = body->getNumConstraintRefs() - 1; i >= 0; i--) {
351 btTypedConstraint *con = body->getConstraintRef(i);
352 body->removeConstraintRef(con);
353 }
354
355 delete body;
356 delete object;
357}
358
359/* Settings ------------------------- */
360
362{
363 btRigidBody *body = object->body;
364
365 /* set new collision shape */
366 body->setCollisionShape(shape->cshape);
367
368 /* recalculate inertia, since that depends on the collision shape... */
369 RB_body_set_mass(object, RB_body_get_mass(object));
370}
371
372/* ............ */
373
375{
376 btRigidBody *body = object->body;
377
378 /* there isn't really a mass setting, but rather 'inverse mass'
379 * which we convert back to mass by taking the reciprocal again
380 */
381 float value = (float)body->getInvMass();
382
383 if (value) {
384 value = 1.0f / value;
385 }
386
387 return value;
388}
389
391{
392 btRigidBody *body = object->body;
393 btVector3 localInertia(0, 0, 0);
394
395 /* calculate new inertia if non-zero mass */
396 if (value) {
397 btCollisionShape *shape = body->getCollisionShape();
398 shape->calculateLocalInertia(value, localInertia);
399 }
400
401 btVector3 minAabb, maxAabb;
402 btTransform ident;
403 ident.setIdentity();
404 body->getCollisionShape()->getAabb(ident, minAabb, maxAabb);
405 body->setMassProps(value, localInertia);
406 body->updateInertiaTensor();
407}
408
410{
411 btRigidBody *body = object->body;
412 return body->getFriction();
413}
414
416{
417 btRigidBody *body = object->body;
418 body->setFriction(value);
419}
420
422{
423 btRigidBody *body = object->body;
424 return body->getRestitution();
425}
426
428{
429 btRigidBody *body = object->body;
430 body->setRestitution(value);
431}
432
434{
435 btRigidBody *body = object->body;
436 return body->getLinearDamping();
437}
438
443
445{
446 btRigidBody *body = object->body;
447 return body->getAngularDamping();
448}
449
454
455void RB_body_set_damping(rbRigidBody *object, float linear, float angular)
456{
457 btRigidBody *body = object->body;
458 body->setDamping(linear, angular);
459}
460
462{
463 btRigidBody *body = object->body;
464 return body->getLinearSleepingThreshold();
465}
466
471
473{
474 btRigidBody *body = object->body;
475 return body->getAngularSleepingThreshold();
476}
477
482
483void RB_body_set_sleep_thresh(rbRigidBody *object, float linear, float angular)
484{
485 btRigidBody *body = object->body;
486 body->setSleepingThresholds(linear, angular);
487}
488
489/* ............ */
490
491void RB_body_get_linear_velocity(rbRigidBody *object, float v_out[3])
492{
493 btRigidBody *body = object->body;
494
495 copy_v3_btvec3(v_out, body->getLinearVelocity());
496}
497
498void RB_body_set_linear_velocity(rbRigidBody *object, const float v_in[3])
499{
500 btRigidBody *body = object->body;
501
502 body->setLinearVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
503}
504
505void RB_body_get_angular_velocity(rbRigidBody *object, float v_out[3])
506{
507 btRigidBody *body = object->body;
508
509 copy_v3_btvec3(v_out, body->getAngularVelocity());
510}
511
512void RB_body_set_angular_velocity(rbRigidBody *object, const float v_in[3])
513{
514 btRigidBody *body = object->body;
515
516 body->setAngularVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
517}
518
519void RB_body_set_linear_factor(rbRigidBody *object, float x, float y, float z)
520{
521 btRigidBody *body = object->body;
522 body->setLinearFactor(btVector3(x, y, z));
523}
524
525void RB_body_set_angular_factor(rbRigidBody *object, float x, float y, float z)
526{
527 btRigidBody *body = object->body;
528 body->setAngularFactor(btVector3(x, y, z));
529}
530
531/* ............ */
532
533void RB_body_set_kinematic_state(rbRigidBody *object, int kinematic)
534{
535 btRigidBody *body = object->body;
536 if (kinematic) {
537 body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
538 }
539 else {
540 body->setCollisionFlags(body->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT);
541 }
542}
543
544/* ............ */
545
546void RB_body_set_activation_state(rbRigidBody *object, int use_deactivation)
547{
548 btRigidBody *body = object->body;
549 if (use_deactivation) {
550 body->forceActivationState(ACTIVE_TAG);
551 }
552 else {
553 body->setActivationState(DISABLE_DEACTIVATION);
554 }
555}
557{
558 btRigidBody *body = object->body;
559 body->setActivationState(ACTIVE_TAG);
560}
562{
563 btRigidBody *body = object->body;
564 body->setActivationState(ISLAND_SLEEPING);
565}
566
567/* ............ */
568
569/* Simulation ----------------------- */
570
571/* The transform matrices Blender uses are OpenGL-style matrices,
572 * while Bullet uses the Right-Handed coordinate system style instead.
573 */
574
575void RB_body_get_transform_matrix(rbRigidBody *object, float m_out[4][4])
576{
577 btRigidBody *body = object->body;
578 btMotionState *ms = body->getMotionState();
579
580 btTransform trans;
581 ms->getWorldTransform(trans);
582
583 trans.getOpenGLMatrix((btScalar *)m_out);
584}
585
586void RB_body_set_loc_rot(rbRigidBody *object, const float loc[3], const float rot[4])
587{
588 btRigidBody *body = object->body;
589 btMotionState *ms = body->getMotionState();
590
591 /* set transform matrix */
592 btTransform trans;
593 trans.setIdentity();
594 trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
595 trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
596
597 ms->setWorldTransform(trans);
598}
599
600void RB_body_set_scale(rbRigidBody *object, const float scale[3])
601{
602 btRigidBody *body = object->body;
603
604 /* apply scaling factor from matrix above to the collision shape */
605 btCollisionShape *cshape = body->getCollisionShape();
606 if (cshape) {
607 cshape->setLocalScaling(btVector3(scale[0], scale[1], scale[2]));
608
609 /* GIimpact shapes have to be updated to take scaling into account */
610 if (cshape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) {
611 ((btGImpactMeshShape *)cshape)->updateBound();
612 }
613 }
614}
615
616/* ............ */
617/* Read-only state info about status of simulation */
618
619void RB_body_get_position(rbRigidBody *object, float v_out[3])
620{
621 btRigidBody *body = object->body;
622
623 copy_v3_btvec3(v_out, body->getWorldTransform().getOrigin());
624}
625
626void RB_body_get_orientation(rbRigidBody *object, float v_out[4])
627{
628 btRigidBody *body = object->body;
629
630 copy_quat_btquat(v_out, body->getWorldTransform().getRotation());
631}
632
633void RB_body_get_scale(rbRigidBody *object, float v_out[3])
634{
635 btRigidBody *body = object->body;
636
637 btCollisionShape *cshape = body->getCollisionShape();
638 /* The body should have a collision shape when we try to set the scale. */
639 btAssert(cshape);
640 copy_v3_btvec3(v_out, cshape->getLocalScaling());
641}
642
643/* ............ */
644/* Overrides for simulation */
645
646void RB_body_apply_central_force(rbRigidBody *object, const float v_in[3])
647{
648 btRigidBody *body = object->body;
649
650 body->applyCentralForce(btVector3(v_in[0], v_in[1], v_in[2]));
651}
652
653/* ********************************** */
654/* Collision Shape Methods */
655
656/* Setup (Standard Shapes) ----------- */
657
658rbCollisionShape *RB_shape_new_box(float x, float y, float z)
659{
661 shape->cshape = new btBoxShape(btVector3(x, y, z));
662 shape->mesh = nullptr;
663 shape->compoundChilds = 0;
664 shape->compoundChildShapes = nullptr;
665 return shape;
666}
667
669{
671 shape->cshape = new btSphereShape(radius);
672 shape->mesh = nullptr;
673 shape->compoundChilds = 0;
674 shape->compoundChildShapes = nullptr;
675 return shape;
676}
677
678rbCollisionShape *RB_shape_new_capsule(float radius, float height)
679{
681 shape->cshape = new btCapsuleShapeZ(radius, height);
682 shape->mesh = nullptr;
683 shape->compoundChilds = 0;
684 shape->compoundChildShapes = nullptr;
685 return shape;
686}
687
688rbCollisionShape *RB_shape_new_cone(float radius, float height)
689{
691 shape->cshape = new btConeShapeZ(radius, height);
692 shape->mesh = nullptr;
693 shape->compoundChilds = 0;
694 shape->compoundChildShapes = nullptr;
695 return shape;
696}
697
698rbCollisionShape *RB_shape_new_cylinder(float radius, float height)
699{
701 shape->cshape = new btCylinderShapeZ(btVector3(radius, radius, height));
702 shape->mesh = nullptr;
703 shape->compoundChilds = 0;
704 shape->compoundChildShapes = nullptr;
705 return shape;
706}
707
708/* Setup (Convex Hull) ------------ */
709
711 const float *verts, int stride, int count, float margin, bool *can_embed)
712{
714
715 // try to embed the margin, if that fails don't shrink the hull
716 if (hull_computer.compute(verts, stride, count, margin, 0.0f) < 0.0f) {
717 hull_computer.compute(verts, stride, count, 0.0f, 0.0f);
718 *can_embed = false;
719 }
720
722 btConvexHullShape *hull_shape = new btConvexHullShape(&(hull_computer.vertices[0].getX()),
723 hull_computer.vertices.size());
724
725 shape->cshape = hull_shape;
726 shape->mesh = nullptr;
727 shape->compoundChilds = 0;
728 shape->compoundChildShapes = nullptr;
729 return shape;
730}
731
732/* Setup (Triangle Mesh) ---------- */
733
734/* Need to call RB_trimesh_finish() after creating triangle mesh and adding vertices and triangles
735 */
736
737rbMeshData *RB_trimesh_data_new(int num_tris, int num_verts)
738{
740 mesh->vertices = new rbVert[num_verts];
741 mesh->triangles = new rbTri[num_tris];
742 mesh->num_vertices = num_verts;
743 mesh->num_triangles = num_tris;
744
745 return mesh;
746}
747
749{
750 delete mesh->index_array;
751 delete[] mesh->vertices;
752 delete[] mesh->triangles;
753 delete mesh;
754}
755
756void RB_trimesh_add_vertices(rbMeshData *mesh, float *vertices, int num_verts, int vert_stride)
757{
758 for (int i = 0; i < num_verts; i++) {
759 float *vert = (float *)(((char *)vertices + i * vert_stride));
760 mesh->vertices[i].x = vert[0];
761 mesh->vertices[i].y = vert[1];
762 mesh->vertices[i].z = vert[2];
763 }
764}
765void RB_trimesh_add_triangle_indices(rbMeshData *mesh, int num, int index0, int index1, int index2)
766{
767 mesh->triangles[num].v0 = index0;
768 mesh->triangles[num].v1 = index1;
769 mesh->triangles[num].v2 = index2;
770}
771
773{
775 (int *)mesh->triangles,
776 sizeof(rbTri),
777 mesh->num_vertices,
778 (btScalar *)mesh->vertices,
779 sizeof(rbVert));
780}
781
783{
785
786 /* triangle-mesh we create is a BVH wrapper for triangle mesh data (for faster lookups) */
787 // RB_TODO perhaps we need to allow saving out this for performance when rebuilding?
789 mesh->index_array, true, true);
790
791 shape->cshape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f));
792 shape->mesh = mesh;
793 shape->compoundChilds = 0;
794 shape->compoundChildShapes = nullptr;
795 return shape;
796}
797
799 const float *vertices,
800 int num_verts,
801 int vert_stride,
802 const float min[3],
803 const float max[3])
804{
805 if (shape->mesh == nullptr || num_verts != shape->mesh->num_vertices) {
806 return;
807 }
808
809 for (int i = 0; i < num_verts; i++) {
810 float *vert = (float *)(((char *)vertices + i * vert_stride));
811 shape->mesh->vertices[i].x = vert[0];
812 shape->mesh->vertices[i].y = vert[1];
813 shape->mesh->vertices[i].z = vert[2];
814 }
815
816 if (shape->cshape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
818 btBvhTriangleMeshShape *mesh_shape = scaled_shape->getChildShape();
819 mesh_shape->refitTree(btVector3(min[0], min[1], min[2]), btVector3(max[0], max[1], max[2]));
820 }
821 else if (shape->cshape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) {
822 btGImpactMeshShape *mesh_shape = (btGImpactMeshShape *)shape->cshape;
823 mesh_shape->updateBound();
824 }
825}
826
828{
830
831 btGImpactMeshShape *gimpactShape = new btGImpactMeshShape(mesh->index_array);
832 gimpactShape->updateBound(); // TODO: add this to the update collision margin call?
833
834 shape->cshape = gimpactShape;
835 shape->mesh = mesh;
836 shape->compoundChilds = 0;
837 shape->compoundChildShapes = nullptr;
838 return shape;
839}
840
841/* Compound Shape ---------------- */
842
844{
846 btCompoundShape *compoundShape = new btCompoundShape();
847
848 shape->cshape = compoundShape;
849 shape->mesh = nullptr;
850 shape->compoundChilds = 0;
851 shape->compoundChildShapes = nullptr;
852 return shape;
853}
854
856 rbCollisionShape *shape,
857 const float loc[3],
858 const float rot[4])
859{
860 /* set transform matrix */
861 btTransform trans;
862 trans.setIdentity();
863 trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
864 trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
865
866 btCompoundShape *compoundShape = (btCompoundShape *)(parentShape->cshape);
867 compoundShape->addChildShape(trans, shape->cshape);
868
869 /* Store shapes for deletion later */
870 parentShape->compoundChildShapes = (rbCollisionShape **)(realloc(
871 parentShape->compoundChildShapes,
872 sizeof(rbCollisionShape *) * (++parentShape->compoundChilds)));
873 parentShape->compoundChildShapes[parentShape->compoundChilds - 1] = shape;
874}
875
876/* Cleanup --------------------------- */
877
879{
880 if (shape->cshape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
881 btBvhTriangleMeshShape *child_shape =
882 ((btScaledBvhTriangleMeshShape *)shape->cshape)->getChildShape();
883
884 delete child_shape;
885 }
886 if (shape->mesh) {
888 }
889 delete shape->cshape;
890
891 /* Delete compound child shapes if there are any */
892 for (int i = 0; i < shape->compoundChilds; i++) {
894 }
895 if (shape->compoundChildShapes != nullptr) {
897 }
898
899 delete shape;
900}
901
902/* Settings --------------------------- */
903
905{
906 return shape->cshape->getMargin();
907}
908
910{
911 shape->cshape->setMargin(value);
912}
913
914/* ********************************** */
915/* Constraints */
916
917/* Setup ----------------------------- */
918
919void RB_dworld_add_constraint(rbDynamicsWorld *world, rbConstraint *con, int disable_collisions)
920{
921 btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
922
923 world->dynamicsWorld->addConstraint(constraint, disable_collisions);
924}
925
927{
928 btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
929
930 world->dynamicsWorld->removeConstraint(constraint);
931}
932
933/* ............ */
934
936 btTransform &transform2,
937 btRigidBody *body1,
938 btRigidBody *body2,
939 const float pivot[3],
940 const float orn[4])
941{
942 btTransform pivot_transform = btTransform();
943 pivot_transform.setIdentity();
944 pivot_transform.setOrigin(btVector3(pivot[0], pivot[1], pivot[2]));
945 pivot_transform.setRotation(btQuaternion(orn[1], orn[2], orn[3], orn[0]));
946
947 transform1 = body1->getWorldTransform().inverse() * pivot_transform;
948 transform2 = body2->getWorldTransform().inverse() * pivot_transform;
949}
950
952{
953 btRigidBody *body1 = rb1->body;
954 btRigidBody *body2 = rb2->body;
955
956 btVector3 pivot1 = body1->getWorldTransform().inverse() *
957 btVector3(pivot[0], pivot[1], pivot[2]);
958 btVector3 pivot2 = body2->getWorldTransform().inverse() *
959 btVector3(pivot[0], pivot[1], pivot[2]);
960
961 btTypedConstraint *con = new btPoint2PointConstraint(*body1, *body2, pivot1, pivot2);
962
963 return (rbConstraint *)con;
964}
965
967 float orn[4],
968 rbRigidBody *rb1,
969 rbRigidBody *rb2)
970{
971 btRigidBody *body1 = rb1->body;
972 btRigidBody *body2 = rb2->body;
973 btTransform transform1;
974 btTransform transform2;
975
976 make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
977
978 btFixedConstraint *con = new btFixedConstraint(*body1, *body2, transform1, transform2);
979
980 return (rbConstraint *)con;
981}
982
984 float orn[4],
985 rbRigidBody *rb1,
986 rbRigidBody *rb2)
987{
988 btRigidBody *body1 = rb1->body;
989 btRigidBody *body2 = rb2->body;
990 btTransform transform1;
991 btTransform transform2;
992
993 make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
994
995 btHingeConstraint *con = new btHingeConstraint(*body1, *body2, transform1, transform2);
996
997 return (rbConstraint *)con;
998}
999
1001 float orn[4],
1002 rbRigidBody *rb1,
1003 rbRigidBody *rb2)
1004{
1005 btRigidBody *body1 = rb1->body;
1006 btRigidBody *body2 = rb2->body;
1007 btTransform transform1;
1008 btTransform transform2;
1009
1010 make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
1011
1012 btSliderConstraint *con = new btSliderConstraint(*body1, *body2, transform1, transform2, true);
1013
1014 return (rbConstraint *)con;
1015}
1016
1018 float orn[4],
1019 rbRigidBody *rb1,
1020 rbRigidBody *rb2)
1021{
1022 btRigidBody *body1 = rb1->body;
1023 btRigidBody *body2 = rb2->body;
1024 btTransform transform1;
1025 btTransform transform2;
1026
1027 make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
1028
1029 btSliderConstraint *con = new btSliderConstraint(*body1, *body2, transform1, transform2, true);
1030 con->setUpperAngLimit(-1.0f); // unlock rotation axis
1031
1032 return (rbConstraint *)con;
1033}
1034
1036 float orn[4],
1037 rbRigidBody *rb1,
1038 rbRigidBody *rb2)
1039{
1040 btRigidBody *body1 = rb1->body;
1041 btRigidBody *body2 = rb2->body;
1042 btTransform transform1;
1043 btTransform transform2;
1044
1045 make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
1046
1047 btTypedConstraint *con = new btGeneric6DofConstraint(
1048 *body1, *body2, transform1, transform2, true);
1049
1050 return (rbConstraint *)con;
1051}
1052
1054 float orn[4],
1055 rbRigidBody *rb1,
1056 rbRigidBody *rb2)
1057{
1058 btRigidBody *body1 = rb1->body;
1059 btRigidBody *body2 = rb2->body;
1060 btTransform transform1;
1061 btTransform transform2;
1062
1063 make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
1064
1065 btTypedConstraint *con = new btGeneric6DofSpringConstraint(
1066 *body1, *body2, transform1, transform2, true);
1067
1068 return (rbConstraint *)con;
1069}
1070
1072 float orn[4],
1073 rbRigidBody *rb1,
1074 rbRigidBody *rb2)
1075{
1076 btRigidBody *body1 = rb1->body;
1077 btRigidBody *body2 = rb2->body;
1078 btTransform transform1;
1079 btTransform transform2;
1080
1081 make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
1082
1083 btTypedConstraint *con = new btGeneric6DofSpring2Constraint(
1084 *body1, *body2, transform1, transform2);
1085
1086 return (rbConstraint *)con;
1087}
1088
1090 float orn[4],
1091 rbRigidBody *rb1,
1092 rbRigidBody *rb2)
1093{
1094 btRigidBody *body1 = rb1->body;
1095 btRigidBody *body2 = rb2->body;
1096 btTransform transform1;
1097 btTransform transform2;
1098
1099 make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
1100
1102 *body1, *body2, transform1, transform2, true);
1103
1104 /* unlock constraint axes */
1105 for (int i = 0; i < 6; i++) {
1106 con->setLimit(i, 0.0f, -1.0f);
1107 }
1108 /* unlock motor axes */
1109 con->getTranslationalLimitMotor()->m_upperLimit.setValue(-1.0f, -1.0f, -1.0f);
1110
1111 return (rbConstraint *)con;
1112}
1113
1114/* Cleanup ----------------------------- */
1115
1117{
1118 btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
1119
1120 /* If the constraint has disabled collisions between the bodies, those bodies
1121 * will have a pointer back to the constraint. We need to remove the constraint
1122 * from each body to avoid dereferencing the deleted constraint later (#91369) */
1123 constraint->getRigidBodyA().removeConstraintRef(constraint);
1124 constraint->getRigidBodyB().removeConstraintRef(constraint);
1125
1126 delete constraint;
1127}
1128
1129/* Settings ------------------------- */
1130
1132{
1133 btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
1134
1135 constraint->setEnabled(enabled);
1136}
1137
1138void RB_constraint_set_limits_hinge(rbConstraint *con, float lower, float upper)
1139{
1140 btHingeConstraint *constraint = reinterpret_cast<btHingeConstraint *>(con);
1141
1142 // RB_TODO expose these
1143 float softness = 0.9f;
1144 float bias_factor = 0.3f;
1145 float relaxation_factor = 1.0f;
1146
1147 constraint->setLimit(lower, upper, softness, bias_factor, relaxation_factor);
1148}
1149
1150void RB_constraint_set_limits_slider(rbConstraint *con, float lower, float upper)
1151{
1152 btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint *>(con);
1153
1154 constraint->setLowerLinLimit(lower);
1155 constraint->setUpperLinLimit(upper);
1156}
1157
1159 rbConstraint *con, float lin_lower, float lin_upper, float ang_lower, float ang_upper)
1160{
1161 btSliderConstraint *constraint = reinterpret_cast<btSliderConstraint *>(con);
1162
1163 constraint->setLowerLinLimit(lin_lower);
1164 constraint->setUpperLinLimit(lin_upper);
1165 constraint->setLowerAngLimit(ang_lower);
1166 constraint->setUpperAngLimit(ang_upper);
1167}
1168
1169void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, float upper)
1170{
1171 btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint *>(con);
1172
1173 constraint->setLimit(axis, lower, upper);
1174}
1175
1176void RB_constraint_set_limits_6dof_spring2(rbConstraint *con, int axis, float lower, float upper)
1177{
1178 btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
1179 con);
1180
1181 constraint->setLimit(axis, lower, upper);
1182}
1183
1184void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness)
1185{
1186 btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint *>(
1187 con);
1188
1189 constraint->setStiffness(axis, stiffness);
1190}
1191
1192void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping)
1193{
1194 btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint *>(
1195 con);
1196
1197 // invert damping range so that 0 = no damping
1198 damping = (damping > 1.0f) ? 0.0f : 1.0f - damping;
1199
1200 constraint->setDamping(axis, damping);
1201}
1202
1204{
1205 btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint *>(
1206 con);
1207
1208 constraint->enableSpring(axis, enable);
1209}
1210
1212{
1213 btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint *>(
1214 con);
1215
1216 constraint->setEquilibriumPoint();
1217}
1218
1219void RB_constraint_set_stiffness_6dof_spring2(rbConstraint *con, int axis, float stiffness)
1220{
1221 btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
1222 con);
1223
1224 constraint->setStiffness(axis, stiffness);
1225}
1226
1227void RB_constraint_set_damping_6dof_spring2(rbConstraint *con, int axis, float damping)
1228{
1229 btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
1230 con);
1231
1232 constraint->setDamping(axis, damping);
1233}
1234
1236{
1237 btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
1238 con);
1239
1240 constraint->enableSpring(axis, enable);
1241}
1242
1244{
1245 btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint *>(
1246 con);
1247
1248 constraint->setEquilibriumPoint();
1249}
1250
1251void RB_constraint_set_solver_iterations(rbConstraint *con, int num_solver_iterations)
1252{
1253 btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
1254
1255 constraint->setOverrideNumSolverIterations(num_solver_iterations);
1256}
1257
1259{
1260 btTypedConstraint *constraint = reinterpret_cast<btTypedConstraint *>(con);
1261
1262 constraint->setBreakingImpulseThreshold(threshold);
1263}
1264
1265void RB_constraint_set_enable_motor(rbConstraint *con, int enable_lin, int enable_ang)
1266{
1267 btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint *>(con);
1268
1269 constraint->getTranslationalLimitMotor()->m_enableMotor[0] = enable_lin;
1270 constraint->getRotationalLimitMotor(0)->m_enableMotor = enable_ang;
1271}
1272
1274 float max_impulse_lin,
1275 float max_impulse_ang)
1276{
1277 btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint *>(con);
1278
1279 constraint->getTranslationalLimitMotor()->m_maxMotorForce.setX(max_impulse_lin);
1280 constraint->getRotationalLimitMotor(0)->m_maxMotorForce = max_impulse_ang;
1281}
1282
1284 float velocity_lin,
1285 float velocity_ang)
1286{
1287 btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint *>(con);
1288
1289 constraint->getTranslationalLimitMotor()->m_targetVelocity.setX(velocity_lin);
1290 constraint->getRotationalLimitMotor(0)->m_targetVelocity = velocity_ang;
1291}
1292
1293/* ********************************** */
void BLI_kdtree_nd_ free(KDTree *tree)
ATTR_WARN_UNUSED_RESULT const size_t num
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)
btScalar max
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
FILE * file
#define rot(x, k)
static float verts[][3]
SearchInfo info
bool enabled
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.cc:36
size_t num_triangles() const
Definition scene/mesh.h:77
rbCollisionShape ** compoundChildShapes
btCollisionShape * cshape
rbMeshData * mesh
btBroadphaseInterface * pairCache
btConstraintSolver * constraintSolver
btDefaultCollisionConfiguration * collisionConfiguration
btDiscreteDynamicsWorld * dynamicsWorld
btOverlapFilterCallback * filterCallback
btDispatcher * dispatcher
bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const override
rbVert * vertices
rbTri * triangles
btTriangleIndexVertexArray * index_array
btRigidBody * body
btScalar y
btScalar x
btScalar z