def __init__(self, key=None): RCOL.__init__(self, key) self.version = 0 self.indices = [] self.vertices = [] self.shader = None self.material = MaterialBlock() self.merge_group = 0 self.skin_controller = ExternalResource( ResourceKey(BodySkinController.ID)) self.sort_order = 0 self.vertex_format = self.VertexFormat() self.bones = []
def read_rcol(self, stream, rcol): s = StreamReader(stream) self.read_tag(stream) self.version = s.u32() tgi = TGIList() tgi.begin_read(stream) self.shader = s.u32() if self.shader: end_material = s.u32() + stream.tell() self.material = MaterialBlock() self.material.read(stream, tgi) assert stream.tell() == end_material self.merge_group = s.u32() self.sort_order = s.u32() cVertices = s.u32() self.vertex_format.read(stream) for vertex_index in range(cVertices): vertex = Vertex() for declaration in self.vertex_format.declarations: if declaration.usage == self.VertexFormat.Declaration.USAGE.POSITION: vertex.position = [s.f32(), s.f32(), s.f32()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.NORMAL: vertex.normal = [s.f32(), s.f32(), s.f32()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.UV: uv = [s.f32(), s.f32()] if vertex.uv == None: vertex.uv = [] vertex.uv.append(uv) elif declaration.usage == self.VertexFormat.Declaration.USAGE.BLEND_INDEX: vertex.blend_indices = [s.i8(), s.i8(), s.i8(), s.i8()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.BLEND_WEIGHT: vertex.blend_weights = [s.f32(), s.f32(), s.f32(), s.f32()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.TANGENT: vertex.tangent = [s.f32(), s.f32(), s.f32()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.COLOUR: vertex.colour = [s.u8(), s.u8(), s.u8(), s.u8()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.ID: vertex.id = s.u32() self.vertices.append(vertex) assert s.u32() == 1 bytes_per_index = s.u8() assert bytes_per_index == 2 self.indices = [[s.u16() for i in range(3)] for i in range(int(s.u32() / 3))] self.skin_controller = tgi.get_resource(s.u32()) self.bones = [s.u32() for i in range(s.u32())] tgi.end_read(stream)
def __init__(self, key=None): RCOL.__init__(self, key) self.version = 0 self.indices = [] self.vertices = [] self.shader = None self.material = MaterialBlock() self.merge_group = 0 self.skin_controller = ExternalResource(ResourceKey(BodySkinController.ID)) self.sort_order = 0 self.vertex_format = self.VertexFormat() self.bones = []
class BodyGeometry(RCOL, Mesh): TAG = 'GEOM' ID = 0x015A1849 BLOCK_ID = 0x00000000 class VertexFormat(Serializable): def __init__(self, stream=None): self.declarations = [] Serializable.__init__(self, stream) def read(self, stream, resource=None): s = StreamReader(stream) self.declarations = [self.Declaration(stream) for i in range(s.i32())] def write(self, stream, resource=None): s = StreamWriter(stream) s.i32(len(self.declarations)) for declaration in self.declarations: declaration.write_rcol(stream) def from_vertex(self, vertex): self.declarations = [] if vertex.position: self.declarations.append( self.Declaration(self.Declaration.USAGE.POSITION, self.Declaration.FORMAT.FLOAT, 12)) if vertex.normal: self.declarations.append( self.Declaration(self.Declaration.USAGE.NORMAL, self.Declaration.FORMAT.FLOAT, 12)) if vertex.uv: for uv in vertex.uv: self.declarations.append( self.Declaration(self.Declaration.USAGE.UV, self.Declaration.FORMAT.FLOAT, 8)) if vertex.blend_indices: self.declarations.append( self.Declaration(self.Declaration.USAGE.BLEND_INDEX, self.Declaration.FORMAT.BYTE, 4)) if vertex.blend_weights: self.declarations.append( self.Declaration(self.Declaration.USAGE.BLEND_WEIGHT, self.Declaration.FORMAT.FLOAT, 16)) if vertex.tangents: self.declarations.append( self.Declaration(self.Declaration.USAGE.TANGENT, self.Declaration.FORMAT.FLOAT, 12)) if vertex.colour: self.declarations.append( self.Declaration(self.Declaration.USAGE.COLOUR, self.Declaration.FORMAT.BYTE, 4)) if vertex.id: self.declarations.append( self.Declaration(self.Declaration.USAGE.ID, self.Declaration.FORMAT.UINT, 4)) class Declaration(Serializable): class USAGE: POSITION = 0x00000001 NORMAL = 0x00000002 UV = 0x00000003 BLEND_INDEX = 0x00000004 BLEND_WEIGHT = 0x00000005 TANGENT = 0x00000006 COLOUR = 0x00000007 ID = 0x0000000A class FORMAT: FLOAT = 0x00000001 BYTE = 0x00000002 ARGB = 0x00000003 UINT = 0x00000004 def __init__(self, stream=None, usage=0, format=0, size=0): self.usage = usage self.format = format self.size = size Serializable.__init__(self, stream) def read(self, stream, resource=None): s = StreamReader(stream) self.usage = s.u32() self.type = s.u32() self.size = s.u8() def write(self, stream, resource=None): s = StreamWriter(stream) s.u32(self.usage) s.u32(self.type) s.u8(self.size) def __init__(self, key=None): RCOL.__init__(self, key) self.version = 0 self.indices = [] self.vertices = [] self.shader = None self.material = MaterialBlock() self.merge_group = 0 self.skin_controller = ExternalResource(ResourceKey(BodySkinController.ID)) self.sort_order = 0 self.vertex_format = self.VertexFormat() self.bones = [] def min_vertex_id(self): if not any(self.vertices) or not any(filter(lambda f: f.usage == BodyGeometry.VertexFormat.Declaration.USAGE.ID, self.vertex_format.declarations)): return 0 return min((vertex.id for vertex in self.vertices if vertex.id != None)) def read_rcol(self, stream, rcol): s = StreamReader(stream) self.read_tag(stream) self.version = s.u32() tgi = TGIList() tgi.begin_read(stream) self.shader = s.u32() if self.shader: end_material = s.u32() + stream.tell() self.material = MaterialBlock() self.material.read(stream, tgi) assert stream.tell() == end_material self.merge_group = s.u32() self.sort_order = s.u32() cVertices = s.u32() self.vertex_format.read(stream) for vertex_index in range(cVertices): vertex = Vertex() for declaration in self.vertex_format.declarations: if declaration.usage == self.VertexFormat.Declaration.USAGE.POSITION: vertex.position = [s.f32(), s.f32(), s.f32()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.NORMAL: vertex.normal = [s.f32(), s.f32(), s.f32()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.UV: uv = [s.f32(), s.f32()] if vertex.uv == None: vertex.uv = [] vertex.uv.append(uv) elif declaration.usage == self.VertexFormat.Declaration.USAGE.BLEND_INDEX: vertex.blend_indices = [s.i8(), s.i8(), s.i8(), s.i8()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.BLEND_WEIGHT: vertex.blend_weights = [s.f32(), s.f32(), s.f32(), s.f32()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.TANGENT: vertex.tangent = [s.f32(), s.f32(), s.f32()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.COLOUR: vertex.colour = [s.u8(), s.u8(), s.u8(), s.u8()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.ID: vertex.id = s.u32() self.vertices.append(vertex) assert s.u32() == 1 bytes_per_index = s.u8() assert bytes_per_index == 2 self.indices = [[s.u16() for i in range(3)] for i in range(int(s.u32() / 3))] self.skin_controller = tgi.get_resource(s.u32()) self.bones = [s.u32() for i in range(s.u32())] tgi.end_read(stream) def write_rcol(self, stream, rcol): s = StreamWriter(stream) self.write_tag(stream) s.u32(self.version) tgi = TGIList(32, 'TGI') tgi.begin_write(stream) s.hash(self.shader) if self.shader: self.material.write(stream, tgi) s.u32(self.merge_group) s.u32(self.sort_order) s.u32(len(self.vertices)) self.vertex_format.from_vertex(self.vertices[0]) self.vertex_format.write(stream) for vertex in self.vertices: uv_index = 0 for declaration in self.vertex_format.declarations: if declaration.usage == self.VertexFormat.Declaration.USAGE.POSITION: for i in range(3): s.f32(vertex.position) elif declaration.usage == self.VertexFormat.Declaration.USAGE.NORMAL: for i in range(3): s.f32(vertex.normal) elif declaration.usage == self.VertexFormat.Declaration.USAGE.UV: for i in range(2): s.f32(vertex.uv[uv_index]) uv_index += 1 elif declaration.usage == self.VertexFormat.Declaration.USAGE.BLEND_INDEX: for i in range(4): s.i8(vertex.blend_indices) elif declaration.usage == self.VertexFormat.Declaration.USAGE.BLEND_WEIGHT: for i in range(4): s.f32(vertex.blend_weights) elif declaration.usage == self.VertexFormat.Declaration.USAGE.TANGENT: for i in range(3): s.f32(vertex.tangents) elif declaration.usage == self.VertexFormat.Declaration.USAGE.COLOUR: for i in range(4): s.i8(vertex.colour) elif declaration.usage == self.VertexFormat.Declaration.USAGE.ID: s.u32(vertex.id) s.u32(tgi.get_resource_index(self.skin_controller)) s.u32(len(self.bones)) for bone in self.bones: s.u32(bone) def get_vertices(self): return self.vertices def get_triangles(self): return self.indices def __str__(self): return "%s : Vertices:(%i) Faces:(%i)" % (PackedResource.__str__(self), len(self.vertices), len(self.indices))
class BodyGeometry(RCOL, Mesh): TAG = 'GEOM' ID = 0x015A1849 BLOCK_ID = 0x00000000 class VertexFormat(Serializable): def __init__(self, stream=None): self.declarations = [] Serializable.__init__(self, stream) def read(self, stream, resource=None): s = StreamReader(stream) self.declarations = [ self.Declaration(stream) for i in range(s.i32()) ] def write(self, stream, resource=None): s = StreamWriter(stream) s.i32(len(self.declarations)) for declaration in self.declarations: declaration.write_rcol(stream) def from_vertex(self, vertex): self.declarations = [] if vertex.position: self.declarations.append( self.Declaration(self.Declaration.USAGE.POSITION, self.Declaration.FORMAT.FLOAT, 12)) if vertex.normal: self.declarations.append( self.Declaration(self.Declaration.USAGE.NORMAL, self.Declaration.FORMAT.FLOAT, 12)) if vertex.uv: for uv in vertex.uv: self.declarations.append( self.Declaration(self.Declaration.USAGE.UV, self.Declaration.FORMAT.FLOAT, 8)) if vertex.blend_indices: self.declarations.append( self.Declaration(self.Declaration.USAGE.BLEND_INDEX, self.Declaration.FORMAT.BYTE, 4)) if vertex.blend_weights: self.declarations.append( self.Declaration(self.Declaration.USAGE.BLEND_WEIGHT, self.Declaration.FORMAT.FLOAT, 16)) if vertex.tangents: self.declarations.append( self.Declaration(self.Declaration.USAGE.TANGENT, self.Declaration.FORMAT.FLOAT, 12)) if vertex.colour: self.declarations.append( self.Declaration(self.Declaration.USAGE.COLOUR, self.Declaration.FORMAT.BYTE, 4)) if vertex.id: self.declarations.append( self.Declaration(self.Declaration.USAGE.ID, self.Declaration.FORMAT.UINT, 4)) class Declaration(Serializable): class USAGE: POSITION = 0x00000001 NORMAL = 0x00000002 UV = 0x00000003 BLEND_INDEX = 0x00000004 BLEND_WEIGHT = 0x00000005 TANGENT = 0x00000006 COLOUR = 0x00000007 ID = 0x0000000A class FORMAT: FLOAT = 0x00000001 BYTE = 0x00000002 ARGB = 0x00000003 UINT = 0x00000004 def __init__(self, stream=None, usage=0, format=0, size=0): self.usage = usage self.format = format self.size = size Serializable.__init__(self, stream) def read(self, stream, resource=None): s = StreamReader(stream) self.usage = s.u32() self.type = s.u32() self.size = s.u8() def write(self, stream, resource=None): s = StreamWriter(stream) s.u32(self.usage) s.u32(self.type) s.u8(self.size) def __init__(self, key=None): RCOL.__init__(self, key) self.version = 0 self.indices = [] self.vertices = [] self.shader = None self.material = MaterialBlock() self.merge_group = 0 self.skin_controller = ExternalResource( ResourceKey(BodySkinController.ID)) self.sort_order = 0 self.vertex_format = self.VertexFormat() self.bones = [] def min_vertex_id(self): if not any(self.vertices) or not any( filter( lambda f: f.usage == BodyGeometry.VertexFormat.Declaration. USAGE.ID, self.vertex_format.declarations)): return 0 return min( (vertex.id for vertex in self.vertices if vertex.id != None)) def read_rcol(self, stream, rcol): s = StreamReader(stream) self.read_tag(stream) self.version = s.u32() tgi = TGIList() tgi.begin_read(stream) self.shader = s.u32() if self.shader: end_material = s.u32() + stream.tell() self.material = MaterialBlock() self.material.read(stream, tgi) assert stream.tell() == end_material self.merge_group = s.u32() self.sort_order = s.u32() cVertices = s.u32() self.vertex_format.read(stream) for vertex_index in range(cVertices): vertex = Vertex() for declaration in self.vertex_format.declarations: if declaration.usage == self.VertexFormat.Declaration.USAGE.POSITION: vertex.position = [s.f32(), s.f32(), s.f32()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.NORMAL: vertex.normal = [s.f32(), s.f32(), s.f32()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.UV: uv = [s.f32(), s.f32()] if vertex.uv == None: vertex.uv = [] vertex.uv.append(uv) elif declaration.usage == self.VertexFormat.Declaration.USAGE.BLEND_INDEX: vertex.blend_indices = [s.i8(), s.i8(), s.i8(), s.i8()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.BLEND_WEIGHT: vertex.blend_weights = [s.f32(), s.f32(), s.f32(), s.f32()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.TANGENT: vertex.tangent = [s.f32(), s.f32(), s.f32()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.COLOUR: vertex.colour = [s.u8(), s.u8(), s.u8(), s.u8()] elif declaration.usage == self.VertexFormat.Declaration.USAGE.ID: vertex.id = s.u32() self.vertices.append(vertex) assert s.u32() == 1 bytes_per_index = s.u8() assert bytes_per_index == 2 self.indices = [[s.u16() for i in range(3)] for i in range(int(s.u32() / 3))] self.skin_controller = tgi.get_resource(s.u32()) self.bones = [s.u32() for i in range(s.u32())] tgi.end_read(stream) def write_rcol(self, stream, rcol): s = StreamWriter(stream) self.write_tag(stream) s.u32(self.version) tgi = TGIList(32, 'TGI') tgi.begin_write(stream) s.hash(self.shader) if self.shader: self.material.write(stream, tgi) s.u32(self.merge_group) s.u32(self.sort_order) s.u32(len(self.vertices)) self.vertex_format.from_vertex(self.vertices[0]) self.vertex_format.write(stream) for vertex in self.vertices: uv_index = 0 for declaration in self.vertex_format.declarations: if declaration.usage == self.VertexFormat.Declaration.USAGE.POSITION: for i in range(3): s.f32(vertex.position) elif declaration.usage == self.VertexFormat.Declaration.USAGE.NORMAL: for i in range(3): s.f32(vertex.normal) elif declaration.usage == self.VertexFormat.Declaration.USAGE.UV: for i in range(2): s.f32(vertex.uv[uv_index]) uv_index += 1 elif declaration.usage == self.VertexFormat.Declaration.USAGE.BLEND_INDEX: for i in range(4): s.i8(vertex.blend_indices) elif declaration.usage == self.VertexFormat.Declaration.USAGE.BLEND_WEIGHT: for i in range(4): s.f32(vertex.blend_weights) elif declaration.usage == self.VertexFormat.Declaration.USAGE.TANGENT: for i in range(3): s.f32(vertex.tangents) elif declaration.usage == self.VertexFormat.Declaration.USAGE.COLOUR: for i in range(4): s.i8(vertex.colour) elif declaration.usage == self.VertexFormat.Declaration.USAGE.ID: s.u32(vertex.id) s.u32(tgi.get_resource_index(self.skin_controller)) s.u32(len(self.bones)) for bone in self.bones: s.u32(bone) def get_vertices(self): return self.vertices def get_triangles(self): return self.indices def __str__(self): return "%s : Vertices:(%i) Faces:(%i)" % (PackedResource.__str__(self), len(self.vertices), len(self.indices))