Взгляд игрока и aabb

Версия Minecraft
1.16.5

ReyMagos

Тег-бомбастер
413
7
131
С первого взгляда ситуация простая: есть взгляд игрока и несколько aabb в мире, пересечение взгляда с которыми надо проверить. Но эти объекты не сущности и не блоки. Сперва появляется идея перебора, которая хоть и не оптимизирована (банально есть объекты за спиной игрока, которые тоже будут лишний раз проверяться), но вполне рабочая. Но если взгляд пересекается с несколькими объектами, то выберется, массив знает какой из них, а не тот, что находится ближе.

Просмотр исходников не очень многое дал. Есть идея только делать объекты сущностями, но это будет костыль. Есть предложения как это лучше реализовать?
 
Если нужно обработать случаи с пересечениями областей и областью-в-области, непонятно откуда считать расстояние (центр области? ближайшая грань? вершина?). По идее может сработать такой метод:
Получаешь вектор взгляда игрока, нормализуешь, а затем запускаешь цикл, в котором нужное количество раз и с нужной тебе точностью прибавляешь к вектору позиции игрока вектор взгляда (помноженный до нужной тебе точности - 1 для блока, 0.5 для половины и тд). При каждой итерации проверяешь, находится ли точка внутри твоих AABB. Если таковых несколько, то проверяешь, содержит ли одна другую и выбираешь ту которая меньше. Если же они не содержат друг друга, увеличиваешь точность. Проверять следует все потенциальные области перебором, можно попробовать добавить оптимизации (например отбрасывать те области, у которых угол между вектором взгляда и вектором к центру области > 90).
Ну и вообще стоит поискать готовые алгоритмы для таких вещей в инете, наверняка это довольно популярная задачка.
 
А вообще, в классе AxisAlignedBB есть куча полезных методов для работы с ними. Я думаю тебе подойдет Optional<Vector3d> rayTrace(Vector3d from, Vector3d to). Он вернет Optional с вектором, идущим от from до места контакта с самой ближней гранью данной AABB, либо пустой Optional, если такого контакта не произошло. Получаешь эти вектора для каждой своей коробки и выбираешь коробку с наименьшим вектором.
 
Ну так сортируй этот массив по расстоянию к
игроку.
К сожалению, как сказал @GlassSpirit области могут пересекаться. Мороки больше будет.


Если нужно обработать случаи с пересечениями областей и областью-в-области, непонятно откуда считать расстояние (центр области? ближайшая грань? вершина?). По идее может сработать такой метод:
Получаешь вектор взгляда игрока, нормализуешь, а затем запускаешь цикл, в котором нужное количество раз и с нужной тебе точностью прибавляешь к вектору позиции игрока вектор взгляда (помноженный до нужной тебе точности - 1 для блока, 0.5 для половины и тд). При каждой итерации проверяешь, находится ли точка внутри твоих AABB. Если таковых несколько, то проверяешь, содержит ли одна другую и выбираешь ту которая меньше. Если же они не содержат друг друга, увеличиваешь точность. Проверять следует все потенциальные области перебором, можно попробовать добавить оптимизации (например отбрасывать те области, у которых угол между вектором взгляда и вектором к центру области > 90).
Ну и вообще стоит поискать готовые алгоритмы для таких вещей в инете, наверняка это довольно популярная задачка.
Смотреть угол между вектором и центром - идея хорошая. И с точностью тоже неплохо, тем более, что дальше 1 блока расстояние не будет считаться.


А вообще, в классе AxisAlignedBB есть куча полезных методов для работы с ними. Я думаю тебе подойдет Optional<Vector3d> rayTrace(Vector3d from, Vector3d to). Он вернет Optional с вектором, идущим от from до места контакта с самой ближней гранью данной AABB, либо пустой Optional, если такого контакта не произошло. Получаешь эти вектора для каждой своей коробки и выбираешь коробку с наименьшим вектором.
Это похоже на то, что мне нужно, вечером посмотрю.

@GoogleTan, почитаю, хотя и не сильно разбираюсь в этом, спасибо.
 
Назад
Сверху