change fps and dilation (still something not that usefull). make collisions a bit less explosive.., do changes on own time limited loop and not on simulation loop, ...

avinationmerge
UbitUmarov 2015-10-13 23:01:54 +01:00
parent f360ddd28e
commit 2e2c1a1fcd
1 changed files with 78 additions and 87 deletions

View File

@ -178,7 +178,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
// const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; // const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce;
const d.ContactFlags comumContactFlags = d.ContactFlags.Bounce | d.ContactFlags.Approx1 | d.ContactFlags.Slip1 | d.ContactFlags.Slip2; const d.ContactFlags comumContactFlags = d.ContactFlags.Bounce | d.ContactFlags.Approx1 | d.ContactFlags.Slip1 | d.ContactFlags.Slip2;
const float comumContactERP = 0.7f; const float comumContactERP = 0.75f;
const float comumContactCFM = 0.0001f; const float comumContactCFM = 0.0001f;
const float comumContactSLIP = 0f; const float comumContactSLIP = 0f;
@ -211,16 +211,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde
private float waterlevel = 0f; private float waterlevel = 0f;
private int framecount = 0; private int framecount = 0;
// private int m_meshExpireCntr;
private float avDensity = 80f; private float avDensity = 80f;
private float avMovementDivisorWalk = 1.3f; private float avMovementDivisorWalk = 1.3f;
private float avMovementDivisorRun = 0.8f; private float avMovementDivisorRun = 0.8f;
private float minimumGroundFlightOffset = 3f; private float minimumGroundFlightOffset = 3f;
public float maximumMassObject = 10000.01f; public float maximumMassObject = 10000.01f;
public float geomDefaultDensity = 10.0f;
public float geomDefaultDensity = 10.000006836f;
public float bodyPIDD = 35f; public float bodyPIDD = 35f;
public float bodyPIDG = 25; public float bodyPIDG = 25;
@ -243,17 +240,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde
private List<PhysicsActor> _collisionEventPrimRemove = new List<PhysicsActor>(); private List<PhysicsActor> _collisionEventPrimRemove = new List<PhysicsActor>();
private HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>(); private HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>();
// public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>();
public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>(); public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>();
private float contactsurfacelayer = 0.001f; private float contactsurfacelayer = 0.002f;
private int contactsPerCollision = 80; private int contactsPerCollision = 80;
internal IntPtr ContactgeomsArray = IntPtr.Zero; internal IntPtr ContactgeomsArray = IntPtr.Zero;
private IntPtr GlobalContactsArray = IntPtr.Zero; private IntPtr GlobalContactsArray = IntPtr.Zero;
private d.Contact SharedTmpcontact = new d.Contact(); private d.Contact SharedTmpcontact = new d.Contact();
const int maxContactsbeforedeath = 4000; const int maxContactsbeforedeath = 6000;
private volatile int m_global_contactcount = 0; private volatile int m_global_contactcount = 0;
private IntPtr contactgroup; private IntPtr contactgroup;
@ -271,7 +267,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
public IntPtr world; public IntPtr world;
// split the spaces acording to contents type // split the spaces acording to contents type
// ActiveSpace contains characters and active prims // ActiveSpace contains characters and active prims
// StaticSpace contains land and other that is mostly static in enviroment // StaticSpace contains land and other that is mostly static in enviroment
@ -347,14 +342,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde
(float)m_frameWorkScene.RegionInfo.RegionSettings.WaterHeight); (float)m_frameWorkScene.RegionInfo.RegionSettings.WaterHeight);
} }
// core hack this just means all modules where loaded
// so now we can look for dependencies
public void RegionLoaded() public void RegionLoaded()
{ {
mesher = m_frameWorkScene.RequestModuleInterface<IMesher>(); mesher = m_frameWorkScene.RequestModuleInterface<IMesher>();
if (mesher == null) if (mesher == null)
{ {
m_log.WarnFormat("[ubOde] No mesher. module disabled"); m_log.ErrorFormat("[ubOde] No mesher. module disabled");
return; return;
} }
@ -453,7 +446,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
} }
// checkThread(); // checkThread();
// Defaults // Defaults
@ -517,7 +510,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
odetimestepMS = (int)(1000.0f * ODE_STEPSIZE + 0.5f); odetimestepMS = (int)(1000.0f * ODE_STEPSIZE + 0.5f);
ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf);
GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf); GlobalContactsArray = Marshal.AllocHGlobal((maxContactsbeforedeath + 100) * d.Contact.unmanagedSizeOf);
SharedTmpcontact.geom.g1 = IntPtr.Zero; SharedTmpcontact.geom.g1 = IntPtr.Zero;
SharedTmpcontact.geom.g2 = IntPtr.Zero; SharedTmpcontact.geom.g2 = IntPtr.Zero;
@ -1155,49 +1148,43 @@ namespace OpenSim.Region.PhysicsModule.ubOde
aprim.CollisionScore = 0; aprim.CollisionScore = 0;
aprim.IsColliding = false; aprim.IsColliding = false;
} }
}
// collide active prims with static enviroment
lock (_activegroups)
{
try try
{ {
foreach (OdePrim prm in _activegroups) foreach (OdePrim aprim in _activeprims)
{ {
if (!prm.m_outbounds) if(d.BodyIsEnabled(aprim.Body))
{ {
if (d.BodyIsEnabled(prm.Body)) d.SpaceCollide2(StaticSpace, aprim.collide_geom, IntPtr.Zero, nearCallback);
{ d.SpaceCollide2(GroundSpace, aprim.collide_geom, IntPtr.Zero, nearCallback);
d.SpaceCollide2(StaticSpace, prm.collide_geom, IntPtr.Zero, nearCallback);
d.SpaceCollide2(GroundSpace, prm.collide_geom, IntPtr.Zero, nearCallback);
}
} }
} }
} }
catch (AccessViolationException) catch (Exception e)
{ {
m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space"); m_log.Warn("[PHYSICS]: Unable to collide Active to Static: " + e.Message);
} }
} }
// colide active amoung them // colide active amoung them
try try
{ {
d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback);
} }
catch (AccessViolationException) catch (Exception e)
{ {
m_log.Warn("[PHYSICS]: Unable to collide Active with Characters space"); m_log.Warn("[PHYSICS]: Unable to collide in Active: " + e.Message);
} }
// and with chars // and with chars
try try
{ {
d.SpaceCollide2(CharsSpace,ActiveSpace, IntPtr.Zero, nearCallback); d.SpaceCollide2(CharsSpace,ActiveSpace, IntPtr.Zero, nearCallback);
} }
catch (AccessViolationException) catch (Exception e)
{ {
m_log.Warn("[PHYSICS]: Unable to collide in Active space"); m_log.Warn("[PHYSICS]: Unable to collide Active to Character: " + e.Message);
} }
// _perloopContact.Clear();
} }
#endregion #endregion
@ -1583,11 +1570,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde
/// </summary> /// </summary>
/// <param name="timeStep"></param> /// <param name="timeStep"></param>
/// <returns></returns> /// <returns></returns>
public override float Simulate(float timeStep) public override float Simulate(float reqTimeStep)
{ {
DateTime now = DateTime.UtcNow; DateTime now = DateTime.UtcNow;
TimeSpan timedif = now - m_lastframe; TimeSpan timedif = now - m_lastframe;
timeStep = (float)timedif.TotalSeconds; float timeStep = (float)timedif.TotalSeconds;
m_lastframe = now; m_lastframe = now;
// acumulate time so we can reduce error // acumulate time so we can reduce error
@ -1601,16 +1588,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde
framecount++; framecount++;
// int curphysiteractions;
// if in trouble reduce step resolution
// if (step_time >= m_SkipFramesAtms)
// curphysiteractions = m_physicsiterations / 2;
// else
// curphysiteractions = m_physicsiterations;
// checkThread(); // checkThread();
int nodeframes = 0; int nodeframes = 0;
float fps = 0;
lock (SimulationLock) lock (SimulationLock)
lock(OdeLock) lock(OdeLock)
@ -1627,8 +1607,36 @@ namespace OpenSim.Region.PhysicsModule.ubOde
int loopstartMS = Util.EnvironmentTickCount(); int loopstartMS = Util.EnvironmentTickCount();
int looptimeMS = 0; int looptimeMS = 0;
int changestimeMS = 0;
int maxChangestime = (int)(reqTimeStep * 500f); // half the time
int maxLoopTime = (int)(reqTimeStep * 1200f); // 1.2 the time
if (ChangesQueue.Count > 0)
{
while (ChangesQueue.Dequeue(out item))
{
if (item.actor != null)
{
try
{
if (item.actor is OdeCharacter)
((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
RemovePrimThreadLocked((OdePrim)item.actor);
}
catch
{
m_log.WarnFormat("[PHYSICS]: doChange failed for a actor {0} {1}",
item.actor.Name, item.what.ToString());
}
}
changestimeMS = Util.EnvironmentTickCountSubtract(loopstartMS);
if (changestimeMS > maxChangestime)
break;
}
}
// do simulation taking at most 150ms total time including changes
while (step_time > HalfOdeStep) while (step_time > HalfOdeStep)
{ {
try try
@ -1636,32 +1644,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
// clear pointer/counter to contacts to pass into joints // clear pointer/counter to contacts to pass into joints
m_global_contactcount = 0; m_global_contactcount = 0;
if (ChangesQueue.Count > 0)
{
int changestartMS = Util.EnvironmentTickCount();
int ttmp;
while (ChangesQueue.Dequeue(out item))
{
if (item.actor != null)
{
try
{
if (item.actor is OdeCharacter)
((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
RemovePrimThreadLocked((OdePrim)item.actor);
}
catch
{
m_log.WarnFormat("[PHYSICS]: doChange failed for a actor {0} {1}",
item.actor.Name, item.what.ToString());
}
}
ttmp = Util.EnvironmentTickCountSubtract(changestartMS);
if (ttmp > 20)
break;
}
}
// Move characters // Move characters
lock (_characters) lock (_characters)
@ -1727,7 +1709,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
// do a ode simulation step // do a ode simulation step
d.WorldQuickStep(world, ODE_STEPSIZE); d.WorldQuickStep(world, ODE_STEPSIZE);
// d.WorldStep(world, ODE_STEPSIZE);
d.JointGroupEmpty(contactgroup); d.JointGroupEmpty(contactgroup);
// update managed ideia of physical data and do updates to core // update managed ideia of physical data and do updates to core
@ -1770,7 +1751,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
nodeframes++; nodeframes++;
looptimeMS = Util.EnvironmentTickCountSubtract(loopstartMS); looptimeMS = Util.EnvironmentTickCountSubtract(loopstartMS);
if (looptimeMS > 100) if (looptimeMS > maxLoopTime)
break; break;
} }
@ -1795,7 +1776,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
m_lastMeshExpire = now; m_lastMeshExpire = now;
} }
// information block running in debug only // information block for in debug breakpoint only
/* /*
int ntopactivegeoms = d.SpaceGetNumGeoms(ActiveSpace); int ntopactivegeoms = d.SpaceGetNumGeoms(ActiveSpace);
int ntopstaticgeoms = d.SpaceGetNumGeoms(StaticSpace); int ntopstaticgeoms = d.SpaceGetNumGeoms(StaticSpace);
@ -1857,21 +1838,26 @@ namespace OpenSim.Region.PhysicsModule.ubOde
d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix);
} }
// think time dilation as to do with dinamic step size that we dont' have fps = (float)nodeframes * ODE_STEPSIZE / reqTimeStep;
// even so tell something to world
if (looptimeMS < 100) // we did the requested loops if(step_time < HalfOdeStep)
m_timeDilation = 1.0f; m_timeDilation = 1.0f;
else if (step_time > 0) else if (step_time > m_SkipFramesAtms)
{ {
m_timeDilation = timeStep / step_time; // if we lag too much skip frames
if (m_timeDilation > 1) m_timeDilation = 0.0f;
m_timeDilation = 1; step_time = 0;
if (step_time > m_SkipFramesAtms)
step_time = 0;
m_lastframe = DateTime.UtcNow; // skip also the time lost m_lastframe = DateTime.UtcNow; // skip also the time lost
} }
else
{
m_timeDilation = ODE_STEPSIZE / step_time;
if (m_timeDilation > 1)
m_timeDilation = 1;
}
} }
return (float)nodeframes * ODE_STEPSIZE / timeStep;
return fps;
} }
/// <summary> /// <summary>
@ -2442,12 +2428,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde
public override void Dispose() public override void Dispose()
{ {
if (m_rayCastManager == null) // if this is null we already did dispose
return;
lock (OdeLock) lock (OdeLock)
{ {
if (world == IntPtr.Zero)
return;
if (m_meshWorker != null) if (m_meshWorker != null)
m_meshWorker.Stop(); m_meshWorker.Stop();
if (m_rayCastManager != null) if (m_rayCastManager != null)
{ {
@ -2484,7 +2471,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
d.GeomDestroy(GroundGeom); d.GeomDestroy(GroundGeom);
} }
RegionTerrain.Clear(); RegionTerrain.Clear();
if (TerrainHeightFieldHeightsHandlers.Count > 0) if (TerrainHeightFieldHeightsHandlers.Count > 0)
@ -2500,10 +2486,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde
TerrainHeightFieldHeights.Clear(); TerrainHeightFieldHeights.Clear();
if (ContactgeomsArray != IntPtr.Zero) if (ContactgeomsArray != IntPtr.Zero)
{
Marshal.FreeHGlobal(ContactgeomsArray); Marshal.FreeHGlobal(ContactgeomsArray);
ContactgeomsArray = IntPtr.Zero;
}
if (GlobalContactsArray != IntPtr.Zero) if (GlobalContactsArray != IntPtr.Zero)
{
Marshal.FreeHGlobal(GlobalContactsArray); Marshal.FreeHGlobal(GlobalContactsArray);
GlobalContactsArray = IntPtr.Zero;
}
d.WorldDestroy(world); d.WorldDestroy(world);
world = IntPtr.Zero; world = IntPtr.Zero;