Faster build times
This commit is contained in:
parent
14d4ad1b96
commit
ccf195cdbd
|
@ -1,22 +1,29 @@
|
|||
import armutils
|
||||
import shutil
|
||||
import os
|
||||
import bpy
|
||||
|
||||
assets = []
|
||||
khafile_defs = []
|
||||
khafile_defs_last = []
|
||||
embedded_data = []
|
||||
shaders = []
|
||||
shaders_last = []
|
||||
shader_datas = []
|
||||
|
||||
def reset():
|
||||
global assets
|
||||
global khafile_defs
|
||||
global khafile_defs_last
|
||||
global embedded_data
|
||||
global shaders
|
||||
global shaders_last
|
||||
global shader_datas
|
||||
assets = []
|
||||
khafile_defs_last = khafile_defs
|
||||
khafile_defs = []
|
||||
embedded_data = []
|
||||
shaders_last = shaders
|
||||
shaders = []
|
||||
shader_datas = []
|
||||
|
||||
|
@ -27,9 +34,14 @@ def add(file):
|
|||
|
||||
def add_khafile_def(d):
|
||||
global khafile_defs
|
||||
global khafile_defs_last
|
||||
if d not in khafile_defs:
|
||||
khafile_defs.append(d)
|
||||
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
if not wrd.arm_recompile_trigger and d not in khafile_defs_last:
|
||||
wrd.arm_recompile_trigger = True
|
||||
|
||||
def add_embedded_data(file):
|
||||
global embedded_data
|
||||
if file not in embedded_data:
|
||||
|
@ -37,9 +49,14 @@ def add_embedded_data(file):
|
|||
|
||||
def add_shader(file):
|
||||
global shaders
|
||||
global shaders_last
|
||||
if file not in shaders:
|
||||
shaders.append(file)
|
||||
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
if not wrd.arm_recompile_trigger and file not in shaders_last:
|
||||
wrd.arm_recompile_trigger = True
|
||||
|
||||
def add_shader_data(file):
|
||||
global shader_datas
|
||||
if file not in shader_datas:
|
||||
|
|
|
@ -57,14 +57,14 @@ def on_scene_update_post(context):
|
|||
break
|
||||
|
||||
# Auto patch on every operator change
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
if state.krom_running and \
|
||||
bpy.data.worlds['Arm'].arm_play_live_patch and \
|
||||
bpy.data.worlds['Arm'].arm_play_auto_build and \
|
||||
wrd.arm_play_live_patch and \
|
||||
wrd.arm_play_auto_build and \
|
||||
operators_changed:
|
||||
# Otherwise rebuild scene
|
||||
if bridge.send_operator(last_operator) == False:
|
||||
make.patch_project()
|
||||
make.compile_project(target_name="krom", patch=True)
|
||||
make.play_project(in_viewport=True)
|
||||
|
||||
# Use frame rate for update frequency for now
|
||||
if time.time() - last_time >= (1 / bpy.context.scene.render.fps):
|
||||
|
@ -131,6 +131,9 @@ def on_scene_update_post(context):
|
|||
obj.data.mesh_cached = False
|
||||
|
||||
if obj.active_material != None and obj.active_material.is_updated:
|
||||
if obj.active_material.lock_cache == True: # is_cached was set to true
|
||||
obj.active_material.lock_cache = False
|
||||
else:
|
||||
obj.active_material.is_cached = False
|
||||
|
||||
@persistent
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import os
|
||||
import glob
|
||||
import time
|
||||
import shutil
|
||||
import bpy
|
||||
import json
|
||||
|
@ -22,6 +24,7 @@ import lib.make_variants
|
|||
import lib.server
|
||||
|
||||
exporter = ArmoryExporter()
|
||||
scripts_mtime = 0 # Monitor source changes
|
||||
|
||||
def compile_shader(raw_shaders_path, shader_name, defs):
|
||||
os.chdir(raw_shaders_path + './' + shader_name)
|
||||
|
@ -161,7 +164,7 @@ def compile_project(target_name=None, is_publish=False, watch=False, patch=False
|
|||
cmd.append('opengl2')
|
||||
|
||||
if kha_target_name == 'krom':
|
||||
if state.in_viewport or patch:
|
||||
if state.in_viewport:
|
||||
if armutils.glsl_version() >= 330:
|
||||
cmd.append('--shaderversion')
|
||||
cmd.append('330')
|
||||
|
@ -178,7 +181,7 @@ def compile_project(target_name=None, is_publish=False, watch=False, patch=False
|
|||
for s in bpy.data.texts[cmd_text].as_string().split(' '):
|
||||
cmd.append(s)
|
||||
|
||||
if state.krom_running:
|
||||
if patch:
|
||||
if state.compileproc == None: # Already compiling
|
||||
# Patch running game, stay silent, disable krafix and haxe
|
||||
# cmd.append('--silent')
|
||||
|
@ -189,22 +192,22 @@ def compile_project(target_name=None, is_publish=False, watch=False, patch=False
|
|||
cmd.append('""')
|
||||
# Khamake throws error when krafix is not found, hide for now
|
||||
state.compileproc = subprocess.Popen(cmd, stderr=subprocess.PIPE)
|
||||
threading.Timer(0.1, watch_patch).start()
|
||||
if state.playproc == None:
|
||||
if state.in_viewport:
|
||||
mode = 'play_viewport'
|
||||
else:
|
||||
mode = 'play'
|
||||
else:
|
||||
mode = 'build'
|
||||
threading.Timer(0.1, watch_patch, [mode]).start()
|
||||
return state.compileproc
|
||||
elif watch == True:
|
||||
elif watch:
|
||||
state.compileproc = subprocess.Popen(cmd)
|
||||
threading.Timer(0.1, watch_compile, ['build']).start()
|
||||
return state.compileproc
|
||||
else:
|
||||
return subprocess.Popen(cmd)
|
||||
|
||||
# For live patching
|
||||
def patch_project():
|
||||
sdk_path = armutils.get_sdk_path()
|
||||
fp = armutils.get_fp()
|
||||
os.chdir(fp)
|
||||
export_data(fp, sdk_path, is_play=True)
|
||||
|
||||
def build_project(is_play=False, is_publish=False, in_viewport=False, target=None):
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
|
||||
|
@ -303,17 +306,20 @@ def watch_compile(mode):
|
|||
state.compileproc = None
|
||||
state.compileproc_finished = True
|
||||
if result == 0:
|
||||
bpy.data.worlds['Arm'].arm_recompile = False
|
||||
state.compileproc_success = True
|
||||
on_compiled(mode)
|
||||
else:
|
||||
state.compileproc_success = False
|
||||
log.print_info('Build failed, check console')
|
||||
|
||||
def watch_patch():
|
||||
def watch_patch(mode):
|
||||
state.compileproc.wait()
|
||||
log.print_progress(100)
|
||||
# result = state.compileproc.poll()
|
||||
state.compileproc = None
|
||||
state.compileproc_finished = True
|
||||
on_compiled(mode)
|
||||
|
||||
def runtime_to_target(in_viewport):
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
|
@ -324,11 +330,20 @@ def runtime_to_target(in_viewport):
|
|||
else:
|
||||
return 'html5'
|
||||
|
||||
def play_project(self, in_viewport):
|
||||
def get_khajs_path(in_viewport, target):
|
||||
if in_viewport:
|
||||
return 'build/krom/krom.js'
|
||||
elif target == 'krom':
|
||||
return 'build/window/krom/krom.js'
|
||||
else: # browser, electron
|
||||
return 'build/html5/kha.js'
|
||||
|
||||
def play_project(in_viewport):
|
||||
global scripts_mtime
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
|
||||
# Store area
|
||||
if armutils.with_krom() and in_viewport and bpy.context.area.type == 'VIEW_3D':
|
||||
if armutils.with_krom() and in_viewport and bpy.context.area != None and bpy.context.area.type == 'VIEW_3D':
|
||||
state.play_area = bpy.context.area
|
||||
|
||||
state.target = runtime_to_target(in_viewport)
|
||||
|
@ -337,7 +352,36 @@ def play_project(self, in_viewport):
|
|||
build_project(is_play=True, in_viewport=in_viewport, target=state.target)
|
||||
state.in_viewport = in_viewport
|
||||
|
||||
# Compile
|
||||
khajs_path = get_khajs_path(in_viewport, state.target)
|
||||
if wrd.arm_recompile or \
|
||||
wrd.arm_recompile_trigger or \
|
||||
not wrd.arm_cache_compiler or \
|
||||
not wrd.arm_cache_shaders or \
|
||||
not os.path.isfile(khajs_path) or \
|
||||
state.last_target != state.target:
|
||||
wrd.arm_recompile = True
|
||||
|
||||
wrd.arm_recompile_trigger = False
|
||||
state.last_target = state.target
|
||||
|
||||
# Trait sources modified
|
||||
script_path = armutils.get_fp() + '/Sources/' + wrd.arm_project_package
|
||||
if os.path.isdir(script_path):
|
||||
for fn in glob.iglob(os.path.join(script_path, '**', '*.hx'), recursive=True):
|
||||
mtime = os.path.getmtime(fn)
|
||||
if scripts_mtime < mtime:
|
||||
scripts_mtime = mtime
|
||||
wrd.arm_recompile = True
|
||||
|
||||
# New compile requred - traits or materials changed
|
||||
if wrd.arm_recompile:
|
||||
|
||||
# Unable to live-patch, stop player
|
||||
if state.krom_running:
|
||||
bpy.ops.arm.space_stop()
|
||||
# play_project(in_viewport=True) # Restart
|
||||
return
|
||||
|
||||
mode = 'play'
|
||||
if state.target == 'native':
|
||||
state.compileproc = compile_project(target_name='--run')
|
||||
|
@ -350,8 +394,9 @@ def play_project(self, in_viewport):
|
|||
write_data.write_electronjs(w, h)
|
||||
write_data.write_indexhtml(w, h)
|
||||
state.compileproc = compile_project(target_name='html5')
|
||||
|
||||
threading.Timer(0.1, watch_compile, [mode]).start()
|
||||
else: # kha.js up to date
|
||||
compile_project(target_name=state.target, patch=True)
|
||||
|
||||
def on_compiled(mode): # build, play, play_viewport, publish
|
||||
log.clear()
|
||||
|
@ -433,21 +478,10 @@ def clean_project():
|
|||
os.chdir(armutils.get_fp())
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
|
||||
# Preserve envmaps
|
||||
# if wrd.arm_cache_envmaps:
|
||||
# envmaps_path = 'build/compiled/Assets/envmaps'
|
||||
# if os.path.isdir(envmaps_path):
|
||||
# shutil.move(envmaps_path, '.')
|
||||
|
||||
# Remove build and compiled data
|
||||
if os.path.isdir('build'):
|
||||
shutil.rmtree('build')
|
||||
|
||||
# Move envmaps back
|
||||
# if wrd.arm_cache_envmaps and os.path.isdir('envmaps'):
|
||||
# os.makedirs('build/compiled/Assets')
|
||||
# shutil.move('envmaps', 'build/compiled/Assets')
|
||||
|
||||
# Remove compiled nodes
|
||||
nodes_path = 'Sources/' + wrd.arm_project_package.replace('.', '/') + '/node/'
|
||||
if os.path.isdir(nodes_path):
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
target = 'krom'
|
||||
last_target = 'krom'
|
||||
in_viewport = False
|
||||
playproc = None
|
||||
compileproc = None
|
||||
|
|
|
@ -32,9 +32,17 @@ def invalidate_mesh_cache(self, context):
|
|||
return
|
||||
context.object.data.mesh_cached = False
|
||||
|
||||
def update_mat_cache(self, context):
|
||||
if self.is_cached == True:
|
||||
self.lock_cache = True
|
||||
else:
|
||||
bpy.data.worlds['Arm'].arm_recompile_trigger = True
|
||||
|
||||
arm_ver = '17.01.1'
|
||||
def init_properties():
|
||||
global arm_ver
|
||||
bpy.types.World.arm_recompile = bpy.props.BoolProperty(name="Recompile", description="Recompile sources on next play", default=True)
|
||||
bpy.types.World.arm_recompile_trigger = bpy.props.BoolProperty(name="Recompile Trigger", description="Force upcoming recomilation", default=False)
|
||||
bpy.types.World.arm_progress = bpy.props.FloatProperty(name="Progress", description="Current build progress", default=100.0, min=0.0, max=100.0, soft_min=0.0, soft_max=100.0, subtype='PERCENTAGE', get=log.get_progress)
|
||||
bpy.types.World.arm_version = StringProperty(name="Version", description="Armory SDK version", default=arm_ver)
|
||||
target_prop = EnumProperty(
|
||||
|
@ -85,6 +93,7 @@ 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_shaders = BoolProperty(name="Cache Shaders", description="Do not rebuild existing shaders", default=True, update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.arm_cache_compiler = BoolProperty(name="Cache Compiler", description="Only recompile sources when required", default=True)
|
||||
bpy.types.World.arm_gpu_processing = BoolProperty(name="GPU Processing", description="Utilize GPU for asset pre-processing at build time", default=True)
|
||||
bpy.types.World.arm_play_live_patch = BoolProperty(name="Live Patching", description="Sync running player data to Blender", default=True)
|
||||
bpy.types.World.arm_play_auto_build = BoolProperty(name="Auto Build", description="Rebuild scene on operator changes", default=True)
|
||||
|
@ -336,7 +345,8 @@ def init_properties():
|
|||
bpy.types.World.voxelgi = bpy.props.BoolProperty(name="VGI", description="Voxel-based Global Illumination", default=False, update=assets.invalidate_shader_cache)
|
||||
bpy.types.World.voxelgi_dimensions = bpy.props.FloatVectorProperty(name="Dimensions", description="3D texture size", size=3, default=[128, 128, 128], update=assets.invalidate_shader_cache)
|
||||
# For material
|
||||
bpy.types.Material.is_cached = bpy.props.BoolProperty(name="Material Cached", description="No need to reexport material data", default=False)
|
||||
bpy.types.Material.is_cached = bpy.props.BoolProperty(name="Material Cached", description="No need to reexport material data", default=False, update=update_mat_cache)
|
||||
bpy.types.Material.lock_cache = bpy.props.BoolProperty(name="Lock Material Cache", description="Prevent is_cached from updating", default=False)
|
||||
bpy.types.Material.cast_shadow = bpy.props.BoolProperty(name="Cast Shadow", default=True)
|
||||
bpy.types.Material.receive_shadow = bpy.props.BoolProperty(name="Receive Shadow", default=True)
|
||||
bpy.types.Material.override_shader = bpy.props.BoolProperty(name="Override Shader", default=False)
|
||||
|
|
|
@ -382,6 +382,7 @@ class ArmoryPlayerPanel(bpy.types.Panel):
|
|||
layout.operator("arm.render", icon="RENDER_STILL")
|
||||
|
||||
layout.prop(wrd, 'arm_cache_shaders')
|
||||
layout.prop(wrd, 'arm_cache_compiler')
|
||||
layout.prop(wrd, 'arm_gpu_processing')
|
||||
layout.prop(wrd, 'arm_minimize')
|
||||
layout.prop(wrd, 'arm_optimize_mesh')
|
||||
|
@ -444,7 +445,7 @@ class ArmoryPlayButton(bpy.types.Operator):
|
|||
nodes_renderpath.check_default()
|
||||
|
||||
assets.invalidate_enabled = False
|
||||
make.play_project(self, False)
|
||||
make.play_project(False)
|
||||
assets.invalidate_enabled = True
|
||||
return{'FINISHED'}
|
||||
|
||||
|
@ -482,10 +483,9 @@ class ArmoryPlayInViewportButton(bpy.types.Operator):
|
|||
if space.viewport_shade == 'RENDERED':
|
||||
space.viewport_shade = 'SOLID'
|
||||
break
|
||||
make.play_project(self, True)
|
||||
make.play_project(True)
|
||||
else:
|
||||
make.patch_project()
|
||||
make.compile_project()
|
||||
make.play_project(True)
|
||||
assets.invalidate_enabled = True
|
||||
return{'FINISHED'}
|
||||
|
||||
|
@ -527,8 +527,7 @@ class ArmoryPatchButton(bpy.types.Operator):
|
|||
|
||||
def execute(self, context):
|
||||
assets.invalidate_enabled = False
|
||||
make.patch_project()
|
||||
make.compile_project()
|
||||
make.play_project(True)
|
||||
assets.invalidate_enabled = True
|
||||
return{'FINISHED'}
|
||||
|
||||
|
|
Loading…
Reference in a new issue