mirror of
https://github.com/DarklightGames/io_scene_psk_psa.git
synced 2024-11-28 00:20:48 +01:00
This commit is contained in:
parent
0622cf43e5
commit
65833b57e8
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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] = []
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user