Я использую Bullet и пытаюсь создать алгоритм столкновения, который генерирует точки соприкосновения с поверхностью на основе куба вместе с соответствующим ответом на столкновение. Я также планирую расширить это, чтобы включить формы не-коробки, но это не является жизненно важным в данный момент. Я обнаружил, что использование треугольной сетки - слишком большая проблема с ОЗУ для больших карт.
Я попробовал процедуру, изложенную здесь Byte56 , однако у меня есть ряд вопросов относительно реализации этого с помощью Bullet:
- Как вы генерируете форму столкновения для мира? Вы используете нестандартную форму? Что вы собираетесь
m_shapeType
на нем? - Или вы все еще используете форму коробки размером с мир?
- Как вы обеспечиваете освобождение контактных точек?
- Как именно вы модифицируете
processCollision
?
Что я сделал:
- Я создал terrainShape
that extends
btBoxShape, the only difference being that
m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE`, чтобы я мог зарегистрировать новый алгоритм столкновения с диспетчером для объектов только с этой формой. - Я расширил
btRigidBody
класс таким же образом, как и Byte56 в его вопросе (см. Ссылку во 2-м абзаце), однакоcheckCollisionWith(CollisionObject * co)
возвращает true, если какой-либо воксель в AABB ofco
не является эфирным. Я расширил
btCollisionAlgorithm
класс аналогичным образомbtCompoundCollisionAlgorithm
,processCollision
выполнив следующее:- Проверьте сталкивающиеся объекты, переданные в качестве аргументов, и определите, какая территория, а какая - сущность.
- Очистить многообразия от любых дочерних алгоритмов.
- Вызов
resultOut->setPersistantManifold(resultOut)
- Создайте новые формы ящиков и преобразуйте их в AABB, занятом сталкивающимся объектом, и затем вызовите
m_dispatcher->findAlgorithm
. Сохраните форму, преобразование и найденный алгоритм в структуре дочернего алгоритма для каждого вокселя в AABB. - Перебирать все дочерние алгоритмы, вызывая
proccessCollision
. - Выполните итерацию по всем дочерним алгоритмам, удаляя любые теперь за пределами AABB сталкивающейся сущности. (звонит
~btCollisionAlgorithm()
тогдаm_dispatcher->freeCollisionAlgorithm()
) - Вызов
resultOut->refreshContactPoints()
.
Что работает: processCollision
вызывается всякий раз, когда AABB игрока пересекается с не воздушными вокселями.
Что не так: реакция на столкновение просто странная ... Сущность игрока начинает подниматься вверх. Если он входит во что-то, он сильно отскакивает. Иногда он не может продолжать двигаться по одной оси после того, как во что-то вошел. Я подозреваю, что происходит то, что точки контакта не освобождаются после реакции на столкновение, возможно, из-за того, что сущность игрока всегда находится в AABB объекта мира. Мне любопытно посмотреть, лаю ли я правильное дерево по отношению к processCollision
?
источник
Ответы:
К сожалению, я не смог получить достоверные результаты с помощью метода, описанного в ответе, на который вы ссылаетесь . Подобно вам, я получал бы странные плавающие события или ситуации, когда удаление вокселя приводило к тому, что объекты, плавающие на них, оставались плавающими в воздухе, или странные колеблющиеся перья падали на землю. Я отказался от этой стратегии для новой стратегии.
Я начал создавать собственные сетки столкновений для каждого участка воксельной местности. Я делаю это с
BvhTriangleMeshShape
. Это работает довольно хорошо:Есть более подробная информация о реализации пользовательских столкновений сеток здесь .
источник