一.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文件