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.