Я экспериментирую с OpenGL 3.2+ и начинаю загружать файлы / модели Obj в 3D и пытаюсь взаимодействовать с ними.
(следующие уроки из таких источников, как этот сайт)
Мне было интересно, какой самый простой способ (если это возможно) настроить обнаружение столкновений между двумя существующими (загруженными) объектами / моделями Obj без использования сторонних физических движков и т. Д.?
Самый простой алгоритм, который может соответствовать вашим критериям, обнаруживает столкновения между сферами, что завершает ваши сетки. Вот Вы можете увидеть пример реализации.
Простейшая модель столкновения — использовать ограничивающие рамки для столкновения. Принцип прост: вы окружаете свой объект коробкой, определяемой двумя точками, минимальной и максимальной. Затем вы используете эти точки, чтобы определить, пересекаются ли два поля.
В моем движке структура ограничивающего прямоугольника и метода обнаружения столкновений установлены следующим образом:
typedef struct BoundingBox
{
Vector3 min; //Contains lowest corner of the box
Vector3 max; //Contains highest corner of the box
} AABB;
//True if collision is detected, false otherwise
bool detectCollision( BoundingBox a, BoundingBox b )
{
return (a.min <= b.max && b.min <= a.max);
}
Другой простой способ — использовать сферы. Этот метод полезен для объектов, которые имеют одинаковый размер во всех измерениях, но он создает много ложных столкновений, если это не так. В этом методе вы окружаете свой объект сферой с радиусом radius
и центральное положение position
и когда дело доходит до столкновения, вы просто проверяете, меньше ли расстояние между центрами, чем сумма радиусов, и в этом случае две сферы пересекаются.
Снова фрагмент кода из моего движка:
struct Sphere
{
Vector3 position; //Center of the sphere
float radius; //Radius of the sphere
};
bool inf::physics::detectCollision( Sphere a, Sphere b )
{
Vector3 tmp = a.position - b.position; //Distance between centers
return (Dot(tmp, tmp) <= pow((a.radius + b.radius), 2));
}
В коде выше Dot()
вычисляет скалярное произведение двух векторов, если вы укажете вектор на себя, это даст вам (по определению) величину вектора в квадрате. Обратите внимание, что я на самом деле не получаю квадратные корни, чтобы получить реальные расстояния, и вместо этого я сравниваю квадраты, чтобы избежать дополнительных вычислений.
Вы также должны знать, что ни один из этих методов не является совершенным и время от времени будет давать ложное обнаружение столкновений (если объекты не являются идеальными коробками или сферами), но это является компромиссом простой реализации и сложности вычислений. Тем не менее, это хороший способ начать обнаружение столкновений.