import bpy import os import shutil import arm.utils import arm.assets as assets import arm.make_state as state check_dot_path = False def add_armory_library(sdk_path, name): return ('project.addLibrary("' + sdk_path + '/' + name + '");\n').replace('\\', '/') def add_assets(path): global check_dot_path if check_dot_path and '/.' in path: # Redirect path to local copy armpath = 'build/compiled/ArmoryAssets/' if not os.path.exists(armpath): os.makedirs(armpath) localpath = armpath + path.rsplit('/')[-1] if not os.path.isfile(localpath): shutil.copy(path, localpath) path = localpath return 'project.addAssets("' + path + '");\n' # Write khafile.js def write_khafilejs(is_play, export_physics, export_navigation, dce_full=False): global check_dot_path sdk_path = arm.utils.get_sdk_path() # Merge duplicates and sort shader_references = sorted(list(set(assets.shaders))) shader_data_references = sorted(list(set(assets.shader_datas))) asset_references = sorted(list(set(assets.assets))) wrd = bpy.data.worlds['Arm'] with open('khafile.js', 'w') as f: f.write( """// Auto-generated let project = new Project('""" + arm.utils.safefilename(wrd.arm_project_name) + """'); project.addSources('Sources'); """) # TODO: Move to khamake f.write("project.addDefine('arm_" + arm.utils.get_gapi() + "');\n") # 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('build/compiled/KhaShaders'): kha_shaders_path = arm.utils.get_kha_path() + '/Sources/Shaders' shutil.copytree(kha_shaders_path, 'build/compiled/KhaShaders') f.write("project.addShaders('build/compiled/KhaShaders/**');\n") # Auto-add assets located in Bundled directory if os.path.exists('Bundled'): f.write(add_assets("Bundled/**")) if os.path.exists('Libraries/armory'): f.write('project.addLibrary("armory")') else: f.write(add_armory_library(sdk_path, 'armory')) if os.path.exists('Libraries/iron'): f.write('project.addLibrary("iron")') else: f.write(add_armory_library(sdk_path, 'iron')) # Project libraries for lib in wrd.my_librarytraitlist: if lib.enabled_prop: f.write('project.addLibrary("{0}");\n'.format(lib.name)) if export_physics: f.write("project.addDefine('arm_physics');\n") f.write(add_armory_library(sdk_path + '/lib/', 'haxebullet')) if state.target == 'krom' or state.target == 'html5': ammojs_path = sdk_path + '/lib/haxebullet/js/ammo/ammo.js' ammojs_path = ammojs_path.replace('\\', '/') f.write(add_assets(ammojs_path)) if export_navigation: f.write("project.addDefine('arm_navigation');\n") 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 dce_full: f.write("project.addParameter('-dce full');") for ref in shader_references: f.write("project.addShaders('" + ref + "');\n") for ref in shader_data_references: ref = ref.replace('\\', '/') f.write(add_assets(ref)) for ref in asset_references: ref = ref.replace('\\', '/') f.write(add_assets(ref)) if wrd.arm_play_console: f.write("project.addDefine('arm_profile');\n") if wrd.arm_play_console or wrd.arm_ui: f.write(add_armory_library(sdk_path, 'lib/zui')) p = sdk_path + '/armory/Assets/droid_sans.ttf' f.write(add_assets(p.replace('\\', '/'))) if wrd.arm_hscript: f.write(add_armory_library(sdk_path, 'lib/hscript')) # if wrd.arm_ui: # f.write(add_armory_library(sdk_path, 'lib/haxeui-core')) # f.write(add_armory_library(sdk_path, 'lib/haxeui-kha')) # f.write(add_armory_library(sdk_path, 'lib/hscript')) if wrd.arm_minimize == False: f.write("project.addDefine('arm_json');\n") if wrd.arm_deinterleaved_buffers == True: f.write("project.addDefine('arm_deinterleaved');\n") if wrd.arm_batch_meshes == True: f.write("project.addDefine('arm_batch');\n") if wrd.generate_gpu_skin == False: f.write("project.addDefine('arm_cpu_skin');\n") 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()) f.write("\n\nresolve(project);\n") # Write Main.hx def write_main(is_play, in_viewport, is_publish): wrd = bpy.data.worlds['Arm'] resx, resy = arm.utils.get_render_resolution(arm.utils.get_active_scene()) scene_name = arm.utils.get_project_scene_name() scene_ext = '.zip' if (bpy.data.scenes[scene_name].data_compressed and is_publish) else '' #if not os.path.isfile('Sources/Main.hx'): with open('Sources/Main.hx', 'w') as f: f.write( """// Auto-generated package ; class Main { public static inline var projectName = '""" + wrd.arm_project_name + """'; public static inline var projectPackage = '""" + wrd.arm_project_package + """'; public static inline var projectAssets = """ + str(len(assets.assets)) + """; static inline var projectWidth = """ + str(resx) + """; static inline var projectHeight = """ + str(resy) + """; static inline var projectSamplesPerPixel = """ + str(int(wrd.arm_samples_per_pixel)) + """; static inline var projectScene = '""" + scene_name + scene_ext + """'; static var state:Int; #if js static function loadLib(name:String) { kha.LoaderImpl.loadBlobFromDescription({ files: [name] }, function(b:kha.Blob) { untyped __js__("(1, eval)({0})", b.toString()); state--; start(); }); } #end public static function main() { iron.system.CompileTime.importPackage('armory.trait'); iron.system.CompileTime.importPackage('armory.renderpath'); iron.system.CompileTime.importPackage('""" + wrd.arm_project_package + """'); state = 1; #if (js && arm_physics) state++; loadLib("ammo.js"); #end #if (js && arm_navigation) state++; loadLib("recast.js"); #end state--; start(); } static function start() { if (state > 0) return; armory.object.Uniforms.register(); kha.System.init({title: projectName, width: projectWidth, height: projectHeight, samplesPerPixel: projectSamplesPerPixel}, function() { iron.App.init(function() { """) if is_publish and wrd.arm_loadbar: f.write("""iron.App.notifyOnRender2D(armory.trait.internal.LoadBar.render);""") f.write(""" iron.Scene.setActive(projectScene, function(object:iron.object.Object) {""") # if arm.utils.with_krom() and in_viewport and is_play: if is_play: f.write(""" object.addTrait(new armory.trait.internal.SpaceArmory());""") f.write(""" }); }); }); } } """) # Write electron.js def write_electronjs(w, h): wrd = bpy.data.worlds['Arm'] with open('build/electron.js', 'w') as f: f.write( """// Auto-generated 'use strict'; const electron = require('electron'); const app = electron.app; const BrowserWindow = electron.BrowserWindow; let mainWindow; function createWindow () { mainWindow = new BrowserWindow({width: """ + str(int(w)) + """, height: """ + str(int(h)) + """, autoHideMenuBar: true, useContentSize: true}); mainWindow.loadURL('file://' + __dirname + '/html5/index.html'); //mainWindow.loadURL('http://localhost:8040/build/html5/index.html'); mainWindow.on('closed', function() { mainWindow = null; }); } app.on('ready', createWindow); app.on('window-all-closed', function () { app.quit(); }); app.on('activate', function () { if (mainWindow === null) { createWindow(); } }); """) # Write index.html def write_indexhtml(w, h): if not os.path.exists('build/html5'): os.makedirs('build/html5') with open('build/html5/index.html', 'w') as f: f.write( """
""") if bpy.data.cameras[0].rp_stereo: f.write(""" """) f.write("""