From 1ea3c8529e465685cb163b0b810d0ceff0c9a17e Mon Sep 17 00:00:00 2001 From: Haiyi Date: Tue, 6 Aug 2024 02:23:31 +0800 Subject: [PATCH] [Version] Bump version to v0.6.3 (#34) Co-authored-by: github-actions[bot] --- .circleci/Start-CircleCIRunner.ps1 | 16 +++++++++ .circleci/continue_config.yml | 34 ++++++++++++++----- .github/workflows/release.yml | 4 +-- .gitignore | 1 + samples/setup.py | 8 +++-- .../Content/Python/sequence.py | 18 ++++++++++ xrfeitoria/camera/camera_unreal.py | 21 ++++++++++++ xrfeitoria/sequence/sequence_base.py | 13 +++++++ xrfeitoria/sequence/sequence_base.pyi | 10 +++++- xrfeitoria/sequence/sequence_blender.py | 2 ++ xrfeitoria/sequence/sequence_unreal.py | 4 +++ xrfeitoria/utils/plugin_infos.json | 5 +++ xrfeitoria/utils/publish_plugins.py | 1 + 13 files changed, 123 insertions(+), 14 deletions(-) create mode 100644 .circleci/Start-CircleCIRunner.ps1 diff --git a/.circleci/Start-CircleCIRunner.ps1 b/.circleci/Start-CircleCIRunner.ps1 new file mode 100644 index 00000000..73921f57 --- /dev/null +++ b/.circleci/Start-CircleCIRunner.ps1 @@ -0,0 +1,16 @@ +# choco install -y git gzip tar + +$installDirPath = "D:\Program Files\CircleCI" +$agentPath = Join-Path -Path $installDirPath -ChildPath "circleci-runner.exe" +$configPath = Join-Path -Path $installDirPath -ChildPath "runner-agent-config.yaml" + +echo "Constantly running CircleCI Runner Agent" +while ($true) { + echo "--- Restarting CircleCI Runner Agent ---" + try { + & $agentPath machine --config $configPath + } catch { + echo "Error: $_" + } + Start-Sleep 1 +} diff --git a/.circleci/continue_config.yml b/.circleci/continue_config.yml index 18076433..e58e4534 100644 --- a/.circleci/continue_config.yml +++ b/.circleci/continue_config.yml @@ -31,7 +31,11 @@ jobs: - when: condition: << pipeline.parameters.build-unreal-plugin >> || << pipeline.parameters.run-unreal-test >> steps: - - checkout + # - checkout + - run: + name: Clone GitHub repository + command: | + git clone << pipeline.project.git_url >> --branch << pipeline.git.branch >> . - run: name: "Build Plugins & Run Tests" shell: powershell.exe @@ -41,6 +45,16 @@ jobs: RUN_TEST: << pipeline.parameters.run-unreal-test >> PYTHONIOENCODING: "utf-8" command: | + echo "#### Get Unreal Engine ####" + $UE_51 = if (Test-Path $env:UE_51) { $env:UE_51 } else { + "C:/Program Files/Epic Games/UE_5.1/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" + } + $UE_52 = if (Test-Path $env:UE_52) { $env:UE_52 } else { + "C:/Program Files/Epic Games/UE_5.2/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" + } + $UE_53 = if (Test-Path $env:UE_53) { $env:UE_53 } else { + "C:/Program Files/Epic Games/UE_5.3/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" + } echo "#### Install XRFeitoria Package ####" conda activate xrfeitoria python -m pip install . @@ -48,19 +62,23 @@ jobs: if ($env:BUILD_UNREAL_PLUGIN -eq 1) { echo "#### Building Unreal Plugin ####" python -m xrfeitoria.utils.publish_plugins build-unreal ` - -u "C:/Program Files/Epic Games/UE_5.1/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" ` - -u "C:/Program Files/Epic Games/UE_5.2/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" ` - -u "C:/Program Files/Epic Games/UE_5.3/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" + -u $UE_51 ` + -u $UE_52 ` + -u $UE_53 $env:XRFEITORIA__VERSION=$(python -c "import xrfeitoria; print(xrfeitoria.__version__)") $env:XRFEITORIA__DIST_ROOT="$PWD/src" } if ($env:RUN_TEST -eq 1) { - echo "#### Running Tests ####" - python -m tests.setup_ci -u "C:/Program Files/Epic Games/UE_5.1/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" + echo "#### Running Tests For UE 5.1 ####" + python -m tests.setup_ci -u $UE_51 python -m tests.unreal.main - python -m tests.setup_ci -u "C:/Program Files/Epic Games/UE_5.2/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" + + echo "#### Running Tests For UE 5.2 ####" + python -m tests.setup_ci -u $UE_52 python -m tests.unreal.main - python -m tests.setup_ci -u "C:/Program Files/Epic Games/UE_5.3/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" + + echo "#### Running Tests For UE 5.3 ####" + python -m tests.setup_ci -u $UE_53 python -m tests.unreal.main } - when: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 727ceb44..28a372a0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -63,7 +63,7 @@ jobs: - 'src/XRFeitoriaUnreal/*' - name: Determine next version - if: ${{ !steps.bumpr.outputs.skip }} + if: ${{ !steps.bumpr.outputs.skip }} && ${{ steps.bumpr.outputs.next_version != '' }} run: | # Get the next version from the previous step echo "::group::Get the next version from the previous step" @@ -104,5 +104,5 @@ jobs: echo "::endgroup::" # - name: suggester / Leave comments on PRs - # if: ${{ !steps.bumpr.outputs.skip }} + # if: ${{ !steps.bumpr.outputs.skip }} && ${{ steps.bumpr.outputs.next_version != '' }} # uses: reviewdog/action-suggester@v1 diff --git a/.gitignore b/.gitignore index 709bb750..fa2c0168 100644 --- a/.gitignore +++ b/.gitignore @@ -508,6 +508,7 @@ Thumbs.db # Plugins src/*.zip +src/XRFeitoriaUnreal-*/ src/XRFeitoriaUnreal/Binaries/ # Configs diff --git a/samples/setup.py b/samples/setup.py index b5193268..dd7daa60 100644 --- a/samples/setup.py +++ b/samples/setup.py @@ -65,10 +65,12 @@ def get_exec(engine: Literal['blender', 'unreal'], exec_from_config: Optional[Pa return path.as_posix() -def ask_unreal_project() -> str: +def ask_unreal_project(unreal_project: Optional[str] = None) -> str: """Ask for unreal project path.""" - txt = 'Please input the path to the unreal project, or press [bold]enter[/bold] to download a sample project\n\[Enter]' - unreal_project = Prompt.ask(txt, default=None) + txt = 'Please input the path to the unreal project' + if unreal_project is None: + txt += ', or press [bold]enter[/bold] to download a sample project\n' '\[Enter]' + unreal_project = Prompt.ask(txt, default=unreal_project) return get_unreal_project(unreal_project) diff --git a/src/XRFeitoriaUnreal/Content/Python/sequence.py b/src/XRFeitoriaUnreal/Content/Python/sequence.py index c1d2d8e9..07d1e5ed 100644 --- a/src/XRFeitoriaUnreal/Content/Python/sequence.py +++ b/src/XRFeitoriaUnreal/Content/Python/sequence.py @@ -601,6 +601,7 @@ def add_camera_to_sequence( camera: unreal.CameraActor, camera_transform_keys: Optional[Union[SequenceTransformKey, List[SequenceTransformKey]]] = None, camera_fov: float = 90.0, + camera_aspect_ratio: float = 16.0 / 9.0, seq_length: Optional[int] = None, ) -> unreal.CameraActor: if seq_length is None: @@ -618,6 +619,11 @@ def add_camera_to_sequence( # set the camera FOV fov_track, fov_section = add_property_float_track_to_binding(camera_component_binding, 'FieldOfView', camera_fov) + # set the camera aspect ratio + aspect_ratio_track, aspect_ratio_section = add_property_float_track_to_binding( + camera_component_binding, 'AspectRatio', camera_aspect_ratio + ) + # ------- add master track ------- # camera_cut_track: unreal.MovieSceneCameraCutTrack = sequence.add_master_track(unreal.MovieSceneCameraCutTrack) # type: ignore @@ -647,6 +653,7 @@ def add_camera_to_sequence( 'self': camera.camera_component, }, 'fov': {'track': fov_track, 'section': fov_section}, + 'aspect_ratio': {'track': aspect_ratio_track, 'section': aspect_ratio_section}, 'transform': {'track': transform_track, 'section': transform_section}, } @@ -657,6 +664,7 @@ def add_spawnable_camera_to_sequence( camera_transform_keys: Optional[Union[SequenceTransformKey, List[SequenceTransformKey]]] = None, camera_class: Type[unreal.CameraActor] = unreal.CameraActor, camera_fov: float = 90.0, + camera_aspect_ratio: float = 16.0 / 9.0, seq_length: Optional[int] = None, ) -> unreal.CameraActor: """Add a camera actor to the sequence. @@ -667,6 +675,7 @@ def add_spawnable_camera_to_sequence( camera_transform_keys (Optional[Union[SequenceTransformKey, List[SequenceTransformKey]]], optional): transform keys of the camera actor. Defaults to None. camera_class (Type[unreal.CameraActor], optional): the camera actor class to spawn. Defaults to unreal.CameraActor. camera_fov (float, optional): Filed of view of the camera. Defaults to 90.0. + camera_aspect_ratio (float, optional): Aspect ratio of the camera. Defaults to 16.0 / 9.0. seq_length (Optional[int], optional): Sequence length. Defaults to None. Returns: @@ -688,6 +697,11 @@ def add_spawnable_camera_to_sequence( # set the camera FOV fov_track, fov_section = add_property_float_track_to_binding(camera_component_binding, 'FieldOfView', camera_fov) + # set the camera aspect ratio + aspect_ratio_track, aspect_ratio_section = add_property_float_track_to_binding( + camera_component_binding, 'AspectRatio', camera_aspect_ratio + ) + # ------- add master track ------- # # add master track (camera) to sequence # camera_cut_track = sequence.add_track(unreal.MovieSceneCameraCutTrack) @@ -726,6 +740,7 @@ def add_spawnable_camera_to_sequence( 'self': camera_actor.camera_component, }, 'fov': {'track': fov_track, 'section': fov_section}, + 'aspect_ratio': {'track': aspect_ratio_track, 'section': aspect_ratio_section}, 'transform': {'track': transform_track, 'section': transform_section}, } @@ -1174,6 +1189,7 @@ def add_camera( camera_name: str, transform_keys: 'Optional[TransformKeys]' = None, fov: float = 90.0, + aspect_ratio: float = 16.0 / 9.0, spawnable: bool = False, ): """Spawn a camera in sequence. @@ -1190,6 +1206,7 @@ def add_camera( camera_name=camera_name, camera_transform_keys=transform_keys, camera_fov=fov, + camera_aspect_ratio=aspect_ratio, ) cls.bindings[camera_name] = bindings else: @@ -1199,6 +1216,7 @@ def add_camera( camera=camera, camera_transform_keys=transform_keys, camera_fov=fov, + camera_aspect_ratio=aspect_ratio, ) cls.bindings[camera_name] = bindings diff --git a/xrfeitoria/camera/camera_unreal.py b/xrfeitoria/camera/camera_unreal.py index b336b67f..0d95ee26 100644 --- a/xrfeitoria/camera/camera_unreal.py +++ b/xrfeitoria/camera/camera_unreal.py @@ -1,6 +1,7 @@ from ..data_structure.constants import Vector from ..object.object_utils import ObjectUtilsUnreal from ..rpc import remote_unreal +from ..utils import Validator from .camera_base import CameraBase try: @@ -16,6 +17,16 @@ class CameraUnreal(CameraBase): _object_utils = ObjectUtilsUnreal + @property + def aspect_ratio(self) -> float: + """Aspect of ratio, Width / Height.""" + return self._get_aspect_ratio_in_engine(self._name) + + @aspect_ratio.setter + def aspect_ratio(self, value: float): + Validator.validate_argument_type(value, [float, int]) + self._set_aspect_ratio_in_engine(self._name, value) + def look_at(self, target: Vector) -> None: """Set the camera to look at the target. @@ -36,6 +47,11 @@ def _get_fov_in_engine(name): camera: unreal.CameraActor = XRFeitoriaUnrealFactory.utils_actor.get_actor_by_name(name) return camera.camera_component.field_of_view + @staticmethod + def _get_aspect_ratio_in_engine(name: str) -> float: + camera: unreal.CameraActor = XRFeitoriaUnrealFactory.utils_actor.get_actor_by_name(name) + return camera.camera_component.aspect_ratio + # ----- Setter ----- # @staticmethod @@ -47,6 +63,11 @@ def _set_camera_fov_in_engine(name, fov): camera: unreal.CameraActor = XRFeitoriaUnrealFactory.utils_actor.get_actor_by_name(name) camera.camera_component.field_of_view = fov + @staticmethod + def _set_aspect_ratio_in_engine(name: str, ratio: float): + camera: unreal.CameraActor = XRFeitoriaUnrealFactory.utils_actor.get_actor_by_name(name) + camera.camera_component.aspect_ratio = ratio + @staticmethod def _spawn_in_engine( camera_name, diff --git a/xrfeitoria/sequence/sequence_base.py b/xrfeitoria/sequence/sequence_base.py index 0e6b523e..533a833c 100644 --- a/xrfeitoria/sequence/sequence_base.py +++ b/xrfeitoria/sequence/sequence_base.py @@ -132,6 +132,7 @@ def spawn_camera( location: 'Vector' = None, rotation: 'Vector' = None, fov: float = 90.0, + aspect_ratio: float = 16.0 / 9.0, camera_name: Optional[str] = None, ) -> CameraBase: """Spawn a new camera in the sequence. @@ -140,6 +141,7 @@ def spawn_camera( location (Vector): Location of the camera. rotation (Vector): Rotation of the camera. fov (float in (0.0, 180.0), optional): Field of view of the camera len. Defaults to 90.0. (unit: degrees) + aspect_ratio (float, optional): Aspect ratio of the camera. Defaults to 16.0 / 9.0. camera_name (str, optional): Name of the camera. Defaults to None. """ if camera_name is None: @@ -148,6 +150,7 @@ def spawn_camera( cls._spawn_camera_in_engine( transform_keys=transform_keys.model_dump(), fov=fov, + aspect_ratio=aspect_ratio, camera_name=camera_name, ) logger.info(f'[cyan]Spawned[/cyan] camera "{camera_name}" in sequence "{cls.name}"') @@ -158,6 +161,7 @@ def spawn_camera_with_keys( cls, transform_keys: 'TransformKeys', fov: float = 90.0, + aspect_ratio: float = 16.0 / 9.0, camera_name: str = None, ) -> CameraBase: """Spawn a new camera with keyframes in the sequence. @@ -165,6 +169,7 @@ def spawn_camera_with_keys( Args: transform_keys (TransformKeys): Keyframes of transform (location, rotation, and scale). fov (float in (0.0, 180.0), optional): Field of view of the camera len. Defaults to 90.0. (unit: degrees) + aspect_ratio (float, optional): Aspect ratio of the camera. Defaults to 16.0 / 9.0. camera_name (str, optional): Name of the camera. Defaults to 'Camera'. """ if not isinstance(transform_keys, list): @@ -175,6 +180,7 @@ def spawn_camera_with_keys( cls._spawn_camera_in_engine( transform_keys=transform_keys, fov=fov, + aspect_ratio=aspect_ratio, camera_name=camera_name, ) logger.info( @@ -269,6 +275,7 @@ def use_camera( location: 'Optional[Vector]' = None, rotation: 'Optional[Vector]' = None, fov: float = None, + aspect_ratio: float = 16.0 / 9.0, ) -> None: """Use the specified level camera in the sequence. The location, rotation and fov set in this method are only used in the sequence. The location, rotation and @@ -279,6 +286,7 @@ def use_camera( location (Optional[Vector], optional): The location of the camera. Defaults to None. unit: meter. rotation (Optional[Vector], optional): The rotation of the camera. Defaults to None. unit: degree. fov (float, optional): The field of view of the camera. Defaults to None. unit: degree. + aspect_ratio (float, optional): The aspect ratio of the camera. Defaults to None. """ camera_name = camera.name location = camera.location if location is None else location @@ -289,6 +297,7 @@ def use_camera( cls._use_camera_in_engine( transform_keys=transform_keys.model_dump(), fov=fov, + aspect_ratio=aspect_ratio, camera_name=camera_name, ) logger.info(f'[cyan]Used[/cyan] camera "{camera_name}" in sequence "{cls.name}"') @@ -299,6 +308,7 @@ def use_camera_with_keys( camera: _camera, transform_keys: 'TransformKeys', fov: float = None, + aspect_ratio: float = 16.0 / 9.0, ) -> None: """Use the specified level camera in the sequence. The transform_keys and fov set in this method are only used in the sequence. The location, rotation and fov @@ -308,6 +318,7 @@ def use_camera_with_keys( camera (CameraUnreal or CameraBlender): The camera to use. transform_keys (TransformKeys): The transform keys to use. fov (float, optional): The field of view to use. Defaults to None. unit: degree. + aspect_ratio (float, optional): The aspect ratio of the camera. Defaults to None. """ camera_name = camera.name if not isinstance(transform_keys, list): @@ -317,6 +328,7 @@ def use_camera_with_keys( cls._use_camera_in_engine( transform_keys=transform_keys, fov=fov, + aspect_ratio=aspect_ratio, camera_name=camera_name, ) logger.info( @@ -453,6 +465,7 @@ def _import_actor_in_engine( def _spawn_camera_in_engine( transform_keys: 'Union[List[Dict], Dict]', fov: float = 90.0, + aspect_ratio: float = 16.0 / 9.0, camera_name: str = 'Camera', ) -> None: pass diff --git a/xrfeitoria/sequence/sequence_base.pyi b/xrfeitoria/sequence/sequence_base.pyi index c82f1eda..9e1137fa 100644 --- a/xrfeitoria/sequence/sequence_base.pyi +++ b/xrfeitoria/sequence/sequence_base.pyi @@ -35,7 +35,12 @@ class SequenceBase(ABC): ) -> ActorBase: ... @classmethod def spawn_camera( - cls, location: Vector = None, rotation: Vector = None, fov: float = 90.0, camera_name: Optional[str] = None + cls, + location: Vector = None, + rotation: Vector = None, + fov: float = 90.0, + aspect_ratio: float = 16.0 / 9.0, + camera_name: Optional[str] = None, ) -> CameraBase: ... @classmethod def spawn_camera_with_keys( @@ -43,6 +48,7 @@ class SequenceBase(ABC): transform_keys: TransformKeys, fov: float = 90.0, camera_name: str = None, + aspect_ratio: float = 16.0 / 9.0, ) -> CameraBase: ... @classmethod def use_camera( @@ -51,6 +57,7 @@ class SequenceBase(ABC): location: Optional[Vector] = None, rotation: Optional[Vector] = None, fov: float = None, + aspect_ratio: float = 16.0 / 9.0, ) -> None: ... @classmethod def use_camera_with_keys( @@ -58,6 +65,7 @@ class SequenceBase(ABC): camera: CameraBase, transform_keys: TransformKeys, fov: float = None, + aspect_ratio: float = 16.0 / 9.0, ) -> None: ... @classmethod def use_actor( diff --git a/xrfeitoria/sequence/sequence_blender.py b/xrfeitoria/sequence/sequence_blender.py index 10d3853f..a22cd3f1 100644 --- a/xrfeitoria/sequence/sequence_blender.py +++ b/xrfeitoria/sequence/sequence_blender.py @@ -194,6 +194,7 @@ def _import_actor_in_engine( def _spawn_camera_in_engine( transform_keys: 'Union[List[Dict], Dict]', fov: float = 90.0, + aspect_ratio: float = 16.0 / 9.0, camera_name: str = 'Camera', ) -> None: """Spawn a camera in the engine. @@ -270,6 +271,7 @@ def _spawn_shape_in_engine( def _use_camera_in_engine( transform_keys: 'Union[List[Dict], Dict]', fov: float = 90.0, + aspect_ratio: float = 16.0 / 9.0, camera_name: str = 'Camera', ) -> None: """Use level camera to render in the sequence in the engine. diff --git a/xrfeitoria/sequence/sequence_unreal.py b/xrfeitoria/sequence/sequence_unreal.py index 3d509322..5fba1654 100644 --- a/xrfeitoria/sequence/sequence_unreal.py +++ b/xrfeitoria/sequence/sequence_unreal.py @@ -460,6 +460,7 @@ def _set_camera_cut_player_in_engine( def _use_camera_in_engine( transform_keys: 'Union[List[Dict], Dict]', fov: float = 90.0, + aspect_ratio: float = 16.0 / 9.0, camera_name: str = 'Camera', ) -> None: if not isinstance(transform_keys, list): @@ -470,6 +471,7 @@ def _use_camera_in_engine( XRFeitoriaUnrealFactory.Sequence.add_camera( transform_keys=transform_keys, fov=fov, + aspect_ratio=aspect_ratio, camera_name=camera_name, ) @@ -522,6 +524,7 @@ def _import_actor_in_engine( def _spawn_camera_in_engine( transform_keys: 'Union[List[Dict], Dict]', fov: float = 90.0, + aspect_ratio: float = 16.0 / 9.0, camera_name: str = 'Camera', ) -> None: if not isinstance(transform_keys, list): @@ -532,6 +535,7 @@ def _spawn_camera_in_engine( XRFeitoriaUnrealFactory.Sequence.add_camera( transform_keys=transform_keys, fov=fov, + aspect_ratio=aspect_ratio, camera_name=camera_name, spawnable=True, ) diff --git a/xrfeitoria/utils/plugin_infos.json b/xrfeitoria/utils/plugin_infos.json index 55a6f8fa..a42b9462 100644 --- a/xrfeitoria/utils/plugin_infos.json +++ b/xrfeitoria/utils/plugin_infos.json @@ -1,4 +1,9 @@ { + "0.6.3": { + "XRFeitoria": "0.6.3", + "XRFeitoriaBpy": "0.6.2", + "XRFeitoriaUnreal": "0.6.3" + }, "0.6.2": { "XRFeitoria": "0.6.2", "XRFeitoriaBpy": "0.6.2", diff --git a/xrfeitoria/utils/publish_plugins.py b/xrfeitoria/utils/publish_plugins.py index 23ab7cb3..1cda615f 100644 --- a/xrfeitoria/utils/publish_plugins.py +++ b/xrfeitoria/utils/publish_plugins.py @@ -211,6 +211,7 @@ def build_unreal( ) # e.g. XRFeitoriaUnreal-0.6.0-Unreal5.3-Source dist_path = src_root / plugin_name subprocess.call([uat_path, 'BuildPlugin', f'-Plugin={uplugin_path}', f'-Package={dist_path}']) + assert (dist_path / 'Binaries').exists(), f'Failed to compile plugin for Unreal Engine {engine_version}' _make_archive(src_folder=dist_path, dst_path=dist_root / f'{plugin_name}.zip') _make_archive( src_folder=dist_path,