# # File:: %RS_TOOLSLIB%/pipeline/resourcing/converters/converter_animation.rb # Description:: Main animation 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' include Pipeline include Pipeline::Resourcing #---------------------------------------------------------------------------- # Implementation #---------------------------------------------------------------------------- module Pipeline module Resourcing module Converters # # == Description # Animation compression processor. # class AnimationConverterCompression < 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, &block ) 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 AnimationConverterCompression::processor( dir, file_list ) puts "Compress process has started for #{dir}" files_for_zip = [] dir_tokens = dir.split( '/' ) dir_name = dir_tokens[dir_tokens.count-1] file_list.each do | clip_list | clip_list_name = OS::Path.get_basename( clip_list ) input_dir = OS::Path.combine( dir, clip_list_name ) clip_list_tokens = clip_list_name.split( '@' ) templates_path = COMPRESSION_TEMPLATE_PATH skeletons_path = SKELETONS_PATH compress_exe = ANIM_COMPRESS_EXE Pipeline::Globals.instance().in_env do |e| compress_exe = e.subst( compress_exe ) templates_path = e.subst( templates_path ) skeletons_path = e.subst( skeletons_path ) end # Extract the compression settings from the clip list name compression_file_path = OS::Path.combine( templates_path, clip_list_tokens[0] + ".txt" ) skel_file_path = OS::Path.combine( skeletons_path, clip_list_tokens[1] + ".skel") additive = clip_list_tokens[2].to_i compressionrules = '' template_file = File.new( compression_file_path ) lines = template_file.readlines lines.each do | line | compressionrules << line.chomp end template_file.close # Loop through the anims compressing each one anim_list = OS::FindEx.find_files( OS::Path.combine( input_dir, "*.anim" ) ) anim_list.each do | anim_file | compress_command = compress_exe + " -anim=#{anim_file} -skel=#{skel_file_path} -out=#{anim_file} -maxblocksize=65536 -compressionrotation=0.0005 -compressiontranslation=0.0005 -compressionscale=0.0005 -compressiondefault=0.005 -compressioncost=60 -decompressioncost=80 -compressionrules=#{compressionrules} -nopopups" status, out, err = OS::start( compress_command ) puts compress_command puts out if ( status.exitstatus != 0 ) then puts "ERROR: Failed to compress #{anim_file}" exit( status.exitstatus ) end end files_for_zip = files_for_zip + OS::FindEx.find_files( input_dir + "/*.clip" ) files_for_zip = files_for_zip + OS::FindEx.find_files( input_dir + "/*.anim" ) end ProjectUtil::data_zip_create( (dir + "/" + dir_name + ".icd.zip"), files_for_zip, false ) end #-------------------------------------------------------------------- # Private #-------------------------------------------------------------------- private ANIM_COMPRESS_EXE = '$(toolsbin)/anim/animcompress.exe' COMPRESSION_TEMPLATE_PATH = '$(toolsconfig)/config/anim/compression_templates' SKELETONS_PATH = '$(toolsconfig)/config/anim/skeletons' 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( "Compression of anims for #{key} succeded." ) else AnimationConverter::log().error( "Compression of amo,s 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 compression packets." ) xge_folder = XGE::get_temp_dir( @project, @branch.name ) xge_packet_folder = OS::Path::combine( xge_folder, 'anim_compress' ) filename = OS::Path.combine( xge_packet_folder, 'anim_compress.xml' ) @log_filename = OS::Path.combine( xge_packet_folder, 'anim_compress.log' ) xge_packets = GenericPacketList.new( xge_packet_folder, "AnimationConverterCompression", :processor, false, 64 ) @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_compress", "") xge_env = XGE::Environment.new( "env_anim_compress" ) xge_env.add_tool( tool ) # Construct XGE Project xge_project = XGE::Project.new( "#{@project.uiname} Animation Compression" ) xge_taskgroup = XGE::TaskGroup.new( "Animation Compression", [], xge_env, xge_env.tools[0] ) # Construct XGE TaskGroup xge_packets.packets.each do | packet | task_name = "anim_compress" 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 animation compression process." ) if ( not XGE::start( filename, @log_filename ) ) then AnimationConverter::log().error( "Animation Compression failed. Check Build Monitor for errors." ) result = false if ( not @conf.user.username.downcase.include?( User::ASSETBUILDER_USER) ) error_msg = "XGE Animation Compression 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_from_dir("*.cliplist") @items << item end end result end def postbuild_internal() end end end # Converters module end # Resourcing module end # Pipeline module