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

Версия Minecraft
1.16.5

ReyMagos

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

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

ReyMagos

Тег-бомбастер
412
7
121
Ну так сортируй этот массив по расстоянию к
игроку.
К сожалению, как сказал @GlassSpirit области могут пересекаться. Мороки больше будет.


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


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

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