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_to_blend import *
class ExportMSH(Operator, ExportHelper):
""" Export the current scene as a SWBF .msh file. """
@ -134,7 +135,7 @@ class ImportMSH(Operator, ImportHelper):
def execute(self, context):
with open(self.filepath, 'rb') as input_file:
extract_scene(read_scene(input_file))
extract_scene(self.filepath, read_scene(input_file))
return {'FINISHED'}
def menu_func_import(self, context):

View File

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

View File

@ -10,6 +10,8 @@ from .msh_utilities import *
from .crc import *
envls = []
def read_scene(input_file) -> Scene:
scene = Scene()
@ -52,20 +54,27 @@ def read_scene(input_file) -> Scene:
pass
elif "SKL2" in next_header:
with hedr.read_child() as skl2:
num_bones = skl2.read_u32()
scene.skeleton = [skl2.read_u32(5)[0] for i in range(num_bones)]
print("Skeleton models: ")
for crc_hash in scene.skeleton:
for model in scene.models:
if crc_hash == crc(model.name):
print("\t" + model.name + " with type: " + str(model.model_type))
with hedr.read_child() as skl2:
num_bones = skl2.read_u32()
scene.skeleton = [skl2.read_u32(5)[0] for i in range(num_bones)]
print("Skeleton models: ")
for crc_hash in scene.skeleton:
for model in scene.models:
if crc_hash == crc(model.name):
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:
with hedr.read_child() as unknown:
with hedr.read_child() as null:
pass
print("Models indexed by ENVLs: ")
for envl_index in set(envls):
print("\t" + scene.models[envl_index].name)
return scene
@ -164,12 +173,23 @@ def _read_modl(modl: Reader, materials_list: List[Material]) -> Model:
elif "GEOM" in next_header:
model.geometry = []
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:
with geom.read_child() as segm:
model.geometry.append(_read_segm(segm, materials_list))
if "SEGM" in next_header_modl:
with geom.read_child() as segm:
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:
prim = CollisionPrimitive()
@ -191,7 +211,7 @@ def _read_tran(tran: Reader) -> ModelTransform:
xform = ModelTransform()
tran.skip_bytes(4 * 3) #ignore scale
tran.skip_bytes(12) #ignore scale
rot = tran.read_f32(4)
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
segm.skip_bytes(-2)
elif "WGHT" in next_header:
with segm.read_child() as null:
pass
else:
with segm.read_child() as unknown:
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 .crc import *
import os
def extract_models(scene: Scene, materials_map):
@ -21,8 +23,12 @@ def extract_models(scene: Scene, materials_map):
model_map = {}
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)
verts = []
@ -42,10 +48,11 @@ def extract_models(scene: Scene, materials_map):
offset += len(seg.positions)
new_mesh.from_pydata(verts, [], faces)
new_mesh.update()
new_mesh.validate()
'''
edit_mesh = bmesh.new()
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.free()
'''
new_obj = bpy.data.objects.new(new_mesh.name, new_mesh)
'''
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 = {}
@ -106,9 +113,16 @@ def extract_materials(scene: Scene) -> Dict[str,bpy.types.Material]:
new_mat = bpy.data.materials.new(name=material_name)
new_mat.use_nodes = True
bsdf = new_mat.node_tree.nodes["Principled BSDF"]
texImage = new_mat.node_tree.nodes.new('ShaderNodeTexImage')
texImage.image = bpy.data.images.load("/Users/will/Desktop/grad.jpg")
new_mat.node_tree.links.new(bsdf.inputs['Base Color'], texImage.outputs['Color'])
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.image = bpy.data.images.load(tex_path)
new_mat.node_tree.links.new(bsdf.inputs['Base Color'], texImage.outputs['Color'])
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):
return None
#matmap = extract_materials(scene)
#extract_models(scene, matmap)
def extract_scene(filepath: str, scene: Scene):
folder = os.path.join(os.path.dirname(filepath),"")
matmap = extract_materials(folder,scene)
extract_models(scene, matmap)