2013-08-23 24 views
0

我想製作一個遊戲引擎,並且我想要一個由播放器控制的攝像頭,並且也受其他jBullet實體影響Java。我被建議使用運動對象,所以我擡頭看着它們。我找不到任何我能理解的文檔。如何在jBullet中創建運動對象?

有人可以解釋如何設置和使用運動學對象或至少告訴我我可以從哪裏開始?

+0

爲什麼這會降低投票率? – Prior99

回答

2

KinematicCharacterController的文檔,發現here不是太完全有幫助,但CharacterDemo中的源代碼可以。演示中定義了兩個主要屬性。

public KinematicCharacterController character; 
    public PairCachingGhostObject ghostObject; 

ghost可用於動態碰撞檢測,因爲它不會自動對這些事件做出反應。可以通過更改變換來移動角色。

//from the source src\com\bulletphysics\demos\character\CharacterDemo.java 
    Transform startTransform = new Transform(); 
    startTransform.setIdentity(); 
    startTransform.origin.set(0.0f, 4.0f, 0.0f); 

    Vector3f worldMin = new Vector3f(-1000f,-1000f,-1000f); 
    Vector3f worldMax = new Vector3f(1000f,1000f,1000f); 
    AxisSweep3 sweepBP = new AxisSweep3(worldMin, worldMax); 

    ghostObject = new PairCachingGhostObject(); 
    ghostObject.setWorldTransform(startTransform); 
    sweepBP.getOverlappingPairCache().setInternalGhostPairCallback(new GhostPairCallback()); 
    float characterHeight = 1.75f * characterScale; 
    float characterWidth = 1.75f * characterScale; 
    ConvexShape capsule = new CapsuleShape(characterWidth, characterHeight); 
    ghostObject.setCollisionShape(capsule); 
    ghostObject.setCollisionFlags(CollisionFlags.CHARACTER_OBJECT); 

    float stepHeight = 0.35f * characterScale; 
    character = new KinematicCharacterController(ghostObject, capsule, stepHeight); 


    dynamicsWorld.addCollisionObject(ghostObject, CollisionFilterGroups.CHARACTER_FILTER, (short)(CollisionFilterGroups.STATIC_FILTER | CollisionFilterGroups.DEFAULT_FILTER)); 

    dynamicsWorld.addAction(character); 

這也將是明智的擴展MotionState類來保存變換

public class MyMotionState extends MotionState { 
     private Transform worldTransform; 
     public MyMotionState() 
     { 
      worldTransform = new Transform(); 
      worldTransform.setIdentity(); 
     } 

     @Override 
     public Transform getWorldTransform(Transform worldTrans) 
     { 
      worldTrans.set(worldTransform); 
      return worldTrans; 
     } 

     @Override 
     public void setWorldTransform(Transform worldTrans) 
     { 
      worldTransform.set(worldTrans); 
     } 
} 

和運動學鏈接到一個剛體用於應用物理學的性格,和渲染得到的信息。

rigidBody.setCollisionFlags(rigidBody.getCollisionFlags() | CollisionFlags.KINEMATIC_OBJECT); 
    rigidBody.setActivationState(CollisionObject.DISABLE_DEACTIVATION); 

不要忘了在遊戲循環的每次迭代中更新一次物理引擎。

Transform transform = new Transform(); 
    transform.setIdentity(); 
    transform.origin.set(input.getX(), input.getY(), input.getZ()); 
    myMotionState.setWorldTransform(transform); 
    rigidBody.setCenterOfMassTransform(myMotionState.getWorldTransform()); 

如果你願意,你可以把這些你MainCharacter類或者無論你怎麼稱呼它(我喜歡它的面向對象的感覺和易於理解)

public class MainCharacter implements KeyListener, MouseListener 
    { 
     private DynamicsWorld world; 
     private MyMotionState myMotionState; 
     private RigidBody rigidBody; 
     private KinematicCharacterController character; 
     private ConvexShape shape; 
     private Texture texture; 
     private GhostObject ghost; 
     private Vector3f pos; 
     public MainCharacter(DynamicsWorld world, Vector3f initialPosition, ConvexShape shape, Texture texture) 
     { 
      this.world = world; 
      RigidBodyConstructionInfo constructInfo = new RigidBodyConstructionInfo(...); 
      this.myMotionState = myMotionState; 
      rigidBody = new RigidBody(constructInfo); 
      ghost = new GhostObject(); 
      character = new KinematicCharacterController(ghost,shape,1); 
     } 
     public void render() 
     { 
      glBegin(GL_QUADS); 
       glVertex3f(... 
       ... 
      glEnd(); 
     } 
     public void mouseMoved(MouseEvent e) 
     { 
       //pseudocode 
       this.yaw = e.getDX(); 
       this.pitch = e.getDY(); 
     } 
     public void keyPressed(KeyEvent e) 
     { 
      Vector3f dPos = null; 
      if(e.getKeyChar() == 'W') 
      { 
       dPos.x = 10; 
      } 
      else if(e.getKeyChar() == 'S') 
      { 
       dPos.x = -10; 
      } 
      etc... 

      move(dPos.x,dPos.y,dPos.z); 
     } 
     public void move(float dx, float dy, float dz) { 
      pos.z += dx * (float) Math.cos(Math.toRadians(yaw - 90)) + dz *  Math.cos(Math.toRadians(yaw)); 
      pos.x -= dx * (float) Math.sin(Math.toRadians(yaw - 90)) + dz * Math.sin(Math.toRadians(yaw)); 
      pos.y += dy * (float) Math.sin(Math.toRadians(pitch - 90)) + dz * Math.sin(Math.toRadians(pitch)); 
      //pseudocode 
      rigidBody.update(pos); 
      world.update(pos); 
     } 
    } 

我希望我有幫助您。

+0

「擴展MotionState類以保存變換也是明智的選擇」 我該怎麼做? – Sierox

+0

已編輯以顯示整個MyMotionState類。此外,MotionState在循環的每次迭代中將其數據發送給世界,所以如果您擁有自己的數據,則可以更改其數據(即位置) – user2727804