Send operators to Krom

This commit is contained in:
luboslenco 2019-02-10 11:47:42 +01:00
parent a1da8b0824
commit e0e4bf303f
12 changed files with 133 additions and 51 deletions

View file

@ -46,6 +46,9 @@ class Starter {
#end
iron.Scene.setActive(scene, function(object:iron.object.Object) {
iron.RenderPath.setActive(getRenderPath());
#if arm_patch
iron.Scene.getRenderPath = getRenderPath;
#end
#if arm_draworder_dist
iron.RenderPath.active.drawOrder = iron.RenderPath.DrawOrder.Distance;
#end // else shader

View file

@ -2,12 +2,13 @@ package armory.trait.internal;
#if js
@:expose("armory")
@:expose("iron")
class Bridge {
public static var App = iron.App;
public static var Scene = iron.Scene;
public static var Time = iron.system.Time;
public static var Input = iron.system.Input;
public static var Object = iron.object.Object;
public static var Data = iron.data.Data;
public static function log(s:String) { trace(s); };

View file

@ -0,0 +1,27 @@
package armory.trait.internal;
#if arm_patch
class LivePatch extends iron.Trait {
static var patchId = 0;
public function new() {
super();
notifyOnUpdate(update);
}
function update() {
kha.Assets.loadBlobFromPath("krom.patch", function(b:kha.Blob) {
if (b.length == 0) return;
var lines = b.toString().split('\n');
var id = Std.parseInt(lines[0]);
if (id > patchId) {
patchId = id;
js.Lib.eval(lines[1]);
}
});
}
}
#end

View file

@ -2172,6 +2172,13 @@ class ArmoryExporter:
x['class_name'] = 'armory.trait.internal.DebugConsole'
x['parameters'] = [str(arm.utils.get_ui_scale())]
self.output['traits'].append(x)
if wrd.arm_live_patch:
if not 'traits' in self.output:
self.output['traits'] = []
x = {}
x['type'] = 'Script'
x['class_name'] = 'armory.trait.internal.LivePatch'
self.output['traits'].append(x)
if len(self.scene.arm_traitlist) > 0:
if not 'traits' in self.output:
self.output['traits'] = []

View file

@ -5,6 +5,7 @@ import importlib
from bpy.app.handlers import persistent
import arm.utils
import arm.props as props
import arm.make as make
import arm.make_state as state
import arm.api
@ -13,6 +14,7 @@ def on_depsgraph_update_post(self):
if state.proc_build != None:
return
# Recache
depsgraph = bpy.context.depsgraph
for update in depsgraph.updates:
uid = update.id
@ -31,6 +33,33 @@ def on_depsgraph_update_post(self):
elif isinstance(uid, bpy.types.Material) and uid.name in bpy.data.materials:
bpy.data.materials[uid.name].arm_cached = False
# Send last operator to Krom
wrd = bpy.data.worlds['Arm']
if state.proc_play != None and \
state.target == 'krom' and \
wrd.arm_live_patch:
ops = bpy.context.window_manager.operators
if len(ops) > 0 and ops[-1] != None:
send_operator(ops[-1])
def send_operator(op):
if hasattr(bpy.context, 'object') and bpy.context.object != None:
obj = bpy.context.object.name
if op.name == 'Move':
vec = bpy.context.object.location
js = 'var o = iron.Scene.active.getChild("' + obj + '"); o.transform.loc.set(' + str(vec[0]) + ', ' + str(vec[1]) + ', ' + str(vec[2]) + '); o.transform.dirty = true;'
make.write_patch(js)
elif op.name == 'Resize':
vec = bpy.context.object.scale
js = 'var o = iron.Scene.active.getChild("' + obj + '"); o.transform.scale.set(' + str(vec[0]) + ', ' + str(vec[1]) + ', ' + str(vec[2]) + '); o.transform.dirty = true;'
make.write_patch(js)
elif op.name == 'Rotate':
vec = bpy.context.object.rotation_euler.to_quaternion()
js = 'var o = iron.Scene.active.getChild("' + obj + '"); o.transform.rot.set(' + str(vec[1]) + ', ' + str(vec[2]) + ', ' + str(vec[3]) + ' ,' + str(vec[0]) + '); o.transform.dirty = true;'
make.write_patch(js)
else: # Rebuild
make.patch()
def always():
# Force ui redraw
if state.redraw_ui and context_screen != None:

View file

@ -197,11 +197,11 @@ def export_data(fp, sdk_path):
# 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_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_viewport, state.is_publish)
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
@ -240,7 +240,7 @@ def compile(assets_only=False):
cmd.append('-g')
cmd.append(state.export_gapi)
if arm.utils.get_legacy_shaders() and not state.is_viewport:
if arm.utils.get_legacy_shaders():
cmd.append('--shaderversion')
cmd.append('110')
elif 'android' in state.target or 'ios' in state.target or 'html5' in state.target:
@ -269,7 +269,7 @@ def compile(assets_only=False):
compilation_server = False
cmd.append('--to')
if (kha_target_name == 'krom' and not state.is_viewport and not state.is_publish) or (kha_target_name == 'html5' and not state.is_publish):
if (kha_target_name == 'krom' and not state.is_publish) or (kha_target_name == 'html5' and not state.is_publish):
cmd.append(arm.utils.build_dir() + '/debug')
# Start compilation server
if kha_target_name == 'krom' and arm.utils.get_compilation_server() and not assets_only:
@ -286,30 +286,13 @@ def compile(assets_only=False):
print("Using project from " + arm.utils.get_fp())
state.proc_build = run_proc(cmd, assets_done if compilation_server else build_done)
def build_viewport():
if state.proc_build != None:
return
if not arm.utils.check_saved(None):
return
if not arm.utils.check_sdkpath(None):
return
arm.utils.check_default_props()
assets.invalidate_enabled = False
play(is_viewport=True)
assets.invalidate_enabled = True
def build(target, is_play=False, is_publish=False, is_viewport=False, is_export=False):
def build(target, is_play=False, is_publish=False, is_export=False):
global profile_time
profile_time = time.time()
state.target = target
state.is_play = is_play
state.is_publish = is_publish
state.is_viewport = is_viewport
state.is_export = is_export
# Save blend
@ -421,40 +404,74 @@ def build_done():
else:
log.print_info('Build failed, check console')
def runtime_to_target(is_viewport):
def patch():
if state.proc_build != None:
return
assets.invalidate_enabled = False
fp = arm.utils.get_fp()
os.chdir(fp)
asset_path = arm.utils.get_fp_build() + '/compiled/Assets/' + arm.utils.safestr(bpy.context.scene.name) + '.arm'
exporter.execute(bpy.context, asset_path, scene=bpy.context.scene)
if not os.path.isdir(arm.utils.build_dir() + '/compiled/Shaders/std'):
raw_shaders_path = arm.utils.get_sdk_path() + '/armory/Shaders/'
shutil.copytree(raw_shaders_path + 'std', arm.utils.build_dir() + '/compiled/Shaders/std')
node_path = arm.utils.get_node_path()
khamake_path = arm.utils.get_khamake_path()
cmd = [node_path, khamake_path, 'krom']
cmd.append('--shaderversion')
cmd.append('330')
cmd.append('--parallelAssetConversion')
cmd.append('4')
cmd.append('--to')
cmd.append(arm.utils.build_dir() + '/debug')
cmd.append('--nohaxe')
cmd.append('--noproject')
assets.invalidate_enabled = True
state.proc_build = run_proc(cmd, patch_done)
def patch_done():
js = 'iron.Scene.patch();'
write_patch(js)
state.proc_build = None
patch_id = 0
def write_patch(js):
global patch_id
with open(arm.utils.get_fp_build() + '/debug/krom/krom.patch', 'w') as f:
patch_id += 1
f.write(str(patch_id) + '\n')
f.write(js)
def runtime_to_target():
wrd = bpy.data.worlds['Arm']
if is_viewport or wrd.arm_runtime == 'Krom':
if wrd.arm_runtime == 'Krom':
return 'krom'
else:
return 'html5'
def get_khajs_path(is_viewport, target):
if is_viewport:
return arm.utils.build_dir() + '/krom/krom.js'
elif target == 'krom':
def get_khajs_path(target):
if target == 'krom':
return arm.utils.build_dir() + '/debug/krom/krom.js'
else: # Browser
return arm.utils.build_dir() + '/debug/html5/kha.js'
def play(is_viewport):
def play():
global scripts_mtime
global code_parsed
wrd = bpy.data.worlds['Arm']
log.clear()
build(target=runtime_to_target(is_viewport), is_play=True, is_viewport=is_viewport)
build(target=runtime_to_target(), is_play=True)
khajs_path = get_khajs_path(is_viewport, state.target)
khajs_path = get_khajs_path(state.target)
if not wrd.arm_cache_build or \
not os.path.isfile(khajs_path) or \
assets.khafile_defs_last != assets.khafile_defs or \
state.last_target != state.target or \
state.last_is_viewport != state.is_viewport:
state.last_target != state.target:
wrd.arm_recompile = True
state.last_target = state.target
state.last_is_viewport = state.is_viewport
# Trait sources modified
state.mod_scripts = []
@ -492,6 +509,8 @@ def build_success():
html5_app_path = 'http://localhost:8040/' + arm.utils.build_dir() + '/debug/html5'
webbrowser.open(html5_app_path)
elif wrd.arm_runtime == 'Krom':
if wrd.arm_live_patch:
open(arm.utils.get_fp_build() + '/debug/krom/krom.patch', 'w').close()
if arm.utils.get_os() == 'win':
bin_ext = '' if state.export_gapi == 'direct3d11' else '_' + state.export_gapi
else:

View file

@ -87,7 +87,7 @@ def add_world_defs():
if rpdat.arm_voxelgi_occ == 0.0:
wrd.world_defs += '_VoxelAONoTrace'
if arm.utils.get_legacy_shaders() and not state.is_viewport:
if arm.utils.get_legacy_shaders():
wrd.world_defs += '_Legacy'
# Light defines

View file

@ -2,7 +2,6 @@ redraw_ui = False
target = 'krom'
last_target = 'krom'
export_gapi = ''
last_is_viewport = False
last_resx = 0
last_resy = 0
last_scene = ''
@ -10,7 +9,6 @@ last_world_defs = ''
proc_play = None
proc_build = None
mod_scripts = []
is_viewport = False
is_export = False
is_play = False
is_publish = False

View file

@ -73,11 +73,10 @@ def init_properties():
bpy.types.World.arm_lod_gen_levels = IntProperty(name="Levels", description="Number of levels to generate", default=3, min=1)
bpy.types.World.arm_lod_gen_ratio = FloatProperty(name="Decimate Ratio", description="Decimate ratio", default=0.8)
bpy.types.World.arm_cache_build = BoolProperty(name="Cache Build", description="Cache build files to speed up compilation", default=True)
bpy.types.World.arm_live_patch = BoolProperty(name="Live Patch", description="Live patching for Krom", default=False)
bpy.types.World.arm_play_camera = EnumProperty(
items=[('Scene', 'Scene', 'Scene'),
('Viewport', 'Viewport', 'Viewport'),
# ('Viewport Shared', 'Shared', 'Viewport Shared')
],
('Viewport', 'Viewport', 'Viewport')],
name="Camera", description="Viewport camera", default='Scene', update=assets.invalidate_compiler_cache)
bpy.types.World.arm_debug_console = BoolProperty(name="Debug Console", description="Show inspector in player and enable debug draw", default=False, update=assets.invalidate_shader_cache)
bpy.types.World.arm_runtime = EnumProperty(

View file

@ -339,7 +339,8 @@ class ArmProjectFlagsPanel(bpy.types.Panel):
layout.use_property_decorate = False
wrd = bpy.data.worlds['Arm']
layout.prop(wrd, 'arm_debug_console')
layout.prop(wrd, 'arm_cache_build')
layout.prop(wrd, 'arm_cache_build')
layout.prop(wrd, 'arm_live_patch')
layout.prop(wrd, 'arm_stream_scene')
layout.prop(wrd, 'arm_batch_meshes')
layout.prop(wrd, 'arm_batch_materials')
@ -497,7 +498,7 @@ class ArmoryPlayButton(bpy.types.Operator):
arm.utils.check_default_props()
assets.invalidate_enabled = False
make.play(is_viewport=False)
make.play()
assets.invalidate_enabled = True
return{'FINISHED'}

View file

@ -85,8 +85,6 @@ def get_os():
def get_gapi():
wrd = bpy.data.worlds['Arm']
if state.is_viewport:
return 'opengl'
if state.is_export:
item = wrd.arm_exporterlist[wrd.arm_exporterlist_index]
return getattr(item, target_to_gapi(item.arm_project_target))

View file

@ -38,7 +38,7 @@ def remove_readonly(func, path, excinfo):
os.chmod(path, stat.S_IWRITE)
func(path)
def write_khafilejs(is_play, export_physics, export_navigation, export_ui, is_publish, enable_dce, is_viewport, import_traits, import_logicnodes):
def write_khafilejs(is_play, export_physics, export_navigation, export_ui, is_publish, enable_dce, import_traits, import_logicnodes):
sdk_path = arm.utils.get_sdk_path()
rel_path = arm.utils.get_relative_paths() # Convert absolute paths to relative
wrd = bpy.data.worlds['Arm']
@ -142,8 +142,10 @@ project.addSources('Sources');
if enable_dce:
f.write("project.addParameter('-dce full');\n")
if is_viewport or wrd.arm_debug_console:
if wrd.arm_debug_console or wrd.arm_live_patch:
import_traits.append('armory.trait.internal.Bridge')
if wrd.arm_live_patch:
assets.add_khafile_def('arm_patch')
import_traits = list(set(import_traits))
for i in range(0, len(import_traits)):
@ -327,15 +329,13 @@ def write_config(resx, resy):
with open(p + '/config.arm', 'w') as f:
f.write(json.dumps(output, sort_keys=True, indent=4))
def write_mainhx(scene_name, resx, resy, is_play, is_viewport, is_publish):
def write_mainhx(scene_name, resx, resy, is_play, is_publish):
wrd = bpy.data.worlds['Arm']
rpdat = arm.utils.get_rp()
scene_ext = '.zip' if (wrd.arm_asset_compression and is_publish) else ''
if scene_ext == '' and not wrd.arm_minimize:
scene_ext = '.json'
winmode = get_winmode(wrd.arm_winmode)
if is_viewport:
winmode = 0
# Detect custom render path
pathpack = 'armory'
if os.path.isfile(arm.utils.get_fp() + '/Sources/' + wrd.arm_project_package + '/renderpath/RenderPathCreator.hx'):