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())
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())
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)
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
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
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")
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