reduce useless waste of cpu. Make character collision events be done similiar to parts. Let same thread do it all ( like in parts ) ( to change this some structs copies must be added)

avinationmerge
UbitUmarov 2012-05-19 16:35:48 +01:00
parent 2c498baf58
commit 10889c86d9
4 changed files with 148 additions and 126 deletions

View File

@ -4098,6 +4098,7 @@ namespace OpenSim.Region.Framework.Scenes
private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata) private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
{ {
/*
lock(m_collisionEventLock) lock(m_collisionEventLock)
{ {
if (m_collisionEventFlag) if (m_collisionEventFlag)
@ -4107,6 +4108,7 @@ namespace OpenSim.Region.Framework.Scenes
Util.FireAndForget(delegate(object x) Util.FireAndForget(delegate(object x)
{ {
*/
try try
{ {
List<uint> thisHitColliders = new List<uint>(); List<uint> thisHitColliders = new List<uint>();
@ -4286,7 +4288,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_collisionEventFlag = false; m_collisionEventFlag = false;
} }
}); // });
} }
private void TeleportFlagsDebug() { private void TeleportFlagsDebug() {

View File

@ -128,9 +128,10 @@ namespace OpenSim.Region.Physics.OdePlugin
public d.Mass ShellMass; public d.Mass ShellMass;
// public bool collidelock = false; // public bool collidelock = false;
private bool m_haseventsubscription = false;
public int m_eventsubscription = 0; public int m_eventsubscription = 0;
private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); private int m_cureventsubscription = 0;
private CollisionEventUpdate CollisionEventsThisFrame = null;
private bool SentEmptyCollisionsEvent;
// unique UUID of this character object // unique UUID of this character object
public UUID m_uuid; public UUID m_uuid;
@ -1120,47 +1121,72 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void SubscribeEvents(int ms) public override void SubscribeEvents(int ms)
{ {
m_requestedUpdateFrequency = ms;
m_eventsubscription = ms; m_eventsubscription = ms;
_parent_scene.AddCollisionEventReporting(this); m_cureventsubscription = 0;
m_haseventsubscription = true; if (CollisionEventsThisFrame == null)
CollisionEventsThisFrame = new CollisionEventUpdate();
SentEmptyCollisionsEvent = false;
} }
public override void UnSubscribeEvents() public override void UnSubscribeEvents()
{ {
m_haseventsubscription = false; if (CollisionEventsThisFrame != null)
_parent_scene.RemoveCollisionEventReporting(this); {
m_requestedUpdateFrequency = 0; CollisionEventsThisFrame.Clear();
CollisionEventsThisFrame = null;
}
m_eventsubscription = 0; m_eventsubscription = 0;
} }
public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) public void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
{ {
if (m_haseventsubscription) if (CollisionEventsThisFrame == null)
{ CollisionEventsThisFrame = new CollisionEventUpdate();
// m_log.DebugFormat(
// "[PHYSICS]: Adding collision event for {0}, collidedWith {1}, contact {2}", "", CollidedWith, contact);
CollisionEventsThisFrame.AddCollider(CollidedWith, contact); CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
} }
}
public void SendCollisions() public void SendCollisions()
{ {
if (m_haseventsubscription && m_eventsubscription > m_requestedUpdateFrequency) if (CollisionEventsThisFrame == null)
{ return;
if (CollisionEventsThisFrame != null)
if (m_cureventsubscription < m_eventsubscription)
return;
m_cureventsubscription = 0;
int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count;
if (!SentEmptyCollisionsEvent || ncolisions > 0)
{ {
base.SendCollisionUpdate(CollisionEventsThisFrame); base.SendCollisionUpdate(CollisionEventsThisFrame);
if (ncolisions == 0)
{
SentEmptyCollisionsEvent = true;
_parent_scene.RemoveCollisionEventReporting(this);
} }
CollisionEventsThisFrame = new CollisionEventUpdate(); else
m_eventsubscription = 0; {
SentEmptyCollisionsEvent = false;
CollisionEventsThisFrame.Clear();
} }
} }
}
internal void AddCollisionFrameTime(int t)
{
// protect it from overflow crashing
if (m_cureventsubscription + t >= int.MaxValue)
m_cureventsubscription = 0;
m_cureventsubscription += t;
}
public override bool SubscribedEvents() public override bool SubscribedEvents()
{ {
return m_haseventsubscription; if (m_eventsubscription > 0)
return true;
return false;
} }
private void changePhysicsStatus(bool NewStatus) private void changePhysicsStatus(bool NewStatus)
@ -1466,14 +1492,5 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
_parent_scene.AddChange((PhysicsActor)this, what, arg); _parent_scene.AddChange((PhysicsActor)this, what, arg);
} }
internal void AddCollisionFrameTime(int p)
{
// protect it from overflow crashing
if (m_eventsubscription + p >= int.MaxValue)
m_eventsubscription = 0;
m_eventsubscription += p;
}
} }
} }

View File

@ -937,12 +937,10 @@ namespace OpenSim.Region.Physics.OdePlugin
if (CollisionEventsThisFrame == null) if (CollisionEventsThisFrame == null)
CollisionEventsThisFrame = new CollisionEventUpdate(); CollisionEventsThisFrame = new CollisionEventUpdate();
SentEmptyCollisionsEvent = false; SentEmptyCollisionsEvent = false;
_parent_scene.AddCollisionEventReporting(this);
} }
public override void UnSubscribeEvents() public override void UnSubscribeEvents()
{ {
_parent_scene.RemoveCollisionEventReporting(this);
if (CollisionEventsThisFrame != null) if (CollisionEventsThisFrame != null)
{ {
CollisionEventsThisFrame.Clear(); CollisionEventsThisFrame.Clear();
@ -975,7 +973,10 @@ namespace OpenSim.Region.Physics.OdePlugin
base.SendCollisionUpdate(CollisionEventsThisFrame); base.SendCollisionUpdate(CollisionEventsThisFrame);
if (ncolisions == 0) if (ncolisions == 0)
{
SentEmptyCollisionsEvent = true; SentEmptyCollisionsEvent = true;
_parent_scene.RemoveCollisionEventReporting(this);
}
else else
{ {
SentEmptyCollisionsEvent = false; SentEmptyCollisionsEvent = false;

View File

@ -247,6 +247,7 @@ namespace OpenSim.Region.Physics.OdePlugin
/// A list of actors that should receive collision events. /// A list of actors that should receive collision events.
/// </summary> /// </summary>
private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>(); private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>();
private readonly List<PhysicsActor> _collisionEventPrimRemove = new List<PhysicsActor>();
private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>(); private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>();
public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>();
@ -1073,6 +1074,12 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!(p2events || p1events)) if (!(p2events || p1events))
return; return;
if (p1events)
AddCollisionEventReporting(p1);
if (p2events)
AddCollisionEventReporting(p2);
Vector3 vel = Vector3.Zero; Vector3 vel = Vector3.Zero;
if (p2 != null && p2.IsPhysical) if (p2 != null && p2.IsPhysical)
vel = p2.Velocity; vel = p2.Velocity;
@ -1255,21 +1262,15 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
#endregion #endregion
/// <summary> /// <summary>
/// Add actor to the list that should receive collision events in the simulate loop. /// Add actor to the list that should receive collision events in the simulate loop.
/// </summary> /// </summary>
/// <param name="obj"></param> /// <param name="obj"></param>
public void AddCollisionEventReporting(PhysicsActor obj) public void AddCollisionEventReporting(PhysicsActor obj)
{
lock (_collisionEventPrim)
{ {
if (!_collisionEventPrim.Contains(obj)) if (!_collisionEventPrim.Contains(obj))
_collisionEventPrim.Add(obj); _collisionEventPrim.Add(obj);
} }
}
/// <summary> /// <summary>
/// Remove actor from the list that should receive collision events in the simulate loop. /// Remove actor from the list that should receive collision events in the simulate loop.
@ -1277,13 +1278,11 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <param name="obj"></param> /// <param name="obj"></param>
public void RemoveCollisionEventReporting(PhysicsActor obj) public void RemoveCollisionEventReporting(PhysicsActor obj)
{ {
lock (_collisionEventPrim) if (_collisionEventPrim.Contains(obj) && !_collisionEventPrimRemove.Contains(obj))
{ _collisionEventPrimRemove.Add(obj);
if (_collisionEventPrim.Contains(obj))
_collisionEventPrim.Remove(obj);
}
} }
#region Add/Remove Entities #region Add/Remove Entities
public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
@ -1472,6 +1471,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
// lock (OdeLock) // lock (OdeLock)
{ {
OdePrim p = (OdePrim)prim; OdePrim p = (OdePrim)prim;
p.setPrimForRemoval(); p.setPrimForRemoval();
} }
@ -1890,8 +1890,6 @@ namespace OpenSim.Region.Physics.OdePlugin
collision_optimized(); collision_optimized();
lock (_collisionEventPrim)
{
foreach (PhysicsActor obj in _collisionEventPrim) foreach (PhysicsActor obj in _collisionEventPrim)
{ {
if (obj == null) if (obj == null)
@ -1915,7 +1913,11 @@ namespace OpenSim.Region.Physics.OdePlugin
break; break;
} }
} }
}
foreach (PhysicsActor obj in _collisionEventPrimRemove)
_collisionEventPrim.Remove(obj);
_collisionEventPrimRemove.Clear();
// do a ode simulation step // do a ode simulation step
d.WorldQuickStep(world, ODE_STEPSIZE); d.WorldQuickStep(world, ODE_STEPSIZE);