Files
2025-09-29 00:52:08 +02:00

296 lines
6.8 KiB
Ruby
Executable File

#
#
# Author:: Mark Harrison-Ball <Mark.Harrison-Ball@rockstargames.com>
# Date:: 20 Februray 2013 (AP3)
# Purpose:
# ~ Class to read and compare anim data
path = File.expand_path $0
path = File.dirname(path)
require "#{path}/../../Global/anim/animCompare.rb"
require "#{path}/../../Global/anim/animReader.rb"
require "#{path}/../../Global/anim/animDump.rb"
require "#{path}/../../Global/anim/clipDump.rb"
require "#{path}/../../Global/anim/clipReader.rb"
require "#{path}/../../Global/array/arrayUtils.rb"
# need to sort out this!!!
require 'X:/gta5/tools/lib/pipeline/util/string'
class CutsceneCameraPairDef
attr_reader :translation
attr_reader :rotation
attr_reader :fov
attr_reader :blockTags
# We hold the differences in a new array so we can see what has changed
def initialize(pInputA, pInputB, clipInput)
@translation = [] # float
@rotation = [] # flaot
@fov = [] # int
@blockTags = [] #
#private
@tracksA = pInputA # Previous Track
@tracksB = pInputB # New Track
@clipInfo = clipInput
@arrayUtils = ArrayUtils.new()
compare()
end
public
# Test is comapre track has any changes
def hasChanged()
result = false
if TranslationChanged() then
result = true
end
if RotationChanged() then
result = true
end
if FovChanged() then
result = true
end
return result
end
# Properties
# Direction Comparrision Test
# Transaltion changed
def TranslationChanged()
return (@translation.min != @translation.max)
end
# Roataiton changed
def RotationChanged()
return (@rotation.min != @rotation.max)
end
# FOV changed
def FovChanged()
return (@fov.min != @fov.max)
end
# Range Difference Tests
# TODO: Set range tests, for x,y,z
#
# Return Translation Difference
def TranslationDiff()
return ( @arrayUtils.retMax(@translation) - @arrayUtils.retMin(@translation))
end
# Return Rotation Difference
def RotationDiff()
return ( @arrayUtils.retMax(@rotation) - @arrayUtils.retMin(@rotation))
end
# Return Fov Difference
def FovDiff()
return ( @arrayUtils.retMax(@fov) - @arrayUtils.retMin(@fov))
end
# build Clip Tag Liast
def intClipTagsList()
@clipInfo.each do |tag|
if tag.name == "'Block'" then
newTag = Array.new()
newTag << tag.tagstart
newTag << tag.tagend
@blockTags << newTag
end
end
#print @blockTags
end
def compare()
puts("comparing Tracks")
# get smallest and comapre agaist biggest : TODO
# We will round down
(0..@tracksA.size-1).each { |i|
#puts @tracksA[i].trackname
if @tracksA[i].trackname == 'cameraTranslation' then
#puts("comparing cameraTranslation")
#puts
#puts
#print @tracksA[i].trackData
#puts
#print @tracksB[i].trackData
@translation = returnTrackDifs( @tracksA[i].trackData, @tracksB[i].trackData)
#print @translation
elsif @tracksA[i].trackname == 'cameraRotation' then
#puts("comparing cameraRotation")
#puts
@rotation = returnTrackDifs( @tracksA[i].trackData, @tracksB[i].trackData)
elsif @tracksA[i].trackname == 'cameraFOV' then
#puts("comparing cameraFOV")
#puts
@fov = returnTrackDifs( @tracksA[i].trackData, @tracksB[i].trackData)
end
}
intClipTagsList()
end
private
def returnTrackDifs(trackDataA, trackDataB)
#puts "trackDataA = #{trackDataA.size}"
#puts "trackDataB = #{trackDataB.size}"
trackdifs = Array.new()
isVector = false
isValidtrans = false
if trackDataA[0].class == Array then
isVector = true
# Test is we are comparing quantaeetion to Euler (BAD)
if trackDataA[0].size == trackDataB[0].size
isValidtrans = true
end
end
#puts "isValidtrans = #{isValidtrans}"
# Loop through the main track
(0..trackDataA.size-1).each { |i|
if isVector then # if its a float array
# Test if we are comparing the Same number in our subawway Roataions (we shoudl nto need to do this)
#puts "#{trackDataA[i].size} == #{trackDataB[i].size}"
if isValidtrans == true then
w = Array.new()
(0..trackDataA[i].size-1).each { |n|
# Test if we still have a valid track to test against
trackB = 0.0
if trackDataB[i] != nil
trackB =trackDataB[i][n]
end
dif = retFloat(validate(trackDataA[i][n]) - validate(trackB))
#print dif, ":"
if dif == -0.0 then
dif = 0.0
end
w << dif
}
trackdifs << w
else
trackdifs << [0,0,0]
end
else
w = retFloat(validate(trackDataA[i]) - validate(trackDataB[i]))
if w == -0.0 then
w = 0.0
end
trackdifs << w # else its a int array
end
}
return trackdifs
end
def validate(fValue)
result = 0.0
if fValue != nil then
result = fValue
end
return result
end
# Retrun float to defined percesion
def retFloat(fValue)
# floating percextion
#percesion = 1000.0
#return ((fValue*100).round / 100.0)
#return (('%.2f' % fValue).to_f)
# Test with one decimal place as it will be noticeable camera change
return (('%.1f' % fValue).to_f)
#return fValue.to_f
end
end
# Class to read in and create a track class object
class CutsceneAnimCompare
def initialize(config, log, p4)
@p4 = p4
@animDump = AnimDump.new(config, log)
@animReader = AnimReader.new(config, log)
@clipDump = ClipDump.new(config, log)
@clipReader = ClipReader.new(config, log)
end
public
# animfile input
# No extension
def compare(animname)
trackArrayA = nil
trackArrayB = nil
clipInfo = nil
cutCameraPairDef = nil
animfile = animname+'.anim'
clipfile = animname+'.clip'
revIndex = @p4.get_file_info(animfile, 'headRev')
if revIndex.to_i > 1 then
args = '#'+(revIndex.to_i-1).to_s
# Sync to previous revison of anim file
@p4.sync(animfile, args)
trackArrayA = parseAnim(animfile)
# Sync to head revison of anim file
@p4.sync(animname+'.*')
trackArrayB = parseAnim(animfile)
# Collect the Clip Info
clipInfo = parseClip(clipfile)
# compare both anim tracks
cutCameraPairDef = CutsceneCameraPairDef.new(trackArrayA, trackArrayB, clipInfo)
end
return cutCameraPairDef
end
private
def parseAnim(animfile)
# extract the export camera anim file
@animDump.dump(animfile)
# read the contents and return
return @animReader.parse(animfile+".txt")
end
def parseClip(clipfile)
@clipDump.dump(clipfile)
# read the contents and return
return @clipReader.parse(clipfile+".txt")
end
end