Exemplo n.º 1
0
    def setup_model_matrix(matrix: QMatrix4x4, rotation: np.ndarray, translation: np.ndarray) -> None:
        matrix.setToIdentity()

        # Translate matrix (translation = rotation_center)
        matrix.translate(*translation)

        # Rotate matrix
        matrix.rotate(rotation[0], 1.0, 0.0, 0.0)
        matrix.rotate(rotation[1], 0.0, 1.0, 0.0)
        matrix.rotate(rotation[2], 0.0, 0.0, 1.0)

        # Restore matrix
        matrix.translate(*-translation)
Exemplo n.º 2
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.m_window_matrix = QMatrix4x4()
        self.m_projection = QMatrix4x4()
        self.m_view = QMatrix4x4()
        self.m_model = QMatrix4x4()
        self.m_brush = QBrush()
        self.m_timer = QTimer()

        self.m_view.lookAt(QVector3D(3, 1, 1), QVector3D(0, 0, 0), QVector3D(0, 1, 0))
        self.m_timer.setInterval(16)
        self.m_timer.timeout.connect(self.update)
        self.m_timer.start()
Exemplo n.º 3
0
    def projectionMatrix(self, region=None):
        # Xw = (Xnd + 1) * width/2 + X
        if region is None:
            region = (0, 0, self.width(), self.height())

        x0, y0, w, h = self.getViewport()
        dist = self.props.distance
        fov = self.props.fov
        nearClip = dist * 0.001
        farClip = dist * 1000.0

        r = nearClip * np.tan(fov * 0.5 * np.pi / 180.0)
        t = r * h / w

        # convert screen coordinates (region) to normalized device coordinates
        # Xnd = (Xw - X0) * 2/width - 1
        ## Note that X0 and width in these equations must be the values used in viewport
        left = r * ((region[0] - x0) * (2.0 / w) - 1)
        right = r * ((region[0] + region[2] - x0) * (2.0 / w) - 1)
        bottom = t * ((region[1] - y0) * (2.0 / h) - 1)
        top = t * ((region[1] + region[3] - y0) * (2.0 / h) - 1)

        tr = QMatrix4x4()
        tr.frustum(left, right, bottom, top, nearClip, farClip)
        return tr
Exemplo n.º 4
0
    def _setup_text_vertices(self) -> None:
        text_vertices = []

        # Retrieve initial position
        x, y, z = self.position

        # Setup text vertices
        for c in self.text:
            ch = TextManager.characters[c]
            w, h = ch.textureSize
            w = w * self.tex_scale
            h = h * self.tex_scale

            text_vertices.append(self._rendering_buffer(x, y, z, w, h))
            x += (ch.advance >> 6) * self.tex_scale

        tvs = np.array(text_vertices).reshape((-1, 3))

        # Centered = Position represents center of the whole text, instead of the bottom left.
        if self.centered:
            ptp = np.ptp(tvs, axis=0)
            tvs -= ptp / 2

        # Rotate vertices as required
        matrix = QMatrix4x4()

        matrix.translate(*self.position)
        matrix.rotate(self.rotation[0], 1.0, 0.0, 0.0)
        matrix.rotate(self.rotation[1], 0.0, 1.0, 0.0)
        matrix.rotate(self.rotation[2], 0.0, 0.0, 1.0)
        matrix.translate(*-self.position)

        # PySide2 requires this workaround
        tvs_response = []

        for vec in tvs:
            vec4 = vec.tolist() + [1.0]
            temp_matrix = QMatrix4x4(*4 * vec4)

            response = (matrix * temp_matrix.transposed()).column(0)
            np_response = np.array([response.x(), response.y(), response.z()], np.float32)

            tvs_response.append(np_response)

        tvs = np.array(tvs_response, np.float32).reshape((len(self.text), -1))

        self.text_vertices = tvs.reshape((len(self.text), -1))
Exemplo n.º 5
0
 def scale(self, x, y, z, local=True):
     """
     Scale the object by (*dx*, *dy*, *dz*) in its local coordinate system.
     If *local* is False, then scale takes place in the parent's coordinates.
     """
     tr = QMatrix4x4()
     tr.scale(x, y, z)
     self.applyTransform(tr, local=local)
Exemplo n.º 6
0
 def translate(self, dx, dy, dz, local=False):
     """
     Translate the object by (*dx*, *dy*, *dz*) in its parent's coordinate system.
     If *local* is True, then translation takes place in local coordinates.
     """
     tr = QMatrix4x4()  # Transform3D()
     tr.translate(dx, dy, dz)
     self.applyTransform(tr, local=local)
Exemplo n.º 7
0
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAcceptDrops(True)

        # Model
        self.model = Model()

        # Factory
        self.factory = DrawableFactory(self.model)

        # Drawable elements
        self.drawable_collection = GLDrawableCollection()
        self.pre_collection = GLPreCollection()
        self.post_collection = GLPostCollection()

        # Controllers
        self.current_controller = None
        self.controllers = {}

        # Model/View/Projection matrices
        self.model_matrix = QMatrix4x4()
        self.view_matrix = QMatrix4x4()
        self.proj_matrix = QMatrix4x4()

        # FPS Counter
        self.fps_counter = FPSCounter()

        # Initial positions and rotations
        self._rotation_center = np.array([0.0, 0.0, 0.0])
        self._rotation_angle = np.array([0.0, 0.0, 0.0])
        self._camera_position = np.array([0.0, 0.0, 200.0])

        # Cross-section data
        self.last_cross_origin = np.asarray([0.0, 0.0, 0.0])
        self.last_cross_normal = np.asarray([1.0, 0.0, 0.0])
        self.is_cross_sectioned = False
        self.is_phantom_enabled = False

        # Extra information
        self.is_animated = False
        self.fov = 45.0
        self.smoothness = 2.0  # Bigger => smoother (but slower) rotations
        self.current_projection = 'Perspective'  # 'Perspective'/'Orthographic'

        # Initialize viewer
        self.initialize()
Exemplo n.º 8
0
    def rotate(self, angle, x, y, z, local=False):
        """
        Rotate the object around the axis specified by (x,y,z).
        *angle* is in degrees.

        """
        tr = QMatrix4x4()
        tr.rotate(angle, x, y, z)
        self.applyTransform(tr, local=local)
Exemplo n.º 9
0
    def paintEvent(self, event):
        p = QPainter(self)
        p.fillRect(QRect(0, 0, self.width(), self.height()), Qt.gray)

        p.setWorldTransform(self.m_window_matrix.toTransform())

        mvp = QMatrix4x4(self.m_projection * self.m_view * self.m_model)
        p.setTransform(mvp.toTransform(), True)

        p.fillPath(painterPathForTriangle(), self.m_brush)

        self.m_model.rotate(1, 0, 1, 0)
Exemplo n.º 10
0
    def unproject(self, x: float, y: float, z: float) -> np.ndarray:
        # Adapted from http://antongerdelan.net/opengl/raycasting.html
        # Note: x, y, z must be normalized to [-1.0, +1.0]

        # We'd use `QVector4D(x, y, -1.0, 1.0)`, but PySide2
        # hasn't implemented QMatrix4x4 * QVector4D yet.
        vector = [x, y, -1.0, 1.0]
        temp_matrix = QMatrix4x4(*[e for e in vector for _ in range(4)])

        ray_eye = (self.proj_matrix.inverted()[0] * temp_matrix).column(0)
        ray_eye = QVector4D(ray_eye.x(), ray_eye.y(), -1.0, 0.0)

        # We'd use `ray_eye`, but PySide2
        # hasn't implemented QMatrix4x4 * QVector4D yet.
        vector = [ray_eye.x(), ray_eye.y(), ray_eye.z(), ray_eye.w()]
        temp_matrix = QMatrix4x4(*[e for e in vector for _ in range(4)])

        # Our self.view_matrix and self.model_matrix are altered to simplify rendering.
        # For ray calculations, that's irrelevant, although we'll still use the correct ones for consistency.
        ray_world = ((self.view_matrix_math * self.model_matrix_math).inverted()[0] * temp_matrix).column(0).toVector3D()
        ray = ray_world.normalized()
        return np.array([ray.x(), ray.y(), ray.z()])
Exemplo n.º 11
0
    def viewMatrix(self):
        tr = QMatrix4x4()
        ntr = np.eye(4, dtype=np.float)

        tr.translate(0.0, 0.0, -self.props.distance)
        ntr[0:3, 3] = [0.0, 0.0, -self.props.distance]

        tr.rotate(self.props.elevation_angle - 90, 1, 0, 0)

        tr.rotate(self.props.azimuth_angle - 90, 0, 0, -1)
        center = self.props.center
        tr.translate(-center[0], -center[1], -center[2])
        return tr
Exemplo n.º 12
0
    def __init__(self,
                 *args,
                 glOptions=DefaultGlOptions.OPAQUE,
                 parentItem=None,
                 **kwargs):
        super(GLGraphicsItem, self).__init__()
        self._id = GLGraphicsItem._nextId
        GLGraphicsItem._nextId += 1

        self.__parent = None
        self.__view = None
        self.__children = set()
        self.__transform = QMatrix4x4()
        self.__visible = True
        self.setParentItem(parentItem)
        # self.setDepthValue(0)
        self.__glOpts = glOptions
Exemplo n.º 13
0
    def resizeEvent(self, event):
        if self.width() <= 0:
            return
        self.m_window_matrix = QMatrix4x4()
        self.m_window_matrix.translate(self.width() / 2.0, self.height() / 2.0)
        self.m_window_matrix.scale(self.width() / 2.0, -self.height() / 2.0)

        self.m_projection.setToIdentity()
        self.m_projection.perspective(45.0,
                                      self.width() * 1.0 / self.height(), 0.1,
                                      100.0)

        gradient = QLinearGradient(QPointF(-1, -1), QPointF(1, 1))
        gradient.setColorAt(0, Qt.red)
        gradient.setColorAt(1, Qt.green)

        self.m_brush = QBrush(gradient)
Exemplo n.º 14
0
 def v_matrix(self):
     """The view matrix in use."""
     matrix = QMatrix4x4()
     matrix.lookAt(self.camera_pos, self.camera_look_at, self.camera_normal)
     return matrix
Exemplo n.º 15
0
 def p_matrix(self):
     """Get the perspective matrix."""
     matrix = QMatrix4x4()
     angle, near, far = self.PERSPECTIVE
     matrix.perspective(angle, self.viewport_proportions, near, far)
     return matrix
Exemplo n.º 16
0
 def model_matrix_math(self) -> QMatrix4x4:
     matrix = QMatrix4x4()
     self.setup_model_matrix(matrix, self.rotation_angle, self.rotation_center)
     return matrix
Exemplo n.º 17
0
 def view_matrix_math(self) -> QMatrix4x4:
     matrix = QMatrix4x4()
     self.setup_view_matrix(matrix, self.camera_position)
     return matrix
Exemplo n.º 18
0
 def setup_view_matrix(matrix: QMatrix4x4, camera: iter) -> None:
     matrix.setToIdentity()
     matrix.translate(*-camera)