* Added an Avatar control tweak that disables the PID controller in certain circumstances.

* This allows collisions with other avatar and prim with a velocity greater then 0 to push avatar around.
afrisby
Teravus Ovares 2007-12-15 05:08:08 +00:00
parent 8a8c89a0f3
commit 81828c9b14
2 changed files with 55 additions and 21 deletions

View File

@ -46,6 +46,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private PhysicsVector _target_velocity; private PhysicsVector _target_velocity;
private PhysicsVector _acceleration; private PhysicsVector _acceleration;
private PhysicsVector m_rotationalVelocity; private PhysicsVector m_rotationalVelocity;
private bool m_pidControllerActive = true;
private static float PID_D = 3020.0f; private static float PID_D = 3020.0f;
private static float PID_P = 7000.0f; private static float PID_P = 7000.0f;
private static float POSTURE_SERVO = 10000.0f; private static float POSTURE_SERVO = 10000.0f;
@ -56,6 +57,8 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool m_iscollidingGround = false; private bool m_iscollidingGround = false;
private bool m_wascolliding = false; private bool m_wascolliding = false;
private bool m_wascollidingGround = false; private bool m_wascollidingGround = false;
private bool m_iscollidingObj = false;
private bool m_wascollidingObj = false;
private bool m_alwaysRun = false; private bool m_alwaysRun = false;
private bool m_hackSentFall = false; private bool m_hackSentFall = false;
private bool m_hackSentFly = false; private bool m_hackSentFly = false;
@ -165,10 +168,13 @@ namespace OpenSim.Region.Physics.OdePlugin
else else
{ {
m_iscolliding = true; m_iscolliding = true;
} }
if (m_wascolliding != m_iscolliding) if (m_wascolliding != m_iscolliding)
{ {
base.SendCollisionUpdate(new CollisionEventUpdate()); base.SendCollisionUpdate(new CollisionEventUpdate());
} }
m_wascolliding = m_iscolliding; m_wascolliding = m_iscolliding;
} }
@ -222,8 +228,14 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
public override bool CollidingObj public override bool CollidingObj
{ {
get { return false; } get { return m_iscollidingObj; }
set { return; } set {
m_iscollidingObj = value;
if (value)
m_pidControllerActive = false;
else
m_pidControllerActive = true;
}
} }
public override PhysicsVector Position public override PhysicsVector Position
@ -248,6 +260,7 @@ namespace OpenSim.Region.Physics.OdePlugin
get { return new PhysicsVector(CAPSULE_RADIUS * 2, CAPSULE_RADIUS * 2, CAPSULE_LENGTH); } get { return new PhysicsVector(CAPSULE_RADIUS * 2, CAPSULE_RADIUS * 2, CAPSULE_LENGTH); }
set set
{ {
m_pidControllerActive = true;
lock (OdeScene.OdeLock) lock (OdeScene.OdeLock)
{ {
PhysicsVector SetSize = value; PhysicsVector SetSize = value;
@ -282,7 +295,9 @@ namespace OpenSim.Region.Physics.OdePlugin
public override PhysicsVector Velocity public override PhysicsVector Velocity
{ {
get { return _velocity; } get { return _velocity; }
set { _target_velocity = value; } set {
m_pidControllerActive = true;
_target_velocity = value; }
} }
public override bool Kinematic public override bool Kinematic
@ -304,12 +319,13 @@ namespace OpenSim.Region.Physics.OdePlugin
public void SetAcceleration(PhysicsVector accel) public void SetAcceleration(PhysicsVector accel)
{ {
m_pidControllerActive = true;
_acceleration = accel; _acceleration = accel;
} }
public override void AddForce(PhysicsVector force) public override void AddForce(PhysicsVector force)
{ {
m_pidControllerActive = true;
_target_velocity.X += force.X; _target_velocity.X += force.X;
_target_velocity.Y += force.Y; _target_velocity.Y += force.Y;
_target_velocity.Z += force.Z; _target_velocity.Z += force.Z;
@ -346,6 +362,12 @@ namespace OpenSim.Region.Physics.OdePlugin
public void Move(float timeStep) public void Move(float timeStep)
{ {
// no lock; for now it's only called from within Simulate() // no lock; for now it's only called from within Simulate()
if (m_pidControllerActive == false)
{
_zeroPosition = d.BodyGetPosition(Body);
}
//PidStatus = true;
PhysicsVector vec = new PhysicsVector(); PhysicsVector vec = new PhysicsVector();
d.Vector3 vel = d.BodyGetLinearVel(Body); d.Vector3 vel = d.BodyGetLinearVel(Body);
float movementdivisor = 1f; float movementdivisor = 1f;
@ -369,17 +391,21 @@ namespace OpenSim.Region.Physics.OdePlugin
_zeroFlag = true; _zeroFlag = true;
_zeroPosition = d.BodyGetPosition(Body); _zeroPosition = d.BodyGetPosition(Body);
} }
d.Vector3 pos = d.BodyGetPosition(Body); if (m_pidControllerActive)
vec.X = (_target_velocity.X - vel.X) * PID_D + (_zeroPosition.X - pos.X) * PID_P;
vec.Y = (_target_velocity.Y - vel.Y) * PID_D + (_zeroPosition.Y - pos.Y) * PID_P;
if (flying)
{ {
vec.Z = (_target_velocity.Z - vel.Z) * (PID_D + 5100) + (_zeroPosition.Z - pos.Z) * PID_P; d.Vector3 pos = d.BodyGetPosition(Body);
vec.X = (_target_velocity.X - vel.X) * PID_D + (_zeroPosition.X - pos.X) * PID_P;
vec.Y = (_target_velocity.Y - vel.Y) * PID_D + (_zeroPosition.Y - pos.Y) * PID_P;
if (flying)
{
vec.Z = (_target_velocity.Z - vel.Z) * (PID_D + 5100) + (_zeroPosition.Z - pos.Z) * PID_P;
}
} }
//PidStatus = true;
} }
else else
{ {
m_pidControllerActive = true;
_zeroFlag = false; _zeroFlag = false;
if (m_iscolliding || flying) if (m_iscolliding || flying)
{ {
@ -455,14 +481,15 @@ namespace OpenSim.Region.Physics.OdePlugin
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
if (primScenAvatarIn == "0") //if (primScenAvatarIn == "0")
{ //{
MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in space with no prim. Arr:':" + arrayitem[0].ToString() + "," + arrayitem[1].ToString()); //MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in space with no prim. Arr:':" + arrayitem[0].ToString() + "," + arrayitem[1].ToString());
} //}
else //else
{ //{
MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in Prim space':" + primScenAvatarIn + ". Arr:" + arrayitem[0].ToString() + "," + arrayitem[1].ToString()); // MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in Prim space':" + primScenAvatarIn + ". Arr:" + arrayitem[0].ToString() + "," + arrayitem[1].ToString());
} //}
} }
} }
else else
@ -477,6 +504,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
m_hackSentFall = true; m_hackSentFall = true;
base.SendCollisionUpdate(new CollisionEventUpdate()); base.SendCollisionUpdate(new CollisionEventUpdate());
m_pidControllerActive = false;
} }
else if (flying && !m_hackSentFly) else if (flying && !m_hackSentFly)
{ {

View File

@ -127,7 +127,7 @@ namespace OpenSim.Region.Physics.OdePlugin
contact.surface.bounce = 0.2f; contact.surface.bounce = 0.2f;
TerrainContact.surface.mode |= d.ContactFlags.SoftERP; TerrainContact.surface.mode |= d.ContactFlags.SoftERP;
TerrainContact.surface.mu = 250.0f; TerrainContact.surface.mu = 550.0f;
TerrainContact.surface.bounce = 0.1f; TerrainContact.surface.bounce = 0.1f;
TerrainContact.surface.soft_erp = 0.1025f; TerrainContact.surface.soft_erp = 0.1025f;
@ -255,7 +255,7 @@ namespace OpenSim.Region.Physics.OdePlugin
PhysicsActor p1; PhysicsActor p1;
PhysicsActor p2; PhysicsActor p2;
if (!actor_name_map.TryGetValue(g2, out p1)) if (!actor_name_map.TryGetValue(g1, out p1))
{ {
p1 = PANull; p1 = PANull;
} }
@ -267,16 +267,22 @@ namespace OpenSim.Region.Physics.OdePlugin
// We only need to test p2 for 'jump crouch purposes' // We only need to test p2 for 'jump crouch purposes'
p2.IsColliding = true; p2.IsColliding = true;
switch(p1.PhysicsActorType) { switch(p1.PhysicsActorType) {
case (int)ActorTypes.Agent: case (int)ActorTypes.Agent:
p2.CollidingObj = true; p2.CollidingObj = true;
break; break;
case (int)ActorTypes.Prim: case (int)ActorTypes.Prim:
p2.CollidingObj = true; if (p2.Velocity.X >0 || p2.Velocity.Y > 0 || p2.Velocity.Z > 0)
p2.CollidingObj = true;
break; break;
case (int)ActorTypes.Unknown: case (int)ActorTypes.Unknown:
p2.CollidingGround = true; p2.CollidingGround = true;
break; break;
default:
p2.CollidingGround = true;
break;
} }
if (name1 == "Terrain" || name2 == "Terrain") if (name1 == "Terrain" || name2 == "Terrain")