def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        self.shaderProgram.bind()

        p_matrix = QMatrix4x4()
        p_matrix.perspective(60.0, 1.33, 0.1, 1000)
        self.shaderProgram.setUniformValue(self.p_matrix_id, p_matrix)

        self.shaderProgram.setUniformValue(self.main_light_dir, QVector4D(0, 1.0, -1.0, 0.0))
        self.shaderProgram.setUniformValue(self.sub_light_dir, QVector4D(0, 1.0, 1.0, 0.0))
        self.shaderProgram.setUniformValue(self.back_light_dir, QVector4D(0, -1.0, 0.0, 0.0))
        self.shaderProgram.setUniformValue(self.ambient_id, QVector4D(0.15, 0.15, 0.15, 0.0))
        self.shaderProgram.setUniformValue(self.diffuse_id, QVector4D(1.0, 1.0, 1.0, 1.0))

        mv_matrix = self.camera.getMatrix()
        self.shaderProgram.setUniformValue(self.mv_matrix_id, mv_matrix)

        viewport_width = self.width() / self.obj_num
        for i in range(self.obj_num):
            glViewport(int(i * viewport_width), 0, int(viewport_width), self.height())
            if self.objs[i] is not None:
                self.objs[i].render()

        self.shaderProgram.release()
예제 #2
0
    def setUniformBindings(self, wireframe=False):
        """Sets up uniform shader bindings"""
        normalMatrix = self._transform.normalMatrix()
        self._active_shader.setUniformValue("modelMatrix", self._transform)
        self._active_shader.setUniformValue("viewMatrix", self._scene.camera.viewMatrix)
        self._active_shader.setUniformValue("projectionMatrix", self._scene.camera.projectionMatrix)
        self._active_shader.setUniformValue("normalMatrix", normalMatrix)

        if self.texture() is not None:
            self._active_shader.setUniformValue("texObject", 0)
        
        ## bind active material
        if self.isSelectable() and self.isSelected():
            self._active_shader.setUniformValue("selected", 1.0)
        else:
            self._active_shader.setUniformValue("selected", 0.65)

        ## set highlight color
        if self.isHighlighted():
            self._active_shader.setUniformValue("material.emission", QVector3D(0.25, 0.25, 0.25))
        else:
            self._active_shader.setUniformValue("material.emission", self._active_material.emissionColor)
        self._active_shader.setUniformValue("material.ambient", self._active_material.ambientColor)
        
        ## set the enabled color
        if self.isEnabled():
            self._active_shader.setUniformValue("material.emission", QVector3D(0.25, 0.25, 0.25))
            self._active_shader.setUniformValue("material.diffuse", self._active_material.diffuseColor)
        else:
            self._active_shader.setUniformValue("material.diffuse", self._active_material.diffuseColor)
        self._active_shader.setUniformValue("material.specular", self._active_material.specularColor)
        self._active_shader.setUniformValue("material.shininess", self._active_material.shininess)
    
        ## set the error and warning colors
        if self._errorHighlight:
            self._active_shader.setUniformValue("material.ambient", self._errorMaterial.ambientColor)
            self._active_shader.setUniformValue("material.diffuse", self._errorMaterial.diffuseColor)
            self._active_shader.setUniformValue("material.specular", self._errorMaterial.specularColor)
            self._active_shader.setUniformValue("material.shininess", self._errorMaterial.shininess)
        if self._warningHighlight:
            self._active_shader.setUniformValue("material.ambient", self._warningMaterial.ambientColor)
            self._active_shader.setUniformValue("material.diffuse", self._warningMaterial.diffuseColor)
            self._active_shader.setUniformValue("material.specular", self._warningMaterial.specularColor)
            self._active_shader.setUniformValue("material.shininess", self._warningMaterial.shininess)     
        
        ## bind lights
        camera_position = QVector4D(self._scene.camera.position[0], self._scene.camera.position[1], self._scene.camera.position[2], 1.0)
        if self._scene.light.headlight:
            if self._scene.light.directional:
                self._active_shader.setUniformValue("lightPosition", QVector4D(0.0, 0.0, 1.0, 0.0))
            else:
                self._active_shader.setUniformValue("lightPosition", QVector4D(0.0, 0.0, 0.0, 1.0))
        else:
            self._active_shader.setUniformValue("lightPosition", self._scene.camera.viewMatrix * self._scene.light.position)

        self._active_shader.setUniformValue("light.ambient", self._scene.light.ambientColor)
        self._active_shader.setUniformValue("light.diffuse", self._scene.light.diffuseColor)
        self._active_shader.setUniformValue("light.specular", self._scene.light.specularColor)
        self._active_shader.setUniformValue("lightAttenuation", self._scene.light.attenuation)
예제 #3
0
    def __init__(self, processor, df, parent=None):
        super().__init__(parent)
        self.parent = parent
        self.processor = processor
        # Data
        self.df = df

        # UI
        self.setupUi(self)
        self.setupControls()
        self.keyPressEvent = self.keyPressed
        self.mouseMoveEvent = self.mouseMoved

        # Control & Display
        self.mouse_grabbed = False

        self.camera_pos = QVector3D(0.5, 0.5, -2)  # Start camera position
        self.center = QVector3D(0.5, 0, 0.5)  # Center of object
        self.rot_center = QVector3D(0.5, 0.5, 0.5)  # Center of rotation
        self.camera_rot = QVector3D(0, 0, 1)  # Camera rotation
        self.scale_vec = QVector3D(1, 1, 1)  # Object scale
        self.real_prop = processor.get_real_scaling()  # val to lat

        self.light_pos = QVector3D(self.xLightSpinBox.value(),
                                   self.yLightSpinBox.value(),
                                   self.zLightSpinBox.value())
        self.ambient = self.ambientSlider.value() / 100
        self.diffuse = self.diffuseSlider.value() / 100
        self.alpha = self.alphaSlider.value() / 100  # Transparency

        # Drawing
        self.normals = []
        self.colors = []
        self.coords_array = []
        # !> len(self.normals) == len(self.colors) == len(self.coords_array)

        self.update_light = False  # Update for light is needed
        self.update_buffer = False  # Update for whole buffer is needed

        self.show_grid = self.gridCheckBox.isChecked()
        self.show_contour = self.contourCheckBox.isChecked()
        self.contour_levels = self.contourLevelSpinBox.value()
        self.show_light_lines = True
        self.grid_freq = 10

        self.grid_color = QVector4D(1, 1, 1, 1)
        self.contour_color = QVector4D(1, 1, 1, 1)
        self.light_line_color = QVector4D(1, 0.6, 0, 1)

        self.prepareScene()
        self.updateUi()

        self.shaders = QOpenGLShaderProgram()
        self.openGLWidget.initializeGL = self.initializeGL
        self.openGLWidget.paintGL = self.paintGL
예제 #4
0
    def pos_at(self, t):
        """
        Gets the position of the spline at the given value of the interpolation parameter.
        t should vary from 0 to 1

        Arguments:
            t: float, the interpolation parameter

        Returns:
            a QVector3D representing the position of this spline at the given value
        """
        # if t out of bounds, return the endpoints
        if t < 0:
            return self.ctrl_pts[0]
        if t >= 1:
            return self.ctrl_pts[-1]
        # scale t to be from (i_start) to (i_end from the end of the ctrl_pts list)
        t = util.lerp(t, 0, 1, self.i_start, len(self.ctrl_pts) + self.i_end)
        # get integer and fractional parts of this
        i = int(t)
        t %= 1
        # i is now the index of the first ctrl point to be used
        # t is the interpolation parameter

        # get control points, depends on spline implementation
        p1, p2, p3, p4 = self._get_ctrl_pts(i)
        B = QMatrix4x4(p1.x(), p1.y(), p1.z(), 1, p2.x(), p2.y(), p2.z(), 1,
                       p3.x(), p3.y(), p3.z(), 1, p4.x(), p4.y(), p4.z(), 1)
        U = QVector4D(t * t * t, t * t, t, 1)
        # left-multiplying a QVector4D with a QMatrix4x4 uses the QVector4D as a 1x4 row vector.
        return QVector3D(U * (self.M * B))
예제 #5
0
    def getLightSourceCoords(self):
        polygons = np.array([((0, 0, 0), (0, 1, 0), (1, 1, 0), (1, 0, 0)),
                             ((0, 0, 1), (0, 1, 1), (1, 1, 1), (1, 0, 1)),
                             ((0, 0, 0), (0, 0, 1), (1, 0, 1), (1, 0, 0)),
                             ((0, 1, 0), (0, 1, 1), (1, 1, 1), (1, 1, 0)),
                             ((0, 0, 0), (0, 0, 1), (0, 1, 1), (0, 1, 0)),
                             ((1, 0, 0), (1, 0, 1), (1, 1, 1), (1, 1, 0))])
        normals = [(0, 0, -1), (0, 0, 1), (0, -1, 0), (0, 1, 0), (-1, 0, 0),
                   (1, 0, 0)]

        normals_vec = []
        [[
            normals_vec.append(QVector3D(*normals[i]))
            for _ in range(len(polygons[i]))
        ] for i in range(len(polygons))]

        center = np.array(
            (self.light_pos.x(), self.light_pos.y(), self.light_pos.z()))
        delta = np.array((0.5, 0.5, 0.5))
        polygons = [[(p - delta) * 0.05 + center for p in side]
                    for side in polygons]
        colors = []
        [
            colors.append(QVector4D(1, 153 / 255, 0, 1) * self.diffuse)
            for _ in range(len(normals_vec))
        ]
        return polygons, normals_vec, colors
예제 #6
0
 def _setUniformValueDirect(self, uniform, value):
     if type(value) is Vector:
         self._shader_program.setUniformValue(
             uniform, QVector3D(value.x, value.y, value.z))
     elif type(value) is Matrix:
         self._shader_program.setUniformValue(
             uniform, self._matrixToQMatrix4x4(value))
     elif type(value) is Color:
         self._shader_program.setUniformValue(
             uniform,
             QColor(value.r * 255, value.g * 255, value.b * 255,
                    value.a * 255))
     elif type(value) is list and type(value[0]) is list and len(
             value[0]) == 4:
         self._shader_program.setUniformValue(
             uniform, self._matrixToQMatrix4x4(Matrix(value)))
     elif type(value) is list and len(value) == 2:
         self._shader_program.setUniformValue(uniform,
                                              QVector2D(value[0], value[1]))
     elif type(value) is list and len(value) == 3:
         self._shader_program.setUniformValue(
             uniform, QVector3D(value[0], value[1], value[2]))
     elif type(value) is list and len(value) == 4:
         self._shader_program.setUniformValue(
             uniform, QVector4D(value[0], value[1], value[2], value[3]))
     elif type(value) is list and type(value[0]) is list and len(
             value[0]) == 2:
         self._shader_program.setUniformValueArray(
             uniform, [QVector2D(i[0], i[1]) for i in value])
     else:
         self._shader_program.setUniformValue(uniform, value)
예제 #7
0
    def render(self):

        ratio = int(self.devicePixelRatio().real)
        GL.glViewport(0, 0, self.width()*ratio, self.height()*ratio)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

        self.m_offsets = QVector4D(sin(self.m_frame/20)*0.5, cos(self.m_frame/20)*0.5, 0.0, 0.0)

        self.m_vertices = [(0.25, -0.25, 0, 1.0),
                           (-0.25, -0.25, 0, 1.0),
                           (0.25,  0.25, 0, 1.0)]

        self.m_colors = [(0.0, 0.0, 1.0, 1.0),
                         (1.0, 0.0, 0.0, 1.0),
                         (0.0, 1.0, 0.0, 1.0)]

        self.m_program.setAttributeValue(self.m_offset, self.m_offsets)
        self.m_program.setAttributeArray(self.m_vertex, self.m_vertices)
        self.m_program.setAttributeArray(self.m_color, self.m_colors)

        self.m_program.bind()

        GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)
        self.m_program.release()

        self.m_frame += 1
예제 #8
0
 def getColorByValue(self, value):
     """Get QVector4D-color from green (value == 0) to red (value == 1)
     :param value: 0 - 1
     """
     hue = 120 * (1 - value) / 360
     color = QColor.fromHslF(hue, 1, 0.5)
     color_vec = QVector4D(color.redF(), color.greenF(), color.blueF(), 0.5)
     return color_vec
예제 #9
0
def from_numpy(v):
    if v.size == 3:
        return QVector3D(v[0], v[1], v[2])
    if v.size == 4:
        return QVector4D(v[0], v[1], v[2], v[3])
    if v.shape == (3, 3):
        return QMatrix3x3(v.flatten().tolist())

    if v.shape == (4, 4):
        return QMatrix4x4(v.flatten().tolist())
예제 #10
0
    def GetUnprojection(winXY: QPoint, winZ: float, winWH: QPoint,
                        vpMat: QMatrix4x4) -> QVector3D:
        #- from gluUnproject definition, I don't consider glViewport
        ndcspaceCursorPos = QVector4D(
            (QVector2D(winXY) / QVector2D(winWH)) * 2 - QVector2D(1, 1),
            winZ * 2 - 1, 1)

        invertedVpMat, success = vpMat.inverted()
        if not success: raise NotImplementedError
        wspaceCursorPos = invertedVpMat * ndcspaceCursorPos

        return QVector3D(wspaceCursorPos) / wspaceCursorPos.w()
예제 #11
0
파일: Scene.py 프로젝트: MLaurentys/mac420
 def ray(self, point):
     ray_start = QVector4D(point)
     ray_start.setZ(-1.0)
     ray_start.setW(1.0)
     ray_end = QVector4D(point)
     ray_end.setZ(0.0)
     ray_end.setW(1.0)
     inverseProjectionMatrix = self._camera.projectionMatrix.inverted()[0]
     inverseViewMatrix = self._camera.viewMatrix.inverted()[0]
     ray_start_camera = inverseProjectionMatrix * ray_start
     ray_start_camera /= ray_start_camera.w()
     ray_end_camera = inverseProjectionMatrix * ray_end
     ray_end_camera /= ray_end_camera.w()
     ray_start_world = inverseViewMatrix * ray_start_camera
     ray_start_world /= ray_start_world.w()
     ray_end_world = inverseViewMatrix * ray_end_camera
     ray_end_world /= ray_end_world.w()
     ray = ray_end_world - ray_start_world
     ray_direction = QVector3D(ray[0], ray[1], ray[2]).normalized()
     return Ray(self,
                origin=QVector3D(ray_start_world[0], ray_start_world[1],
                                 ray_start_world[2]),
                direction=QVector3D(ray_direction[0], ray_direction[1],
                                    ray_direction[2]))
예제 #12
0
    def render(self):
        self.m_frame += 1
        ratio = int(self.devicePixelRatio().real)
        GL.glViewport(0, 0, self.width() * ratio, self.height() * ratio)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

        self.m_program.setAttributeArray(self.m_vertex_index, self.m_vertices)
        self.m_program.setAttributeValue(
            self.m_offset_index, QVector4D(0.0, 0.0, 0.0, 0.0))
        self.m_program.bind()

        GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE)
        GL.glPatchParameteri(GL.GL_PATCH_VERTICES, 3)
        GL.glDrawArrays(GL.GL_PATCHES, 0, 3)
        self.m_program.release()
예제 #13
0
    def resizeGL(self, width, height):
        scaleX = 1.0
        scaleY = 1.0
        scaleZ = 1.0  # Will always be 1.0 since we don't scale depth
        scaleW = 1.0  # A global scale factor, also always 1.0

        if width > height:
            scaleX = height / width
        else:
            scaleY = width / height

        self.currentScaling = QVector4D(scaleX, scaleY, scaleZ, scaleW)

        # Redraw since we changed the value of the scaling uniform
        self.update()
예제 #14
0
    def render(self):
        self.m_frame += 1
        ratio = int(self.devicePixelRatio().real)
        GL.glViewport(0, 0, self.width() * ratio, self.height() * ratio)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

        self.m_program.setAttributeArray(self.m_vertex_index, self.m_vertices)
        self.m_program.setAttributeArray(self.m_norm_index, self.m_norms)
        self.m_program.setAttributeValue(self.m_color_index,
                                         QVector4D(1.0, 0.0, 0.0, 0.0))
        self.m_program.bind()

        self.m_program.setUniformValue(self.m_mvp_index, self.m_mvp_matrix)

        GL.glDrawArrays(GL.GL_TRIANGLES, 0, len(self.m_vertices))
        self.m_program.release()
예제 #15
0
 def prepareNormalLines(self, polygons, normals, colors):
     """Normal lines for each polygon.
     Debug only
     """
     norm_i = 0
     start = len(self.coords_array)
     for polygon in polygons:
         point = polygon[0]
         normal = normals[norm_i]
         # color = colors[norm_i]
         color = QVector4D(1, 1, 1, 1)
         point_2 = QVector3D(*point) + normal * 0.04
         point_2 = (point_2.x(), point_2.y(), point_2.z())
         self.prepareLine((point, point_2), [color] * 2)
         norm_i += len(polygon)
     end = len(self.coords_array)
     return start, end
예제 #16
0
 def _setUniformValueDirect(
     self, uniform: int, value: Union[Vector, Matrix, Color, List[float],
                                      List[List[float]], float, int]
 ) -> None:
     if type(value) is Matrix:
         cast(QOpenGLShaderProgram, self._shader_program).setUniformValue(
             uniform, self._matrixToQMatrix4x4(cast(Matrix, value)))
     elif type(value) is Vector:
         value = cast(Vector, value)
         cast(QOpenGLShaderProgram, self._shader_program).setUniformValue(
             uniform, QVector3D(value.x, value.y, value.z))
     elif type(value) is Color:
         value = cast(Color, value)
         cast(QOpenGLShaderProgram, self._shader_program).setUniformValue(
             uniform,
             QColor(round(value.r * 255), round(value.g * 255),
                    round(value.b * 255), round(value.a * 255)))
     elif type(value) is list and type(cast(
             List[List[float]], value)[0]) is list and len(
                 cast(List[List[float]], value)[0]) == 4:
         value = cast(List[List[float]], value)
         cast(QOpenGLShaderProgram, self._shader_program).setUniformValue(
             uniform, self._matrixToQMatrix4x4(Matrix(value)))
     elif type(value) is list and len(cast(List[float], value)) == 4:
         value = cast(List[float], value)
         cast(QOpenGLShaderProgram, self._shader_program).setUniformValue(
             uniform, QVector4D(value[0], value[1], value[2], value[3]))
     elif type(value) is list and type(cast(
             List[List[float]], value)[0]) is list and len(
                 cast(List[List[float]], value)[0]) == 2:
         value = cast(List[List[float]], value)
         cast(QOpenGLShaderProgram,
              self._shader_program).setUniformValueArray(
                  uniform, [QVector2D(i[0], i[1]) for i in value])
     elif type(value) is list and len(cast(List[float], value)) == 2:
         value = cast(List[float], value)
         cast(QOpenGLShaderProgram, self._shader_program).setUniformValue(
             uniform, QVector2D(value[0], value[1]))
     elif type(value) is list and len(cast(List[float], value)) == 3:
         value = cast(List[float], value)
         cast(QOpenGLShaderProgram, self._shader_program).setUniformValue(
             uniform, QVector3D(value[0], value[1], value[2]))
     else:
         cast(QOpenGLShaderProgram, self._shader_program).setUniformValue(
             uniform, cast(Union[float, int], value))
예제 #17
0
    def __init__(self):

        with open("vertex.glsl","r") as f:
            self.vertexShaderSource = f.read()

        with open("fragment.glsl","r") as f:
            self.fragmentShaderSource = f.read()

        if self.vertexShaderSource is None:
            raise Exception("Could not load the source for the vertex shader")

        if self.fragmentShaderSource is None:
            raise Exception("Could not load the source for the fragment shader")

        # Use an initial scale assuming width = height (should always be overwritten
        # in the resizeGL method below)
        self.currentScaling = QVector4D(1.0, 1.0, 1.0, 1.0)

        super(TestCanvas,self).__init__()
예제 #18
0
파일: glview.py 프로젝트: vibbits/volumina
    def mouseMoveEvent(self, event):
        """
        The Qt event handler when the mouse is dragged.

        If a slice plane is selected the slice plane is dragged otherwise the scene is rotated.

        :param QMouseEvent event: the qt mouse event
        """
        if self._slice_planes.has_selection():
            x, y = event.x(), event.y()
            m = self.viewMatrix()
            dx = x - self._mouse_pos[0]
            dy = y - self._mouse_pos[1]
            vec = QVector4D(dx, -dy, 0, 0) * m
            dx, dy, dz = vec.x(), vec.y(), vec.z()
            self._mouse_pos = x, y
            self._slice_planes.drag(dx, dy, dz)
            self.slice_changed.emit()
        else:
            return GLViewWidget.mouseMoveEvent(self, event)
예제 #19
0
    def __init__(self, **kwargs):
        """Initialize actor."""
        super(Light, self).__init__()

        self._headlight = kwargs.get("headlight", True)
        self._position = kwargs.get("position", QVector4D(2.0, 2.0, 2.0, 1.0))
        self._ambientColor = kwargs.get("ambient", QVector3D(0.5, 0.5, 0.5))
        self._diffuseColor = kwargs.get("diffuse", QVector3D(1.0, 1.0, 1.0))
        self._specularColor = kwargs.get("specular", QVector3D(1.0, 1.0, 1.0))
        self._attenuation = kwargs.get("attenuation",
                                       QVector3D(1.0, 0.02, 0.002))
        self._directional = kwargs.get("directional", False)
        self._color = kwargs.get("color", QVector3D(0.5, 0.5, 0.5))
        self._lradious = float(kwargs.get("lradious", 0.0))
        self._aconst = float(kwargs.get("aconst", 0.06))
        self._alinear = float(kwargs.get("alinear", 0.01))
        self._aquad = float(kwargs.get("aquad", 0.0))
        self._hemispheric = kwargs.get("hemispheric", False)
        self._csky = kwargs.get("csky", QVector3D(0.0, 0.0, 1.0))
        self._cground = kwargs.get("cground", QVector3D(0.0, 1.0, 0.0))
예제 #20
0
 def _setUniformValueDirect(self, uniform, value):
     if type(value) is Vector:
         self._shader_program.setUniformValue(
             uniform, QVector3D(value.x, value.y, value.z))
     elif type(value) is Matrix:
         self._shader_program.setUniformValue(
             uniform, self._matrixToQMatrix4x4(value))
     elif type(value) is Color:
         self._shader_program.setUniformValue(
             uniform,
             QColor(value.r * 255, value.g * 255, value.b * 255,
                    value.a * 255))
     elif type(value) is list and len(value) is 2:
         self._shader_program.setUniformValue(uniform,
                                              QVector2D(value[0], value[1]))
     elif type(value) is list and len(value) is 3:
         self._shader_program.setUniformValue(
             uniform, QVector3D(value[0], value[1], value[2]))
     elif type(value) is list and len(value) is 4:
         self._shader_program.setUniformValue(
             uniform, QVector4D(value[0], value[1], value[2], value[3]))
     else:
         self._shader_program.setUniformValue(uniform, value)
예제 #21
0
 def position(self):
     """The position of this light in space"""
     return QVector4D(self._position[0], self._position[1],
                      self._position[2], 1.0 - float(self._directional))
예제 #22
0
 def _mouseEyeSpace(self, clipCoord):
     invertedProjectionMatrix = self.projectionMatrix.inverted()[0]
     eye = invertedProjectionMatrix * clipCoord
     return QVector4D(eye.x(), eye.y(), -1.0, 0.0)
예제 #23
0
 def _mouseDirection(self, xin, yin, width, height, plane):
     x, y, z = self.devicePortCoordinates(xin, yin, width, height)
     clipCoord = QVector4D(x, y, plane, 0.0)
     eyeCoord = self._mouseEyeSpace(clipCoord)
     ray = self._mouseWorldCoord(eyeCoord)
     return ray
예제 #24
0
 def read_Vector4D(self):
     return QVector4D(self.read_float(), self.read_float(), self.read_float(), self.read_float())
예제 #25
0
 def calculate_model_matrix(self, viewmatrix_inv=None):
     """
     Calculates the Model matrix based upon self.origin and self.scale.
     
     If self.billboard == False, the Model matrix will also be rotated
     determined by self.rotation_angle and self.rotation_axis.
     
     If self.billboard == True and self.billboard_axis == None
     the Model matrix will also be rotated so that the local Z axis
     will face the camera and the local Y axis will be parallel to
     the camera up axis at all times.
     
     If self.billboard == True and self.billboard_axis is either "X",
     "Y", or "Z", the local Z axis will always face the camera, but
     the items rotation will be restricted to self.billboard_axis.
     
     @param viewmatrix_inv
     The inverted View matrix as instance of QMatrix4x4. Mandatory when
     self.billboard == True, otherwise optional.
     """
     mat_m = QMatrix4x4()
     mat_m.translate(self.origin)
     
     if self.billboard:
         # Billboard calulation is based on excellent tutorial:
         # http://nehe.gamedev.net/article/billboarding_how_to/18011/
         
         # extract 2nd column which is camera up vector
         cam_up = viewmatrix_inv * QVector4D(0,1,0,0)
         cam_up = QVector3D(cam_up[0], cam_up[1], cam_up[2])
         cam_up.normalize()
         
         # extract 4th column which is camera position
         cam_pos = viewmatrix_inv * QVector4D(0,0,0,1)
         cam_pos = QVector3D(cam_pos[0], cam_pos[1], cam_pos[2])
         
         # calculate self look vector (vector from self.origin to camera)
         bill_look = cam_pos - self.origin
         bill_look.normalize()
         
         if self.billboard_axis == None:
             # Fully aligned billboard, rotation not restricted to axes.
             # Calculate new self right vector based upon self look and camera up
             bill_right = QVector3D.crossProduct(cam_up, bill_look)
             
             # Calculate self up vector based on self look and self right
             bill_up = QVector3D.crossProduct(bill_look, bill_right)
             
         else:
             axis_words = ["X", "Y", "Z"]
             axis = axis_words.index(self.billboard_axis)
             
             bill_up = [0]*3
             for i in range(0,3):
                 bill_up[i] = 1 if i == axis else 0
             bill_up = QVector3D(*bill_up)
             
             bill_look_zeroed = [0]*3
             for i in range(0,3):
                 bill_look_zeroed[i] = 0 if i == axis else bill_look[i]
             bill_look = QVector3D(*bill_look_zeroed)
             bill_look.normalize()
             
             bill_right = QVector3D.crossProduct(bill_up, bill_look)
         
         # View and Model matrices are actually nicely structured!
         # 1st column: camera right vector
         # 2nd column: camera up vector
         # 3rd column: camera look vector
         # 4th column: camera position
         
         # Here we only overwrite right, up and look.
         # Position is already in the matrix, and we don't have to change it.
         mat_m[0,0] = bill_right[0]
         mat_m[1,0] = bill_right[1]
         mat_m[2,0] = bill_right[2]
         
         mat_m[0,1] = bill_up[0]
         mat_m[1,1] = bill_up[1]
         mat_m[2,1] = bill_up[2]
         
         mat_m[0,2] = bill_look[0]
         mat_m[1,2] = bill_look[1]
         mat_m[2,2] = bill_look[2]
         
     else:
         mat_m.rotate(self.rotation_angle, self.rotation_vector)
     
     mat_m.scale(self.scale)
     
     return mat_m
예제 #26
0
    def setUniformBindings(self, wireframe=False):
        """Sets up uniform shader bindings"""
        normalMatrix = self._transform.normalMatrix()
        self._active_shader.setUniformValue("modelMatrix", self._transform)
        self._active_shader.setUniformValue("viewMatrix",
                                            self._scene.camera.viewMatrix)
        self._active_shader.setUniformValue(
            "projectionMatrix", self._scene.camera.projectionMatrix)
        self._active_shader.setUniformValue("normalMatrix", normalMatrix)

        ## bind active material
        if self.isSelectable() and self.isSelected():
            self._active_shader.setUniformValue("selected", 1.0)
        else:
            self._active_shader.setUniformValue("selected", 0.65)

        ## set highlight color
        if self.isHighlighted():
            self._active_shader.setUniformValue("material.emission",
                                                QVector3D(0.25, 0.25, 0.25))
        else:
            self._active_shader.setUniformValue(
                "material.emission", self._active_material.emissionColor)
        self._active_shader.setUniformValue("material.ambient",
                                            self._active_material.ambientColor)

        ## set the enabled color
        if self.isEnabled():
            self._active_shader.setUniformValue("material.emission",
                                                QVector3D(0.25, 0.25, 0.25))
            self._active_shader.setUniformValue(
                "material.diffuse", self._active_material.diffuseColor)
        else:
            self._active_shader.setUniformValue(
                "material.diffuse", self._active_material.diffuseColor)
        self._active_shader.setUniformValue(
            "material.specular", self._active_material.specularColor)
        self._active_shader.setUniformValue("material.shininess",
                                            self._active_material.shininess)

        ## set the error and warning colors
        if self._errorHighlight:
            self._active_shader.setUniformValue(
                "material.ambient", self._errorMaterial.ambientColor)
            self._active_shader.setUniformValue(
                "material.diffuse", self._errorMaterial.diffuseColor)
            self._active_shader.setUniformValue(
                "material.specular", self._errorMaterial.specularColor)
            self._active_shader.setUniformValue("material.shininess",
                                                self._errorMaterial.shininess)
        if self._warningHighlight:
            self._active_shader.setUniformValue(
                "material.ambient", self._warningMaterial.ambientColor)
            self._active_shader.setUniformValue(
                "material.diffuse", self._warningMaterial.diffuseColor)
            self._active_shader.setUniformValue(
                "material.specular", self._warningMaterial.specularColor)
            self._active_shader.setUniformValue(
                "material.shininess", self._warningMaterial.shininess)

        if self._shader_name == "BRDF":
            self._active_shader.setUniformValue("material.metallic",
                                                self._active_material.metallic)
            self._active_shader.setUniformValue(
                "material.roughness", self._active_material.roughness)
            self._active_shader.setUniformValue("material.cbase",
                                                self._active_material.cbase)

        self._active_shader.setUniformValue("spike",
                                            self._active_material._spike)
        self._active_shader.setUniformValue("h",
                                            self._active_material._spike_h)
        self._active_shader.setUniformValue("w",
                                            self._active_material._spike_w)

        self._active_shader.setUniformValue("portalIteration",
                                            self._portalInteration)

        ## bind lights
        camera_position = QVector4D(self._scene.camera.position[0],
                                    self._scene.camera.position[1],
                                    self._scene.camera.position[2], 1.0)
        lightpos = self._scene.light._position
        if self._scene.light.headlight:
            if self._scene.light.directional:
                self._active_shader.setUniformValue(
                    "lightPosition",
                    QVector4D(lightpos.x(), lightpos.y(), lightpos.z(), 0.0))
            elif self._scene.light.hemispheric:
                self._active_shader.setUniformValue(
                    "lightPosition",
                    QVector4D(lightpos.x(), lightpos.y(), lightpos.z(), 0.2))
            else:
                self._active_shader.setUniformValue(
                    "lightPosition",
                    QVector4D(lightpos.x(), lightpos.y(), lightpos.z(), 1.0))
        else:
            self._active_shader.setUniformValue(
                "lightPosition",
                self._scene.camera.viewMatrix * self._scene.light.position)

        self._active_shader.setUniformValue("light.ambient",
                                            self._scene.light.ambientColor)
        self._active_shader.setUniformValue("light.diffuse",
                                            self._scene.light.diffuseColor)
        self._active_shader.setUniformValue("light.specular",
                                            self._scene.light.specularColor)
        self._active_shader.setUniformValue("lightAttenuation",
                                            self._scene.light.attenuation)
        if self._shader_name == "BRDF":
            self._active_shader.setUniformValue("light.color",
                                                self._scene.light.color)
            self._active_shader.setUniformValue("light.lradious",
                                                self._scene.light.lradious)
            self._active_shader.setUniformValue("light.aconst",
                                                self._scene.light.aconst)
            self._active_shader.setUniformValue("light.alinear",
                                                self._scene.light.alinear)
            self._active_shader.setUniformValue("light.aquad",
                                                self._scene.light.aquad)
            self._active_shader.setUniformValue("light.csky",
                                                self._scene.light.csky)
            self._active_shader.setUniformValue("light.cground",
                                                self._scene.light.cground)
            if self._isIcosahedron:
                self._active_shader.setUniformValue("isIcosahedron", 1)
            else:
                self._active_shader.setUniformValue("isIcosahedron", 0)
예제 #27
0
def calc_upper_vertex(upper_vertices, model, head_links, frames, bf):
    # キー:頂点Y位置小数点第一位まるめ
    upper_vertex_pos = {}

    # グローバル行列算出
    _, _, matrixs, _ = create_matrix(model, head_links, frames, bf)

    # 該当ボーンのグローバル行列まで求める
    upper_matrixes = [QMatrix4x4() for i in range(len(head_links))]

    for n in range(len(matrixs)):
        for m in range(n + 1):
            if n == 0:
                # 最初は行列そのもの
                upper_matrixes[n] = copy.deepcopy(matrixs[0])
            else:
                # 2番目以降は行列をかける
                upper_matrixes[n] *= copy.deepcopy(matrixs[m])

            # logger.debug("**u_matrixes[%s]: %s %s -> %s", n, m, matrixs[m], upper_matrixes[n])

        # logger.debug("upper_matrixes[%s]: %s", n, upper_matrixes[n])

    # 該当リンクボーンのリンクINDEX取得
    head_links_indexes = {}
    for lidx, l in enumerate(reversed(head_links)):
        head_links_indexes[l.index] = lidx

    # 上半身の頂点位置
    for uv in upper_vertices:
        # 頂点が乗っているウェイトボーン情報取得
        deform_bone = model.bones[model.bone_indexes[uv.deform.index0]]

        # 頂点初期位置
        uv_diff = uv.position - deform_bone.position

        # 上半身の頂点の位置を算出する
        upper_pos = upper_matrixes[head_links_indexes[
            deform_bone.index]] * QVector4D(uv_diff, 1)
        # logger.debug("upper_matrixes0 : %s, upper_pos: %s", upper_matrixes[0], upper_pos)
        # logger.debug("upper_matrixes1 : %s, upper_pos: %s", upper_matrixes[1], upper_pos)

        # 3Dに変換
        uv_pos = upper_pos.toVector3D()
        uv_round = round(uv_pos.y(), 1)
        # logger.debug("uv_pos.y: %s -> %s: 0:%s, -1:%s, 1:%s", uv_pos.y(), uv_round, round(uv_pos.y(), 0), round(uv_pos.y(), -1), round(uv_pos.y(), 1))
        if uv_round not in upper_vertex_pos.keys():
            upper_vertex_pos[uv_round] = {}
            # 最小値
            upper_vertex_pos[uv_round]["min"] = QVector3D(99999, 99999, 99999)
            # 最大値
            upper_vertex_pos[uv_round]["max"] = QVector3D(
                -99999, -99999, -99999)
            # 実値
            upper_vertex_pos[uv_round]["values"] = []

        # if round(uv.position.y(),2) == 8.01:
        #     logger.info("v: %s %s, uv_pos: %s", uv.index, uv.position, uv_pos)

        if upper_vertex_pos[uv_round]["min"].z() > uv_pos.z():
            # 最小値より小さい場合、上書き
            upper_vertex_pos[uv_round]["min"] = uv_pos

        if upper_vertex_pos[uv_round]["max"].z() < uv_pos.z():
            # 最大値より小さい場合、上書き
            upper_vertex_pos[uv_round]["max"] = uv_pos

        # 実値追加
        upper_vertex_pos[uv_round]["values"].append(uv_pos)

    # if bf.frame == 0:
    #     for uvkey in upper_vertex_pos.keys():
    #         logger.info("upper_vertex_pos key: %s, min: %s, max: %s, len: %s", uvkey, upper_vertex_pos[uv_round]["min"], upper_vertex_pos[uv_round]["max"], len(upper_vertex_pos[uvkey]["values"]))

    return upper_vertex_pos
예제 #28
0
 def paintGL(self):
     """ This function is automatially called by the Qt libraries
     whenever updateGL() has been called. This happens for example
     when the window is resized or moved or when it is marked as
     'dirty' by the window manager. It also fires during mouse
     interactivity.
     
     paintGL() traditionally is structured in the following way, see
     also OpenGL documentation:
     
     1. Call to glClear()
     2. Uploading of per-frame CPU-calculated data if they have changed
        since the last call. This can include:
        a. Projection and View matrices
        b. For each object in the scene:
            - Model Matrix (translation, scale, rotation of object)
     3. For each object in the scene:
        a. Binding the data buffers of the object
        b. Drawing of the object
     """
     print("paintGL called")
     
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
     
     # ======= VIEW MATRIX BEGIN ==========
     # start with an empty matrix
     self.mat_v = QMatrix4x4()
     
     # rotate the world
     self.mat_v.rotate(self._rotation_quat) # math is done by Qt!
     
     # translate the world
     self.mat_v.translate(self._translation_vec) # math is done by Qt!
     
     # calculate inverse view matrix which contains
     # camera right, up, look directions, and camera position
     # Items in "billboard" mode will need this to know where the camera is
     self.mat_v_inverted = self.mat_v.inverted()[0]
     
     # the right direction of the camera
     cam_right = self.mat_v_inverted * QVector4D(1,0,0,0) # extract 1st column
     self.cam_right = QVector3D(cam_right[0], cam_right[1], cam_right[2])
     
     # the up direction of the camera
     cam_up = self.mat_v_inverted * QVector4D(0,1,0,0) # extract 2nd column
     self.cam_up = QVector3D(cam_up[0], cam_up[1], cam_up[2])
     
     # the look direction of the camera
     cam_look = self.mat_v_inverted * QVector4D(0,0,1,0) # extract 3rd column
     self.cam_look = QVector3D(cam_look[0], cam_look[1], cam_look[2])
     
     # the postion of the camera
     cam_pos = self.mat_v_inverted * QVector4D(0,0,0,1) # extract 4th column
     self.cam_pos = QVector3D(cam_pos[0], cam_pos[1], cam_pos[2])
     
     # upload the View matrix into the GPU,
     # accessible to the vertex shader under the variable name "mat_v"
     mat_v_list = PainterWidget.qt_mat_to_list(self.mat_v) # Transform Qt object to Python list
     # ======= VIEW MATRIX END ==========
     
     # ======= PROJECTION MATRIX BEGIN ==========
     self.mat_p = QMatrix4x4() # start with an empty matrix
     self.mat_p.perspective(self.fov, self.aspect, 0.1, 100000) # math is done by Qt!
     mat_p_list = PainterWidget.qt_mat_to_list(self.mat_p) #Transform Qt object to Python list
     # ======= PROJECTION MATRIX END ==========
     
     # loop over all programs/shaders
     # first switch to that program (expensive operation)
     # then draw all items belonging to that program
     for key, prog in self.programs.items():
         if len(list(prog.items.keys())) > 0:
             glUseProgram(prog.id)
             prog.set_uniform("mat_v", mat_v_list) # set view matrix
             prog.set_uniform("mat_p", mat_p_list) # set projection matrix
             prog.items_draw(self.mat_v_inverted)
예제 #29
0
def create_matrix(model, links, frames, bf):

    # ローカル位置
    trans_vs = [QVector3D() for i in range(len(links))]
    # 加算用クォータニオン
    add_qs = [QQuaternion() for i in range(len(links))]

    for lidx, lbone in enumerate(reversed(links)):
        # 位置
        if lidx == 0:
            # 一番親は、グローバル座標を考慮
            trans_vs[lidx] = lbone.position + calc_bone_by_complement(
                frames, lbone.name, bf.frame).position
        else:
            # 位置:自身から親の位置を引いた値
            trans_vs[lidx] = lbone.position + calc_bone_by_complement(
                frames, lbone.name,
                bf.frame).position - links[len(links) - lidx].position

        # 回転
        rot = calc_bone_by_complement(frames, lbone.name, bf.frame).rotation
        if lbone.fixed_axis != QVector3D():
            # 軸固定の場合、回転を制限する
            rot = QQuaternion.fromAxisAndAngle(lbone.fixed_axis,
                                               rot.lengthSquared())
        add_qs[lidx] = rot

        # if "ひじ" in lbone.name:
        #     # 右手系→左手系への変換
        #     # trans_vs[lidx].setX(trans_vs[lidx].x() * -1)
        #     add_qs[lidx].setX(add_qs[lidx].x() * -1)
        #     add_qs[lidx].setY(add_qs[lidx].y() * -1)
        #     # add_qs[lidx].setScalar(add_qs[lidx].scalar() * -1)
        #     # logger.info("%s: fix: %s, vs: %s, qs: %s", lbone.name, lbone.fixed_axis, trans_vs[lidx], add_qs[lidx].toEulerAngles())

        # logger.info("trans_vs[%s]: %s", lidx, trans_vs[lidx])
        # logger.info("add_qs[%s]: %s", lidx, add_qs[lidx])

    # 行列
    matrixs = [QMatrix4x4() for i in range(len(links))]

    for n in range(len(matrixs)):
        # 行列を生成
        matrixs[n] = QMatrix4x4()
        # 移動
        matrixs[n].translate(trans_vs[n])
        # 回転
        matrixs[n].rotate(add_qs[n])

        # logger.info("matrixs n: %s, %s", n, matrixs[n])

    # 各関節の位置
    global_4ds = [QVector4D() for i in range(len(links))]

    for n in range(len(global_4ds)):
        for m in range(n):
            if m == 0:
                # 0番目の位置を初期値とする
                global_4ds[n] = copy.deepcopy(matrixs[0])
            else:
                # 自分より前の行列結果を掛け算する
                global_4ds[n] *= copy.deepcopy(matrixs[m])

        # 自分は、位置だけ掛ける
        global_4ds[n] *= QVector4D(trans_vs[n], 1)

        # if bf.frame == 0:
        #     logger.info("global_4ds %s, %s, %s", n, links[len(links) - n - 1].name, global_4ds[n].toVector3D())

    return trans_vs, add_qs, matrixs, global_4ds
예제 #30
0
def calc_boundingbox(model, bone_name, body_links, frames, bf):
    # グローバル行列算出
    _, _, _, matrixs = utils.create_matrix(model, body_links, frames, bf)

    # 該当ボーンを含む末端までのグローバル行列まで求める
    upper_matrixes = [QMatrix4x4() for i in range(len(body_links))]

    target_idx = 0
    for i, l in enumerate(reversed(body_links)):
        if l.name == bone_name:
            target_idx = i
            break

    for n in range(len(matrixs)):
        for m in range(n + 1):
            if n == 0:
                # 最初は行列そのもの
                upper_matrixes[n] = copy.deepcopy(matrixs[0])
            else:
                # 2番目以降は行列をかける
                upper_matrixes[n] *= copy.deepcopy(matrixs[m])

            # logger.debug("**u_matrixes[%s]: %s %s -> %s", n, m, matrixs[m], upper_matrixes[n])

        # logger.debug("upper_matrixes[%s]: %s", n, upper_matrixes[n])

    x_min = y_min = z_min = 99999
    x_max = y_max = z_max = -99999

    # 指定ボーンにウェイトが振ってある頂点リスト
    for hv in model.vertices[model.bones[bone_name].index]:
        # 頂点初期位置
        hv_diff = hv.position - model.bones[bone_name].position

        # 指定ボーンまでの行列と、頂点をかけて頂点の現在位置を取得する
        head_pos = (upper_matrixes[target_idx] *
                    QVector4D(hv_diff, 1)).toVector3D()

        if head_pos.x() < x_min:
            # X位置がより前の場合、x_min更新
            x_min = head_pos.x()

        if head_pos.x() > x_max:
            # X位置がより後の場合、x_max更新
            x_max = head_pos.x()

        if head_pos.y() < y_min:
            # Y位置がより前の場合、y_min更新
            y_min = head_pos.y()

        if head_pos.y() > y_max:
            # Y位置がより後の場合、y_max更新
            y_max = head_pos.y()

        if head_pos.z() < z_min:
            # Z位置がより前の場合、z_min更新
            z_min = head_pos.z()

        if head_pos.z() > z_max:
            # Z位置がより後の場合、z_max更新
            z_max = head_pos.z()

    return QVector3D(x_min, y_min, z_min), QVector3D(x_max, y_max, z_max)