Files
gtav-src/tools_ng/lib/pipeline/resourcing/converters/converter_animation.rb
T
2025-09-29 00:52:08 +02:00

352 lines
12 KiB
Ruby
Executable File

#
# File:: %RS_TOOLSLIB%/pipeline/resourcing/converters/converter_animation.rb
# Description:: Main animation processor.
#
# Author:: Luke Openshaw
# Date:: 21st November 2011
#
#----------------------------------------------------------------------------
# Uses
#----------------------------------------------------------------------------
require 'pipeline/config/projects'
require 'pipeline/content/content_core'
require 'pipeline/content/content_anim'
require 'pipeline/resourcing/converter'
require 'pipeline/resourcing/converters/converter_animation_clipdump'
require 'pipeline/resourcing/converters/converter_animation_coalesce'
require 'pipeline/resourcing/converters/converter_animation_compress'
require 'pipeline/util/incredibuild'
require 'pipeline/util/incredibuild_xge'
include Pipeline
include Pipeline::Resourcing
require 'xml'
#----------------------------------------------------------------------------
# Implementation
#----------------------------------------------------------------------------
module Pipeline
module Resourcing
module Converters
#
# == Description
# Main animation processor.
#
class AnimationConverter < ConverterBase
include HasConverterChildren
#attr_reader :input_file_list
def initialize( project, branch )
super( project, branch )
initialize_children( )
@processed_clip_node = nil
@processed_clip_node_list = []
@file_list = []
AnimationConverter::log().info( "Initialising Animation Converter" )
# Add child converters
add_child_converter( AnimationConverterClipDump::new( project, branch ) )
add_child_converter( AnimationConverterCoalesce::new( project, branch ) )
add_child_converter( AnimationConverterCompression::new( project, branch ) )
end
# Return whether this converter can convert the specified content node.
def can_convert?( content )
( content.is_a?( Content::ProcessedAnimationDir ) )
end
def prebuild( )
end
# Build the content.
def build( &block )
clips_result = true
output_list = []
if @processed_clip_node_list.length > 0 then
AnimationConverter::log().info( "Animation converter processing clip dictionaries for #{@processed_clip_node_list.length} anim content." )
input_lists = {}
start_time = Time.now
prebuild_internal( @processed_clip_node_list, input_lists, @c.rebuild )
end_time = Time.now
AnimationConverter::log().info( "Animation converter prebuild took #{((end_time - start_time)/60)} minutes." )
# Push clipzip through all of the child converters.
@children.each do |child|
start_time = Time.now
clips_result = child.build( @processed_clip_node_list, input_lists ) if clips_result == true
end_time = Time.now
AnimationConverter::log().info( "Animation sub converter #{child.to_s} took #{((end_time - start_time)/60)} minutes." )
end
# Package up result after building up our data.
start_time = Time.now
clips_result = postbuild_internal( @processed_clip_node_list, input_lists, output_list ) if clips_result == true
end_time = Time.now
AnimationConverter::log().info( "Animation postbuild took #{((end_time - start_time)/60)} minutes." )
end
clear()
result = {}
result[:conversion] = output_list
result[:success] = clips_result
result
end
# Clear the content from the build list.
def clear( )
@processed_clip_node_list = []
@processed_clip_node = nil
end
# Add the content to the build list (if valid).
def add_content( content )
AnimationConverter::log().info( "Animation converter adding content: #{content}" )
if ( content.is_a?( Content::ProcessedAnimationDir ) ) then
clip_node = content
output_dir = clip_node.absolute_path
FileUtils::mkdir_p( output_dir ) \
unless ( File::directory?( output_dir ) )
@processed_clip_node_list << clip_node
true
else
AnimationConverter::log().error( "Could not convert: #{content}." )
false
end
end
# Return raw animation converter cache directory.
def AnimationConverter::cache_dir_raw( branch )
c = ConvertSystem::instance( )
OS::Path::combine( c.cache_root, 'clips' )
end
# Return animation converter cache directory.
def AnimationConverter::cache_dir( branch, processed_clip_node )
OS::Path::combine( AnimationConverter::cache_dir_raw( branch ), processed_clip_node.name )
end
# Return AnimationConverter log object.
def AnimationConverter::log()
@@log = Log.new( 'convert_animation' ) if ( @@log.nil? )
@@log
end
#--------------------------------------------------------------------
# Private
#--------------------------------------------------------------------
private
@@log = nil
# Build out input list
def prebuild_internal( processed_clip_node_list, input_lists, rebuild )
result = true
processed_clip_node_list.each do | processed_clip_node |
input_lists[processed_clip_node] = []
cache_dir = AnimationConverter::cache_dir( @branch, processed_clip_node )
# Collect all the input content for the processed node
clip_input_nodes = processed_clip_node.inputs.collect do | input_dir_node |
AnimationConverter::log().info( "Input Directory: #{input_dir_node.path}." )
input_dir_node
end
output_dir = processed_clip_node.absolute_path
FileUtils::mkdir_p( output_dir ) \
unless ( File::directory?( output_dir ) )
# Flush the processing and processed caches if this is a rebuild
if rebuild then
AnimationConverter::log().info( "Deleting processing cache: #{OS::Path::combine( cache_dir, '*.*' )}." )
cache_dirs = OS::FindEx::find_dirs( cache_dir + "/" )
cache_dirs.each do | dir |
::FileUtils::rm_r( dir )
end
AnimationConverter::log().info( "Deleting processed cache: #{processed_clip_node.absolute_path}." )
OS::FileUtilsEx::delete_files( OS::Path::combine( processed_clip_node.absolute_path, '*.*' ) )
end
# Add clip nodes to the input hash
clip_input_nodes.each do | input_dir_node |
input_dir_node.inputs.each do | clip_node |
input_lists[processed_clip_node] << clip_node if ( rebuild or need_convert?( clip_node, processed_clip_node ) ) and ( clip_node.extension == 'zip' )
end
end
end
result
end
def need_convert?( clip_node, processed_clip_node )
dest_clip = OS::Path.combine( processed_clip_node.absolute_path, OS::Path.get_basename( clip_node.filename ) + ".zip" )
return ( true ) if File.exist?( dest_clip ) == false
return ( true ) if( File::mtime( clip_node.filename ) > File::mtime( dest_clip ) )
false
end
#
def postbuild_internal( processed_clip_node_list, input_lists, output_list )
# XML doc which contains a list of each processed icd with file size stats
xmldoc = LibXML::XML::Document.new
xmldoc.root = XML::Node.new("entries")
processed_clip_node_list.each do | processed_clip_node |
AnimationConverter::log().info( "Post build: #{processed_clip_node.absolute_path}." )
cache_dir = AnimationConverter::cache_dir( @branch, processed_clip_node )
# Repackage all our clip zips
@file_list = []
output_dir = processed_clip_node.absolute_path
input_lists[processed_clip_node].each do | input_node |
clip_base_name = OS::Path.get_basename( input_node.filename )
clip_dir = OS::Path::combine( cache_dir, OS::Path.remove_extension( clip_base_name ) )
OS::FileUtilsEx::copy_file( OS::Path::combine( clip_dir, clip_base_name ) + ".zip", OS::Path::combine( output_dir, clip_base_name ) + ".zip" )
# Write entry to the stat xml, size before and after compression
xml_entry = XML::Node.new("dict")
xml_entry.attributes["name"] = clip_base_name + ".zip"
xml_entry.attributes["sizeBefore"] = File.size(OS::Path::combine(input_node.path, clip_base_name ) + ".zip").to_s()
xml_entry.attributes["sizeAfter"] = File.size(OS::Path::combine( output_dir, clip_base_name ) + ".zip").to_s()
xmldoc.root << xml_entry
end
# Reform the inputs to our processed node prior to it being handled by the rage converter
if @c.preview then
preview_inputs = []
input_lists[processed_clip_node].each do | input |
preview_inputs << OS::Path.combine( processed_clip_node.path, processed_clip_node.name, OS::Path.get_filename( input.filename ) )
end
processed_clip_node.reform_inputs_from( preview_inputs )
else
processed_clip_node.reform_inputs()
end
end
xmldoc.save(OS::Path::combine(@c.branch.common, "data") + "/clip_dictionary_build_data.xml")
end
end
#
# == Description
# Main network converter.
#
class NetworkConverter < ConverterBase
def initialize( project, branch )
super( project, branch )
NetworkConverter::log().info( "Initialising Network Converter" )
@nodes_to_process = []
end
# Return whether this converter can convert the specified content node.
def can_convert?( content )
( content.is_a?( Content::ProcessedNetworksZip ) )
end
def prebuild( )
NetworkConverter::log().info( "NetworkConverter.prebuild()." )
end
# Build the content.
def build( &block )
NetworkConverter::log().info( "NetworkConverter.build()." )
@nodes_to_process.each do |content_node|
input = content_node.inputs[0]
source_filename = input.filename
target_filename = content_node.filename
# extract source data
cache_dir = NetworkConverter::get_cache_dir( @branch, content_node )
imvf_filenames = ProjectUtil::data_zip_extract( source_filename, cache_dir, true )
mrf_filenames = []
# process data
imvf_filenames.each do |imvf_filename|
mrf_filename = OS::Path.remove_extension(imvf_filename) + ".mrf"
command = ''
@branch.in_env do |e|
command = e.subst("#{MAKENETWORK_CL} -file=\"#{imvf_filename}\" -out=\"#{mrf_filename}\"")
end
status, out, err = OS::start( command )
if ( status.exitstatus == 0 ) then
mrf_filenames << mrf_filename
NetworkConverter::log().info( "Converted '#{mrf_filename}'." )
else
NetworkConverter::log().error( "Failed to convert #{imvf_filename}." )
end
end
# build target zip
ProjectUtil::data_zip_create( target_filename, mrf_filenames, true )
end
result = {}
result[:conversion] = []
result[:success] = true
result
end
# Add the content to the build list (if valid).
def add_content( content )
NetworkConverter::log().info( "Network converter adding content..." )
if ( content.is_a?( Content::ProcessedNetworksZip ) ) then
@nodes_to_process << content
@nodes_to_process.uniq!
true
else
NetworkConverter::log().error( "Could not convert: #{content}." )
false
end
end
# Clear the content from the build list.
def clear( )
@nodes_to_process.clear()
end
#--------------------------------------------------------------------
# Private
#--------------------------------------------------------------------
private
# Return raw animation converter cache directory.
def NetworkConverter::get_base_cache_dir( branch )
c = ConvertSystem::instance( )
OS::Path::combine( c.cache_root, 'networks' )
end
# Return animation converter cache directory.
def NetworkConverter::get_cache_dir( branch, content_node )
OS::Path::combine( NetworkConverter::get_base_cache_dir( branch ), content_node.name )
end
# Return NetworkConverter log object.
def NetworkConverter::log()
@@log = Log.new( 'convert_network' ) if ( @@log.nil? )
@@log
end
@@log = nil
MAKENETWORK_CL = '$(toolsbin)/MoVE/tool/makenetwork.exe'
end
end # Converters module
end # Resourcing module
end # Pipeline module