bulletのjavaラッパでHelloWorld成功
まず、bullet本体のbtRigidBody::btRigidBodyConstructionInfoと、btTypedConstraint::btConstriantInfo1およびbtTypedConstraint::btConstraintInfo2を内部クラスから外に出す。で、bulletを再ビルド。この、作業自体は簡単。
bullet.i
%module bullet %{ #include <btBulletDynamicsCommon.h> %} %javaconst(1); %include "LinearMath/btScalar.h" %include "LinearMath/btVector3.h" %include "LinearMath/btQuaternion.h" %include "LinearMath/btTransform.h" %include "LinearMath/btMotionState.h" %include "LinearMath/btDefaultMotionState.h" %include "btBulletCollisionCommon.h" %include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" %include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.h" %include "BulletCollision/BroadphaseCollision/btDispatcher.h" %include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h" %include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h" %include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" %include "BulletCollision/CollisionShapes/btCollisionShape.h" %include "BulletCollision/CollisionShapes/btConvexShape.h" %include "BulletCollision/CollisionShapes/btConvexInternalShape.h" %include "BulletCollision/CollisionShapes/btSphereShape.h" %include "BulletCollision/CollisionShapes/btConcaveShape.h" %include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" %include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" %include "BulletDynamics/Dynamics/btContinuousDynamicsWorld.h" %include "BulletDynamics/Dynamics/btSimpleDynamicsWorld.h" %include "BulletDynamics/Dynamics/btRigidBodyConstructionInfo.h" %include "BulletDynamics/Dynamics/btRigidBody.h" %include "BulletDynamics/ConstraintSolver/btConstraintSolver.h" %include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" %include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" %include "BulletDynamics/ConstraintSolver/btHingeConstraint.h" %include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h" %include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h" %include "BulletDynamics/ConstraintSolver/btSliderConstraint.h" %include "BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h" %include "BulletDynamics/ConstraintSolver/btUniversalConstraint.h" %include "BulletDynamics/ConstraintSolver/btHinge2Constraint.h" %include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
superクラスのヘッダが、subクラスのヘッダより上に来るように並べる必要がある。
Mingwのgcc-4.5.2でビルドした。
vcではswig実行時にifdefで__MINGW32__が無いほうに分岐したときに死ぬのでできなかった。
cl.exeへの最適化指示?(attribute(xxx))とか__forceinline)がswig的にシンタックスエラーになるっぽい。
PACKAGE=org.swig.bullet DST=src/main/java/org/swig/bullet bullet.dll: bullet_wrap.o g++ -shared -o $@ $^ -L../../bullet-2.78-build/lib -lBulletDynamics -lBulletCollision -lLinearMath -Wl,--add-stdcall-alias bullet_wrap.o: bullet_wrap.cxx g++ -c -o $@ -IC:/Java32/jdk1.6.0_26/include -IC:/Java32/jdk1.6.0_26/include/win32 -I../src $^ bullet_wrap.cxx: bullet.i mkdir -p $(DST) swig -c++ -java -I../src -outdir $(DST) -package $(PACKAGE) -D_WIN32 -D__MINGW32__ bullet.i clean: rm -rf src *.cxx bullet.dll
dll作成時に-Wl,--add-stdcall-aliasをつけるのが必要で、これでしばらくはまった。
動作を確認したbulletのHello worldのテストコード。
先頭のSystem.loadLibraryでdllを指定している。
あとは、c++のコードをコピペしてスタックに変数を確保しているところをnewで置き換えたくらいである。
終了処理は全て省いているが、GC任せでいいことにしておこう。
Sample.java
import org.swig.bullet.*; class Sample { public static void main(String[] args){ System.loadLibrary("bullet"); btBroadphaseInterface broadphase = new btDbvtBroadphase(); btDefaultCollisionConfiguration collisionConfiguration = new btDefaultCollisionConfiguration(); btCollisionDispatcher dispatcher = new btCollisionDispatcher(collisionConfiguration); btSequentialImpulseConstraintSolver solver = new btSequentialImpulseConstraintSolver(); btDiscreteDynamicsWorld dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration); dynamicsWorld.setGravity(new btVector3(0,-10,0)); btCollisionShape groundShape = new btStaticPlaneShape(new btVector3(0,1,0),1); btCollisionShape fallShape = new btSphereShape(1); btDefaultMotionState groundMotionState = new btDefaultMotionState(new btTransform(new btQuaternion(0,0,0,1),new btVector3(0,-1,0))); btRigidBodyConstructionInfo groundRigidBodyCI=new btRigidBodyConstructionInfo(0,groundMotionState,groundShape,new btVector3(0,0,0)); btRigidBody groundRigidBody = new btRigidBody(groundRigidBodyCI); dynamicsWorld.addRigidBody(groundRigidBody); btDefaultMotionState fallMotionState = new btDefaultMotionState(new btTransform(new btQuaternion(0,0,0,1),new btVector3(0,50,0))); float mass = 1; btVector3 fallInertia=new btVector3(0,0,0); fallShape.calculateLocalInertia(mass,fallInertia); btRigidBodyConstructionInfo fallRigidBodyCI=new btRigidBodyConstructionInfo(mass,fallMotionState,fallShape,fallInertia); btRigidBody fallRigidBody = new btRigidBody(fallRigidBodyCI); dynamicsWorld.addRigidBody(fallRigidBody); for (int i=0 ; i<300 ; i++) { dynamicsWorld.stepSimulation(1/60.f,10); btTransform trans=new btTransform(); fallRigidBody.getMotionState().getWorldTransform(trans); System.out.println("sphere height: "+trans.getOrigin().getY()); } dynamicsWorld.removeRigidBody(fallRigidBody); dynamicsWorld.removeRigidBody(groundRigidBody); } }
swig素晴らしい。
めずらしく予定通りの作業量でこなせたのであった。
ということで、本題のMMDモーション再生への組み込みに進む。