from re import match as regexp from enum import Enum from panda3d.core import Vec3 class MapFace: def __init__(self): self.v1 = Vec3() self.v2 = Vec3() self.v3 = Vec3() self.tex = '' self.offset = Vec3() self.scale = Vec3() self.angle = 0.0 self.normal = Vec3() class MapBrush: def __init__(self): self.faces = [] class MapEntity: def __init__(self): self.classname = '' self.attributes = {} self.brushes = [] class MapFile: def __init__(self, filepath, entities): self.filepath = filepath self.entities = entities def entity_count(self): return len(self.entities) def brush_count(self): total = 0 for ent in self.entities: total += len(ent.brushes) return total def face_count(self): total = 0 for ent in self.entities: for brush in ent.brushes: total += len(brush.faces) return total class MapStack(Enum): TOP = 0 ENTITY = 1 BRUSH = 2 def parse_map_file(filepath): entities = [] with open(filepath, 'r') as mapfile: current_stack = MapStack.TOP current_entity = None current_brush = None for mapline in mapfile: if mapline[:2] == '//': continue if current_stack == MapStack.TOP and mapline[:1] == '{': current_stack = MapStack.ENTITY current_entity = MapEntity() entities.append(current_entity) elif current_stack == MapStack.ENTITY and mapline[:1] == '}': current_stack = MapStack.TOP current_entity = None elif current_stack == MapStack.ENTITY and mapline[:1] == '{': current_stack = MapStack.BRUSH current_brush = MapBrush() current_entity.brushes.append(current_brush) elif current_stack == MapStack.BRUSH and mapline[:1] == '}': current_stack = MapStack.ENTITY current_brush = None elif current_stack == MapStack.ENTITY and mapline[:1] == '"': result = regexp('^"(.+)" "(.+)"$', mapline) current_entity.attributes[result.group(1)] = result.group(2) elif current_stack == MapStack.BRUSH and mapline[:1] == '(': result = regexp("^(\\(.+\\)) (.+)", mapline) coordinates = result.group(1) texture = result.group(2).split(' ') as_num = lambda v: float(v) verts = regexp("^\\( (.+?) \\) \\( (.+?) \\) \\( (.+?) \\)$", coordinates) verts1 = map(as_num, verts.group(1).split(' ')) verts2 = map(as_num, verts.group(2).split(' ')) verts3 = map(as_num, verts.group(3).split(' ')) current_face = MapFace() current_face.v1 = Vec3(tuple(verts1)) current_face.v2 = Vec3(tuple(verts2)) current_face.v3 = Vec3(tuple(verts3)) current_face.tex = texture[0] current_face.offset = Vec3(float(texture[1]), float(texture[2]), 0) current_face.angle = float(texture[3]) current_face.scale = Vec3(float(texture[4]), float(texture[5]), 0) current_brush.faces.append(current_face) edge_a = current_face.v2 - current_face.v1 edge_b = current_face.v3 - current_face.v1 current_face.normal = edge_b.cross(edge_a).normalized() return MapFile(filepath, entities) ''' mapfile = parse_map_file("C:\\Users\\Bryan\\Documents\\MBH\\assets\\meshes\\maps\\test.map") print(mapfile.entity_count()) print(mapfile.brush_count()) print(mapfile.face_count()) '''