Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 21, 2017 05:38:49

Povert
Зарегистрирован: 2017-02-19
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Скрипт экспорта *.blend => *.dag для War Thunder CDK

Приветствую форумчан, и прошу помощи с использованием скрипта экспорта файлов из Blender в War Thunder CDK.
Конечно логичнее спрашивать у разработчиков скрипта. Спрашивал, второй месяц нет ответа, а моя тема потихоньку принимает вид блога и собирает просмотры.
Имею очень поверхностное понимание в программировании.
Блендеровские скрипты пишутся на питоне, по этому здесь создаю эту тему.

Суть вороса…

Проект War Thunder CDK заточен под 3DsMax.
В комплекте идет куча плагинов для Максов, разных версий и разрядности.
Как я смог понять. Плагин для Макса невозможно самостоятельно переделать для блендер.
Для этого нужно знать как работает Максов плагин.
Но в War Thunder CDK рядом с папкой набитой Максовыми плагинами для разных вверсий, есть папка blender_plugins.
В папке редмишка

Copy whole this folder to blender (“…\Blender Foundation\Blender\2.71\scripts\addons\io_export_dag” )


1. В параметрах текстуры (custom properties) должен быть указан ее тип (параметр - type, значение из dagorShaders.cfg - “diffuse”, “CUBE environment”, “normalmap” и т.п.
2. В параметрах материала (custom properties) казываются необходимые параметры для его настройки, согласно dagorShaders.cfg


Сам скрипт

 # http://live.warthunder.com/assistance_agreement/ 
bl_info = {"name": "Export to Dagor Engine",
           "description": "Script exports mesh to Dagor Engine",
           "author": "http://live.warthunder.com/assistance_agreement/",
           "version": (1, 0),
           "blender": (2, 68, 0),
           "location": "File > Export",
           "wiki_url": "",
           "tracker_url": "http://live.warthunder.com/assistance_agreement/",
           "category": "Import-Export"}
# Standard library imports
import sys
import os
# Blender imports
import bpy
from bpy_extras.io_utils import ImportHelper
from bpy.props import IntProperty, StringProperty
from bpy.types import AddonPreferences, Operator, Panel
import mathutils, math, struct
from mathutils import *
import subprocess
SUPPORTED_TYPES = ('MESH')#,'CURVE','EMPTY','TEXT','CAMERA','LAMP')
class BLKWriter:
    file = None
    ident = 0
    def getIdent(self):
        s = ""
        for x in range(0, self.ident):
            s += "  "
        return s
    def writeHeader(self):
        self.file.write('HEAD:t="BLK(float)"\n')
        return
    def open( self, filename ):
        self.file = open(filename, "wt")
        self.writeHeader()
        return
    def close( self ):
        self.file.flush()
        self.file.close()
    def beginBlock(self, name):
        self.file.write('\n%s%s{\n' % ( self.getIdent(), name ) )
        self.ident += 1
        return
    def endBlock(self ):
        self.ident -= 1
        if self.ident < 0 : #assert
            self.ident = 0
        self.file.write('%s}\n' % self.getIdent() )
        return
    def writeStr(self, name, str):
        self.file.write('%s%s:t="%s"\n' % ( self.getIdent(), name, str ) )
        return
    def writeInt(self, name, val):
        self.file.write('%s%s:i=%d\n' % ( self.getIdent(), name, val ) )
        return
    def writeFloat(self, name, val):
        self.file.write('%s%s:r=%g\n' % ( self.getIdent(), name, val ) )
        return
    def writeBool(self, name, val):
        self.file.write('%s%s:b=%s\n' % ( self.getIdent(), name, "yes" if val else "no" ) )
        return
    def writeTM(self, name, m):
        self.file.write('%s%s:m=[[%f, %f, %f] [%f, %f, %f] [%f, %f, %f] [%f, %f, %f]]\n' % ( self.getIdent(), name, m[0][0], m[0][1], m[0][2],  m[1][0], m[1][1], m[1][2],   m[2][0], m[2][1], m[2][2],  m[3][0], m[3][1], m[3][2] ) )
        #self.file.write('%s%s:m=[[%f, %f, %f] [%f, %f, %f] [%f, %f, %f] [%f, %f, %f]]\n' % ( self.getIdent(), name, m[0][0], m[0][1], m[0][2],  m[1][0], m[1][1], m[1][2],   m[2][0], m[2][1], m[2][2],  m[0][3], m[1][3], m[2][3] ) )
        #self.file.write('%s%s:m=[[%f, %f, %f] [%f, %f, %f] [%f, %f, %f] [%f, %f, %f]]\n' % ( self.getIdent(), name, m[0][0], m[2][0], m[1][0],  m[0][1], m[2][1], m[1][1],   m[0][2], m[2][2], m[1][2],  m[0][3], m[2][3], m[1][3] ) )
        #self.file.write('%s\n' % m )
        return
class MaterialExp:
    def __init__(self):
        self.index = -1
        self.mat = None
class MeshExp:
    def __init__(self):
        self.vertexes = list()
        self.faces = list()
        self.uv = list()
        self.normals = list()
        self.normals_per_face_ver = list()
        self.normals_ver = list()
        self.normals_faces = list()
    def addNormal( self, normal ):
        for i,n in enumerate(self.normals_ver):
            if n == normal:
                return i
        index = len( self.normals_ver )
        self.normals_ver.append( normal )
        return index
class NodeExp:
    def __init__(self):
        self.name = ""
        self.id = -1
        self.parent_id = -1
        #self.parent = None
        self.child = list()
        self.mesh = None
        self.tm = None
        self.wtm = None
        self.renderable = True
class DagExporter(Operator, ImportHelper):
    bl_idname = "dag.exporter"
    bl_label = "Dagor Engine (.dag)"
    bl_options = {'REGISTER', 'UNDO'}
    file = None
    nodes = None
    last_index = 0
    writer = None
    materials = {}
    def __init__(self):
        self.writer = BLKWriter()
        self.last_index = 0
        self.nodes = list()
        self.materials = {}
    # ImportHelper mixin class uses this
    filename_ext = ".dag"
    filter_glob = StringProperty(default="*.dag", options={'HIDDEN'})
    def createRootNode( self ):
        node = NodeExp()
        node.id = 65535;
        node.parent_id = -1;
        node.tm = Matrix()
        node.tm.identity()
        node.wtm = Matrix()
        node.wtm.identity()
        node.renderable=False
        self.nodes.append( node )    
        return node
    def writeNode(self, node ):
        self.writer.beginBlock("node")
        self.writer.writeStr( "name", node.name )
        self.writer.writeInt( "id", node.id )
        self.writer.writeInt( "parent_id", node.parent_id )
        self.writer.writeBool( "renderable", node.renderable )
        self.writer.writeBool( "castshadow", False )
        self.writer.writeBool( "rcvshadow", False )
        self.writer.writeTM( "tm", node.tm )
        if node.mesh == None:
            self.writer.endBlock()
            return
        self.writer.beginBlock("vert_data")
        for i,v in enumerate( node.mesh.vertexes):
            self.writer.writeStr( "vert", str( '[%d] x:%f y:%f z:%f' % (i, v.x, v.y, v.z ) ) );
        self.writer.endBlock()
        self.writer.beginBlock("face_data")
        for i,f in enumerate(node.mesh.faces):
            self.writer.writeStr( "face", str( '[%d] i1:%d i2:%d i3:%d smgrp:%d mat: %d' % (i, f[ 0 ], f[ 1 ], f[ 2 ], 0, f[ 3 ] ) ) );
        self.writer.endBlock()
        self.writer.beginBlock("normal_vert")
        for i,n in enumerate(node.mesh.normals_ver):
            self.writer.writeStr( "nvert", str( '[%d] x:%f y:%f z:%f' % (i, n[ 0 ], n[ 1 ], n[ 2 ] ) ) );
        self.writer.endBlock()
        self.writer.beginBlock("normal_faces")
        for i,f in enumerate(node.mesh.normals_faces):
            self.writer.writeStr( "nface", str( '[%d] i1:%d i2:%d i3:%d' % (i, f[ 0 ], f[ 1 ], f[ 2 ] ) ) );
        self.writer.endBlock()
        if len(node.mesh.uv) > 0:
            self.writer.beginBlock("uv_data")
            for channel in node.mesh.uv:
                #self.writer.writeStr( str('%s\n' % channel ) );
                self.writer.beginBlock("channel")
                self.writer.beginBlock("uv_vert")
                for i,f in enumerate(channel):
                    self.writer.writeStr( "uv", str( '[%d] x:%f y:%f' % (i, f[0],1.0-f[1] ) ) );
                    #self.writer.writeStr( str('%s\n' % ch ) );
                self.writer.endBlock()
               
                self.writer.endBlock()
            self.writer.endBlock()
        self.writer.endBlock()
        return
    def dumpObjectData( self, obj, node, scene ):
        
        #mesh_calc_normals()
        if obj.type != 'MESH':
            try:
                me = obj.to_mesh(scene, True, "PREVIEW")
            except:
                me = None
                is_tmp_mesh = True
        else:
            me = obj.data
            if not me.tessfaces and me.polygons:
                me.calc_tessface()
            is_tmp_mesh = False
        has_uv = bool(me.tessface_uv_textures)
        has_vcol = bool(me.tessface_vertex_colors)
        if has_uv == False :
            self.file.write("Object hasn't UV mapping\n" )
        # export data
        if me is not None:
            if len( obj.material_slots ) == 0:
                print( "Need assign material to object \"%s\"\n" % obj.name )
                return
            me.calc_normals_split()
            
            materials_indexes = [ list() for p in range( len( obj.material_slots ) )]
            for i,slot in enumerate( obj.material_slots ):
                self.file.write("  Material %s\n" % slot )
                #self.file.write("  Mat %s\n" % slot.material.name )
                if slot.material.name not in self.materials:
                    mat_exp = MaterialExp()
                    mat_exp.index = len(self.materials)
                    mat_exp.mat = slot.material
                    self.materials[ slot.material.name ] = mat_exp
                val = self.materials.get( slot.material.name )
                if val != None:
                    materials_indexes[i] = val.index
                else:
                    materials_indexes[i] = -1
            #print("Mesh object:", me.name)
            self.file.write(str('mesh %s\n' % me) )
            meshExp = MeshExp()
            for v in me.vertices:
                #self.file.write(str('vert %s %s %s\n' % (v.co.x, v.co.y, v.co.z) ) )
                meshExp.vertexes.append( v.co )
                meshExp.normals.append( -v.normal );
            meshExp.uv = [ list() for p in range( len( me.tessface_uv_textures ) )]
            
            for i, f in enumerate( me.tessfaces ):
                #self.file.write(str('vf %s %s %s\n' % (f.vertices[0], f.vertices[1], f.vertices[2] ) ) )
                useSmooth = f.use_smooth
                self.file.write(str('mat %d\n' % f.material_index ) )
                fexp = []
                fexp.append( f.vertices[0] )
                fexp.append( f.vertices[2] )
                fexp.append( f.vertices[1] )
                fexp.append( materials_indexes[ f.material_index ] );
                meshExp.faces.append( fexp )
                norm = []
                if useSmooth:
                    norm.append( -meshExp.normals[ f.vertices[0] ] )
                    norm.append( -meshExp.normals[ f.vertices[2] ] )
                    norm.append( -meshExp.normals[ f.vertices[1] ] )
                else:
                    norm.append( f.normal )
                    norm.append( f.normal )
                    norm.append( f.normal )
                meshExp.normals_per_face_ver.append( norm )
                norm_face_ind = []
                for nv in norm:
                    norm_face_ind.append( meshExp.addNormal( nv ) )
                meshExp.normals_faces.append( norm_face_ind )
                for n, layer in enumerate( me.tessface_uv_textures ):
                    uv = layer.data[i].uv
                    #self.file.write(str('uv_face[%d] (%f,%f), (%f,%f), (%f,%f)\n' % (n, uv[0][0], uv[0][1],uv[1][0], uv[1][0],uv[2][0],uv[2][1]) ) )
                    meshExp.uv[ n ].append( uv[0] )
                    meshExp.uv[ n ].append( uv[2] )
                    meshExp.uv[ n ].append( uv[1] )
                    if len(f.vertices) == 4: # if quad
                        meshExp.uv[ n ].append( uv[2] )
                        meshExp.uv[ n ].append( uv[0] )
                        meshExp.uv[ n ].append( uv[3] )
                self.file.write(str('smth %s\n' % f.use_smooth ) )
                if len(f.vertices) == 4: # if quad
                    self.file.write(str('vf %s %s %s\n' % (f.vertices[2], f.vertices[3], f.vertices[0] ) ) )
                    fexp = []
                    fexp.append( f.vertices[2] )
                    fexp.append( f.vertices[0] )
                    fexp.append( f.vertices[3] )
                    fexp.append( materials_indexes[f.material_index] );
                    meshExp.faces.append( fexp )
                    #self.file.write(str('uv_face (%f,%f), (%f,%f), (%f,%f)\n' % (uv[2][0], uv[2][1],uv[3][0], uv[3][0],uv[0][0],uv[0][1]) ) )
                    norm = []
                    if useSmooth:
                        norm.append( -meshExp.normals[ f.vertices[2] ] )
                        norm.append( -meshExp.normals[ f.vertices[0] ] )
                        norm.append( -meshExp.normals[ f.vertices[3] ] )
                    else:
                        norm.append( f.normal )
                        norm.append( f.normal )
                        norm.append( f.normal )
                    meshExp.normals_per_face_ver.append( norm )
                    norm_face_ind = []
                    for nv in norm:
                        norm_face_ind.append( meshExp.addNormal( nv ) )
                    meshExp.normals_faces.append( norm_face_ind )
            node.mesh = meshExp
        if is_tmp_mesh:
            bpy.data.meshes.remove(me)
        return
    def recursObjects( self, objs, parent, scene):
        objects = (ob for ob in objs if ob.is_visible(scene) and ob.type in SUPPORTED_TYPES)
        for o in objects:
            self.last_index += 1;
            node = NodeExp()
            node.name = o.name
            node.id = self.last_index;
            node.parent_id = parent.id
            mParentInv = parent.wtm.copy()
            mParentInv.invert()
            node.wtm = o.matrix_world;
            node.tm =  mParentInv * node.wtm;
            #--------------------------------------
            if parent.parent_id == -1 :
                tmp_r = node.tm[1].copy()
                node.tm[1] = node.tm[2].copy()
                node.tm[2] = tmp_r.copy()
                node.tm.transpose()
            #self.file.write( str( '(%s) mat: %s\n' % ( node.name, node.tm ) ) )
            #--------------------------------------
            #if o.name == 'gear_c' :
            #    self.file.write( str( 'mat: %s\n' % o.matrix_world ) )
            parent.child.append( node )
            print('Exporting %s, parent%s\n' % ( node.name, parent.name) )
            self.nodes.append( node )
            self.dumpObjectData( o, node, scene )
            self.recursObjects( o.children, node, scene )
        return
    def writeParam(self,params):
        for key in params:
            if key[0] == "_RNA_UI":
                continue
            self.writer.beginBlock( "param")
            self.writer.writeStr( "name", key[0] )            
            self.writer.writeStr( "value", key[1] )
            self.writer.endBlock()
    
    def writeMaterail(self, mat, id):
        self.writer.beginBlock( "material")
        self.writer.writeInt( "id", id )
        self.writer.writeStr( "name", mat.name )
        self.writer.writeStr( "diffuse", str( 'r:%f g:%f b:%f' % (mat.diffuse_color.r, mat.diffuse_color.g, mat.diffuse_color.b)) )
        self.writer.writeStr( "specular", str( 'r:%f g:%f b:%f' % (mat.specular_color.r, mat.specular_color.g, mat.specular_color.b)) )
        for mtex_slot in mat.texture_slots:
            if mtex_slot:
                #self.file.write( "test: %s" % str( mtex_slot.uv_layer ) )
                
                if hasattr(mtex_slot.texture , 'image'):
                    self.writer.beginBlock( "texture" )
                    self.writer.writeStr( "filepath",  mtex_slot.texture.image.filepath )
                    self.writeParam( mtex_slot.texture.items() )
                    self.writer.endBlock()
                    
        self.writeParam( mat.items() )
        self.writer.endBlock()       
        
    def writeBlk(self, filename):
        self.writer.open( filename )
        for n in self.nodes:
            self.writeNode( n )
        for key, value in self.materials.items():
            self.writeMaterail( value.mat, value.index )
            print(key, value)
        self.writer.close()
        return
    def execute(self, context):
        filepath = self.filepath
        filepath = bpy.path.ensure_ext(filepath, self.filename_ext)
        print("Blender Version {}.{}.{}".format(bpy.app.version[0], bpy.app.version[1], bpy.app.version[2]))
        print("Filepath: {}".format(filepath))
        scene = context.scene
        self.file = open(filepath+".log", "wt")
        objs = (ob for ob in scene.objects if ob.is_visible(scene) and ob.type in SUPPORTED_TYPES and ob.parent == None)
        par_node = self.createRootNode()
        self.recursObjects( objs, par_node, scene )
        path_blk = filepath + ".blk"
        print( 'path_blk=%s' % path_blk );
        self.writeBlk( path_blk )
        prev_path = os.getcwd()
        new_path = os.path.dirname( os.path.realpath(__file__) )
        os.chdir( new_path )
        print(new_path);
        try:
            return_code = subprocess.call(["blk2dag.exe", path_blk, filepath ])
            print( 'ret=%d' % return_code );
        except IOError:
            print( 'convert failed' );
        os.chdir( prev_path )
        self.file.flush()
        self.file.close()
        return {'FINISHED'}
def menu_func_import(self, context):
    self.layout.operator(DagExporter.bl_idname,text=DagExporter.bl_label)
def register():
    bpy.utils.register_module(__name__)
    bpy.types.INFO_MT_file_export.append(menu_func_import)
def unregister():
    bpy.utils.unregister_module(__name__)
    bpy.types.INFO_MT_file_export.remove(menu_func_import)
if __name__ == "__main__":
    register()

Сам dagorShaders.cfg присутствует в папках к почти каждому Максовому плагину с небольшими вариациями.

tex1_name=“diffuse”
tex2_name=“CUBE environment”
tex3_name=“normalmap”
tex4_name=“parallax (height field)”
tex5_name=“glossmap (specular mask+shininess)”
tex6_name=“emission tex (unsupported!)”
tex7_name=“lightmap”
tex8_name=“detail tex”


lighting=enum(none lightmap vltmap)
real_two_sided=enum(yes no)
scene_emission=real optional
emission=real optional
relief = real optional
atest=text optional
reflection_multiplier=int optional


;Aces

atest=int optional
zbias=real optional




atest=text optional
zbias=real optional


atest=int optional
normal_offset=real optional
impostor=int optional


min_reflect=real optional
max_reflect=real optional
fresnel_power=real optional
opacity=real optional


atest=int optional
ablend=int optional


//тайлы детейлов:
detail1_tile_u=real optional
detail1_tile_v=real optional
detail2_tile_u=real optional
detail2_tile_v=real optional

detail1_scroll_u=text optional
detail1_scroll_v=text optional
detail2_scroll_u=text optional
detail2_scroll_v=text optional

//тайл атласа оверлея:
atlas_tile_u=real optional
atlas_tile_v=real optional
atlas_first_tile=real optional
atlas_last_tile=real optional

//тайл маски:
mask_tile_u=real optional
mask_tile_v=real optional

//скроллить или нет маску от положения (может быть 0 или 1):
mask_scroll_u=text optional
mask_scroll_v=text optional

//рандомизованная гамма (“от” .. “до”):
mask_gamma_start=real optional
mask_gamma_end=real optional

//2nd detail recolour
detail2_colored=text optional

//горизонтальное проецирование второго детейла сверху на объект:
top_projection=text optional

//углы проецирования:
top_projection_from=real optional
top_projection_to=real optional

//уровень влияния оверлая на второй детрейл при проецировании:
top_projection_detail2_modulate=real optional

//покраска 1го или 2го детейла текстурой покраски
use_painting=real optional
painting_line=real optional
paint1stdetail=real optional

//смешиваем нормали детейлов, где преобладает 2й детейл
detail2_combined_normal=real optional



min_reflect=real optional
max_reflect=real optional
atest=int optional
use_decal_tex=int optional
lit_with_gun_fire=int optional


not_use_fxaa=int optional
is_outer_cockpit=int optional
min_reflect=real optional
max_reflect=real optional
fresnel_power=real optional
sun_reflection_power=real optional
atest=int optional
use_decal_tex=int optional
texcoord_mulp=int optional
texcoord_anim=int optional
lit_with_gun_fire=int optional
//покраска модели текстурой покраски
use_painting=real optional
painting_line=real optional



min_reflect=real optional
max_reflect=real optional
fresnel_power=real optional
zbias=real optional
slope_zbias=real optional
opacity=real optional
rain_droplets=real optional


detail_scale_x=real optional
detail_scale_y=real optional
detail_distinctness=real optional
camo_gamma_mul=real optional
atest=int optional











atest=text optional
lit_with_gun_fire=int optional


atest=text optional
zbias=real optional
slope_zbias=real optional


texcoord_anim=int optional


atest=int optional






atest=int optional












water_move_period=real optional
water_dir_u=real optional
water_dir_v=real optional
water_x_scale=real optional
water_y_scale=real optional
water_min_reflect=real optional
water_max_reflect=real optional
water_height=real optional
;water_height_speed=real optional
;water_tex_rotate=real optional


big=int optional
should_use_detail=real optional
bake_landmesh_combined=int optional
render_landmesh_combined=int optional
vertical_from_geom_norm=int optional






detail1_tile_u=real optional
detail1_tile_v=real optional
detail2_tile_u=real optional
detail2_tile_v=real optional


reflection_multiplier=real optional
detail1_tile_u=real optional
detail1_tile_v=real optional
detail2_tile_u=real optional
detail2_tile_v=real optional


opacity=real optional













//тайлы детейлов:
detail1_tile_u=real optional
detail1_tile_v=real optional
detail2_tile_u=real optional
detail2_tile_v=real optional

detail1_scroll_u=text optional
detail1_scroll_v=text optional
detail2_scroll_u=text optional
detail2_scroll_v=text optional

//тайл атласа оверлея:
atlas_tile_u=real optional
atlas_tile_v=real optional
atlas_first_tile=real optional
atlas_last_tile=real optional

//тайл маски:
mask_tile_u=real optional
mask_tile_v=real optional

//скроллить или нет маску от положения (может быть 0 или 1):
mask_scroll_u=text optional
mask_scroll_v=text optional

//рандомизованная гамма (“от” .. “до”):
mask_gamma_start=real optional
mask_gamma_end=real optional

//трава
draw_grass=text optional

//2nd detail recolour
detail2_colored=text optional

//горизонтальное проецирование второго детейла сверху на объект:
top_projection=text optional

//углы проецирования:
top_projection_from=real optional
top_projection_to=real optional

//уровень влияния оверлая на второй детрейл при проецировании:
top_projection_detail2_modulate=real optional

//покраска 1го детейла текстурой покраски
use_painting=real optional
painting_line=real optional
paint1stdetail=real optional

//смешиваем нормали детейлов, где преобладает 2й детейл
detail2_combined_normal=real optional




atest=text optional
detail_scale_u=real optional
detail_scale_v=real optional

//покраска модели текстурой покраски
use_painting=real optional
painting_line=real optional




atest=text optional
zbias=real optional
slope_zbias=real optional
specularStr=real optional
specularPow=real optional
relief=real optional


detail1_tile_u=real optional
detail1_tile_v=real optional
detail2_tile_u=real optional
detail2_tile_v=real optional



В Максе плагин добавляет “менюшки” в интерфейс.
Если не соотвецтвуют требования подготовки модели к экспорту, появляется окошко с причиной ошибки.
Требования 4.
У модели должна быть UV развертка.
У модели должен быть “материал”. Выбирается нужный “матерал/шейдер” с помощью плагиного интерфейса. Иначе вообще ниего не отображается.
У модели должна быть текстура. Выбирается в настройках “материала/шейдера” выбранного с помощью плагина. Иначе модель получится черная.
У модели должны быть “группы сглаживания”, иначе будет глюковато отображаться.

По идеи, при экспорте из Блендер, ритуал должен быть похожий.
Но незнаю как запустить скрипт правильно. Модель получается всегда черная.

В интерфейс Блендер, есть пункт custom properties.
Как понимаю, используя эту менюшку, можно “привязать” шейдер и материал из Максового. В редмишке про это и говориться. Но не могу понять “что” именно нужно скрипту.


Посоветуйте хоть какой нибудь учебник по питону “внятный” для моего уровня.
Пробовал читать разные учебники, содержание вроде одинаковое, но объяснения больше запутывают.

Посоветуйте хоть что нибудь.

Офлайн

#2 Фев. 21, 2017 06:10:58

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9849
Репутация: +  853  -
Профиль   Отправить e-mail  

Скрипт экспорта *.blend => *.dag для War Thunder CDK

Povert
Посоветуйте хоть какой нибудь учебник по питону “внятный” для моего уровня.
Тут питон ни при чём. В этом скрипте используется API блендера, которое сложное само по себе. Даже если питон выучишь, знание апи блендера от этого не появится.
(API (Application Programming Interface) - интерфейс программирования приложений, типа это он, но я зову его оно (как с детства привык).)



Офлайн

#3 Фев. 21, 2017 06:36:33

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Скрипт экспорта *.blend => *.dag для War Thunder CDK

Питон учится за неделю, по любому учебнику. Вы потратили 2 месяца. Скорее всего программирование это не ваше. Проще заказать работу специалисту.



Офлайн

#4 Фев. 21, 2017 15:57:35

Povert
Зарегистрирован: 2017-02-19
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Скрипт экспорта *.blend => *.dag для War Thunder CDK

Блендер хобби. Захотелось смоделить чтото по масштабнее чем картинка или моделька.
Моделю в Блендер. Модель с UV, экспортирую в fbx (не портится масштаб). Потом в Максе навешиваю материалы и сглаживание и перегоняю в *.dag.
Интерфейс Макса для меня “не логичный”. Трудные моменты уже “прояндексил”, ритуал становится привычным.
Но нудное тыкание мышкой по туче кнопочек в Максе… По этому и заморочился с экспортом напрямую с Блендера.

Спасибо за подсказку про Application Programming Interface, попробую почитать блендерскую вики на эту тему, может что и станет понятнее.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version