2009-11-04 8 views
18

현재 C++ 및 Ogre3D을 사용하여 작성중인 3D 우주 게임에 대해 Bullet Physics Library을 평가 중입니다. 나는 Ogre3D와 Bullet을 btMotionState에서 파생시키고 내 SceneNode를 연결하여 훌륭하게 통합했지만 지금은 달성해야 할 btRigidBody :: applyCentralImpulse 및 btRigidBody :: applyTorqueImpulse 메서드에 전달해야하는 값을 계산하는 데 많은 어려움을 겪고 있습니다. 내가 찾고있는 결과들.Bullet Physics - 신체의 로컬 공간에 토크 임펄스 적용

키보드의 왼쪽 또는 오른쪽 키를 누르면 우주선이 로컬 Z 축을 굴러 가기를 원합니다. UP 또는 DOWN 키를 누르면 로컬 X 축에서 피치를 지정합니다. A 또는 Z를 누르면 로컬 Z 축의 방향으로 가속/감속합니다. 저는 Ogre에서 일부 쿼터니언 수학을 사용하고 SceneNode에서 직접 translate/rotate를 적용 할 수 있습니다.하지만 Force/Torque 메서드를 사용하여 Bullet 엔진에이 값을 적용하여 피치/롤 이동을 계속합니다. 사용자가 키를 누르지 않아도 오브젝트가 마찰을 일으켜 필요한만큼 속도를 늦 춥니 다.

임펄스가 세계의 축을 사용하는 대신 본체의 현재 방향을 기반으로 작동하도록하기 위해이 두 가지 임펄스 방법에 필요한 값을 계산하려면 어떻게해야합니까?

감사합니다, 마크

업데이트 :

나는 진퇴에 필요한 충동을 해결 할 수 있었다, 그러나 나는 여전히 요/피치/롤 값을 재교육하는 방법을 고민하고있다 토크 임펄스 방식과 함께 사용하십시오.

if (mKeyboard->isKeyDown(OIS::KC_A)) 
    mBody->applyCentralImpulse(mBody->getWorldTransform().getBasis().getColumn(2) * 20 * time); 
if (mKeyboard->isKeyDown(OIS::KC_Z)) 
    mBody->applyCentralImpulse(mBody->getWorldTransform().getBasis().getColumn(2) * -20 * time); 
+0

임펄스 API에 쿼터니언을 전달하거나 쿼터니언을 전달할 수있는 것으로 변환 할 수 있습니까? – fbrereto

+0

API에서 볼 수 있듯이 선형 임펄스 방법은 월드 좌표에서 방향의 x, y, z 벡터 만 받아 들일 수 있으며 각도 임펄스 방법은 yaw에 대해 y, p, r 벡터 만 허용하며, 피치 (pitch), 롤 (roll) 등이있다. 수학은 약간 머리가 맞을 수 있지만 (점과 십자가 같은 것을 시각화하는 데는 어려움이 있습니다), 실제 Bullet API 자체는 내 머리 위로 완전히 새로운 것입니다 ...이 둘의 결합으로 인해 지금 불가능한 삶. – Lusid

답변

3

그래서 btRigidBody.h

나는 다음과 같은 코드를 알

보고 : 여기가 앞으로/뒤로 이동했던 방법은 지금은 그것을 이해

 void applyTorqueImpulse(const btVector3& torque) 
    { 
        m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor; 
    } 

을, 당신은 당신의 토크를 원한다 우주선과 관련된 x (또는 z) 축 주위의 회전 벡터를 일정 시간 동안 동일하게 유지해야합니다.

우리는 다음과 같이 일반화 회전 행렬을 결정할 수다시피 :

  1. 회전을 표준 축을 중심으로 한

이 방법 단계의

  • 역을 축 프리폼
  • 회전 맞추는 축 정렬 된 토크 (내 머리 꼭대기에서 알지 못하는)를 식별 할 수 있다면 다음과 같이 변환 할 수 있습니다.

    mBody->getWorldTransform()*axisAlignedXTorque 
    

    어느 것이 든 * 연산자는 Torque 벡터에서 월드 변환을 수행하기 위해 오버라이드됩니다.

  • 1
    body->getInvInertiaTensorWorld().inverse()*(body->getWorldTransform().getBasis()*torque) 
    

    좌절의 긴 기간 후에, 마침내 applyTorqueImpulse (또는 applyTorque)에 대한 입력으로서 전술을 사용하여 작동하는 신체 지방 토크를 얻었다. 나는 그것이 왜이 시점에서 작동 하는지를 이해하는 척하지 않지만 그것이 그렇다.총알에서

    :

    void applyTorqueImpulse(const btVector3& torque) 
    { 
         m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor; 
    } 
    

    아마이 tzenes 토크 정렬 축을 생산에 대해 언급 한 것입니다. 그러나 나는 다른 사람이 이런 방식으로하는 사례를 발견 할 수 없다는 것이 당황 스럽다. 확실하게 다른 누군가가 신체의 로컬 공간에 토크를 가하기를 원했던 것입니까? 그러나 내가 본 것처럼 온라인으로 찾은 것은 전혀 없었습니다.

    변형 * 토크 만 적용하면 세계 기원에서 벗어날 때까지 처음에는 작동하는 것처럼 보입니다. 따라서 더 멀리 회전하는 것이 어려워지면 원점을 벗어났습니다. 또는 몸이 어디에 있는지에 따라 물건이 반대로 회전하기 시작하면 이는 아마도 문제 일 것입니다.

    편집 : 여기 아, 그리고 내가 내 번역이 방법은 다음과 같습니다.

    btVector3 m = 신체 -> getWorldTransform() getBasis() * btVector3 (기총 소사, 이동, 상승);