一.Blender模型导出为BRF文件
import bpy
import structclass 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.000self.y = 0.000self.z = 0.000class VertexFvf:def __init__(self):self.vertex_index = 0self.vertex_color = -1self.normal_x = 0.000self.normal_y = 0.000 self.normal_z = 0.000self.uv_x = 0.000self.uv_y = 0.000class Face:def __init__(self):self.vertex_fvf_indices = []def write_brf_file(brf_file, f):#write meshesf.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 verticesf.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 keysf.write(struct.pack('i', 0))f.write(struct.pack('i', 0))#write vertices_fvff.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 facesf.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].datablender_uv = blender_mesh.uv_layers.active.datablender_loops = blender_mesh.loopsmesh = Mesh()mesh.name = blender_mesh.namemesh.material_name = blender_mesh.materials[0].name#create vetexfor 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 facesfor blender_face in blender_mesh.polygons:vertex_indices = blender_face.verticesloop_indices = blender_face.loop_indicesface = 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_indexvertex_fvf.normal_x = vertex_normal_xvertex_fvf.normal_y = vertex_normal_yvertex_fvf.normal_z = vertex_normal_zvertex_fvf.uv_x = vertex_uv_xvertex_fvf.uv_y = vertex_uv_yvertex_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) - 1face.vertex_fvf_indices.append(vertex_fvf_index) mesh.faces.append(face)return meshdef get_vertex_fvf_index(vertex_fvf, vertices_fvf):vertex_fvf_index = -1for 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 = indexbreakreturn vertex_fvf_indexbrf_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 structclass 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.000self.y = 0.000self.z = 0.000class MorphKey:def __init__(self):self.morph_time = 0self.vertices = []self.vertices_fvf = []class VertexFvf:def __init__(self):self.vertex_index = 0self.vertex_color = -1self.normal_x = 0.000self.normal_y = 0.000 self.normal_z = 0.000self.uv_x = 0.000self.uv_y = 0.000class Face:def __init__(self):self.vertex_fvf_indices = []def write_brf_file(brf_file, f):#write meshesf.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 verticesf.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 meshf.write(struct.pack('i', 0))#write morph keysf.write(struct.pack('i', len(mesh.morph_keys)))for morph_key in mesh.morph_keys:write_morph_key(morph_key, f)#write vertices_fvff.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 facesf.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 verticesf.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_fvff.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].datablender_uv = blender_mesh.uv_layers.active.datablender_loops = blender_mesh.loopsmesh = Mesh()mesh.name = blender_mesh.namemesh.material_name = blender_mesh.materials[0].name#create vetexfor 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 facesfor blender_face in blender_mesh.polygons:vertex_indices = blender_face.verticesloop_indices = blender_face.loop_indicesface = 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_indexvertex_fvf.normal_x = vertex_normal_xvertex_fvf.normal_y = vertex_normal_yvertex_fvf.normal_z = vertex_normal_zvertex_fvf.uv_x = vertex_uv_xvertex_fvf.uv_y = vertex_uv_yvertex_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) - 1face.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].datablender_loops = blender_mesh.loopsmorph_key = MorphKey()#create vetexfor 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 normalsfor 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.verticesloop_indices = blender_face.loop_indicesfor 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_xmorph_key.vertices_fvf[vertex_fvf_index].normal_y = vertex_normal_ymorph_key.vertices_fvf[vertex_fvf_index].normal_z = vertex_normal_z#set morph timemorph_key.morph_time = morph_timemesh.morph_keys.append(morph_key)return meshdef get_vertex_fvf_index(vertex_fvf, vertices_fvf):vertex_fvf_index = -1for 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 = indexbreakreturn vertex_fvf_indexbrf_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文件