Ejemplo n.º 1
0
    def execute(self, context, scene, ray_origin, ray_vector):
        # Raycast the object
        obj = context.object
        # Get the work layer filter, based on layer settings
        work_layer_mask = sprytile_utils.get_work_layer_data(
            scene.sprytile_data)
        hit_loc, hit_normal, face_index, hit_dist = self.modal.raycast_object(
            obj, ray_origin, ray_vector, work_layer_mask=work_layer_mask)
        if hit_loc is None:
            return

        face, verts, uvs, target_grid, data, target_img, tile_xy = ToolPaint.process_preview(
            self.modal, context, scene, face_index)
        if face is None:
            return

        self.modal.add_virtual_cursor(hit_loc)
        sprytile_uv.apply_uvs(context,
                              face,
                              uvs,
                              target_grid,
                              self.modal.bmesh,
                              data,
                              target_img,
                              tile_xy,
                              origin_xy=tile_xy)
Ejemplo n.º 2
0
    def execute(self, context, scene, ray_origin, ray_vector):
        # Raycast the object
        obj = context.object
        hit_loc, hit_normal, face_index, hit_dist = self.modal.raycast_object(obj, ray_origin, ray_vector)
        if hit_loc is None:
            return

        face, verts, uvs, target_grid, data, target_img, tile_xy = ToolPaint.process_preview(
                                                                        self.modal,
                                                                        context,
                                                                        scene,
                                                                        face_index)
        if face is None:
            return

        self.modal.add_virtual_cursor(hit_loc)
        sprytile_uv.apply_uvs(context, face, uvs, target_grid,
                              self.modal.bmesh, data, target_img,
                              tile_xy, origin_xy=tile_xy)
Ejemplo n.º 3
0
    def execute(self, context, scene, ray_origin, ray_vector, is_start):
        data = scene.sprytile_data
        grid = sprytile_utils.get_grid(context, context.object.sprytile_gridid)
        tile_xy = (grid.tile_selection[0], grid.tile_selection[1])

        # Get vectors for grid, without rotation
        up_vector, right_vector, plane_normal = sprytile_utils.get_current_grid_vectors(
            scene,
            with_rotation=False
        )
        # Rotate the vectors
        rotation = Quaternion(plane_normal, data.mesh_rotate)
        up_vector = rotation * up_vector
        right_vector = rotation * right_vector

        # Used to move raycast slightly along ray vector
        shift_vec = ray_vector.normalized() * 0.001

        # raycast grid to get the grid position under the mouse
        grid_coord, grid_right, grid_up, plane_pos = sprytile_utils.raycast_grid(
            scene, context,
            up_vector, right_vector, plane_normal,
            ray_origin, ray_vector,
            as_coord=True
        )

        # Record starting position of stroke
        if is_start:
            self.start_coord = grid_coord
        # Not starting, filter out when can build
        elif self.start_coord is not None:
            tolerance_min = (floor(grid.tile_selection[2] * 0.25),
                             floor(grid.tile_selection[3] * 0.25))
            coord_offset = (
                (grid_coord[0] - self.start_coord[0]) % grid.tile_selection[2],
                (grid_coord[1] - self.start_coord[1]) % grid.tile_selection[3]
            )
            if coord_offset[0] > 0 or coord_offset[1] > 0:
                return

        # Get the area to build
        offset_tile_id, offset_grid, coord_min, coord_max = sprytile_utils.get_grid_area(
            grid.tile_selection[2],
            grid.tile_selection[3],
            data.uv_flip_x, data.uv_flip_y
        )

        # Check if joining multi tile faces
        grid_no_spacing = sprytile_utils.grid_no_spacing(grid)
        is_single_pixel = sprytile_utils.grid_is_single_pixel(grid)
        do_join = is_single_pixel
        if do_join is False:
            do_join = grid_no_spacing and data.auto_join

        # Raycast under mouse
        hit_loc, hit_normal, hit_face_idx, hit_dist = self.modal.raycast_object(
            context.object, ray_origin, ray_vector)

        # Hit a face
        if hit_face_idx is not None:
            # Determine if face can be painted
            plane_hit = intersect_line_plane(ray_origin, ray_origin + ray_vector,
                                             scene.cursor_location, plane_normal)
            plane_dist = (plane_hit - ray_origin).magnitude
            difference = abs(hit_dist - plane_dist)
            # If valid for painting instead of creating…
            if difference < 0.01 or hit_dist < plane_dist:
                if do_join is False:
                    return
                check_dot = abs(plane_normal.dot(hit_normal))
                check_dot -= 1
                check_coplanar = distance_point_to_plane(hit_loc, scene.cursor_location, plane_normal)

                check_coplanar = abs(check_coplanar) < 0.05
                check_dot = abs(check_dot) < 0.05
                # Paint if coplanar and dot angle checks out
                if check_coplanar and check_dot:
                    face, verts, uvs, target_grid, data, target_img, tile_xy = tool_paint.ToolPaint.process_preview(
                                                    self.modal, context,
                                                    scene, hit_face_idx)
                    sprytile_uv.apply_uvs(context, face, uvs, target_grid,
                                          self.modal.bmesh, data, target_img,
                                          tile_xy, origin_xy=tile_xy)
                # Hit a face, that could have been painted, don't do anything else
                return

        # Build mode with auto join
        if do_join:
            origin_coord = scene.cursor_location + \
                           (grid_coord[0] + coord_min[0]) * grid_right + \
                           (grid_coord[1] + coord_min[1]) * grid_up
            self.modal.add_virtual_cursor(origin_coord)

            size_x = (coord_max[0] - coord_min[0]) + 1
            size_y = (coord_max[1] - coord_min[1]) + 1

            size_x *= grid.grid[0]
            size_y *= grid.grid[1]

            grid_right *= size_x / grid.grid[0]
            grid_up *= size_y / grid.grid[1]

            verts = self.modal.get_build_vertices(origin_coord,
                                                  grid_right, grid_up,
                                                  up_vector, right_vector)
            face_index = self.modal.create_face(context, verts)
            if face_index is None:
                return
            vtx_center = Vector((0, 0, 0))
            for vtx in verts:
                vtx_center += vtx
            vtx_center /= len(verts)

            origin_xy = (grid.tile_selection[0],
                         grid.tile_selection[1])

            target_img = sprytile_utils.get_grid_texture(context.object, grid)

            uvs = sprytile_uv.get_uv_pos_size(data, target_img.size, grid,
                                              origin_xy, size_x, size_y,
                                              up_vector, right_vector,
                                              verts, vtx_center)
            sprytile_uv.apply_uvs(context, self.modal.bmesh.faces[face_index],
                                  uvs, grid, self.modal.bmesh,
                                  data, target_img, origin_xy)

            if data.auto_merge:
                threshold = (1 / data.world_pixels) * min(2, grid.grid[0], grid.grid[1])
                face = self.modal.bmesh.faces[face_index]
                self.modal.merge_doubles(context, face, vtx_center, -plane_normal, threshold)
        # Build mode without auto join
        else:
            virtual_cursor = scene.cursor_location + \
                             (grid_coord[0] * grid_right) + \
                             (grid_coord[1] * grid_up)
            self.modal.add_virtual_cursor(virtual_cursor)
            # Loop through grid coordinates to build
            for i in range(len(offset_grid)):
                grid_offset = offset_grid[i]
                tile_offset = offset_tile_id[i]

                grid_pos = [grid_coord[0] + grid_offset[0], grid_coord[1] + grid_offset[1]]
                tile_pos = [tile_xy[0] + tile_offset[0], tile_xy[1] + tile_offset[1]]

                self.modal.construct_face(context, grid_pos,
                                          tile_pos, tile_xy,
                                          grid_up, grid_right,
                                          up_vector, right_vector, plane_normal,
                                          shift_vec=shift_vec)