def __init__(self, editor_dialogs: dialogs.Dialogs, *args, **kwargs): super().__init__(*args, **kwargs) self._drawing_mode = drawing_mode_2d.EditMode(*args, **kwargs) self._highlighter: highlighter.Highlighter = None self._object_editor = object_editor.ObjectEditor( editor_dialogs, self._make_clicker, self._camera_collection, self._edit_mode_selector, self._menu, ) self._moving_clicker: moving_clicker.MovingClicker = None self._marquee_start = core.Point2() self._marquee_end = core.Point2() self._marquee_display: core.NodePath = None self._wall_bevel_editor = wall_bevel.EditMode(*args, **kwargs) self._sector_prefab: operations.sector_copy.SectorCopy = None self._make_clicker( [core.KeyboardButton.alt(), core.MouseButton.one()], on_mouse_down=self._start_selection_marquee, on_click_move=self._move_selection_marquee, on_click_after_move=self._select_from_marquee, ) self._tickers.append(self._mouse_collision_tests) self._tickers.append(self._update_mover)
def build_rectangular_sector( all_sectors: map_objects.SectorCollection, left: float, right: float, bottom: float, top: float, ): sector = all_sectors.new_sector(map_data.sector.Sector()) point_1 = sector.add_wall(map_data.wall.Wall()) point_1.teleport_point_1_to(core.Point2(left, bottom)) point_2 = sector.add_wall(map_data.wall.Wall()) point_2.teleport_point_1_to(core.Point2(right, bottom)) point_3 = sector.add_wall(map_data.wall.Wall()) point_3.teleport_point_1_to(core.Point2(right, top)) point_4 = sector.add_wall(map_data.wall.Wall()) point_4.teleport_point_1_to(core.Point2(left, top)) point_1.set_wall_point_2(point_2) point_2.set_wall_point_2(point_3) point_3.set_wall_point_2(point_4) point_4.set_wall_point_2(point_1) return sector
def test_can_split_on_point_2(self): sector = utils.build_rectangular_sector(self._sectors, -1, 1, -1, 1) wall_to_split = utils.find_wall_on_point(sector, core.Point2(-1, 1)) operations.wall_split.WallSplit(wall_to_split, core.Point2(-1, -1)).split() self.assertEqual(4, len(sector.walls))
def setUp(self): self._sectors = utils.new_sector_collection() self._start_sector = utils.build_rectangular_sector(self._sectors, -1, 1, -1, 1) operations.sector_split.SectorSplit(self._start_sector, self._sectors).split( [core.Point2(-1, 0), core.Point2(1, 0)] ) wall_to_split = utils.find_wall_on_point(self._start_sector, core.Point2(-1, 0)) operations.wall_split.WallSplit(wall_to_split, core.Point2(0, 0)).split()
def floor_plane(self): point_1_2d = self.origin_2d point_2_2d = core.Point2(point_1_2d.x + 1, point_1_2d.y) point_3_2d = core.Point2(point_1_2d.x, point_1_2d.y + 1) return plane.Plane( core.Point3(point_1_2d.x, point_1_2d.y, self.floor_z_at_point(point_1_2d)), core.Point3(point_2_2d.x, point_2_2d.y, self.floor_z_at_point(point_2_2d)), core.Point3(point_3_2d.x, point_3_2d.y, self.floor_z_at_point(point_3_2d)), )
def test_can_grab_walls_4_sectors(self): operations.sector_split.SectorSplit(self._start_sector, self._sectors).split( [core.Point2(0, 0), core.Point2(0, 1)] ) operations.sector_split.SectorSplit( self._sectors.sectors[1], self._sectors ).split([core.Point2(0, 0), core.Point2(0, -1)]) self._assert_got_all_walls()
def test_completely_overlapping(self): first_sector = utils.build_rectangular_sector(self._sectors, -1, 0, -1, 1) second_sector = utils.build_rectangular_sector(self._sectors, 0, 1, -1, 1) wall = utils.find_wall_on_point(first_sector, core.Point2(0, -1)) operations.wall_link.SectorWallLink(wall, self._sectors).try_link_wall() other_side_wall = utils.find_wall_on_point(second_sector, core.Point2(0, 1)) self.assertEqual(wall.other_side_wall, other_side_wall) self.assertEqual(other_side_wall.other_side_wall, wall)
def floor_slope_direction(self) -> core.Vec2: point_2d_x = self.origin_2d + core.Point2(1, 0) point_2d_y = self.origin_2d + core.Point2(0, 1) x_z = self.floor_z_at_point(point_2d_x) y_z = self.floor_z_at_point(point_2d_y) theta_x = -math.atan2(x_z - self.floor_z, 1) theta_y = math.atan2(y_z - self.floor_z, 1) return core.Vec2(math.degrees(theta_x), math.degrees(theta_y))
def test_can_delete(self): sector = utils.build_rectangular_sector(self._sectors, -1, 1, -1, 1) wall = utils.find_wall_on_point(sector, core.Point2(1, 1)) operations.wall_split.WallSplit(wall, core.Point2(0, 1)).split() split_wall = utils.find_wall_on_point(sector, core.Point2(0, 1)) operations.wall_delete.WallDelete(split_wall).delete() self.assertEqual(4, len(sector.walls)) self.assertEqual(split_wall.point_2, core.Point2(-1, 1))
def test_can_flip_both(self): sector = utils.build_rectangular_sector(self._sectors, 0, 1, 0, 1) operations.sector_flip.SectorFlip([sector]).flip(True, True) utils.assert_sector_has_shape( sector, core.Point2(-1, -1), core.Point2(-1, 0), core.Point2(0, 0), core.Point2(0, -1), )
def test_can_delete_with_previous_having_other_side(self): sector = utils.build_rectangular_sector(self._sectors, -1, 1, -1, 1) other_side_sector = utils.build_rectangular_sector(self._sectors, -1, 1, 1, 2) wall = utils.find_wall_on_point(sector, core.Point2(1, 1)) operations.wall_link.SectorWallLink(wall, self._sectors).try_link_wall() other_side_wall = utils.find_wall_on_point(other_side_sector, core.Point2(1, 1)) operations.wall_delete.WallDelete(other_side_wall).delete() utils.assert_sector_has_point(sector, core.Point2(1, 2))
def test_can_link_smaller_to_bigger_two_splits(self): sector = utils.build_rectangular_sector(self._sectors, -1, 1, -1, 1) other_side_sector = utils.build_rectangular_sector( self._sectors, -2, 2, 1, 2) link_wall = utils.find_wall_on_point(sector, core.Point2(1, 1)) operations.wall_link.SectorWallLink(link_wall, self._sectors).try_link_wall() link_other_side_wall = utils.find_wall_on_point( other_side_sector, core.Point2(-1, 1)) self.assertEqual(link_wall.other_side_wall, link_other_side_wall)
def test_breaks_joined_sector_link_if_other_side_not_flipped(self): sector = utils.build_rectangular_sector(self._sectors, -1, 1, -1, 0) sector_2 = utils.build_rectangular_sector(self._sectors, -1, 1, 0, 1) wall = utils.find_wall_on_point(sector, core.Point2(1, 0)) operations.wall_link.SectorWallLink(wall, self._sectors).try_link_wall() operations.sector_flip.SectorFlip([sector_2]).flip(True, False) wall = utils.find_wall_on_point(sector_2, core.Point2(1, 0)) expected_other_side_wall = utils.find_wall_on_point( sector, core.Point2(-1, 0)) self.assertIsNone(wall.other_side_wall) self.assertIsNone(expected_other_side_wall.other_side_wall)
def test_first_within_second_partial_wall_2(self): first_sector = utils.build_rectangular_sector(self._sectors, -1, 0, -1, 1) second_sector = utils.build_rectangular_sector(self._sectors, 0, 1, -1, 2) wall = utils.find_wall_on_point(first_sector, core.Point2(0, -1)) operations.wall_link.SectorWallLink(wall, self._sectors).try_link_wall() other_side_wall = utils.find_wall_on_point(second_sector, core.Point2(0, 2)) self.assertEqual(other_side_wall.point_2, core.Point2(0, 1)) other_side_wall_2 = other_side_wall.wall_point_2 self.assertEqual(other_side_wall_2.point_2, core.Point2(0, -1)) self.assertEqual(wall.other_side_wall, other_side_wall_2) self.assertEqual(other_side_wall_2.other_side_wall, wall)
def test_can_delete_with_other_side(self): sector = utils.build_rectangular_sector(self._sectors, -1, 1, -1, 1) other_side_sector = utils.build_rectangular_sector(self._sectors, -1, 1, 1, 2) wall = utils.find_wall_on_point(sector, core.Point2(1, 1)) operations.wall_link.SectorWallLink(wall, self._sectors).try_link_wall() other_side_wall = utils.find_wall_on_point( other_side_sector, core.Point2(-1, 1) ) operations.wall_delete.WallDelete(other_side_wall).delete() wall = utils.find_wall_on_point(sector, core.Point2(1, 1)) self.assertEqual(wall.wall_point_2.point_1, core.Point2(-1, 2)) self.assertEqual(wall.other_side_wall.point_1, core.Point2(-1, 2))
def test_no_fill_if_a_portal_exists(self): sector = utils.build_rectangular_sector(self._sectors, -3, 3, -3, 3) operations.sector_insert.SectorInsert(sector, self._sectors).insert([ core.Point2(-1, -1), core.Point2(1, -1), core.Point2(1, 1), core.Point2(-1, 1), ]) start_wall = utils.find_wall_on_point(sector, core.Point2(-1, -1)) result = operations.sector_fill.SectorFill( sector, self._sectors).fill(start_wall) self.assertFalse(result) self.assertEqual(2, len(self._sectors.sectors))
def line_intersection( segment_1_point_1: core.Point2, segment_1_point_2: core.Point2, segment_2_point_1: core.Point2, segment_2_point_2: core.Point2, ): segment_1_diff = segment_1_point_1 - segment_1_point_2 segment_2_diff = segment_2_point_1 - segment_2_point_2 x_diff = core.Vec2(segment_1_diff.x, segment_2_diff.x) y_diff = core.Vec2(segment_1_diff.y, segment_2_diff.y) divisor = determinant(x_diff, y_diff) if divisor == 0: raise ValueError("Lines do not intersect") det = core.Vec2( determinant(segment_1_point_1, segment_1_point_2), determinant(segment_2_point_1, segment_2_point_2), ) x = determinant(det, x_diff) / divisor y = determinant(det, y_diff) / divisor return core.Point2(x, y)
def test_adjacent_links(self): sector = utils.build_rectangular_sector(self._sectors, -1, 1, -1, 0) sector_2 = utils.build_rectangular_sector(self._sectors, -1, 0, 0, 1) sector_3 = utils.build_rectangular_sector(self._sectors, 0, 1, 0, 1) wall = utils.find_wall_on_point(sector, core.Point2(1, 0)) operations.wall_link.SectorWallLink(wall, self._sectors).try_link_wall() operations.wall_link.SectorWallLink(wall, self._sectors).try_link_wall() wall = utils.find_wall_on_point(sector_2, core.Point2(0, 0)) operations.wall_link.SectorWallLink(wall, self._sectors).try_link_wall() operations.sector_flip.SectorFlip([sector, sector_2, sector_3]).flip(False, True)
def test_split_with_multiple_sectors_different_sector_order(self): first_sector = utils.build_rectangular_sector(self._sectors, -1, 0, -1, 1) second_sector = utils.build_rectangular_sector(self._sectors, 0, 1, -1, 0) third_sector = utils.build_rectangular_sector(self._sectors, 0, 1, 0, 1) wall = utils.find_wall_on_point(first_sector, core.Point2(0, -1)) operations.wall_link.SectorWallLink(wall, self._sectors).try_link_wall() wall_2 = wall.wall_point_2 other_side_wall = utils.find_wall_on_point(third_sector, core.Point2(0, 1)) self.assertEqual(wall_2.other_side_wall, other_side_wall) self.assertEqual(other_side_wall.other_side_wall, wall_2) other_side_wall_2 = utils.find_wall_on_point(second_sector, core.Point2(0, 0)) self.assertEqual(wall.other_side_wall, other_side_wall_2) self.assertEqual(other_side_wall_2.other_side_wall, wall)
def test_no_link_when_facing_same_direction(self): sector = utils.build_rectangular_sector(self._sectors, -1, 1, -1, 1) utils.build_rectangular_sector(self._sectors, -2, 2, -2, 1) link_wall = utils.find_wall_on_point(sector, core.Point2(1, 1)) operations.wall_link.SectorWallLink(link_wall, self._sectors).try_link_wall() self.assertIsNone(link_wall.other_side_wall)
def test_no_fill_if_not_clockwise_wall_bunch(self): sector = utils.build_rectangular_sector(self._sectors, -3, 3, -3, 3) start_wall = utils.find_wall_on_point(sector, core.Point2(-3, -3)) result = operations.sector_fill.SectorFill( sector, self._sectors).fill(start_wall) self.assertFalse(result) self.assertEqual(1, len(self._sectors.sectors))
def _get_marquee(self): start_2d = core.Point3() far = core.Point3() self._camera.lens.extrude(self._marquee_start, start_2d, far) end_2d = core.Point3() far = core.Point3() self._camera.lens.extrude(self._marquee_end, end_2d, far) start = self._camera_collection.scene.get_relative_point( self._camera.camera, start_2d) end = self._camera_collection.scene.get_relative_point( self._camera.camera, end_2d) left = min(start.x, end.x) right = max(start.x, end.x) bottom = min(start.y, end.y) top = max(start.y, end.y) return core.Point2(left, bottom), core.Point2(right, top)
def _assert_got_all_walls(self): start_wall = utils.find_wall_on_point(self._start_sector, core.Point2(0, 0)) walls_at_point = start_wall.all_walls_at_point_1() for wall in walls_at_point: self.assertEqual(wall.point_1, start_wall.point_1) wall_sectors = [wall.get_sector() for wall in walls_at_point] for sector_index, sector in enumerate(self._sectors.sectors): if sector not in wall_sectors: raise AssertionError(f"Sector {sector_index} not found in wall gather")
def setup_geometry(self, *args, **kwargs): if self._sector_type < 1: return self._sector_centre = core.Point2(0, 0) wall_count = len(self._sector.walls) if wall_count > 0: for wall in self._sector.walls: self._sector_centre += wall.point_1 self._sector_centre /= wall_count super().setup_geometry(*args, **kwargs)
def __init__( self, position: str, sector_part: str, sector: "bloom.editor.map_objects.sector.EditorSector", undos: undo_stack.UndoStack, ): super().__init__(map_data.sprite.Sprite.new(), f"z_motion_marker_{position}", sector, undos) self._position = position self._sector_part = sector_part self._sector_centre = core.Point2(0, 0)
def point_in_sector(self, point: core.Point2): ray_start = core.Point2(-(1 << 31), point.y) intersecting = 0 for editor_wall in self._walls: max_y = max(editor_wall.point_1.y, editor_wall.point_2.y) min_y = min(editor_wall.point_1.y, editor_wall.point_2.y) if min_y <= point.y and max_y > point.y: start_side = editor_wall.side_of_line(ray_start) side = editor_wall.side_of_line(point) if start_side != side: intersecting += 1 return intersecting % 2 == 1
def rotate(self, amount_in_degrees: float): self._sector.invalidate_geometry() centre = core.Point2(0, 0) for wall in self._sector.walls: centre += wall.point_1 centre /= len(self._sector.walls) rotation: core.Mat3 = core.Mat3.rotate_mat(amount_in_degrees) for wall in self._sector.walls: offset_point = wall.point_1 - centre new_point = rotation.xform_point(offset_point) + centre walls_at_point = wall.all_walls_at_point_1() for other_wall in walls_at_point: other_wall.teleport_point_1_to(new_point)
def tick(self): if not self._watcher.has_mouse(): return x = self._watcher.get_mouse_x() y = self._watcher.get_mouse_y() mouse_point = core.Point2(x, y) if self._buttons_down(): if self._mouse_down_point is None: self._mouse_down_point = mouse_point self._last_mouse_point = mouse_point if self._on_mouse_down is not None: self._on_mouse_down(self._mouse_down_point) delta: core.Vec2 = mouse_point - self._last_mouse_point total_delta: core.Vec2 = mouse_point - self._mouse_down_point moved = delta.length() > 0 if moved: self._moved_when_down = True if self._on_click_move is not None: self._on_click_move(total_delta, delta) self._last_mouse_point = mouse_point else: if self._mouse_down_point is not None: if self._no_mouse_buttons_down(): if self._moved_when_down: if self._on_click_after_move is not None: self._on_click_after_move() else: if (self._mouse_button_released and self._on_double_click is not None): self._on_double_click() else: self._mouse_button_released = True if self._on_click is not None: self._on_click() self._task_manager.do_method_later( constants.DOUBLE_CLICK_TIMEOUT, self._reset_double_click, self._id, ) self._mouse_down_point = None self._moved_when_down = False
def test_can_draw(self): sector = utils.build_rectangular_sector(self._sectors, -3, 3, -3, 3) operations.sector_insert.SectorInsert(sector, self._sectors).insert([ core.Point2(-1, -1), core.Point2(1, -1), core.Point2(1, 1), core.Point2(-1, 1), ]) self.assertEqual(2, len(self._sectors.sectors)) utils.assert_wall_bunch_not_clockwise(sector, core.Point2(-3, -3)) utils.assert_wall_bunch_clockwise(sector, core.Point2(-1, -1)) new_sector = self._sectors.sectors[1] utils.assert_wall_bunch_not_clockwise(new_sector, core.Point2(-1, -1))
def test_can_split(self): sector = utils.build_rectangular_sector(self._sectors, -1, 1, -1, 1) wall_to_split = utils.find_wall_on_point(sector, core.Point2(-1, 1)) operations.wall_split.WallSplit(wall_to_split, core.Point2(-1, 0)).split() self.assertEqual(5, len(sector.walls)) utils.assert_sector_has_point(sector, core.Point2(-1, 0)) split_wall = utils.find_wall_on_point(sector, core.Point2(-1, 0)) self.assertEqual(split_wall.wall_previous_point.point_1, core.Point2(-1, 1)) self.assertEqual(split_wall.wall_point_2.point_1, core.Point2(-1, -1))