Code:
import os
import bpy
import mathutils
from struct import pack
from mathutils import Matrix, Vector, Color
from bpy_extras import io_utils, node_shader_utils
print('*********************************************************')
oo = bpy.context.scene.objects
VV = []
TT = []
NN = []
WW = []
II = []
MM = []
GG = []
BB = []
KK = []
ML = []
MI = []
MB = []
MG = []
arm_name = 'Armature'
icon_a = 8
icon_k = 0
if bpy.data.objects.find(arm_name) != -1:
armature = bpy.data.objects[arm_name]
BB = armature.data.bones[:]
def bone_index( b ):
for i in range(len(BB)):
if b == BB[i]:
return i
return -1
def get_MG( i ):
M = ML[i] @ MB[i] @ MI[i]
if KK[i] < 0:
return M
else:
return get_MG(KK[i]) @ M
def root_path( _f_name = '' ):
s = os.path.dirname(bpy.data.filepath)
return s + '\\' + _f_name
def name_compat(name):
if name is None:
return 'None'
else:
return name.replace(' ', '_')
def mesh_triangulate(me):
import bmesh
bm = bmesh.new()
bm.from_mesh(me)
bmesh.ops.triangulate( bm , faces = bm.faces )
bm.to_mesh( me )
bm.free()
def aa_add(aa,a):
for i in range(len(aa)):
if a == aa[i]:
return i
aa.append(a)
return len(aa)-1
def get_mat_tex(m):
mat_wrap = node_shader_utils.PrincipledBSDFWrapper(m)
tex_wrap = getattr( mat_wrap , "base_color_texture" , None )
if tex_wrap:
image = tex_wrap.image
if image:
d0 = os.path.dirname(bpy.data.filepath)
d1 = os.path.normpath( d0 + image.filepath )
d2 = os.path.relpath( d1 , start = d0 )
return d2
return 'none'
def get_w2(v):
gg = v.groups[:]
if len(gg) == 0:
return ( 0 , 1.0 ) , ( 0 , 0.0 )
if len(gg) == 1:
return ( gg[0].group , 1.0 ) , ( 0 , 0.0 )
if len(gg) > 2:
gg.sort( key = lambda g: -g.weight )
w1 = gg[0].weight
w2 = gg[1].weight
ww = w1 + w2
return ( gg[0].group , w1/ww ) , ( gg[1].group , w2/ww )
def read_mesh(o):
mesh_triangulate(o)
o.calc_normals_split()
vv_count = len(VV)
LL = o.loops
tt = o.uv_layers.active.data[:]
def loop_to_ii(L):
return LL[L].vertex_index + vv_count , aa_add( TT , tt[L].uv ) , aa_add( NN , LL[L].normal )
gg = [ [[],m,0] for m in o.materials ]
for f in o.polygons:
f_ii = tuple( loop_to_ii(L) for L in f.loop_indices )
gg[f.material_index][0].append( f_ii )
VV.extend( o.vertices[:] )
for g in gg:
if len(g[0]) > 0:
g[2] = aa_add( MM , g[1] )
GG.append(g)
def mesh_to_aa():
for o in oo:
if o.type == "MESH":
read_mesh(o.to_mesh())
for i in range(len(MM)):
tex_name = get_mat_tex(MM[i])
tex_index = aa_add( II , tex_name )
MM[i] = MM[i] , tex_index
def write_arm( fw ):
def write_m( M ):
t = M.to_translation()
e = M.to_euler()
fw( pack('3f', M[0][3] , M[1][3] , M[2][3] ) )
fw( pack('3f', e[0] , e[1] , e[2] ) )
# icon pos
fw( pack( '2B' , icon_a , icon_k ) )
# BB
fw( pack( 'i' , len(BB) ) )
for b in BB:
i = bone_index( b.parent )
KK.append(i)
fw( pack('i', i ) )
# t_pose
for i in range(len(BB)):
b = BB[i]
M = b.matrix_local.copy()
ML.append( M.copy() )
MI.append( M.inverted().copy() )
MB.append( None )
write_m(M)
# t_anim
fw( pack( 'i' , len(bpy.data.actions)-1 ) )
for i in range( 1 , len(bpy.data.actions) ):
a = bpy.data.actions[i]
cc = a.fcurves
a_len = len( cc[0].keyframe_points )
fw( pack('B',len(a.name)) )
fw( bytes( a.name , 'ansi' ) )
fw( pack( 'i' , a_len ) )
for j in range( a_len ):
for k in range(len(BB)):
b = BB[k]
path_p = 'pose.bones["' + b.name + '"].location'
path_q = 'pose.bones["' + b.name + '"].rotation_quaternion'
pp = []
qq = []
for c in cc:
if c.data_path == path_p:
pp.append(c)
if c.data_path == path_q:
qq.append(c)
v = [c.keyframe_points[j].co[1] for c in pp]
p = mathutils.Matrix.Translation( ( v[0] , v[1] , v[2] ) )
v = [c.keyframe_points[j].co[1] for c in qq]
q = mathutils.Quaternion( ( v[0] , v[1] , v[2] , v[3] ) )
MB[k] = p @ q.to_matrix().to_4x4()
for k in range(len(BB)):
M = get_MG(k)
write_m(M)
def save_arm( f_name ):
f = open( f_name , 'bw' )
fw = f.write
write_arm( fw )
f.close()
def save_to_b2m( f_name , s_format ):
mesh_to_aa()
f = open(f_name,'bw')
fw = f.write
# format
fw( pack( 'B' , s_format ) )
# images
fw( pack( 'i' , len(II) ) )
for I in II:
fw( pack('B',len(I)) )
fw( bytes( I , 'ansi' ) )
# mat
fw( pack( 'i' , len(MM) ) )
for M in MM:
fw( pack( 'i' , M[1] ) )
s = M[0].name
fw( pack( 'B' , len(s) ) )
fw( bytes( s , 'ansi' ) )
# VV
fw( pack( 'i' , len(VV) ) )
for v in VV:
fw( pack('3f', v.co[0] , v.co[1] , v.co[2] ) )
# TT
fw( pack( 'i' , len(TT) ) )
for t in TT:
fw( pack('2f', t[0] , t[1] ) )
# NN
fw( pack( 'i' , len(NN) ) )
for n in NN:
fw( pack('3f', n[0] , n[1] , n[2] ) )
# GG
fw( pack( 'i' , len(GG) ) )
for G in GG:
fw( pack( 'i' , G[2] ) )
fw( pack( 'i' , len(G[0]) ) )
for g in G[0]:
#fw( pack( '9i', g[0][0],g[0][1],g[0][2], g[1][0],g[1][1],g[1][2], g[2][0],g[2][1],g[2][2] ) )
fw( pack( '9H', g[0][0],g[0][1],g[0][2], g[1][0],g[1][1],g[1][2], g[2][0],g[2][1],g[2][2] ) )
# animation ...
if s_format < 1:
f.close()
return
# WW
for v in VV:
w = get_w2(v)
fw( pack('<BfBf', w[0][0] , w[0][1] , w[1][0] , w[1][1] ) )
if s_format == 2:
write_arm( fw )
f.close()
save_to_b2m( root_path('m1.b2m') , 2 )
#save_arm( 'm1.arm' )
Bookmarks