Skip to content

Instantly share code, notes, and snippets.

@snipsnipsnip
Last active December 17, 2015 08:49
Show Gist options
  • Save snipsnipsnip/5583152 to your computer and use it in GitHub Desktop.
Save snipsnipsnip/5583152 to your computer and use it in GitHub Desktop.
A single-class btDiscreteDynamicsWorld wrapper
#ifndef INCLUDED_BULLET_HPP_
#define INCLUDED_BULLET_HPP_
#include "btBulletDynamicsCommon.h"
namespace bullet_wrapper {
// 使うクラスの目次がわりのtypedef
typedef btDiscreteDynamicsWorld World;
typedef btDefaultCollisionConfiguration Config;
typedef btCollisionDispatcher Dispatcher;
typedef btSequentialImpulseConstraintSolver Solver;
typedef btAxisSweep3 Cache;
typedef btInternalTickCallback BulletTickCallback;
typedef btIDebugDraw IDebugDraw;
typedef btCollisionShape Shape;
typedef btSphereShape SphereShape;
typedef btStaticPlaneShape PlaneShape;
typedef btBoxShape BoxShape;
typedef btDefaultMotionState MotionState;
typedef btRigidBody Body;
typedef Body::btRigidBodyConstructionInfo BodyConstructionInfo;
typedef btTypedConstraint Constraint;
typedef btGeneric6DofConstraint DofConstraint;
typedef btVector3 Vector;
typedef btScalar Scalar;
typedef btTransform Transform;
typedef btQuaternion Quaternion;
// btDiscreteDynamicsWorldを使いたいだけのラッパー
class Bullet
{
Config config;
Dispatcher dispatcher;
Cache cache;
Solver solver;
World world;
public:
Bullet(const Vector &from, const Vector &to, unsigned short max_bodies)
:
config(),
dispatcher(&config),
cache(from, to, max_bodies),
solver(),
world(&dispatcher, &cache, &solver, &config)
{
}
// クラスの外部からnewして挿入したオブジェクトの類を親切にもdeleteする
~Bullet()
{
// 登録されたbtConstraintを全てdeleteして削除
for (int i = world.getNumConstraints() - 1; i >= 0; i--)
{
Constraint *constraint = world.getConstraint(i);
world.removeConstraint(constraint);
delete constraint;
}
btCollisionObjectArray &objects = world.getCollisionObjectArray();
for (int i = objects.size() - 1; i >= 0; i--)
{
// これから削除するbtCollisionObject
btCollisionObject *object = objects[i];
// 紐付いたbtCollisionShapeを削除
if (btCollisionShape *shape = object->getCollisionShape())
{
// object間で共有してる場合の二重deleteを防ぐ
for (int j = 0; j < i; j++)
{
if (objects[j]->getCollisionShape() == shape)
{
objects[j]->setCollisionShape(NULL);
}
}
delete shape;
}
// 紐付いたbtMotionStateを削除
if (Body *body = Body::upcast(object))
{
if (btMotionState *state = body->getMotionState())
{
delete state;
}
}
world.removeCollisionObject(object);
delete object;
}
}
/* miso */
void step(btScalar delta = btScalar(1 / 60.0))
{
world.stepSimulation(delta);
}
void draw()
{
world.debugDrawWorld();
}
/* getter / setter */
void set_debug_draw(IDebugDraw *drawer)
{
world.setDebugDrawer(drawer);
}
void add_body(Body *body)
{
world.addRigidBody(body);
}
void remove_body(Body *body)
{
world.removeRigidBody(body);
}
void add_constraint(Constraint *constraint, bool disableCollisionsBetweenLinkedBodies)
{
world.addConstraint(constraint, disableCollisionsBetweenLinkedBodies);
}
void set_tick_callback(BulletTickCallback callback, void *callback_context, bool pre_tick)
{
world.setInternalTickCallback(callback, callback_context, pre_tick);
}
// predicates
// taken from http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Collision_Callbacks_and_Triggers
bool is_colliding(btCollisionObject *a, btCollisionObject *b)
{
typedef World::ContactResultCallback CallbackBase;
struct Callback : public CallbackBase
{
bool result;
virtual btScalar addSingleResult(btManifoldPoint&, const btCollisionObjectWrapper*, int, int, const btCollisionObjectWrapper*, int, int)
{
result = true;
return 0;
}
};
Callback callback;
callback.result = false;
world.contactPairTest(a, b, callback);
return callback.result;
}
};
} /* namespace bullet_wrapper */
#endif /* !defined(INCLUDED_BULLET_HPP_) */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment