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( CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
// "[PHYSICS]: Adding collision event for {0}, collidedWith {1}, contact {2}", "", CollidedWith, contact);
CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
}
} }
public void SendCollisions() public void SendCollisions()
{ {
if (m_haseventsubscription && m_eventsubscription > m_requestedUpdateFrequency) if (CollisionEventsThisFrame == null)
return;
if (m_cureventsubscription < m_eventsubscription)
return;
m_cureventsubscription = 0;
int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count;
if (!SentEmptyCollisionsEvent || ncolisions > 0)
{ {
if (CollisionEventsThisFrame != null) base.SendCollisionUpdate(CollisionEventsThisFrame);
if (ncolisions == 0)
{ {
base.SendCollisionUpdate(CollisionEventsThisFrame); 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

@ -477,58 +477,58 @@ namespace OpenSim.Region.Physics.OdePlugin
// if(childPrim) we only know about physical linksets // if(childPrim) we only know about physical linksets
return Ptot; return Ptot;
/* /*
float tmass = _mass; float tmass = _mass;
Ptot *= tmass; Ptot *= tmass;
float m; float m;
foreach (OdePrim prm in childrenPrim) foreach (OdePrim prm in childrenPrim)
{ {
m = prm._mass; m = prm._mass;
Ptot += prm.CenterOfMass * m; Ptot += prm.CenterOfMass * m;
tmass += m; tmass += m;
} }
if (tmass == 0) if (tmass == 0)
tmass = 0; tmass = 0;
else else
tmass = 1.0f / tmass; tmass = 1.0f / tmass;
Ptot *= tmass; Ptot *= tmass;
return Ptot; return Ptot;
*/ */
} }
else else
return _position; return _position;
} }
} }
} }
/* /*
public override Vector3 PrimOOBsize public override Vector3 PrimOOBsize
{ {
get get
{ {
return primOOBsize; return primOOBsize;
} }
} }
public override Vector3 PrimOOBoffset public override Vector3 PrimOOBoffset
{ {
get get
{ {
return primOOBoffset; return primOOBoffset;
} }
} }
public override float PrimOOBRadiusSQ public override float PrimOOBRadiusSQ
{ {
get get
{ {
return primOOBradiusSQ; return primOOBradiusSQ;
} }
} }
*/ */
public override PrimitiveBaseShape Shape public override PrimitiveBaseShape Shape
{ {
set set
@ -582,7 +582,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (value.IsFinite()) if (value.IsFinite())
{ {
AddChange(changes.Velocity, value); AddChange(changes.Velocity, value);
// _velocity = value; // _velocity = value;
} }
else else
@ -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;
@ -1735,8 +1736,8 @@ namespace OpenSim.Region.Physics.OdePlugin
d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableFlag(Body, true);
d.BodySetAutoDisableSteps(Body, body_autodisable_frames); d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
// d.BodySetLinearDampingThreshold(Body, 0.01f); // d.BodySetLinearDampingThreshold(Body, 0.01f);
// d.BodySetAngularDampingThreshold(Body, 0.001f); // d.BodySetAngularDampingThreshold(Body, 0.001f);
d.BodySetDamping(Body, .002f, .002f); d.BodySetDamping(Body, .002f, .002f);
if (m_targetSpace != IntPtr.Zero) if (m_targetSpace != IntPtr.Zero)
@ -2966,7 +2967,7 @@ namespace OpenSim.Region.Physics.OdePlugin
givefakepos--; givefakepos--;
if (givefakepos < 0) if (givefakepos < 0)
givefakepos = 0; givefakepos = 0;
// changeSelectedStatus(); // changeSelectedStatus();
resetCollisionAccounting(); resetCollisionAccounting();
} }
@ -2981,14 +2982,14 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
_orientation = newOri; _orientation = newOri;
} }
/* /*
else if (m_forcePosOrRotation && _orientation != newOri && Body != IntPtr.Zero) else if (m_forcePosOrRotation && _orientation != newOri && Body != IntPtr.Zero)
{ {
FixInertia(_position, newOri); FixInertia(_position, newOri);
if (!d.BodyIsEnabled(Body)) if (!d.BodyIsEnabled(Body))
d.BodyEnable(Body); d.BodyEnable(Body);
} }
*/ */
} }
else else
{ {
@ -3939,12 +3940,12 @@ namespace OpenSim.Region.Physics.OdePlugin
changevelocity((Vector3)arg); changevelocity((Vector3)arg);
break; break;
// case changes.Acceleration: // case changes.Acceleration:
// changeacceleration((Vector3)arg); // changeacceleration((Vector3)arg);
// break; // break;
// case changes.AngVelocity: // case changes.AngVelocity:
// changeangvelocity((Vector3)arg); // changeangvelocity((Vector3)arg);
// break; // break;
case changes.Force: case changes.Force:
changeForce((Vector3)arg); changeForce((Vector3)arg);

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,20 +1262,14 @@ 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))
{ _collisionEventPrim.Add(obj);
if (!_collisionEventPrim.Contains(obj))
_collisionEventPrim.Add(obj);
}
} }
/// <summary> /// <summary>
@ -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,33 +1890,35 @@ namespace OpenSim.Region.Physics.OdePlugin
collision_optimized(); collision_optimized();
lock (_collisionEventPrim) foreach (PhysicsActor obj in _collisionEventPrim)
{ {
foreach (PhysicsActor obj in _collisionEventPrim) if (obj == null)
continue;
switch ((ActorTypes)obj.PhysicsActorType)
{ {
if (obj == null) case ActorTypes.Agent:
continue; OdeCharacter cobj = (OdeCharacter)obj;
cobj.AddCollisionFrameTime((int)(ODE_STEPSIZE * 1000.0f));
cobj.SendCollisions();
break;
switch ((ActorTypes)obj.PhysicsActorType) case ActorTypes.Prim:
{ OdePrim pobj = (OdePrim)obj;
case ActorTypes.Agent: if (pobj.Body == IntPtr.Zero || (d.BodyIsEnabled(pobj.Body) && !pobj.m_outbounds))
OdeCharacter cobj = (OdeCharacter)obj; {
cobj.AddCollisionFrameTime((int)(ODE_STEPSIZE*1000.0f)); pobj.AddCollisionFrameTime((int)(ODE_STEPSIZE * 1000.0f));
cobj.SendCollisions(); pobj.SendCollisions();
break; }
break;
case ActorTypes.Prim:
OdePrim pobj = (OdePrim)obj;
if (pobj.Body == IntPtr.Zero || (d.BodyIsEnabled(pobj.Body) && !pobj.m_outbounds))
{
pobj.AddCollisionFrameTime((int)(ODE_STEPSIZE * 1000.0f));
pobj.SendCollisions();
}
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);
d.JointGroupEmpty(contactgroup); d.JointGroupEmpty(contactgroup);