Reader class simplified

This commit is contained in:
William Herald Snyder 2020-11-01 18:11:26 -05:00
parent 706c32431d
commit 049803f750
4 changed files with 104 additions and 31 deletions

View File

@ -62,6 +62,7 @@ from .msh_scene_read import read_scene
from .msh_material_properties import * from .msh_material_properties import *
from .msh_to_blend import * from .msh_to_blend import *
class ExportMSH(Operator, ExportHelper): class ExportMSH(Operator, ExportHelper):
""" Export the current scene as a SWBF .msh file. """ """ Export the current scene as a SWBF .msh file. """
@ -134,7 +135,7 @@ class ImportMSH(Operator, ImportHelper):
def execute(self, context): def execute(self, context):
with open(self.filepath, 'rb') as input_file: with open(self.filepath, 'rb') as input_file:
extract_scene(read_scene(input_file)) extract_scene(self.filepath, read_scene(input_file))
return {'FINISHED'} return {'FINISHED'}
def menu_func_import(self, context): def menu_func_import(self, context):

View File

@ -16,9 +16,9 @@ class ModelType(Enum):
class CollisionPrimitiveShape(Enum): class CollisionPrimitiveShape(Enum):
SPHERE = 0 SPHERE = 0
# ELLIPSOID = 1 ELLIPSOID = 1
CYLINDER = 2 CYLINDER = 2
# MESH = 3 MESH = 3
BOX = 4 BOX = 4
@dataclass @dataclass

View File

@ -10,6 +10,8 @@ from .msh_utilities import *
from .crc import * from .crc import *
envls = []
def read_scene(input_file) -> Scene: def read_scene(input_file) -> Scene:
scene = Scene() scene = Scene()
@ -61,11 +63,18 @@ def read_scene(input_file) -> Scene:
if crc_hash == crc(model.name): if crc_hash == crc(model.name):
print("\t" + model.name + " with type: " + str(model.model_type)) print("\t" + model.name + " with type: " + str(model.model_type))
elif "ANM2" in next_header:
with hedr.read_child() as anm2:
_read_anm2(anm2, scene.models)
else: else:
with hedr.read_child() as unknown: with hedr.read_child() as null:
pass pass
print("Models indexed by ENVLs: ")
for envl_index in set(envls):
print("\t" + scene.models[envl_index].name)
return scene return scene
@ -164,13 +173,24 @@ def _read_modl(modl: Reader, materials_list: List[Material]) -> Model:
elif "GEOM" in next_header: elif "GEOM" in next_header:
model.geometry = [] model.geometry = []
with modl.read_child() as geom: with modl.read_child() as geom:
while geom.could_have_child():
next_header_geom = geom.peak_next_header()
next_header_modl = geom.peak_next_header() if "SEGM" in next_header_geom:
if "SEGM" in next_header_modl:
with geom.read_child() as segm: with geom.read_child() as segm:
model.geometry.append(_read_segm(segm, materials_list)) model.geometry.append(_read_segm(segm, materials_list))
elif "ENVL" in next_header_geom:
with geom.read_child() as envl:
global envls
num_indicies = envl.read_u32()
print("reading ENVL with " + str(num_indicies) + " indicies")
envls += [envl.read_u32() for _ in range(num_indicies)]
else:
with geom.read_child() as null:
pass
elif "SWCI" in next_header: elif "SWCI" in next_header:
prim = CollisionPrimitive() prim = CollisionPrimitive()
with modl.read_child() as swci: with modl.read_child() as swci:
@ -191,7 +211,7 @@ def _read_tran(tran: Reader) -> ModelTransform:
xform = ModelTransform() xform = ModelTransform()
tran.skip_bytes(4 * 3) #ignore scale tran.skip_bytes(12) #ignore scale
rot = tran.read_f32(4) rot = tran.read_f32(4)
xform.rotation = Quaternion((rot[3], rot[0], rot[1], rot[2])) xform.rotation = Quaternion((rot[3], rot[0], rot[1], rot[2]))
@ -264,6 +284,10 @@ def _read_segm(segm: Reader, materials_list: List[Material]) -> GeometrySegment:
if segm.read_u16 != 0: #trailing 0 bug https://schlechtwetterfront.github.io/ze_filetypes/msh.html#STRP if segm.read_u16 != 0: #trailing 0 bug https://schlechtwetterfront.github.io/ze_filetypes/msh.html#STRP
segm.skip_bytes(-2) segm.skip_bytes(-2)
elif "WGHT" in next_header:
with segm.read_child() as null:
pass
else: else:
with segm.read_child() as unknown: with segm.read_child() as unknown:
pass pass
@ -272,3 +296,35 @@ def _read_segm(segm: Reader, materials_list: List[Material]) -> GeometrySegment:
def _read_anm2(anm2: Reader, models):
hash_dict = {}
for model in models:
hash_dict[crc(model.name)] = model.name
while anm2.could_have_child():
next_header = anm2.peak_next_header()
if "CYCL" in next_header:
with anm2.read_child() as cycl:
pass
elif "KFR3" in next_header:
with anm2.read_child() as kfr3:
num_bones = kfr3.read_u32()
for _ in range(num_bones):
kfr3.read_u32()
frametype = kfr3.read_u32()
num_loc_frames = kfr3.read_u32()
num_rot_frames = kfr3.read_u32()
kfr3.skip_bytes(16 * num_loc_frames + 20 * num_rot_frames)

View File

@ -14,6 +14,8 @@ from .msh_utilities import *
from .msh_model_gather import * from .msh_model_gather import *
from .crc import * from .crc import *
import os
def extract_models(scene: Scene, materials_map): def extract_models(scene: Scene, materials_map):
@ -21,8 +23,12 @@ def extract_models(scene: Scene, materials_map):
model_map = {} model_map = {}
for model in sort_by_parent(scene.models): for model in sort_by_parent(scene.models):
new_obj = None
if model.model_type == ModelType.STATIC: if model.name.startswith("p_") or "collision" in model.name:
continue
if model.model_type == ModelType.STATIC or model.model_type == ModelType.SKIN:
new_mesh = bpy.data.meshes.new(model.name) new_mesh = bpy.data.meshes.new(model.name)
verts = [] verts = []
@ -42,10 +48,11 @@ def extract_models(scene: Scene, materials_map):
offset += len(seg.positions) offset += len(seg.positions)
new_mesh.from_pydata(verts, [], faces) new_mesh.from_pydata(verts, [], faces)
new_mesh.update() new_mesh.update()
new_mesh.validate() new_mesh.validate()
'''
edit_mesh = bmesh.new() edit_mesh = bmesh.new()
edit_mesh.from_mesh(new_mesh) edit_mesh.from_mesh(new_mesh)
@ -60,11 +67,11 @@ def extract_models(scene: Scene, materials_map):
edit_mesh.to_mesh(new_mesh) edit_mesh.to_mesh(new_mesh)
edit_mesh.free() edit_mesh.free()
'''
new_obj = bpy.data.objects.new(new_mesh.name, new_mesh) new_obj = bpy.data.objects.new(new_mesh.name, new_mesh)
''' '''
Assign Materials - will do per segment later... Assign Materials - will do per segment later...
''' '''
@ -97,7 +104,7 @@ def extract_models(scene: Scene, materials_map):
def extract_materials(scene: Scene) -> Dict[str,bpy.types.Material]: def extract_materials(folder_path: str, scene: Scene) -> Dict[str,bpy.types.Material]:
extracted_materials = {} extracted_materials = {}
@ -106,8 +113,15 @@ def extract_materials(scene: Scene) -> Dict[str,bpy.types.Material]:
new_mat = bpy.data.materials.new(name=material_name) new_mat = bpy.data.materials.new(name=material_name)
new_mat.use_nodes = True new_mat.use_nodes = True
bsdf = new_mat.node_tree.nodes["Principled BSDF"] bsdf = new_mat.node_tree.nodes["Principled BSDF"]
tex_path_def = os.path.join(folder_path, scene.materials[material_name].texture0)
tex_path_alt = os.path.join(folder_path, "PC", scene.materials[material_name].texture0)
tex_path = tex_path_def if os.path.exists(tex_path_def) else tex_path_alt
if os.path.exists(tex_path):
texImage = new_mat.node_tree.nodes.new('ShaderNodeTexImage') texImage = new_mat.node_tree.nodes.new('ShaderNodeTexImage')
texImage.image = bpy.data.images.load("/Users/will/Desktop/grad.jpg") texImage.image = bpy.data.images.load(tex_path)
new_mat.node_tree.links.new(bsdf.inputs['Base Color'], texImage.outputs['Color']) new_mat.node_tree.links.new(bsdf.inputs['Base Color'], texImage.outputs['Color'])
extracted_materials[material_name] = new_mat extracted_materials[material_name] = new_mat
@ -116,10 +130,12 @@ def extract_materials(scene: Scene) -> Dict[str,bpy.types.Material]:
def extract_scene(scene: Scene): def extract_scene(filepath: str, scene: Scene):
return None
#matmap = extract_materials(scene) folder = os.path.join(os.path.dirname(filepath),"")
#extract_models(scene, matmap)
matmap = extract_materials(folder,scene)
extract_models(scene, matmap)