2015-01-26 3 views
0

일부 일반적인 시뮬레이션에 gdx-bullet을 사용하려고합니다. 더 구체적으로 말하자면, 경사면에서 벗어날 때 구형의 롤링 마찰을 설정하려고합니다.libgdx 총알 3D 및 롤링 마찰로 NaN 발생

나는 구의 회전 마찰을 0이 아닌 값으로 설정했습니다. 나는 경사면 위에 위치시킨다. 구가 평면에 닿을 때까지 구가 내려오고 평면에서 굴러 내려야합니다. 그러나, 대신, 매트릭스는 (마지막 행을 제외한) 모든 NaN을로 대체 :

Step 36 
[1.0|0.0|0.0|0.0] 
[0.0|1.0|0.0|0.0] 
[0.0|0.0|1.0|2.0862775] 
[0.0|0.0|0.0|1.0] 

Step 37 
[NaN|NaN|NaN|NaN] 
[NaN|NaN|NaN|NaN] 
[NaN|NaN|NaN|NaN] 
[0.0|0.0|0.0|1.0] 

실행 예제 코드 :

import com.badlogic.gdx.math.Matrix4; 
import com.badlogic.gdx.math.Quaternion; 
import com.badlogic.gdx.math.Vector3; 
import com.badlogic.gdx.physics.bullet.Bullet; 
import com.badlogic.gdx.physics.bullet.collision.btBoxShape; 
import com.badlogic.gdx.physics.bullet.collision.btCollisionDispatcher; 
import com.badlogic.gdx.physics.bullet.collision.btCollisionShape; 
import com.badlogic.gdx.physics.bullet.collision.btDbvtBroadphase; 
import com.badlogic.gdx.physics.bullet.collision.btDefaultCollisionConfiguration; 
import com.badlogic.gdx.physics.bullet.collision.btSphereShape; 
import com.badlogic.gdx.physics.bullet.dynamics.btDiscreteDynamicsWorld; 
import com.badlogic.gdx.physics.bullet.dynamics.btRigidBody; 
import com.badlogic.gdx.physics.bullet.dynamics.btSequentialImpulseConstraintSolver; 
import com.badlogic.gdx.physics.bullet.linearmath.btMotionState; 


public class TestRollingFriction { 

    private static class BasicMotion extends btMotionState 
    { 
     Matrix4 m4 = new Matrix4(); 

     @Override 
     public void setWorldTransform(Matrix4 transform) { 
      m4.set(transform); 
     } 

     @Override 
     public void getWorldTransform(Matrix4 transform) { 
      transform.set(m4); 
     } 

     public String toString() { 
      return m4.toString(); 
     } 
    } 

    public static void main(String[] args) 
    { 
     Bullet.init(); 

     btDefaultCollisionConfiguration collisionConfiguration = new btDefaultCollisionConfiguration(); 
     btCollisionDispatcher dispatcher = new btCollisionDispatcher(collisionConfiguration); 
     btDbvtBroadphase broadphase = new btDbvtBroadphase(); 
     btSequentialImpulseConstraintSolver solver = new btSequentialImpulseConstraintSolver(); 
     btDiscreteDynamicsWorld collisionWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration); 
     collisionWorld.setGravity(new Vector3(0, 0, -9.8f)); 

     // Create a box at the origin, of size 1,1,1 
     btCollisionShape boxShape = new btBoxShape(new Vector3(1, 1, 1)); 
     // Rotate it by 20 degrees about the y axis so that the sphere will roll off it 
     btMotionState boxMotion = new BasicMotion(); 
     Quaternion q = new Quaternion(new Vector3(0,1,0),20); 
     boxMotion.setWorldTransform(new Matrix4(q)); 

     // Print out the box's matrix 
     System.out.println(boxMotion); 

     btRigidBody boxBody = new btRigidBody(0, boxMotion, boxShape); 
     boxBody.setFriction(2); 
     boxBody.setRollingFriction(0.2f); 
     collisionWorld.addRigidBody(boxBody); 

     btCollisionShape sphereShape = new btSphereShape(1); 
     btMotionState sphereMotion = new BasicMotion(); 

     // Set the sphere's position, rotation, and scale 
     Matrix4 tempM2 = new Matrix4(new Vector3(0, 0, 4), new Quaternion(), new Vector3(1,1,1)); 
     sphereMotion.setWorldTransform(tempM2); 
     btRigidBody sphereBody = new btRigidBody(3, sphereMotion, sphereShape); 

     // Does not matter what I put in here; 
       // If it's non-zero, then the matrix ends up with NaN in it. 
     sphereBody.setRollingFriction(0.2f); 
     sphereBody.setFriction(2); 

     collisionWorld.addRigidBody(sphereBody); 

     int count = 0;  
     while(count < 100) 
     { 
      collisionWorld.stepSimulation(0.05f); 

      System.out.println(count); 
      System.out.println(sphereMotion); 
      count++; 
     } 
    } 
} 

나는 안드로이드와 리눅스 데스크탑 모두에서 실행되는 동일한 결과를 얻을.

내가 잘못하고있는 아이디어가 있습니까? 감사합니다.

답변

0

나는 결국 무엇이 잘못되었는지 알아 냈습니다. 기본적으로 I :

  • 사용 볼의 구름 마찰
  • 설정 공의 localInteria 문제를 해결하기 위해 제로

에 I가 추가되면, 나는

Vector3 localInertia = new Vector3(); 
float mass=1; 
// Calculate the inertia of the sphere, with mass=1, 
// and store it into 'localInertia' 
sphereShape.calculateLocalInertia(mass, localInerertia); 

btRigidBody sphereBody = new btRigidBody(mass, sphereMotion, sphereShape, localInertia); 

를 호출 할 필요 국부적 인 관성을 얻기 위해 전화를 건 다음 강체에 추가하면 제대로 작동하기 시작합니다.