'******************************************************************************
'
' File supervisor : Ronald Beirouti
'
' (c) Copyright 2003 Softimage
'
' $Archive:  $
' $Revision: grahamdclark.com  $Date:  29/05/2004
' Backup your old simulation.vbs file and copy this one to C:\Softimage\XSI_4.0\Application\DSScripts
' I assume no responsibility for lost work, minds or children due to the use of this modified version.
' Use at your own risk.
'
' Checkin by: $Author:  $
'
' @doc		EXTERNAL
'
' @module	simulation.vbs
'
'******************************************************************************

' Ensure that all variables are explicitly declared
'Option explicit

'******************************************************************************
' DEBUGGING
'******************************************************************************

' DEVNOTE: remove comment to force a break point when script loaded.
'stop

'******************************************************************************
' CONSTANTS
'******************************************************************************

'******************************************************************************
' Public Functions/Subroutines
'******************************************************************************



'------------------------------------------------------------------------------
' NAME:		SetRigidBodyInitialStateProc
'
' DESCRIPTION: Set the rigid body initial state of the selected objects. 
'------------------------------------------------------------------------------
sub SetRigidBodyInitialStateProc( in_objs )

	set l_ObjectList = SIFilter( in_objs, siObjectFilter )

	for each l_obj in l_ObjectList
		
		set global = l_obj.kinematics.global

		set initstate = l_obj.properties.find("DynamicsInitState")

		if typename( initstate ) <> "Nothing" then
	
			initstate.parameters("posx").value = global.Parameters("posx").value 
			initstate.parameters("posy").value = global.Parameters("posy").value 
			initstate.parameters("posz").value = global.Parameters("posz").value

			initstate.parameters("rotx").value = global.Parameters("rotx").value 
			initstate.parameters("roty").value = global.Parameters("roty").value 
			initstate.parameters("rotz").value = global.Parameters("rotz").value

			initstate.parameters("posfromanim").value = false
			initstate.parameters("linvelfromanim").value = false
			initstate.parameters("rotfromanim").value = false
			initstate.parameters("angvelfromanim").value = false

		end if
	next

end sub

'------------------------------------------------------------------------------
' NAME:		GetRigidBodyInitialStateFromAnimProc
'
' DESCRIPTION: Let the rigid body to use animation as its initial state. 
'------------------------------------------------------------------------------
function GetRigidBodyInitialStateFromAnimProc ( in_objs )

	set l_ObjectList = SIFilter( in_objs, siObjectFilter )

	for each l_obj in l_ObjectList
		
		set initstate = l_obj.properties.find("DynamicsInitState")

		if typename( initstate ) <> "Nothing" then
	
			initstate.parameters("posfromanim").value = true
			initstate.parameters("linvelfromanim").value = true

			initstate.parameters("rotfromanim").value = true
			initstate.parameters("angvelfromanim").value = true

		end if
	next

end function

'------------------------------------------------------------------------------
' NAME:		SetActiveRigidBodyProc
'
' DESCRIPTION: Set the rigid body initial state of the selected objects. 
'------------------------------------------------------------------------------
function SetActiveRigidBodyProc ( byref in_objs )

	set propcoll = CreateObject("XSI.Collection")  
	set l_ObjectList = SIFilter( in_objs, siObjectFilter )

	set in_objs = l_ObjectList 	

	if typename(l_ObjectList) <> "Nothing" then

		for each l_obj in l_ObjectList

			'Get the default environment
			set oEnvironments = Dictionary.GetObject("Environments")				
			set oDefaultEnvironment = EnumElements(oEnvironments)(1)

			'Check if the object is already owned by an Environment	
			l_needToModifyRBD = true		
			for each l_owner in l_obj.owners
				aNames = split(l_owner.fullname,".")
				if aNames(0) = "Environments" then
					if aNames(1) = oDefaultEnvironment.name  then					
						propcoll.add l_obj.Properties("Rigid Body Properties")
						l_obj.Properties("Rigid Body Properties").passive = false						
						l_needToModifyRBD = false
						exit for
					else
						logmessage "CreateActiveRigidBody: The object " +  l_obj.fullname +" is already part of a simulation environment. It will not be added to the current environment", siError	
						exit function
					end if
					
				end if
			next
				
			if l_needToModifyRBD = true then
				if typename(oDefaultEnvironment) = "Parameter" then
					dim l_env, l_rbGroup
					set l_env  = CreateEnvironment( "Environment" )

					set l_rbGroup  = AddContainerToEnvironment( l_env,"RigidBody",1,"RigidBodies")
					AddContainerToEnvironment l_env,"Constraint",1,"Constraints"
					AddContainerToEnvironment l_env,"Force",1,"Forces"

					set oCache = CreateEnvironmentCache( l_env )
					oCache.name = "Environment_Cache"

					AddToContainer l_rbGroup, l_obj.FullName  
					applyop "DynamicsOp" , l_env
				else
					set oContainerGroups = EnumElements(EnumElements(oDefaultEnvironment)(1))
					if typename(oContainerGroups)  = "Nothing" then
						set l_rbGroup  = AddContainerToEnvironment( oDefaultEnvironment,"RigidBody",1,"RigidBodies")
						AddContainerToEnvironment oDefaultEnvironment,"Constraint",1,"Constraints"
						AddContainerToEnvironment oDefaultEnvironment,"Force",1,"Forces"

						set oCache = CreateEnvironmentCache( oDefaultEnvironment )
						oCache.name = "Environment_Cache"

						AddToContainer l_rbGroup, l_obj.FullName  
						applyop "DynamicsOp" , oDefaultEnvironment
					else
						AddToContainer oDefaultEnvironment.fullname & ".RigidBodies", l_obj.FullName  
						if typename(EnumElements(EnumElements(oDefaultEnvironment)(4))) = "Nothing" then
							applyop "DynamicsOp" , oDefaultEnvironment
						end if
					end if
				end if

				l_obj.Properties("Rigid Body Properties").passive = false
				propcoll.Add l_obj.Properties("Rigid Body Properties")
			end if
		next

	end if

	AutoInspect l_ObjectList, , , "Dynamics"

	set SetActiveRigidBodyProc = propcoll

end function

'------------------------------------------------------------------------------
' NAME:		SetPassiveRigidBodyProc
'
' DESCRIPTION: Set the rigid body initial state of the selected objects. 
'------------------------------------------------------------------------------
function SetPassiveRigidBodyProc ( byref in_objs )

	set rigidbodyprops = SetActiveRigidBodyProc ( in_objs )

	for each prop in rigidbodyprops
		prop.passive = true
	next
	
end function

'------------------------------------------------------------------------------
' NAME:		MultiAttachRigidBodiesTool
'
' DESCRIPTION: Create a rigid constraint of the given type, launch a pick session to
' pick the bodies to attach to the constraint. 
'------------------------------------------------------------------------------
function MultiAttachRigidBodiesTool( in_CnsType,  in_Selection )

	dim l_button,l_PickedBody,l_modifier, l_trs, oBody, oCns
	dim x,y,z,button

	dim l_collBodiesToAttach, l_collFilteredSelection, l_collPositioning, l_collCnsBodies, l_collCns

	' filter the selection for objects
	set l_collBodiesToAttach	= CreateObject("XSI.Collection")
	set l_collPositioning		= CreateObject("XSI.Collection")	
	set l_collCnsBodies			= CreateObject("XSI.Collection")	
	set l_collFilteredSelection = CreateObject("XSI.Collection")
	set l_collCns				= CreateObject("XSI.Collection")

	set l_trs = XSIMath.CreateVector3 

	' update selection with filtered list
	set l_collFilteredSelection = SIFilter( in_Selection, siObjectFilter )

	if typename(l_collFilteredSelection) <> "Nothing" then
		l_collBodiesToAttach.AddItems l_collFilteredSelection
		Application.Selection.SetAsText l_collBodiesToAttach.GetAsText
	end if

	l_collCnsBodies.Unique		= true
	l_collBodiesToAttach.Unique = true

	'
	' Picking Loop. Exits on RMB or ESC key 
	'
	do until false

		PickElement , "Pick Bodies ", "Attach To", l_PickedBody, l_button, 0, l_modifier

		if l_button = 0 then exit do 'exit when RMB or ESC key

		if typename(l_PickedBody) = "X3DObject" then 
		'
		' check that the picked body is not a constraint
		' ValidateObject
		'
			select case l_button
				case 1 'LMB

					select case l_modifier
						case 0 'no modifier: replace selection with picked body
							l_collBodiesToAttach.RemoveAll
							l_collBodiesToAttach.Add l_PickedBody 
							Application.Selection.Clear
							Application.Selection.Add l_PickedBody
						case 1 'shift : add to selection
							l_collBodiesToAttach.Add l_PickedBody 
							Application.Selection.Add l_PickedBody
						case 2	'ctrl : toggle selection
							set oBody = l_collBodiesToAttach(l_PickedBody.name) 
							'if not found, add
 							if typename(oBody) = "Nothing" then
								l_collBodiesToAttach.Add l_PickedBody 
								Application.Selection.Add l_PickedBody
							'if found, remove
							else
								l_collBodiesToAttach.Remove l_PickedBody 
								Application.Selection.Remove l_PickedBody
							end if
						case 3	'ctrl+shift: connect to world with a picked position
							' used when connecting bodies to the world
							PickPosition "Pick Cns Position", " ", x,y,z, button
							l_trs.Set x,y,z
							set oCns = AttachRigidBodies(in_CnsType, l_PickedBody.Name , l_trs.x, l_trs.y, l_trs.z)
							if typename(oCns) <> "Nothing" then l_collCns.Add oCns
					end select
				case 2 'MMB

					for each oBody in l_collBodiesToAttach

						l_collCnsBodies.RemoveAll
						l_collCnsBodies.Add oBody
						l_collCnsBodies.Add l_PickedBody

						l_collPositioning.RemoveAll
					
						'special case: if MMB pick the same body as LMB
						'pick position and connect constraint to world
						if l_collCnsBodies.count = 1 then
								PickPosition "Pick Constraint Location", " ", x,y,z, button
								l_trs.Set x,y,z
						else
							select case l_modifier
								case 0	'none : anchor cns at body picked with MMB
									l_collPositioning.Add l_PickedBody
									set l_trs = GetAvgPosOfColl(l_collPositioning)
								case 1	'shift : anchor cns at body picked with LMB 
									l_collPositioning.Add oBody
									set l_trs = GetAvgPosOfColl(l_collPositioning)
								case 2	'ctrl : anchor cns at midpoint
									l_collPositioning.Add l_PickedBody
									l_collPositioning.Add oBody
									set l_trs = GetAvgPosOfColl(l_collPositioning)
								case 3	'ctrl+shift : pick anchor position
									PickPosition "Pick Constraint Location", " ", x,y,z, button
									l_trs.Set x,y,z
							end select
						end if

						set oCns = AttachRigidBodies(in_CnsType, l_collCnsBodies.GetAsText , l_trs.x, l_trs.y, l_trs.z)
						if typename(oCns) <> "Nothing" then l_collCns.Add oCns

					next 
					
					'replace pick list with MMB selection. For chaining
					l_collBodiesToAttach.RemoveAll
					l_collBodiesToAttach.Add l_PickedBody

					Application.Selection.Clear
					Application.Selection.Add l_PickedBody

			end select
		else
			logmessage "AttachRigidBodies: picked element is not a rigid body", siError
		end if

		set l_PickedBody = Nothing
	loop

	'select the created constraints
	if l_collCns.count > 0 then
		Application.Selection.Clear
		Application.Selection.SetAsText l_collCns.GetAsText
		AutoInspect l_collCns, , , siSimulationKeyword
	end if

end function

'--------------------------------------
' Get Rigid Bodies
'--------------------------------------
function GetAvgPosOfColl (in_bodyColl )	
	
	dim l_body,l_Trs,l_AvgTrs
	set l_AvgTrs = XSIMath.CreateVector3
	set l_Trs = XSIMath.CreateVector3 

	l_AvgTrs.Set 0,0,0

	for each l_body in in_bodyColl
		l_body.Kinematics.Global.Transform.GetTranslation l_Trs
		l_AvgTrs.AddInPlace l_Trs
	next

	l_AvgTrs.ScaleInPlace 1/in_bodyColl.count

	set GetAvgPosOfColl = l_AvgTrs

end function

'------------------------------------------------------------------------------
' NAME:		AttachRigidBodiesProc
'
' DESCRIPTION: Create a constraint, add to environment, add bodies to group.
'------------------------------------------------------------------------------

function AttachRigidBodiesProc ( in_CnsType, in_RigidBodiesToAttach, in_px, in_py, in_pz )

	dim l_rtn,l_cns, oEnvironments, oDefaultEnvironment, oRB, oContainerGroups, oRBDGroup

	set AttachRigidBodiesProc = nothing

	if in_RigidBodiesToAttach.count = 0 then
		logmessage "AttachRigidBodies: No rigid bodies to attach", siError
		set AttachRigidBodiesProc = nothing
		exit function
	end if

	'
	' go through the object list and make sure we are not constraining to a constraint
	' ValidateObject
	'
	for each oRB in in_RigidBodiesToAttach
		if ValidateRigidBody(oRB) = false then
			logmessage oRB & " is not a rigid body, no constraint was created", siError
			exit function
		end if
	next

	'Get the default environment
	set oEnvironments = Dictionary.GetObject("Environments")
	set oDefaultEnvironment = EnumElements(oEnvironments)(1)				

	'Only add the constraint if we have an environment to add to 
	if typename(oDefaultEnvironment) = "Parameter" then
		logmessage "AttachRigidBodies: There is no simulation environment. No constraint was created", siError
		exit function
	end if

	'
	' go through the object list and make sure that all object are rigid bodies under 
	' the same environment.
	'
	set oContainerGroups = EnumElements(EnumElements(oDefaultEnvironment)(1))
	if typename(oContainerGroups) = "Nothing" then
		logmessage "AttachRigidBodies: No rigid bodies to attach", siError
		exit function
	end if

	set oRBDGroup = oContainerGroups(0)

	l_isRBDFromSameEnvironment = false
	for each oRB in in_RigidBodiesToAttach						
		for each oM in oRBDGroup.Members
			if om.IsEqualTo(oRB) = true then
				l_isRBDFromSameEnvironment = true				
			end if						
		next
		if l_isRBDFromSameEnvironment = false then		
			logmessage oRB & " is not a rigid body in the same environment, no constraint was created", siError
			exit function
		end if
	next
	
	'
	' create the constraint and add it to the environment
	'
	set l_rtn = SIGetPrim(in_CnsType,in_CnsType)
	set l_cns = l_rtn.value("Value") 

	AddToContainer oDefaultEnvironment.fullname & ".Constraints", l_cns.FullName  
	'add the rigid bodies to the constraint group
	SIAddToGroup l_cns & ".RigidCns.AttachedBodies", in_RigidBodiesToAttach

	dim CnsXfo
	set CnsXfo = XSIMath.CreateTransform
	CnsXfo.SetTranslationFromValues in_px,in_py,in_pz
	l_cns.kinematics.global.transform = CnsXfo

	SetRigidBodyInitState l_cns

	DeselectAll
	SelectObj l_cns

	set AttachRigidBodiesProc = l_cns

end function


'------------------------------------------------------------------------------
' NAME:		GetNbAttachedBodies
'
' DESCRIPTION: count the number of bodies in the attached bodies group
'------------------------------------------------------------------------------
function GetNbAttachedBodies( in_oCns )

	GetNbAttachedBodies = 0

	dim oAttachedBodies
	set oAttachedBodies = EnumElements(in_oCns.ActivePrimitive & ".Attached Bodies.Members")

	if typename(oAttachedBodies) = "Nothing" then exit function

	GetNbAttachedBodies = oAttachedBodies.count

end function


'------------------------------------------------------------------------------
' NAME:		AttachRigidBodiesToolProc
'
' DESCRIPTION: Create a constraint, add to environment, add bodies to group.
'------------------------------------------------------------------------------

function AttachRigidBodiesToolProc( in_CnsType, in_RigidBodiesToAttach, inoutX, inoutY, inoutZ)

	dim l_rtn,l_cns, oEnvironments, oDefaultEnvironment, oRB, oContainerGroups, oRBDGroup, l_button

	set AttachRigidBodiesToolProc = nothing

	'
	' create the constraint
	'
	set l_rtn = SIGetPrim(in_CnsType,in_CnsType)
	set l_cns = l_rtn.value("Value") 

	'''''''''''''''''''''''''''''
	' Filter the selection for objects
	'
	set l_collBodiesToAttach	= CreateObject("XSI.Collection")
	set l_collFilteredSelection	= CreateObject("XSI.Collection")
	set l_collBodiesAttached	= CreateObject("XSI.Collection")

	' update selection with filtered list
	set l_collFilteredSelection = SIFilter( in_RigidBodiesToAttach, siObjectFilter )

	if typename(l_collFilteredSelection) <> "Nothing" then

		for each oRB in l_collFilteredSelection
			if ValidateRigidBody(oRB) = true then 
				l_collBodiesToAttach.Add  oRB
			end if
		next

		Application.Selection.Clear
		if l_collBodiesToAttach.count > 0 then
			Application.Selection.SetAsText l_collBodiesToAttach.GetAsText
		end if
	end if

	''''''''''''''''''''''''''''''''''''''''''
	' move the constraint to desired position
	'
	' if the selection was empty pick a position, otherwise use the average position of selection

	set l_trs = XSIMath.CreateVector3 
	if l_collBodiesToAttach.count = 0 then
		PickPosition "Pick Cns Position", " ", inoutX,inoutY,inoutZ, l_button
		l_trs.Set inoutX,inoutY,inoutZ
	else
		set l_trs = GetAvgPosOfColl(l_collBodiesToAttach)
		inoutX = l_trs.x
		inoutY = l_trs.y
		inoutZ = l_trs.z
	end if

	dim CnsXfo
	set CnsXfo = XSIMath.CreateTransform

	CnsXfo.SetTranslation  l_trs
	l_cns.kinematics.global.transform = CnsXfo

	'add any existing bodies to the constraint
	for each oRB in l_collBodiesToAttach
		if GetNbAttachedBodies(l_cns) >= 2 then 
			exit for 
		else
			dim oBody
			set oBody = AttachRBToCns( l_cns, oRB )
			if typename(oBody) <> "Nothing" then 
				l_collBodiesAttached.Add  oBody
			end if
		end if
	next

	if l_collBodiesToAttach.count < 2 then
		'while picking and not more than 2 bodies attached, attach bodies INTERACTIVELY

		BodyPrompt = Array(" 1st "," 2nd ")
		dim prompt1, prompt2, l_PickedBody

		l_button = 1
		while  l_button <> 0 and GetNbAttachedBodies(l_cns) < 2 

			prompt = "Pick" & BodyPrompt(GetNbAttachedBodies(l_cns)) & "Rigid Body To Attach"

			set l_PickedBody = nothing
			PickElement , prompt, prompt, l_PickedBody, l_button, 0, l_modifier
			dim oAttachedBody
			set oAttachedBody = AttachRBToCns(	l_cns, l_PickedBody )

			if typename(oAttachedBody) <> "Nothing" then 
				l_collBodiesAttached.Add oAttachedBody
			end if
		wend
	else
	end if

	DeselectAll
	SelectObj l_cns

	AutoInspect l_cns, , , siSimulationKeyword

	in_RigidBodiesToAttach.Clear
	in_RigidBodiesToAttach.AddItems l_collBodiesAttached 

	set AttachRigidBodiesToolProc = l_collBodiesAttached

end function

'------------------------------------------------------------------------------
' NAME:		AttachRBToCns
'
' DESCRIPTION: Helper that attaches a single body to an existing constraint.
'------------------------------------------------------------------------------
function AttachRBToCns( in_Cns, in_RB ) 

	set AttachRBToCns = nothing

	'
	' go through the object list and make sure we are not constraining to a constraint
	' ValidateObject
	'
	if ValidateRigidBody(in_RB) = false then 
		exit function
	end if

	'Get the default environment
	set oEnvironments = Dictionary.GetObject("Environments")
	set oDefaultEnvironment = EnumElements(oEnvironments)(1)				

	'Only add the constraint if we have an environment to add to 
	if typename(oDefaultEnvironment) = "Parameter" then
		logmessage "AttachRigidBodyToConstraint: There is no simulation environment to add the constraint to.", siError
		exit function
	end if

	'
	' go through the object list and make sure that all object are rigid bodies under 
	' the same environment.
	'
	set oContainerGroups = EnumElements(EnumElements(oDefaultEnvironment)(1))
	if typename(oContainerGroups) = "Nothing" then
		logmessage "AttachRigidBodyToConstraint: " & oDefaultEnvironment & " has no rigid bodies to attach", siError
		exit function
	end if

	set oRBDGroup = oContainerGroups(0)

	l_isRBDFromSameEnvironment = false
	for each oM in oRBDGroup.Members
		if om.IsEqualTo(in_RB) = true then
			l_isRBDFromSameEnvironment = true				
		end if						
	next
	if l_isRBDFromSameEnvironment = false then		
		logmessage in_RB & " is not a rigid body in the same environment, body will not be attached to constraint.", siError
		exit function
	end if

	'
	' add to environtment if not already there
	AddToContainer oDefaultEnvironment.fullname & ".Constraints", in_Cns.FullName  
	' Add the body to the constraint's attached bodies group
	SIAddToGroup in_Cns & ".RigidCns.AttachedBodies", in_RB

	SetRigidBodyInitState in_Cns

	set AttachRBToCns = in_RB

end function


'------------------------------------------------------------------------------
' NAME:		ValidateRigidBody
'
' DESCRIPTION: Make sure we can use this object as a rigid body
'------------------------------------------------------------------------------
function ValidateRigidBody( in_RigidBody )

	ValidateRigidBody = false

	if typename(in_RigidBody) = "Nothing" then exit function
	'must be a 3D object
	'if typename(in_RigidBody) <> "X3DObject" then exit function
	'cannot attach constriant to another constraint
	if in_RigidBody.ActivePrimitive.Name = "Rigid Dynamics Cns" then exit function

	ValidateRigidBody = true

end function

'------------------------------------------------------------------------------
' NAME:		RemoveRigidBodyProc
'
' DESCRIPTION: Remove the objects from the rigid body simulation
'------------------------------------------------------------------------------
function RemoveRigidBodyProc ( byref in_objs )

	set propcoll = CreateObject("XSI.Collection")  
	set l_ObjectList = SIFilter( in_objs, siObjectFilter )

	set in_objs = l_ObjectList 	

	for each obj in in_objs
		for each oOwner in obj.owners
			
			if oOwner.type = "#Group" then
				if oOwner.parent.type = "Environment" then
					RemoveFromGroup oOwner, obj
				end if
			end if

		next
		
	next	

end function



function StoreEnvironmentCacheToMixerProc( byref in_environment, byref in_name, byref in_addclip )
	'modified grahamdclark.com for Action Synthese 2004
	dim l_pos
	dim l_ui

	' by default not ui
	l_ui = false

	set StoreEnvironmentCacheToMixerProc = nothing

	' get ui encoding in name (hack, but better than passing a ui argument)
	if( in_name = "(UIOnly)" ) then
		l_ui = true
		in_name = "SimulationRun"
	end if

	if( l_ui ) then

		set oPSet = ActiveSceneRoot.AddProperty( "CustomProperty", false, "StoreEnvironmentCacheToMixer" )
		set oLayout = oPSet.PPGLayout

		set oPName		= oPSet.AddParameter2("ActionName", siString, "SimulationRun",,,,,,,"Action Name", "The name given to the new action created" ) 
		set oPAddClip	= oPSet.AddParameter2("AddClip"   ,	siBool  , false          ,,,,,,,"Add Clip To Mixer", "If checked, adds a clip to the mixer on a new track")
		'modified grahamdclark.com for Action Synthese 2004
		set oPAddAction2SelectedModelsMixer	= oPSet.AddParameter2("AddAction2SelectedModelsMixer"   ,	siBool  , false          ,,,,,,,"AddAction2SelectedModelsMixer", "If checked, adds a clip to the mixer on a new track of selected Model")
		set oPAddClip2SelectedModelsMixer	= oPSet.AddParameter2("AddClip2SelectedModelsMixer"   ,	siBool  , false          ,,,,,,,"AddClip2SelectedModelsMixer", "If checked, also adds a clip on a new track to the mixer of selected Model")

		if not InspectObj( oPSet, , "Store environment cache in mixer", siModal, false ) then
			
			in_name = oPName.value
			in_addclip = oPAddClip.value

			'Create the Action
			'modified grahamdclark.com for Action Synthese 2004
			set oSource = SIStoreEnvironmentCacheToMixer( in_environment, in_name, in_addclip)
			if (oPSet.AddAction2SelectedModelsMixer.value) or (oPSet.AddClip2SelectedModelsMixer.value) then
			if (selection(0).type = "#model") then
				copyTemplatedAction2Model selection(0), oSource,in_environment,in_name,oPSet.AddClip2SelectedModelsMixer.value
			end if
			end if
		End If

		DeleteObj oPSet
	Else
		SIStoreEnvironmentCacheToMixer in_environment, in_name, in_addclip
	end if

end function

function copyTemplatedAction2Model(oModel,oSource,in_environment,in_name,clipvalue)
'grahamdclark.com for Action Synthese 2004
			if oModel.HasMixer then
				set oMixer = oModel.mixer
			else
				set oMixer = oModel.addmixer
			end if
			CreateEmptyConnectionMap oModel, oCnxMap 
			for i = 0 to oSource.SourceItems.count - 1 
				AddMappingRule oCnxMap, oSource.SourceItems.item(i).Target, Mid(oSource.SourceItems.item(i).Target,Instr(oSource.SourceItems.item(i).Target, ".")+1)
			next 
			'set oNewSource = CopySourceActionToFolder(oSource, oModel&".Mixer.Sources")'not possible no return object
			set oClip = AddClip( oModel, oSource, , , 1, oSource.name, oCnxMap,,false) 
			DeleteObj oCnxMap
			'I know the merge is stupid, but it allows us to delete the template and for a user to dragndrop the action onto the mixer track without need of the template in the future
			oSourceName = oSource.name
			DeleteObj oSource
			set oMergeClips = MergeClips(oClip)
			DeleteObj oClip.source
			oMergeClips.name = in_name
			if clipvalue then set oMergedClip = AddClip( oModel, oMergeClips, , , 1, oMergeClips.name)
			SetValue in_environment&".simtimectrl.active", False
end function