Paveltrpn GitHub IO

Posts

About

Todo

Начало работы с Bullet Physics Engine

Bullet Physics - обширная библиотека для симуляции физических эффектов в реальном времени, предназначенная для игр, специальных эффектов, машинного обучения и т.д. Включает в себя различные инструменты для симуляции физики твёрдых тел, связанных и не связанных ограничителями, симуляции ткани, упругих, мягких объектов, библиотеку методов линейной алгебры и средства для распаралеливания расчётов.

В этой заметке будет описано как скачать и собрать Bullet Physics Engine из исходиков и показана небольшая программа, демонстрирующая работу этой замечательнйо библиотеки.

Получение дистрибутива библиотеки

Скачиваем исходные коды с github.com:

git clone https://github.com/bulletphysics/bullet3

Сборка

Собираем с помощью CMake, традиционным способом:

cd <bullet_dir>
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=<path> .. -G "MinGW Makefiles"
make -j<over 9000 cores>
make install

Единственное "но" в моём случае и с моим окружением (Windows 10, MinGW-W64, Cmake 3.18.2, GCC 11.1.0) cmake выдал следующее -

CMake Error at Extras/BulletRoboticsGUI/CMakeLists.txt:188 (INSTALL):
INSTALL FILES given no DESTINATION!
  
  
CMake Error at Extras/BulletRobotics/CMakeLists.txt:309 (INSTALL):
INSTALL FILES given no DESTINATION!
  
  
-- Configuring incomplete, errors occurred!
See also "E:/github.com/bullet3/build/CMakeFiles/CMakeOutput.log".

Ситуацию удалось исправить редактированием соответствующих фаилов CMakeLists.txt в строках 188 и 309 соответственно, было:

...
    DESTINATION
    ${PKGCONFIG_INSTALL_PREFIX}
...

Стало:

...
    DESTINATION include
    ${PKGCONFIG_INSTALL_PREFIX}
...

make install в моём случае делает непонятные вещи, и поэтому вручную помещяем фаилы *.a из папки build/lib и заголовочные файлы в выбраную для установки папку.

В общем случае, если /build/examples/ExampleBrowser/App_ExampleBrowser.exe создан, запускается и показывает такие вещи, то сборку можно считать законченой.

Демо для теста свежесобранного bullet engine

Тестировать всё это добро будем с помощью демки. Собственно демо будет основано на встроенных примерах из дистрибутива bullet, но для лучшего усвоения материала перепишем всё самостоятельно. Само демо можно найти тут - https://github.com/paveltrpn/demos в папке 014_*.

Использовать будем C++ (конечно-же), OpenGL и всё необходимое для него (GLM, GLFW, GLEW), а так же самописные вспомогательные классы (не будем на них останавливаться подробно) для организации простой геометрии, загрузки текстур с диска (обёртка над libjpeg, libtga) и др.

Базовая структура приложения выглядит так:

...
void main(int argc, char *argv[]) {
    //Инициализация приложения, создание окна, загрузка ресурсов, в том числе
    //инициализация bullet engine
    appSetup();

    //Очевидно, главный цикл
    appLoop();

    //Освобождаем ресурсы
    appDefer();

    return 0;
}
...

В глабальном скоупе объявляем всё необходимое для bullet engine и напишем функцию для инициализации всего этого:

...
btDefaultCollisionConfiguration* 		collisionConfiguration;
btCollisionDispatcher* 					dispatcher;
btBroadphaseInterface* 					overlappingPairCache;
btSequentialImpulseConstraintSolver* 	solver;
btDiscreteDynamicsWorld* 				dynamicsWorld;
CDebugDraw*								debugDraw;

...

void initBulletPhysicsWorld() {
    collisionConfiguration = new btDefaultCollisionConfiguration();

    dispatcher = new btCollisionDispatcher(collisionConfiguration);

    overlappingPairCache = new btDbvtBroadphase();

    solver = new btSequentialImpulseConstraintSolver;

    debugDraw = new CDebugDraw;

    dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);

    debugDraw->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
    dynamicsWorld->setDebugDrawer(debugDraw);
    
    dynamicsWorld->setGravity(btVector3(0, -10, 0));
}
...

Разберём подробнее что тут к чему (опираясь на официальную документацию bullet engine).

  btDefaultCollisionConfiguration - класс служит для настройки стекового аллокатора памяти, pool аллокатора bullet engine.
  btCollisionDispatcher - класс предоставляет алгоритмы для управления Convex-Convex и Convex-Concave тел, участвующих во взаимодействии.
  btBroadphaseInterface - класс предоставляет интерфейс для определения перекрывающихся AABB-пар объектов. Некоторые имплементации этого интерфейса включают в себя btAxisSweep3, bt32BitAxisSweep3 и btDbvtBroadphase. Действительную обработку перекрытий и столкновений AABB-пар, а так-же хранение, добавление и удаление таких пар берёт на себя класс btOverlappingPairCache
  btSequentialImpulseConstraintSolver - это быстрая имплементация (с использованием SIMD) метода Гаусса — Зейделя (классический итерационный метод решения СЛАУ).
  btDiscreteDynamicsWorld - обеспечивает дискретное моделирование твердотельных объектов, этот класс заменяет устаревшие CcdPhysicsEnvironment/CcdPhysicsController.
  CDebugDraw - класс, унаследованный от btIDebugDraw и предоставляющий средства для отладочного вывода (рендера) тел, зарегестрированных в btDiscreteDynamicsWorld.