Плавное вращение с использованием Bullet и Ogre3D
Я страдал от проблемы, связанной с реализацией ориентировочных персонажей в игре, которую я реализую с использованием физики Ogre3D и Bullet.
Что у меня есть: Вектор направления, в котором движется персонаж, вместе с его текущей ориентацией.
Что мне нужно: установить ориентацию персонажа, чтобы он смотрел так, как он движется.
У меня есть фрагмент кода, который делает то, что я хочу:
btTransform src = body->getCenterOfMassTransform();
btVector3 up = BtOgre::Convert::toBullet(Ogre::Vector3::UNIT_X);
btVector3 normDirection = mDirection.normalized();
btScalar angle = acos(up.dot(normDirection));
btVector3 axis = up.cross(normDirection);
src.setRotation(btQuaternion(axis, angle));
body->setCenterOfMassTransform(src);
Где "тело" - это твердое тело, которое я пытаюсь сориентировать.
Этот фрагмент имеет несколько проблем:
1) При изменении направления он имеет тенденцию к "дрожанию", т. Е. Быстро поворачивается в одну сторону, а затем в течение секунды или около того, прежде чем исправиться в той ориентации, в которой он должен находиться.
2) В большинстве случаев, когда код запускается, я получаю ошибку подтверждения от btQuaternion Буллета наassert(d != btScalar(0.0));
Кто-нибудь может помочь?
Спасибо!
1 ответ
Я думаю, что вы не должны использовать такие функции, как 'acos' для таких вещей, так как это может привести к некоторым несоответствиям в граничных случаях, таких как поворот на 180 против 0, упомянутый выше. Вы также можете получить высокую числовую ошибку для таких данных.
Во-вторых, в общем, вы должны избегать установки явного положения и вращения в физических движках, а вместо этого применять силы и моменты, чтобы ваше тело двигалось так, как вы хотите. Ваш текущий подход может работать отлично сейчас, но когда вы добавите другой объект и заставите своего персонажа занимать то же пространство, ваша симуляция взорвется. И на этом этапе это очень сложно исправить, поэтому лучше сделать это с самого начала:) .
Я знаю, что найти правильную силу / крутящий момент может быть сложно, но это лучший способ сделать вашу симуляцию последовательной.