## SimulationEnvironment

Object Hierarchy | Related C++ Class: SimulationEnvironment

### Inheritance

###

SIObject

ProjectItem

SimulationEnvironment

### Introduced

v4.2

### Description

The SimulationEnvironment object represents a construct which is used to define a simulation. For now SimulationEnvironment objects are used only for RigidBody simulations. A simulation environment is a set of connection containers, one for each kind of element in the simulation: the rigid body objects, the rigid body constraints and the forces. The environment keeps track of the relationships between the objects in the simulation and determines on which objects the dynamics operator is applied. The dynamics operator solves the simulation for all elements that are in this environment. As well, a TimeControl object determines how the simulation in this environment is played back.
An environment is created as soon as you create a RigidBody object, which you can achieve by using CreateActiveRigidBody or CreatePassiveRigidBody. You can also explicitly create an environment by using CreateEnvironment. SimulationEnvironment object can be retrieved using Scene.ActiveSimulationEnvironment or Scene.SimulationEnvironments.

### Methods

AddCustomOp | AddICEAttribute | AddScriptedOp | AddScriptedOpFromFile
AnimatedParameters2 | BelongsTo | EvaluateAt | FindCacheForModel
GetICEAttributeFromName | IsA | IsAnimated2 | IsClassOf
IsEqualTo | IsKindOf | IsLocked | IsSelected
LockOwners | RemoveICEAttribute | SetAsSelected | SetCapabilityFlag
SetLock | TaggedParameters | UnSetLock |

### Properties

Application | BranchFlag | Caches | Capabilities
Categories | Containers | EvaluationID | Families
FullName | Help | HierarchicalEvaluationID | ICEAttributes
LockLevel | LockMasters | LockType | Model
Name | NestedObjects | ObjectID | Operators
Origin | OriginPath | Owners | PPGLayout
Parameters | Parent | Parent3DObject | Selected
SimulationTimeControl | Type |  |

### Examples

#### 1. JScript Example

    /*

    This example illustrates how to create a cached RigidBody simulation and

    apply that cache to animate the simulated objects directly without using

    the simulation.

    */

    NewScene( null, false );

    var oCone = ActiveSceneRoot.AddGeometry( "cone","MeshSurface" );

    var oModel = ActiveSceneRoot.AddModel();

    oModel.Name = "Model";

    var oGrid = oModel.AddGeometry( "grid","MeshSurface" );

    // Move the cone

    oCone.posy.value = 6.0;

    // Modify the grid

    oGrid.ulength.value = 24;

    oGrid.vlength.value = 24;

    oGrid.subdivu.value = 24;

    oGrid.subdivv.value = 24;

    // The following line creates the SimulationEnvironment object.

    CreatePassiveRigidBody( oGrid );

    CreateActiveRigidBody( oCone );

    CreateForce( "Gravity" );

    var oEnvironment = ActiveProject.ActiveScene.ActiveSimulationEnvironment;

    var oSimulationTimeControl = oEnvironment.SimulationTimeControl;

    // Turn the caching on.

    oSimulationTimeControl.caching.value = true;

    oSimulationTimeControl.playmode.value = 0; //Standard play mode.

    // Simulate

    // To make sure that all frames get simulated

    for ( i=0; i<100; i++ ) {

    	NextFrame();

    	Refresh();

    }

    // Get all models in the scene (getting the identifier of the Scene Root's class = Model)

    var sModelClassID = XSIUtils.DataRepository.GetIdentifier( ActiveSceneRoot, siObjectCLSID );

    var oModels = FindObjects( "", sModelClassID );

    ApplyCurrentEnvironmentCacheToSimulateObjectForModels( oModels );

    // The FCurve animated objects

    PlayForwardsFromStart();

    // This function takes the cached simulation and copies it directly

    // on the driven objects as FCurves. It also turns off the simulation

    // so that we could

    function ApplyCurrentEnvironmentCacheToSimulateObjectForModels( in_models )

    {

    	var eModels = new Enumerator( in_models );

    	var oCurrEnvironment = ActiveProject.ActiveScene.ActiveSimulationEnvironment;

    	var oSimulationTimeControl = oCurrEnvironment.SimulationTimeControl;

    	// Deactivate the simulation so that objects are driven by their

    	// animation.

    	oSimulationTimeControl.Active.Value = false;

    	for ( ; !eModels.atEnd(); eModels.moveNext() ) {

    		var oCurrModel = eModels.item();

    		var oCache = oCurrEnvironment.FindCacheForModel( oCurrModel );

    		var oSourceItems = oCache.SourceItems;

    		var eSourceItems = new Enumerator(oSourceItems);

    		for( ; !eSourceItems.atEnd(); eSourceItems.moveNext() ) {

    			var oSourceItem = eSourceItems.item();

    			strTarget = oSourceItem.Target;

    			if ( oCurrModel.IsEqualTo(ActiveSceneRoot) == false ) {

    				// ActionSource keeps the relative name of an

    				// animated parameter. We need to prepend the

    				// model name if the model owner is not the scene

    				// root in order to fetch the parameter.

    				strTarget = oCurrModel.Name + "." + strTarget;

    			}

    			var oTargetParameter = Dictionary.GetObject(strTarget);

    			// The RigidBody simulation caches linear acceleration which

    			// is not animatable. We won't be copying those values on

    			// the global transform.

    			if ( oTargetParameter.Animatable ) {

    				var oCachedFCurve = oSourceItem.Source;

    				CopyFCurveOnParameter( oCachedFCurve, oTargetParameter );

    			}

    		}

    	}

    }

    // This function creates a copy of an FCurve on a parameter by creating a new

    // FCurve on the parameter and adding all keys. It will take use the default

    // Tangent and Interpolation.

    function CopyFCurveOnParameter( in_FCurve, in_Parameter )

    {

    	var oNewFCurve = in_Parameter.AddFCurve2();

    	var oFCurveKeys = in_FCurve.Keys;

    	var eFCurveKeys = new Enumerator( oFCurveKeys );

    	oNewFCurve.BeginEdit();

    	for( ; !eFCurveKeys.atEnd(); eFCurveKeys.moveNext() ) {

    		var oCurrentKey = eFCurveKeys.item();

    		oNewFCurve.AddKey( oCurrentKey.time, oCurrentKey.value );

    	}

    	oNewFCurve.EndEdit();

    }

#### 2. Python Example

    #

    #     This example illustrates how to create cached RigidBody simulations, export

    #     that cache as an action source, import it into a new scene, and then

    #     instantiate it as a clip in the new mixer.

    #

    from win32com.client import constants as c

    Application.NewScene( "", 0 )

    oRoot = Application.ActiveSceneRoot

    oCone = oRoot.AddGeometry( "cone","MeshSurface" )

    oModel = oRoot.AddModel()

    oModel.Name = "TestModel"

    oGrid = oModel.AddGeometry( "grid","MeshSurface" )

    # Move the cone

    oCone.posy.Value = 6.0

    # Modify the grid

    oGrid.ulength.Value = 24

    oGrid.vlength.Value = 24

    oGrid.subdivu.Value = 24

    oGrid.subdivv.Value = 24

    # The following line creates the SimulationEnvironment object.

    Application.CreatePassiveRigidBody( oGrid )

    Application.CreateActiveRigidBody( oCone )

    Application.CreateForce( "Gravity" )

    oEnvironment = Application.ActiveProject.ActiveScene.ActiveSimulationEnvironment

    oSimulationTimeControl = oEnvironment.SimulationTimeControl

    # Turn the caching on.

    oSimulationTimeControl.caching.Value = 1;

    oSimulationTimeControl.playmode.Value = 0; #Standard play mode.

    # Simulate, making sure that all frames get simulated

    i=0

    while i < 100 :

    	Application.NextFrame()

    	Application.Refresh()

    	i = i + 1

    # Export the action sources

    aModelNames = [ "two", "one", "two", "one" ]

    sPath = Application.InstallationPath( c.siProjectPath )

    for oActionSource in oEnvironment.Caches :

    	Application.ExportAction( oActionSource, sPath + "\\Actions\\SimCache"

    		+ aModelNames.pop() + ".xsi" )

    # Dump the current scene and open a new one

    Application.NewScene( "", 0 )

    oRoot = Application.ActiveSceneRoot

    oCone = oRoot.AddGeometry( "cone","MeshSurface" )

    oGrid = oRoot.AddGeometry( "grid","MeshSurface" )

    # Reload the sources

    oNewAction = Application.ImportAction( oRoot, sPath + "\\Actions\\SimCache"

    	+ aModelNames.pop() + ".xsi", "MyImportedAction1", c.siSourceStorageTypeInternal )

    Application.AddClip( oRoot, oNewAction )

    oNewAction = Application.ImportAction( oRoot, sPath + "\\Actions\\SimCache"

    	+ aModelNames.pop() + ".xsi", "MyImportedAction2", c.siSourceStorageTypeInternal )

    Application.AddClip( oRoot, oNewAction );

    # Playback the results

    Application.PlayForwardsFromStart()

### See Also

Scene.ActiveSimulationEnvironment Scene.SimulationEnvironments SetCurrentEnvironment