Положение мыши на сцене (OpenGL)

Я пытаюсь получить координату мыши на сцене OpenGL. Мой код:

from PySide.QtGui import (QColor)
from PySide.QtCore import (Qt, QSize)
from PySide.QtOpenGL import (QGLWidget)
from OpenGL.GL import *
from OpenGL.GLU import *

class QGL(QGLWidget):
    def __init__(self, parent=None):
        self._pan_valid = False

        super(QGL, self).__init__(parent)
        self.setFocusPolicy(Qt.ClickFocus)

        self.local_translate = (0.0, 0.0, 0.0)
        self.zoomVal = 1.2

    def minimumSizeHint(self):
        return QSize(50, 50)

    def sizeHint(self):
        return QSize(800, 800)

    def initializeGL(self):
        self.qglClearColor(QColor.fromCmykF(0.0, 0.1, 0.0, 0.882))
        glViewport( 0, 0, self.width(), self.height())
        glEnable(GL_TEXTURE_2D)
        glEnable(GL_CULL_FACE)
        glEnable(GL_MULTISAMPLE)
        glEnable(GL_LINE_SMOOTH, GL_LINE_WIDTH, GL_ALIASED_LINE_WIDTH_RANGE)
        glShadeModel(GL_FLAT)
        glEnable(GL_DEPTH_TEST)
        glHint(GL_LINE_SMOOTH_HINT,  GL_NICEST)
        glDepthRange (0.1, 1.0)

    def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        gluOrtho2D(-self.zoomVal, +self.zoomVal, -self.zoomVal, +self.zoomVal)
        glLoadIdentity()

        genList = glGenLists(1)
        glNewList(genList, GL_COMPILE)

        vertices = [
            (0,0,0),
            (0.5,0,0),
            (0.5,0.5,0),
            (0,0.5,0)
        ]

        glBegin(GL_QUADS)
        self.qglColor(QColor(0,255,255))
        for vertex in vertices:
            glVertex3fv(vertex)
        glEnd()

        glEndList()
        glCallList(genList)

    def mousePressEvent(self, event):
        print event.pos()
        print self.mapToGlobal(event.pos())

когда я делаю это:

print event.pos() 

это даст мне положение мыши в окне.

и когда я делаю это:

print self.mapToGlobal(event.pos())

это даст мне положение мыши на мониторе.

Как я могу получить положение мыши на сцене? Я использую 2D-просмотр (gluOrtho2D).


person Bear    schedule 20.04.2018    source источник


Ответы (1)


Я не думаю, что для этого есть удобная встроенная функция, но вычисление должно быть тривиальным, особенно учитывая, что это 2D-орфографическая сцена. Вы знаете размер окна в пикселях, и вы знаете, где в этом окне щелкнул пользователь, с учетом того, что возвращает event.pos() (также в пикселях). Что должно произойти, так это то, что вам нужно сопоставить этот диапазон в пикселях с вашим диапазоном, указанным в вашем вызове gluOrtho2D. Следующий код можно адаптировать по своему усмотрению:

#specifying a bunch of example values
zoom_val = 1.2
window_size = (800, 600)
mouse_pos = (300, 150)
ortho_2d = (-zoom_val, +zoom_val, -zoom_val, +zoom_val)

#First, calculate the "normalized" mouse coordinates by dividing by window_size
mouse_norm_x = mouse_pos[0] / window_size[0]
mouse_norm_y = mouse_pos[1] / window_size[1]

#Now map those coordinates to your orthographic projection range
mouse_ortho_x = (mouse_norm_x * (ortho_2d[1] - ortho_2d[0])) + ortho_2d[0]
mouse_ortho_y = (mouse_norm_y * (ortho_2d[3] - ortho_2d[2])) + ortho_2d[2]
mouse_ortho = (mouse_ortho_x, mouse_ortho_y)
print(mouse_ortho)

Получить z-координату сложнее. Я бы предложил для этого прочитать о концепции «выбора мышей». Вам нужно будет получить буфер глубины, сохранить его результаты в текстуре и сэмплировать координату мыши в соответствующем месте этой текстуры, чтобы получить z-координату. Вы можете объединить эти два ответа (1, 2) Я ранее писал для других вопросов вместе, чтобы что-то работало. Позвольте мне знать, если это помогает!

person CodeSurgeon    schedule 21.04.2018
comment
Я вижу... да, это работает отлично, просто при делении mouse_pos[0] / window_size[0] я изменил его на float(mouse_pos[0]) / float(self.width()) и float(mouse_pos[1]) / float(self.height()). - person Bear; 23.04.2018
comment
также, да, я видел статью о Mouse Picking with Ray Casting, но мне пока не нужно 3 измерения, возможно, я когда-нибудь учту это в будущем. - person Bear; 23.04.2018