'/// TransActionSource: ver 1.0 for XSI 3.5+
'/// By Homam Bahnassi - In|Framez 2003
'--------------------------------------

set oSelection = Application.Selection

PickElement "model", "Select Target Model", "Select Target Model", oModel, button
if button = 0 then logmessage "TransActionSource: Canceled by user..."

TransActionSource oSelection,oModel

function TransActionSource(oActionSourceCollection,oTargetModel)

TransActionSource = false

'--- Checking oActionSourceCollection...
if oActionSourceCollection.count = 0 then
	logmessage "TransActionSource: ActionSources required..."
	exit function
end if

'--- Checking oTargetModel...
if typename(oTargetModel) <> "Model" then
	logmessage "TransActionSource: Invaled Model..."
	exit function
end if

'--- Saving any existing animation on Target Model
set oTargetTree = oTargetModel.FindChildren()
set oDstAnimatedParams = CreateObject("XSI.Collection")
for each oTargetNode in oTargetTree
	set oDstAnimParams = oTargetNode.AnimatedParameters
	for each oDstAnimParam in oDstAnimParams
		oDstAnimatedParams.add oDstAnimParam
	next
next
GetAnimLimits oTargetTree,iStartTime,iEndTime
set oTargetTempAction = StoreAction (oTargetModel, oDstAnimatedParams, 6, "TempAction", true, iStartTime, iEndTime, false, false, false, 1)

'--- Saving any existing animation on Source Model
set oSrcModel = oActionSourceCollection(0).Model
set oSrcTree = oSrcModel.FindChildren()
set oSrcAnimatedParams = CreateObject("XSI.Collection")
for each oSrcNode in oSrcTree
	set oSrcAnimParams = oSrcNode.AnimatedParameters
	for each oSrcAnimParam in oSrcAnimParams
		oSrcAnimatedParams.add oSrcAnimParam
	next
next
GetAnimLimits oSrcTree,iStartTime,iEndTime
set SrcTempAction = StoreAction (oSrcModel, oSrcAnimatedParams, 6, "TempAction", true, iStartTime, iEndTime, false, false, false, 1)

set oParams = CreateObject("XSI.Collection")

for each oTargetNode in oTargetTree
	'---- Store Plotted Parameters
	oParams.add oTargetNode & ".kine.local.rotx"
	oParams.add oTargetNode & ".kine.local.roty"
	oParams.add oTargetNode & ".kine.local.rotz"
	oParams.add oTargetNode & ".kine.local.posx"
	oParams.add oTargetNode & ".kine.local.posy"
	oParams.add oTargetNode & ".kine.local.posz"
next

'--- Constrain Rigs
SetUserPref "SI3D_CONSTRAINT_COMPENSATION_MODE", 0
on error resume next
for each oTargetNode in oTargetTree
	ApplyCns "Pose", oTargetNode, oSrcModel & "." & oTargetNode.name
next
on error goto 0

for each oSourceClip in oActionSourceCollection
	if oSourceClip.Type <> "Action" then
		logmessage "TransActionSource: " & oSourceClip & "is not a valid ActionSource... Caceled"
	else
		sTargetName = oSourceClip.Name
		ApplyAction oSourceClip,oSrcModel , false, 0, 0, false

		set oSrcTree = oSrcModel.FindChildren()
		GetAnimLimits oSrcTree,iStartTime,iEndTime
		
		'--- Plot & Filter Animation
		PlotAndApplyAction oTargetModel, oParams, sTargetName, iStartTime, iEndTime, 1, 20, 2, true, 0.01, true, false, true, true

		'--- Remove Constrains
		for each oTargetNode in oTargetTree
			DeleteObj oTargetNode & ".kine.posecns"
		next

		'--- Remove Applied Animation from source tree
		for each oSrcNode in oSrcTree
			RemoveAllAnimation oSrcNode, 1, siUnspecified, siFCurveSource, siAllParam
		next
	end if
next

'--- Restoring any old animation on the Source and Target Model
ApplyAction SrcTempAction,oSrcModel , false, 0, 0, false
ApplyAction oTargetTempAction ,oTargetModel , false, 0, 0, false
DeleteObj SrcTempAction
DeleteObj oTargetTempAction 

TransActionSource = true

end function

function GetAnimLimits(oObjCollection,iMinTimeNew,iMaxTimeNew)
	'--- Checking oObjCollection
	if typename(oObjCollection) <> "X3DObjectCollection" then
		logmessage "GetAnimLimits: Objects collection required..."
		exit function
	end if
	
	'--- Intialize Outputs
	set oAnimParams = oObjCollection(0).AnimatedParameters( siAnySource )
	on error resume next
	iMaxTimeNew = oAnimParams(0).source.keys(0).time
	iMaxTimeNew = oAnimParams(0).source.keys(oAnimParams(0).source.GetNumKeys-1).time

	for each Obj in oObjCollection
		set oAnimatedParams = Obj.AnimatedParameters( siAnySource )

		for each oParam in oAnimatedParams
			set oFcurve = oParam.source
			set oKeys = oFcurve.Keys
			iMinTime = oKeys(0).time
			iMaxTime = oKeys(oFCurve.GetNumKeys-1).time
			if iMinTime < iMinTimeNew then iMinTimeNew = iMinTime
			if iMaxTime > iMaxTimeNew then iMaxTimeNew = iMaxTime
		next
	next
	on error goto 0
end function
