Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff2fe35846 | ||
|
|
f6fa646a63 | ||
|
|
16471344f0 | ||
|
|
172249dfff | ||
|
|
0b30161cd7 | ||
|
|
e66f7f98e2 | ||
|
|
879c3cbaf6 | ||
|
|
2e7814804d | ||
|
|
2f972a31df | ||
|
|
18915b3d86 | ||
|
|
5ea7e23cb9 | ||
|
|
385acd40bb | ||
|
|
5cfb883a32 |
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Build Extension
|
||||
name: tests
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
7
.vscode/tasks.json
vendored
7
.vscode/tasks.json
vendored
@@ -6,7 +6,12 @@
|
||||
{
|
||||
"label": "io_scene_psk_psa: test",
|
||||
"type": "shell",
|
||||
"command": "docker run -it --volume ${PWD}/io_scene_psk_psa:/addons/io_scene_psk_psa --volume ${PWD}/tests:/tests $(docker build -q .)"
|
||||
"command": "docker run -it --volume ${PWD}:/io_scene_psk_psa --volume ${PWD}/io_scene_psk_psa:/addons/io_scene_psk_psa --volume ${PWD}/tests:/tests $(docker build -q .)",
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -13,16 +13,16 @@ RUN pip install blender-downloader
|
||||
# Set BLENDER_EXECUTABLE and BLENDER_PYTHON as environment variables
|
||||
RUN BLENDER_EXECUTABLE=$(blender-downloader $BLENDER_VERSION --extract --remove-compressed --print-blender-executable) && \
|
||||
BLENDER_PYTHON=$(pytest-blender --blender-executable "${BLENDER_EXECUTABLE}") && \
|
||||
echo "Blender executable: $BLENDER_EXECUTABLE" && \
|
||||
echo "Blender Python: $BLENDER_PYTHON" && \
|
||||
echo "export BLENDER_EXECUTABLE=${BLENDER_EXECUTABLE}" >> /etc/environment && \
|
||||
echo "export BLENDER_PYTHON=${BLENDER_PYTHON}" >> /etc/environment && \
|
||||
echo $BLENDER_EXECUTABLE > /blender_executable_path
|
||||
|
||||
RUN pip install pytest-cov
|
||||
|
||||
# Source the environment variables and install Python dependencies
|
||||
RUN . /etc/environment && \
|
||||
$BLENDER_PYTHON -m ensurepip && \
|
||||
$BLENDER_PYTHON -m pip install pytest
|
||||
$BLENDER_PYTHON -m pip install pytest pytest-cov
|
||||
|
||||
# Persist BLENDER_EXECUTABLE as an environment variable
|
||||
RUN echo $(cat /blender_executable_path) > /tmp/blender_executable_path_env && \
|
||||
@@ -30,4 +30,5 @@ RUN echo $(cat /blender_executable_path) > /tmp/blender_executable_path_env && \
|
||||
ENV BLENDER_EXECUTABLE /tmp/blender_executable_path_env
|
||||
|
||||
ENTRYPOINT [ "/bin/bash", "-c" ]
|
||||
CMD ["export BLENDER_EXECUTABLE=$(cat /blender_executable_path) && echo $BLENDER_EXECUTABLE && pytest -svv tests --blender-executable $BLENDER_EXECUTABLE --blender-addons-dirs addons"]
|
||||
WORKDIR /io_scene_psk_psa
|
||||
CMD ["source tests/test.sh"]
|
||||
|
||||
47
README.md
47
README.md
@@ -1,6 +1,5 @@
|
||||
[](https://www.blender.org/download/ "Download Blender")
|
||||
[](https://github.com/DarklightGames/io_scene_psk_psa/releases/)
|
||||
[](https://github.com/DarklightGames/io_scene_psk_psa/actions/workflows/main.yml)
|
||||
[](https://extensions.blender.org/add-ons/io-scene-psk-psa/ "Download Blender")
|
||||
[](https://github.com/DarklightGames/io_scene_psk_psa/actions/workflows/main.yml)
|
||||
|
||||
[](https://ko-fi.com/L4L3853VR)
|
||||
|
||||
@@ -20,22 +19,10 @@ This software is licensed under the [GPLv3](https://www.gnu.org/licenses/gpl-3.0
|
||||
* Support for exporting instance collections.
|
||||
|
||||
# Installation
|
||||
For Blender 4.2 and higher, it is recommended to download the latest version from the [Blender Extensions](https://extensions.blender.org/add-ons/io-scene-psk-psa/) platform.
|
||||
For Blender 4.2 and higher, download the latest version from the [Blender Extensions](https://extensions.blender.org/add-ons/io-scene-psk-psa/) platform.
|
||||
|
||||
For Blender 4.1 and lower, see [Legacy Compatibility](#legacy-compatibility).
|
||||
|
||||
# Legacy Compatibility
|
||||
Below is a table of the latest addon versions that are compatible with older versions of Blender. These versions are no longer maintained and may contain bugs that have been fixed in newer versions. It is recommended to use the latest version of the addon for the best experience.
|
||||
|
||||
Critical bug fixes may be issued for legacy addon versions that are under [Blender's LTS maintenance period](https://www.blender.org/download/lts/). Once the LTS period has ended, legacy addon versions will no longer be supported by the maintainers of this repository, although the releases will still be available for download.
|
||||
|
||||
| Blender Version| Addon Version | Long Term Support |
|
||||
|-|--------------------------------------------------------------------------------|-----------------|
|
||||
| [4.1](https://www.blender.org/download/releases/4-1/) | [7.0.0](https://github.com/DarklightGames/io_scene_psk_psa/releases/tag/7.0.0) | No |
|
||||
| [4.0](https://www.blender.org/download/releases/4-0/) | [6.2.1](https://github.com/DarklightGames/io_scene_psk_psa/releases/tag/6.2.1) | No |
|
||||
| [3.4 - 3.6](https://www.blender.org/download/lts/3-6/) | [5.0.6](https://github.com/DarklightGames/io_scene_psk_psa/releases/tag/5.0.6) | June 2025 |
|
||||
| [2.93 - 3.3](https://www.blender.org/download/releases/3-3/) | [4.3.0](https://github.com/DarklightGames/io_scene_psk_psa/releases/tag/4.3.0) | ~~September 2024~~ |
|
||||
|
||||
# Usage
|
||||
## Exporting a PSK
|
||||
1. Select the mesh objects you wish to export.
|
||||
@@ -69,7 +56,7 @@ The PSA importer creates [Actions](https://docs.blender.org/manual/en/latest/ani
|
||||
## Why are imported PSKs too big/too small?
|
||||
The PSK format, unlike other more modern formats, has no explicit or implicit unit system. Each game has its own convention as to what the base distance unit will represent. As such, this addon makes no assumptions as to the unit scale of the imported PSKs. If you think that your models are being imported into Blender either too big or too small, there are a couple ways to remedy this.
|
||||
|
||||
The method I prefer is to simply change the Blender [scene properties](https://docs.blender.org/manual/en/4.4/scene_layout/scene/properties.html#units) to match the unit system and scale for the game you're using. This is non-destructive and ensures that the actual raw unit scaling of any PSK or PSA exports from Blender will match the source file from which it was derived.
|
||||
The method I prefer is to simply change the Blender [scene properties](https://docs.blender.org/manual/en/4.4/scene_layout/scene/properties.html#units) to match the unit system and scale for the game you're using. This is non-destructive and ensures that the unit scaling of any PSK or PSA exports from Blender will match the source file from which it was derived.
|
||||
|
||||
The second option is to simply change the `Scale` value on the PSK import dialog. This will scale the armature by the factor provided. Note that this is more destructive, but may be preferable if you don't intend on exporting PSKs or PSAs to a game engine.
|
||||
|
||||
@@ -79,4 +66,28 @@ The PSK format does not support vertex normals and instead uses [smoothing group
|
||||
## Why are the mesh normals not accurate when importing a PSK extracted from [UE Viewer](https://www.gildor.org/en/projects/umodel)?
|
||||
If preserving the mesh normals of models is important for your workflow, it is *not recommended* to export PSK files from UE Viewer. This is because UE Viewer makes no attempt to reconstruct the original [smoothing groups](https://en.wikipedia.org/wiki/Smoothing_group). As a result, the normals of imported PSK files will be incorrect when imported into Blender and will need to be manually fixed.
|
||||
|
||||
There is a [pull request](https://github.com/gildor2/UEViewer/pull/277) to add support for exporting explicit normals from UE Viewer in the future.
|
||||
There is a [pull request](https://github.com/gildor2/UEViewer/pull/277) to add support for exporting explicit normals from UE Viewer, although UEViewer's maintainer has seemingly abandoned the project.
|
||||
|
||||
# Legacy Compatibility
|
||||
Below is a table of the latest addon versions that are compatible with older versions of Blender. These versions are no longer maintained and may contain bugs that have been fixed in newer versions. It is recommended to use the latest version of the addon for the best experience.
|
||||
|
||||
Critical bug fixes may be issued for legacy addon versions that are under [Blender's LTS maintenance period](https://www.blender.org/download/lts/). Once the LTS period has ended, legacy addon versions will no longer be supported by the maintainers of this repository, although the releases will still be available for download.
|
||||
|
||||
| Blender Version| Addon Version | Long Term Support |
|
||||
|-|--------------------------------------------------------------------------------|-----------------|
|
||||
| [4.1](https://www.blender.org/download/releases/4-1/) | [7.0.0](https://github.com/DarklightGames/io_scene_psk_psa/releases/tag/7.0.0) | No |
|
||||
| [4.0](https://www.blender.org/download/releases/4-0/) | [6.2.1](https://github.com/DarklightGames/io_scene_psk_psa/releases/tag/6.2.1) | No |
|
||||
| [3.4 - 3.6](https://www.blender.org/download/lts/3-6/) | [5.0.6](https://github.com/DarklightGames/io_scene_psk_psa/releases/tag/5.0.6) | June 2025 |
|
||||
| [2.93 - 3.3](https://www.blender.org/download/releases/3-3/) | [4.3.0](https://github.com/DarklightGames/io_scene_psk_psa/releases/tag/4.3.0) | ~~September 2024~~ |
|
||||
|
||||
|
||||
# Testing
|
||||
To execute the automated tests, run:
|
||||
|
||||
```
|
||||
./test.sh
|
||||
````
|
||||
|
||||
This will create a [Docker](https://www.docker.com/) container with and run the tests inside it. The tests are executed using [pytest](https://docs.pytest.org/en/stable/) and the results will be displayed in the terminal.
|
||||
|
||||
For now, the tests are not exhaustive and primarily focus on sanity checking the most common use cases (PSK & PSA import). New tests will likely be made to cover new features and prevent further regressions of reported issues.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
schema_version = "1.0.0"
|
||||
id = "io_scene_psk_psa"
|
||||
version = "8.1.0"
|
||||
version = "8.1.2"
|
||||
name = "Unreal PSK/PSA (.psk/.psa)"
|
||||
tagline = "Import and export PSK and PSA files used in Unreal Engine"
|
||||
maintainer = "Colin Basnett <cmbasnett@gmail.com>"
|
||||
|
||||
@@ -91,7 +91,7 @@ def _get_pose_bone_location_and_rotation(
|
||||
else:
|
||||
is_child_bone = pose_bone.parent is not None
|
||||
|
||||
if is_child_bone is not None:
|
||||
if is_child_bone:
|
||||
rotation.conjugate()
|
||||
|
||||
return location, rotation
|
||||
|
||||
@@ -179,7 +179,7 @@ def build_psk(context: Context, input_objects: PskInputObjects, options: PskBuil
|
||||
|
||||
for material in materials:
|
||||
psk_material = Psk.Material()
|
||||
psk_material.name = convert_string_to_cp1252_bytes(material.name)
|
||||
psk_material.name = convert_string_to_cp1252_bytes(material.name if material else 'None')
|
||||
psk_material.texture_index = len(psk.materials)
|
||||
psk_material.poly_flags = triangle_type_and_bit_flags_to_poly_flags(material.psk.mesh_triangle_type,
|
||||
material.psk.mesh_triangle_bit_flags)
|
||||
@@ -421,6 +421,9 @@ def build_psk(context: Context, input_objects: PskInputObjects, options: PskBuil
|
||||
|
||||
context.window_manager.progress_end()
|
||||
|
||||
# https://github.com/DarklightGames/io_scene_psk_psa/issues/129.
|
||||
psk.sort_and_normalize_weights()
|
||||
|
||||
result.psk = psk
|
||||
|
||||
return result
|
||||
|
||||
@@ -113,6 +113,31 @@ class Psk(object):
|
||||
def has_morph_data(self):
|
||||
return len(self.morph_infos) > 0
|
||||
|
||||
def sort_and_normalize_weights(self):
|
||||
self.weights.sort(key=lambda x: x.point_index)
|
||||
|
||||
weight_index = 0
|
||||
weight_total = len(self.weights)
|
||||
|
||||
while weight_index < weight_total:
|
||||
point_index = self.weights[weight_index].point_index
|
||||
weight_sum = self.weights[weight_index].weight
|
||||
point_weight_total = 1
|
||||
|
||||
# Calculate the sum of weights for the current point_index.
|
||||
for i in range(weight_index + 1, weight_total):
|
||||
if self.weights[i].point_index != point_index:
|
||||
break
|
||||
weight_sum += self.weights[i].weight
|
||||
point_weight_total += 1
|
||||
|
||||
# Normalize the weights for the current point_index.
|
||||
for i in range(weight_index, weight_index + point_weight_total):
|
||||
self.weights[i].weight /= weight_sum
|
||||
|
||||
# Move to the next group of weights.
|
||||
weight_index += point_weight_total
|
||||
|
||||
def __init__(self):
|
||||
self.points: List[Vector3] = []
|
||||
self.wedges: List[Psk.Wedge] = []
|
||||
|
||||
@@ -307,7 +307,8 @@ def create_psx_bones(
|
||||
bones: List[Tuple[PsxBone, Optional[Object]]] = []
|
||||
|
||||
if export_space != 'WORLD' and len(armature_objects) > 1:
|
||||
raise RuntimeError('When exporting multiple armatures, the Export Space must be World')
|
||||
armature_object_names = [armature_object.name for armature_object in armature_objects]
|
||||
raise RuntimeError(f'When exporting multiple armatures, the Export Space must be World. The following armatures are attempting to be exported: {armature_object_names}')
|
||||
|
||||
coordinate_system_matrix = get_coordinate_system_transform(forward_axis, up_axis)
|
||||
coordinate_system_default_rotation = coordinate_system_matrix.to_quaternion()
|
||||
|
||||
@@ -3,4 +3,10 @@ name = "io_scene_psk_psa"
|
||||
|
||||
[pytest]
|
||||
blender-addons-dirs = "io_scene_psk_psa"
|
||||
testpaths = "tests"
|
||||
testpaths = "../tests"
|
||||
|
||||
[tool.coverage.run]
|
||||
branch = true
|
||||
|
||||
[tool.coverage.report]
|
||||
ignore_errors = true
|
||||
|
||||
2
test.sh
Executable file
2
test.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
# usr/bin/env bash
|
||||
docker run -it --volume ${PWD}:/io_scene_psk_psa --volume ${PWD}/io_scene_psk_psa:/addons/io_scene_psk_psa --volume ${PWD}/tests:/tests $(docker build -q .)
|
||||
8
tests/test.sh
Normal file
8
tests/test.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
# usr/bin/env bash
|
||||
# This file is meant to be executed from inside a Docker container.
|
||||
# To run tests on the host system, use the `test.sh` script in the root directory.
|
||||
export BLENDER_EXECUTABLE=$(cat /blender_executable_path)
|
||||
pytest --cov-report xml --cov=/root/.config/blender -svv tests --blender-executable $BLENDER_EXECUTABLE --blender-addons-dirs ../addons
|
||||
# Fixes the paths in the coverage report to be relative to the current directory.
|
||||
sed -i 's|/root/.config/blender||g' coverage.xml
|
||||
sed -i 's|4.4/scripts/addons/io_scene_psk_psa/||g' coverage.xml
|
||||
Reference in New Issue
Block a user