def on_compiled(mode): # build, play, play_viewport, publish log.clear() sdk_path = armutils.get_sdk_path() wrd = bpy.data.worlds['Arm'] # Print info if mode == 'publish': target_name = make_utils.get_kha_target(wrd.arm_project_target) print('Project published') files_path = armutils.get_fp() + '/build/' + target_name if target_name == 'html5': print('HTML5 files are located in ' + files_path) elif target_name == 'ios' or target_name == 'osx': # TODO: to macos print('XCode project files are located in ' + files_path + '-build') elif target_name == 'windows': print('VisualStudio 2015 project files are located in ' + files_path + '-build') elif target_name == 'android-native': print('Android Studio project files are located in ' + files_path + '-build/' + wrd.arm_project_name) else: print('Makefiles are located in ' + files_path + '-build') return # Launch project in new window elif mode =='play': if wrd.arm_play_runtime == 'Electron': electron_app_path = './build/electron.js' if armutils.get_os() == 'win': electron_path = sdk_path + 'win32/Kode Studio.exe' elif armutils.get_os() == 'mac': electron_path = sdk_path + 'Kode Studio.app/Contents/MacOS/Electron' else: electron_path = sdk_path + 'linux64/kodestudio' state.playproc = subprocess.Popen([electron_path, '--chromedebug', '--remote-debugging-port=9222', '--enable-logging', electron_app_path], stderr=subprocess.PIPE) watch_play() elif wrd.arm_play_runtime == 'Browser': # Start server os.chdir(armutils.get_fp()) t = threading.Thread(name='localserver', target=lib.server.run) t.daemon = True t.start() html5_app_path = 'http://localhost:8040/build/html5' webbrowser.open(html5_app_path) elif wrd.arm_play_runtime == 'Krom': if armutils.get_os() == 'win': krom_location = sdk_path + '/win32/Krom/win32' krom_path = krom_location + '/Krom.exe' elif armutils.get_os() == 'mac': krom_location = sdk_path + '/Kode Studio.app/Contents/Krom/macos/Krom.app/Contents/MacOS' krom_path = krom_location + '/Krom' else: krom_location = sdk_path + '/linux64/Krom/linux' krom_path = krom_location + '/Krom' os.chdir(krom_location) state.playproc = subprocess.Popen([krom_path, armutils.get_fp() + '/build/window/krom', armutils.get_fp() + '/build/window/krom-resources'], stderr=subprocess.PIPE) watch_play()
def on_compiled(mode): # build, play, play_viewport, publish log.clear() sdk_path = armutils.get_sdk_path() # Print info if mode == 'publish': target_name = make_utils.get_kha_target(bpy.data.worlds['Arm'].arm_project_target) print('Project published') files_path = armutils.get_fp() + '/build/' + target_name if target_name == 'html5': print('HTML5 files are located in ' + files_path) elif target_name == 'ios' or target_name == 'osx': # TODO: to macos print('XCode project files are located in ' + files_path + '-build') elif target_name == 'windows': print('VisualStudio 2015 project files are located in ' + files_path + '-build') elif target_name == 'android-native': print('Android Studio project files are located in ' + files_path + '-build') else: print('Makefiles are located in ' + files_path + '-build') return # Launch project in new window elif mode =='play': wrd = bpy.data.worlds['Arm'] if wrd.arm_play_runtime == 'Electron': electron_app_path = './build/electron.js' if armutils.get_os() == 'win': electron_path = sdk_path + 'win32/Kode Studio.exe' elif armutils.get_os() == 'mac': electron_path = sdk_path + 'Kode Studio.app/Contents/MacOS/Electron' else: electron_path = sdk_path + 'linux64/kodestudio' state.playproc = subprocess.Popen([electron_path, '--chromedebug', '--remote-debugging-port=9222', '--enable-logging', electron_app_path], stderr=subprocess.PIPE) watch_play() elif wrd.arm_play_runtime == 'Browser': # Start server os.chdir(armutils.get_fp()) t = threading.Thread(name='localserver', target=lib.server.run) t.daemon = True t.start() html5_app_path = 'http://localhost:8040/build/html5' webbrowser.open(html5_app_path) elif wrd.arm_play_runtime == 'Krom': if armutils.get_os() == 'win': krom_location = sdk_path + '/win32/Krom/win32' krom_path = krom_location + '/Krom.exe' elif armutils.get_os() == 'mac': krom_location = sdk_path + '/Kode Studio.app/Contents/Krom/macos/Krom.app/Contents/MacOS' krom_path = krom_location + '/Krom' else: krom_location = sdk_path + '/linux64/Krom/linux' krom_path = krom_location + '/Krom' os.chdir(krom_location) state.playproc = subprocess.Popen([krom_path, armutils.get_fp() + '/build/window/krom', armutils.get_fp() + '/build/window/krom-resources'], stderr=subprocess.PIPE) watch_play()
def kode_studio(): sdk_path = armutils.get_sdk_path() project_path = armutils.get_fp() if armutils.get_os() == 'win': kode_path = sdk_path + '/win32/Kode Studio.exe' subprocess.Popen([kode_path, armutils.get_fp()]) elif armutils.get_os() == 'mac': kode_path = '"' + sdk_path + '/Kode Studio.app/Contents/MacOS/Electron"' subprocess.Popen([kode_path + ' ' + armutils.get_fp()], shell=True) else: kode_path = sdk_path + '/linux64/kodestudio' subprocess.Popen([kode_path, armutils.get_fp()])
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): shutil.rmtree(nodes_path) # Remove khafile/korefile/Main.hx if os.path.isfile('khafile.js'): os.remove('khafile.js') if os.path.isfile('korefile.js'): os.remove('korefile.js') if os.path.isfile('Sources/Main.hx'): os.remove('Sources/Main.hx') print('Project cleaned')
def register(): bpy.app.handlers.scene_update_post.append(on_scene_update_post) bpy.app.handlers.save_pre.append(on_save_pre) bpy.app.handlers.load_post.append(on_load_post) # On windows, on_load_post is not called when opening .blend file from explorer if armutils.get_os() == 'win' and armutils.get_fp() != '': on_load_post(None)
def execute(self, context): sdk_path = armutils.get_sdk_path() project_path = armutils.get_fp() pkg = bpy.data.worlds['Arm'].arm_project_package item = context.object.my_traitlist[context.object.traitlist_index] source_hx_path = sdk_path + '/armory/Sources/armory/trait/' + item.class_name_prop + '.hx' target_hx_path = project_path + '/Sources/' + pkg + '/' + item.class_name_prop + '.hx' if not os.path.isfile(target_hx_path): # Rewrite package and copy sf = open(source_hx_path) sf.readline() tf = open(target_hx_path, 'w') tf.write('package ' + pkg + ';\n') shutil.copyfileobj(sf, tf) sf.close() tf.close() armutils.fetch_script_names() # From bundled to script item.type_prop = 'Haxe Script' # Edit in Kode Studio bpy.ops.arm.edit_script('EXEC_DEFAULT') return {'FINISHED'}
def parse_operator(text): if text == None: return cmd = text.split('|') # Reflect commands from Armory player in Blender if cmd[0] == '__arm': if cmd[1] == 'quit': bpy.ops.arm.space_stop('EXEC_DEFAULT') elif cmd[1] == 'setx': bpy.context.scene.objects[cmd[2]].location.x = float(cmd[3]) elif cmd[1] == 'select': if hasattr(bpy.context, 'object') and bpy.context.object != None: bpy.context.object.select = False bpy.context.scene.objects[cmd[2]].select = True bpy.context.scene.objects.active = bpy.context.scene.objects[ cmd[2]] elif cmd[1] == 'render': import numpy data = numpy.fromfile(armutils.get_fp() + '/build/html5/render.bin', dtype=numpy.uint8) data = data.astype(float) data = numpy.divide(data, 255) image = bpy.data.images.new("Render Result", width=int(cmd[2]), height=int(cmd[3])) image.pixels = data return
def invalidate_shader_cache(self, context): # compiled.glsl changed, recompile all shaders next time global invalidate_enabled if invalidate_enabled == False: return fp = armutils.get_fp() if os.path.isdir(fp + '/build/compiled/ShaderDatas'): shutil.rmtree(fp + '/build/compiled/ShaderDatas')
def execute(self, context): project_path = armutils.get_fp() item = context.object.my_traitlist[context.object.traitlist_index] hx_path = project_path + '/Sources/' + bpy.data.worlds['Arm'].arm_project_package + '/' + item.class_name_prop + '.hx' sdk_path = armutils.get_sdk_path() if armutils.get_os() == 'win': kode_path = sdk_path + '/win32/Kode Studio.exe' subprocess.Popen([kode_path, armutils.get_fp(), hx_path]) elif armutils.get_os() == 'mac': kode_path = '"' + sdk_path + '/Kode Studio.app/Contents/MacOS/Electron"' subprocess.Popen([kode_path + ' ' + armutils.get_fp() + ' ' + hx_path], shell=True) else: kode_path = sdk_path + '/linux64/kodestudio' subprocess.Popen([kode_path, armutils.get_fp(), hx_path]) return{'FINISHED'}
def invalidate_compiled_data(self, context): global invalidate_enabled if invalidate_enabled == False: return fp = armutils.get_fp() if os.path.isdir(fp + '/build/compiled/Assets'): shutil.rmtree(fp + '/build/compiled/Assets') if os.path.isdir(fp + '/build/compiled/ShaderDatas'): shutil.rmtree(fp + '/build/compiled/ShaderDatas')
def write_shader(shader, ext, rpass, keep_cache=True): if shader == None: return shader_rel_path = mat_state.rel_path + '/' + armutils.safe_source_name( mat_state.material.name) + '_' + rpass + '.' + ext + '.glsl' shader_path = armutils.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 invalidate_shader_cache(self, context): # compiled.glsl changed, recompile all shaders next time global invalidate_enabled if invalidate_enabled == False: return fp = armutils.get_fp() if os.path.isdir(fp + '/build/compiled/ShaderDatas'): shutil.rmtree(fp + '/build/compiled/ShaderDatas') if os.path.isdir(fp + '/build/compiled/ShaderRaws'): shutil.rmtree(fp + '/build/compiled/ShaderRaws')
def execute(self, context): project_path = armutils.get_fp() item = context.object.my_traitlist[context.object.traitlist_index] hx_path = project_path + '/Sources/' + bpy.data.worlds[ 'Arm'].arm_project_package + '/' + item.class_name_prop + '.hx' sdk_path = armutils.get_sdk_path() if armutils.get_os() == 'win': kode_path = sdk_path + '/win32/Kode Studio.exe' subprocess.Popen([kode_path, armutils.get_fp(), hx_path]) elif armutils.get_os() == 'mac': kode_path = '"' + sdk_path + '/Kode Studio.app/Contents/MacOS/Electron"' subprocess.Popen( [kode_path + ' ' + armutils.get_fp() + ' ' + hx_path], shell=True) else: kode_path = sdk_path + '/linux64/kodestudio' subprocess.Popen([kode_path, armutils.get_fp(), hx_path]) return {'FINISHED'}
def compile_shader(raw_shaders_path, shader_name, defs): os.chdir(raw_shaders_path + './' + shader_name) fp = armutils.get_fp() # Open json file json_name = shader_name + '.json' base_name = json_name.split('.', 1)[0] with open(json_name) as f: json_file = f.read() json_data = json.loads(json_file) lib.make_datas.make(base_name, json_data, fp, defs) lib.make_variants.make(base_name, json_data, fp, defs)
def clean_cache(): os.chdir(armutils.get_fp()) wrd = bpy.data.worlds['Arm'] # Preserve envmaps envmaps_path = 'build/compiled/Assets/envmaps' if os.path.isdir(envmaps_path): shutil.move(envmaps_path, '.') # Remove compiled data if os.path.isdir('build/compiled'): shutil.rmtree('build/compiled') # Move envmaps back if os.path.isdir('envmaps'): os.makedirs('build/compiled/Assets') shutil.move('envmaps', 'build/compiled/Assets')
def init_properties_on_load(): global arm_ver if not "Arm" in bpy.data.worlds: init_properties() armutils.fetch_script_names() wrd = bpy.data.worlds["Arm"] # Outdated project if int(wrd.arm_version.replace(".", "")) < int(arm_ver.replace(".", "")): wrd.arm_version = arm_ver # Set url for embedded player if armutils.with_krom(): barmory.set_files_location(armutils.get_fp() + "/build/krom")
def init_properties_on_load(): global arm_ver if not 'Arm' in bpy.data.worlds: init_properties() armutils.fetch_script_names() wrd = bpy.data.worlds['Arm'] # Outdated project if int(wrd.arm_version.replace(".", "")[:4]) < int( arm_ver.replace(".", "")[:4]): # 17.01 - 17.01.1 wrd.arm_version = arm_ver # Set url for embedded player if armutils.with_krom(): barmory.set_files_location(armutils.get_fp() + '/build/krom')
def on_load_post(context): global appended_py_paths props.init_properties_on_load() nodes_renderpath.reload_blend_data() # Check for blender.py scripts in enabled libraries # for fp in appended_py_paths: # sys.path.remove(fp) # appended_py_paths = [] wrd = bpy.data.worlds['Arm'] for lib in wrd.my_librarytraitlist: if lib.enabled_prop: fp = armutils.get_fp() + '/Libraries/' + lib.name if fp not in appended_py_paths and os.path.exists(fp + '/blender.py'): # if os.path.exists(fp + '/blender.py'): sys.path.append(fp) appended_py_paths.append(fp) import blender blender.register()
def clean_project(): os.chdir(armutils.get_fp()) wrd = bpy.data.worlds['Arm'] # Remove build and compiled data if os.path.isdir('build'): shutil.rmtree('build') # Remove compiled nodes nodes_path = 'Sources/' + wrd.arm_project_package.replace('.', '/') + '/node/' if os.path.isdir(nodes_path): shutil.rmtree(nodes_path) # Remove khafile/korefile/Main.hx if os.path.isfile('khafile.js'): os.remove('khafile.js') if os.path.isfile('korefile.js'): os.remove('korefile.js') if os.path.isfile('Sources/Main.hx'): os.remove('Sources/Main.hx') print('Project cleaned')
def parse_operator(text): if text == None: return cmd = text.split('|') # Reflect commands from Armory player in Blender if cmd[0] == '__arm': if cmd[1] == 'quit': bpy.ops.arm.space_stop('EXEC_DEFAULT') elif cmd[1] == 'setx': bpy.context.scene.objects[cmd[2]].location.x = float(cmd[3]) elif cmd[1] == 'select': if bpy.context.object != None: bpy.context.object.select = False bpy.context.scene.objects[cmd[2]].select = True bpy.context.scene.objects.active = bpy.context.scene.objects[cmd[2]] elif cmd[1] == 'render': import numpy data = numpy.fromfile(armutils.get_fp() + '/build/html5/render.bin', dtype=numpy.uint8) data = data.astype(float) data = numpy.divide(data, 255) image = bpy.data.images.new("Render Result", width=int(cmd[2]), height=int(cmd[3])) image.pixels = data return
def write_traithx(class_name): wrd = bpy.data.worlds['Arm'] package_path = armutils.get_fp() + '/Sources/' + wrd.arm_project_package if not os.path.exists(package_path): os.makedirs(package_path) with open(package_path + '/' + class_name + '.hx', 'w') as f: f.write( """package """ + wrd.arm_project_package + """; class """ + class_name + """ extends armory.Trait { public function new() { super(); // notifyOnInit(function() { // }); // notifyOnUpdate(function() { // }); // notifyOnRemove(function() { // }); } } """)
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 != None and bpy.context.area.type == 'VIEW_3D': state.play_area = bpy.context.area state.target = runtime_to_target(in_viewport) # Build data build_project(is_play=True, in_viewport=in_viewport, target=state.target) state.in_viewport = in_viewport 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 or \ state.last_in_viewport != state.in_viewport: wrd.arm_recompile = True wrd.arm_recompile_trigger = False state.last_target = state.target state.last_in_viewport = state.in_viewport # 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 or state.target == 'native': # Unable to live-patch, stop player if state.krom_running: bpy.ops.arm.space_stop('EXEC_DEFAULT') # play_project(in_viewport=True) # Restart return mode = 'play' if state.target == 'native': state.compileproc = compile_project(target_name='--run') elif state.target == 'krom': if in_viewport: mode = 'play_viewport' state.compileproc = compile_project(target_name='krom') else: # Electron, Browser w, h = armutils.get_render_resolution(armutils.get_active_scene()) 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 parse_color(world, node, context, envmap_strength_const): wrd = bpy.data.worlds['Arm'] # Env map included if node.type == 'TEX_ENVIRONMENT' and node.image != None: image = node.image filepath = image.filepath if image.packed_file == None and not os.path.isfile( armutils.safe_assetpath(filepath)): log.warn(world.name + ' - unable to open ' + image.filepath) return tex = {} context['bind_textures'].append(tex) tex['name'] = 'envmap' tex['u_addressing'] = 'clamp' tex['v_addressing'] = 'clamp' # Reference image name tex['file'] = armutils.extract_filename(image.filepath) tex['file'] = armutils.safe_filename(tex['file']) base = tex['file'].rsplit('.', 1) ext = base[1].lower() if ext == 'hdr': target_format = 'HDR' else: target_format = 'JPEG' do_convert = ext != 'hdr' and ext != 'jpg' if do_convert: if ext == 'exr': tex['file'] = base[0] + '.hdr' target_format = 'HDR' else: tex['file'] = base[0] + '.jpg' target_format = 'JPEG' if image.packed_file != None: # Extract packed data unpack_path = armutils.get_fp() + '/build/compiled/Assets/unpacked' if not os.path.exists(unpack_path): os.makedirs(unpack_path) unpack_filepath = unpack_path + '/' + tex['file'] filepath = unpack_filepath if do_convert: if not os.path.isfile(unpack_filepath): armutils.write_image(image, unpack_filepath, file_format=target_format) elif os.path.isfile(unpack_filepath) == False or os.path.getsize( unpack_filepath) != image.packed_file.size: with open(unpack_filepath, 'wb') as f: f.write(image.packed_file.data) assets.add(unpack_filepath) else: if do_convert: converted_path = armutils.get_fp( ) + '/build/compiled/Assets/unpacked/' + tex['file'] filepath = converted_path # TODO: delete cache when file changes if not os.path.isfile(converted_path): armutils.write_image(image, converted_path, file_format=target_format) assets.add(converted_path) else: # Link image path to assets assets.add(armutils.safe_assetpath(image.filepath)) # Generate prefiltered envmaps world.world_envtex_name = tex['file'] world.world_envtex_irr_name = tex['file'].rsplit('.', 1)[0] disable_hdr = target_format == 'JPEG' mip_count = world.world_envtex_num_mips mip_count = write_probes.write_probes( filepath, disable_hdr, mip_count, generate_radiance=wrd.generate_radiance) world.world_envtex_num_mips = mip_count # Append envtex define bpy.data.worlds['Arm'].world_defs += '_EnvTex' # Append LDR define if disable_hdr: bpy.data.worlds['Arm'].world_defs += '_EnvLDR' # Append radiance define if wrd.generate_irradiance and wrd.generate_radiance: bpy.data.worlds['Arm'].world_defs += '_Rad' # Static image background elif node.type == 'TEX_IMAGE': bpy.data.worlds['Arm'].world_defs += '_EnvImg' tex = {} context['bind_textures'].append(tex) tex['name'] = 'envmap' # No repeat for now tex['u_addressing'] = 'clamp' tex['v_addressing'] = 'clamp' image = node.image filepath = image.filepath if image.packed_file != None: # Extract packed data filepath = '/build/compiled/Assets/unpacked' unpack_path = armutils.get_fp() + filepath if not os.path.exists(unpack_path): os.makedirs(unpack_path) unpack_filepath = unpack_path + '/' + image.name if os.path.isfile(unpack_filepath) == False or os.path.getsize( unpack_filepath) != image.packed_file.size: with open(unpack_filepath, 'wb') as f: f.write(image.packed_file.data) assets.add(unpack_filepath) else: # Link image path to assets assets.add(armutils.safe_assetpath(image.filepath)) # Reference image name tex['file'] = armutils.extract_filename(image.filepath) tex['file'] = armutils.safe_filename(tex['file']) # Append sky define elif node.type == 'TEX_SKY': # Match to cycles envmap_strength_const['float'] *= 0.1 bpy.data.worlds['Arm'].world_defs += '_EnvSky' # Append sky properties to material const = {} const['name'] = 'sunDirection' sun_direction = [ node.sun_direction[0], node.sun_direction[1], node.sun_direction[2] ] sun_direction[1] *= -1 # Fix Y orientation const['vec3'] = list(sun_direction) context['bind_constants'].append(const) world.world_envtex_sun_direction = sun_direction world.world_envtex_turbidity = node.turbidity world.world_envtex_ground_albedo = node.ground_albedo # Irradiance json file name world.world_envtex_irr_name = world.name write_probes.write_sky_irradiance(world.name) # Radiance if wrd.generate_radiance_sky and wrd.generate_radiance and wrd.generate_irradiance: bpy.data.worlds['Arm'].world_defs += '_Rad' if wrd.generate_radiance_sky_type == 'Hosek': hosek_path = 'armory/Assets/hosek/' else: hosek_path = 'armory/Assets/hosek_fake/' sdk_path = armutils.get_sdk_path() # Use fake maps for now assets.add(sdk_path + hosek_path + 'hosek_radiance.hdr') for i in range(0, 8): assets.add(sdk_path + hosek_path + 'hosek_radiance_' + str(i) + '.hdr') world.world_envtex_name = 'hosek' world.world_envtex_num_mips = 8
def make_texture(image_node, tex_name): wrd = bpy.data.worlds["Arm"] tex = {} tex["name"] = tex_name tex["file"] = "" image = image_node.image matname = mat_state.material.name if image == None: return None if image.filepath == "": log.warn(matname + "/" + image.name + " - file path not found") return None # Reference image name tex["file"] = armutils.extract_filename(image.filepath) tex["file"] = armutils.safefilename(tex["file"]) s = tex["file"].rsplit(".", 1) if len(s) == 1: log.warn(matname + "/" + image.name + " - file extension required for image name") return None ext = s[1].lower() do_convert = ext != "jpg" and ext != "png" and ext != "hdr" # Convert image if do_convert: tex["file"] = tex["file"].rsplit(".", 1)[0] + ".jpg" # log.warn(matname + '/' + image.name + ' - image format is not (jpg/png/hdr), converting to jpg.') if image.packed_file != None: # Extract packed data unpack_path = armutils.get_fp() + "/build/compiled/Assets/unpacked" if not os.path.exists(unpack_path): os.makedirs(unpack_path) unpack_filepath = unpack_path + "/" + tex["file"] if do_convert: if not os.path.isfile(unpack_filepath): armutils.write_image(image, unpack_filepath) # Write bytes if size is different or file does not exist yet elif os.path.isfile(unpack_filepath) == False or os.path.getsize(unpack_filepath) != image.packed_file.size: with open(unpack_filepath, "wb") as f: f.write(image.packed_file.data) assets.add(unpack_filepath) else: # if not os.path.isfile(image.filepath): # log.warn(matname + '/' + image.name + ' - file not found') # return tex if do_convert: converted_path = armutils.get_fp() + "/build/compiled/Assets/unpacked/" + tex["file"] # TODO: delete cache when file changes if not os.path.isfile(converted_path): armutils.write_image(image, converted_path) assets.add(converted_path) else: # Link image path to assets assets.add(armutils.safe_assetpath(image.filepath)) # if image_format != 'RGBA32': # tex['format'] = image_format interpolation = image_node.interpolation aniso = wrd.anisotropic_filtering_state if aniso == "On": interpolation = "Smart" elif aniso == "Off" and interpolation == "Smart": interpolation = "Linear" # TODO: Blender seems to load full images on size request, cache size instead powimage = is_pow(image.size[0]) and is_pow(image.size[1]) # Pow2 required to generate mipmaps if powimage == True: if interpolation == "Cubic": # Mipmap linear tex["mipmap_filter"] = "linear" tex["generate_mipmaps"] = True elif interpolation == "Smart": # Mipmap anisotropic tex["min_filter"] = "anisotropic" tex["mipmap_filter"] = "linear" tex["generate_mipmaps"] = True elif image_node.interpolation == "Cubic" or image_node.interpolation == "Smart": log.warn( matname + "/" + image.name + " - power of 2 texture required for " + image_node.interpolation + " interpolation" ) if image_node.extension != "REPEAT": # Extend or clip tex["u_addressing"] = "clamp" tex["v_addressing"] = "clamp" else: if state.target == "html5" and powimage == False: log.warn(matname + "/" + image.name + " - non power of 2 texture can not use repeat mode on HTML5 target") tex["u_addressing"] = "clamp" tex["v_addressing"] = "clamp" # if image.source == 'MOVIE': # Just append movie texture trait for now # movie_trait = {} # movie_trait['type'] = 'Script' # movie_trait['class_name'] = 'armory.trait.internal.MovieTexture' # movie_trait['parameters'] = [tex['file']] # for o in self.materialToGameObjectDict[material]: # o['traits'].append(movie_trait) # tex['source'] = 'movie' # tex['file'] = '' # MovieTexture will load the video return tex
def build_project(is_play=False, is_publish=False, in_viewport=False, target=None): wrd = bpy.data.worlds['Arm'] # Set target if target == None: state.target = wrd.arm_project_target.lower() # Clear flag state.in_viewport = False # Save blend if armutils.get_save_on_build(): bpy.ops.wm.save_mainfile() log.clear() # Set camera in active scene active_scene = bpy.context.screen.scene if wrd.arm_play_active_scene else bpy.data.scenes[wrd.arm_project_scene] if active_scene.camera == None: for o in active_scene.objects: if o.type == 'CAMERA': active_scene.camera = o break # Get paths sdk_path = armutils.get_sdk_path() raw_shaders_path = sdk_path + '/armory/Shaders/' # Set dir fp = armutils.get_fp() os.chdir(fp) # Create directories sources_path = 'Sources/' + wrd.arm_project_package if not os.path.exists(sources_path): os.makedirs(sources_path) # Compile path tracer shaders if len(bpy.data.cameras) > 0 and bpy.data.cameras[0].renderpath_path == 'pathtrace_path': path_tracer.compile(raw_shaders_path + 'pt_trace_pass/pt_trace_pass.frag.glsl') # Save external scripts edited inside Blender write_texts = False for text in bpy.data.texts: if text.filepath != '' and text.is_dirty: write_texts = True break if write_texts: area = bpy.context.area old_type = area.type area.type = 'TEXT_EDITOR' for text in bpy.data.texts: if text.filepath != '' and text.is_dirty and os.path.isfile(text.filepath): area.spaces[0].text = text bpy.ops.text.save() area.type = old_type # Save internal Haxe scripts for text in bpy.data.texts: if text.filepath == '' and text.name[-3:] == '.hx': with open('Sources/' + bpy.data.worlds['Arm'].arm_project_package + '/' + text.name, 'w') as f: f.write(text.as_string()) # Export data export_data(fp, sdk_path, is_play=is_play, is_publish=is_publish, in_viewport=in_viewport) if state.playproc == None: log.print_progress(50)
def update_gapi_ios(self, context): if os.path.isdir(armutils.get_fp() + 'build/ios-build'): shutil.rmtree(armutils.get_fp() + 'build/ios-build') bpy.data.worlds['Arm'].arm_recompile_trigger = True
def make_texture(image_node, tex_name, matname=None): wrd = bpy.data.worlds['Arm'] tex = {} tex['name'] = tex_name tex['file'] = '' image = image_node.image if matname == None: matname = mat_state.material.name if image == None: return None if image.filepath == '': log.warn(matname + '/' + image.name + ' - file path not found') return None # Reference image name tex['file'] = armutils.extract_filename(image.filepath) tex['file'] = armutils.safefilename(tex['file']) s = tex['file'].rsplit('.', 1) if len(s) == 1: log.warn(matname + '/' + image.name + ' - file extension required for image name') return None ext = s[1].lower() do_convert = ext != 'jpg' and ext != 'png' and ext != 'hdr' and ext != 'mp4' # Convert image if do_convert: tex['file'] = tex['file'].rsplit('.', 1)[0] + '.jpg' # log.warn(matname + '/' + image.name + ' - image format is not (jpg/png/hdr), converting to jpg.') if image.packed_file != None: # Extract packed data unpack_path = armutils.get_fp() + '/build/compiled/Assets/unpacked' if not os.path.exists(unpack_path): os.makedirs(unpack_path) unpack_filepath = unpack_path + '/' + tex['file'] if do_convert: if not os.path.isfile(unpack_filepath): armutils.write_image(image, unpack_filepath) # Write bytes if size is different or file does not exist yet elif os.path.isfile(unpack_filepath) == False or os.path.getsize( unpack_filepath) != image.packed_file.size: with open(unpack_filepath, 'wb') as f: f.write(image.packed_file.data) assets.add(unpack_filepath) else: if not os.path.isfile(armutils.safe_assetpath(image.filepath)): log.warn('Material ' + matname + '/' + image.name + ' - file not found(' + image.filepath + ')') return None if do_convert: converted_path = armutils.get_fp( ) + '/build/compiled/Assets/unpacked/' + tex['file'] # TODO: delete cache when file changes if not os.path.isfile(converted_path): armutils.write_image(image, converted_path) assets.add(converted_path) else: # Link image path to assets # TODO: Khamake converts .PNG to .jpg? Convert ext to lowercase on windows if armutils.get_os() == 'win': s = image.filepath.rsplit('.', 1) assets.add(armutils.safe_assetpath(s[0] + '.' + s[1].lower())) else: assets.add(armutils.safe_assetpath(image.filepath)) # if image_format != 'RGBA32': # tex['format'] = image_format interpolation = image_node.interpolation aniso = wrd.anisotropic_filtering_state if aniso == 'On': interpolation = 'Smart' elif aniso == 'Off' and interpolation == 'Smart': interpolation = 'Linear' # TODO: Blender seems to load full images on size request, cache size instead powimage = is_pow(image.size[0]) and is_pow(image.size[1]) # Pow2 required to generate mipmaps if powimage == True: if interpolation == 'Cubic': # Mipmap linear tex['mipmap_filter'] = 'linear' tex['generate_mipmaps'] = True elif interpolation == 'Smart': # Mipmap anisotropic tex['min_filter'] = 'anisotropic' tex['mipmap_filter'] = 'linear' tex['generate_mipmaps'] = True elif (image_node.interpolation == 'Cubic' or image_node.interpolation == 'Smart'): log.warn(matname + '/' + image.name + ' - power of 2 texture required for ' + image_node.interpolation + ' interpolation') if image_node.extension != 'REPEAT': # Extend or clip tex['u_addressing'] = 'clamp' tex['v_addressing'] = 'clamp' else: if state.target == 'html5' and powimage == False: log.warn( matname + '/' + image.name + ' - non power of 2 texture can not use repeat mode on HTML5 target' ) tex['u_addressing'] = 'clamp' tex['v_addressing'] = 'clamp' if image.source == 'MOVIE': # Just append movie texture trait for now movie_trait = {} movie_trait['type'] = 'Script' movie_trait['class_name'] = 'armory.trait.internal.MovieTexture' movie_trait['parameters'] = [tex['file']] for o in mat_state.mat_armusers[mat_state.material]: o['traits'].append(movie_trait) tex['source'] = 'movie' tex['file'] = '' # MovieTexture will load the video return tex
def invalidate_envmap_data(self, context): fp = armutils.get_fp() if os.path.isdir(fp + '/build/compiled/Assets/envmaps'): shutil.rmtree(fp + '/build/compiled/Assets/envmaps')
def build_project(is_play=False, is_publish=False, in_viewport=False, target=None): wrd = bpy.data.worlds['Arm'] # Set target if target == None: state.target = wrd.arm_project_target.lower() # Clear flag state.in_viewport = False # Save blend bpy.ops.wm.save_mainfile() log.clear() # Set camera in active scene active_scene = bpy.context.screen.scene if wrd.arm_play_active_scene else bpy.data.scenes[wrd.arm_project_scene] if active_scene.camera == None: for o in active_scene.objects: if o.type == 'CAMERA': active_scene.camera = o break # Get paths sdk_path = armutils.get_sdk_path() raw_shaders_path = sdk_path + '/armory/Shaders/' # Set dir fp = armutils.get_fp() os.chdir(fp) # Create directories if not os.path.exists('Sources'): os.makedirs('Sources') # Compile path tracer shaders if len(bpy.data.cameras) > 0 and bpy.data.cameras[0].renderpath_path == 'pathtrace_path': path_tracer.compile(raw_shaders_path + 'pt_trace_pass/pt_trace_pass.frag.glsl') # Save external scripts edited inside Blender write_texts = False for text in bpy.data.texts: if text.filepath != '' and text.is_dirty: write_texts = True break if write_texts: area = bpy.context.area old_type = area.type area.type = 'TEXT_EDITOR' for text in bpy.data.texts: if text.filepath != '' and text.is_dirty: area.spaces[0].text = text bpy.ops.text.save() area.type = old_type # Save internal Haxe scripts for text in bpy.data.texts: if text.filepath == '' and text.name[-3:] == '.hx': with open('Sources/' + bpy.data.worlds['Arm'].arm_project_package + '/' + text.name, 'w') as f: f.write(text.as_string()) # Export data export_data(fp, sdk_path, is_play=is_play, is_publish=is_publish, in_viewport=in_viewport) if state.playproc == None: log.print_progress(50)
def parse(material, mat_data, mat_users, rid): wrd = bpy.data.worlds['Arm'] mat_state.material = material mat_state.nodes = material.node_tree.nodes mat_state.mat_data = mat_data mat_state.mat_users = mat_users mat_state.output_node = cycles.node_by_type(mat_state.nodes, 'OUTPUT_MATERIAL') if mat_state.output_node == None: return None matname = armutils.safe_source_name(material.name) mat_state.path = armutils.get_fp() + '/build/compiled/ShaderRaws/' + matname if not os.path.exists(mat_state.path): os.makedirs(mat_state.path) mat_state.data = ShaderData(material) mat_state.data.add_elem('pos', 3) mat_state.data.add_elem('nor', 3) if mat_users != None: for bo in mat_users[material]: # GPU Skinning if bo.find_armature() and armutils.is_bone_animation_enabled(bo) and wrd.generate_gpu_skin == True: mat_state.data.add_elem('bone', 4) mat_state.data.add_elem('weight', 4) # Instancing if bo.instanced_children or len(bo.particle_systems) > 0: mat_state.data.add_elem('off', 3) rpasses = mat_utils.get_rpasses(material) for rp in rpasses: c = {} c['name'] = rp c['bind_constants'] = [] c['bind_textures'] = [] mat_state.mat_data['contexts'].append(c) mat_state.mat_context = c if rp == 'mesh': const = {} const['name'] = 'receiveShadow' const['bool'] = material.receive_shadow c['bind_constants'].append(const) con = make_mesh.make(rp, rid) elif rp == 'shadowmap': con = make_shadowmap.make(rp, rpasses) elif rp == 'translucent': const = {} const['name'] = 'receiveShadow' const['bool'] = material.receive_shadow c['bind_constants'].append(const) con = make_transluc.make(rp) elif rp == 'overlay': con = make_overlay.make(rp) elif rp == 'decal': con = make_decal.make(rp) elif rp == 'depth': con = make_depth.make(rp) write_shaders(con, rp) armutils.write_arm(mat_state.path + '/' + matname + '_data.arm', mat_state.data.get()) shader_data_name = matname + '_data' shader_data_path = 'build/compiled/ShaderRaws/' + matname + '/' + shader_data_name + '.arm' assets.add_shader_data(shader_data_path) mat_data['shader'] = shader_data_name + '/' + shader_data_name return mat_state.data.sd
def get_render_result(): with open(armutils.get_fp() + '/build/html5/render.msg', 'w') as f: pass
def parse(material, mat_data, mat_users, mat_armusers, rid): wrd = bpy.data.worlds['Arm'] mat_state.material = material mat_state.nodes = material.node_tree.nodes mat_state.mat_data = mat_data mat_state.mat_users = mat_users mat_state.mat_armusers = mat_armusers mat_state.output_node = cycles.node_by_type(mat_state.nodes, 'OUTPUT_MATERIAL') if mat_state.output_node == None: return None matname = armutils.safe_source_name(material.name) mat_state.rel_path = 'build/compiled/ShaderRaws/' + matname mat_state.path = armutils.get_fp() + '/' + mat_state.rel_path if not os.path.exists(mat_state.path): os.makedirs(mat_state.path) mat_state.data = ShaderData(material) mat_state.data.add_elem('pos', 3) mat_state.data.add_elem('nor', 3) if mat_users != None: for bo in mat_users[material]: # GPU Skinning if bo.find_armature() and armutils.is_bone_animation_enabled( bo) and wrd.generate_gpu_skin == True: mat_state.data.add_elem('bone', 4) mat_state.data.add_elem('weight', 4) # Instancing if bo.instanced_children or len(bo.particle_systems) > 0: mat_state.data.add_elem('off', 3) rpasses = mat_utils.get_rpasses(material) for rp in rpasses: c = {} c['name'] = rp c['bind_constants'] = [] c['bind_textures'] = [] mat_state.mat_data['contexts'].append(c) mat_state.mat_context = c if rp == 'mesh': const = {} const['name'] = 'receiveShadow' const['bool'] = material.receive_shadow c['bind_constants'].append(const) con = mesh_make(rp, rid) elif rp == 'shadowmap': con = make_shadowmap.make(rp, rpasses) elif rp == 'translucent': const = {} const['name'] = 'receiveShadow' const['bool'] = material.receive_shadow c['bind_constants'].append(const) con = make_transluc.make(rp) elif rp == 'overlay': con = make_overlay.make(rp) elif rp == 'decal': con = make_decal.make(rp) elif rp == 'depth': con = make_depth.make(rp) elif rp == 'voxel': con = make_voxel.make(rp) elif rpass_hook != None: con = rpass_hook(rp) write_shaders(con, rp) armutils.write_arm(mat_state.path + '/' + matname + '_data.arm', mat_state.data.get()) shader_data_name = matname + '_data' shader_data_path = 'build/compiled/ShaderRaws/' + matname + '/' + shader_data_name + '.arm' assets.add_shader_data(shader_data_path) mat_data['shader'] = shader_data_name + '/' + shader_data_name return mat_state.data.sd, 'translucent' in rpasses, 'overlay' in rpasses, 'decal' in rpasses
def execute(self, context): if not armutils.check_saved(self): return {"CANCELLED"} webbrowser.open('file://' + armutils.get_fp()) return{'FINISHED'}
def patch_project(): sdk_path = armutils.get_sdk_path() fp = armutils.get_fp() os.chdir(fp) export_data(fp, sdk_path, is_play=True)