Results 1 to 10 of 22

Thread: Periphery Online / MMORTS

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #9
    The animation is too deeply integrated with the game engine. The code is written for internal useage only, it contains many strange and specific structures and names, it will not be understandable to the general public without detailed comments.

    Right now It's too hard and not realistic to quickly make a simple animation example without the game engine itself. Sorry.


    If anyone is interested, here is the Python code I use to export an animation model from Blender to my own binary format:
    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' )
    Last edited by rts111; 11-12-2021 at 03:44 PM.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •