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

View File

@ -128,9 +128,10 @@ namespace OpenSim.Region.Physics.OdePlugin
public d.Mass ShellMass;
// public bool collidelock = false;
private bool m_haseventsubscription = false;
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
public UUID m_uuid;
@ -1120,47 +1121,72 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void SubscribeEvents(int ms)
{
m_requestedUpdateFrequency = ms;
m_eventsubscription = ms;
_parent_scene.AddCollisionEventReporting(this);
m_haseventsubscription = true;
m_cureventsubscription = 0;
if (CollisionEventsThisFrame == null)
CollisionEventsThisFrame = new CollisionEventUpdate();
SentEmptyCollisionsEvent = false;
}
public override void UnSubscribeEvents()
{
m_haseventsubscription = false;
_parent_scene.RemoveCollisionEventReporting(this);
m_requestedUpdateFrequency = 0;
if (CollisionEventsThisFrame != null)
{
CollisionEventsThisFrame.Clear();
CollisionEventsThisFrame = null;
}
m_eventsubscription = 0;
}
public void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
{
if (m_haseventsubscription)
{
// m_log.DebugFormat(
// "[PHYSICS]: Adding collision event for {0}, collidedWith {1}, contact {2}", "", CollidedWith, contact);
CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
}
if (CollisionEventsThisFrame == null)
CollisionEventsThisFrame = new CollisionEventUpdate();
CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
}
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();
m_eventsubscription = 0;
}
else
{
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()
{
return m_haseventsubscription;
if (m_eventsubscription > 0)
return true;
return false;
}
private void changePhysicsStatus(bool NewStatus)
@ -1466,14 +1492,5 @@ namespace OpenSim.Region.Physics.OdePlugin
{
_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
return Ptot;
/*
float tmass = _mass;
Ptot *= tmass;
/*
float tmass = _mass;
Ptot *= tmass;
float m;
float m;
foreach (OdePrim prm in childrenPrim)
{
m = prm._mass;
Ptot += prm.CenterOfMass * m;
tmass += m;
}
foreach (OdePrim prm in childrenPrim)
{
m = prm._mass;
Ptot += prm.CenterOfMass * m;
tmass += m;
}
if (tmass == 0)
tmass = 0;
else
tmass = 1.0f / tmass;
if (tmass == 0)
tmass = 0;
else
tmass = 1.0f / tmass;
Ptot *= tmass;
return Ptot;
*/
Ptot *= tmass;
return Ptot;
*/
}
else
return _position;
}
}
}
/*
public override Vector3 PrimOOBsize
{
get
{
return primOOBsize;
}
}
/*
public override Vector3 PrimOOBsize
{
get
{
return primOOBsize;
}
}
public override Vector3 PrimOOBoffset
{
get
{
return primOOBoffset;
}
}
public override Vector3 PrimOOBoffset
{
get
{
return primOOBoffset;
}
}
public override float PrimOOBRadiusSQ
{
get
{
return primOOBradiusSQ;
}
}
*/
public override float PrimOOBRadiusSQ
{
get
{
return primOOBradiusSQ;
}
}
*/
public override PrimitiveBaseShape Shape
{
set
@ -582,7 +582,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (value.IsFinite())
{
AddChange(changes.Velocity, value);
// _velocity = value;
// _velocity = value;
}
else
@ -937,12 +937,10 @@ namespace OpenSim.Region.Physics.OdePlugin
if (CollisionEventsThisFrame == null)
CollisionEventsThisFrame = new CollisionEventUpdate();
SentEmptyCollisionsEvent = false;
_parent_scene.AddCollisionEventReporting(this);
}
public override void UnSubscribeEvents()
{
_parent_scene.RemoveCollisionEventReporting(this);
if (CollisionEventsThisFrame != null)
{
CollisionEventsThisFrame.Clear();
@ -975,7 +973,10 @@ namespace OpenSim.Region.Physics.OdePlugin
base.SendCollisionUpdate(CollisionEventsThisFrame);
if (ncolisions == 0)
{
SentEmptyCollisionsEvent = true;
_parent_scene.RemoveCollisionEventReporting(this);
}
else
{
SentEmptyCollisionsEvent = false;
@ -1735,8 +1736,8 @@ namespace OpenSim.Region.Physics.OdePlugin
d.BodySetAutoDisableFlag(Body, true);
d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
// d.BodySetLinearDampingThreshold(Body, 0.01f);
// d.BodySetAngularDampingThreshold(Body, 0.001f);
// d.BodySetLinearDampingThreshold(Body, 0.01f);
// d.BodySetAngularDampingThreshold(Body, 0.001f);
d.BodySetDamping(Body, .002f, .002f);
if (m_targetSpace != IntPtr.Zero)
@ -2966,7 +2967,7 @@ namespace OpenSim.Region.Physics.OdePlugin
givefakepos--;
if (givefakepos < 0)
givefakepos = 0;
// changeSelectedStatus();
// changeSelectedStatus();
resetCollisionAccounting();
}
@ -2981,14 +2982,14 @@ namespace OpenSim.Region.Physics.OdePlugin
{
_orientation = newOri;
}
/*
else if (m_forcePosOrRotation && _orientation != newOri && Body != IntPtr.Zero)
{
FixInertia(_position, newOri);
if (!d.BodyIsEnabled(Body))
d.BodyEnable(Body);
}
*/
/*
else if (m_forcePosOrRotation && _orientation != newOri && Body != IntPtr.Zero)
{
FixInertia(_position, newOri);
if (!d.BodyIsEnabled(Body))
d.BodyEnable(Body);
}
*/
}
else
{
@ -3939,12 +3940,12 @@ namespace OpenSim.Region.Physics.OdePlugin
changevelocity((Vector3)arg);
break;
// case changes.Acceleration:
// changeacceleration((Vector3)arg);
// break;
// case changes.AngVelocity:
// changeangvelocity((Vector3)arg);
// break;
// case changes.Acceleration:
// changeacceleration((Vector3)arg);
// break;
// case changes.AngVelocity:
// changeangvelocity((Vector3)arg);
// break;
case changes.Force:
changeForce((Vector3)arg);

View File

@ -247,6 +247,7 @@ namespace OpenSim.Region.Physics.OdePlugin
/// A list of actors that should receive collision events.
/// </summary>
private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>();
private readonly List<PhysicsActor> _collisionEventPrimRemove = new List<PhysicsActor>();
private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>();
public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>();
@ -1073,6 +1074,12 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!(p2events || p1events))
return;
if (p1events)
AddCollisionEventReporting(p1);
if (p2events)
AddCollisionEventReporting(p2);
Vector3 vel = Vector3.Zero;
if (p2 != null && p2.IsPhysical)
vel = p2.Velocity;
@ -1255,20 +1262,14 @@ namespace OpenSim.Region.Physics.OdePlugin
}
#endregion
/// <summary>
/// Add actor to the list that should receive collision events in the simulate loop.
/// </summary>
/// <param name="obj"></param>
public void AddCollisionEventReporting(PhysicsActor obj)
{
lock (_collisionEventPrim)
{
if (!_collisionEventPrim.Contains(obj))
_collisionEventPrim.Add(obj);
}
if (!_collisionEventPrim.Contains(obj))
_collisionEventPrim.Add(obj);
}
/// <summary>
@ -1277,13 +1278,11 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <param name="obj"></param>
public void RemoveCollisionEventReporting(PhysicsActor obj)
{
lock (_collisionEventPrim)
{
if (_collisionEventPrim.Contains(obj))
_collisionEventPrim.Remove(obj);
}
if (_collisionEventPrim.Contains(obj) && !_collisionEventPrimRemove.Contains(obj))
_collisionEventPrimRemove.Add(obj);
}
#region Add/Remove Entities
public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
@ -1472,6 +1471,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
// lock (OdeLock)
{
OdePrim p = (OdePrim)prim;
p.setPrimForRemoval();
}
@ -1890,33 +1890,35 @@ namespace OpenSim.Region.Physics.OdePlugin
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)
continue;
case ActorTypes.Agent:
OdeCharacter cobj = (OdeCharacter)obj;
cobj.AddCollisionFrameTime((int)(ODE_STEPSIZE * 1000.0f));
cobj.SendCollisions();
break;
switch ((ActorTypes)obj.PhysicsActorType)
{
case ActorTypes.Agent:
OdeCharacter cobj = (OdeCharacter)obj;
cobj.AddCollisionFrameTime((int)(ODE_STEPSIZE*1000.0f));
cobj.SendCollisions();
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;
}
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
d.WorldQuickStep(world, ODE_STEPSIZE);
d.JointGroupEmpty(contactgroup);