2012-12-21 23:21:32 +00:00
/ *
* Copyright ( c ) Contributors , http : //opensimulator.org/
* See CONTRIBUTORS . TXT for a full list of copyright holders .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* * Redistributions in binary form must reproduce the above copyrightD
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ` ` AS IS ' ' AND ANY
* EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
* ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
* LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
using System ;
using System.Collections.Generic ;
2013-05-08 13:02:12 +00:00
using System.Reflection ;
2012-12-21 23:21:32 +00:00
using System.Text ;
using OpenSim.Region.Physics.Manager ;
using OpenMetaverse ;
using Nini.Config ;
namespace OpenSim.Region.Physics.BulletSPlugin
{
public static class BSParam
{
2013-05-08 13:02:12 +00:00
private static string LogHeader = "[BULLETSIM PARAMETERS]" ;
// Tuning notes:
// From: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=6575
// Contact points can be added even if the distance is positive. The constraint solver can deal with
// contacts with positive distances as well as negative (penetration). Contact points are discarded
// if the distance exceeds a certain threshold.
// Bullet has a contact processing threshold and a contact breaking threshold.
// If the distance is larger than the contact breaking threshold, it will be removed after one frame.
// If the distance is larger than the contact processing threshold, the constraint solver will ignore it.
// This is separate/independent from the collision margin. The collision margin increases the object a bit
// to improve collision detection performance and accuracy.
// ===================
// From:
2012-12-21 23:21:32 +00:00
// Level of Detail values kept as float because that's what the Meshmerizer wants
public static float MeshLOD { get ; private set ; }
2013-05-08 13:02:12 +00:00
public static float MeshCircularLOD { get ; private set ; }
2012-12-21 23:21:32 +00:00
public static float MeshMegaPrimLOD { get ; private set ; }
public static float MeshMegaPrimThreshold { get ; private set ; }
public static float SculptLOD { get ; private set ; }
2013-05-08 13:02:12 +00:00
public static int CrossingFailuresBeforeOutOfBounds { get ; private set ; }
public static float UpdateVelocityChangeThreshold { get ; private set ; }
2012-12-21 23:21:32 +00:00
public static float MinimumObjectMass { get ; private set ; }
public static float MaximumObjectMass { get ; private set ; }
2013-05-08 13:02:12 +00:00
public static float MaxLinearVelocity { get ; private set ; }
public static float MaxLinearVelocitySquared { get ; private set ; }
public static float MaxAngularVelocity { get ; private set ; }
public static float MaxAngularVelocitySquared { get ; private set ; }
public static float MaxAddForceMagnitude { get ; private set ; }
public static float MaxAddForceMagnitudeSquared { get ; private set ; }
public static float DensityScaleFactor { get ; private set ; }
2012-12-21 23:21:32 +00:00
public static float LinearDamping { get ; private set ; }
public static float AngularDamping { get ; private set ; }
public static float DeactivationTime { get ; private set ; }
public static float LinearSleepingThreshold { get ; private set ; }
public static float AngularSleepingThreshold { get ; private set ; }
public static float CcdMotionThreshold { get ; private set ; }
public static float CcdSweptSphereRadius { get ; private set ; }
public static float ContactProcessingThreshold { get ; private set ; }
public static bool ShouldMeshSculptedPrim { get ; private set ; } // cause scuplted prims to get meshed
public static bool ShouldForceSimplePrimMeshing { get ; private set ; } // if a cube or sphere, let Bullet do internal shapes
public static bool ShouldUseHullsForPhysicalObjects { get ; private set ; } // 'true' if should create hulls for physical objects
2013-05-08 13:02:12 +00:00
public static bool ShouldRemoveZeroWidthTriangles { get ; private set ; }
public static bool ShouldUseBulletHACD { get ; set ; }
public static bool ShouldUseSingleConvexHullForPrims { get ; set ; }
2012-12-21 23:21:32 +00:00
public static float TerrainImplementation { get ; private set ; }
2013-05-08 13:02:12 +00:00
public static int TerrainMeshMagnification { get ; private set ; }
2012-12-21 23:21:32 +00:00
public static float TerrainFriction { get ; private set ; }
public static float TerrainHitFraction { get ; private set ; }
public static float TerrainRestitution { get ; private set ; }
2013-05-08 13:02:12 +00:00
public static float TerrainContactProcessingThreshold { get ; private set ; }
2012-12-21 23:21:32 +00:00
public static float TerrainCollisionMargin { get ; private set ; }
2013-05-08 13:02:12 +00:00
public static float DefaultFriction { get ; private set ; }
public static float DefaultDensity { get ; private set ; }
public static float DefaultRestitution { get ; private set ; }
public static float CollisionMargin { get ; private set ; }
public static float Gravity { get ; private set ; }
// Physics Engine operation
public static float MaxPersistantManifoldPoolSize { get ; private set ; }
public static float MaxCollisionAlgorithmPoolSize { get ; private set ; }
public static bool ShouldDisableContactPoolDynamicAllocation { get ; private set ; }
public static bool ShouldForceUpdateAllAabbs { get ; private set ; }
public static bool ShouldRandomizeSolverOrder { get ; private set ; }
public static bool ShouldSplitSimulationIslands { get ; private set ; }
public static bool ShouldEnableFrictionCaching { get ; private set ; }
public static float NumberOfSolverIterations { get ; private set ; }
public static bool UseSingleSidedMeshes { get ; private set ; }
public static float GlobalContactBreakingThreshold { get ; private set ; }
2012-12-21 23:21:32 +00:00
// Avatar parameters
public static float AvatarFriction { get ; private set ; }
public static float AvatarStandingFriction { get ; private set ; }
2012-12-28 20:01:57 +00:00
public static float AvatarAlwaysRunFactor { get ; private set ; }
2012-12-21 23:21:32 +00:00
public static float AvatarDensity { get ; private set ; }
public static float AvatarRestitution { get ; private set ; }
public static float AvatarCapsuleWidth { get ; private set ; }
public static float AvatarCapsuleDepth { get ; private set ; }
public static float AvatarCapsuleHeight { get ; private set ; }
2013-05-13 20:03:13 +00:00
public static float AvatarHeightLowFudge { get ; private set ; }
public static float AvatarHeightMidFudge { get ; private set ; }
public static float AvatarHeightHighFudge { get ; private set ; }
2012-12-21 23:21:32 +00:00
public static float AvatarContactProcessingThreshold { get ; private set ; }
2013-05-08 13:02:12 +00:00
public static float AvatarBelowGroundUpCorrectionMeters { get ; private set ; }
public static float AvatarStepHeight { get ; private set ; }
public static float AvatarStepApproachFactor { get ; private set ; }
public static float AvatarStepForceFactor { get ; private set ; }
public static float AvatarStepUpCorrectionFactor { get ; private set ; }
public static int AvatarStepSmoothingSteps { get ; private set ; }
// Vehicle parameters
public static float VehicleMaxLinearVelocity { get ; private set ; }
public static float VehicleMaxLinearVelocitySquared { get ; private set ; }
public static float VehicleMaxAngularVelocity { get ; private set ; }
public static float VehicleMaxAngularVelocitySq { get ; private set ; }
2012-12-21 23:21:32 +00:00
public static float VehicleAngularDamping { get ; private set ; }
2013-05-08 13:02:12 +00:00
public static float VehicleFriction { get ; private set ; }
public static float VehicleRestitution { get ; private set ; }
public static Vector3 VehicleLinearFactor { get ; private set ; }
public static Vector3 VehicleAngularFactor { get ; private set ; }
public static float VehicleGroundGravityFudge { get ; private set ; }
public static float VehicleAngularBankingTimescaleFudge { get ; private set ; }
public static bool VehicleDebuggingEnable { get ; private set ; }
// Convex Hulls
public static int CSHullMaxDepthSplit { get ; private set ; }
public static int CSHullMaxDepthSplitForSimpleShapes { get ; private set ; }
public static float CSHullConcavityThresholdPercent { get ; private set ; }
public static float CSHullVolumeConservationThresholdPercent { get ; private set ; }
public static int CSHullMaxVertices { get ; private set ; }
public static float CSHullMaxSkinWidth { get ; private set ; }
public static float BHullMaxVerticesPerHull { get ; private set ; } // 100
public static float BHullMinClusters { get ; private set ; } // 2
public static float BHullCompacityWeight { get ; private set ; } // 0.1
public static float BHullVolumeWeight { get ; private set ; } // 0.0
public static float BHullConcavity { get ; private set ; } // 100
public static bool BHullAddExtraDistPoints { get ; private set ; } // false
public static bool BHullAddNeighboursDistPoints { get ; private set ; } // false
public static bool BHullAddFacesPoints { get ; private set ; } // false
public static bool BHullShouldAdjustCollisionMargin { get ; private set ; } // false
// Linkset implementation parameters
2012-12-21 23:21:32 +00:00
public static float LinksetImplementation { get ; private set ; }
2013-05-08 13:02:12 +00:00
public static bool LinkConstraintUseFrameOffset { get ; private set ; }
public static bool LinkConstraintEnableTransMotor { get ; private set ; }
2012-12-21 23:21:32 +00:00
public static float LinkConstraintTransMotorMaxVel { get ; private set ; }
public static float LinkConstraintTransMotorMaxForce { get ; private set ; }
public static float LinkConstraintERP { get ; private set ; }
public static float LinkConstraintCFM { get ; private set ; }
public static float LinkConstraintSolverIterations { get ; private set ; }
public static float PID_D { get ; private set ; } // derivative
public static float PID_P { get ; private set ; } // proportional
2013-05-08 13:02:12 +00:00
// Various constants that come from that other virtual world that shall not be named.
2012-12-27 14:58:07 +00:00
public const float MinGravityZ = - 1f ;
public const float MaxGravityZ = 28f ;
public const float MinFriction = 0f ;
public const float MaxFriction = 255f ;
2013-05-08 13:02:12 +00:00
public const float MinDensity = 0.01f ;
2012-12-27 14:58:07 +00:00
public const float MaxDensity = 22587f ;
public const float MinRestitution = 0f ;
public const float MaxRestitution = 1f ;
2013-05-08 13:02:12 +00:00
// =====================================================================================
// =====================================================================================
2012-12-21 23:21:32 +00:00
2013-05-08 13:02:12 +00:00
// Base parameter definition that gets and sets parameter values via a string
public abstract class ParameterDefnBase
2012-12-21 23:21:32 +00:00
{
public string name ; // string name of the parameter
public string desc ; // a short description of what the parameter means
2013-05-08 13:02:12 +00:00
public ParameterDefnBase ( string pName , string pDesc )
{
name = pName ;
desc = pDesc ;
}
// Set the parameter value to the default
public abstract void AssignDefault ( BSScene s ) ;
// Get the value as a string
public abstract string GetValue ( BSScene s ) ;
// Set the value to this string value
public abstract void SetValue ( BSScene s , string valAsString ) ;
// set the value on a particular object (usually sets in physics engine)
public abstract void SetOnObject ( BSScene s , BSPhysObject obj ) ;
public abstract bool HasSetOnObject { get ; }
}
// Specific parameter definition for a parameter of a specific type.
public delegate T PGetValue < T > ( BSScene s ) ;
public delegate void PSetValue < T > ( BSScene s , T val ) ;
public delegate void PSetOnObject < T > ( BSScene scene , BSPhysObject obj ) ;
public sealed class ParameterDefn < T > : ParameterDefnBase
{
private T defaultValue ;
private PSetValue < T > setter ;
private PGetValue < T > getter ;
private PSetOnObject < T > objectSet ;
public ParameterDefn ( string pName , string pDesc , T pDefault , PGetValue < T > pGetter , PSetValue < T > pSetter )
: base ( pName , pDesc )
{
defaultValue = pDefault ;
setter = pSetter ;
getter = pGetter ;
objectSet = null ;
}
public ParameterDefn ( string pName , string pDesc , T pDefault , PGetValue < T > pGetter , PSetValue < T > pSetter , PSetOnObject < T > pObjSetter )
: base ( pName , pDesc )
2012-12-21 23:21:32 +00:00
{
2013-05-08 13:02:12 +00:00
defaultValue = pDefault ;
setter = pSetter ;
getter = pGetter ;
objectSet = pObjSetter ;
2012-12-21 23:21:32 +00:00
}
2013-05-08 13:02:12 +00:00
// Simple parameter variable where property name is the same as the INI file name
// and the value is only a simple get and set.
public ParameterDefn ( string pName , string pDesc , T pDefault )
: base ( pName , pDesc )
2012-12-21 23:21:32 +00:00
{
2013-05-08 13:02:12 +00:00
defaultValue = pDefault ;
setter = ( s , v ) = > { SetValueByName ( s , name , v ) ; } ;
getter = ( s ) = > { return GetValueByName ( s , name ) ; } ;
objectSet = null ;
}
// Use reflection to find the property named 'pName' in BSParam and assign 'val' to same.
private void SetValueByName ( BSScene s , string pName , T val )
{
PropertyInfo prop = typeof ( BSParam ) . GetProperty ( pName , BindingFlags . Public | BindingFlags . Static | BindingFlags . FlattenHierarchy ) ;
if ( prop = = null )
{
// This should only be output when someone adds a new INI parameter and misspells the name.
s . Logger . ErrorFormat ( "{0} SetValueByName: did not find '{1}'. Verify specified property name is the same as the given INI parameters name." , LogHeader , pName ) ;
}
else
{
prop . SetValue ( null , val , null ) ;
}
}
// Use reflection to find the property named 'pName' in BSParam and return the value in same.
private T GetValueByName ( BSScene s , string pName )
{
PropertyInfo prop = typeof ( BSParam ) . GetProperty ( pName , BindingFlags . Public | BindingFlags . Static | BindingFlags . FlattenHierarchy ) ;
if ( prop = = null )
{
// This should only be output when someone adds a new INI parameter and misspells the name.
s . Logger . ErrorFormat ( "{0} GetValueByName: did not find '{1}'. Verify specified property name is the same as the given INI parameter name." , LogHeader , pName ) ;
}
return ( T ) prop . GetValue ( null , null ) ;
}
public override void AssignDefault ( BSScene s )
{
setter ( s , defaultValue ) ;
}
public override string GetValue ( BSScene s )
{
return getter ( s ) . ToString ( ) ;
}
public override void SetValue ( BSScene s , string valAsString )
{
// Get the generic type of the setter
Type genericType = setter . GetType ( ) . GetGenericArguments ( ) [ 0 ] ;
// Find the 'Parse' method on that type
System . Reflection . MethodInfo parser = null ;
try
{
parser = genericType . GetMethod ( "Parse" , new Type [ ] { typeof ( String ) } ) ;
}
catch ( Exception e )
{
s . Logger . ErrorFormat ( "{0} Exception getting parser for type '{1}': {2}" , LogHeader , genericType , e ) ;
parser = null ;
}
if ( parser ! = null )
{
// Parse the input string
try
{
T setValue = ( T ) parser . Invoke ( genericType , new Object [ ] { valAsString } ) ;
// Store the parsed value
setter ( s , setValue ) ;
// s.Logger.DebugFormat("{0} Parameter {1} = {2}", LogHeader, name, setValue);
}
catch
{
s . Logger . ErrorFormat ( "{0} Failed parsing parameter value '{1}' as type '{2}'" , LogHeader , valAsString , genericType ) ;
}
}
else
{
s . Logger . ErrorFormat ( "{0} Could not find parameter parser for type '{1}'" , LogHeader , genericType ) ;
}
}
public override bool HasSetOnObject
{
get { return objectSet ! = null ; }
}
public override void SetOnObject ( BSScene s , BSPhysObject obj )
{
if ( objectSet ! = null )
objectSet ( s , obj ) ;
2012-12-21 23:21:32 +00:00
}
}
// List of all of the externally visible parameters.
// For each parameter, this table maps a text name to getter and setters.
// To add a new externally referencable/settable parameter, add the paramter storage
// location somewhere in the program and make an entry in this table with the
// getters and setters.
// It is easiest to find an existing definition and copy it.
/ /
2013-05-08 13:02:12 +00:00
// A ParameterDefn<T>() takes the following parameters:
2012-12-21 23:21:32 +00:00
// -- the text name of the parameter. This is used for console input and ini file.
// -- a short text description of the parameter. This shows up in the console listing.
2013-05-08 13:02:12 +00:00
// -- a default value
// -- a delegate for getting the value
// -- a delegate for setting the value
2012-12-21 23:21:32 +00:00
// -- an optional delegate to update the value in the world. Most often used to
// push the new value to an in-world object.
/ /
// The single letter parameters for the delegates are:
// s = BSScene
// o = BSPhysObject
2013-05-08 13:02:12 +00:00
// v = value (appropriate type)
private static ParameterDefnBase [ ] ParameterDefinitions =
2012-12-21 23:21:32 +00:00
{
2013-05-08 13:02:12 +00:00
new ParameterDefn < bool > ( "MeshSculptedPrim" , "Whether to create meshes for sculpties" ,
true ,
( s ) = > { return ShouldMeshSculptedPrim ; } ,
( s , v ) = > { ShouldMeshSculptedPrim = v ; } ) ,
new ParameterDefn < bool > ( "ForceSimplePrimMeshing" , "If true, only use primitive meshes for objects" ,
false ,
( s ) = > { return ShouldForceSimplePrimMeshing ; } ,
( s , v ) = > { ShouldForceSimplePrimMeshing = v ; } ) ,
new ParameterDefn < bool > ( "UseHullsForPhysicalObjects" , "If true, create hulls for physical objects" ,
true ,
( s ) = > { return ShouldUseHullsForPhysicalObjects ; } ,
( s , v ) = > { ShouldUseHullsForPhysicalObjects = v ; } ) ,
new ParameterDefn < bool > ( "ShouldRemoveZeroWidthTriangles" , "If true, remove degenerate triangles from meshes" ,
true ) ,
new ParameterDefn < bool > ( "ShouldUseBulletHACD" , "If true, use the Bullet version of HACD" ,
false ) ,
new ParameterDefn < bool > ( "ShouldUseSingleConvexHullForPrims" , "If true, use a single convex hull shape for physical prims" ,
true ) ,
new ParameterDefn < int > ( "CrossingFailuresBeforeOutOfBounds" , "How forgiving we are about getting into adjactent regions" ,
5 ) ,
new ParameterDefn < float > ( "UpdateVelocityChangeThreshold" , "Change in updated velocity required before reporting change to simulator" ,
0.1f ) ,
new ParameterDefn < float > ( "MeshLevelOfDetail" , "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)" ,
32f ,
2012-12-21 23:21:32 +00:00
( s ) = > { return MeshLOD ; } ,
2013-05-08 13:02:12 +00:00
( s , v ) = > { MeshLOD = v ; } ) ,
new ParameterDefn < float > ( "MeshLevelOfDetailCircular" , "Level of detail for prims with circular cuts or shapes" ,
32f ,
( s ) = > { return MeshCircularLOD ; } ,
( s , v ) = > { MeshCircularLOD = v ; } ) ,
new ParameterDefn < float > ( "MeshLevelOfDetailMegaPrimThreshold" , "Size (in meters) of a mesh before using MeshMegaPrimLOD" ,
2012-12-21 23:21:32 +00:00
10f ,
( s ) = > { return MeshMegaPrimThreshold ; } ,
2013-05-08 13:02:12 +00:00
( s , v ) = > { MeshMegaPrimThreshold = v ; } ) ,
new ParameterDefn < float > ( "MeshLevelOfDetailMegaPrim" , "Level of detail to render meshes larger than threshold meters" ,
32f ,
( s ) = > { return MeshMegaPrimLOD ; } ,
( s , v ) = > { MeshMegaPrimLOD = v ; } ) ,
new ParameterDefn < float > ( "SculptLevelOfDetail" , "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)" ,
2012-12-21 23:21:32 +00:00
32f ,
( s ) = > { return SculptLOD ; } ,
2013-05-08 13:02:12 +00:00
( s , v ) = > { SculptLOD = v ; } ) ,
2012-12-21 23:21:32 +00:00
2013-05-08 13:02:12 +00:00
new ParameterDefn < int > ( "MaxSubStep" , "In simulation step, maximum number of substeps" ,
10 ,
( s ) = > { return s . m_maxSubSteps ; } ,
( s , v ) = > { s . m_maxSubSteps = ( int ) v ; } ) ,
new ParameterDefn < float > ( "FixedTimeStep" , "In simulation step, seconds of one substep (1/60)" ,
2012-12-21 23:21:32 +00:00
1f / 60f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return s . m_fixedTimeStep ; } ,
( s , v ) = > { s . m_fixedTimeStep = v ; } ) ,
new ParameterDefn < float > ( "NominalFrameRate" , "The base frame rate we claim" ,
2012-12-28 02:19:25 +00:00
55f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return s . NominalFrameRate ; } ,
( s , v ) = > { s . NominalFrameRate = ( int ) v ; } ) ,
new ParameterDefn < int > ( "MaxCollisionsPerFrame" , "Max collisions returned at end of each frame" ,
2048 ,
( s ) = > { return s . m_maxCollisionsPerFrame ; } ,
( s , v ) = > { s . m_maxCollisionsPerFrame = ( int ) v ; } ) ,
new ParameterDefn < int > ( "MaxUpdatesPerFrame" , "Max updates returned at end of each frame" ,
8000 ,
( s ) = > { return s . m_maxUpdatesPerFrame ; } ,
( s , v ) = > { s . m_maxUpdatesPerFrame = ( int ) v ; } ) ,
new ParameterDefn < float > ( "MinObjectMass" , "Minimum object mass (0.0001)" ,
2012-12-21 23:21:32 +00:00
0.0001f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return MinimumObjectMass ; } ,
( s , v ) = > { MinimumObjectMass = v ; } ) ,
new ParameterDefn < float > ( "MaxObjectMass" , "Maximum object mass (10000.01)" ,
2012-12-21 23:21:32 +00:00
10000.01f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return MaximumObjectMass ; } ,
( s , v ) = > { MaximumObjectMass = v ; } ) ,
new ParameterDefn < float > ( "MaxLinearVelocity" , "Maximum velocity magnitude that can be assigned to an object" ,
1000.0f ,
( s ) = > { return MaxLinearVelocity ; } ,
( s , v ) = > { MaxLinearVelocity = v ; MaxLinearVelocitySquared = v * v ; } ) ,
new ParameterDefn < float > ( "MaxAngularVelocity" , "Maximum rotational velocity magnitude that can be assigned to an object" ,
1000.0f ,
( s ) = > { return MaxAngularVelocity ; } ,
( s , v ) = > { MaxAngularVelocity = v ; MaxAngularVelocitySquared = v * v ; } ) ,
// LL documentation says thie number should be 20f for llApplyImpulse and 200f for llRezObject
new ParameterDefn < float > ( "MaxAddForceMagnitude" , "Maximum force that can be applied by llApplyImpulse (SL says 20f)" ,
20000.0f ,
( s ) = > { return MaxAddForceMagnitude ; } ,
( s , v ) = > { MaxAddForceMagnitude = v ; MaxAddForceMagnitudeSquared = v * v ; } ) ,
// Density is passed around as 100kg/m3. This scales that to 1kg/m3.
new ParameterDefn < float > ( "DensityScaleFactor" , "Conversion for simulator/viewer density (100kg/m3) to physical density (1kg/m3)" ,
0.01f ) ,
new ParameterDefn < float > ( "PID_D" , "Derivitive factor for motion smoothing" ,
2200f ) ,
new ParameterDefn < float > ( "PID_P" , "Parameteric factor for motion smoothing" ,
900f ) ,
new ParameterDefn < float > ( "DefaultFriction" , "Friction factor used on new objects" ,
2012-12-21 23:21:32 +00:00
0.2f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return DefaultFriction ; } ,
( s , v ) = > { DefaultFriction = v ; s . UnmanagedParams [ 0 ] . defaultFriction = v ; } ) ,
new ParameterDefn < float > ( "DefaultDensity" , "Density for new objects" ,
2012-12-21 23:21:32 +00:00
10.000006836f , // Aluminum g/cm3
2013-05-08 13:02:12 +00:00
( s ) = > { return DefaultDensity ; } ,
( s , v ) = > { DefaultDensity = v ; s . UnmanagedParams [ 0 ] . defaultDensity = v ; } ) ,
new ParameterDefn < float > ( "DefaultRestitution" , "Bouncyness of an object" ,
2012-12-21 23:21:32 +00:00
0f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return DefaultRestitution ; } ,
( s , v ) = > { DefaultRestitution = v ; s . UnmanagedParams [ 0 ] . defaultRestitution = v ; } ) ,
new ParameterDefn < float > ( "CollisionMargin" , "Margin around objects before collisions are calculated (must be zero!)" ,
2012-12-21 23:21:32 +00:00
0.04f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return CollisionMargin ; } ,
( s , v ) = > { CollisionMargin = v ; s . UnmanagedParams [ 0 ] . collisionMargin = v ; } ) ,
new ParameterDefn < float > ( "Gravity" , "Vertical force of gravity (negative means down)" ,
2012-12-21 23:21:32 +00:00
- 9.80665f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return Gravity ; } ,
( s , v ) = > { Gravity = v ; s . UnmanagedParams [ 0 ] . gravity = v ; } ,
( s , o ) = > { s . PE . SetGravity ( o . PhysBody , new Vector3 ( 0f , 0f , Gravity ) ) ; } ) ,
2012-12-21 23:21:32 +00:00
2013-05-08 13:02:12 +00:00
new ParameterDefn < float > ( "LinearDamping" , "Factor to damp linear movement per second (0.0 - 1.0)" ,
2012-12-21 23:21:32 +00:00
0f ,
( s ) = > { return LinearDamping ; } ,
2013-05-08 13:02:12 +00:00
( s , v ) = > { LinearDamping = v ; } ,
( s , o ) = > { s . PE . SetDamping ( o . PhysBody , LinearDamping , AngularDamping ) ; } ) ,
new ParameterDefn < float > ( "AngularDamping" , "Factor to damp angular movement per second (0.0 - 1.0)" ,
2012-12-21 23:21:32 +00:00
0f ,
( s ) = > { return AngularDamping ; } ,
2013-05-08 13:02:12 +00:00
( s , v ) = > { AngularDamping = v ; } ,
( s , o ) = > { s . PE . SetDamping ( o . PhysBody , LinearDamping , AngularDamping ) ; } ) ,
new ParameterDefn < float > ( "DeactivationTime" , "Seconds before considering an object potentially static" ,
2012-12-21 23:21:32 +00:00
0.2f ,
( s ) = > { return DeactivationTime ; } ,
2013-05-08 13:02:12 +00:00
( s , v ) = > { DeactivationTime = v ; } ,
( s , o ) = > { s . PE . SetDeactivationTime ( o . PhysBody , DeactivationTime ) ; } ) ,
new ParameterDefn < float > ( "LinearSleepingThreshold" , "Seconds to measure linear movement before considering static" ,
2012-12-21 23:21:32 +00:00
0.8f ,
( s ) = > { return LinearSleepingThreshold ; } ,
2013-05-08 13:02:12 +00:00
( s , v ) = > { LinearSleepingThreshold = v ; } ,
( s , o ) = > { s . PE . SetSleepingThresholds ( o . PhysBody , LinearSleepingThreshold , AngularSleepingThreshold ) ; } ) ,
new ParameterDefn < float > ( "AngularSleepingThreshold" , "Seconds to measure angular movement before considering static" ,
2012-12-21 23:21:32 +00:00
1.0f ,
( s ) = > { return AngularSleepingThreshold ; } ,
2013-05-08 13:02:12 +00:00
( s , v ) = > { AngularSleepingThreshold = v ; } ,
( s , o ) = > { s . PE . SetSleepingThresholds ( o . PhysBody , LinearSleepingThreshold , AngularSleepingThreshold ) ; } ) ,
new ParameterDefn < float > ( "CcdMotionThreshold" , "Continuious collision detection threshold (0 means no CCD)" ,
0.0f , // set to zero to disable
2012-12-21 23:21:32 +00:00
( s ) = > { return CcdMotionThreshold ; } ,
2013-05-08 13:02:12 +00:00
( s , v ) = > { CcdMotionThreshold = v ; } ,
( s , o ) = > { s . PE . SetCcdMotionThreshold ( o . PhysBody , CcdMotionThreshold ) ; } ) ,
new ParameterDefn < float > ( "CcdSweptSphereRadius" , "Continuious collision detection test radius" ,
0.2f ,
2012-12-21 23:21:32 +00:00
( s ) = > { return CcdSweptSphereRadius ; } ,
2013-05-08 13:02:12 +00:00
( s , v ) = > { CcdSweptSphereRadius = v ; } ,
( s , o ) = > { s . PE . SetCcdSweptSphereRadius ( o . PhysBody , CcdSweptSphereRadius ) ; } ) ,
new ParameterDefn < float > ( "ContactProcessingThreshold" , "Distance above which contacts can be discarded (0 means no discard)" ,
0.0f ,
2012-12-21 23:21:32 +00:00
( s ) = > { return ContactProcessingThreshold ; } ,
2013-05-08 13:02:12 +00:00
( s , v ) = > { ContactProcessingThreshold = v ; } ,
( s , o ) = > { s . PE . SetContactProcessingThreshold ( o . PhysBody , ContactProcessingThreshold ) ; } ) ,
new ParameterDefn < float > ( "TerrainImplementation" , "Type of shape to use for terrain (0=heightmap, 1=mesh)" ,
( float ) BSTerrainPhys . TerrainImplementation . Mesh ) ,
new ParameterDefn < int > ( "TerrainMeshMagnification" , "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" ,
2 ) ,
new ParameterDefn < float > ( "TerrainFriction" , "Factor to reduce movement against terrain surface" ,
0.3f ) ,
new ParameterDefn < float > ( "TerrainHitFraction" , "Distance to measure hit collisions" ,
0.8f ) ,
new ParameterDefn < float > ( "TerrainRestitution" , "Bouncyness" ,
0f ) ,
new ParameterDefn < float > ( "TerrainContactProcessingThreshold" , "Distance from terrain to stop processing collisions" ,
0.0f ) ,
new ParameterDefn < float > ( "TerrainCollisionMargin" , "Margin where collision checking starts" ,
0.08f ) ,
new ParameterDefn < float > ( "AvatarFriction" , "Factor to reduce movement against an avatar. Changed on avatar recreation." ,
0.2f ) ,
new ParameterDefn < float > ( "AvatarStandingFriction" , "Avatar friction when standing. Changed on avatar recreation." ,
0.95f ) ,
new ParameterDefn < float > ( "AvatarAlwaysRunFactor" , "Speed multiplier if avatar is set to always run" ,
1.3f ) ,
new ParameterDefn < float > ( "AvatarDensity" , "Density of an avatar. Changed on avatar recreation." ,
3.5f ) ,
new ParameterDefn < float > ( "AvatarRestitution" , "Bouncyness. Changed on avatar recreation." ,
0f ) ,
new ParameterDefn < float > ( "AvatarCapsuleWidth" , "The distance between the sides of the avatar capsule" ,
0.6f ) ,
new ParameterDefn < float > ( "AvatarCapsuleDepth" , "The distance between the front and back of the avatar capsule" ,
0.45f ) ,
new ParameterDefn < float > ( "AvatarCapsuleHeight" , "Default height of space around avatar" ,
1.5f ) ,
2013-05-13 20:03:13 +00:00
new ParameterDefn < float > ( "AvatarHeightLowFudge" , "A fudge factor to make small avatars stand on the ground" ,
- 0.2f ) ,
new ParameterDefn < float > ( "AvatarHeightMidFudge" , "A fudge distance to adjust average sized avatars to be standing on ground" ,
0.1f ) ,
new ParameterDefn < float > ( "AvatarHeightHighFudge" , "A fudge factor to make tall avatars stand on the ground" ,
0.1f ) ,
2013-05-08 13:02:12 +00:00
new ParameterDefn < float > ( "AvatarContactProcessingThreshold" , "Distance from capsule to check for collisions" ,
0.1f ) ,
new ParameterDefn < float > ( "AvatarBelowGroundUpCorrectionMeters" , "Meters to move avatar up if it seems to be below ground" ,
1.0f ) ,
new ParameterDefn < float > ( "AvatarStepHeight" , "Height of a step obstacle to consider step correction" ,
0.6f ) ,
new ParameterDefn < float > ( "AvatarStepApproachFactor" , "Factor to control angle of approach to step (0=straight on)" ,
0.6f ) ,
new ParameterDefn < float > ( "AvatarStepForceFactor" , "Controls the amount of force up applied to step up onto a step" ,
1.0f ) ,
new ParameterDefn < float > ( "AvatarStepUpCorrectionFactor" , "Multiplied by height of step collision to create up movement at step" ,
1.0f ) ,
new ParameterDefn < int > ( "AvatarStepSmoothingSteps" , "Number of frames after a step collision that we continue walking up stairs" ,
2 ) ,
new ParameterDefn < float > ( "VehicleMaxLinearVelocity" , "Maximum velocity magnitude that can be assigned to a vehicle" ,
1000.0f ,
( s ) = > { return ( float ) VehicleMaxLinearVelocity ; } ,
( s , v ) = > { VehicleMaxLinearVelocity = v ; VehicleMaxLinearVelocitySquared = v * v ; } ) ,
new ParameterDefn < float > ( "VehicleMaxAngularVelocity" , "Maximum rotational velocity magnitude that can be assigned to a vehicle" ,
12.0f ,
( s ) = > { return ( float ) VehicleMaxAngularVelocity ; } ,
( s , v ) = > { VehicleMaxAngularVelocity = v ; VehicleMaxAngularVelocitySq = v * v ; } ) ,
new ParameterDefn < float > ( "VehicleAngularDamping" , "Factor to damp vehicle angular movement per second (0.0 - 1.0)" ,
0.0f ) ,
new ParameterDefn < Vector3 > ( "VehicleLinearFactor" , "Fraction of physical linear changes applied to vehicle (<0,0,0> to <1,1,1>)" ,
new Vector3 ( 1f , 1f , 1f ) ) ,
new ParameterDefn < Vector3 > ( "VehicleAngularFactor" , "Fraction of physical angular changes applied to vehicle (<0,0,0> to <1,1,1>)" ,
new Vector3 ( 1f , 1f , 1f ) ) ,
new ParameterDefn < float > ( "VehicleFriction" , "Friction of vehicle on the ground (0.0 - 1.0)" ,
0.0f ) ,
new ParameterDefn < float > ( "VehicleRestitution" , "Bouncyness factor for vehicles (0.0 - 1.0)" ,
0.0f ) ,
new ParameterDefn < float > ( "VehicleGroundGravityFudge" , "Factor to multiply gravity if a ground vehicle is probably on the ground (0.0 - 1.0)" ,
0.2f ) ,
new ParameterDefn < float > ( "VehicleAngularBankingTimescaleFudge" , "Factor to multiple angular banking timescale. Tune to increase realism." ,
60.0f ) ,
new ParameterDefn < bool > ( "VehicleDebuggingEnable" , "Turn on/off vehicle debugging" ,
false ) ,
new ParameterDefn < float > ( "MaxPersistantManifoldPoolSize" , "Number of manifolds pooled (0 means default of 4096)" ,
2012-12-21 23:21:32 +00:00
0f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return MaxPersistantManifoldPoolSize ; } ,
( s , v ) = > { MaxPersistantManifoldPoolSize = v ; s . UnmanagedParams [ 0 ] . maxPersistantManifoldPoolSize = v ; } ) ,
new ParameterDefn < float > ( "MaxCollisionAlgorithmPoolSize" , "Number of collisions pooled (0 means default of 4096)" ,
2012-12-21 23:21:32 +00:00
0f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return MaxCollisionAlgorithmPoolSize ; } ,
( s , v ) = > { MaxCollisionAlgorithmPoolSize = v ; s . UnmanagedParams [ 0 ] . maxCollisionAlgorithmPoolSize = v ; } ) ,
new ParameterDefn < bool > ( "ShouldDisableContactPoolDynamicAllocation" , "Enable to allow large changes in object count" ,
false ,
( s ) = > { return ShouldDisableContactPoolDynamicAllocation ; } ,
( s , v ) = > { ShouldDisableContactPoolDynamicAllocation = v ;
s . UnmanagedParams [ 0 ] . shouldDisableContactPoolDynamicAllocation = NumericBool ( v ) ; } ) ,
new ParameterDefn < bool > ( "ShouldForceUpdateAllAabbs" , "Enable to recomputer AABBs every simulator step" ,
false ,
( s ) = > { return ShouldForceUpdateAllAabbs ; } ,
( s , v ) = > { ShouldForceUpdateAllAabbs = v ; s . UnmanagedParams [ 0 ] . shouldForceUpdateAllAabbs = NumericBool ( v ) ; } ) ,
new ParameterDefn < bool > ( "ShouldRandomizeSolverOrder" , "Enable for slightly better stacking interaction" ,
true ,
( s ) = > { return ShouldRandomizeSolverOrder ; } ,
( s , v ) = > { ShouldRandomizeSolverOrder = v ; s . UnmanagedParams [ 0 ] . shouldRandomizeSolverOrder = NumericBool ( v ) ; } ) ,
new ParameterDefn < bool > ( "ShouldSplitSimulationIslands" , "Enable splitting active object scanning islands" ,
true ,
( s ) = > { return ShouldSplitSimulationIslands ; } ,
( s , v ) = > { ShouldSplitSimulationIslands = v ; s . UnmanagedParams [ 0 ] . shouldSplitSimulationIslands = NumericBool ( v ) ; } ) ,
new ParameterDefn < bool > ( "ShouldEnableFrictionCaching" , "Enable friction computation caching" ,
true ,
( s ) = > { return ShouldEnableFrictionCaching ; } ,
( s , v ) = > { ShouldEnableFrictionCaching = v ; s . UnmanagedParams [ 0 ] . shouldEnableFrictionCaching = NumericBool ( v ) ; } ) ,
new ParameterDefn < float > ( "NumberOfSolverIterations" , "Number of internal iterations (0 means default)" ,
0f , // zero says use Bullet default
( s ) = > { return NumberOfSolverIterations ; } ,
( s , v ) = > { NumberOfSolverIterations = v ; s . UnmanagedParams [ 0 ] . numberOfSolverIterations = v ; } ) ,
new ParameterDefn < bool > ( "UseSingleSidedMeshes" , "Whether to compute collisions based on single sided meshes." ,
true ,
( s ) = > { return UseSingleSidedMeshes ; } ,
( s , v ) = > { UseSingleSidedMeshes = v ; s . UnmanagedParams [ 0 ] . useSingleSidedMeshes = NumericBool ( v ) ; } ) ,
new ParameterDefn < float > ( "GlobalContactBreakingThreshold" , "Amount of shape radius before breaking a collision contact (0 says Bullet default (0.2))" ,
2012-12-21 23:21:32 +00:00
0f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return GlobalContactBreakingThreshold ; } ,
( s , v ) = > { GlobalContactBreakingThreshold = v ; s . UnmanagedParams [ 0 ] . globalContactBreakingThreshold = v ; } ) ,
new ParameterDefn < int > ( "CSHullMaxDepthSplit" , "CS impl: max depth to split for hull. 1-10 but > 7 is iffy" ,
7 ) ,
new ParameterDefn < int > ( "CSHullMaxDepthSplitForSimpleShapes" , "CS impl: max depth setting for simple prim shapes" ,
2 ) ,
new ParameterDefn < float > ( "CSHullConcavityThresholdPercent" , "CS impl: concavity threshold percent (0-20)" ,
5f ) ,
new ParameterDefn < float > ( "CSHullVolumeConservationThresholdPercent" , "percent volume conservation to collapse hulls (0-30)" ,
5f ) ,
new ParameterDefn < int > ( "CSHullMaxVertices" , "CS impl: maximum number of vertices in output hulls. Keep < 50." ,
32 ) ,
new ParameterDefn < float > ( "CSHullMaxSkinWidth" , "CS impl: skin width to apply to output hulls." ,
0f ) ,
new ParameterDefn < float > ( "BHullMaxVerticesPerHull" , "Bullet impl: max number of vertices per created hull" ,
100f ) ,
new ParameterDefn < float > ( "BHullMinClusters" , "Bullet impl: minimum number of hulls to create per mesh" ,
2f ) ,
new ParameterDefn < float > ( "BHullCompacityWeight" , "Bullet impl: weight factor for how compact to make hulls" ,
0.1f ) ,
new ParameterDefn < float > ( "BHullVolumeWeight" , "Bullet impl: weight factor for volume in created hull" ,
0f ) ,
new ParameterDefn < float > ( "BHullConcavity" , "Bullet impl: weight factor for how convex a created hull can be" ,
100f ) ,
new ParameterDefn < bool > ( "BHullAddExtraDistPoints" , "Bullet impl: whether to add extra vertices for long distance vectors" ,
false ) ,
new ParameterDefn < bool > ( "BHullAddNeighboursDistPoints" , "Bullet impl: whether to add extra vertices between neighbor hulls" ,
false ) ,
new ParameterDefn < bool > ( "BHullAddFacesPoints" , "Bullet impl: whether to add extra vertices to break up hull faces" ,
false ) ,
new ParameterDefn < bool > ( "BHullShouldAdjustCollisionMargin" , "Bullet impl: whether to shrink resulting hulls to account for collision margin" ,
false ) ,
new ParameterDefn < float > ( "LinksetImplementation" , "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)" ,
( float ) BSLinkset . LinksetImplementation . Compound ) ,
new ParameterDefn < bool > ( "LinkConstraintUseFrameOffset" , "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset." ,
false ) ,
new ParameterDefn < bool > ( "LinkConstraintEnableTransMotor" , "Whether to enable translational motor on linkset constraints" ,
true ) ,
new ParameterDefn < float > ( "LinkConstraintTransMotorMaxVel" , "Maximum velocity to be applied by translational motor in linkset constraints" ,
5.0f ) ,
new ParameterDefn < float > ( "LinkConstraintTransMotorMaxForce" , "Maximum force to be applied by translational motor in linkset constraints" ,
0.1f ) ,
new ParameterDefn < float > ( "LinkConstraintCFM" , "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1" ,
0.1f ) ,
new ParameterDefn < float > ( "LinkConstraintERP" , "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2" ,
0.1f ) ,
new ParameterDefn < float > ( "LinkConstraintSolverIterations" , "Number of solver iterations when computing constraint. (0 = Bullet default)" ,
40 ) ,
new ParameterDefn < int > ( "PhysicsMetricFrames" , "Frames between outputting detailed phys metrics. (0 is off)" ,
0 ,
( s ) = > { return s . PhysicsMetricDumpFrames ; } ,
( s , v ) = > { s . PhysicsMetricDumpFrames = v ; } ) ,
new ParameterDefn < float > ( "ResetBroadphasePool" , "Setting this is any value resets the broadphase collision pool" ,
2012-12-21 23:21:32 +00:00
0f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return 0f ; } ,
( s , v ) = > { BSParam . ResetBroadphasePoolTainted ( s , v ) ; } ) ,
new ParameterDefn < float > ( "ResetConstraintSolver" , "Setting this is any value resets the constraint solver" ,
2012-12-21 23:21:32 +00:00
0f ,
2013-05-08 13:02:12 +00:00
( s ) = > { return 0f ; } ,
( s , v ) = > { BSParam . ResetConstraintSolverTainted ( s , v ) ; } ) ,
2012-12-21 23:21:32 +00:00
} ;
// Convert a boolean to our numeric true and false values
public static float NumericBool ( bool b )
{
return ( b ? ConfigurationParameters . numericTrue : ConfigurationParameters . numericFalse ) ;
}
// Convert numeric true and false values to a boolean
public static bool BoolNumeric ( float b )
{
return ( b = = ConfigurationParameters . numericTrue ? true : false ) ;
}
// Search through the parameter definitions and return the matching
// ParameterDefn structure.
// Case does not matter as names are compared after converting to lower case.
// Returns 'false' if the parameter is not found.
2013-05-08 13:02:12 +00:00
internal static bool TryGetParameter ( string paramName , out ParameterDefnBase defn )
2012-12-21 23:21:32 +00:00
{
bool ret = false ;
2013-05-08 13:02:12 +00:00
ParameterDefnBase foundDefn = null ;
2012-12-21 23:21:32 +00:00
string pName = paramName . ToLower ( ) ;
2013-05-08 13:02:12 +00:00
foreach ( ParameterDefnBase parm in ParameterDefinitions )
2012-12-21 23:21:32 +00:00
{
if ( pName = = parm . name . ToLower ( ) )
{
foundDefn = parm ;
ret = true ;
break ;
}
}
defn = foundDefn ;
return ret ;
}
// Pass through the settable parameters and set the default values
internal static void SetParameterDefaultValues ( BSScene physicsScene )
{
2013-05-08 13:02:12 +00:00
foreach ( ParameterDefnBase parm in ParameterDefinitions )
2012-12-21 23:21:32 +00:00
{
2013-05-08 13:02:12 +00:00
parm . AssignDefault ( physicsScene ) ;
2012-12-21 23:21:32 +00:00
}
}
// Get user set values out of the ini file.
internal static void SetParameterConfigurationValues ( BSScene physicsScene , IConfig cfg )
{
2013-05-08 13:02:12 +00:00
foreach ( ParameterDefnBase parm in ParameterDefinitions )
2012-12-21 23:21:32 +00:00
{
2013-05-08 13:02:12 +00:00
parm . SetValue ( physicsScene , cfg . GetString ( parm . name , parm . GetValue ( physicsScene ) ) ) ;
2012-12-21 23:21:32 +00:00
}
}
internal static PhysParameterEntry [ ] SettableParameters = new PhysParameterEntry [ 1 ] ;
// This creates an array in the correct format for returning the list of
// parameters. This is used by the 'list' option of the 'physics' command.
internal static void BuildParameterTable ( )
{
if ( SettableParameters . Length < ParameterDefinitions . Length )
{
List < PhysParameterEntry > entries = new List < PhysParameterEntry > ( ) ;
for ( int ii = 0 ; ii < ParameterDefinitions . Length ; ii + + )
{
2013-05-08 13:02:12 +00:00
ParameterDefnBase pd = ParameterDefinitions [ ii ] ;
2012-12-21 23:21:32 +00:00
entries . Add ( new PhysParameterEntry ( pd . name , pd . desc ) ) ;
}
2013-05-08 13:02:12 +00:00
// make the list alphabetical for ease of finding anything
entries . Sort ( ( ppe1 , ppe2 ) = > { return ppe1 . name . CompareTo ( ppe2 . name ) ; } ) ;
2012-12-21 23:21:32 +00:00
SettableParameters = entries . ToArray ( ) ;
}
}
2013-05-08 13:02:12 +00:00
// =====================================================================
// =====================================================================
// There are parameters that, when set, cause things to happen in the physics engine.
// This causes the broadphase collision cache to be cleared.
private static void ResetBroadphasePoolTainted ( BSScene pPhysScene , float v )
{
BSScene physScene = pPhysScene ;
physScene . TaintedObject ( "BSParam.ResetBroadphasePoolTainted" , delegate ( )
{
physScene . PE . ResetBroadphasePool ( physScene . World ) ;
} ) ;
}
2012-12-21 23:21:32 +00:00
2013-05-08 13:02:12 +00:00
// This causes the constraint solver cache to be cleared and reset.
private static void ResetConstraintSolverTainted ( BSScene pPhysScene , float v )
{
BSScene physScene = pPhysScene ;
physScene . TaintedObject ( "BSParam.ResetConstraintSolver" , delegate ( )
{
physScene . PE . ResetConstraintSolver ( physScene . World ) ;
} ) ;
}
2012-12-21 23:21:32 +00:00
}
}