i just wanted to let you guys know that we're working on a fresh swig file for binding bullet to lua and possibly other scripting languages (C#,python,ruby,...)
it's early work in progress and there are still many things missing, but a few basic problems have been solved and the hello world example already works in lua,
so i though i'd post it here as it might help other people trying to make swig bindings.
required files for binding generation
http://zwischenwelt.org/svn/cliffrider/ ... e/bullet.i
http://zwischenwelt.org/svn/cliffrider/ ... tionInfo.i
http://zwischenwelt.org/svn/cliffrider/ ... internal.i
http://zwischenwelt.org/svn/cliffrider/ ... isSweep3.i
http://zwischenwelt.org/svn/cliffrider/ ... ig.debug.h
command to generate binding / wrapper :
swig -c++ -lua -Ibullet/ -Iinterfaces/ -Iinclude/ -o src/swig.bullet_L.cpp interface/bullet.i
to activate the binding :
Code: Select all
...
extern "C" {
extern int luaopen_bullet (lua_State* L);
}
...
luaopen_bullet(L);
...
Code: Select all
--~ ///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
local collisionConfiguration = bullet.btDefaultCollisionConfiguration()
--~ ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
local dispatcher = bullet.btCollisionDispatcher(collisionConfiguration)
--~ ///the maximum size of the collision world. Make sure objects stay within these boundaries
--~ ///Don't make the world AABB size too large, it will harm simulation quality and performance
local worldAabbMin = bullet.btVector3(-10000,-10000,-10000)
local worldAabbMax = bullet.btVector3(10000,10000,10000)
local maxProxies = 1024
local overlappingPairCache = bullet.btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
--~ ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
local solver = bullet.btSequentialImpulseConstraintSolver()
local dynamicsWorld = bullet.btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration)
--~ local test = dynamicsWorld:getWorldUserInfo()
dynamicsWorld:setGravity(bullet.btVector3(0,-10,0))
--~ ///create a few basic rigid bodies
local groundShape = bullet.btBoxShape(bullet.btVector3((50.),(50.),(50.))) -- btCollisionShape*
--~ //keep track of the shapes, we release memory at exit.
--~ //make sure to re-use collision shapes among rigid bodies whenever possible!
--~ btAlignedObjectArray<btCollisionShape*> collisionShapes;
local collisionShapes = bullet.btAlignedObjectArray_btCollisionShape()
collisionShapes:push_back(groundShape)
local groundTransform = bullet.btTransform()
groundTransform:setIdentity()
groundTransform:setOrigin(bullet.btVector3(0,-56,0))
if (1 == 1) then
local mass = 0
--~ //rigidbody is dynamic if and only if mass is non zero, otherwise static
local isDynamic = (mass ~= 0)
local localInertia = bullet.btVector3(0,0,0)
if (isDynamic) then
groundShape:calculateLocalInertia(mass,localInertia)
end
--~ //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
local myMotionState = bullet.btDefaultMotionState(groundTransform)
--~ btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
local rbInfo = bullet.btRigidBodyConstructionInfo(mass,myMotionState,groundShape,localInertia)
local body = bullet.btRigidBody(rbInfo)
--~ //add the body to the dynamics world
dynamicsWorld:addRigidBody(body)
end
if (1 == 1) then
--~ //create a dynamic rigidbody
-- local colShape = bullet.btBoxShape(bullet.btVector3(1,1,1))-- btCollisionShape*
local colShape = bullet.btSphereShape(1) -- btCollisionShape*
collisionShapes:push_back(colShape)
--~ /// Create Dynamic Objects
local startTransform = bullet.btTransform()
startTransform:setIdentity()
local mass = 1
--~ //rigidbody is dynamic if and only if mass is non zero, otherwise static
local isDynamic = (mass ~= 0)
local localInertia = bullet.btVector3(0,0,0)
if (isDynamic) then
colShape:calculateLocalInertia(mass,localInertia);
end
startTransform:setOrigin(bullet.btVector3(2,10,0))
--~ //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
local myMotionState = bullet.btDefaultMotionState(startTransform)
local rbInfo = bullet.btRigidBodyConstructionInfo(mass,myMotionState,colShape,localInertia)
local body = bullet.btRigidBody(rbInfo)
dynamicsWorld:addRigidBody(body)
end
--~ /// Do some simulation
--~ for (i=0;i<100;i++)
for i = 0,100-1 do
dynamicsWorld:stepSimulation(1/60,10);
--~ //print positions of all objects
local collisionWorld = bullet.CastTo_btCollisionWorld(dynamicsWorld) -- work around for swig-lua inheritance wrapping bug
for j=collisionWorld:getNumCollisionObjects()-1,0,-1 do
local obj = collisionWorld:getCollisionObjectArray()[j] -- btCollisionObject*
local body = bullet.btRigidBody_upcast(obj) -- btRigidBody*
if (body and body:getMotionState()) then
local trans = bullet.btTransform()
body:getMotionState():getWorldTransform(trans)
printf("world pos = %f,%f,%f\n",(trans:getOrigin():getX()),(trans:getOrigin():getY()),(trans:getOrigin():getZ()));
end
end
end
see also SWIG HP and Bullet SWIG 4 Java(2007)
Update : 25.02 : i ran into problems due to garbage collection, things like ( myMotionState,rbInfo , body ) have to be kept, if they are destroyed while still in use due to lua grabage collection, then there will be unexpected segfaults at some later point, hard to trace.