Осуществление выбора луча

У меня есть renderer, использующий directx и openGL и 3-я сцена. viewport и окно имеют те же размеры.

Как я осуществляю выбирающих данных X и Y координат мыши в платформе независимый путь?

31
задан Tom J Nowell 19 January 2010 в 12:22
поделиться

3 ответа

Если вы сможете, сделайте сбор на процессоре путем расчета луча от глаз через указатель мыши и пересекаете его своими моделями.

Если это не вариант, я бы пошел с некоторым типом рендеринга идентификатора. Назначьте каждый объект, который вы хотите выбрать уникальный цвет, представьте объекты с этими цветами и, наконец, зачитайте цвет из кадра под указателем мыши.

Редактировать: Если вопрос заключается в том, как построить луч из координат мыши, вам нужно следующее: матрица проекции p и трансформация камеры C . Если координаты указателя мыши представляют собой (x, y) , а размер просмотра (ширина, высота) одна позиция в пространстве клипа вдоль луча:

mouse_clip = [
  float(x) * 2 / float(width) - 1,
  1 - float(y) * 2 / float(height),
  0,
  1]

(Обратите внимание, что я перевернул ось Y, поскольку часто происхождение координат мыши находятся в верхнем левом углу)

Следующее также верно:

mouse_clip = P * C * mouse_worldspace

, который дает:

mouse_worldspace = inverse(C) * inverse(P) * mouse_clip

Теперь у нас есть:

p = C.position(); //origin of camera in worldspace
n = normalize(mouse_worldspace - p); //unit vector from p through mouse pos in worldspace
29
ответ дан 27 November 2019 в 22:19
поделиться

У меня мало опыта DirectX, но я уверен, что он похож на OpenGL. То, что вы хотите, это вызов GluunProject.

Предполагая, что у вас есть действительный Z Buffer, вы можете запросить содержимое буфера Z на положении мыши с:

// obtain the viewport, modelview matrix and projection matrix
// you may keep the viewport and projection matrices throughout the program if you don't change them
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);

// obtain the Z position (not world coordinates but in range 0 - 1)
GLfloat z_cursor;
glReadPixels(x_cursor, y_cursor, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z_cursor);

// obtain the world coordinates
GLdouble x, y, z;
gluUnProject(x_cursor, y_cursor, z_cursor, modelview, projection, viewport, &x, &y, &z);

Если вы не хотите использовать GLU, вы также можете реализовать GluunProject, что вы также можете внести его сами, Это функциональность относительно проста и описана в opengl.org

1
ответ дан 27 November 2019 в 22:19
поделиться

Ну, довольно простые, теория позади этого всегда одинаково

1), в два раза в два раза в 3D координата на трехмерное пространство. (Каждая API имеет свою собственную функцию, но вы можете реализовать свои собственные, если хотите). Один в минуту Z, один на Max Z.

2) с этими двумя значениями рассчитывают вектор, который идет от MIN Z и указывает на MAX Z.

3) с вектором и точкой, рассчитав на луч, который идет от Мин Z в MAXZ

4) Теперь у вас есть луч, с этим вы можете сделать рентсериал / лучевую плоскость / ray-что-то пересечение и получить ваш результат ...

1
ответ дан 27 November 2019 в 22:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: