1
0
mirror of https://github.com/DarklightGames/io_scene_psk_psa.git synced 2024-11-28 00:20:48 +01:00
Colin Basnett 2021-09-07 21:40:42 -07:00
parent 0622cf43e5
commit 65833b57e8
4 changed files with 62 additions and 41 deletions

View File

@ -70,8 +70,6 @@ class PsaBuilder(object):
psa.bones.append(psa_bone) psa.bones.append(psa_bone)
frame_start_index = 0
for action in options.actions: for action in options.actions:
if len(action.fcurves) == 0: if len(action.fcurves) == 0:
continue continue
@ -84,7 +82,7 @@ class PsaBuilder(object):
sequence = Psa.Sequence() sequence = Psa.Sequence()
sequence.name = bytes(action.name, encoding='utf-8') sequence.name = bytes(action.name, encoding='utf-8')
sequence.frame_count = frame_max - frame_min + 1 sequence.frame_count = frame_max - frame_min + 1
sequence.frame_start_index = frame_start_index sequence.frame_start_index = 0
sequence.fps = context.scene.render.fps sequence.fps = context.scene.render.fps
frame_count = frame_max - frame_min + 1 frame_count = frame_max - frame_min + 1

View File

@ -10,6 +10,7 @@ class PskInputObjects(object):
self.mesh_objects = [] self.mesh_objects = []
self.armature_object = None self.armature_object = None
class PskBuilder(object): class PskBuilder(object):
def __init__(self): def __init__(self):
pass pass
@ -52,14 +53,8 @@ class PskBuilder(object):
def build(self, context) -> Psk: def build(self, context) -> Psk:
input_objects = PskBuilder.get_input_objects(context) input_objects = PskBuilder.get_input_objects(context)
wedge_count = sum([len(m.data.loops) for m in input_objects.mesh_objects])
if wedge_count <= 65536:
wedge_type = Psk.Wedge16
else:
wedge_type = Psk.Wedge32
psk = Psk() psk = Psk()
materials = OrderedDict() materials = OrderedDict()
if input_objects.armature_object is None: if input_objects.armature_object is None:
@ -111,10 +106,7 @@ class PskBuilder(object):
psk.bones.append(psk_bone) psk.bones.append(psk_bone)
vertex_offset = 0 vertex_offset = 0
wedge_offset = 0
weight_offset = 0
# TODO: if there is an edge-split modifier, we need to apply it (maybe?)
for object in input_objects.mesh_objects: for object in input_objects.mesh_objects:
# VERTICES # VERTICES
for vertex in object.data.vertices: for vertex in object.data.vertices:
@ -125,17 +117,7 @@ class PskBuilder(object):
point.z = v.z point.z = v.z
psk.points.append(point) psk.points.append(point)
# WEDGES
uv_layer = object.data.uv_layers.active.data uv_layer = object.data.uv_layers.active.data
psk.wedges.extend([wedge_type() for _ in range(len(object.data.loops))])
for loop_index, loop in enumerate(object.data.loops):
wedge = psk.wedges[wedge_offset + loop_index]
wedge.material_index = 0 # NOTE: this material index is set properly while building the faces
wedge.point_index = loop.vertex_index + vertex_offset
wedge.u, wedge.v = uv_layer[loop_index].uv
wedge.v = 1.0 - wedge.v
psk.wedges.append(wedge)
# MATERIALS # MATERIALS
material_indices = [] material_indices = []
@ -153,20 +135,46 @@ class PskBuilder(object):
material_index = material.texture_index material_index = material.texture_index
material_indices.append(material_index) material_indices.append(material_index)
# FACES # WEDGES
object.data.calc_loop_triangles() object.data.calc_loop_triangles()
# Build a list of non-unique wedges.
wedges = []
for loop_index, loop in enumerate(object.data.loops):
wedge = Psk.Wedge()
wedge.point_index = loop.vertex_index + vertex_offset
wedge.u, wedge.v = uv_layer[loop_index].uv
wedge.v = 1.0 - wedge.v
wedges.append(wedge)
# Assign material indices to the wedges.
for triangle in object.data.loop_triangles:
for loop_index in triangle.loops:
wedges[loop_index].material_index = material_indices[triangle.material_index]
# Populate the list of wedges with unique wedges & build a look-up table of loop indices to wedge indices
wedge_indices = {}
loop_wedge_indices = [-1] * len(object.data.loops)
for loop_index, wedge in enumerate(wedges):
wedge_hash = hash(wedge)
if wedge_hash in wedge_indices:
loop_wedge_indices[loop_index] = wedge_indices[wedge_hash]
else:
wedge_index = len(psk.wedges)
wedge_indices[wedge_hash] = wedge_index
psk.wedges.append(wedge)
loop_wedge_indices[loop_index] = wedge_index
# FACES
poly_groups, groups = object.data.calc_smooth_groups(use_bitflags=True) poly_groups, groups = object.data.calc_smooth_groups(use_bitflags=True)
for f in object.data.loop_triangles: for f in object.data.loop_triangles:
face = Psk.Face() face = Psk.Face()
face.material_index = material_indices[f.material_index] face.material_index = material_indices[f.material_index]
face.wedge_index_1 = f.loops[2] + wedge_offset face.wedge_indices[0] = loop_wedge_indices[f.loops[2]]
face.wedge_index_2 = f.loops[1] + wedge_offset face.wedge_indices[1] = loop_wedge_indices[f.loops[1]]
face.wedge_index_3 = f.loops[0] + wedge_offset face.wedge_indices[2] = loop_wedge_indices[f.loops[0]]
face.smoothing_groups = poly_groups[f.polygon_index] face.smoothing_groups = poly_groups[f.polygon_index]
psk.faces.append(face) psk.faces.append(face)
# update the material index of the wedges
for i in range(3):
psk.wedges[wedge_offset + f.loops[i]].material_index = face.material_index
# WEIGHTS # WEIGHTS
# TODO: bone ~> vg might not be 1:1, provide a nice error message if this is the case # TODO: bone ~> vg might not be 1:1, provide a nice error message if this is the case
@ -190,8 +198,6 @@ class PskBuilder(object):
w.weight = weight w.weight = weight
psk.weights.append(w) psk.weights.append(w)
vertex_offset += len(psk.points) vertex_offset = len(psk.points)
wedge_offset += len(psk.wedges)
weight_offset += len(psk.weights)
return psk return psk

View File

@ -4,30 +4,38 @@ from ..data import *
class Psk(object): class Psk(object):
class Wedge(object):
def __init__(self):
self.point_index: int = 0
self.u: float = 0.0
self.v: float = 0.0
self.material_index: int = 0
def __hash__(self):
return hash(f'{self.point_index}-{self.u}-{self.v}-{self.material_index}')
class Wedge16(Structure): class Wedge16(Structure):
_fields_ = [ _fields_ = [
('point_index', c_int16), ('point_index', c_uint16),
('padding1', c_int16), ('padding1', c_int16),
('u', c_float), ('u', c_float),
('v', c_float), ('v', c_float),
('material_index', c_int8), ('material_index', c_uint8),
('reserved', c_int8), ('reserved', c_int8),
('padding2', c_int16) ('padding2', c_int16)
] ]
class Wedge32(Structure): class Wedge32(Structure):
_fields_ = [ _fields_ = [
('point_index', c_int32), ('point_index', c_uint32),
('u', c_float), ('u', c_float),
('v', c_float), ('v', c_float),
('material_index', c_int32) ('material_index', c_uint32)
] ]
class Face(Structure): class Face(Structure):
_fields_ = [ _fields_ = [
('wedge_index_1', c_int16), ('wedge_indices', c_uint16 * 3),
('wedge_index_2', c_int16),
('wedge_index_3', c_int16),
('material_index', c_int8), ('material_index', c_int8),
('aux_material_index', c_int8), ('aux_material_index', c_int8),
('smoothing_groups', c_int32) ('smoothing_groups', c_int32)
@ -65,7 +73,7 @@ class Psk(object):
def __init__(self): def __init__(self):
self.points: List[Vector3] = [] self.points: List[Vector3] = []
self.wedges: List[Psk.Wedge16] = [] self.wedges: List[Psk.Wedge] = []
self.faces: List[Psk.Face] = [] self.faces: List[Psk.Face] = []
self.materials: List[Psk.Material] = [] self.materials: List[Psk.Material] = []
self.weights: List[Psk.Weight] = [] self.weights: List[Psk.Weight] = []

View File

@ -29,7 +29,16 @@ class PskExporter(object):
else: else:
wedge_type = Psk.Wedge32 wedge_type = Psk.Wedge32
self.write_section(fp, b'VTXW0000', wedge_type, self.psk.wedges) wedges = []
for index, w in enumerate(self.psk.wedges):
wedge = wedge_type()
wedge.material_index = w.material_index
wedge.u = w.u
wedge.v = w.v
wedge.point_index = w.point_index
wedges.append(wedge)
self.write_section(fp, b'VTXW0000', wedge_type, wedges)
self.write_section(fp, b'FACE0000', Psk.Face, self.psk.faces) self.write_section(fp, b'FACE0000', Psk.Face, self.psk.faces)
self.write_section(fp, b'MATT0000', Psk.Material, self.psk.materials) self.write_section(fp, b'MATT0000', Psk.Material, self.psk.materials)
self.write_section(fp, b'REFSKELT', Psk.Bone, self.psk.bones) self.write_section(fp, b'REFSKELT', Psk.Bone, self.psk.bones)