В очень простых трехмерных гоночных играх как обрабатываются столкновения?

9

Мне было интересно, как происходят столкновения в некоторых простых гоночных играх для 3d автомобилей (особенно в таких играх, как Outrun 2 / Motoracer).

В классических автомобильных гоночных играх со сложной средой (открытый мир), я думаю, это делается с помощью базовой коробки (для автомобиля) для столкновения самолета (для трассы, зданий и прочего). Все это было бы оптимизировано с помощью некоторых ограничивающих рамок (именно так во многих играх происходит столкновение).

В такой игре, как Outrun 2 / Motoracer, игровой процесс настолько прост, что разработчикам это может и не понадобиться, и все могло бы быть значительно упрощено. Для тех, кто никогда не играет в нее, вот что конкретно:

  • Автомобиль / велосипед всегда наклеен на дороге.
  • Дорога всегда одинакового размера и имеет очень простую форму.
  • Единственная возможность - следовать по этой дороге, невозможно покинуть дорогу или столкнуться с чем-то другим (кроме других автомобилей / мотоциклов, но нам все равно).
  • Когда вы сталкиваетесь с дорогой, происходит очень простое аркадное столкновение (автомобиль просто отталкивается от него)

Вот как я думаю, что столкновение (возможно) было сделано:

Весь трек можно считать гигантской кривой Безье. Из этой кривой могут быть сгенерированы дорожные полигоны (с использованием векторов спереди, слева и вверх, сгенерированных из кривой). Другие элементы (например, дома, деревья, ...) также могут быть размещены и выровнены с помощью этого метода.

Затем, чтобы обработать столкновения (и нарисовать машину):

1) Найти ближайшую позицию на 3d-кривой из текущей 3d-позиции автомобиля. Другими словами, преобразуйте положение 3d-автомобиля в положение кривой Безье. Каждое 3d-положение на дороге можно рассматривать как смещение вдоль 3d-кривой ( t) + боковое смещение ( d). Проверьте изображение ниже, если оно нечеткое (это 2d пример, но это легко относится к 3d).

введите описание изображения здесь

когда t = 0, автомобиль находится в начале участка пути, когда t = 1, автомобиль находится в конце. когда d = -1 или 1 автомобиль находится на границе пути, когда d = 0 автомобиль находится в середине дороги

2) выровнять машину на дорогу с использованием tи d(очень просто: для любого tи dзначения я могу получить 3d позиции + вверх / передний / левые векторы). машина теперь наклеена на дорогу

3) проверить боковое смещение dавтомобиля. если значение слишком велико (d > 1)или слишком низкое, (d < -1)автомобиль не в пути. просто обрежьте его, чтобы поставить машину в нужное место.

Это также делает 3D-выборку очень простой, просто нарисуйте дорожку от текущей tпозиции автомобиля до t + some_big_enough_value_to_avoid_visible_clipping.

Или, может быть, я совершенно неправ: было бы намного быстрее и проще просто проверить столкновение автомобиля (ограничивающий прямоугольник) и очень упрощенный набор полигонов, представляющих трек (без зданий и тому подобного). 3D-мир (и полученная в результате модель коллизии) просто генерировались бы раньше с использованием какого-либо стороннего инструмента (больше нет 3D-кривой при запуске игры, просто куча полигонов).

tigrou
источник

Ответы:

16

Я работал над несколькими коммерческими играми, похожими на те, которые вы описываете.

В каждой из этих игр у нас на самом деле были полигоны, создающие невидимую «стену» вдоль сторон трека, и мы проводили традиционное тестирование столкновений с этими стенами. Это означало, что у нас могут быть некоторые дополнительные встречные опасности на обочине дороги, внутри невидимых стен, а также мы можем изменять ширину дороги быстрее, чем вы обычно можете с помощью сплайнового подхода.

Но с учетом вышесказанного мы также сделали то, что вы перечислили в разделе о том, как, я думаю, будет работать коллизия , чтобы защититься от туннелирования / сбоев коллизий, и эта система также активно использовалась для гоночной логики ИИ. Мы также использовали его для определения того, какие машины лидировали, чтобы мы могли отображать индикатор «1-й / 2-й / 3-й / и т. Д.» В HUD. Иногда эти данные также использовались для возрождения автомобиля после крупной аварии.

Одна вещь, которую вы пропустили в том, как я думаю, что столкновение будет работать, это то, что когда вы работаете со сплайнами, как это, вы обычно даете ребра сплайнов, Ребра - это биты данных, выражающие, как далеко проходит дорожка вбок в каждом направлении от сплайна. Таким образом, для сплайна длиной 100 метров у вас может быть 50 ребер, которые дают ширину колеи каждые два метра по всей длине. Это позволяет вашей дорожке изменять ширину по длине. В играх, над которыми я работал, эти ребра также различали «поверхность дорожки» и «зону вождения». Таким образом, у вас будет один набор ширины дороги, показывающий, как далеко от середины сплайна у вас есть хорошая асфальт, а затем другая ширина, указывающая, как далеко песок / трава / все, что выходит за пределы этого. Это позволило нам иметь игроков, способных проехать разумное расстояние вне трассы, но при этом ИИ знал, где было реальное дорожное покрытие.

Многие игры, над которыми я работал, также хранили другие данные в ребрах; одна игра запекла информацию о освещении трека в ребра, чтобы легко вычислить, была ли область в тени (которая затем использовалась для рендеринга автомобиля, решить, следует ли рисовать блики объектива и другие эффекты). Еще один был запечатлен в информации о том, какие места размещения кинематографической камеры могли видеть эту часть сплайна, поэтому нам не приходилось выполнять вычисления на линии прямой видимости во время повторов. Еще один включал информацию о том, сколько полос было на сплайне, в каком направлении они шли и горизонтальное смещение, где была расположена каждая полоса. Это позволило нам включить транспортные машины, которые могли бы правильно проехать по полосам движения. Ребра отлично подходят для хранения любых различных данных, которые могут вам понадобиться о вашем дорожном покрытии.

Ребра обычно хранятся в массиве, который связан со сплайном. По соображениям скорости обычная реализация будет иметь равномерно расположенные ребра, поэтому, когда вы знаете расстояние объекта вдоль сплайна, вы можете вычислить индекс ближайшего ребра в массиве, разделив расстояние вдоль сплайна на расстояние между ребрами. В противном случае вы застреваете, выполняя бинарный поиск по массиву ребер, чтобы найти правильные данные о ширине дороги.

Ваше описание отбраковки дает хорошее базовое описание того, как можно использовать сплайн-подход, но на самом деле это немного сложнее, чем вы предлагаете - если вы используете сплайны для отбраковки таким образом, длинные повороты шпильки часто не будут рисовать противоположную сторону поворота, так как при измерении расстоянием вдоль пути противоположная сторона поворота может быть очень далеко, даже если он находится всего в нескольких метрах при измерении по прямой линии, Кроме того, расстояния, на которых можно видеть геометрию мира, обычно отличаются от расстояний, на которых можно видеть сетку треков, поэтому они тоже не вписываются в эту систему. Мой опыт показывает, что в большинстве случаев лучше не полагаться на логику следования дорожек для определения, следует ли рисовать модель; это намного более надежно и вызывает меньше глюков, чтобы использовать стандартное тестирование усеченной камеры для этого.

Тревор Пауэлл
источник
Информативно и интересно читать ответ
onedayitwillmake
0

В своем гонщике OpenGL я изначально начинал с использования двух кругов для определения границ трассы, но это выглядело слишком хлопотно. Я просто использую glReadPixel, чтобы прочитать цвет пикселя. Если автомобиль игрока находится над зеленым (травянистым) пикселем, то движение еще более ограничено. Это очень мало влияет на производительность.

ztech79
источник
Похоже, вы описываете 2D-игру (круги, сталкивающиеся с цветами пикселей). Это так? Тогда ответ оффтоп.
Кромстер
Я имею в виду игру в перспективе. glReadpixel может быть применен в режиме 2D или 3D-перспективы.
ztech79