1
0
mirror of https://github.com/DarklightGames/io_scene_psk_psa.git synced 2024-11-27 16:10: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)
frame_start_index = 0
for action in options.actions:
if len(action.fcurves) == 0:
continue
@ -84,7 +82,7 @@ class PsaBuilder(object):
sequence = Psa.Sequence()
sequence.name = bytes(action.name, encoding='utf-8')
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
frame_count = frame_max - frame_min + 1

View File

@ -10,6 +10,7 @@ class PskInputObjects(object):
self.mesh_objects = []
self.armature_object = None
class PskBuilder(object):
def __init__(self):
pass
@ -52,14 +53,8 @@ class PskBuilder(object):
def build(self, context) -> Psk:
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()
materials = OrderedDict()
if input_objects.armature_object is None:
@ -111,10 +106,7 @@ class PskBuilder(object):
psk.bones.append(psk_bone)
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:
# VERTICES
for vertex in object.data.vertices:
@ -125,17 +117,7 @@ class PskBuilder(object):
point.z = v.z
psk.points.append(point)
# WEDGES
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
material_indices = []
@ -153,20 +135,46 @@ class PskBuilder(object):
material_index = material.texture_index
material_indices.append(material_index)
# FACES
# WEDGES
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)
for f in object.data.loop_triangles:
face = Psk.Face()
face.material_index = material_indices[f.material_index]
face.wedge_index_1 = f.loops[2] + wedge_offset
face.wedge_index_2 = f.loops[1] + wedge_offset
face.wedge_index_3 = f.loops[0] + wedge_offset
face.wedge_indices[0] = loop_wedge_indices[f.loops[2]]
face.wedge_indices[1] = loop_wedge_indices[f.loops[1]]
face.wedge_indices[2] = loop_wedge_indices[f.loops[0]]
face.smoothing_groups = poly_groups[f.polygon_index]
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
# 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
psk.weights.append(w)
vertex_offset += len(psk.points)
wedge_offset += len(psk.wedges)
weight_offset += len(psk.weights)
vertex_offset = len(psk.points)
return psk

View File

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

View File

@ -29,7 +29,16 @@ class PskExporter(object):
else:
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'MATT0000', Psk.Material, self.psk.materials)
self.write_section(fp, b'REFSKELT', Psk.Bone, self.psk.bones)