Skip to content

Commit 6279d0b

Browse files
committed
refactor: updating animation and armature handling
1 parent 3b76565 commit 6279d0b

6 files changed

Lines changed: 777 additions & 209 deletions

File tree

io_soulworker/__init__.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
import bpy
2-
31
from logging import DEBUG, INFO, basicConfig, debug
4-
from io_soulworker.file_import.runner import FileImportRunner
5-
from io_soulworker.file_import.object_panel_default_values import FileImportObjectPanelDefaultValues
6-
from io_soulworker.file_import.object_panel_features import FileImportObjectPanelFeatures
2+
3+
try:
4+
import bpy
5+
except ModuleNotFoundError:
6+
bpy = None
7+
8+
if bpy is not None:
9+
from io_soulworker.file_import.runner import FileImportRunner
10+
from io_soulworker.file_import.object_panel_default_values import FileImportObjectPanelDefaultValues
11+
from io_soulworker.file_import.object_panel_features import FileImportObjectPanelFeatures
712

813
basicConfig(
914
level=DEBUG if __debug__ else INFO,
@@ -14,30 +19,37 @@
1419
"name": "SoulWorker",
1520
"author": "sawich",
1621
"version": (1, 0, 0),
17-
"blender": (4, 4, 0),
22+
"blender": (5, 1, 1),
1823
"location": "File > Import/Export",
1924
"description": "Import-Export SoulWorker content",
2025
"support": "COMMUNITY",
2126
"category": "Import-Export",
2227
}
2328

2429

25-
classes = {
26-
FileImportObjectPanelDefaultValues,
27-
FileImportObjectPanelFeatures,
28-
FileImportRunner,
29-
}
30+
classes = set()
31+
32+
if bpy is not None:
33+
classes = {
34+
FileImportObjectPanelDefaultValues,
35+
FileImportObjectPanelFeatures,
36+
FileImportRunner,
37+
}
3038

3139

3240
def menu_func_import(self, context):
41+
if bpy is None:
42+
return
3343

3444
self.layout.operator(
3545
FileImportRunner.bl_idname,
36-
text="SoulWorker (.model, .vmesh)"
46+
text="SoulWorker (.model, .vmesh, .anim)"
3747
)
3848

3949

4050
def register():
51+
if bpy is None:
52+
return
4153

4254
for cls in classes:
4355
bpy.utils.register_class(cls)
@@ -46,6 +58,8 @@ def register():
4658

4759

4860
def unregister():
61+
if bpy is None:
62+
return
4963

5064
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
5165

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from collections.abc import Iterable, Sequence
2+
from typing import Any
3+
4+
5+
VISION_FRAMES_PER_SECOND = 33
6+
7+
8+
def vision_time_to_frame(time: float) -> int:
9+
return round(time * VISION_FRAMES_PER_SECOND) + 1
10+
11+
12+
def group_keyframes_by_bone(
13+
keyframes: Iterable[Any],
14+
bone_names: Sequence[str],
15+
values_attr: str,
16+
) -> dict[str, list[tuple[int, Any]]]:
17+
grouped = {name: [] for name in bone_names}
18+
19+
for keyframe in keyframes:
20+
frame = vision_time_to_frame(keyframe.time)
21+
values = getattr(keyframe, values_attr)
22+
23+
for bone_index, bone_name in enumerate(bone_names):
24+
if bone_index >= len(values):
25+
break
26+
27+
grouped[bone_name].append((frame, values[bone_index]))
28+
29+
return grouped

io_soulworker/file_import/animation/chunk_reader.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from io_soulworker.chunks.brot_chunk import BrotChunk
44
from io_soulworker.chunks.xbsv_chunk import XbsvChunk
55
from io_soulworker.chunks.head_chunk import HeadChunk
6+
from io_soulworker.chunks.skel_chunk import SkelChunk
67
from io_soulworker.core.binary_reader import BinaryReader
78
from io_soulworker.core.vis_chunk_file import VisChunkFileReader
89
from io_soulworker.core.vis_chunk_id import VisChunkId
@@ -26,6 +27,12 @@ def on_bone_rotation(self, chunk: BrotChunk) -> None:
2627
def on_animation(self, skeleton_index: int, name: str) -> None:
2728
debug('Not impl callback')
2829

30+
def on_animation_end(self) -> None:
31+
debug('Not impl callback')
32+
33+
def on_skeleton(self, chunk: SkelChunk) -> None:
34+
debug('Not impl callback')
35+
2936
def on_chunk_start(self, scope: VisChunkReaderScope, reader: BinaryReader) -> None:
3037

3138
if scope.chunk == VisChunkId.HEAD:
@@ -50,6 +57,11 @@ def on_chunk_start(self, scope: VisChunkReaderScope, reader: BinaryReader) -> No
5057

5158
self.on_animation(skeleton_index, name)
5259
self.run_sub(reader, scope)
60+
self.on_animation_end()
61+
62+
elif scope.chunk == VisChunkId.SKEL:
63+
64+
self.on_skeleton(SkelChunk(reader))
5365

5466
elif scope.chunk == VisChunkId.VSBX:
5567

0 commit comments

Comments
 (0)