骑砍战团MOD开发(52)-使用BrfExporter&Blender制作BRF文件
一.Blender模型导出为BRF文件
(图片来源网络,侵删)
import bpy import struct class BrfFile: def __init__(self): self.meshes = [] self.bodies = [] class Mesh: def __init__(self): self.name = '' self.material_name = '' self.vertices = [] self.morph_keys = [] self.vertices_fvf = [] self.faces = [] class Vertex: def __init__(self): self.x = 0.000 self.y = 0.000 self.z = 0.000 class VertexFvf: def __init__(self): self.vertex_index = 0 self.vertex_color = -1 self.normal_x = 0.000 self.normal_y = 0.000 self.normal_z = 0.000 self.uv_x = 0.000 self.uv_y = 0.000 class Face: def __init__(self): self.vertex_fvf_indices = [] def write_brf_file(brf_file, f): #write meshes f.write(struct.pack('i', len('mesh'))) f.write(b'mesh') f.write(struct.pack('i', len(brf_file.meshes))) for mesh in brf_file.meshes: write_mesh(mesh, f) f.write(struct.pack('i', len('end'))) f.write(b'end') def write_mesh(mesh, f): f.write(struct.pack('i', len(mesh.name))) f.write(mesh.name.encode()) f.write(struct.pack('i', 0)) f.write(struct.pack('i', len(mesh.material_name))) f.write(mesh.material_name.encode()) #write vertices f.write(struct.pack('i', len(mesh.vertices))) for vertex in mesh.vertices: f.write(struct.pack('f', vertex.x)) f.write(struct.pack('f', vertex.y)) f.write(struct.pack('f', vertex.z)) #write morph keys f.write(struct.pack('i', 0)) f.write(struct.pack('i', 0)) #write vertices_fvf f.write(struct.pack('i', len(mesh.vertices_fvf))) for vertex_fvf in mesh.vertices_fvf: f.write(struct.pack('i', vertex_fvf.vertex_index)) f.write(struct.pack('i', vertex_fvf.vertex_color)) f.write(struct.pack('f', vertex_fvf.normal_x)) f.write(struct.pack('f', vertex_fvf.normal_y)) f.write(struct.pack('f', vertex_fvf.normal_z)) f.write(struct.pack('f', vertex_fvf.uv_x)) f.write(struct.pack('f', vertex_fvf.uv_y)) f.write(struct.pack('f', vertex_fvf.uv_x)) f.write(struct.pack('f', vertex_fvf.uv_y)) #write faces f.write(struct.pack('i', len(mesh.faces))) for face in mesh.faces: for vertex_fvf_index in face.vertex_fvf_indices: f.write(struct.pack('i', vertex_fvf_index)) def create_blender_mesh(blender_object_name): blender_mesh = bpy.context.scene.objects[blender_object_name].data blender_uv = blender_mesh.uv_layers.active.data blender_loops = blender_mesh.loops mesh = Mesh() mesh.name = blender_mesh.name mesh.material_name = blender_mesh.materials[0].name #create vetex for blender_vertex in blender_mesh.vertices: vertex = Vertex() vertex.x = round(blender_vertex.co.x, 6) vertex.y = round(blender_vertex.co.y, 6) vertex.z = round(blender_vertex.co.z, 6) mesh.vertices.append(vertex) #create fvf and faces for blender_face in blender_mesh.polygons: vertex_indices = blender_face.vertices loop_indices = blender_face.loop_indices face = Face() for loop_index, vertex_index in enumerate(vertex_indices): vertex_normal_x = round(blender_loops[loop_indices[loop_index]].normal.x, 4) vertex_normal_y = round(blender_loops[loop_indices[loop_index]].normal.y, 4) vertex_normal_z = round(blender_loops[loop_indices[loop_index]].normal.z, 4) vertex_uv_x = round(blender_uv[loop_indices[loop_index]].uv.x, 4) vertex_uv_y = round(blender_uv[loop_indices[loop_index]].uv.y, 4) vertex_fvf = VertexFvf() vertex_fvf.vertex_index = vertex_index vertex_fvf.normal_x = vertex_normal_x vertex_fvf.normal_y = vertex_normal_y vertex_fvf.normal_z = vertex_normal_z vertex_fvf.uv_x = vertex_uv_x vertex_fvf.uv_y = vertex_uv_y vertex_fvf_index = get_vertex_fvf_index(vertex_fvf, mesh.vertices_fvf) if vertex_fvf_index == -1: mesh.vertices_fvf.append(vertex_fvf) vertex_fvf_index = len(mesh.vertices_fvf) - 1 face.vertex_fvf_indices.append(vertex_fvf_index) mesh.faces.append(face) return mesh def get_vertex_fvf_index(vertex_fvf, vertices_fvf): vertex_fvf_index = -1 for index, element in enumerate(vertices_fvf): if element.vertex_index == vertex_fvf.vertex_index and round(element.normal_x, 3) == round(vertex_fvf.normal_x, 3) and round(element.normal_y, 3) == round(vertex_fvf.normal_y, 3) and round(element.normal_z, 3) == round(vertex_fvf.normal_z, 3) and round(element.uv_x, 3) == round(vertex_fvf.uv_x, 3) and round(element.uv_y, 3) == round(vertex_fvf.uv_y, 3): vertex_fvf_index = index break return vertex_fvf_index brf_export_path = 'D:/work/Tool/MB_Warband/BrfExporter/building.brf' brf_file = BrfFile() mesh = create_blender_mesh('89_hushi_tank_cheti') brf_file.meshes.append(mesh) print('vertex count: ' + str(len(brf_file.meshes[0].vertices))) print('vertex fvf count: ' + str(len(brf_file.meshes[0].vertices_fvf))) print('face count: ' + str(len(brf_file.meshes[0].faces))) with open(brf_export_path, 'wb') as f: write_brf_file(brf_file, f)
二.Blender顶点动画导出为BRF文件
import bpy import struct class BrfFile: def __init__(self): self.meshes = [] self.bodies = [] class Mesh: def __init__(self): self.name = '' self.material_name = '' self.vertices = [] self.morph_keys = [] self.vertices_fvf = [] self.faces = [] class Vertex: def __init__(self): self.x = 0.000 self.y = 0.000 self.z = 0.000 class MorphKey: def __init__(self): self.morph_time = 0 self.vertices = [] self.vertices_fvf = [] class VertexFvf: def __init__(self): self.vertex_index = 0 self.vertex_color = -1 self.normal_x = 0.000 self.normal_y = 0.000 self.normal_z = 0.000 self.uv_x = 0.000 self.uv_y = 0.000 class Face: def __init__(self): self.vertex_fvf_indices = [] def write_brf_file(brf_file, f): #write meshes f.write(struct.pack('i', len('mesh'))) f.write(b'mesh') f.write(struct.pack('i', len(brf_file.meshes))) for mesh in brf_file.meshes: write_mesh(mesh, f) f.write(struct.pack('i', len('end'))) f.write(b'end') def write_mesh(mesh, f): f.write(struct.pack('i', len(mesh.name))) f.write(mesh.name.encode()) f.write(struct.pack('i', 0)) f.write(struct.pack('i', len(mesh.material_name))) f.write(mesh.material_name.encode()) #write vertices f.write(struct.pack('i', len(mesh.vertices))) for vertex in mesh.vertices: f.write(struct.pack('f', vertex.x)) f.write(struct.pack('f', vertex.y)) f.write(struct.pack('f', vertex.z)) #non rigged mesh f.write(struct.pack('i', 0)) #write morph keys f.write(struct.pack('i', len(mesh.morph_keys))) for morph_key in mesh.morph_keys: write_morph_key(morph_key, f) #write vertices_fvf f.write(struct.pack('i', len(mesh.vertices_fvf))) for vertex_fvf in mesh.vertices_fvf: f.write(struct.pack('i', vertex_fvf.vertex_index)) f.write(struct.pack('i', vertex_fvf.vertex_color)) f.write(struct.pack('f', vertex_fvf.normal_x)) f.write(struct.pack('f', vertex_fvf.normal_y)) f.write(struct.pack('f', vertex_fvf.normal_z)) f.write(struct.pack('f', vertex_fvf.uv_x)) f.write(struct.pack('f', vertex_fvf.uv_y)) f.write(struct.pack('f', vertex_fvf.uv_x)) f.write(struct.pack('f', vertex_fvf.uv_y)) #write faces f.write(struct.pack('i', len(mesh.faces))) for face in mesh.faces: for vertex_fvf_index in face.vertex_fvf_indices: f.write(struct.pack('i', vertex_fvf_index)) def write_morph_key(morph_key, f): f.write(struct.pack('i', morph_key.morph_time)) #write vertices f.write(struct.pack('i', len(morph_key.vertices))) for vertex in morph_key.vertices: f.write(struct.pack('f', vertex.x)) f.write(struct.pack('f', vertex.y)) f.write(struct.pack('f', vertex.z)) #write vertices_fvf f.write(struct.pack('i', len(morph_key.vertices_fvf))) for vertex_fvf in morph_key.vertices_fvf: f.write(struct.pack('f', vertex_fvf.normal_x)) f.write(struct.pack('f', vertex_fvf.normal_y)) f.write(struct.pack('f', vertex_fvf.normal_z)) def create_blender_mesh(blender_object_name): blender_mesh = bpy.context.scene.objects[blender_object_name].data blender_uv = blender_mesh.uv_layers.active.data blender_loops = blender_mesh.loops mesh = Mesh() mesh.name = blender_mesh.name mesh.material_name = blender_mesh.materials[0].name #create vetex for blender_vertex in blender_mesh.vertices: vertex = Vertex() vertex.x = round(blender_vertex.co.x, 6) vertex.y = round(blender_vertex.co.y, 6) vertex.z = round(blender_vertex.co.z, 6) mesh.vertices.append(vertex) #create fvf and faces for blender_face in blender_mesh.polygons: vertex_indices = blender_face.vertices loop_indices = blender_face.loop_indices face = Face() for loop_index, vertex_index in enumerate(vertex_indices): vertex_normal_x = round(blender_loops[loop_indices[loop_index]].normal.x, 3) vertex_normal_y = round(blender_loops[loop_indices[loop_index]].normal.y, 3) vertex_normal_z = round(blender_loops[loop_indices[loop_index]].normal.z, 3) vertex_uv_x = round(blender_uv[loop_indices[loop_index]].uv.x, 3) vertex_uv_y = round(blender_uv[loop_indices[loop_index]].uv.y, 3) vertex_fvf = VertexFvf() vertex_fvf.vertex_index = vertex_index vertex_fvf.normal_x = vertex_normal_x vertex_fvf.normal_y = vertex_normal_y vertex_fvf.normal_z = vertex_normal_z vertex_fvf.uv_x = vertex_uv_x vertex_fvf.uv_y = vertex_uv_y vertex_fvf_index = get_vertex_fvf_index(vertex_fvf, mesh.vertices_fvf) if vertex_fvf_index == -1: mesh.vertices_fvf.append(vertex_fvf) vertex_fvf_index = len(mesh.vertices_fvf) - 1 face.vertex_fvf_indices.append(vertex_fvf_index) mesh.faces.append(face) return mesh def add_morph_key_to_blender_mesh(blender_object_name, morph_time, mesh): blender_mesh = bpy.context.scene.objects[blender_object_name].data blender_loops = blender_mesh.loops morph_key = MorphKey() #create vetex for blender_vertex in blender_mesh.vertices: vertex = Vertex() vertex.x = round(blender_vertex.co.x, 6) vertex.y = round(blender_vertex.co.y, 6) vertex.z = round(blender_vertex.co.z, 6) morph_key.vertices.append(vertex) #create fvf normals for i in range(0, len(mesh.vertices_fvf)): fvf = VertexFvf() morph_key.vertices_fvf.append(fvf) for blender_face_index, blender_face in enumerate(blender_mesh.polygons): vertex_indices = blender_face.vertices loop_indices = blender_face.loop_indices for loop_index, vertex_index in enumerate(vertex_indices): vertex_fvf_index = mesh.faces[blender_face_index].vertex_fvf_indices[loop_index] vertex_normal_x = round(blender_loops[loop_indices[loop_index]].normal.x, 3) vertex_normal_y = round(blender_loops[loop_indices[loop_index]].normal.y, 3) vertex_normal_z = round(blender_loops[loop_indices[loop_index]].normal.z, 3) morph_key.vertices_fvf[vertex_fvf_index].normal_x = vertex_normal_x morph_key.vertices_fvf[vertex_fvf_index].normal_y = vertex_normal_y morph_key.vertices_fvf[vertex_fvf_index].normal_z = vertex_normal_z #set morph time morph_key.morph_time = morph_time mesh.morph_keys.append(morph_key) return mesh def get_vertex_fvf_index(vertex_fvf, vertices_fvf): vertex_fvf_index = -1 for index, element in enumerate(vertices_fvf): if element.vertex_index == vertex_fvf.vertex_index and round(element.normal_x, 3) == round(vertex_fvf.normal_x, 3) and round(element.normal_y, 3) == round(vertex_fvf.normal_y, 3) and round(element.normal_z, 3) == round(vertex_fvf.normal_z, 3) and round(element.uv_x, 3) == round(vertex_fvf.uv_x, 3) and round(element.uv_y, 3) == round(vertex_fvf.uv_y, 3): vertex_fvf_index = index break return vertex_fvf_index brf_export_path = 'D:/work/Tool/MB_Warband/BlenderBrfExporter/building.brf' brf_file = BrfFile() mesh = create_blender_mesh('jap_car_wheel_morph_key_base') for morph_key_index in range(0, 12): add_morph_key_to_blender_mesh('jap_car_wheel_morph_key_' + str(morph_key_index + 1), morph_key_index + 1, mesh) brf_file.meshes.append(mesh) print('vertex count: ' + str(len(brf_file.meshes[0].vertices))) print('vertex morph key count: ' + str(len(brf_file.meshes[0].morph_keys))) print('vertex fvf count: ' + str(len(brf_file.meshes[0].vertices_fvf))) print('face count: ' + str(len(brf_file.meshes[0].faces))) with open(brf_export_path, 'wb') as f: write_brf_file(brf_file, f)
三.Blender绑骨模型导出为BRF文件
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。