* Fixed occasional character drift caused by sim not sending the avatar's final resting velocity.

* Added Smooth moving prim
* Added event to PhysicsActor RequestPhysicsterseUpdate to allow physics plugins to be able to schedule a terse update.
afrisby
Teravus Ovares 2007-11-08 15:22:36 +00:00
parent a9b5732c33
commit fcc276a68d
4 changed files with 111 additions and 16 deletions

View File

@ -782,10 +782,15 @@ namespace OpenSim.Region.Environment.Scenes
if (UsePhysics) if (UsePhysics)
{ {
AddFlag(LLObject.ObjectFlags.Physics); AddFlag(LLObject.ObjectFlags.Physics);
if (PhysActor != null)
PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
} }
else else
{ {
RemFlag(LLObject.ObjectFlags.Physics); RemFlag(LLObject.ObjectFlags.Physics);
if (PhysActor != null)
PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
} }
if (IsPhantom) if (IsPhantom)
@ -1067,6 +1072,13 @@ namespace OpenSim.Region.Environment.Scenes
public virtual void UpdateMovement() public virtual void UpdateMovement()
{ {
} }
#region Events
public void PhysicsRequestingTerseUpdate()
{
SendTerseUpdateToAllClients();
}
#endregion
public virtual void OnGrab(LLVector3 offsetPos, IClientAPI remoteClient) public virtual void OnGrab(LLVector3 offsetPos, IClientAPI remoteClient)
{ {

View File

@ -386,6 +386,7 @@ namespace OpenSim.Region.Environment.Scenes
if (PhysicsActor != null) if (PhysicsActor != null)
{ {
m_scene.PhysScene.RemoveAvatar(PhysicsActor); m_scene.PhysScene.RemoveAvatar(PhysicsActor);
m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
PhysicsActor = null; PhysicsActor = null;
} }
} }
@ -1092,6 +1093,7 @@ namespace OpenSim.Region.Environment.Scenes
AbsolutePosition.Z); AbsolutePosition.Z);
m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec); m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec);
m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
} }
internal void Close() internal void Close()

View File

@ -36,14 +36,19 @@ namespace OpenSim.Region.Physics.Manager
public delegate void OrientationUpdate(Quaternion orientation); public delegate void OrientationUpdate(Quaternion orientation);
public abstract class PhysicsActor public abstract class PhysicsActor
{ {
public delegate void RequestTerseUpdate();
#pragma warning disable 67 #pragma warning disable 67
public event PositionUpdate OnPositionUpdate; public event PositionUpdate OnPositionUpdate;
public event VelocityUpdate OnVelocityUpdate; public event VelocityUpdate OnVelocityUpdate;
public event OrientationUpdate OnOrientationUpdate; public event OrientationUpdate OnOrientationUpdate;
public event RequestTerseUpdate OnRequestTerseUpdate;
#pragma warning restore 67 #pragma warning restore 67
public static PhysicsActor Null public static PhysicsActor Null
@ -57,6 +62,19 @@ namespace OpenSim.Region.Physics.Manager
{ {
set; set;
} }
public virtual void RequestPhysicsterseUpdate()
{
// Make a temporary copy of the event to avoid possibility of
// a race condition if the last subscriber unsubscribes
// immediately after the null check and before the event is raised.
RequestTerseUpdate handler = OnRequestTerseUpdate;
if (handler != null)
{
OnRequestTerseUpdate();
}
}
public abstract PhysicsVector Position { get; set; } public abstract PhysicsVector Position { get; set; }

View File

@ -217,21 +217,18 @@ namespace OpenSim.Region.Physics.OdePlugin
private void collision_optimized(float timeStep) private void collision_optimized(float timeStep)
{ {
foreach (OdeCharacter chr in _characters)
{
chr.IsColliding = false;
}
foreach (OdeCharacter chr in _characters) foreach (OdeCharacter chr in _characters)
{ {
chr.IsColliding = false;
d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback); d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback);
foreach (OdeCharacter ch2 in _characters) foreach (OdeCharacter ch2 in _characters)
/// should be a separate space -- lots of avatars will be N**2 slow /// should be a separate space -- lots of avatars will be N**2 slow
{ {
d.SpaceCollide2(chr.Shell, ch2.Shell, IntPtr.Zero, nearCallback); d.SpaceCollide2(chr.Shell, ch2.Shell, IntPtr.Zero, nearCallback);
} }
@ -614,6 +611,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private PhysicsVector _position; private PhysicsVector _position;
private d.Vector3 _zeroPosition; private d.Vector3 _zeroPosition;
private bool _zeroFlag = false; private bool _zeroFlag = false;
private bool m_lastUpdateSent = false;
private PhysicsVector _velocity; private PhysicsVector _velocity;
private PhysicsVector _target_velocity; private PhysicsVector _target_velocity;
private PhysicsVector _acceleration; private PhysicsVector _acceleration;
@ -624,7 +622,10 @@ namespace OpenSim.Region.Physics.OdePlugin
public static float CAPSULE_RADIUS = 0.5f; public static float CAPSULE_RADIUS = 0.5f;
public static float CAPSULE_LENGTH = 0.79f; public static float CAPSULE_LENGTH = 0.79f;
private bool flying = false; private bool flying = false;
private bool iscolliding = false; private bool m_iscolliding = false;
private bool[] m_colliderarr = new bool[10];
private bool jumping = false; private bool jumping = false;
//private float gravityAccel; //private float gravityAccel;
public IntPtr Body; public IntPtr Body;
@ -640,6 +641,12 @@ namespace OpenSim.Region.Physics.OdePlugin
_position = pos; _position = pos;
_acceleration = new PhysicsVector(); _acceleration = new PhysicsVector();
_parent_scene = parent_scene; _parent_scene = parent_scene;
for (int i = 0; i < 10; i++)
{
m_colliderarr[i] = false;
}
lock (OdeScene.OdeLock) lock (OdeScene.OdeLock)
{ {
@ -667,11 +674,48 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
public override bool IsColliding public override bool IsColliding
{ {
get { return iscolliding; }
get { return m_iscolliding; }
set set
{iscolliding = value;} {
int i;
int truecount=0;
int falsecount=0;
if (m_colliderarr.Length >= 6)
{
for (i = 0; i < 6; i++)
{
m_colliderarr[i] = m_colliderarr[i + 1];
}
}
m_colliderarr[6] = value;
for (i = 0; i < 7; i++)
{
if (m_colliderarr[i])
{
truecount++;
}
else
{
falsecount++;
}
}
// Equal truecounts and false counts means we're colliding with something.
if (falsecount > truecount)
{
m_iscolliding = false;
}
else
{
m_iscolliding = true;
}
}
} }
public override PhysicsVector Position public override PhysicsVector Position
{ {
get { return _position; } get { return _position; }
set set
@ -737,7 +781,7 @@ namespace OpenSim.Region.Physics.OdePlugin
_target_velocity.Y += force.Y; _target_velocity.Y += force.Y;
_target_velocity.Z += force.Z; _target_velocity.Z += force.Z;
//m_lastUpdateSent = false;
} }
public void doForce(PhysicsVector force) public void doForce(PhysicsVector force)
{ {
@ -756,6 +800,8 @@ namespace OpenSim.Region.Physics.OdePlugin
float servo = (2.5f - posture) * POSTURE_SERVO; float servo = (2.5f - posture) * POSTURE_SERVO;
d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f); d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f);
d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f); d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f);
//m_lastUpdateSent = false;
} }
} }
@ -771,7 +817,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.Vector3 vel = d.BodyGetLinearVel(Body); d.Vector3 vel = d.BodyGetLinearVel(Body);
// if velocity is zero, use position control; otherwise, velocity control // if velocity is zero, use position control; otherwise, velocity control
if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && iscolliding) if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && m_iscolliding)
{ {
// keep track of where we stopped. No more slippin' & slidin' // keep track of where we stopped. No more slippin' & slidin'
if (!_zeroFlag) if (!_zeroFlag)
@ -791,12 +837,12 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
_zeroFlag = false; _zeroFlag = false;
if (iscolliding || flying) if (m_iscolliding || flying)
{ {
vec.X = (_target_velocity.X - vel.X) * PID_D; vec.X = (_target_velocity.X - vel.X) * PID_D;
vec.Y = (_target_velocity.Y - vel.Y) * PID_D; vec.Y = (_target_velocity.Y - vel.Y) * PID_D;
} }
if (iscolliding && !flying && _target_velocity.Z > 0.0f) if (m_iscolliding && !flying && _target_velocity.Z > 0.0f)
{ {
d.Vector3 pos = d.BodyGetPosition(Body); d.Vector3 pos = d.BodyGetPosition(Body);
vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P;
@ -836,9 +882,16 @@ namespace OpenSim.Region.Physics.OdePlugin
_velocity.X = 0.0f; _velocity.X = 0.0f;
_velocity.Y = 0.0f; _velocity.Y = 0.0f;
_velocity.Z = 0.0f; _velocity.Z = 0.0f;
if (!m_lastUpdateSent)
{
m_lastUpdateSent = true;
base.RequestPhysicsterseUpdate();
}
} }
else else
{ {
m_lastUpdateSent = false;
vec = d.BodyGetLinearVel(Body); vec = d.BodyGetLinearVel(Body);
_velocity.X = (vec.X); _velocity.X = (vec.X);
_velocity.Y = (vec.Y); _velocity.Y = (vec.Y);
@ -875,7 +928,10 @@ namespace OpenSim.Region.Physics.OdePlugin
public IntPtr _triMeshData; public IntPtr _triMeshData;
private bool iscolliding = false; private bool iscolliding = false;
private bool m_isphysical = false; private bool m_isphysical = false;
public bool _zeroFlag = false; public bool _zeroFlag = false;
private bool m_lastUpdateSent = false;
public IntPtr Body = (IntPtr) 0; public IntPtr Body = (IntPtr) 0;
private String m_primName; private String m_primName;
private PhysicsVector _target_velocity; private PhysicsVector _target_velocity;
@ -1281,6 +1337,7 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
IsPhysical = false; IsPhysical = false;
_velocity.X = 0; _velocity.X = 0;
_velocity.Y = 0; _velocity.Y = 0;
@ -1288,15 +1345,20 @@ namespace OpenSim.Region.Physics.OdePlugin
m_rotationalVelocity.X = 0; m_rotationalVelocity.X = 0;
m_rotationalVelocity.Y = 0; m_rotationalVelocity.Y = 0;
m_rotationalVelocity.Z = 0; m_rotationalVelocity.Z = 0;
base.RequestPhysicsterseUpdate();
_zeroFlag = true; _zeroFlag = true;
} }
if (m_lastposition == l_position) if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
&& (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02)
&& (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02 ))
{ {
_zeroFlag = true; _zeroFlag = true;
} }
else else
{ {
System.Console.WriteLine(Math.Abs(m_lastposition.X - l_position.X).ToString());
_zeroFlag = false; _zeroFlag = false;
} }
m_lastposition = l_position; m_lastposition = l_position;
@ -1337,6 +1399,7 @@ namespace OpenSim.Region.Physics.OdePlugin
_orientation.x = ori.X; _orientation.x = ori.X;
_orientation.y = ori.Y; _orientation.y = ori.Y;
_orientation.z = ori.Z; _orientation.z = ori.Z;
base.RequestPhysicsterseUpdate();
} }
} }