Для выбора объектов я реализовал алгоритм лучевого каста, аналогичный тому, что описано here. После преобразования щелчка мыши на луч (с началом и направлением) следующей задачей является пересечение этого луча со всеми треугольниками в сцене для определения точек попадания для каждой сетки.Литье под открытым небом OpenGL (сбор): учет для преобразования объекта
Я также реализовал алгоритм теста пересечения треугольника, основанный на описанном here. Мой вопрос в том, как мы должны учитывать преобразования объектов при выполнении пересечения? Очевидно, что я не хочу применять матрицу преобразования ко всем вершинам, а затем выполнить тест пересечения (слишком медленный).
EDIT:
Вот реализация UnProject Я использую (я использую OpenTK, кстати). Я сравнил результаты, они совпадают, что дает мне GluUnProject
:
private Vector3d UnProject(Vector3d screen)
{
int[] viewport = new int[4];
OpenTK.Graphics.OpenGL.GL.GetInteger(OpenTK.Graphics.OpenGL.GetPName.Viewport, viewport);
Vector4d pos = new Vector4d();
// Map x and y from window coordinates, map to range -1 to 1
pos.X = (screen.X - (float)viewport[0])/(float)viewport[2] * 2.0f - 1.0f;
pos.Y = 1 - (screen.Y - (float)viewport[1])/(float)viewport[3] * 2.0f;
pos.Z = screen.Z * 2.0f - 1.0f;
pos.W = 1.0f;
Vector4d pos2 = Vector4d.Transform(pos, Matrix4d.Invert(GetModelViewMatrix() * GetProjectionMatrix()));
Vector3d pos_out = new Vector3d(pos2.X, pos2.Y, pos2.Z);
return pos_out/pos2.W;
}
Затем я использую эту функцию, чтобы создать луч (с началом и направления):
private Ray ScreenPointToRay(Point mouseLocation)
{
Vector3d near = UnProject(new Vector3d(mouseLocation.X, mouseLocation.Y, 0));
Vector3d far = UnProject(new Vector3d(mouseLocation.X, mouseLocation.Y, 1));
Vector3d origin = near;
Vector3d direction = (far - near).Normalized();
return new Ray(origin, direction);
}
Если вы имеете в виду применение обратного преобразования как к началу луча, так и по направлению луча, то я должен сказать, что я его пробовал, и он не работает. – M2X
Применяя (обратное) преобразование к лучу: помните, что это вектор направленности, а не позиция, что означает, что на него не влияют переводы. Этого можно добиться, установив w-компонент в ноль: (dx, dy, dz, 0) вместо одного. –
@ DannyRuijters Я не уверен, что понимаю, что вы имеете в виду. Луч уже находится в формате vec3 (почему бы это было в однородной системе координат (vec4)?!) Вы предлагаете мне преобразовать его в vec4? Можете ли вы объяснить немного больше? – M2X