crypt of decay - May 7th, 2019 [entries|archive|friends|userinfo]
ketmar

[ userinfo | ljr userinfo ]
[ archive | journal archive ]

May 7th, 2019

движемся к новому колдету [May. 7th, 2019|06:26 pm]
[Tags|]

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

но! можно зайти с другой стороны. нам, по сути, надо определить время (и сам факт) столкновения axis-algned box и line. для чего можно надуть линию при помощи minkowski sum, и потом просто сделать рэйкаст. звучит страшно? bear with me.

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

потому как — что такое наша линия? это дегенерировавший выпуклый мэш! он ограничен шестью плоскостями (четырьмя для линий, параллельных осям координат). поскольку линия у нас бесконечная по высоте, то достаточно создать две плоскости для самой линии, две вертикальных плоскости для ограничения линии справа и слева, и ещё две горизонтальных для верха и низа (если смотреть на линию сверху, как мы видим автомап; очевидно, что z top и z bottom плоскости не нужны, потому что мы никогда не сможем об них удариться). всё, у нас готов объём, который можно скормить совершенно стандартному алгоритму. и этот объём можно «надуть», чтобы «сдуть» ящик в точку. проблема решена.

почему так, а не более классическим путешествием по bsp, с проверкой листьев? ну, в принципе разница небольшая (санс «вывернутая логика», см. выше), но у нас, вообще-то, 2д чертёж. который вдобавок разложен в блокмапе. то есть, мы можем собирать линии и предметы одновременно, тупо шагая по блокмапу, и проверяя столкновения со всем собраным. тем более, что предметы отлично обрабатываются точно тем же алгоритмом, потому что это всё те же самые шесть плоскостей. и 3д-полы тоже, потому что… да-да, те же самые шесть плоскостей. и обычные полы с потолками, потому что… опять две ограничивающие плоскости. и всё это отлично работает для 3д-пути, хотя карта и 2д. и ещё у нас есть нормаль точки столкновения, так что можно сделать слайд. да, имеем небольшой оверхэд, но зато единообразный код для всего (одна функция свипа), и никаких дополнительных данных хранить не надо (все нужные плоскости игра уже посчитала и использует в других местах, а недостающие — тупо axis-aligned, и создаются даже без дот-продукта).

на самом деле это открывает и другие интересные возможности. например, проверка столкновений с md2/md3 моделями не просто по bounding box, а по их конкретной форме (строим для них бсп при загрузке, докидывем axial planes — бинго!), полиобъекты любой сложности и ориентации, в том числе ограниченые сверху и снизу, автоматическая обработка слопов… и всё это одним и тем же кодом. ну не прелесть ли?

ах, да. вращающиеся/движущиеся полидвери и прочие сложные штуки, которые должны отталкивать игрока — это снова таки всё тот же код. нам без разницы, считать ли время до столкновения, или минимально необходимое усилие для выталкивания одного объекта из другого: алгоритм может посчитать и это.

правда, оригинальный думокод по дороге делает ещё кучу всякого другого говна, и это надо будет бережно вытащить оттуда. но в итоге получим красивый универсальный код для трассировки ящиков, и код, который будет использовать трасер чтобы посчитать реальный путь, слайд, активировать лайндефы и ты пы. сам трасер останется в крестах, а остальное можно (и нужно!) вытащить в вавумцэ — и вуаля: моды смогут создавать кастомную физику. да хоть полноценный физический движок — все нужные примитивы есть, и колдет больше не ограничен рамками «ящик-ящик».

а ещё трэйсер отлично пригодится в создании navigational meshes для ботов: наконец-то можно будет надёжно определить, можно ли из одной точки субсектора попасть в другую. можно делать сложно, но можно и просто: каждый субсектор — нода. проверяем, можно ли (с учётом слайдов и прыжков) дойти из центра одного субсектора до центра другого — и вуаля: готова инфа по проходимости., даже с примерной оценкой стоимости. потом a-star, твики навигации — опа, вполне разумно бегающие боты без вручную расставленых вэйпоинтов.

тут очень кстати «вывернутая логика» дума: в ку3 приходилось делать сложные вычисления, чтобы построить карту «пустот», а в думе субсекторы уже предоставляют эту карту, и каждый субсектор гарантировано выпуклый. are we cool yet? ain't it cool?
Link6 meows|meow!

к прошлому [May. 7th, 2019|08:30 pm]
те полтора инвалида, которые таки прочитали прошлое псто, могли заметить, что для превращения линии в мэш на самом деле достаточно всего четырёх плоскостей: две дополнительных можно добавить по краям, с нормалями по направлению самой линии. можно и так, но тогда их придётся считать дот-продуктом, а axial planes не надо. зато проверять четыре, а не шесть. и две дополнительных можно посчитать заранее, потому что в думе линии не двигаются (за исключением полиобъектов). на колдет это не влияет, только на нормаль при ударе о край линии.

p.s.: блин, не дописал. конечно, так можно. но тогда «надувание» линии не будет правильным, увы: поскольку это не совсем честная minkowski sum, то для такого мэша надо дополнительные точки (в нашем случае — дополнительные bevel planes), иначе удары об края будут не совсем у края линии. ну, нарисуйте и увидите. а с axial planes всё чётко как надо (благодаря тому, что у нас aabb). чит, но всё тржидэ состоит из читов.
Link2 meows|meow!

и ещё к прошлому [May. 7th, 2019|09:35 pm]
если вы вдруг читали статью от биоварей про beveled bsp, то могли видеть, что они там добавляют более-менее честные bevel planes. а квака докидывает исключительно axial. это как раз потому, что биотвари используют bounding spheres, а не aabb. для слуая сфер «минковское надувание» работает более-менее приемлемо именно с такими «честными» плоскостями, и херово с axial. а для aabb — наоборот. это нюанс, который можно проебать, если не понять, что мы на самом деле читерим именно minkowski sum. которая, по уму, должна включать в себя все вершины обоих мэшей, и по этим вершинам строить bounding hull. но для aabb сдвинутые axial planes как раз и являются границами bounding hull. а вот «честные» — неа. у сферы же — примерно наоборот. так что если вы вдруг решили использовать beveled bsp (или просто beveled meshes), то имейте это в виду, и или ограничтесь одним видом bounding volume для колдетов, или храните оба вида капсов-бевелов, выбирая нужный.

а ещё можете козырять в беседах умной фамилией: «а, сложение фигур по минковскому. знаю-знаю.» и все сразу поймут, какой вы дохуя гениальный чувак.

p.s.: немного компенсировать ошибку для сфер и axial planes можно хитрыми манипуляциями с расстоянием сдвига, но оно того не стоит.
Link4 meows|meow!

navigation
[ viewing | May 7th, 2019 ]
[ go | Previous Day|Next Day ]