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.