import bpy import os import assets import utils def add_armory_library(sdk_path, name): return ('project.addLibrary("../' + bpy.path.relpath(sdk_path + '/' + name)[2:] + '");\n').replace('\\', '/') # Write khafile.js def write_khafilejs(is_play, export_physics): sdk_path = 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))) with open('khafile.js', 'w') as f: f.write( """// Auto-generated let project = new Project('""" + bpy.data.worlds['Arm'].ArmProjectName + """'); project.addSources('Sources'); project.addShaders('Sources/Shaders/**'); """) f.write(add_armory_library(sdk_path, 'armory')) f.write(add_armory_library(sdk_path, 'iron')) if export_physics: f.write("project.addDefine('WITH_PHYSICS');\n") f.write(add_armory_library(sdk_path + '/lib/', 'haxebullet')) # Electron live patching # if is_play and bpy.data.worlds['Arm'].ArmPlayLivePatch == True and bpy.data.worlds['Arm'].ArmPlayRuntime == 'Electron': # f.write("project.addDefine('WITH_PATCH_ELECTRON');\n") # Native scripting # f.write(add_armory_library(sdk_path + '/lib/', 'haxeduktape')) for ref in shader_references: f.write("project.addShaders('" + ref + "');\n") for ref in shader_data_references: ref = ref.replace('\\', '/') f.write("project.addAssets('" + ref + "');\n") for ref in asset_references: ref = ref.replace('\\', '/') f.write("project.addAssets('" + ref + "');\n") if bpy.data.worlds['Arm'].ArmPlayConsole: f.write("project.addDefine('WITH_PROFILE');\n") f.write(add_armory_library(sdk_path, 'lib/zui')) font_path = sdk_path + '/armory/Assets/droid_sans.ttf' font_path = font_path.replace('\\', '/') f.write('project.addAssets("' + font_path + '");\n') # f.write(add_armory_library(sdk_path, 'lib/haxeui/haxeui-core')) # f.write(add_armory_library(sdk_path, 'lib/haxeui/haxeui-kha')) # f.write(add_armory_library(sdk_path, 'lib/haxeui/hscript')) if bpy.data.worlds['Arm'].ArmMinimize == False: f.write("project.addDefine('WITH_JSON');\n") if bpy.data.worlds['Arm'].ArmDeinterleavedBuffers == True: f.write("project.addDefine('WITH_DEINTERLEAVED');\n") if bpy.data.worlds['Arm'].generate_gpu_skin == False: f.write("project.addDefine('WITH_CPU_SKIN');\n") for d in assets.khafile_defs: f.write("project.addDefine('" + d + "');\n") config_text = bpy.data.worlds['Arm'].ArmKhafile 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): wrd = bpy.data.worlds['Arm'] resx, resy = utils.get_render_resolution() #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.ArmProjectName + """'; public static inline var projectPackage = '""" + wrd.ArmProjectPackage + """'; static inline var projectWidth = """ + str(resx) + """; static inline var projectHeight = """ + str(resy) + """; static inline var projectSamplesPerPixel = """ + str(wrd.ArmProjectSamplesPerPixel) + """; static inline var projectScene = '""" + utils.get_project_scene_name() + """'; public static function main() { iron.system.CompileTime.importPackage('armory.trait'); iron.system.CompileTime.importPackage('armory.renderpath'); iron.system.CompileTime.importPackage('""" + wrd.ArmProjectPackage + """'); #if (js && WITH_PHYSICS) untyped __js__(" function loadScript(url, callback) { var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.type = 'text/javascript'; script.src = url; script.onreadystatechange = callback; script.onload = callback; head.appendChild(script); } "); """) f.write(""" untyped loadScript('ammo.js', start); #else start(); #end } static function start() {""") f.write(""" kha.System.init({title: projectName, width: projectWidth, height: projectHeight, samplesPerPixel: projectSamplesPerPixel}, function() { iron.App.init(function() { iron.Scene.setActive(projectScene, function(object:iron.object.Object) {""") if utils.with_chromium() and in_viewport and is_play: f.write(""" object.addTrait(new armory.trait.internal.EditorSpace());""") f.write(""" }); }); }); } } """) # Write electron.js def write_electronjs(x, y, w, h, winoff, in_viewport): wrd = bpy.data.worlds['Arm'] dev_tools = wrd.ArmPlayDeveloperTools 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 () { """) if in_viewport: f.write( """ let point = electron.screen.getCursorScreenPoint(); let targetDisplay = electron.screen.getDisplayNearestPoint(point); """) if utils.get_os() == 'mac': # Perform scale in python f.write("""let scale = 1;""") else: f.write("""let scale = targetDisplay.scaleFactor;""") f.write( """ let _x = Math.floor(""" + str(int(x)) + """ / scale); let _y = Math.floor(""" + str(int(y)) + """ / scale); let _w = Math.floor(""" + str(int(w)) + """ / scale); let _h = Math.floor(""" + str(int(h)) + """ / scale); let _winoff = Math.floor(""" + str(int(winoff)) + """ / scale); let offY = targetDisplay.workAreaSize.height - _winoff; _x = targetDisplay.bounds.x + _x; _y = targetDisplay.bounds.y + _y + offY; mainWindow = new BrowserWindow({x: _x, y: _y, width: _w, height: _h, frame: false, autoHideMenuBar: true, useContentSize: true, movable: false, resizable: false, transparent: true, enableLargerThanScreen: true}); mainWindow.setSkipTaskbar(true); mainWindow.setAlwaysOnTop(true); """) else: f.write( """ mainWindow = new BrowserWindow({width: """ + str(int(w)) + """, height: """ + str(int(h)) + """, autoHideMenuBar: true, useContentSize: true}); """) f.write( """ mainWindow.loadURL('file://' + __dirname + '/html5/index.html'); //mainWindow.loadURL('http://localhost:8040/build/html5/index.html'); mainWindow.on('closed', function() { mainWindow = null; });""") if dev_tools: f.write(""" mainWindow.toggleDevTools();""") f.write(""" } 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, in_viewport): with open('build/html5/index.html', 'w') as f: f.write( """