Комментарии на скорую руку набросал. В этом скрипте не экспортируется текстура и текстурные координаты, в старой версии оно было, пока еще в эту версию не перекинул
# как это работает:
# надо выделить нужный меш, привязанный к арматуре, состоящий только из треугольников
# поменять имя файла в самом низу и запустить скрипт
# скрипт пройдется по всем кадрам от FrameStart до FrameEnd. В качестве разделителей анимаций используются timeline_markers
import bpy
import struct
import os
import math
import xml.dom.minidom
# возвращает нужную bonegroup
def getbonegroup(bg, obj, arm):
groupname = obj.vertex_groups[bg.group].name
return(arm.pose.bones.find(groupname))
# возвращает финальную матрицу кости
def getmatrix(bone):
return(bone.matrix_channel)
# сохранение матриц всех костей
def SaveBones(arm, f):
f.write(struct.pack('i', len(arm.pose.bones)))
for bone in arm.pose.bones:
matrix = getmatrix(bone)
for matrix_i in matrix:
for matrix_ij in matrix_i:
f.write(struct.pack('f', matrix_ij))
# сохранение вершин
def SaveVertexs(obj, f):
vertcount = len(obj.data.vertices)
f.write(struct.pack("i", vertcount))
# координаты вершин
for vert in obj.data.vertices:
for vertco in vert.co:
f.write(struct.pack("f", vertco))
# нормали вершин
for vert in obj.data.vertices:
for vertnormal in vert.normal:
f.write(struct.pack("f", vertnormal))
# дальше пошли полигоны
polycount = len(obj.data.polygons)
f.write(struct.pack("i", polycount))
# для каждого полигона пишем индексы вершин
for poly in obj.data.polygons:
for vert in poly.vertices:
f.write(struct.pack("i", vert))
# сохраняем веса вершин
for vert in obj.data.vertices:
count = 0
# количество групп костей для вершины
for bonegroup in vert.groups:
if getbonegroup(bonegroup, obj, obj.parent) == -1:
continue
else:
count = count + 1
#f.write(struct.pack('i', len(vert.groups)))
f.write(struct.pack('i', count))
for bonegroup in vert.groups:
if getbonegroup(bonegroup, obj, obj.parent) == -1:
continue
# нужный индекс группы костей
f.write(struct.pack('i', getbonegroup(bonegroup, obj, obj.parent)))
#f.write(struct.pack('i', bonegroup.group))
# далее сохраняем вес каждой кости для вершины поделенный на общий
AllWeight = 0
for bonegroup in vert.groups:
if getbonegroup(bonegroup, obj, obj.parent) == -1:
continue
AllWeight = AllWeight + bonegroup.weight
for bonegroup in vert.groups:
if getbonegroup(bonegroup, obj, obj.parent) == -1:
continue
f.write(struct.pack('f', bonegroup.weight/AllWeight))
# сохраняет меш + скелет + анимацию
def SaveMesh(obj, f):
if obj.parent == None:
return()
print(obj.name)
# сохраняем меш в бинд позе
obj.parent.data.pose_position = 'REST'
SaveVertexs(obj, f)
#Rest Pose
SaveBones(obj.parent, f)
# далее сохраняем анимацию, тупо бегаем по кадрам и сохраняем матрицы костей
# в качестве разделителей анимаций используются timeline_markers, т.к. других способов я не знаю:)
obj.parent.data.pose_position = 'POSE'
frame_start = bpy.data.scenes[0].frame_start
frame_end = bpy.data.scenes[0].frame_end
frame_ind = 0
markers = bpy.context.scene.timeline_markers
animcount = len(markers)
f.write(struct.pack('i', animcount))
for i in range(0, animcount):
f.write(struct.pack('i', len(markers[i].name)))
f.write(bytes(markers[i].name, encoding = 'ascii'))
if i<animcount-1:
framecount = markers[i+1].frame-markers[i].frame
else:
framecount = frame_end-markers[i].frame
f.write(struct.pack('i', framecount))
for frame_ind in range(markers[i].frame, markers[i].frame + framecount):
bpy.data.scenes[0].frame_set(frame_ind)
print(frame_ind)
SaveBones(obj.parent, f)
#SaveVertexs(obj, f)
print("Start")
f = open('d:\PathToExport','wb')
for obj in bpy.data.scenes[0].objects:
if obj.type!='MESH':
continue
if obj.select == False:
continue
SaveMesh(obj, f)
f.flush()
f.close()
print('Done')
#for uv_co in mesh.uv_textures.active.data[face.index].uv:
# uv.append(uv_co[0])
# uv.append(-uv_co[1])
#Текстурные координаты:
#bpy.context.object.active_material.texture_slots[0].texture_coords
#Пути к файлам текстур:
#bpy.data.images["имя текстуры"].filepath |