Animation capture
This commit is contained in:
parent
e4275aac53
commit
424665c70a
|
@ -129,8 +129,63 @@ class SpaceArmory extends Trait {
|
|||
|
||||
#if (kha_krom && arm_render)
|
||||
static var frame = 0;
|
||||
static var captured = false;
|
||||
|
||||
#if arm_render_anim
|
||||
|
||||
static var current = 0.0;
|
||||
static var framesCaptured = 0;
|
||||
|
||||
@:access(kha.Scheduler)
|
||||
function renderCapture() {
|
||||
App.pauseUpdates = true;
|
||||
App.notifyOnRender(function(g:kha.graphics4.Graphics) {
|
||||
if (captured) return;
|
||||
kha.Scheduler.current = current;
|
||||
frame++;
|
||||
if (frame >= 2) { // Init TAA
|
||||
App.pauseUpdates = false;
|
||||
if (frame % 2 == 0) { // Alternate TAA
|
||||
current += iron.system.Time.delta;
|
||||
return;
|
||||
}
|
||||
var info = iron.Scene.active.raw.capture_info;
|
||||
var pd = iron.Scene.active.cameras[0].data.pathdata;
|
||||
var tex = pd.renderTargets.get("capture").image;
|
||||
|
||||
if (tex != null) {
|
||||
var pixels = tex.getPixels();
|
||||
var bd = pixels.getData();
|
||||
var bo = new haxe.io.BytesOutput();
|
||||
var rgb = haxe.io.Bytes.alloc(tex.width * tex.height * 3);
|
||||
for (j in 0...tex.height) {
|
||||
for (i in 0...tex.width) {
|
||||
var k = j * tex.width + i;
|
||||
var l = (tex.height - j) * tex.width + i; // Reverse Y
|
||||
rgb.set(k * 3 + 0, pixels.get(l * 4 + 2));
|
||||
rgb.set(k * 3 + 1, pixels.get(l * 4 + 1));
|
||||
rgb.set(k * 3 + 2, pixels.get(l * 4 + 0));
|
||||
}
|
||||
}
|
||||
var pngwriter = new iron.format.png.Writer(bo);
|
||||
pngwriter.write(iron.format.png.Tools.buildRGB(tex.width, tex.height, rgb));
|
||||
var fname = framesCaptured + "";
|
||||
while (fname.length < 4) fname = "0" + fname;
|
||||
Krom.fileSaveBytes(info.path + "/" + fname + ".png", bo.getBytes().getData());
|
||||
}
|
||||
if (framesCaptured++ == info.frame_end) {
|
||||
captured = true;
|
||||
kha.System.requestShutdown();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
function renderCapture() {
|
||||
App.notifyOnRender(function(g:kha.graphics4.Graphics) {
|
||||
if (captured) return;
|
||||
frame++;
|
||||
if (frame >= 3) {
|
||||
var pd = iron.Scene.active.cameras[0].data.pathdata;
|
||||
|
@ -138,20 +193,12 @@ class SpaceArmory extends Trait {
|
|||
if (tex != null) {
|
||||
var pixels = tex.getPixels();
|
||||
Krom.fileSaveBytes("render.bin", pixels.getData());
|
||||
// var bo = new haxe.io.BytesOutput();
|
||||
// var rgb = haxe.io.Bytes.alloc(tex.width * tex.height * 3);
|
||||
// for (i in 0...tex.width * tex.height) {
|
||||
// rgb.set(i * 3 + 0, pixels.get(i * 4 + 2));
|
||||
// rgb.set(i * 3 + 1, pixels.get(i * 4 + 1));
|
||||
// rgb.set(i * 3 + 2, pixels.get(i * 4 + 0));
|
||||
// }
|
||||
// var pngwriter = new armory.format.png.Writer(bo);
|
||||
// pngwriter.write(armory.format.png.Tools.buildRGB(tex.width, tex.height, rgb));
|
||||
// Krom.fileSaveBytes("render.png", bo.getBytes().getData());
|
||||
}
|
||||
captured = true;
|
||||
kha.System.requestShutdown();
|
||||
}
|
||||
});
|
||||
}
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
|
|
@ -2508,7 +2508,7 @@ class ArmoryExporter:
|
|||
self.output['mesh_datas'] = [];
|
||||
self.do_export_mesh(objectRef, scene)
|
||||
|
||||
def execute(self, context, filepath, scene=None):
|
||||
def execute(self, context, filepath, scene=None, write_capture_info=False):
|
||||
profile_time = time.time()
|
||||
|
||||
self.output = {}
|
||||
|
@ -2523,6 +2523,12 @@ class ArmoryExporter:
|
|||
self.endFrame = self.scene.frame_end
|
||||
self.output['frame_time'] = 1.0 / (self.scene.render.fps / self.scene.render.fps_base)
|
||||
|
||||
if write_capture_info:
|
||||
self.output['capture_info'] = {}
|
||||
self.output['capture_info']['path'] = self.scene.render.filepath
|
||||
self.output['capture_info']['frame_start'] = self.scene.frame_start
|
||||
self.output['capture_info']['frame_end'] = self.scene.frame_end
|
||||
|
||||
self.bobjectArray = {}
|
||||
self.meshArray = {}
|
||||
self.lampArray = {}
|
||||
|
|
|
@ -62,7 +62,9 @@ def on_scene_update_post(context):
|
|||
# op_changed(last_operator, bpy.context.object)
|
||||
# last_operator = None
|
||||
|
||||
if state.is_render:
|
||||
if state.is_render_anim:
|
||||
pass
|
||||
elif state.is_render:
|
||||
import numpy
|
||||
# fp = arm.utils.get_fp_build()
|
||||
krom_location, krom_path = arm.utils.krom_paths()
|
||||
|
|
|
@ -96,7 +96,7 @@ def export_data(fp, sdk_path, is_play=False, is_publish=False, in_viewport=False
|
|||
if scene.arm_export:
|
||||
ext = '.zip' if (scene.arm_compress and is_publish) else '.arm'
|
||||
asset_path = arm.utils.build_dir() + '/compiled/Assets/' + arm.utils.safestr(scene.name) + ext
|
||||
exporter.execute(bpy.context, asset_path, scene=scene)
|
||||
exporter.execute(bpy.context, asset_path, scene=scene, write_capture_info=state.is_render_anim)
|
||||
if ArmoryExporter.export_physics:
|
||||
physics_found = True
|
||||
if ArmoryExporter.export_navigation:
|
||||
|
@ -232,10 +232,11 @@ def compile_project(target_name=None, watch=False, patch=False):
|
|||
else:
|
||||
return subprocess.Popen(cmd)
|
||||
|
||||
def build_project(is_play=False, is_publish=False, is_render=False, in_viewport=False):
|
||||
def build_project(is_play=False, is_publish=False, is_render=False, is_render_anim=False, in_viewport=False):
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
|
||||
state.is_render = is_render
|
||||
state.is_render_anim = is_render_anim
|
||||
|
||||
# Clear flag
|
||||
state.in_viewport = False
|
||||
|
@ -366,7 +367,7 @@ def get_khajs_path(in_viewport, target):
|
|||
else: # Browser
|
||||
return arm.utils.build_dir() + '/html5/kha.js'
|
||||
|
||||
def play_project(in_viewport, is_render=False):
|
||||
def play_project(in_viewport, is_render=False, is_render_anim=False):
|
||||
global scripts_mtime
|
||||
global code_parsed
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
|
@ -380,7 +381,7 @@ def play_project(in_viewport, is_render=False):
|
|||
state.target = runtime_to_target(in_viewport)
|
||||
|
||||
# Build data
|
||||
build_project(is_play=True, is_render=is_render, in_viewport=in_viewport)
|
||||
build_project(is_play=True, is_render=is_render, is_render_anim=is_render_anim, in_viewport=in_viewport)
|
||||
state.in_viewport = in_viewport
|
||||
|
||||
khajs_path = get_khajs_path(in_viewport, state.target)
|
||||
|
@ -521,3 +522,8 @@ def clean_project():
|
|||
|
||||
def get_render_result():
|
||||
play_project(False, is_render=True)
|
||||
|
||||
def get_render_anim_result():
|
||||
if bpy.context.scene != None:
|
||||
print('Capturing animation frames into ' + bpy.context.scene.render.filepath)
|
||||
play_project(False, is_render=True, is_render_anim=True)
|
||||
|
|
|
@ -15,5 +15,6 @@ play_area = None
|
|||
krom_running = False
|
||||
is_paused = False
|
||||
is_render = False
|
||||
is_render_anim = False
|
||||
recompiled = False
|
||||
mod_scripts = []
|
||||
|
|
|
@ -838,13 +838,30 @@ class ArmoryRenderAnimButton(bpy.types.Operator):
|
|||
bl_label = 'Animation'
|
||||
|
||||
def execute(self, context):
|
||||
if not arm.utils.check_saved(self):
|
||||
return {"CANCELLED"}
|
||||
|
||||
if not arm.utils.check_sdkpath(self):
|
||||
return {"CANCELLED"}
|
||||
|
||||
if not arm.utils.check_engine(self):
|
||||
return {"CANCELLED"}
|
||||
|
||||
make_renderer.check_default()
|
||||
|
||||
if state.playproc != None:
|
||||
make.stop_project()
|
||||
if bpy.data.worlds['Arm'].arm_play_runtime != 'Krom':
|
||||
bpy.data.worlds['Arm'].arm_play_runtime = 'Krom'
|
||||
self.report({"ERROR"}, "Animation capture not yet supported")
|
||||
return {"CANCELLED"}
|
||||
# return{'FINISHED'}
|
||||
rpdat = arm.utils.get_rp()
|
||||
if rpdat.rp_rendercapture == False:
|
||||
rpdat.rp_rendercapture = True
|
||||
if rpdat.rp_antialiasing != 'TAA':
|
||||
rpdat.rp_antialiasing = 'TAA'
|
||||
assets.invalidate_enabled = False
|
||||
make.get_render_anim_result()
|
||||
assets.invalidate_enabled = True
|
||||
return{'FINISHED'}
|
||||
|
||||
# Play button in 3D View panel
|
||||
def draw_view3d_header(self, context):
|
||||
|
|
|
@ -125,6 +125,10 @@ project.addSources('Sources');
|
|||
|
||||
if state.is_render:
|
||||
assets.add_khafile_def('arm_render')
|
||||
if state.is_render_anim:
|
||||
assets.add_khafile_def('arm_render_anim')
|
||||
if not os.path.exists('Libraries/iron_format'):
|
||||
f.write(add_armory_library(sdk_path + '/lib/', 'iron_format'))
|
||||
|
||||
shaderload = state.target == 'krom' or state.target == 'html5'
|
||||
if wrd.arm_cache_compiler and shaderload and not is_publish:
|
||||
|
|
Loading…
Reference in a new issue