# # File:: %RS_TOOLSLIB%/pipeline/resourcing/converters/converter_animation_coalesce.rb # Description:: Animation Coalescing processor. # # Author:: Luke Openshaw # Date:: 22nd November 2011 # #---------------------------------------------------------------------------- # Uses #---------------------------------------------------------------------------- #require 'pipeline/config/projects' require 'pipeline/content/content_core' require 'pipeline/os/file' require 'pipeline/os/path' require 'pipeline/os/start' require 'pipeline/projectutil/data_zip' require 'pipeline/resourcing/converter' require 'pipeline/fileformats/clipascii' include Pipeline include Pipeline::Resourcing #---------------------------------------------------------------------------- # Implementation #---------------------------------------------------------------------------- module Pipeline module Resourcing module Converters # # == Description # Animation Coalescing processor. # class AnimationConverterCoalesce < ChildConverterBase attr_reader :items attr_reader :use_xge attr_reader :conf def initialize( project, branch ) super( project, branch ) @items = [] @use_xge = ( Pipeline::Config::instance().use_xge and Incredibuild.is_installed?() ) @conf = Pipeline::Config::instance() end # Build the content. def build( content_node_list, input_lists, &block ) result = true prebuild_internal( content_node_list, input_lists ) begin if @use_xge then result = build_xge( &block ) else result = build_local( &block ) end rescue BuildError => ex result = false throw end @items = [] result end def AnimationConverterCoalesce::processor(dir, file_list ) puts "Coalesce process has started for #{dir}" coalesce_exe = CLIP_COALESCE_EXE combine_exe = ANIM_COMBINE_EXE edit_exe = ANIM_EDIT_EXE dof_xml = DOF_INJECTION_XML Pipeline::Globals.instance().in_env do |e| coalesce_exe = e.subst(coalesce_exe) combine_exe = e.subst(combine_exe) edit_exe = e.subst(edit_exe) dof_xml = e.subst(dof_xml) end xmldoc = REXML::Document.new( File.new(dof_xml) ) if not xmldoc then puts "ERROR: Failed to load file: #{dof_xml}" exit( -1 ) end skeletons = [] xmldoc.elements.each( '/Skeletons/Item' ) do |item| skeletons << item.text end file_list.each do | zip | clip_list_files = OS::FindEx.find_files(dir + "/*.cliplist") # First lets apply additive / dof injection clip_list_files.each do | clip_list | clip_list_base = OS::Path.get_basename( clip_list ) clip_list_tokens = clip_list_base.split( '@' ) additive = clip_list_tokens[2].to_i File.open(clip_list) do |clip_list_file| begin clip_list_file.each do |clip_file| anim_file = OS::Path.remove_extension( clip_file ) + ".anim" if not File.exist?( anim_file ) puts "ERROR: Failed to make additive/inject dof: #{anim_file} does not exist" exit( -1 ) end if additive == 1 then puts "Processing as additive #{anim_file}" additive_command = combine_exe + " -anims #{anim_file},#{anim_file} -subtract -time 0 -out #{anim_file} -nocompress -nopopups -output" status, out, err = OS::start( additive_command ) if ( status.exitstatus != 0 ) then puts "ERROR: Failed to make additive: #{anim_file}" exit( status.exitstatus ) end end skel_file = clip_list_tokens[1] + ".skel" skeletons.each_index do |skeleton_index| if skel_file.index(skeletons[skeleton_index]) != nil then edit_command = edit_exe + " -anim=#{anim_file} -out=#{anim_file} -op add[134,0]=float(0.0)" status, out, err = OS::start( edit_command ) if ( status.exitstatus != 0 ) then puts "ERROR: Failed to inject DOF into #{anim_file}" exit( status.exitstatus ) end puts "WARNING: Injected DOF: #{anim_file} - skel: #{skel_file}" end end end ensure clip_list_file.close() end end end clip_list_files.each do | clip_list | clip_list_name = OS::Path.get_basename(clip_list) output_dir = OS::Path.combine( dir, clip_list_name ) FileUtils::mkdir( output_dir ) unless ( File::directory?( output_dir ) ) coalesce_command = coalesce_exe + " -cliplist=#{clip_list} -outdir=#{output_dir} -outprefix=#{OS::Path.get_basename(clip_list)}_ -framelimit=200 -score -nopopups -output" puts "Coalesce command: #{coalesce_command}" status, out, err = OS::start( coalesce_command ) puts out if ( status.exitstatus != 0 ) then puts "Failed to process #{clip_list}" exit( status.exitstatus ) end end end end #-------------------------------------------------------------------- # Private #-------------------------------------------------------------------- private CLIP_COALESCE_EXE = '$(toolsbin)/anim/clipcoalesce.exe' ANIM_COMBINE_EXE = '$(toolsbin)/anim/animcombine.exe' ANIM_EDIT_EXE = '$(toolsbin)/anim/animedit.exe' DOF_INJECTION_XML = '$(toolsroot)/etc/config/anim/dof_injection_skeletons.xml' def build_local( ) status = 0 @command_list.each_key do | key | status, out, err = OS::start( @command_list[key] ) if ( status.exitstatus == 0 ) then AnimationConverter::log().info( "Coalesce of clips for #{key} succeded." ) else AnimationConverter::log().error( "Coalesce of clips for #{key} failed." ) end end status.exitstatus == 0 end def build_xge() result = true if ( 0 == @items.size ) then AnimationConverter::log().info( "Nothing to convert." ) else AnimationConverter::log().info( "Creating XGE animation processing packets." ) xge_folder = XGE::get_temp_dir( @project, @branch.name ) xge_packet_folder = OS::Path::combine( xge_folder, 'anim_coalesce' ) filename = OS::Path.combine( xge_packet_folder, 'anim_coalesce.xml' ) @log_filename = OS::Path.combine( xge_packet_folder, 'anim_coalesce.log' ) xge_packets = GenericPacketList.new( xge_packet_folder, "AnimationConverterCoalesce", :processor, false, 1024 ) @items.each do |item| xge_packets.add_item( item ) end xge_packets.create( ) AnimationConverter::log().info( "Creating XGE task" ) # Create environment and tools options = "" tool = XGE::Tool.ruby( "anim_colaesce", "") xge_env = XGE::Environment.new( "env_anim_coalesce" ) xge_env.add_tool( tool ) # Construct XGE Project xge_project = XGE::Project.new( "#{@project.uiname} Animation Coalescing" ) xge_taskgroup = XGE::TaskGroup.new( "Animation Coalescing", [], xge_env, xge_env.tools[0] ) # Construct XGE TaskGroup xge_packets.packets.each do | packet | task_name = "anim_coalesce" task = XGE::Task.new( task_name, packet.filename ) task.caption = "#{task_name}" task.parameters = packet.filename xge_taskgroup.tasks << task end xge_project.add_task( xge_taskgroup ) xge_project.write( filename ) AnimationConverter::log().info( "Starting XGE coalescing process." ) if ( not XGE::start( filename, @log_filename ) ) then AnimationConverter::log().error( "Animation Coalesce failed. Check Build Monitor for errors." ) result = false if ( not @conf.user.username.downcase.include?( User::ASSETBUILDER_USER) ) error_msg = "XGE Animation Coalescing failed. Check #{@log_filename} for errors." GUI::MessageBox::error("XGE Error Notification", error_msg) end end end result end def prebuild_internal( content_node_list, input_lists ) result = true content_node_list.each do | content_node | cache_dir = AnimationConverter::cache_dir( @branch, content_node ) input_lists[content_node].each do | clip_node | clip_basename = OS::Path.get_basename(clip_node.filename) item = GenericItem.new( OS::Path.combine( cache_dir, OS::Path::remove_extension( clip_basename) ) ) item.set_files( [clip_node.filename] ) @items << item end end result end def postbuild_internal() end end end # Converters module end # Resourcing module end # Pipeline module