public override void Dispose()
        {
            lock (OdeLock)
            {

                if (world == IntPtr.Zero)
                    return;

                d.AllocateODEDataForThread(~0U);

                if (m_meshWorker != null)
                    m_meshWorker.Stop();

                if (m_rayCastManager != null)
                {
                    m_rayCastManager.Dispose();
                    m_rayCastManager = null;
                }

                lock (_prims)
                {
                    ChangesQueue.Clear();
                    foreach (OdePrim prm in _prims)
                    {
                        prm.DoAChange(changes.Remove, null);
                        _collisionEventPrim.Remove(prm);
                    }
                    _prims.Clear();
                }

                OdeCharacter[] chtorem;
                lock (_characters)
                {
                    chtorem = new OdeCharacter[_characters.Count];
                    _characters.CopyTo(chtorem);
                }

                ChangesQueue.Clear();
                foreach (OdeCharacter ch in chtorem)
                    ch.DoAChange(changes.Remove, null);


                foreach (IntPtr GroundGeom in RegionTerrain.Values)
                {
                    if (GroundGeom != IntPtr.Zero)
                        d.GeomDestroy(GroundGeom);
                }

                RegionTerrain.Clear();

                if (TerrainHeightFieldHeightsHandlers.Count > 0)
                {
                    foreach (GCHandle gch in TerrainHeightFieldHeightsHandlers.Values)
                    {
                        if (gch.IsAllocated)
                            gch.Free();
                    }
                }

                TerrainHeightFieldHeightsHandlers.Clear();
                TerrainHeightFieldHeights.Clear();

                if (ContactgeomsArray != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(ContactgeomsArray);
                    ContactgeomsArray = IntPtr.Zero;
                }
                if (GlobalContactsArray != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(GlobalContactsArray);
                    GlobalContactsArray = IntPtr.Zero;
                }

                d.WorldDestroy(world);
                world = IntPtr.Zero;
                //d.CloseODE();
            }
        }
 public void BadCharacter(OdeCharacter chr)
 {
     lock (_badCharacter)
     {
         if (!_badCharacter.Contains(chr))
             _badCharacter.Add(chr);
     }
 }
 public void AddCharacter(OdeCharacter chr)
 {
     lock (_characters)
     {
         if (!_characters.Contains(chr))
         {
             _characters.Add(chr);
             if (chr.bad)
                 m_log.DebugFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid);
         }
     }
 }
 public void RemoveCharacter(OdeCharacter chr)
 {
     lock (_characters)
     {
         if (_characters.Contains(chr))
         {
             _characters.Remove(chr);
         }
     }
 }
 public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float feetOffset, bool isFlying)
 {
      OdeCharacter newAv = new OdeCharacter(localID, avName, this, position,
         size, feetOffset, avDensity, avMovementDivisorWalk, avMovementDivisorRun);
     newAv.Flying = isFlying;
     newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset;
     
     return newAv;
 }