Blender V5.0
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
9
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
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{
126 rbDynamicsWorld *world = new rbDynamicsWorld;
127
128 /* collision detection/handling */
130
133
134 world->pairCache = new btDbvtBroadphase();
135
136 world->filterCallback = new rbFilterCallback();
138
139 /* constraint solving */
141
142 /* world */
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 */
166
167void RB_dworld_get_gravity(rbDynamicsWorld *world, float g_out[3])
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
179void RB_dworld_set_solver_iterations(rbDynamicsWorld *world, int num_solver_iterations)
180{
181 btContactSolverInfo &info = world->dynamicsWorld->getSolverInfo();
182
183 info.m_numIterations = num_solver_iterations;
184}
185
186/* Split Impulse */
187
188void RB_dworld_set_split_impulse(rbDynamicsWorld *world, int split_impulse)
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
230void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *object, int col_groups)
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--) {
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
390void RB_body_set_mass(rbRigidBody *object, float value)
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
415void RB_body_set_friction(rbRigidBody *object, float value)
416{
417 btRigidBody *body = object->body;
418 body->setFriction(value);
419}
420
422{
423 btRigidBody *body = object->body;
424 return body->getRestitution();
425}
426
427void RB_body_set_restitution(rbRigidBody *object, float value)
428{
429 btRigidBody *body = object->body;
430 body->setRestitution(value);
431}
432
434{
435 btRigidBody *body = object->body;
436 return body->getLinearDamping();
437}
438
439void RB_body_set_linear_damping(rbRigidBody *object, float value)
440{
441 RB_body_set_damping(object, value, RB_body_get_linear_damping(object));
442}
443
445{
446 btRigidBody *body = object->body;
447 return body->getAngularDamping();
448}
449
450void RB_body_set_angular_damping(rbRigidBody *object, float value)
451{
452 RB_body_set_damping(object, RB_body_get_linear_damping(object), value);
453}
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
468{
470}
471
473{
474 btRigidBody *body = object->body;
475 return body->getAngularSleepingThreshold();
476}
477
479{
481}
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{
739 rbMeshData *mesh = new rbMeshData;
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
909void RB_shape_set_margin(rbCollisionShape *shape, float value)
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
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
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
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 rbConstraint rbConstraint
Definition RBI_api.h:44
btBoxShape(const btVector3 &boxHalfExtents)
@ GIMPACT_SHAPE_PROXYTYPE
Used for GIMPACT Trimesh integration.
@ SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE
btBroadphaseProxy
btBvhTriangleMeshShape(btStridingMeshInterface *meshInterface, bool useQuantizedAabbCompression, bool buildBvh=true)
#define ACTIVE_TAG
#define DISABLE_DEACTIVATION
#define ISLAND_SLEEPING
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()
btTypedConstraint(btTypedConstraintType type, btRigidBody &rbA)
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
virtual btOverlappingPairCache * getOverlappingPairCache()=0
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
virtual void setOverlapFilterCallback(btOverlapFilterCallback *callback)=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
nullptr float
#define rot(x, k)
static float verts[][3]
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
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
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251