35 using System.Collections.Generic;
 
   36 using System.Diagnostics;
 
   39 using System.Reflection;
 
   40 using System.Runtime.ExceptionServices;
 
   41 using System.Runtime.InteropServices;
 
   42 using System.Threading;
 
   47 using OpenSim.Framework;
 
   48 using OpenSim.Region.PhysicsModules.SharedBase;
 
   49 using OpenSim.Region.Framework.Scenes;
 
   50 using OpenSim.Region.Framework.Interfaces;
 
   52 namespace OpenSim.
Region.PhysicsModule.ODE
 
   99         private readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString());
 
  127         internal static Object UniversalColliderSyncObject = 
new Object();
 
  133         public bool CollectStats { 
get; set; }
 
  138         private Dictionary<string, float> m_stats = 
new Dictionary<string, float>();
 
  143         public const string ODETotalAvatarsStatName = 
"ODETotalAvatars";
 
  148         public const string ODETotalPrimsStatName = 
"ODETotalPrims";
 
  153         public const string ODEActivePrimsStatName = 
"ODEActivePrims";
 
  161         public const string ODETotalFrameMsStatName = 
"ODETotalFrameMS";
 
  166         public const string ODEAvatarTaintMsStatName = 
"ODEAvatarTaintFrameMS";
 
  171         public const string ODEPrimTaintMsStatName = 
"ODEPrimTaintFrameMS";
 
  176         public const string ODEAvatarForcesFrameMsStatName = 
"ODEAvatarForcesFrameMS";
 
  181         public const string ODEPrimForcesFrameMsStatName = 
"ODEPrimForcesFrameMS";
 
  186         public const string ODERaycastingFrameMsStatName = 
"ODERaycastingFrameMS";
 
  191         public const string ODENativeStepFrameMsStatName = 
"ODENativeStepFrameMS";
 
  196         public const string ODENativeSpaceCollisionFrameMsStatName = 
"ODENativeSpaceCollisionFrameMS";
 
  201         public const string ODENativeGeomCollisionFrameMsStatName = 
"ODENativeGeomCollisionFrameMS";
 
  206         public const string ODEOtherCollisionFrameMsStatName = 
"ODEOtherCollisionFrameMS";
 
  211         public const string ODECollisionNotificationFrameMsStatName = 
"ODECollisionNotificationFrameMS";
 
  216         public const string ODEAvatarUpdateFrameMsStatName = 
"ODEAvatarUpdateFrameMS";
 
  221         public const string ODEPrimUpdateFrameMsStatName = 
"ODEPrimUpdateFrameMS";
 
  226         public const string ODEAvatarContactsStatsName = 
"ODEAvatarContacts";
 
  231         public const string ODEPrimContactsStatName = 
"ODEPrimContacts";
 
  236         private int m_nativeCollisionStartTick;
 
  241         private bool m_inCollisionTiming;
 
  247         private int m_tempAvatarCollisionsThisFrame;
 
  252         private int tickCountFrameRun;
 
  257         private int latertickcount;
 
  259         private Random fluidRandomizer = 
new Random(Environment.TickCount);
 
  261         public bool m_suportCombine = 
true;
 
  263         private uint m_regionWidth = Constants.RegionSize;
 
  264         private uint m_regionHeight = Constants.RegionSize;
 
  266         private float ODE_STEPSIZE = 0.0178f;
 
  267         private float metersInSpace = 29.9f;
 
  268         private float m_timeDilation = 1.0f;
 
  270         public float gravityx = 0f;
 
  271         public float gravityy = 0f;
 
  272         public float gravityz = -9.8f;
 
  274         public float AvatarTerminalVelocity { 
get; set; }
 
  276         private float contactsurfacelayer = 0.001f;
 
  278         private int HashspaceLow = -5;
 
  279         private int HashspaceHigh = 12;
 
  281         private float waterlevel = 0f;
 
  282         private int framecount = 0;
 
  285         private IntPtr contactgroup;
 
  289         private float nmTerrainContactFriction = 255.0f;
 
  290         private float nmTerrainContactBounce = 0.1f;
 
  291         private float nmTerrainContactERP = 0.1025f;
 
  293         private float mTerrainContactFriction = 75f;
 
  294         private float mTerrainContactBounce = 0.1f;
 
  295         private float mTerrainContactERP = 0.05025f;
 
  297         private float nmAvatarObjectContactFriction = 250f;
 
  298         private float nmAvatarObjectContactBounce = 0.1f;
 
  300         private float mAvatarObjectContactFriction = 75f;
 
  301         private float mAvatarObjectContactBounce = 0.1f;
 
  303         private float avPIDD = 3200f;
 
  304         private float avPIDP = 1400f;
 
  305         private float avCapRadius = 0.37f;
 
  306         private float avStandupTensor = 2000000f;
 
  314         public bool IsAvCapsuleTilted { 
get; 
private set; }
 
  316         private float avDensity = 80f;
 
  317         private float avMovementDivisorWalk = 1.3f;
 
  318         private float avMovementDivisorRun = 0.8f;
 
  319         private float minimumGroundFlightOffset = 3f;
 
  320         public float maximumMassObject = 10000.01f;
 
  322         public bool meshSculptedPrim = 
true;
 
  323         public bool forceSimplePrimMeshing = 
false;
 
  325         public float meshSculptLOD = 32;
 
  326         public float MeshSculptphysicalLOD = 16;
 
  328         public float geomDefaultDensity = 10.000006836f;
 
  330         public int geomContactPointsStartthrottle = 3;
 
  331         public int geomUpdatesPerThrottledUpdate = 15;
 
  332         private const int avatarExpectedContacts = 3;
 
  334         public float bodyPIDD = 35f;
 
  335         public float bodyPIDG = 25;
 
  337         public int bodyFramesAutoDisable = 20;
 
  339         private bool m_filterCollisions = 
true;
 
  341         private d.NearCallback nearCallback;
 
  348         private readonly HashSet<OdeCharacter> _characters = 
new HashSet<OdeCharacter>();
 
  353         private readonly HashSet<OdePrim> _prims = 
new HashSet<OdePrim>();
 
  358         private readonly HashSet<OdePrim> _activeprims = 
new HashSet<OdePrim>();
 
  363         private readonly HashSet<OdePrim> _taintedPrims = 
new HashSet<OdePrim>();
 
  368         private readonly HashSet<OdeCharacter> _taintedActors = 
new HashSet<OdeCharacter>();
 
  378         private readonly Dictionary<uint, PhysicsActor> m_collisionEventActors = 
new Dictionary<uint, PhysicsActor>();
 
  383         private readonly Dictionary<uint, PhysicsActor> m_collisionEventActorsChanges = 
new Dictionary<uint, PhysicsActor>();
 
  393         public Dictionary<IntPtr, String> geom_name_map = 
new Dictionary<IntPtr, String>();
 
  401         public Dictionary<IntPtr, PhysicsActor> actor_name_map = 
new Dictionary<IntPtr, PhysicsActor>();
 
  409         private readonly List<OdeCharacter> defects = 
new List<OdeCharacter>();
 
  411         private bool m_NINJA_physics_joints_enabled = 
false;
 
  413         private readonly Dictionary<String, List<PhysicsJoint>> joints_connecting_actor = 
new Dictionary<String, List<PhysicsJoint>>();
 
  419         private readonly List<PhysicsJoint> requestedJointsToBeCreated = 
new List<PhysicsJoint>();
 
  424         private readonly List<PhysicsJoint> pendingJoints = 
new List<PhysicsJoint>();
 
  429         private readonly List<PhysicsJoint> activeJoints = 
new List<PhysicsJoint>();
 
  434         private readonly List<string> requestedJointsToBeDeleted = 
new List<string>();
 
  436         private Object externalJointRequestsLock = 
new Object();
 
  437         private readonly Dictionary<String, PhysicsJoint> SOPName_to_activeJoint = 
new Dictionary<String, PhysicsJoint>();
 
  438         private readonly Dictionary<String, PhysicsJoint> SOPName_to_pendingJoint = 
new Dictionary<String, PhysicsJoint>();
 
  439         private readonly DoubleDictionary<Vector3, IntPtr, IntPtr> RegionTerrain = 
new DoubleDictionary<Vector3, IntPtr, IntPtr>();
 
  440         private readonly Dictionary<IntPtr,float[]> TerrainHeightFieldHeights = 
new Dictionary<IntPtr, float[]>();
 
  444         private d.Contact AvatarMovementprimContact;
 
  445         private d.Contact AvatarMovementTerrainContact;
 
  449         private int m_physicsiterations = 10;
 
  450         private const float m_SkipFramesAtms = 0.40f; 
 
  452         private float step_time = 0.0f;
 
  454         private uint obj2LocalID = 0;
 
  459         private int p1ExpectedPoints = 0;
 
  460         private int p2ExpectedPoints = 0;
 
  472         private bool _worldInitialized = 
false;
 
  476         private IConfigSource m_config;
 
  478         public bool physics_logging = 
false;
 
  479         public int physics_logging_interval = 0;
 
  480         public bool physics_logging_append_existing_logfile = 
false;
 
  482         private bool avplanted = 
false;
 
  483         private bool av_av_collisions_off = 
false;
 
  488         private volatile int m_global_contactcount = 0;
 
  490         private Vector3 m_worldOffset = Vector3.Zero;
 
  494         float spacesPerMeterX;
 
  495         float spacesPerMeterY;
 
  501         public Scene m_frameWorkScene = null;
 
  505             m_config = psourceconfig;
 
  506             m_frameWorkScene = pscene;
 
  509             PhysicsSceneName = EngineType + 
"/" + pscene.RegionInfo.RegionName;
 
  514             InitialiseFromConfig(m_config);
 
  517             base.Initialise(pscene.PhysicsRequestAsset, 
 
  518                 (pscene.Heightmap != null ? pscene.Heightmap.GetFloatsSerialised() : 
new float[(
int)(extent.X * extent.Y)]), 
 
  525             mesher = m_frameWorkScene.RequestModuleInterface<
IMesher>();
 
  527                 m_log.WarnFormat(
"[ODE SCENE]: No mesher in {0}. Things will not work well.", PhysicsSceneName);
 
  529             m_frameWorkScene.PhysicsEnabled = 
true;             
 
  537         private void Initialise(Vector3 regionExtent)
 
  539             WorldExtents.X = regionExtent.X;
 
  540             m_regionWidth = (uint)regionExtent.X;
 
  541             WorldExtents.Y = regionExtent.Y;
 
  542             m_regionHeight = (uint)regionExtent.Y;
 
  544             m_suportCombine = 
false;
 
  550             world = d.WorldCreate();
 
  551             space = d.HashSpaceCreate(IntPtr.Zero);
 
  553             contactgroup = d.JointGroupCreate(0);
 
  555             d.WorldSetAutoDisableFlag(world, 
false);
 
  559         private void InitialiseFromConfig(IConfigSource config)
 
  561             InitializeExtraStats();
 
  568             avStandupTensor = 550000f;
 
  570             int contactsPerCollision = 80;
 
  572             if (m_config != null)
 
  574                 IConfig physicsconfig = m_config.Configs[
"ODEPhysicsSettings"];
 
  575                 if (physicsconfig != null)
 
  577                     CollectStats = physicsconfig.GetBoolean(
"collect_stats", 
false);
 
  579                     gravityx = physicsconfig.GetFloat(
"world_gravityx", 0f);
 
  580                     gravityy = physicsconfig.GetFloat(
"world_gravityy", 0f);
 
  581                     gravityz = physicsconfig.GetFloat(
"world_gravityz", -9.8f);
 
  583                     float avatarTerminalVelocity = physicsconfig.GetFloat(
"avatar_terminal_velocity", 54f);
 
  584                     AvatarTerminalVelocity = Util.Clamp<
float>(avatarTerminalVelocity, 0, 255f);
 
  585                     if (AvatarTerminalVelocity != avatarTerminalVelocity)
 
  588                             "[ODE SCENE]: avatar_terminal_velocity of {0} is invalid.  Clamping to {1}",
 
  589                             avatarTerminalVelocity, AvatarTerminalVelocity);
 
  592                     HashspaceLow = physicsconfig.GetInt(
"world_hashspace_level_low", -5);
 
  593                     HashspaceHigh = physicsconfig.GetInt(
"world_hashspace_level_high", 12);
 
  595                     metersInSpace = physicsconfig.GetFloat(
"meters_in_small_space", 29.9f);
 
  597                     contactsurfacelayer = physicsconfig.GetFloat(
"world_contact_surface_layer", 0.001f);
 
  599                     nmTerrainContactFriction = physicsconfig.GetFloat(
"nm_terraincontact_friction", 255.0f);
 
  600                     nmTerrainContactBounce = physicsconfig.GetFloat(
"nm_terraincontact_bounce", 0.1f);
 
  601                     nmTerrainContactERP = physicsconfig.GetFloat(
"nm_terraincontact_erp", 0.1025f);
 
  603                     mTerrainContactFriction = physicsconfig.GetFloat(
"m_terraincontact_friction", 75f);
 
  604                     mTerrainContactBounce = physicsconfig.GetFloat(
"m_terraincontact_bounce", 0.05f);
 
  605                     mTerrainContactERP = physicsconfig.GetFloat(
"m_terraincontact_erp", 0.05025f);
 
  607                     nmAvatarObjectContactFriction = physicsconfig.GetFloat(
"objectcontact_friction", 250f);
 
  608                     nmAvatarObjectContactBounce = physicsconfig.GetFloat(
"objectcontact_bounce", 0.2f);
 
  610                     mAvatarObjectContactFriction = physicsconfig.GetFloat(
"m_avatarobjectcontact_friction", 75f);
 
  611                     mAvatarObjectContactBounce = physicsconfig.GetFloat(
"m_avatarobjectcontact_bounce", 0.1f);
 
  613                     ODE_STEPSIZE = physicsconfig.GetFloat(
"world_stepsize", ODE_STEPSIZE);
 
  614                     m_physicsiterations = physicsconfig.GetInt(
"world_solver_iterations", 10);
 
  616                     avDensity = physicsconfig.GetFloat(
"av_density", 80f);
 
  618                     avMovementDivisorWalk = physicsconfig.GetFloat(
"av_movement_divisor_walk", 1.3f);
 
  619                     avMovementDivisorRun = physicsconfig.GetFloat(
"av_movement_divisor_run", 0.8f);
 
  620                     avCapRadius = physicsconfig.GetFloat(
"av_capsule_radius", 0.37f);
 
  621                     avplanted = physicsconfig.GetBoolean(
"av_planted", 
false);
 
  622                     av_av_collisions_off = physicsconfig.GetBoolean(
"av_av_collisions_off", 
false);
 
  624                     IsAvCapsuleTilted = physicsconfig.GetBoolean(
"av_capsule_tilted", 
false);
 
  626                     contactsPerCollision = physicsconfig.GetInt(
"contacts_per_collision", 80);
 
  628                     geomContactPointsStartthrottle = physicsconfig.GetInt(
"geom_contactpoints_start_throttling", 5);
 
  629                     geomUpdatesPerThrottledUpdate = physicsconfig.GetInt(
"geom_updates_before_throttled_update", 15);
 
  631                     geomDefaultDensity = physicsconfig.GetFloat(
"geometry_default_density", 10.000006836f);
 
  632                     bodyFramesAutoDisable = physicsconfig.GetInt(
"body_frames_auto_disable", 20);
 
  634                     bodyPIDD = physicsconfig.GetFloat(
"body_pid_derivative", 35f);
 
  635                     bodyPIDG = physicsconfig.GetFloat(
"body_pid_gain", 25f);
 
  637                     forceSimplePrimMeshing = physicsconfig.GetBoolean(
"force_simple_prim_meshing", forceSimplePrimMeshing);
 
  638                     meshSculptedPrim = physicsconfig.GetBoolean(
"mesh_sculpted_prim", 
true);
 
  639                     meshSculptLOD = physicsconfig.GetFloat(
"mesh_lod", 32f);
 
  640                     MeshSculptphysicalLOD = physicsconfig.GetFloat(
"mesh_physical_lod", 16f);
 
  641                     m_filterCollisions = physicsconfig.GetBoolean(
"filter_collisions", 
false);
 
  643                     avPIDD = physicsconfig.GetFloat(
"av_pid_derivative", 2200.0f);
 
  644                     avPIDP = physicsconfig.GetFloat(
"av_pid_proportional", 900.0f);
 
  645                     avStandupTensor = physicsconfig.GetFloat(
"av_capsule_standup_tensor", 550000f);
 
  647                     physics_logging = physicsconfig.GetBoolean(
"physics_logging", 
false);
 
  648                     physics_logging_interval = physicsconfig.GetInt(
"physics_logging_interval", 0);
 
  649                     physics_logging_append_existing_logfile = physicsconfig.GetBoolean(
"physics_logging_append_existing_logfile", 
false);
 
  652                     minimumGroundFlightOffset = physicsconfig.GetFloat(
"minimum_ground_flight_offset", 3f);
 
  653                     maximumMassObject = physicsconfig.GetFloat(
"maximum_mass_object", 10000.01f);
 
  657             contacts = 
new d.ContactGeom[contactsPerCollision];
 
  659             spacesPerMeterX = 1.0f / metersInSpace;
 
  660             spacesPerMeterY = 1.0f / metersInSpace;
 
  662             spaceGridMaxX = (int)(WorldExtents.X * spacesPerMeterX);
 
  663             spaceGridMaxY = (int)(WorldExtents.Y * spacesPerMeterY);
 
  666             if (spaceGridMaxX > 24)
 
  669                 spacesPerMeterX =  spaceGridMaxX / WorldExtents.X;
 
  671             if (spaceGridMaxY > 24)
 
  674                 spacesPerMeterY = spaceGridMaxY / WorldExtents.Y;
 
  677             staticPrimspace = 
new IntPtr[spaceGridMaxX, spaceGridMaxY]; 
 
  686             contact.surface.mode |= d.ContactFlags.SoftERP;
 
  687             contact.surface.mu = nmAvatarObjectContactFriction;
 
  688             contact.surface.bounce = nmAvatarObjectContactBounce;
 
  689             contact.surface.soft_cfm = 0.010f;
 
  690             contact.surface.soft_erp = 0.010f;
 
  695             TerrainContact.surface.mode |= d.ContactFlags.SoftERP;
 
  696             TerrainContact.surface.mu = nmTerrainContactFriction;
 
  697             TerrainContact.surface.bounce = nmTerrainContactBounce;
 
  698             TerrainContact.surface.soft_erp = nmTerrainContactERP;
 
  700             WaterContact.surface.mode |= (d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM);
 
  701             WaterContact.surface.mu = 0f; 
 
  702             WaterContact.surface.bounce = 0.0f; 
 
  703             WaterContact.surface.soft_cfm = 0.010f;
 
  704             WaterContact.surface.soft_erp = 0.010f;
 
  710             AvatarMovementprimContact.surface.mu = mAvatarObjectContactFriction;
 
  711             AvatarMovementprimContact.surface.bounce = mAvatarObjectContactBounce;
 
  715             AvatarMovementTerrainContact.surface.mode |= d.ContactFlags.SoftERP;
 
  716             AvatarMovementTerrainContact.surface.mu = mTerrainContactFriction;
 
  717             AvatarMovementTerrainContact.surface.bounce = mTerrainContactBounce;
 
  718             AvatarMovementTerrainContact.surface.soft_erp = mTerrainContactERP;
 
  737             m_materialContacts = 
new d.Contact[7,2];
 
  739             m_materialContacts[(int)
Material.Stone, 0] = 
new d.Contact();
 
  740             m_materialContacts[(int)
Material.Stone, 0].surface.mode |= d.ContactFlags.SoftERP;
 
  741             m_materialContacts[(
int)Material.Stone, 0].surface.mu = nmAvatarObjectContactFriction;
 
  742             m_materialContacts[(int)
Material.Stone, 0].surface.bounce = nmAvatarObjectContactBounce;
 
  743             m_materialContacts[(
int)Material.Stone, 0].surface.soft_cfm = 0.010f;
 
  744             m_materialContacts[(int)
Material.Stone, 0].surface.soft_erp = 0.010f;
 
  746             m_materialContacts[(
int)Material.Stone, 1] = 
new d.Contact();
 
  747             m_materialContacts[(int)
Material.Stone, 1].surface.mode |= d.ContactFlags.SoftERP;
 
  748             m_materialContacts[(
int)Material.Stone, 1].surface.mu = mAvatarObjectContactFriction;
 
  749             m_materialContacts[(int)
Material.Stone, 1].surface.bounce = mAvatarObjectContactBounce;
 
  750             m_materialContacts[(
int)Material.Stone, 1].surface.soft_cfm = 0.010f;
 
  751             m_materialContacts[(int)
Material.Stone, 1].surface.soft_erp = 0.010f;
 
  753             m_materialContacts[(
int)Material.Metal, 0] = 
new d.Contact();
 
  754             m_materialContacts[(int)
Material.Metal, 0].surface.mode |= d.ContactFlags.SoftERP;
 
  755             m_materialContacts[(
int)Material.Metal, 0].surface.mu = nmAvatarObjectContactFriction;
 
  756             m_materialContacts[(int)
Material.Metal, 0].surface.bounce = nmAvatarObjectContactBounce;
 
  757             m_materialContacts[(
int)Material.Metal, 0].surface.soft_cfm = 0.010f;
 
  758             m_materialContacts[(int)
Material.Metal, 0].surface.soft_erp = 0.010f;
 
  760             m_materialContacts[(
int)Material.Metal, 1] = 
new d.Contact();
 
  761             m_materialContacts[(int)
Material.Metal, 1].surface.mode |= d.ContactFlags.SoftERP;
 
  762             m_materialContacts[(
int)Material.Metal, 1].surface.mu = mAvatarObjectContactFriction;
 
  763             m_materialContacts[(int)
Material.Metal, 1].surface.bounce = mAvatarObjectContactBounce;
 
  764             m_materialContacts[(
int)Material.Metal, 1].surface.soft_cfm = 0.010f;
 
  765             m_materialContacts[(int)
Material.Metal, 1].surface.soft_erp = 0.010f;
 
  767             m_materialContacts[(
int)Material.Glass, 0] = 
new d.Contact();
 
  768             m_materialContacts[(int)
Material.Glass, 0].surface.mode |= d.ContactFlags.SoftERP;
 
  769             m_materialContacts[(
int)Material.Glass, 0].surface.mu = 1f;
 
  770             m_materialContacts[(int)
Material.Glass, 0].surface.bounce = 0.5f;
 
  771             m_materialContacts[(
int)Material.Glass, 0].surface.soft_cfm = 0.010f;
 
  772             m_materialContacts[(int)
Material.Glass, 0].surface.soft_erp = 0.010f;
 
  781             m_materialContacts[(
int)Material.Glass, 1] = 
new d.Contact();
 
  782             m_materialContacts[(int)
Material.Glass, 1].surface.mode |= d.ContactFlags.SoftERP;
 
  783             m_materialContacts[(
int)Material.Glass, 1].surface.mu = 1f;
 
  784             m_materialContacts[(int)
Material.Glass, 1].surface.bounce = 0.5f;
 
  785             m_materialContacts[(
int)Material.Glass, 1].surface.soft_cfm = 0.010f;
 
  786             m_materialContacts[(int)
Material.Glass, 1].surface.soft_erp = 0.010f;
 
  788             m_materialContacts[(
int)Material.Wood, 0] = 
new d.Contact();
 
  789             m_materialContacts[(int)
Material.Wood, 0].surface.mode |= d.ContactFlags.SoftERP;
 
  790             m_materialContacts[(
int)Material.Wood, 0].surface.mu = nmAvatarObjectContactFriction;
 
  791             m_materialContacts[(int)
Material.Wood, 0].surface.bounce = nmAvatarObjectContactBounce;
 
  792             m_materialContacts[(
int)Material.Wood, 0].surface.soft_cfm = 0.010f;
 
  793             m_materialContacts[(int)
Material.Wood, 0].surface.soft_erp = 0.010f;
 
  795             m_materialContacts[(
int)Material.Wood, 1] = 
new d.Contact();
 
  796             m_materialContacts[(int)
Material.Wood, 1].surface.mode |= d.ContactFlags.SoftERP;
 
  797             m_materialContacts[(
int)Material.Wood, 1].surface.mu = mAvatarObjectContactFriction;
 
  798             m_materialContacts[(int)
Material.Wood, 1].surface.bounce = mAvatarObjectContactBounce;
 
  799             m_materialContacts[(
int)Material.Wood, 1].surface.soft_cfm = 0.010f;
 
  800             m_materialContacts[(int)
Material.Wood, 1].surface.soft_erp = 0.010f;
 
  802             m_materialContacts[(
int)Material.Flesh, 0] = 
new d.Contact();
 
  803             m_materialContacts[(int)
Material.Flesh, 0].surface.mode |= d.ContactFlags.SoftERP;
 
  804             m_materialContacts[(
int)Material.Flesh, 0].surface.mu = nmAvatarObjectContactFriction;
 
  805             m_materialContacts[(int)
Material.Flesh, 0].surface.bounce = nmAvatarObjectContactBounce;
 
  806             m_materialContacts[(
int)Material.Flesh, 0].surface.soft_cfm = 0.010f;
 
  807             m_materialContacts[(int)
Material.Flesh, 0].surface.soft_erp = 0.010f;
 
  809             m_materialContacts[(
int)Material.Flesh, 1] = 
new d.Contact();
 
  810             m_materialContacts[(int)
Material.Flesh, 1].surface.mode |= d.ContactFlags.SoftERP;
 
  811             m_materialContacts[(
int)Material.Flesh, 1].surface.mu = mAvatarObjectContactFriction;
 
  812             m_materialContacts[(int)
Material.Flesh, 1].surface.bounce = mAvatarObjectContactBounce;
 
  813             m_materialContacts[(
int)Material.Flesh, 1].surface.soft_cfm = 0.010f;
 
  814             m_materialContacts[(int)
Material.Flesh, 1].surface.soft_erp = 0.010f;
 
  816             m_materialContacts[(
int)Material.Plastic, 0] = 
new d.Contact();
 
  817             m_materialContacts[(int)
Material.Plastic, 0].surface.mode |= d.ContactFlags.SoftERP;
 
  818             m_materialContacts[(
int)Material.Plastic, 0].surface.mu = nmAvatarObjectContactFriction;
 
  819             m_materialContacts[(int)
Material.Plastic, 0].surface.bounce = nmAvatarObjectContactBounce;
 
  820             m_materialContacts[(
int)Material.Plastic, 0].surface.soft_cfm = 0.010f;
 
  821             m_materialContacts[(int)
Material.Plastic, 0].surface.soft_erp = 0.010f;
 
  823             m_materialContacts[(
int)Material.Plastic, 1] = 
new d.Contact();
 
  824             m_materialContacts[(int)
Material.Plastic, 1].surface.mode |= d.ContactFlags.SoftERP;
 
  825             m_materialContacts[(
int)Material.Plastic, 1].surface.mu = mAvatarObjectContactFriction;
 
  826             m_materialContacts[(int)
Material.Plastic, 1].surface.bounce = mAvatarObjectContactBounce;
 
  827             m_materialContacts[(
int)Material.Plastic, 1].surface.soft_cfm = 0.010f;
 
  828             m_materialContacts[(int)
Material.Plastic, 1].surface.soft_erp = 0.010f;
 
  830             m_materialContacts[(
int)Material.Rubber, 0] = 
new d.Contact();
 
  831             m_materialContacts[(int)
Material.Rubber, 0].surface.mode |= d.ContactFlags.SoftERP;
 
  832             m_materialContacts[(
int)Material.Rubber, 0].surface.mu = nmAvatarObjectContactFriction;
 
  833             m_materialContacts[(int)
Material.Rubber, 0].surface.bounce = nmAvatarObjectContactBounce;
 
  834             m_materialContacts[(
int)Material.Rubber, 0].surface.soft_cfm = 0.010f;
 
  835             m_materialContacts[(int)
Material.Rubber, 0].surface.soft_erp = 0.010f;
 
  837             m_materialContacts[(
int)Material.Rubber, 1] = 
new d.Contact();
 
  838             m_materialContacts[(int)
Material.Rubber, 1].surface.mode |= d.ContactFlags.SoftERP;
 
  839             m_materialContacts[(
int)Material.Rubber, 1].surface.mu = mAvatarObjectContactFriction;
 
  840             m_materialContacts[(int)
Material.Rubber, 1].surface.bounce = mAvatarObjectContactBounce;
 
  841             m_materialContacts[(
int)Material.Rubber, 1].surface.soft_cfm = 0.010f;
 
  842             m_materialContacts[(int)
Material.Rubber, 1].surface.soft_erp = 0.010f;
 
  844             d.HashSpaceSetLevels(space, HashspaceLow, HashspaceHigh);
 
  848             d.WorldSetGravity(world, gravityx, gravityy, gravityz);
 
  849             d.WorldSetContactSurfaceLayer(world, contactsurfacelayer);
 
  851             d.WorldSetLinearDamping(world, 256f);
 
  852             d.WorldSetAngularDamping(world, 256f);
 
  853             d.WorldSetAngularDampingThreshold(world, 256f);
 
  854             d.WorldSetLinearDampingThreshold(world, 256f);
 
  855             d.WorldSetMaxAngularSpeed(world, 256f);
 
  857             d.WorldSetQuickStepNumIterations(world, m_physicsiterations);
 
  860             for (
int i = 0; i < staticPrimspace.GetLength(0); i++)
 
  862                 for (
int j = 0; j < staticPrimspace.GetLength(1); j++)
 
  864                     staticPrimspace[i, j] = IntPtr.Zero;
 
  868             _worldInitialized = 
true;
 
  871         #region Collision Detection 
  882         private int CollideGeoms(
 
  883             IntPtr geom1, IntPtr geom2, 
int maxContacts, d.ContactGeom[] contactsArray, 
int contactGeomSize)
 
  887             lock (OdeScene.UniversalColliderSyncObject)
 
  891                     m_nativeCollisionStartTick = Util.EnvironmentTickCount();
 
  893                 count = d.Collide(geom1, geom2, maxContacts, contactsArray, contactGeomSize);
 
  899                 m_stats[ODENativeGeomCollisionFrameMsStatName]
 
  900                     += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick);
 
  911         private void CollideSpaces(IntPtr space1, IntPtr space2, IntPtr data)
 
  915                 m_inCollisionTiming = 
true;
 
  916                 m_nativeCollisionStartTick = Util.EnvironmentTickCount();
 
  919             d.SpaceCollide2(space1, space2, data, nearCallback);
 
  921             if (CollectStats && m_inCollisionTiming)
 
  923                 m_stats[ODENativeSpaceCollisionFrameMsStatName]
 
  924                     += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick);
 
  925                 m_inCollisionTiming = 
false;
 
  935         private void near(IntPtr space, IntPtr g1, IntPtr g2)
 
  937             if (CollectStats && m_inCollisionTiming)
 
  939                 m_stats[ODENativeSpaceCollisionFrameMsStatName]
 
  940                     += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick);
 
  941                 m_inCollisionTiming = 
false;
 
  950             if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
 
  952                 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
 
  961                     CollideSpaces(g1, g2, IntPtr.Zero);
 
  963                 catch (AccessViolationException)
 
  965                     m_log.Error(
"[ODE SCENE]: Unable to collide test a space");
 
  976             if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
 
  979             IntPtr b1 = d.GeomGetBody(g1);
 
  980             IntPtr b2 = d.GeomGetBody(g2);
 
  987             if (!geom_name_map.TryGetValue(g1, out name1))
 
  991             if (!geom_name_map.TryGetValue(g2, out name2))
 
 1007                 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
 
 1010                 count = CollideGeoms(g1, g2, contacts.Length, contacts, d.ContactGeom.unmanagedSizeOf);
 
 1016                 if (count > contacts.Length)
 
 1017                     m_log.Error(
"[ODE SCENE]: Got " + count + 
" contacts when we asked for a maximum of " + contacts.Length);
 
 1019             catch (SEHException)
 
 1022                     "[ODE SCENE]: The Operating system shut down ODE because of corrupt memory.  This could be a result of really irregular terrain.  If this repeats continuously, restart using Basic Physics and terrain fill your terrain.  Restarting the sim.");
 
 1023                 base.TriggerPhysicsBasedRestart();
 
 1027                 m_log.ErrorFormat(
"[ODE SCENE]: Unable to collide test an object: {0}", e.Message);
 
 1034             p1ExpectedPoints = 0;
 
 1035             p2ExpectedPoints = 0;
 
 1037             if (!actor_name_map.TryGetValue(g1, out p1))
 
 1042             if (!actor_name_map.TryGetValue(g2, out p2))
 
 1048             if (p1.CollisionScore + count >= 
float.MaxValue)
 
 1049                 p1.CollisionScore = 0;
 
 1050             p1.CollisionScore += count;
 
 1052             if (p2.CollisionScore + count >= 
float.MaxValue)
 
 1053                 p2.CollisionScore = 0;
 
 1054             p2.CollisionScore += count;
 
 1056             for (
int i = 0; i < count; i++)
 
 1058                 d.ContactGeom curContact = contacts[i];
 
 1063                         new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z),
 
 1064                         new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z),
 
 1075                 if (p2 is OdeCharacter && p1.PhysicsActorType == (
int)
ActorTypes.Prim)
 
 1080                     if ((p2.Position.Z - curContact.pos.Z) > (p2.Size.Z * 0.6f))
 
 1081                         p2.IsColliding = 
true;
 
 1085                     p2.IsColliding = 
true;
 
 1090                 switch (p1.PhysicsActorType)
 
 1092                     case (
int)ActorTypes.Agent:
 
 1093                         p1ExpectedPoints = avatarExpectedContacts;
 
 1094                         p2.CollidingObj = 
true;
 
 1096                     case (
int)ActorTypes.Prim:
 
 1097                         if (p1 != null && p1 is OdePrim)
 
 1098                             p1ExpectedPoints = ((OdePrim) p1).ExpectedCollisionContacts;
 
 1100                         if (p2.Velocity.LengthSquared() > 0.0f)
 
 1101                             p2.CollidingObj = 
true;
 
 1103                     case (
int)ActorTypes.Unknown:
 
 1104                         p2.CollidingGround = 
true;
 
 1107                         p2.CollidingGround = 
true;
 
 1113                 #region InterPenetration Handling - Unintended physics explosions 
 1115                 if (curContact.depth >= 0.08f)
 
 1117                     if (curContact.depth >= 1.00f)
 
 1120                         if ((p2.PhysicsActorType == (
int) 
ActorTypes.Agent &&
 
 1121                              p1.PhysicsActorType == (
int) 
ActorTypes.Unknown) ||
 
 1122                             (p1.PhysicsActorType == (int) 
ActorTypes.Agent &&
 
 1123                              p2.PhysicsActorType == (
int) ActorTypes.Unknown))
 
 1125                             if (p2.PhysicsActorType == (
int) ActorTypes.Agent)
 
 1127                                 if (p2 is OdeCharacter)
 
 1129                                     OdeCharacter character = (OdeCharacter) p2;
 
 1132                                     curContact.depth = 0.00000003f;
 
 1133                                     p2.Velocity = p2.Velocity + 
new Vector3(0f, 0f, 0.5f);
 
 1135                                         new d.Vector3(curContact.pos.X + (p1.Size.X/2),
 
 1136                                                       curContact.pos.Y + (p1.Size.Y/2),
 
 1137                                                       curContact.pos.Z + (p1.Size.Z/2));
 
 1138                                     character.SetPidStatus(
true);
 
 1142                             if (p1.PhysicsActorType == (
int) ActorTypes.Agent)
 
 1144                                 if (p1 is OdeCharacter)
 
 1146                                     OdeCharacter character = (OdeCharacter) p1;
 
 1149                                     curContact.depth = 0.00000003f;
 
 1150                                     p1.Velocity = p1.Velocity + 
new Vector3(0f, 0f, 0.5f);
 
 1152                                         new d.Vector3(curContact.pos.X + (p1.Size.X/2),
 
 1153                                                       curContact.pos.Y + (p1.Size.Y/2),
 
 1154                                                       curContact.pos.Z + (p1.Size.Z/2));
 
 1155                                     character.SetPidStatus(
true);
 
 1168                 Boolean skipThisContact = 
false;
 
 1170                 if ((p1 is OdePrim) && (((OdePrim)p1).m_isVolumeDetect))
 
 1171                     skipThisContact = 
true;   
 
 1173                 if (av_av_collisions_off)
 
 1174                     if ((p1 is OdeCharacter) && (p2 is OdeCharacter))
 
 1175                         skipThisContact = 
true;
 
 1177                 if (!skipThisContact && (p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect))
 
 1178                     skipThisContact = 
true;   
 
 1180                 if (!skipThisContact && curContact.depth < 0f)
 
 1181                     skipThisContact = 
true;
 
 1183                 if (!skipThisContact && checkDupe(curContact, p2.PhysicsActorType))
 
 1184                     skipThisContact = 
true;
 
 1186                 const int maxContactsbeforedeath = 4000;
 
 1187                 joint = IntPtr.Zero;
 
 1189                 if (!skipThisContact)
 
 1191                     _perloopContact.Add(curContact);
 
 1193                     if (name1 == 
"Terrain" || name2 == 
"Terrain")
 
 1195                         if ((p2.PhysicsActorType == (
int) ActorTypes.Agent) &&
 
 1196                             (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
 
 1198                             p2ExpectedPoints = avatarExpectedContacts;
 
 1200                             AvatarMovementTerrainContact.geom = curContact;
 
 1202                             if (m_global_contactcount < maxContactsbeforedeath)
 
 1204                                 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact);
 
 1205                                 m_global_contactcount++;
 
 1210                             if (p2.PhysicsActorType == (
int)ActorTypes.Agent)
 
 1212                                 p2ExpectedPoints = avatarExpectedContacts;
 
 1214                                 TerrainContact.geom = curContact;
 
 1216                                 if (m_global_contactcount < maxContactsbeforedeath)
 
 1218                                     joint = d.JointCreateContact(world, contactgroup, ref TerrainContact);
 
 1219                                     m_global_contactcount++;
 
 1224                                 if (p2.PhysicsActorType == (
int)ActorTypes.Prim && p1.PhysicsActorType == (int)
ActorTypes.Prim)
 
 1229                                     int material = (int) 
Material.Wood;
 
 1231                                     if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)
 
 1238                                         material = ((OdePrim) p2).m_material;
 
 1239                                         p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
 
 1249                                     m_materialContacts[material, movintYN].geom = curContact;
 
 1251                                     if (m_global_contactcount < maxContactsbeforedeath)
 
 1253                                         joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]);
 
 1254                                         m_global_contactcount++;
 
 1261                                     if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)
 
 1270                                         material = ((OdePrim)p2).m_material;
 
 1271                                         p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
 
 1275                                     m_materialContacts[material, movintYN].geom = curContact;
 
 1277                                     if (m_global_contactcount < maxContactsbeforedeath)
 
 1279                                         joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]);
 
 1280                                         m_global_contactcount++;
 
 1290                     else if (name1 == 
"Water" || name2 == 
"Water")
 
 1302                         if (curContact.depth > 0.1f)
 
 1304                             curContact.depth *= 52;
 
 1309                         WaterContact.geom = curContact;
 
 1311                         if (m_global_contactcount < maxContactsbeforedeath)
 
 1313                             joint = d.JointCreateContact(world, contactgroup, ref WaterContact);
 
 1314                             m_global_contactcount++;
 
 1320                         if ((p2.PhysicsActorType == (
int)ActorTypes.Agent))
 
 1322                             p2ExpectedPoints = avatarExpectedContacts;
 
 1323                             if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
 
 1326                                 AvatarMovementprimContact.geom = curContact;
 
 1328                                 if (m_global_contactcount < maxContactsbeforedeath)
 
 1330                                     joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact);
 
 1331                                     m_global_contactcount++;
 
 1337                                 contact.geom = curContact;
 
 1339                                 if (m_global_contactcount < maxContactsbeforedeath)
 
 1341                                     joint = d.JointCreateContact(world, contactgroup, ref contact);
 
 1342                                     m_global_contactcount++;
 
 1346                         else if (p2.PhysicsActorType == (
int)ActorTypes.Prim)
 
 1353                                 material = ((OdePrim)p2).m_material;
 
 1354                                 p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
 
 1358                             m_materialContacts[material, 0].geom = curContact;
 
 1360                             if (m_global_contactcount < maxContactsbeforedeath)
 
 1362                                 joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, 0]);
 
 1363                                 m_global_contactcount++;
 
 1368                     if (m_global_contactcount < maxContactsbeforedeath && joint != IntPtr.Zero) 
 
 1370                         d.JointAttach(joint, b1, b2);
 
 1371                         m_global_contactcount++;
 
 1375                 collision_accounting_events(p1, p2, maxDepthContact);
 
 1377                 if (count > ((p1ExpectedPoints + p2ExpectedPoints) * 0.25) + (geomContactPointsStartthrottle))
 
 1383                     p2.ThrottleUpdates = 
true;
 
 1390         private bool checkDupe(d.ContactGeom contactGeom, 
int atype)
 
 1392             if (!m_filterCollisions)
 
 1395             bool result = 
false;
 
 1399             foreach (d.ContactGeom contact in _perloopContact)
 
 1406                     if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f)
 
 1407                         && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f)
 
 1408                         && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)))
 
 1410                         if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f)
 
 1419                     if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)))
 
 1421                         if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z)
 
 1423                             if (Math.Abs(contact.depth - contactGeom.depth) < 0.272f)
 
 1447             bool p1events = p1.SubscribedEvents();
 
 1448             bool p2events = p2.SubscribedEvents();
 
 1455             if (!p2events && !p1events)
 
 1458             Vector3 vel = Vector3.Zero;
 
 1465             contact.RelativeSpeed = Vector3.Dot(vel, contact.SurfaceNormal);
 
 1469                 case ActorTypes.Agent:
 
 1470                     cc2 = (OdeCharacter)p2;
 
 1475                         case ActorTypes.Agent:
 
 1476                             cc1 = (OdeCharacter)p1;
 
 1477                             obj2LocalID = cc1.LocalID;
 
 1478                             cc1.AddCollisionEvent(cc2.LocalID, contact);
 
 1481                         case ActorTypes.Prim:
 
 1485                                 obj2LocalID = cp1.LocalID;
 
 1486                                 cp1.AddCollisionEvent(cc2.LocalID, contact);
 
 1490                         case ActorTypes.Ground:
 
 1491                         case ActorTypes.Unknown:
 
 1496                     cc2.AddCollisionEvent(obj2LocalID, contact);
 
 1499                 case ActorTypes.Prim:
 
 1508                             case ActorTypes.Agent:
 
 1509                                 if (p1 is OdeCharacter)
 
 1511                                     cc1 = (OdeCharacter) p1;
 
 1512                                     obj2LocalID = cc1.LocalID;
 
 1513                                     cc1.AddCollisionEvent(cp2.LocalID, contact);
 
 1516                             case ActorTypes.Prim:
 
 1521                                     obj2LocalID = cp1.LocalID;
 
 1522                                     cp1.AddCollisionEvent(cp2.LocalID, contact);
 
 1526                             case ActorTypes.Ground:
 
 1527                             case ActorTypes.Unknown:
 
 1532                         cp2.AddCollisionEvent(obj2LocalID, contact);
 
 1540         private void collision_optimized()
 
 1542             _perloopContact.Clear();
 
 1544             foreach (OdeCharacter chr 
in _characters)
 
 1548                 if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero)
 
 1551                 chr.IsColliding = 
false;
 
 1552                 chr.CollidingGround = 
false;
 
 1553                 chr.CollidingObj = 
false;
 
 1562                     CollideSpaces(space, chr.Shell, IntPtr.Zero);
 
 1564                 catch (AccessViolationException)
 
 1566                     m_log.ErrorFormat(
"[ODE SCENE]: Unable to space collide {0}", PhysicsSceneName);
 
 1579                 m_tempAvatarCollisionsThisFrame = _perloopContact.Count;
 
 1580                 m_stats[ODEAvatarContactsStatsName] += m_tempAvatarCollisionsThisFrame;
 
 1583             List<OdePrim> removeprims = null;
 
 1584             foreach (OdePrim chr 
in _activeprims)
 
 1586                 if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled))
 
 1592                             if (space != IntPtr.Zero && chr.prim_geom != IntPtr.Zero && chr.m_taintremove == 
false)
 
 1594                                 CollideSpaces(space, chr.prim_geom, IntPtr.Zero);
 
 1598                                 if (removeprims == null)
 
 1600                                     removeprims = 
new List<OdePrim>();
 
 1602                                 removeprims.Add(chr);
 
 1604                                     "[ODE SCENE]: unable to collide test active prim against space.  The space was zero, the geom was zero or it was in the process of being removed.  Removed it from the active prim list.  This needs to be fixed!");
 
 1608                     catch (AccessViolationException)
 
 1610                         m_log.Error(
"[ODE SCENE]: Unable to space collide");
 
 1616                 m_stats[ODEPrimContactsStatName] += _perloopContact.Count - m_tempAvatarCollisionsThisFrame;
 
 1618             if (removeprims != null)
 
 1620                 foreach (OdePrim chr 
in removeprims)
 
 1622                     _activeprims.Remove(chr);
 
 1631             if (!m_suportCombine)
 
 1633             m_worldOffset = offset;
 
 1634             WorldExtents = 
new Vector2(extents.X, extents.Y);
 
 1635             m_parentScene = pScene;
 
 1639         internal float GetTerrainHeightAtXY(
float x, 
float y)
 
 1641             IntPtr heightFieldGeom = IntPtr.Zero;
 
 1645             if (m_suportCombine)
 
 1651             if(RegionTerrain.TryGetValue(
new Vector3(offsetX,offsetY,0), out heightFieldGeom))
 
 1653                 if (heightFieldGeom != IntPtr.Zero)
 
 1655                     if (TerrainHeightFieldHeights.ContainsKey(heightFieldGeom))
 
 1661                         if ((
int)x > WorldExtents.X || (int)y > WorldExtents.Y ||
 
 1662                             (
int)x < 0.001f || (int)y < 0.001f)
 
 1665                         x = x - offsetX + 1f;
 
 1666                         y = y - offsetY + 1f;
 
 1669                         index = (int)x * ((
int)m_regionHeight + 3) + (
int)y;
 
 1671                         if (index < TerrainHeightFieldHeights[heightFieldGeom].Length)
 
 1674                             return (
float)TerrainHeightFieldHeights[heightFieldGeom][index];
 
 1703         internal void AddCollisionEventReporting(
PhysicsActor obj)
 
 1707             lock (m_collisionEventActorsChanges)
 
 1708                 m_collisionEventActorsChanges[obj.LocalID] = obj;
 
 1715         internal 
void RemoveCollisionEventReporting(
PhysicsActor obj)
 
 1719             lock (m_collisionEventActorsChanges)
 
 1720                 m_collisionEventActorsChanges[obj.LocalID] = null;
 
 1723         #region Add/Remove Entities 
 1727             d.AllocateODEDataForThread(0);
 
 1731                     avName, 
this, position, velocity, size, avPIDD, avPIDP,
 
 1732                     avCapRadius, avStandupTensor, avDensity,
 
 1733                     avMovementDivisorWalk, avMovementDivisorRun);
 
 1735             newAv.Flying = isFlying;
 
 1736             newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset;
 
 1737             newAv.m_avatarplanted = avplanted;
 
 1750                 d.AllocateODEDataForThread(0);
 
 1752                 ((OdeCharacter) actor).Destroy();
 
 1756         internal void AddCharacter(OdeCharacter chr)
 
 1758             chr.m_avatarplanted = avplanted;
 
 1759             if (!_characters.Contains(chr))
 
 1761                 _characters.Add(chr);
 
 1768                     m_log.ErrorFormat(
"[ODE SCENE]: Added BAD actor {0} to characters list", chr.m_uuid);
 
 1773                     "[ODE SCENE]: Tried to add character {0} {1} but they are already in the set!",
 
 1774                     chr.Name, chr.LocalID);
 
 1778         internal void RemoveCharacter(OdeCharacter chr)
 
 1780             if (_characters.Contains(chr))
 
 1782                 _characters.Remove(chr);
 
 1791                     "[ODE SCENE]: Tried to remove character {0} {1} but they are not in the list!",
 
 1792                     chr.Name, chr.LocalID);
 
 1799             Vector3 pos = position;
 
 1807                 d.AllocateODEDataForThread(0);
 
 1808                 newPrim = 
new OdePrim(name, 
this, pos, siz, rot, pbs, isphysical);
 
 1811                     _prims.Add(newPrim);
 
 1813             newPrim.LocalID = localID;
 
 1821         internal 
void ActivatePrim(OdePrim prim)
 
 1824             if (!_activeprims.Contains(prim))
 
 1825                 _activeprims.Add(prim);
 
 1831                                                   Vector3 size, Quaternion rotation, 
bool isPhysical, uint localid)
 
 1835             return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid);
 
 1838         public override float TimeDilation
 
 1840             get { 
return m_timeDilation; }
 
 1843         public override bool SupportsNINJAJoints
 
 1845             get { 
return m_NINJA_physics_joints_enabled; }
 
 1849         private void InternalAddActiveJoint(
PhysicsJoint joint)
 
 1851             activeJoints.Add(joint);
 
 1852             SOPName_to_activeJoint.Add(joint.ObjectNameInScene, joint);
 
 1856         private void InternalAddPendingJoint(OdePhysicsJoint joint)
 
 1858             pendingJoints.Add(joint);
 
 1859             SOPName_to_pendingJoint.Add(joint.ObjectNameInScene, joint);
 
 1863         private void InternalRemovePendingJoint(
PhysicsJoint joint)
 
 1865             pendingJoints.Remove(joint);
 
 1866             SOPName_to_pendingJoint.Remove(joint.ObjectNameInScene);
 
 1870         private void InternalRemoveActiveJoint(
PhysicsJoint joint)
 
 1872             activeJoints.Remove(joint);
 
 1873             SOPName_to_activeJoint.Remove(joint.ObjectNameInScene);
 
 1878             string hdr = 
"[NINJA] JOINTINFO: ";
 
 1881                 m_log.Debug(hdr + 
" pending joint, Name: " + j.ObjectNameInScene + 
" raw parms:" + j.RawParams);
 
 1883             m_log.Debug(hdr + pendingJoints.Count + 
" total pending joints");
 
 1884             foreach (
string jointName 
in SOPName_to_pendingJoint.Keys)
 
 1886                 m_log.Debug(hdr + 
" pending joints dict contains Name: " + jointName);
 
 1888             m_log.Debug(hdr + SOPName_to_pendingJoint.Keys.Count + 
" total pending joints dict entries");
 
 1891                 m_log.Debug(hdr + 
" active joint, Name: " + j.ObjectNameInScene + 
" raw parms:" + j.RawParams);
 
 1893             m_log.Debug(hdr + activeJoints.Count + 
" total active joints");
 
 1894             foreach (
string jointName 
in SOPName_to_activeJoint.Keys)
 
 1896                 m_log.Debug(hdr + 
" active joints dict contains Name: " + jointName);
 
 1898             m_log.Debug(hdr + SOPName_to_activeJoint.Keys.Count + 
" total active joints dict entries");
 
 1900             m_log.Debug(hdr + 
" Per-body joint connectivity information follows.");
 
 1901             m_log.Debug(hdr + joints_connecting_actor.Keys.Count + 
" bodies are connected by joints.");
 
 1902             foreach (
string actorName 
in joints_connecting_actor.Keys)
 
 1904                 m_log.Debug(hdr + 
" Actor " + actorName + 
" has the following joints connecting it");
 
 1905                 foreach (
PhysicsJoint j 
in joints_connecting_actor[actorName])
 
 1907                     m_log.Debug(hdr + 
" * joint Name: " + j.ObjectNameInScene + 
" raw parms:" + j.RawParams);
 
 1909                 m_log.Debug(hdr + joints_connecting_actor[actorName].Count + 
" connecting joints total for this actor");
 
 1915             lock (externalJointRequestsLock)
 
 1917                 if (!requestedJointsToBeDeleted.Contains(ObjectNameInScene)) 
 
 1919                     requestedJointsToBeDeleted.Add(ObjectNameInScene);
 
 1924         private void DeleteRequestedJoints()
 
 1926             List<string> myRequestedJointsToBeDeleted;
 
 1927             lock (externalJointRequestsLock)
 
 1930                 myRequestedJointsToBeDeleted = 
new List<string>(requestedJointsToBeDeleted);
 
 1933             foreach (
string jointName 
in myRequestedJointsToBeDeleted)
 
 1938                     if (SOPName_to_activeJoint.ContainsKey(jointName) || SOPName_to_pendingJoint.ContainsKey(jointName))
 
 1940                         OdePhysicsJoint joint = null;
 
 1941                         if (SOPName_to_activeJoint.ContainsKey(jointName))
 
 1943                             joint = SOPName_to_activeJoint[jointName] as OdePhysicsJoint;
 
 1944                             InternalRemoveActiveJoint(joint);
 
 1946                         else if (SOPName_to_pendingJoint.ContainsKey(jointName))
 
 1948                             joint = SOPName_to_pendingJoint[jointName] as OdePhysicsJoint;
 
 1949                             InternalRemovePendingJoint(joint);
 
 1955                             for (
int iBodyName = 0; iBodyName < 2; iBodyName++)
 
 1957                                 string bodyName = joint.BodyNames[iBodyName];
 
 1958                                 if (bodyName != 
"NULL")
 
 1960                                     joints_connecting_actor[bodyName].Remove(joint);
 
 1961                                     if (joints_connecting_actor[bodyName].Count == 0)
 
 1963                                         joints_connecting_actor.Remove(bodyName);
 
 1968                             DoJointDeactivated(joint);
 
 1969                             if (joint.jointID != IntPtr.Zero)
 
 1971                                 d.JointDestroy(joint.jointID);
 
 1972                                 joint.jointID = IntPtr.Zero;
 
 1993             lock (externalJointRequestsLock)
 
 1995                 foreach (
string jointName 
in myRequestedJointsToBeDeleted)
 
 1997                     requestedJointsToBeDeleted.Remove(jointName);
 
 2004         private void CreateRequestedJoints()
 
 2006             List<PhysicsJoint> myRequestedJointsToBeCreated;
 
 2007             lock (externalJointRequestsLock)
 
 2010                 myRequestedJointsToBeCreated = 
new List<PhysicsJoint>(requestedJointsToBeCreated);
 
 2013             foreach (
PhysicsJoint joint 
in myRequestedJointsToBeCreated)
 
 2017                     if (SOPName_to_pendingJoint.ContainsKey(joint.
ObjectNameInScene) && SOPName_to_pendingJoint[joint.ObjectNameInScene] != null)
 
 2019                         DoJointErrorMessage(joint, 
"WARNING: ignoring request to re-add already pending joint Name:" + joint.
ObjectNameInScene + 
" type:" + joint.
Type + 
" parms: " + joint.
RawParams + 
" pos: " + joint.
Position + 
" rot:" + joint.
Rotation);
 
 2022                     if (SOPName_to_activeJoint.ContainsKey(joint.
ObjectNameInScene) && SOPName_to_activeJoint[joint.ObjectNameInScene] != null)
 
 2024                         DoJointErrorMessage(joint, 
"WARNING: ignoring request to re-add already active joint Name:" + joint.
ObjectNameInScene + 
" type:" + joint.
Type + 
" parms: " + joint.
RawParams + 
" pos: " + joint.
Position + 
" rot:" + joint.
Rotation);
 
 2028                     InternalAddPendingJoint(joint as OdePhysicsJoint);
 
 2032                         for (
int iBodyName = 0; iBodyName < 2; iBodyName++)
 
 2034                             string bodyName = joint.BodyNames[iBodyName];
 
 2035                             if (bodyName != 
"NULL")
 
 2037                                 if (!joints_connecting_actor.ContainsKey(bodyName))
 
 2039                                     joints_connecting_actor.Add(bodyName, 
new List<PhysicsJoint>());
 
 2041                                 joints_connecting_actor[bodyName].Add(joint);
 
 2049             lock (externalJointRequestsLock)
 
 2051                 foreach (
PhysicsJoint joint 
in myRequestedJointsToBeCreated)
 
 2053                     requestedJointsToBeCreated.Remove(joint);
 
 2076             Quaternion rotation, 
string parms, List<string> bodyNames, 
string trackedBodyName, Quaternion localRotation)
 
 2079             joint.ObjectNameInScene = objectNameInScene;
 
 2080             joint.Type = jointType;
 
 2081             joint.Position = position;
 
 2083             joint.RawParams = parms;
 
 2084             joint.BodyNames = 
new List<string>(bodyNames);
 
 2085             joint.TrackedBodyName = trackedBodyName;
 
 2086             joint.LocalRotation = localRotation;
 
 2087             joint.jointID = IntPtr.Zero;
 
 2088             joint.ErrorMessageCount = 0;
 
 2090             lock (externalJointRequestsLock)
 
 2092                 if (!requestedJointsToBeCreated.Contains(joint)) 
 
 2094                     requestedJointsToBeCreated.Add(joint);
 
 2101         private void RemoveAllJointsConnectedToActor(
PhysicsActor actor)
 
 2104             if (actor.
SOPName != null && joints_connecting_actor.ContainsKey(actor.
SOPName) && joints_connecting_actor[actor.SOPName] != null)
 
 2106                 List<PhysicsJoint> jointsToRemove = 
new List<PhysicsJoint>();
 
 2110                     jointsToRemove.Add(j);
 
 2117                     j.TrackedBodyName = null; 
 
 2128                 RemoveAllJointsConnectedToActor(actor);
 
 2135             Debug.Assert(joint.IsInPhysicsEngine);
 
 2140                 DoJointErrorMessage(joint, 
"warning: non-ODE joint requesting anchor: " + joint.
ObjectNameInScene);
 
 2144                 OdePhysicsJoint odeJoint = (OdePhysicsJoint)joint;
 
 2145                 switch (odeJoint.
Type)
 
 2147                     case PhysicsJointType.Ball:
 
 2148                         d.JointGetBallAnchor(odeJoint.jointID, out pos);
 
 2150                     case PhysicsJointType.Hinge:
 
 2151                         d.JointGetHingeAnchor(odeJoint.jointID, out pos);
 
 2155             return new Vector3(pos.X, pos.Y, pos.Z);
 
 2171             Debug.Assert(joint.IsInPhysicsEngine);
 
 2176                 DoJointErrorMessage(joint, 
"warning: non-ODE joint requesting anchor: " + joint.
ObjectNameInScene);
 
 2180                 OdePhysicsJoint odeJoint = (OdePhysicsJoint)joint;
 
 2181                 switch (odeJoint.
Type)
 
 2183                     case PhysicsJointType.Ball:
 
 2184                         DoJointErrorMessage(joint, 
"warning - axis requested for ball joint: " + joint.
ObjectNameInScene);
 
 2186                     case PhysicsJointType.Hinge:
 
 2187                         d.JointGetHingeAxis(odeJoint.jointID, out axis);
 
 2191             return new Vector3(axis.X, axis.Y, axis.Z);
 
 2198         internal void DeactivatePrim(OdePrim prim)
 
 2200             _activeprims.Remove(prim);
 
 2207             if (prim is OdePrim)
 
 2211                     OdePrim p = (OdePrim) prim;
 
 2213                     p.setPrimForRemoval();
 
 2214                     AddPhysicsActorTaint(prim);
 
 2231         internal void RemovePrimThreadLocked(OdePrim prim)
 
 2237                 RemoveCollisionEventReporting(prim);
 
 2248                             prim.childPrim = 
false;
 
 2249                             prim.Body = IntPtr.Zero;
 
 2250                             prim.m_disabled = 
true;
 
 2251                             prim.IsPhysical = 
false;
 
 2256                     prim.m_targetSpace = IntPtr.Zero;
 
 2257                     if (!prim.RemoveGeom())
 
 2258                         m_log.Warn(
"[ODE SCENE]: Unable to remove prim from physics scene");
 
 2261                         _prims.Remove(prim);
 
 2264                     if (SupportsNINJAJoints)
 
 2265                         RemoveAllJointsConnectedToActorThreadLocked(prim);
 
 2272         #region Space Separation Calculation 
 2278         private void resetSpaceArrayItemToZero(IntPtr pSpace)
 
 2280             for (
int x = 0; x < staticPrimspace.GetLength(0); x++)
 
 2282                 for (
int y = 0; y < staticPrimspace.GetLength(1); y++)
 
 2284                     if (staticPrimspace[x, y] == pSpace)
 
 2285                         staticPrimspace[x, y] = IntPtr.Zero;
 
 2302         internal IntPtr recalculateSpaceForGeom(IntPtr geom, Vector3 pos, IntPtr currentspace)
 
 2313             if (currentspace != space)
 
 2320                 if (d.SpaceQuery(currentspace, geom) && currentspace != IntPtr.Zero)
 
 2322                     if (d.GeomIsSpace(currentspace))
 
 2325                         d.SpaceRemove(currentspace, geom);
 
 2329                         m_log.Info(
"[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + currentspace +
 
 2335                     IntPtr sGeomIsIn = d.GeomGetSpace(geom);
 
 2336                     if (sGeomIsIn != IntPtr.Zero)
 
 2338                         if (d.GeomIsSpace(currentspace))
 
 2341                             d.SpaceRemove(sGeomIsIn, geom);
 
 2345                             m_log.Info(
"[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" +
 
 2346                                        sGeomIsIn + 
" Geom:" + geom);
 
 2352                 if (d.SpaceGetNumGeoms(currentspace) == 0)
 
 2354                     if (currentspace != IntPtr.Zero)
 
 2356                         if (d.GeomIsSpace(currentspace))
 
 2358                             d.SpaceRemove(space, currentspace);
 
 2361                             resetSpaceArrayItemToZero(currentspace);
 
 2365                             m_log.Info(
"[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" +
 
 2366                                        currentspace + 
" Geom:" + geom);
 
 2374                 if (currentspace != IntPtr.Zero && geom != IntPtr.Zero)
 
 2376                     if (d.SpaceQuery(currentspace, geom))
 
 2378                         if (d.GeomIsSpace(currentspace))
 
 2381                             d.SpaceRemove(currentspace, geom);
 
 2385                             m_log.Info(
"[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" +
 
 2386                                        currentspace + 
" Geom:" + geom);
 
 2391                         IntPtr sGeomIsIn = d.GeomGetSpace(geom);
 
 2392                         if (sGeomIsIn != IntPtr.Zero)
 
 2394                             if (d.GeomIsSpace(sGeomIsIn))
 
 2397                                 d.SpaceRemove(sGeomIsIn, geom);
 
 2401                                 m_log.Info(
"[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" +
 
 2402                                            sGeomIsIn + 
" Geom:" + geom);
 
 2412             int[] iprimspaceArrItem = calculateSpaceArrayItemFromPos(pos);
 
 2413             IntPtr newspace = calculateSpaceForGeom(pos);
 
 2415             if (newspace == IntPtr.Zero)
 
 2417                 newspace = createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]);
 
 2418                 d.HashSpaceSetLevels(newspace, HashspaceLow, HashspaceHigh);
 
 2430         internal IntPtr createprimspace(
int iprimspaceArrItemX, 
int iprimspaceArrItemY)
 
 2433             staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY] = d.HashSpaceCreate(IntPtr.Zero);
 
 2434             d.GeomSetCategoryBits(staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY], (int)
CollisionCategories.Space);
 
 2436             d.SpaceSetSublevel(space, 1);
 
 2437             d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]);
 
 2439             return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY];
 
 2447         internal IntPtr calculateSpaceForGeom(Vector3 pos)
 
 2449             int[] xyspace = calculateSpaceArrayItemFromPos(pos);
 
 2451             return staticPrimspace[xyspace[0], xyspace[1]];
 
 2459         internal int[] calculateSpaceArrayItemFromPos(Vector3 pos)
 
 2461             int[] returnint = 
new int[2];
 
 2463             returnint[0] = (int) (pos.X * spacesPerMeterX);
 
 2465             if (returnint[0] > spaceGridMaxX)
 
 2466                 returnint[0] = spaceGridMaxX;
 
 2467             if (returnint[0] < 0)
 
 2470             returnint[1] = (int)(pos.Y * spacesPerMeterY);
 
 2471             if (returnint[1] > spaceGridMaxY)
 
 2472                 returnint[1] = spaceGridMaxY;
 
 2473             if (returnint[1] < 0)
 
 2494             int iPropertiesNotSupportedDefault = 0;
 
 2499                 m_log.Warn(
"NonMesh");
 
 2508                     || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)
Extrusion.Curve1
 
 2521                     m_log.Warn(
"NonMesh");
 
 2529                 iPropertiesNotSupportedDefault++;
 
 2531             if ((pbs.
PathBegin != 0) || pbs.PathEnd != 0)
 
 2532                 iPropertiesNotSupportedDefault++;
 
 2535                 iPropertiesNotSupportedDefault++; 
 
 2538                 iPropertiesNotSupportedDefault++;
 
 2540             if ((pbs.
PathScaleX != 100) || (pbs.PathScaleY != 100))
 
 2541                 iPropertiesNotSupportedDefault++;
 
 2543             if ((pbs.
PathShearX != 0) || (pbs.PathShearY != 0))
 
 2544                 iPropertiesNotSupportedDefault++;
 
 2547                 iPropertiesNotSupportedDefault++;
 
 2549             if (pbs.
ProfileShape == 
ProfileShape.HalfCircle && pbs.
PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X))
 
 2550                 iPropertiesNotSupportedDefault++;
 
 2553                 iPropertiesNotSupportedDefault++;
 
 2558                 if (pbs.
PathCurve == (byte)Extrusion.Curve1)
 
 2560                     iPropertiesNotSupportedDefault++;
 
 2565                 if (pbs.
PathCurve == (byte)Extrusion.Straight)
 
 2567                     iPropertiesNotSupportedDefault++;
 
 2571                 else if (pbs.
PathCurve == (byte)Extrusion.Curve1)
 
 2573                     iPropertiesNotSupportedDefault++;
 
 2578                 if (pbs.
PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)
Extrusion.Curve2)
 
 2580                     iPropertiesNotSupportedDefault++;
 
 2585                 if (pbs.
PathCurve == (byte)Extrusion.Straight)
 
 2587                     iPropertiesNotSupportedDefault++;
 
 2589                 else if (pbs.
PathCurve == (byte)Extrusion.Curve1)
 
 2591                     iPropertiesNotSupportedDefault++;
 
 2596                 iPropertiesNotSupportedDefault++;
 
 2598             if (iPropertiesNotSupportedDefault == 0)
 
 2601                 m_log.Warn(
"NonMesh");
 
 2606             m_log.Debug(
"Mesh");
 
 2621             if (actor is OdePrim)
 
 2623                 OdePrim taintedprim = ((OdePrim)actor);
 
 2624                 lock (_taintedPrims)
 
 2625                     _taintedPrims.Add(taintedprim);
 
 2627             else if (actor is OdeCharacter)
 
 2629                 OdeCharacter taintedchar = ((OdeCharacter)actor);
 
 2630                 lock (_taintedActors)
 
 2632                     _taintedActors.Add(taintedchar);
 
 2633                     if (taintedchar.bad)
 
 2634                         m_log.ErrorFormat(
"[ODE SCENE]: Added BAD actor {0} to tainted actors", taintedchar.m_uuid);
 
 2644                 if (world == IntPtr.Zero)
 
 2646                     _taintedPrims.Clear();;
 
 2650                 int donechanges = 0;
 
 2651                 if (_taintedPrims.Count > 0)
 
 2654                     m_log.InfoFormat(
"[Ode] start processing pending actor operations");
 
 2655                     int tstart = Util.EnvironmentTickCount();
 
 2657                     d.AllocateODEDataForThread(0);
 
 2659                     lock (_taintedPrims)
 
 2661                         foreach (OdePrim prim 
in _taintedPrims)
 
 2664                                 RemovePrimThreadLocked(prim);
 
 2666                                 prim.ProcessTaints();
 
 2668                             prim.m_collisionscore = 0;
 
 2671                         _taintedPrims.Clear();
 
 2674                     int time = Util.EnvironmentTickCountSubtract(tstart);
 
 2675                     m_log.InfoFormat(
"[Ode] finished {0} operations in {1}ms", donechanges, time);
 
 2677                 m_log.InfoFormat(
"[Ode] {0} prim actors loaded",_prims.Count);
 
 2695             if (!_worldInitialized)
 
 2698             int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0;
 
 2699             int tempTick = 0, tempTick2 = 0;
 
 2701             if (framecount >= 
int.MaxValue)
 
 2708             step_time += timeStep;
 
 2710             float HalfOdeStep = ODE_STEPSIZE * 0.5f;
 
 2711             if (step_time < HalfOdeStep)
 
 2718             lock (m_collisionEventActorsChanges)
 
 2720                 foreach (KeyValuePair<uint, PhysicsActor> kvp 
in m_collisionEventActorsChanges)
 
 2722                     if (kvp.Value == null)
 
 2723                         m_collisionEventActors.Remove(kvp.Key);
 
 2725                         m_collisionEventActors[kvp.Key] = kvp.Value;
 
 2728                 m_collisionEventActorsChanges.Clear();
 
 2731             if (SupportsNINJAJoints)
 
 2733                 DeleteRequestedJoints(); 
 
 2734                 CreateRequestedJoints(); 
 
 2740                 d.AllocateODEDataForThread(~0U);
 
 2742                  while (step_time > HalfOdeStep)
 
 2747                             tempTick = Util.EnvironmentTickCount();
 
 2749                         lock (_taintedActors)
 
 2751                             foreach (OdeCharacter character 
in _taintedActors)
 
 2752                                 character.ProcessTaints();
 
 2754                             _taintedActors.Clear();
 
 2759                             tempTick2 = Util.EnvironmentTickCount();
 
 2760                             m_stats[ODEAvatarTaintMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
 
 2761                             tempTick = tempTick2;
 
 2764                         lock (_taintedPrims)
 
 2766                             foreach (OdePrim prim 
in _taintedPrims)
 
 2771                                     RemovePrimThreadLocked(prim);
 
 2776                                     prim.ProcessTaints();
 
 2779                                 prim.m_collisionscore = 0;
 
 2788                             if (SupportsNINJAJoints)
 
 2789                                 SimulatePendingNINJAJoints();
 
 2791                             _taintedPrims.Clear();
 
 2796                             tempTick2 = Util.EnvironmentTickCount();
 
 2797                             m_stats[ODEPrimTaintMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
 
 2798                             tempTick = tempTick2;
 
 2802                         foreach (OdeCharacter actor 
in _characters)
 
 2803                             actor.Move(defects);
 
 2805                         if (defects.Count != 0)
 
 2807                             foreach (OdeCharacter actor 
in defects)
 
 2810                                     "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2} due to defect found when moving",
 
 2811                                     actor.Name, actor.LocalID, PhysicsSceneName);
 
 2813                                 RemoveCharacter(actor);
 
 2814                                 actor.DestroyOdeStructures();
 
 2822                             tempTick2 = Util.EnvironmentTickCount();
 
 2823                             m_stats[ODEAvatarForcesFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
 
 2824                             tempTick = tempTick2;
 
 2828                         foreach (OdePrim prim 
in _activeprims)
 
 2830                             prim.m_collisionscore = 0;
 
 2831                             prim.Move(timeStep);
 
 2836                             tempTick2 = Util.EnvironmentTickCount();
 
 2837                             m_stats[ODEPrimForcesFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
 
 2838                             tempTick = tempTick2;
 
 2841                         m_rayCastManager.ProcessQueuedRequests();
 
 2845                             tempTick2 = Util.EnvironmentTickCount();
 
 2846                             m_stats[ODERaycastingFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
 
 2847                             tempTick = tempTick2;
 
 2850                         collision_optimized();
 
 2854                             tempTick2 = Util.EnvironmentTickCount();
 
 2855                             m_stats[ODEOtherCollisionFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
 
 2856                             tempTick = tempTick2;
 
 2859                         foreach (
PhysicsActor obj 
in m_collisionEventActors.Values)
 
 2865                                 case ActorTypes.Agent:
 
 2866                                     OdeCharacter cobj = (OdeCharacter)obj;
 
 2867                                     cobj.AddCollisionFrameTime(100);
 
 2868                                     cobj.SendCollisions();
 
 2871                                 case ActorTypes.Prim:
 
 2872                                     OdePrim pobj = (OdePrim)obj;
 
 2873                                     pobj.SendCollisions();
 
 2882                         m_global_contactcount = 0;
 
 2886                             tempTick2 = Util.EnvironmentTickCount();
 
 2887                             m_stats[ODECollisionNotificationFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
 
 2888                             tempTick = tempTick2;
 
 2891                         lock(SimulationLock)
 
 2892                             d.WorldQuickStep(world, ODE_STEPSIZE);
 
 2895                             m_stats[ODENativeStepFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick);
 
 2897                         d.JointGroupEmpty(contactgroup);
 
 2901                         m_log.ErrorFormat(
"[ODE SCENE]: {0}, {1}, {2}", e.Message, e.TargetSite, e);
 
 2904                     step_time -= ODE_STEPSIZE;
 
 2905                     fps += ODE_STEPSIZE;
 
 2909                     tempTick = Util.EnvironmentTickCount();
 
 2911                 foreach (OdeCharacter actor 
in _characters)
 
 2914                         m_log.ErrorFormat(
"[ODE SCENE]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid);
 
 2916                     actor.UpdatePositionAndVelocity(defects);
 
 2919                 if (defects.Count != 0)
 
 2921                     foreach (OdeCharacter actor 
in defects)
 
 2924                             "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2} due to defect found when updating position and velocity",
 
 2925                             actor.Name, actor.LocalID, PhysicsSceneName);
 
 2927                         RemoveCharacter(actor);
 
 2928                         actor.DestroyOdeStructures();
 
 2936                     tempTick2 = Util.EnvironmentTickCount();
 
 2937                     m_stats[ODEAvatarUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
 
 2938                     tempTick = tempTick2;
 
 2943                 foreach (OdePrim prim 
in _activeprims)
 
 2945                     if (prim.
IsPhysical && (d.BodyIsEnabled(prim.
Body) || !prim._zeroFlag))
 
 2947                         prim.UpdatePositionAndVelocity();
 
 2949                         if (SupportsNINJAJoints)
 
 2950                             SimulateActorPendingJoints(prim);
 
 2955                     m_stats[ODEPrimUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick);
 
 2962                 if (physics_logging && (physics_logging_interval > 0) && (framecount % physics_logging_interval == 0))
 
 2964                     string fname = 
"state-" + world.ToString() + 
".DIF"; 
 
 2965                     string prefix = 
"world" + world.ToString(); 
 
 2967                     if (physics_logging_append_existing_logfile)
 
 2969                         string header = 
"-------------- START OF PHYSICS FRAME " + framecount.ToString() + 
" --------------";
 
 2970                         TextWriter fwriter = File.AppendText(fname);
 
 2971                         fwriter.WriteLine(header);
 
 2975                     d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix);
 
 2978                 latertickcount = Util.EnvironmentTickCountSubtract(tickCountFrameRun);
 
 2985                 if (latertickcount < 100)
 
 2987                     m_timeDilation = 1.0f;
 
 2991                     m_timeDilation = 100f / latertickcount;
 
 2995                 tickCountFrameRun = Util.EnvironmentTickCount();
 
 2998                     m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCountSubtract(startFrameTick);
 
 3001             fps *= 1.0f/timeStep;
 
 3011         private void SimulatePendingNINJAJoints()
 
 3017             if (pendingJoints.Count > 0)
 
 3019                 List<PhysicsJoint> successfullyProcessedPendingJoints = 
new List<PhysicsJoint>();
 
 3024                     string[] jointParams = joint.RawParams.Split(
" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries);
 
 3025                     List<IntPtr> jointBodies = 
new List<IntPtr>();
 
 3026                     bool allJointBodiesAreReady = 
true;
 
 3027                     foreach (
string jointParam 
in jointParams)
 
 3029                         if (jointParam == 
"NULL")
 
 3032                             jointBodies.Add(IntPtr.Zero);
 
 3037                             bool foundPrim = 
false;
 
 3040                                 foreach (OdePrim prim 
in _prims) 
 
 3042                                     if (prim.SOPName == jointParam)
 
 3045                                         if (prim.IsPhysical && prim.Body != IntPtr.Zero)
 
 3047                                             jointBodies.Add(prim.Body);
 
 3053                                             DoJointErrorMessage(joint, 
"prim name " + jointParam +
 
 3054                                                 " exists but is not (yet) physical; deferring joint creation. " +
 
 3055                                                 "IsPhysical property is " + prim.IsPhysical +
 
 3056                                                 " and body is " + prim.Body);
 
 3069                                 allJointBodiesAreReady = 
false;
 
 3075                     if (allJointBodiesAreReady)
 
 3078                         if (jointBodies[0] == jointBodies[1])
 
 3080                             DoJointErrorMessage(joint, 
"ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + 
". raw parms: " + joint.
RawParams);
 
 3086                                 case PhysicsJointType.Ball:
 
 3090                                         odeJoint = d.JointCreateBall(world, IntPtr.Zero);
 
 3092                                         d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]);
 
 3094                                         d.JointSetBallAnchor(odeJoint,
 
 3104                                         if (joint is OdePhysicsJoint)
 
 3106                                             ((OdePhysicsJoint)joint).jointID = odeJoint;
 
 3110                                             DoJointErrorMessage(joint, 
"WARNING: non-ode joint in ODE!");
 
 3114                                 case PhysicsJointType.Hinge:
 
 3118                                         odeJoint = d.JointCreateHinge(world, IntPtr.Zero);
 
 3120                                         d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]);
 
 3122                                         d.JointSetHingeAnchor(odeJoint,
 
 3142                                         Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation);
 
 3155                                         Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame);
 
 3158                                         d.JointSetHingeAxis(odeJoint,
 
 3163                                         if (joint is OdePhysicsJoint)
 
 3165                                             ((OdePhysicsJoint)joint).jointID = odeJoint;
 
 3169                                             DoJointErrorMessage(joint, 
"WARNING: non-ode joint in ODE!");
 
 3174                             successfullyProcessedPendingJoints.Add(joint);
 
 3179                         DoJointErrorMessage(joint, 
"joint could not yet be created; still pending");
 
 3183                 foreach (
PhysicsJoint successfullyProcessedJoint 
in successfullyProcessedPendingJoints)
 
 3187                     InternalRemovePendingJoint(successfullyProcessedJoint);
 
 3189                     InternalAddActiveJoint(successfullyProcessedJoint);
 
 3202         private void SimulateActorPendingJoints(OdePrim actor)
 
 3209             if (actor.SOPName != null &&
 
 3210                 joints_connecting_actor.ContainsKey(actor.SOPName) &&
 
 3211                 joints_connecting_actor[actor.SOPName] != null &&
 
 3212                 joints_connecting_actor[actor.SOPName].Count > 0)
 
 3214                 foreach (
PhysicsJoint affectedJoint 
in joints_connecting_actor[actor.SOPName])
 
 3218                         DoJointMoved(affectedJoint);
 
 3222                         DoJointErrorMessage(affectedJoint, 
"a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.
ObjectNameInScene + 
" parms:" + affectedJoint.
RawParams);
 
 3232         public override bool IsThreaded
 
 3235             get { 
return false; }
 
 3240             if (m_worldOffset != Vector3.Zero && m_parentScene != null)
 
 3244                     ((OdeScene)m_parentScene).SetTerrain(heightMap, m_worldOffset);
 
 3249                 SetTerrain(heightMap, m_worldOffset);
 
 3253         private void SetTerrain(
float[] heightMap, Vector3 pOffset)
 
 3255             int startTime = Util.EnvironmentTickCount();
 
 3256             m_log.DebugFormat(
"[ODE SCENE]: Setting terrain for {0} with offset {1}", PhysicsSceneName, pOffset);
 
 3262             uint regionsizeX = m_regionWidth;
 
 3263             uint regionsizeY = m_regionHeight;
 
 3266             uint heightmapWidth = regionsizeY + 2;
 
 3267             uint heightmapHeight = regionsizeX + 2;
 
 3269             uint heightmapWidthSamples = heightmapWidth + 1;
 
 3270             uint heightmapHeightSamples = heightmapHeight + 1;
 
 3272             _heightmap = 
new float[heightmapWidthSamples * heightmapHeightSamples];
 
 3274             const float scale = 1.0f;
 
 3275             const float offset = 0.0f;
 
 3276             const float thickness = 10f;
 
 3280             float hfmin = float.MaxValue;
 
 3281             float hfmax = float.MinValue;
 
 3286             uint maxXX = regionsizeX - 1;
 
 3287             uint maxYY = regionsizeY - 1;
 
 3295             for (uint x = 0; x < heightmapWidthSamples; x++)
 
 3297                 if (x > 1 && xx < maxXX)
 
 3300                 for (uint y = 0; y < heightmapHeightSamples; y++)
 
 3302                     if (y > 1 && y < maxYY)
 
 3305                     val = heightMap[yy + xx];
 
 3308                     _heightmap[xt + y] = val;
 
 3315                 xt += heightmapHeightSamples;
 
 3320                 d.AllocateODEDataForThread(~0U);
 
 3322                 IntPtr GroundGeom = IntPtr.Zero;
 
 3323                 if (RegionTerrain.TryGetValue(pOffset, out GroundGeom))
 
 3325                     RegionTerrain.Remove(pOffset);
 
 3326                     if (GroundGeom != IntPtr.Zero)
 
 3328                         if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
 
 3330                             TerrainHeightFieldHeights.Remove(GroundGeom);
 
 3332                         d.SpaceRemove(space, GroundGeom);
 
 3333                         d.GeomDestroy(GroundGeom);
 
 3337                 IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
 
 3338                 d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0,
 
 3339                             heightmapWidth, heightmapHeight,
 
 3340                             (int)heightmapWidthSamples,
 
 3341                             (
int)heightmapHeightSamples,
 
 3342                             scale, offset, thickness, wrap);
 
 3344                 d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
 
 3345                 GroundGeom = d.CreateHeightfield(space, HeightmapData, 1);
 
 3346                 if (GroundGeom != IntPtr.Zero)
 
 3352                 geom_name_map[GroundGeom] = 
"Terrain";
 
 3354                 d.Matrix3 R = 
new d.Matrix3();
 
 3356                 Quaternion q1 = Quaternion.CreateFromAxisAngle(
new Vector3(1, 0, 0), 1.5707f);
 
 3357                 Quaternion q2 = Quaternion.CreateFromAxisAngle(
new Vector3(0, 1, 0), 1.5707f);
 
 3362                 q1.GetAxisAngle(out v3, out angle);
 
 3364                 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
 
 3365                 d.GeomSetRotation(GroundGeom, ref R);
 
 3366                 d.GeomSetPosition(GroundGeom, pOffset.X + regionsizeX * 0.5f, pOffset.Y + regionsizeY * 0.5f, 0.0f);
 
 3367                 IntPtr testGround = IntPtr.Zero;
 
 3368                 if (RegionTerrain.TryGetValue(pOffset, out testGround))
 
 3370                     RegionTerrain.Remove(pOffset);
 
 3372                 RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
 
 3373                 TerrainHeightFieldHeights.Add(GroundGeom,_heightmap);
 
 3377                 "[ODE SCENE]: Setting terrain for {0} took {1}ms", PhysicsSceneName, Util.EnvironmentTickCountSubtract(startTime));
 
 3384         internal float GetWaterLevel()
 
 3391             return m_suportCombine;
 
 3396             waterlevel = baseheight;
 
 3399         [HandleProcessCorruptedStateExceptions]
 
 3402             lock(SimulationLock)
 
 3405                 if(world == IntPtr.Zero)
 
 3408                 _worldInitialized = 
false;
 
 3410                 d.AllocateODEDataForThread(~0U);
 
 3412                 if (m_rayCastManager != null)
 
 3414                     m_rayCastManager.Dispose();
 
 3415                     m_rayCastManager = null;
 
 3420                     foreach (OdePrim prm 
in _prims)
 
 3430                 IntPtr GroundGeom = IntPtr.Zero;
 
 3431                 if (RegionTerrain.TryGetValue(m_worldOffset, out GroundGeom))
 
 3433                     RegionTerrain.Remove(m_worldOffset);
 
 3434                     if (GroundGeom != IntPtr.Zero)
 
 3436                         if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
 
 3437                             TerrainHeightFieldHeights.Remove(GroundGeom);
 
 3438                         d.GeomDestroy(GroundGeom);
 
 3444                     d.WorldDestroy(world);
 
 3445                     world = IntPtr.Zero;
 
 3447                 catch (AccessViolationException e)
 
 3449                     m_log.ErrorFormat(
"[ODE SCENE]: exception {0}", e.Message);
 
 3456             Dictionary<uint, float> topColliders;
 
 3460                 List<OdePrim> orderedPrims = 
new List<OdePrim>(_prims);
 
 3461                 orderedPrims.OrderByDescending(p => p.CollisionScore);
 
 3462                 topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore);
 
 3464                 foreach (OdePrim p 
in _prims)
 
 3465                     p.CollisionScore = 0;
 
 3468             return topColliders;
 
 3478             if (retMethod != null)
 
 3480                 m_rayCastManager.QueueRequest(position, direction, length, retMethod);
 
 3486             if (retMethod != null)
 
 3488                 m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod);
 
 3492         public override List<ContactResult> 
RaycastWorld(Vector3 position, Vector3 direction, 
float length, 
int Count)
 
 3495             RayCallback retMethod = delegate(List<ContactResult> results)
 
 3498                 results.CopyTo(ourResults, 0);
 
 3501             m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod);
 
 3502             while (ourResults == null && waitTime < 1000)
 
 3507             if (ourResults == null)
 
 3508                 return new List<ContactResult> ();
 
 3509             return new List<ContactResult>(ourResults);
 
 3517             Dictionary<string, float> returnStats;
 
 3521                 returnStats = 
new Dictionary<string, float>(m_stats);
 
 3525                 returnStats[ODETotalAvatarsStatName] = _characters.Count * 3;
 
 3526                 returnStats[ODETotalPrimsStatName] = _prims.Count * 3;
 
 3527                 returnStats[ODEActivePrimsStatName] = _activeprims.Count * 3;
 
 3529                 InitializeExtraStats();
 
 3532             returnStats[ODEOtherCollisionFrameMsStatName]
 
 3533                 = returnStats[ODEOtherCollisionFrameMsStatName]
 
 3534                     - returnStats[ODENativeSpaceCollisionFrameMsStatName]
 
 3535                     - returnStats[ODENativeGeomCollisionFrameMsStatName];
 
 3540         private void InitializeExtraStats()
 
 3542             m_stats[ODETotalFrameMsStatName] = 0;
 
 3543             m_stats[ODEAvatarTaintMsStatName] = 0;
 
 3544             m_stats[ODEPrimTaintMsStatName] = 0;
 
 3545             m_stats[ODEAvatarForcesFrameMsStatName] = 0;
 
 3546             m_stats[ODEPrimForcesFrameMsStatName] = 0;
 
 3547             m_stats[ODERaycastingFrameMsStatName] = 0;
 
 3548             m_stats[ODENativeStepFrameMsStatName] = 0;
 
 3549             m_stats[ODENativeSpaceCollisionFrameMsStatName] = 0;
 
 3550             m_stats[ODENativeGeomCollisionFrameMsStatName] = 0;
 
 3551             m_stats[ODEOtherCollisionFrameMsStatName] = 0;
 
 3552             m_stats[ODECollisionNotificationFrameMsStatName] = 0;
 
 3553             m_stats[ODEAvatarContactsStatsName] = 0;
 
 3554             m_stats[ODEPrimContactsStatName] = 0;
 
 3555             m_stats[ODEAvatarUpdateFrameMsStatName] = 0;
 
 3556             m_stats[ODEPrimUpdateFrameMsStatName] = 0;
 
override bool SupportsCombining()
override bool IsPhysical
Is this prim subject to physics? Even if not, it's still solid for collision purposes. 
override PhysicsJoint RequestJointCreation(string objectNameInScene, PhysicsJointType jointType, Vector3 position, Quaternion rotation, string parms, List< string > bodyNames, string trackedBodyName, Quaternion localRotation)
Add a request for joint creation. 
override void DeleteTerrain()
override void ProcessPreSimulation()
uint RegionSizeX
X dimension of the region. 
override List< ContactResult > RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
uint RegionSizeY
X dimension of the region. 
override Vector3 GetJointAxis(PhysicsJoint joint)
Get joint axis. 
delegate void RayCallback(List< ContactResult > list)
override bool SupportsRayCast()
True if the physics plugin supports raycasting against the physics scene 
override float Simulate(float timeStep)
This is our main simulate loop 
RegionSettings RegionSettings
override void RequestJointDeletion(string ObjectNameInScene)
override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
Add an avatar 
override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
override void DumpJointInfo()
override void AddPhysicsActorTaint(PhysicsActor actor)
Called after our prim properties are set Scale, position etc. 
Processes raycast requests as ODE is in a state to be able to do them. This ensures that it's thread ...
Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ours...
override void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
Queue a raycast against the physics scene. The provided callback method will be called when the rayca...
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion rotation
string SOPName
This is being used by ODE joint code. 
override Vector3 GetJointAnchor(PhysicsJoint joint)
ProfileShape ProfileShape
override Dictionary< uint, float > GetTopColliders()
override void RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod)
OdeScene(Scene pscene, IConfigSource psourceconfig, string pname)
virtual bool IsInPhysicsEngine
override void SetWaterLevel(float baseheight)
override void RemoveAllJointsConnectedToActorThreadLocked(PhysicsActor actor)
IntPtr prim_geom
The prim geometry, used for collision detection. 
override void SetTerrain(float[] heightMap)
Material
Material type for a primitive 
override void GetResults()
uint RegionSizeZ
Z dimension of the region. 
virtual RegionInfo RegionInfo
d.TriCallback triCallback
override void RemoveAvatar(PhysicsActor actor)
Remove an avatar. 
IntPtr[,] staticPrimspace
d.TriArrayCallback triArrayCallback
override void RemovePrim(PhysicsActor prim)
Remove a prim. 
override Dictionary< string, float > GetStats()
Get statistics about this scene.