JBulletことはじめ
http://jbullet.advel.cz/
オリジナルのBulletのほぼ忠実な移植のようだ。
OpenGL等によるビジュアルを伴わない最小のサンプル
http://bulletphysics.org/mediawiki-1.5.8/index.php/Hello_World
のJBullet版を書いてみた(scala-2.9向け)。
import com.bulletphysics.util.ObjectArrayList import com.bulletphysics.collision.broadphase.DbvtBroadphase import com.bulletphysics.collision.dispatch.CollisionDispatcher import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration import com.bulletphysics.collision.shapes import com.bulletphysics.dynamics.DiscreteDynamicsWorld import com.bulletphysics.dynamics.RigidBody import com.bulletphysics.dynamics.RigidBodyConstructionInfo import com.bulletphysics.dynamics.constraintsolver.SequentialImpulseConstraintSolver import com.bulletphysics.linearmath.DefaultMotionState import com.bulletphysics.linearmath.Transform import javax.vecmath object Main extends App { val broadphase = new DbvtBroadphase(); val collisionConfiguration = new DefaultCollisionConfiguration(); val dispatcher = new CollisionDispatcher(collisionConfiguration); val solver = new SequentialImpulseConstraintSolver; val dynamicsWorld = new DiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration); dynamicsWorld.setGravity(new vecmath.Vector3f(0,-10,0)); val groundShape = new shapes.StaticPlaneShape(new vecmath.Vector3f(0,1,0),1); val fallShape = new shapes.SphereShape(1); val groundMotionState = new DefaultMotionState(new Transform(new vecmath.Matrix4f( new vecmath.Quat4f(0,0,0,1),new vecmath.Vector3f(0,-1,0), 1.0f))); val groundRigidBodyCI=new RigidBodyConstructionInfo(0,groundMotionState,groundShape,new vecmath.Vector3f(0,0,0)); val groundRigidBody = new RigidBody(groundRigidBodyCI); dynamicsWorld.addRigidBody(groundRigidBody); val fallMotionState = new DefaultMotionState(new Transform(new vecmath.Matrix4f( new vecmath.Quat4f(0,0,0,1),new vecmath.Vector3f(0,50,0), 1.0f))); val mass = 1; val fallInertia=new vecmath.Vector3f(0,0,0); fallShape.calculateLocalInertia(mass,fallInertia); val fallRigidBodyCI=new RigidBodyConstructionInfo(mass,fallMotionState,fallShape,fallInertia); val fallRigidBody = new RigidBody(fallRigidBodyCI); dynamicsWorld.addRigidBody(fallRigidBody); var lastHeight=50.0f; for (i <- 0 until 300) { dynamicsWorld.stepSimulation(1/60.f,10); val trans=new Transform; fallRigidBody.getMotionState().getWorldTransform(trans); println("sphere height: %f(%f)".format(trans.origin.y, lastHeight-trans.origin.y)); lastHeight=trans.origin.y; } dynamicsWorld.removeRigidBody(fallRigidBody); dynamicsWorld.removeRigidBody(groundRigidBody); }
注意点としては、bulletのクラスのプレフィクスであるbtは無い。次に、btQuaternion, btVector3にあたるクラスがjbulletではなくてvecmathから提供される。btTransformの初期化は以下のようなコードになる。
new Transform(new vecmath.Matrix4f( new vecmath.Quat4f(0,0,0,1),new vecmath.Vector3f(0,-1,0), 1.0f))
TransformのコンストラクタでQuaternoinとVectorを受け付けるものはなくなっていて、vecmath.Matrix4f経由で作成するようだ。このときMatrix4fは第3の引数でscale値を取る。
そんなわけで最小の必要なjarは、jbullet.jarとvecmath.jarの2つである。なんにせよ、使い手は素のbulletをある程度知っていることを前提にされる。知っていればすんなりと変換していける感じだ。
だが、しかしbtGeneric6DofSpringConstraintが実装されていない(jbulletはbullet2.72ベースで、btGeneric6DofSpringConstraintは2.75で追加された)ことが発覚。jbulletにbtGeneric6DofSpringConstraintを移植するのは手間隙がかかるので、JMEに含まれるnative bulletというものを試してみることにした。