Example #1
0
def write_shader(rel_path, shader, ext, rpass, keep_cache=True):
    if shader == None:
        return
    shader_rel_path = rel_path + '/' + arm.utils.safesrc(
        mat_state.material.name) + '_' + rpass + '.' + ext + '.glsl'
    shader_path = arm.utils.get_fp() + '/' + shader_rel_path
    assets.add_shader(shader_rel_path)
    if not os.path.isfile(shader_path) or not keep_cache:
        with open(shader_path, 'w') as f:
            f.write(shader.get())
Example #2
0
def write_shader(rel_path, shader, ext, rpass, matname, keep_cache=True):
    if shader == None or shader.is_linked:
        return

    # TODO: blend context
    if mat_state.material.arm_blending and rpass == 'mesh':
        rpass = '******'

    shader_rel_path = rel_path + '/' + matname + '_' + rpass + '.' + ext + '.glsl'
    shader_path = arm.utils.get_fp() + '/' + shader_rel_path
    assets.add_shader(shader_path)
    if not os.path.isfile(shader_path) or not keep_cache:
        with open(shader_path, 'w') as f:
            f.write(shader.get())
Example #3
0
def write_shader(rel_path: str,
                 shader: Shader,
                 ext: str,
                 rpass: str,
                 matname: str,
                 keep_cache=True) -> None:
    if shader is None or shader.is_linked:
        return

    # TODO: blend context
    if rpass == 'mesh' and mat_state.material.arm_blending:
        rpass = '******'

    file_ext = '.glsl'
    if shader.noprocessing:
        # Use hlsl directly
        hlsl_dir = arm.utils.build_dir() + '/compiled/Hlsl/'
        if not os.path.exists(hlsl_dir):
            os.makedirs(hlsl_dir)
        file_ext = '.hlsl'
        rel_path = rel_path.replace('/compiled/Shaders/', '/compiled/Hlsl/')

    shader_file = matname + '_' + rpass + '.' + ext + file_ext
    shader_path = arm.utils.get_fp() + '/' + rel_path + '/' + shader_file
    assets.add_shader(shader_path)
    if not os.path.isfile(shader_path) or not keep_cache:
        with open(shader_path, 'w') as f:
            f.write(shader.get())

        if shader.noprocessing:
            cwd = os.getcwd()
            os.chdir(arm.utils.get_fp() + '/' + rel_path)
            hlslbin_path = arm.utils.get_sdk_path(
            ) + '/lib/armory_tools/hlslbin/hlslbin.exe'
            prof = 'vs_5_0' if ext == 'vert' else 'ps_5_0' if ext == 'frag' else 'gs_5_0'
            # noprocessing flag - gets renamed to .d3d11
            args = [
                hlslbin_path.replace('/', '\\').replace('\\\\', '\\'),
                shader_file, shader_file[:-4] + 'glsl', prof
            ]
            if ext == 'vert':
                args.append('-i')
                args.append('pos')
            proc = subprocess.call(args)
            os.chdir(cwd)
Example #4
0
def export_data(fp, sdk_path):
    wrd = bpy.data.worlds['Arm']

    print('Armory v{0} ({1})'.format(wrd.arm_version, wrd.arm_commit))
    if wrd.arm_verbose_output:
        print(
            f'Blender: {bpy.app.version_string}, Target: {state.target}, GAPI: {arm.utils.get_gapi()}'
        )

    # Clean compiled variants if cache is disabled
    build_dir = arm.utils.get_fp_build()
    if not wrd.arm_cache_build:
        if os.path.isdir(build_dir + '/debug/html5-resources'):
            shutil.rmtree(build_dir + '/debug/html5-resources',
                          onerror=remove_readonly)
        if os.path.isdir(build_dir + '/krom-resources'):
            shutil.rmtree(build_dir + '/krom-resources',
                          onerror=remove_readonly)
        if os.path.isdir(build_dir + '/debug/krom-resources'):
            shutil.rmtree(build_dir + '/debug/krom-resources',
                          onerror=remove_readonly)
        if os.path.isdir(build_dir + '/windows-resources'):
            shutil.rmtree(build_dir + '/windows-resources',
                          onerror=remove_readonly)
        if os.path.isdir(build_dir + '/linux-resources'):
            shutil.rmtree(build_dir + '/linux-resources',
                          onerror=remove_readonly)
        if os.path.isdir(build_dir + '/osx-resources'):
            shutil.rmtree(build_dir + '/osx-resources',
                          onerror=remove_readonly)
        if os.path.isdir(build_dir + '/compiled/Shaders'):
            shutil.rmtree(build_dir + '/compiled/Shaders',
                          onerror=remove_readonly)

    raw_shaders_path = sdk_path + '/armory/Shaders/'
    assets_path = sdk_path + '/armory/Assets/'
    export_physics = bpy.data.worlds['Arm'].arm_physics != 'Disabled'
    export_navigation = bpy.data.worlds['Arm'].arm_navigation != 'Disabled'
    export_ui = bpy.data.worlds['Arm'].arm_ui != 'Disabled'
    assets.reset()

    # Build node trees
    ArmoryExporter.import_traits = []
    make_logic.build()
    make_world.build()
    make_renderpath.build()

    # Export scene data
    assets.embedded_data = sorted(list(set(assets.embedded_data)))
    physics_found = False
    navigation_found = False
    ui_found = False
    ArmoryExporter.compress_enabled = state.is_publish and wrd.arm_asset_compression
    ArmoryExporter.optimize_enabled = state.is_publish and wrd.arm_optimize_data
    if not os.path.exists(build_dir + '/compiled/Assets'):
        os.makedirs(build_dir + '/compiled/Assets')
    # have a "zoo" collection in the current scene
    export_coll = bpy.data.collections.new("export_coll")
    bpy.context.scene.collection.children.link(export_coll)
    for scene in bpy.data.scenes:
        if scene == bpy.context.scene: continue
        for o in scene.collection.all_objects:
            if o.type == "MESH" or o.type == "EMPTY":
                if o.name not in export_coll.all_objects.keys():
                    export_coll.objects.link(o)
    depsgraph = bpy.context.evaluated_depsgraph_get()
    bpy.data.collections.remove(export_coll)  # destroy "zoo" collection

    for scene in bpy.data.scenes:
        if scene.arm_export:
            ext = '.lz4' if ArmoryExporter.compress_enabled else '.arm'
            asset_path = build_dir + '/compiled/Assets/' + arm.utils.safestr(
                scene.name) + ext
            ArmoryExporter.export_scene(bpy.context,
                                        asset_path,
                                        scene=scene,
                                        depsgraph=depsgraph)
            if ArmoryExporter.export_physics:
                physics_found = True
            if ArmoryExporter.export_navigation:
                navigation_found = True
            if ArmoryExporter.export_ui:
                ui_found = True
            assets.add(asset_path)

    if physics_found == False:  # Disable physics if no rigid body is exported
        export_physics = False

    if navigation_found == False:
        export_navigation = False

    if ui_found == False:
        export_ui = False

    if wrd.arm_ui == 'Enabled':
        export_ui = True

    modules = []
    if wrd.arm_audio == 'Enabled':
        modules.append('audio')
    if export_physics:
        modules.append('physics')
    if export_navigation:
        modules.append('navigation')
    if export_ui:
        modules.append('ui')

    defs = arm.utils.def_strings_to_array(wrd.world_defs)
    cdefs = arm.utils.def_strings_to_array(wrd.compo_defs)

    if wrd.arm_verbose_output:
        print('Exported modules:', ', '.join(modules))
        print('Shader flags:', ' '.join(defs))
        print('Compositor flags:', ' '.join(cdefs))
        print('Khafile flags:', ' '.join(assets.khafile_defs))

    # Render path is configurable at runtime
    has_config = wrd.arm_write_config or os.path.exists(arm.utils.get_fp() +
                                                        '/Bundled/config.arm')

    # Write compiled.inc
    shaders_path = build_dir + '/compiled/Shaders'
    if not os.path.exists(shaders_path):
        os.makedirs(shaders_path)
    write_data.write_compiledglsl(defs + cdefs, make_variants=has_config)

    # Write referenced shader passes
    if not os.path.isfile(build_dir + '/compiled/Shaders/shader_datas.arm'
                          ) or state.last_world_defs != wrd.world_defs:
        res = {'shader_datas': []}

        for ref in assets.shader_passes:
            # Ensure shader pass source exists
            if not os.path.exists(raw_shaders_path + '/' + ref):
                continue
            assets.shader_passes_assets[ref] = []
            if ref.startswith('compositor_pass'):
                compile_shader_pass(res,
                                    raw_shaders_path,
                                    ref,
                                    defs + cdefs,
                                    make_variants=has_config)
            else:
                compile_shader_pass(res,
                                    raw_shaders_path,
                                    ref,
                                    defs,
                                    make_variants=has_config)

        # Workaround to also export non-material world shaders
        res['shader_datas'] += make_world.shader_datas

        arm.utils.write_arm(shaders_path + '/shader_datas.arm', res)

    for ref in assets.shader_passes:
        for s in assets.shader_passes_assets[ref]:
            assets.add_shader(shaders_path + '/' + s + '.glsl')
    for file in assets.shaders_external:
        name = file.split('/')[-1].split('\\')[-1]
        target = build_dir + '/compiled/Shaders/' + name
        if not os.path.exists(target):
            shutil.copy(file, target)
    state.last_world_defs = wrd.world_defs

    # Reset path
    os.chdir(fp)

    # Copy std shaders
    if not os.path.isdir(build_dir + '/compiled/Shaders/std'):
        shutil.copytree(raw_shaders_path + 'std',
                        build_dir + '/compiled/Shaders/std')

    # Write config.arm
    resx, resy = arm.utils.get_render_resolution(arm.utils.get_active_scene())
    if wrd.arm_write_config:
        write_data.write_config(resx, resy)

    # Change project version (Build, Publish)
    if (not state.is_play) and (wrd.arm_project_version_autoinc):
        wrd.arm_project_version = arm.utils.arm.utils.change_version_project(
            wrd.arm_project_version)

    # Write khafile.js
    enable_dce = state.is_publish and wrd.arm_dce
    import_logic = not state.is_publish and arm.utils.logic_editor_space(
    ) != None
    write_data.write_khafilejs(state.is_play, export_physics,
                               export_navigation, export_ui, state.is_publish,
                               enable_dce, ArmoryExporter.import_traits,
                               import_logic)

    # Write Main.hx - depends on write_khafilejs for writing number of assets
    scene_name = arm.utils.get_project_scene_name()
    write_data.write_mainhx(scene_name, resx, resy, state.is_play,
                            state.is_publish)
    if scene_name != state.last_scene or resx != state.last_resx or resy != state.last_resy:
        wrd.arm_recompile = True
        state.last_resx = resx
        state.last_resy = resy
        state.last_scene = scene_name
Example #5
0
def export_data(fp, sdk_path):
    global exporter
    wrd = bpy.data.worlds['Arm']

    print('\nArmory v{0} ({1})'.format(wrd.arm_version, wrd.arm_commit))
    print('OS: ' + arm.utils.get_os() + ', Target: ' + state.target +
          ', GAPI: ' + arm.utils.get_gapi() + ', Blender: ' +
          bpy.app.version_string)

    # Clean compiled variants if cache is disabled
    build_dir = arm.utils.get_fp_build()
    if wrd.arm_cache_shaders == False:
        if os.path.isdir(build_dir + '/debug/html5-resources'):
            shutil.rmtree(build_dir + '/debug/html5-resources',
                          onerror=remove_readonly)
        if os.path.isdir(build_dir + '/krom-resources'):
            shutil.rmtree(build_dir + '/krom-resources',
                          onerror=remove_readonly)
        if os.path.isdir(build_dir + '/debug/krom-resources'):
            shutil.rmtree(build_dir + '/debug/krom-resources',
                          onerror=remove_readonly)
        if os.path.isdir(build_dir + '/windows-resources'):
            shutil.rmtree(build_dir + '/windows-resources',
                          onerror=remove_readonly)
        if os.path.isdir(build_dir + '/linux-resources'):
            shutil.rmtree(build_dir + '/linux-resources',
                          onerror=remove_readonly)
        if os.path.isdir(build_dir + '/osx-resources'):
            shutil.rmtree(build_dir + '/osx-resources',
                          onerror=remove_readonly)
        if os.path.isdir(build_dir + '/compiled/Shaders'):
            shutil.rmtree(build_dir + '/compiled/Shaders',
                          onerror=remove_readonly)

    raw_shaders_path = sdk_path + '/armory/Shaders/'
    assets_path = sdk_path + '/armory/Assets/'
    export_physics = bpy.data.worlds['Arm'].arm_physics != 'Disabled'
    export_navigation = bpy.data.worlds['Arm'].arm_navigation != 'Disabled'
    export_ui = bpy.data.worlds['Arm'].arm_ui != 'Disabled'
    assets.reset()

    # Build node trees
    ArmoryExporter.import_traits = []
    make_logic.build()
    make_world.build()
    make_renderpath.build()

    # Export scene data
    assets.embedded_data = sorted(list(set(assets.embedded_data)))
    physics_found = False
    navigation_found = False
    ui_found = False
    ArmoryExporter.compress_enabled = state.is_publish and wrd.arm_asset_compression
    for scene in bpy.data.scenes:
        if scene.arm_export:
            ext = '.zip' if (scene.arm_compress
                             and state.is_publish) else '.arm'
            asset_path = build_dir + '/compiled/Assets/' + arm.utils.safestr(
                scene.name) + ext
            exporter.execute(bpy.context, asset_path, scene=scene)
            if ArmoryExporter.export_physics:
                physics_found = True
            if ArmoryExporter.export_navigation:
                navigation_found = True
            if ArmoryExporter.export_ui:
                ui_found = True
            assets.add(asset_path)

    if physics_found == False:  # Disable physics if no rigid body is exported
        export_physics = False

    if navigation_found == False:
        export_navigation = False

    if ui_found == False:
        export_ui = False

    if wrd.arm_ui == 'Enabled':
        export_ui = True

    modules = []
    if wrd.arm_audio == 'Enabled':
        modules.append('audio')
    if export_physics:
        modules.append('physics')
    if export_navigation:
        modules.append('navigation')
    if export_ui:
        modules.append('ui')
    if wrd.arm_hscript == 'Enabled':
        modules.append('hscript')
    if wrd.arm_formatlib == 'Enabled':
        modules.append('format')
    print('Exported modules: ' + str(modules))

    defs = arm.utils.def_strings_to_array(wrd.world_defs)
    cdefs = arm.utils.def_strings_to_array(wrd.compo_defs)
    print('Shader flags: ' + str(defs))
    if wrd.arm_play_console:
        print('Khafile flags: ' + str(assets.khafile_defs))

    # Write compiled.inc
    shaders_path = build_dir + '/compiled/Shaders'
    if not os.path.exists(shaders_path):
        os.makedirs(shaders_path)
    write_data.write_compiledglsl(defs + cdefs)

    # Write referenced shader passes
    if not os.path.isfile(build_dir + '/compiled/Shaders/shader_datas.arm'
                          ) or state.last_world_defs != wrd.world_defs:
        res = {}
        res['shader_datas'] = []
        for ref in assets.shader_passes:
            # Ensure shader pass source exists
            if not os.path.exists(raw_shaders_path + '/' + ref):
                continue
            assets.shader_passes_assets[ref] = []
            if ref.startswith('compositor_pass'):
                compile_shader_pass(res, raw_shaders_path, ref, defs + cdefs)
            # elif ref.startswith('grease_pencil'):
            # compile_shader_pass(res, raw_shaders_path, ref, [])
            else:
                compile_shader_pass(res, raw_shaders_path, ref, defs)
        arm.utils.write_arm(shaders_path + '/shader_datas.arm', res)
    for ref in assets.shader_passes:
        for s in assets.shader_passes_assets[ref]:
            assets.add_shader(shaders_path + '/' + s + '.glsl')
    for file in assets.shaders_external:
        name = file.split('/')[-1].split('\\')[-1]
        target = build_dir + '/compiled/Shaders/' + name
        if not os.path.exists(target):
            shutil.copy(file, target)
    state.last_world_defs = wrd.world_defs

    # Reset path
    os.chdir(fp)

    # Copy std shaders
    if not os.path.isdir(build_dir + '/compiled/Shaders/std'):
        shutil.copytree(raw_shaders_path + 'std',
                        build_dir + '/compiled/Shaders/std')

    # Write config.arm
    resx, resy = arm.utils.get_render_resolution(arm.utils.get_active_scene())
    if wrd.arm_write_config:
        write_data.write_config(resx, resy)

    # Write khafile.js
    enable_dce = state.is_publish and wrd.arm_dce
    import_logic = not state.is_publish and arm.utils.logic_editor_space(
    ) != None
    write_data.write_khafilejs(state.is_play, export_physics,
                               export_navigation, export_ui, state.is_publish,
                               enable_dce, state.is_viewport,
                               ArmoryExporter.import_traits, import_logic)

    # Write Main.hx - depends on write_khafilejs for writing number of assets
    scene_name = arm.utils.get_project_scene_name()
    write_data.write_mainhx(scene_name, resx, resy, state.is_play,
                            state.is_viewport, state.is_publish)
    if scene_name != state.last_scene or resx != state.last_resx or resy != state.last_resy:
        wrd.arm_recompile = True
        state.last_resx = resx
        state.last_resy = resy
        state.last_scene = scene_name
Example #6
0
def write_khafilejs(is_play, export_physics, export_navigation, export_ui,
                    is_publish, enable_dce, in_viewport, import_traits,
                    import_logicnodes):
    global check_dot_path
    sdk_path = arm.utils.get_sdk_path()
    wrd = bpy.data.worlds['Arm']

    with open('khafile.js', 'w') as f:
        f.write("""// Auto-generated
let project = new Project('""" + arm.utils.safestr(wrd.arm_project_name) +
                """');

project.addSources('Sources');
""")

        # TODO: Khamake bug workaround - assets & shaders located in folder starting with '.' get discarded - copy them to project
        check_dot_path = False
        if '/.' in sdk_path:
            check_dot_path = True
            if not os.path.exists(arm.utils.build_dir() +
                                  '/compiled/KhaShaders'):
                kha_shaders_path = arm.utils.get_kha_path(
                ) + '/Sources/Shaders'
                shutil.copytree(kha_shaders_path,
                                arm.utils.build_dir() + '/compiled/KhaShaders')
            f.write("project.addShaders('" + arm.utils.build_dir() +
                    "/compiled/KhaShaders/**');\n")

        # Auto-add assets located in Bundled directory
        if os.path.exists('Bundled'):
            for file in glob.glob("Bundled/**", recursive=True):
                if os.path.isfile(file):
                    assets.add(file)

        if os.path.exists('Shaders'):
            for file in glob.glob("Shaders/**", recursive=True):
                if os.path.isfile(file):
                    assets.add_shader(file)

        if not os.path.exists('Libraries/armory'):
            f.write(add_armory_library(sdk_path, 'armory'))

        if not os.path.exists('Libraries/iron'):
            f.write(add_armory_library(sdk_path, 'iron'))

        # Project libraries
        if os.path.exists('Libraries'):
            libs = os.listdir('Libraries')
            for lib in libs:
                if os.path.isdir('Libraries/' + lib):
                    f.write('project.addLibrary("{0}");\n'.format(lib))

        if export_physics:
            assets.add_khafile_def('arm_physics')
            if wrd.arm_physics == 'Bullet':
                assets.add_khafile_def('arm_bullet')
                if not os.path.exists('Libraries/haxebullet'):
                    f.write(
                        add_armory_library(sdk_path + '/lib/', 'haxebullet'))
                if state.target == 'krom' or state.target == 'html5' or state.target == 'node':
                    ammojs_path = sdk_path + '/lib/haxebullet/js/ammo/ammo.js'
                    ammojs_path = ammojs_path.replace('\\', '/')
                    f.write(add_assets(ammojs_path))
            elif wrd.arm_physics == 'Oimo':
                assets.add_khafile_def('arm_oimo')
                if not os.path.exists('Libraries/oimo'):
                    f.write(add_armory_library(sdk_path + '/lib/', 'oimo'))

        if export_navigation:
            assets.add_khafile_def('arm_navigation')
            if not os.path.exists('Libraries/haxerecast'):
                f.write(add_armory_library(sdk_path + '/lib/', 'haxerecast'))
            if state.target == 'krom' or state.target == 'html5':
                recastjs_path = sdk_path + '/lib/haxerecast/js/recast/recast.js'
                recastjs_path = recastjs_path.replace('\\', '/')
                f.write(add_assets(recastjs_path))

        if not is_publish:
            f.write(
                """project.addParameter("--macro include('armory.trait')");\n"""
            )
            f.write(
                """project.addParameter("--macro include('armory.trait.internal')");\n"""
            )
            if export_physics:
                f.write(
                    """project.addParameter("--macro include('armory.trait.physics')");\n"""
                )
                if wrd.arm_physics == 'Bullet':
                    f.write(
                        """project.addParameter("--macro include('armory.trait.physics.bullet')");\n"""
                    )
                else:
                    f.write(
                        """project.addParameter("--macro include('armory.trait.physics.oimo')");\n"""
                    )
            if export_navigation:
                f.write(
                    """project.addParameter("--macro include('armory.trait.navigation')");\n"""
                )

        if import_logicnodes:  # Live patching for logic nodes
            f.write(
                """project.addParameter("--macro include('armory.logicnode')");\n"""
            )

        if enable_dce:
            f.write("project.addParameter('-dce full');\n")

        if in_viewport:
            assets.add_khafile_def('arm_viewport')
            import_traits.append('armory.trait.internal.Bridge')

        import_traits = list(set(import_traits))
        for i in range(0, len(import_traits)):
            f.write("project.addParameter('" + import_traits[i] + "');\n")
            f.write("""project.addParameter("--macro keep('""" +
                    import_traits[i] + """')");\n""")

        if state.is_render:
            assets.add_khafile_def('arm_render')
            if state.is_render_anim:
                assets.add_khafile_def('arm_render_anim')
                if not os.path.exists('Libraries/iron_format'):
                    f.write(
                        add_armory_library(sdk_path + '/lib/', 'iron_format'))

        shaderload = state.target == 'krom' or state.target == 'html5'
        if wrd.arm_cache_compiler and shaderload and not is_publish:
            # Load shaders manually
            assets.add_khafile_def('arm_shaderload')

        sceneload = state.target == 'krom'
        if wrd.arm_play_live_patch and is_play and in_viewport and sceneload:
            # Scene patch
            assets.add_khafile_def('arm_sceneload')

        shader_references = sorted(list(set(assets.shaders)))
        for ref in shader_references:
            ref = ref.replace('\\', '/')
            f.write("project.addShaders('" + ref + "');\n")

        shader_data_references = sorted(list(set(assets.shader_datas)))
        for ref in shader_data_references:
            ref = ref.replace('\\', '/')
            f.write(add_assets(ref))

        asset_references = sorted(list(set(assets.assets)))
        for ref in asset_references:
            ref = ref.replace('\\', '/')
            quality = 1.0
            s = ref.lower()
            if s.endswith('.wav'):
                quality = wrd.arm_sound_quality
            elif s.endswith('.png') or s.endswith('.jpg'):
                quality = wrd.arm_texture_quality
            f.write(add_assets(ref, quality=quality))

        if wrd.arm_sound_quality < 1.0 or state.target == 'html5':
            assets.add_khafile_def('arm_soundcompress')

        if wrd.arm_texture_quality < 1.0:
            assets.add_khafile_def('arm_texcompress')

        if wrd.arm_play_console:
            assets.add_khafile_def('arm_debug')
            f.write("project.addShaders('" + sdk_path +
                    "/armory/Shaders/debug_draw/**');\n")

        if export_ui:
            if not os.path.exists('Libraries/zui'):
                f.write(add_armory_library(sdk_path, 'lib/zui'))
            p = sdk_path + '/armory/Assets/droid_sans.ttf'
            f.write(add_assets(p.replace('\\', '/')))
            assets.add_khafile_def('arm_ui')

        if wrd.arm_hscript == 'Enabled':
            if not os.path.exists('Libraries/hscript'):
                f.write(add_armory_library(sdk_path, 'lib/hscript'))
            assets.add_khafile_def('arm_hscript')

        if wrd.arm_minimize == False:
            assets.add_khafile_def('arm_json')

        if wrd.arm_deinterleaved_buffers == True:
            assets.add_khafile_def('arm_deinterleaved')

        if wrd.arm_batch_meshes == True:
            assets.add_khafile_def('arm_batch')

        if wrd.arm_stream_scene:
            assets.add_khafile_def('arm_stream')

        if wrd.arm_skin == 'CPU':
            assets.add_khafile_def('arm_skin_cpu')
        elif wrd.arm_skin == 'GPU (Matrix)':
            assets.add_khafile_def('arm_skin_mat')

        if arm.utils.get_viewport_controls() == 'azerty':
            assets.add_khafile_def('arm_azerty')

        for d in assets.khafile_defs:
            f.write("project.addDefine('" + d + "');\n")

        config_text = wrd.arm_khafile
        if config_text != '':
            f.write(bpy.data.texts[config_text].as_string())

        if wrd.arm_winorient != 'Multi':
            if state.target == 'android-native':
                f.write(
                    "project.targetOptions.android_native.screenOrientation = '{0}';\n"
                    .format(wrd.arm_winorient.lower()))

        f.write("\n\nresolve(project);\n")
Example #7
0
def export_data(fp, sdk_path, is_play=False, is_publish=False, in_viewport=False):
    global exporter
    wrd = bpy.data.worlds['Arm']

    print('\nArmory v{0} ({1})'.format(wrd.arm_version, wrd.arm_commit))
    print('OS: ' + arm.utils.get_os() + ', Target: ' + state.target + ', GAPI: ' + arm.utils.get_gapi())

    # Clean compiled variants if cache is disabled
    build_dir = arm.utils.get_fp_build()
    if wrd.arm_cache_shaders == False:
        if os.path.isdir(build_dir + '/debug/html5-resources'):
            shutil.rmtree(build_dir + '/debug/html5-resources', onerror=remove_readonly)
        if os.path.isdir(build_dir + '/krom-resources'):
            shutil.rmtree(build_dir + '/krom-resources', onerror=remove_readonly)
        if os.path.isdir(build_dir + '/debug/krom-resources'):
            shutil.rmtree(build_dir + '/debug/krom-resources', onerror=remove_readonly)
        if os.path.isdir(build_dir + '/windows-resources'):
            shutil.rmtree(build_dir + '/windows-resources', onerror=remove_readonly)
        if os.path.isdir(build_dir + '/linux-resources'):
            shutil.rmtree(build_dir + '/linux-resources', onerror=remove_readonly)
        if os.path.isdir(build_dir + '/osx-resources'):
            shutil.rmtree(build_dir + '/osx-resources', onerror=remove_readonly)
        if os.path.isdir(build_dir + '/compiled/Shaders'):
            shutil.rmtree(build_dir + '/compiled/Shaders', onerror=remove_readonly)

    # Detect camera plane changes
    if len(bpy.data.cameras) > 0:
        cam = bpy.data.cameras[0]
        if state.last_clip_start == 0:
            state.last_clip_start = cam.clip_start
            state.last_clip_end = cam.clip_end
        elif cam.clip_start != state.last_clip_start or cam.clip_end != state.last_clip_end:
            if os.path.isdir(build_dir + '/compiled/Shaders'):
                shutil.rmtree(build_dir + '/compiled/Shaders', onerror=remove_readonly)
            state.last_clip_start = cam.clip_start
            state.last_clip_end = cam.clip_end

    raw_shaders_path = sdk_path + 'armory/Shaders/'
    assets_path = sdk_path + 'armory/Assets/'
    export_physics = bpy.data.worlds['Arm'].arm_physics != 'Disabled'
    export_navigation = bpy.data.worlds['Arm'].arm_navigation != 'Disabled'
    export_ui = bpy.data.worlds['Arm'].arm_ui != 'Disabled'
    assets.reset()

    # Build node trees
    ArmoryExporter.import_traits = []
    make_logic.build()
    make_world.build()
    make_renderpath.build()

    # Export scene data
    assets.embedded_data = sorted(list(set(assets.embedded_data)))
    physics_found = False
    navigation_found = False
    ui_found = False
    ArmoryExporter.compress_enabled = is_publish and wrd.arm_asset_compression
    ArmoryExporter.in_viewport = in_viewport
    for scene in bpy.data.scenes:
        if scene.arm_export:
            ext = '.zip' if (scene.arm_compress and is_publish) else '.arm'
            asset_path = build_dir + '/compiled/Assets/' + arm.utils.safestr(scene.name) + ext
            exporter.execute(bpy.context, asset_path, scene=scene, write_capture_info=state.is_render_anim, play_area=state.play_area)
            if ArmoryExporter.export_physics:
                physics_found = True
            if ArmoryExporter.export_navigation:
                navigation_found = True
            if ArmoryExporter.export_ui:
                ui_found = True
            assets.add(asset_path)

    if physics_found == False: # Disable physics if no rigid body is exported
        export_physics = False

    if navigation_found == False:
        export_navigation = False

    if ui_found == False:
        export_ui = False

    if wrd.arm_ui == 'Enabled':
        export_ui = True

    modules = []
    if export_physics:
        modules.append('physics')
    if export_navigation:
        modules.append('navigation')
    if export_ui:
        modules.append('ui')
    print('Exported modules: ' + str(modules))

    defs = arm.utils.def_strings_to_array(wrd.world_defs)
    print('Shader flags: ' + str(defs))

    # Write referenced shader passes
    path = build_dir + '/compiled/Shaders'
    if not os.path.isfile(build_dir + '/compiled/Shaders/shader_datas.arm') or state.last_world_defs != wrd.world_defs:
        path = build_dir + '/compiled/Shaders'
        if not os.path.exists(path):
            os.makedirs(path)
        res = {}
        res['shader_datas'] = []
        for ref in assets.shader_passes:
            # Ensure shader pass source exists
            if not os.path.exists(raw_shaders_path + '/' + ref):
                continue
            assets.shader_passes_assets[ref] = []
            if ref.startswith('compositor_pass'):
                cdefs = arm.utils.def_strings_to_array(wrd.compo_defs)
                compile_shader_pass(res, raw_shaders_path, ref, defs + cdefs)
            # elif ref.startswith('grease_pencil'):
                # compile_shader_pass(res, raw_shaders_path, ref, [])
            else:
                compile_shader_pass(res, raw_shaders_path, ref, defs)
        arm.utils.write_arm(path + '/shader_datas.arm', res)
    for ref in assets.shader_passes:
        for s in assets.shader_passes_assets[ref]:
            assets.add_shader(path + '/' + s + '.glsl')
    state.last_world_defs = wrd.world_defs

    # Reset path
    os.chdir(fp)

    # Copy std shaders
    if not os.path.isdir(build_dir + '/compiled/Shaders/std'):
        shutil.copytree(raw_shaders_path + 'std', build_dir + '/compiled/Shaders/std')

    # Write compiled.glsl
    write_data.write_compiledglsl()

    # Write khafile.js
    enable_dce = is_publish and wrd.arm_dce
    import_logic = not is_publish and arm.utils.logic_editor_space() != None
    write_data.write_khafilejs(is_play, export_physics, export_navigation, export_ui, is_publish, enable_dce, in_viewport, ArmoryExporter.import_traits, import_logic)

    # Write Main.hx - depends on write_khafilejs for writing number of assets
    scene_name = arm.utils.get_project_scene_name()
    resx, resy = arm.utils.get_render_resolution(arm.utils.get_active_scene())
    # Import all logic nodes for patching if logic is being edited
    write_data.write_main(scene_name, resx, resy, is_play, in_viewport, is_publish)
    if scene_name != state.last_scene or resx != state.last_resx or resy != state.last_resy:
        wrd.arm_recompile = True
        state.last_resx = resx
        state.last_resy = resy
        state.last_scene = scene_name