Я делаю клон Minecraft в качестве своего самого первого проекта OpenGL и застрял в части выбора коробки. Каков наилучший способ сделать надежный выбор коробки?
Я прошел через некоторые алгоритмы AABB, но ни один из них не объясняет достаточно хорошо, что именно они делают (особенно супер-настроенные), и я не хочу использовать то, чего не понимаю.
Поскольку мир состоит из кубов, я использовал октодеревья, чтобы снять некоторую нагрузку на вычисления ray cast, в основном единственное, что мне нужно, это эта функция:
float cube_intersect(Vector ray, Vector origin, Vector min, Vector max)
{
//???
}
Луч и начало координат легко получить с помощью
Vector ray, origin, point_far;
double mx, my, mz;
gluUnProject(viewport[2]/2, viewport[3]/2, 1.0, (double*)modelview, (double*)projection, viewport, &mx, &my, &mz);
point_far = Vector(mx, my, mz);
gluUnProject(viewport[2]/2, viewport[3]/2, 0.0, (double*)modelview, (double*)projection, viewport, &mx, &my, &mz);
origin = Vector(mx, my, mz);
ray = point_far-origin;
min и max - противоположные углы куба.
Я даже не уверен, что это правильный способ сделать это, учитывая количество кубов, которые мне придется проверить, даже с октодеревьями.
Я также пробовал gluProject
, это работает, но очень ненадежно и не дает мне выбранную грань куба.
ИЗМЕНИТЬ
Итак, вот что я сделал: вычислил положение в пространстве с помощью луча:
float t = 0;
for(int i=0; i<10; i++)
{
Vector p = ray*t+origin;
while(visible octree)
{
if(p inside octree)
{
// then call recursive function until a cube is found
break;
}
octree = octree->next;
}
if(found a cube)
{
break;
}
t += .5;
}
Это на самом деле удивительно быстро и останавливается после первого найденного куба.
Как вы можете видеть, луч должен пройти через несколько октодеревьев, прежде чем он найдет куб (на самом деле позицию в пространстве) — в середине экрана есть перекрестие. Чем меньше шаг приращения, тем точнее выбор, но и медленнее.