msh_reader refined, more chunks implemented
This commit is contained in:
@@ -16,7 +16,7 @@ def read_scene(input_file) -> Scene:
|
||||
scene.models = []
|
||||
scene.materials = {}
|
||||
|
||||
with Reader(file=input_file, chunk_id="HEDR") as hedr:
|
||||
with Reader(file=input_file) as hedr:
|
||||
|
||||
while hedr.could_have_child():
|
||||
|
||||
@@ -24,7 +24,7 @@ def read_scene(input_file) -> Scene:
|
||||
|
||||
if "MSH2" in next_header:
|
||||
|
||||
with hedr.read_child("MSH2") as msh2:
|
||||
with hedr.read_child() as msh2:
|
||||
|
||||
materials_list = []
|
||||
|
||||
@@ -33,26 +33,37 @@ def read_scene(input_file) -> Scene:
|
||||
next_header = msh2.peak_next_header()
|
||||
|
||||
if "SINF" in next_header:
|
||||
with msh2.read_child("SINF") as sinf:
|
||||
with msh2.read_child() as sinf:
|
||||
pass
|
||||
|
||||
elif "MATL" in next_header:
|
||||
with msh2.read_child("MATL") as matl:
|
||||
with msh2.read_child() as matl:
|
||||
materials_list += _read_matl_and_get_materials_list(matl)
|
||||
for i,mat in enumerate(materials_list):
|
||||
scene.materials[mat.name] = mat
|
||||
|
||||
elif "MODL" in next_header:
|
||||
while ("MODL" in msh2.peak_next_header()):
|
||||
with msh2.read_child("MODL") as modl:
|
||||
with msh2.read_child() as modl:
|
||||
scene.models.append(_read_modl(modl, materials_list))
|
||||
|
||||
else:
|
||||
with hedr.read_child("NULL") as unknown:
|
||||
with hedr.read_child() as unknown:
|
||||
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))
|
||||
|
||||
|
||||
else:
|
||||
with hedr.read_child("NULL") as unknown:
|
||||
with hedr.read_child() as unknown:
|
||||
pass
|
||||
|
||||
return scene
|
||||
@@ -64,7 +75,7 @@ def _read_matl_and_get_materials_list(matl: Reader) -> List[Material]:
|
||||
num_mats = matl.read_u32()
|
||||
|
||||
for _ in range(num_mats):
|
||||
with matl.read_child("MATD") as matd:
|
||||
with matl.read_child() as matd:
|
||||
materials_list.append(_read_matd(matd))
|
||||
|
||||
return materials_list
|
||||
@@ -80,36 +91,36 @@ def _read_matd(matd: Reader) -> Material:
|
||||
next_header = matd.peak_next_header()
|
||||
|
||||
if "NAME" in next_header:
|
||||
with matd.read_child("NAME") as name:
|
||||
with matd.read_child() as name:
|
||||
mat.name = name.read_string()
|
||||
|
||||
elif "DATA" in next_header:
|
||||
with matd.read_child("DATA") as data:
|
||||
with matd.read_child() as data:
|
||||
data.read_f32(4) # Diffuse Color (Seams to get ignored by modelmunge)
|
||||
mat.specular_color = data.read_f32(4)
|
||||
data.read_f32(4) # Ambient Color (Seams to get ignored by modelmunge and Zero(?))
|
||||
data.read_f32() # Specular Exponent/Decay (Gets ignored by RedEngine in SWBFII for all known materials)
|
||||
|
||||
elif "ATRB" in next_header:
|
||||
with matd.read_child("ATRB") as atrb:
|
||||
with matd.read_child() as atrb:
|
||||
mat.flags = atrb.read_u8()
|
||||
mat.rendertype = atrb.read_u8()
|
||||
mat.data = atrb.read_u8(2)
|
||||
|
||||
elif "TX0D" in next_header:
|
||||
with matd.read_child("TX0D") as tx0d:
|
||||
with matd.read_child() as tx0d:
|
||||
mat.texture0 = tx0d.read_string()
|
||||
|
||||
elif "TX1D" in next_header:
|
||||
with matd.read_child("TX1D") as tx1d:
|
||||
with matd.read_child() as tx1d:
|
||||
mat.texture1 = tx1d.read_string()
|
||||
|
||||
elif "TX2D" in next_header:
|
||||
with matd.read_child("TX2D") as tx2d:
|
||||
with matd.read_child() as tx2d:
|
||||
mat.texture2 = tx2d.read_string()
|
||||
|
||||
elif "TX3D" in next_header:
|
||||
with matd.read_child("TX3D") as tx3d:
|
||||
with matd.read_child() as tx3d:
|
||||
mat.texture3 = tx3d.read_string()
|
||||
|
||||
else:
|
||||
@@ -127,50 +138,50 @@ def _read_modl(modl: Reader, materials_list: List[Material]) -> Model:
|
||||
next_header = modl.peak_next_header()
|
||||
|
||||
if "MTYP" in next_header:
|
||||
with modl.read_child("MTYP") as mtyp:
|
||||
with modl.read_child() as mtyp:
|
||||
model.model_type = ModelType(mtyp.read_u32())
|
||||
|
||||
elif "MNDX" in next_header:
|
||||
with modl.read_child("MNDX") as mndx:
|
||||
with modl.read_child() as mndx:
|
||||
pass
|
||||
|
||||
elif "NAME" in next_header:
|
||||
with modl.read_child("NAME") as name:
|
||||
with modl.read_child() as name:
|
||||
model.name = name.read_string()
|
||||
|
||||
elif "PRNT" in next_header:
|
||||
with modl.read_child("PRNT") as prnt:
|
||||
with modl.read_child() as prnt:
|
||||
model.parent = prnt.read_string()
|
||||
|
||||
elif "FLGS" in next_header:
|
||||
with modl.read_child("FLGS") as flgs:
|
||||
with modl.read_child() as flgs:
|
||||
model.hidden = flgs.read_u32()
|
||||
|
||||
elif "TRAN" in next_header:
|
||||
with modl.read_child("TRAN") as tran:
|
||||
with modl.read_child() as tran:
|
||||
model.transform = _read_tran(tran)
|
||||
|
||||
elif "GEOM" in next_header:
|
||||
model.geometry = []
|
||||
with modl.read_child("GEOM") as geom:
|
||||
with modl.read_child() as geom:
|
||||
|
||||
next_header_modl = geom.peak_next_header()
|
||||
|
||||
if "SEGM" in next_header_modl:
|
||||
with geom.read_child("SEGM") as segm:
|
||||
with geom.read_child() as segm:
|
||||
model.geometry.append(_read_segm(segm, materials_list))
|
||||
|
||||
elif "SWCI" in next_header:
|
||||
prim = CollisionPrimitive()
|
||||
with modl.read_child("SWCI") as swci:
|
||||
prim.shape.value = swci.read_u32()
|
||||
with modl.read_child() as swci:
|
||||
prim.shape = CollisionPrimitiveShape(swci.read_u32())
|
||||
prim.radius = swci.read_f32()
|
||||
prim.height = swci.read_f32()
|
||||
prim.length = swci.read_f32()
|
||||
model.collisionprimitive = prim
|
||||
|
||||
else:
|
||||
with modl.read_child("NULL") as unknown:
|
||||
with modl.read_child() as unknown:
|
||||
pass
|
||||
|
||||
return model
|
||||
@@ -198,18 +209,18 @@ def _read_segm(segm: Reader, materials_list: List[Material]) -> GeometrySegment:
|
||||
next_header = segm.peak_next_header()
|
||||
|
||||
if "MATI" in next_header:
|
||||
with segm.read_child("MATI") as mati:
|
||||
with segm.read_child() as mati:
|
||||
geometry_seg.material_name = materials_list[mati.read_u32()].name
|
||||
|
||||
elif "POSL" in next_header:
|
||||
with segm.read_child("POSL") as posl:
|
||||
with segm.read_child() as posl:
|
||||
num_positions = posl.read_u32()
|
||||
|
||||
for _ in range(num_positions):
|
||||
geometry_seg.positions.append(Vector(posl.read_f32(3)))
|
||||
|
||||
elif "NRML" in next_header:
|
||||
with segm.read_child("NRML") as nrml:
|
||||
with segm.read_child() as nrml:
|
||||
num_normals = nrml.read_u32()
|
||||
|
||||
for _ in range(num_positions):
|
||||
@@ -218,21 +229,21 @@ def _read_segm(segm: Reader, materials_list: List[Material]) -> GeometrySegment:
|
||||
elif "CLRL" in next_header:
|
||||
geometry_seg.colors = []
|
||||
|
||||
with segm.read_child("CLRL") as clrl:
|
||||
with segm.read_child() as clrl:
|
||||
num_colors = clrl.read_u32()
|
||||
|
||||
for _ in range(num_colors):
|
||||
geometry_seg.colors += unpack_color(clrl.read_u32())
|
||||
|
||||
elif "UV0L" in next_header:
|
||||
with segm.read_child("UV0L") as uv0l:
|
||||
with segm.read_child() as uv0l:
|
||||
num_texcoords = uv0l.read_u32()
|
||||
|
||||
for _ in range(num_texcoords):
|
||||
geometry_seg.texcoords.append(Vector(uv0l.read_f32(2)))
|
||||
|
||||
elif "NDXL" in next_header:
|
||||
with segm.read_child("NDXL") as ndxl:
|
||||
with segm.read_child() as ndxl:
|
||||
num_polygons = ndxl.read_u32()
|
||||
|
||||
for _ in range(num_polygons):
|
||||
@@ -240,23 +251,24 @@ def _read_segm(segm: Reader, materials_list: List[Material]) -> GeometrySegment:
|
||||
geometry_seg.polygons.append(polygon)
|
||||
|
||||
elif "NDXT" in next_header:
|
||||
with segm.read_child("NDXT") as ndxt:
|
||||
with segm.read_child() as ndxt:
|
||||
num_tris = ndxt.read_u32()
|
||||
|
||||
for _ in range(num_tris):
|
||||
geometry_seg.triangles.append(ndxt.read_u16(3))
|
||||
|
||||
elif "STRP" in next_header:
|
||||
with segm.read_child("STRP") as strp:
|
||||
with segm.read_child() as strp:
|
||||
pass
|
||||
|
||||
if segm.read_u16 != 0: #trailing 0 bug https://schlechtwetterfront.github.io/ze_filetypes/msh.html#STRP
|
||||
segm.skip_bytes(-2)
|
||||
|
||||
else:
|
||||
with segm.read_child("NULL") as unknown:
|
||||
with segm.read_child() as unknown:
|
||||
pass
|
||||
|
||||
return geometry_seg
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user