Added support for reading and importing MRPHINFO and MRPHKEYS sections.

This commit is contained in:
Colin Basnett
2023-04-03 21:28:08 -07:00
parent c99725b686
commit f54d10bb80
3 changed files with 34 additions and 0 deletions

View File

@@ -80,6 +80,19 @@ class Psk(object):
('bone_index', c_int32),
]
class MorphInfo(Structure):
_fields_ = [
('name', c_char * 64),
('vertex_count', c_int32)
]
class MorphData(Structure):
_fields_ = [
('position_delta', Vector3),
('tangent_z_delta', Vector3),
('point_index', c_int32)
]
@property
def has_extra_uvs(self):
return len(self.extra_uvs) > 0
@@ -92,6 +105,10 @@ class Psk(object):
def has_vertex_normals(self):
return len(self.vertex_normals) > 0
@property
def has_morph_data(self):
return len(self.morph_infos) > 0
def __init__(self):
self.points: List[Vector3] = []
self.wedges: List[Psk.Wedge] = []
@@ -102,3 +119,5 @@ class Psk(object):
self.extra_uvs: List[Vector2] = []
self.vertex_colors: List[Color] = []
self.vertex_normals: List[Vector3] = []
self.morph_infos: List[Psk.MorphInfo] = []
self.morph_data: List[Psk.MorphData] = []

View File

@@ -221,6 +221,7 @@ def import_psk(psk: Psk, context, options: PskImportOptions) -> PskImportResult:
bm.normal_update()
bm.free()
# WEIGHTS
# Get a list of all bones that have weights associated with them.
vertex_group_bone_indices = set(map(lambda weight: weight.bone_index, psk.weights))
vertex_groups: List[Optional[VertexGroup]] = [None] * len(psk.bones)
@@ -230,6 +231,16 @@ def import_psk(psk: Psk, context, options: PskImportOptions) -> PskImportResult:
for weight in psk.weights:
vertex_groups[weight.bone_index].add((weight.point_index,), weight.weight, 'ADD')
# MORPHS (SHAPE KEYS)
morph_data_iterator = iter(psk.morph_data)
for morph_info in psk.morph_infos:
shape_key = mesh_object.shape_key_add(name=morph_info.name.decode('windows-1252'), from_mix=False)
for _ in range(morph_info.vertex_count):
morph_data = next(morph_data_iterator)
x, y, z = morph_data.position_delta
shape_key.data[morph_data.point_index].co += Vector((x, -y, z))
context.scene.collection.objects.link(mesh_object)
# Add armature modifier to our mesh object.

View File

@@ -46,6 +46,10 @@ def read_psk(path: str) -> Psk:
_read_types(fp, Vector2, section, psk.extra_uvs)
elif section.name == b'VTXNORMS':
_read_types(fp, Vector3, section, psk.vertex_normals)
elif section.name == b'MRPHINFO':
_read_types(fp, Psk.MorphInfo, section, psk.morph_infos)
elif section.name == b'MRPHDATA':
_read_types(fp, Psk.MorphData, section, psk.morph_data)
else:
# Section is not handled, skip it.
fp.seek(section.data_size * section.data_count, os.SEEK_CUR)