c++ physics ogre3d bullet

c++ - Física de bala: aplique un impulso de par en el espacio local del cuerpo



physics ogre3d (2)

Actualmente estoy evaluando la Biblioteca de Física de Bullet para un juego espacial en 3D que estoy escribiendo usando C ++ y Ogre3D . Logré que Ogre3D y Bullet se integraran muy bien al derivar de btMotionState y conectar mis SceneNodes, pero ahora tengo muchos problemas para calcular qué valores debo pasar a btRigidBody :: applyCentralImpulse y btRigidBody :: applyTorqueImpulse métodos para lograr Los resultados que estoy buscando.

Cuando presiono las teclas IZQUIERDA o DERECHA en el teclado, quiero que la nave espacial ruede en el eje Z local. Cuando presiono ARRIBA o ABAJO, quiero que se desplace en el eje X local. Cuando presiono A o Z, quiero que acelere / desacelere en la dirección del eje Z local. Puedo lograr esto perfectamente en Ogre usando algunas matemáticas de cuaternión y aplicando la conversión / rotación directamente en el SceneNode, pero realmente quiero aplicar estos valores en el motor Bullet usando los métodos de fuerza / torque para que continúe moviéndose / pitch / roll incluso después de que el usuario deja de presionar las teclas, la fricción actuará sobre el objeto para reducir la velocidad según sea necesario.

Entonces, ¿cómo calculo los valores necesarios para proporcionar estos dos métodos de impulso a fin de garantizar que el impulso actúe en función de la orientación actual del cuerpo en lugar de utilizar los ejes del mundo?

Gracias marc

Actualizar:

Pude calcular los impulsos necesarios para el movimiento hacia adelante y hacia atrás, pero todavía estoy luchando con la forma de reorientar los valores de guiñada / inclinación / balanceo para usarlos con el método de impulso de par. Así es como hice el movimiento de avance / retroceso:

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);


Así que mirando btRigidBody.h

Observo el siguiente código:

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

Ahora como lo entiendo, quieres que tu Torque sea igual a algunas veces constantes el vector de rotación alrededor del eje x (o z) asociado con tu nave espacial.

Como sabemos, la matriz de rotación generalizada se puede determinar de la siguiente manera:

  1. Girar para alinear la preforma del eje
  2. Rotación sobre el eje canónico
  3. Inverso del paso 1

Esto significa que si puedes identificar un par alineado con el eje (que no conozco en la parte superior de mi cabeza) puedes transformarlo con tu:

mBody->getWorldTransform()*axisAlignedXTorque

Que de acuerdo con http://www.bulletphysics.com/Bullet/BulletFull/classbtTransform.html el operador * aquí se reemplaza para preformar la transformación del mundo en el vector Torque.


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

Después de un largo período de frustración, finalmente conseguí el torque local del cuerpo para trabajar utilizando lo anterior como entrada para applyTorqueImpulse (o applyTorque). No pretendo entender por qué funciona en este punto, pero lo hace.

Desde Bullet:

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

Quizás esto es lo que mencionaron los tzenes sobre la producción del par alineado con el eje. Pero me sorprende que no pueda encontrar ningún ejemplo de que alguien más lo haga de esta manera. ¿Seguramente alguien más ha querido aplicar torque en el espacio local del cuerpo? Pero nada de lo que encontré en línea funcionó, a pesar de que se veía como debería.

Si solo aplicas transform * torque, parecerá que funciona al principio, hasta que comiences a alejarte del origen de tu mundo. Por lo tanto, si siente que es más difícil rotar, cuanto más lejos esté del origen, o si las cosas comienzan a girar en sentido inverso según el cuerpo, probablemente este sea su problema.

EDIT: Ah, y aquí está como tengo mis traducciones:

btVector3 m = body-> getWorldTransform (). getBasis () * btVector3 (strafe, move, rise);