Somewhat improve avatar region crossings by properly preserving velocity when avatar enters the new region.

This commit addresses the following issues were causing velocity to be set to 0 on the new region, disrupting flight in particular
* Full avatar updates contained no velocity information, which does appear to have some effect in testing.
* BulletSim was always setting the velocity to 0 for the new BSCharacter.  Now, physics engines take a velocity parameter when setting up characters so we can avoid this.
This patch applies to both Bullet and ODE.
mb-throttle-test
Justin Clark-Casey (justincc) 2014-11-29 00:12:11 +00:00
parent 09534f378e
commit 265fe349e0
12 changed files with 94 additions and 54 deletions

View File

@ -5196,7 +5196,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ScenePresence presence = (ScenePresence)entity; ScenePresence presence = (ScenePresence)entity;
// m_log.DebugFormat( // m_log.DebugFormat(
// "[LLCLIENTVIEW]: Sending terse update to {0} with position {1} in {2}", Name, presence.OffsetPosition, m_scene.Name); // "[LLCLIENTVIEW]: Sending terse update to {0} with pos {1}, vel {2} in {3}",
// Name, presence.OffsetPosition, presence.Velocity, m_scene.Name);
attachPoint = presence.State; attachPoint = presence.State;
collisionPlane = presence.CollisionPlane; collisionPlane = presence.CollisionPlane;
@ -5333,13 +5334,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[LLCLIENTVIEW]: Sending full update to {0} with position {1} in {2}", Name, data.OffsetPosition, m_scene.Name); // "[LLCLIENTVIEW]: Sending full update to {0} with pos {1}, vel {2} in {3}", Name, data.OffsetPosition, data.Velocity, m_scene.Name);
byte[] objectData = new byte[76]; byte[] objectData = new byte[76];
data.CollisionPlane.ToBytes(objectData, 0); data.CollisionPlane.ToBytes(objectData, 0);
data.OffsetPosition.ToBytes(objectData, 16); data.OffsetPosition.ToBytes(objectData, 16);
// data.Velocity.ToBytes(objectData, 28); data.Velocity.ToBytes(objectData, 28);
// data.Acceleration.ToBytes(objectData, 40); // data.Acceleration.ToBytes(objectData, 40);
// Whilst not in mouselook, an avatar will transmit only the Z rotation as this is the only axis // Whilst not in mouselook, an avatar will transmit only the Z rotation as this is the only axis

View File

@ -636,6 +636,11 @@ namespace OpenSim.Region.Framework.Scenes
set set
{ {
// Util.PrintCallStack();
// m_log.DebugFormat(
// "[SCENE PRESENCE]: In {0} set velocity of {1} to {2}",
// Scene.RegionInfo.RegionName, Name, value);
if (PhysicsActor != null) if (PhysicsActor != null)
{ {
try try
@ -649,10 +654,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
m_velocity = value; m_velocity = value;
// m_log.DebugFormat(
// "[SCENE PRESENCE]: In {0} set velocity of {1} to {2}",
// Scene.RegionInfo.RegionName, Name, m_velocity);
} }
} }
/* /*
@ -1185,15 +1186,23 @@ namespace OpenSim.Region.Framework.Scenes
} }
AbsolutePosition = pos; AbsolutePosition = pos;
// m_log.DebugFormat(
// "Set pos {0}, vel {1} in {1} to {2} from input position of {3} on MakeRootAgent",
// Name, Scene.Name, AbsolutePosition, pos);
//
if (m_teleportFlags == TeleportFlags.Default) if (m_teleportFlags == TeleportFlags.Default)
{ {
Vector3 vel = Velocity;
AddToPhysicalScene(isFlying); AddToPhysicalScene(isFlying);
if (PhysicsActor != null) //
PhysicsActor.SetMomentum(vel); // Console.WriteLine(
// "Set velocity of {0} in {1} to {2} from input velocity of {3} on MakeRootAgent",
// Name, Scene.Name, PhysicsActor.Velocity, vel);
// }
} }
else else
{
AddToPhysicalScene(isFlying); AddToPhysicalScene(isFlying);
}
// XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
// location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
@ -1211,6 +1220,7 @@ namespace OpenSim.Region.Framework.Scenes
Flying = false; Flying = false;
} }
} }
// Don't send an animation pack here, since on a region crossing this will sometimes cause a flying // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
// avatar to return to the standing position in mid-air. On login it looks like this is being sent // avatar to return to the standing position in mid-air. On login it looks like this is being sent
// elsewhere anyway // elsewhere anyway
@ -1275,7 +1285,6 @@ namespace OpenSim.Region.Framework.Scenes
// If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
// stall on the border crossing since the existing child agent will still have the last movement // stall on the border crossing since the existing child agent will still have the last movement
// recorded, which stops the input from being processed. // recorded, which stops the input from being processed.
MovementFlag = 0; MovementFlag = 0;
m_scene.EventManager.TriggerOnMakeRootAgent(this); m_scene.EventManager.TriggerOnMakeRootAgent(this);
@ -3668,10 +3677,7 @@ namespace OpenSim.Region.Framework.Scenes
// Compute the avatar position in the next physics tick. // Compute the avatar position in the next physics tick.
// If the avatar will be crossing, we force the crossing to happen now // If the avatar will be crossing, we force the crossing to happen now
// in the hope that this will make the avatar movement smoother when crossing. // in the hope that this will make the avatar movement smoother when crossing.
float timeStep = 0.1f; pos2 += vel * 0.1f;
pos2.X = pos2.X + (vel.X * timeStep);
pos2.Y = pos2.Y + (vel.Y * timeStep);
pos2.Z = pos2.Z + (vel.Z * timeStep);
if (m_scene.PositionIsInCurrentRegion(pos2)) if (m_scene.PositionIsInCurrentRegion(pos2))
return; return;
@ -3682,9 +3688,11 @@ namespace OpenSim.Region.Framework.Scenes
// Disconnect from the current region // Disconnect from the current region
bool isFlying = Flying; bool isFlying = Flying;
RemoveFromPhysicalScene(); RemoveFromPhysicalScene();
// pos2 is the forcasted position so make that the 'current' position so the crossing // pos2 is the forcasted position so make that the 'current' position so the crossing
// code will move us into the newly addressed region. // code will move us into the newly addressed region.
m_pos = pos2; m_pos = pos2;
if (CrossToNewRegion()) if (CrossToNewRegion())
{ {
AddToPhysicalScene(isFlying); AddToPhysicalScene(isFlying);
@ -4117,18 +4125,14 @@ namespace OpenSim.Region.Framework.Scenes
// Appearance.SetHeight(); // Appearance.SetHeight();
Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f)); Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
PhysicsScene scene = m_scene.PhysicsScene;
Vector3 pVec = AbsolutePosition;
/* /*
PhysicsActor = scene.AddAvatar( PhysicsActor = scene.AddAvatar(
LocalId, Firstname + "." + Lastname, pVec, LocalId, Firstname + "." + Lastname, pVec,
new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying); new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
*/ */
PhysicsActor = scene.AddAvatar( PhysicsActor = m_scene.PhysicsScene.AddAvatar(
LocalId, Firstname + "." + Lastname, pVec, LocalId, Firstname + "." + Lastname, AbsolutePosition, Velocity,
Appearance.AvatarBoxSize, isFlying); Appearance.AvatarBoxSize, isFlying);
//PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;

View File

@ -80,10 +80,11 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
return prim; return prim;
} }
public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
{ {
BasicActor act = new BasicActor(size); BasicActor act = new BasicActor(size);
act.Position = position; act.Position = position;
act.Velocity = velocity;
act.Flying = isFlying; act.Flying = isFlying;
_actors.Add(act); _actors.Add(act);
return act; return act;

View File

@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager; using OpenSim.Region.Physics.Manager;
using OMV = OpenMetaverse; using OMV = OpenMetaverse;
@ -109,6 +110,10 @@ public class BSActorAvatarMove : BSActor
{ {
if (m_velocityMotor != null) if (m_velocityMotor != null)
{ {
// if (targ == OMV.Vector3.Zero)
// Util.PrintCallStack();
//
// Console.WriteLine("SetVelocityAndTarget, {0} {1}", vel, targ);
m_velocityMotor.Reset(); m_velocityMotor.Reset();
m_velocityMotor.SetTarget(targ); m_velocityMotor.SetTarget(targ);
m_velocityMotor.SetCurrent(vel); m_velocityMotor.SetCurrent(vel);

View File

@ -64,7 +64,17 @@ public sealed class BSCharacter : BSPhysObject
private bool _usePID; private bool _usePID;
private float _PIDTau; private float _PIDTau;
public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) // public override OMV.Vector3 RawVelocity
// { get { return base.RawVelocity; }
// set {
// if (value != base.RawVelocity)
// Util.PrintCallStack();
// Console.WriteLine("Set rawvel to {0}", value);
// base.RawVelocity = value; }
// }
public BSCharacter(
uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, bool isFlying)
: base(parent_scene, localID, avName, "BSCharacter") : base(parent_scene, localID, avName, "BSCharacter")
{ {
_physicsActorType = (int)ActorTypes.Agent; _physicsActorType = (int)ActorTypes.Agent;
@ -72,7 +82,7 @@ public sealed class BSCharacter : BSPhysObject
_flying = isFlying; _flying = isFlying;
RawOrientation = OMV.Quaternion.Identity; RawOrientation = OMV.Quaternion.Identity;
RawVelocity = OMV.Vector3.Zero; RawVelocity = vel;
_buoyancy = ComputeBuoyancyFromFlying(isFlying); _buoyancy = ComputeBuoyancyFromFlying(isFlying);
Friction = BSParam.AvatarStandingFriction; Friction = BSParam.AvatarStandingFriction;
Density = BSParam.AvatarDensity; Density = BSParam.AvatarDensity;
@ -89,13 +99,15 @@ public sealed class BSCharacter : BSPhysObject
// set _avatarVolume and _mass based on capsule size, _density and Scale // set _avatarVolume and _mass based on capsule size, _density and Scale
ComputeAvatarVolumeAndMass(); ComputeAvatarVolumeAndMass();
DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6}", DetailLog(
LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos); "{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6},vel={7}",
LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos, vel);
// do actual creation in taint time // do actual creation in taint time
PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate() PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate()
{ {
DetailLog("{0},BSCharacter.create,taint", LocalID); DetailLog("{0},BSCharacter.create,taint", LocalID);
// New body and shape into PhysBody and PhysShape // New body and shape into PhysBody and PhysShape
PhysScene.Shapes.GetBodyAndShape(true, PhysScene.World, this); PhysScene.Shapes.GetBodyAndShape(true, PhysScene.World, this);
@ -142,6 +154,7 @@ public sealed class BSCharacter : BSPhysObject
m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false); m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false);
ForceVelocity = RawVelocity; ForceVelocity = RawVelocity;
TargetVelocity = RawVelocity;
// This will enable or disable the flying buoyancy of the avatar. // This will enable or disable the flying buoyancy of the avatar.
// Needs to be reset especially when an avatar is recreated after crossing a region boundry. // Needs to be reset especially when an avatar is recreated after crossing a region boundry.
@ -256,7 +269,6 @@ public sealed class BSCharacter : BSPhysObject
// Called at taint time! // Called at taint time!
public override void ZeroMotion(bool inTaintTime) public override void ZeroMotion(bool inTaintTime)
{ {
RawVelocity = OMV.Vector3.Zero;
_acceleration = OMV.Vector3.Zero; _acceleration = OMV.Vector3.Zero;
_rotationalVelocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero;
@ -267,6 +279,7 @@ public sealed class BSCharacter : BSPhysObject
PhysScene.PE.ClearAllForces(PhysBody); PhysScene.PE.ClearAllForces(PhysBody);
}); });
} }
public override void ZeroAngularMotion(bool inTaintTime) public override void ZeroAngularMotion(bool inTaintTime)
{ {
_rotationalVelocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero;
@ -441,32 +454,40 @@ public sealed class BSCharacter : BSPhysObject
get { return RawVelocity; } get { return RawVelocity; }
set { set {
RawVelocity = value; RawVelocity = value;
// m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity); OMV.Vector3 vel = RawVelocity;
DetailLog("{0}: set Velocity = {1}", LogHeader, value);
PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate() PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate()
{ {
if (m_moveActor != null) if (m_moveActor != null)
m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */); m_moveActor.SetVelocityAndTarget(vel, vel, true /* inTaintTime */);
DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, RawVelocity); m_log.DebugFormat("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, vel);
ForceVelocity = RawVelocity; ForceVelocity = vel;
}); });
} }
} }
public override OMV.Vector3 ForceVelocity { public override OMV.Vector3 ForceVelocity {
get { return RawVelocity; } get { return RawVelocity; }
set { set {
PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity"); PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity");
// Util.PrintCallStack();
DetailLog("{0}: set ForceVelocity = {1}", LogHeader, value);
RawVelocity = value; RawVelocity = value;
PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity); PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
PhysScene.PE.Activate(PhysBody, true); PhysScene.PE.Activate(PhysBody, true);
} }
} }
public override OMV.Vector3 Torque { public override OMV.Vector3 Torque {
get { return RawTorque; } get { return RawTorque; }
set { RawTorque = value; set { RawTorque = value;
} }
} }
public override float CollisionScore { public override float CollisionScore {
get { return _collisionScore; } get { return _collisionScore; }
set { _collisionScore = value; set { _collisionScore = value;

View File

@ -228,7 +228,7 @@ public abstract class BSPhysObject : PhysicsActor
public virtual OMV.Quaternion RawOrientation { get; set; } public virtual OMV.Quaternion RawOrientation { get; set; }
public abstract OMV.Quaternion ForceOrientation { get; set; } public abstract OMV.Quaternion ForceOrientation { get; set; }
public OMV.Vector3 RawVelocity { get; set; } public virtual OMV.Vector3 RawVelocity { get; set; }
public abstract OMV.Vector3 ForceVelocity { get; set; } public abstract OMV.Vector3 ForceVelocity { get; set; }
public OMV.Vector3 RawForce { get; set; } public OMV.Vector3 RawForce { get; set; }

View File

@ -461,19 +461,19 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
#region Prim and Avatar addition and removal #region Prim and Avatar addition and removal
public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
{ {
m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader); m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader);
return null; return null;
} }
public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying) public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
{ {
// m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName); // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName);
if (!m_initialized) return null; if (!m_initialized) return null;
BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); BSCharacter actor = new BSCharacter(localID, avName, this, position, velocity, size, isFlying);
lock (PhysObjects) lock (PhysObjects)
PhysObjects.Add(localID, actor); PhysObjects.Add(localID, actor);

View File

@ -45,7 +45,8 @@ namespace OpenSim.Region.Physics.Manager
// Does nothing right now // Does nothing right now
} }
public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) public override PhysicsActor AddAvatar(
string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
{ {
m_log.InfoFormat("[PHYSICS]: NullPhysicsScene : AddAvatar({0})", position); m_log.InfoFormat("[PHYSICS]: NullPhysicsScene : AddAvatar({0})", position);
return PhysicsActor.Null; return PhysicsActor.Null;

View File

@ -142,10 +142,12 @@ namespace OpenSim.Region.Physics.Manager
/// </summary> /// </summary>
/// <param name="avName"></param> /// <param name="avName"></param>
/// <param name="position"></param> /// <param name="position"></param>
/// <param name="velocity"></param>
/// <param name="size"></param> /// <param name="size"></param>
/// <param name="isFlying"></param> /// <param name="isFlying"></param>
/// <returns></returns> /// <returns></returns>
public abstract PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying); public abstract PhysicsActor AddAvatar(
string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying);
/// <summary> /// <summary>
/// Add an avatar /// Add an avatar
@ -153,13 +155,18 @@ namespace OpenSim.Region.Physics.Manager
/// <param name="localID"></param> /// <param name="localID"></param>
/// <param name="avName"></param> /// <param name="avName"></param>
/// <param name="position"></param> /// <param name="position"></param>
/// <param name="velocity"></param>
/// <param name="size"></param> /// <param name="size"></param>
/// <param name="isFlying"></param> /// <param name="isFlying"></param>
/// <returns></returns> /// <returns></returns>
public virtual PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying) public virtual PhysicsActor AddAvatar(
uint localID, string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
{ {
PhysicsActor ret = AddAvatar(avName, position, size, isFlying); PhysicsActor ret = AddAvatar(avName, position, velocity, size, isFlying);
if (ret != null) ret.LocalID = localID;
if (ret != null)
ret.LocalID = localID;
return ret; return ret;
} }

View File

@ -167,6 +167,7 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <param name="avName"></param> /// <param name="avName"></param>
/// <param name="parent_scene"></param> /// <param name="parent_scene"></param>
/// <param name="pos"></param> /// <param name="pos"></param>
/// <param name="vel"></param>
/// <param name="size"></param> /// <param name="size"></param>
/// <param name="pid_d"></param> /// <param name="pid_d"></param>
/// <param name="pid_p"></param> /// <param name="pid_p"></param>
@ -178,7 +179,7 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <param name="walk_divisor"></param> /// <param name="walk_divisor"></param>
/// <param name="rundivisor"></param> /// <param name="rundivisor"></param>
public OdeCharacter( public OdeCharacter(
String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, String avName, OdeScene parent_scene, Vector3 pos, Vector3 vel, Vector3 size, float pid_d, float pid_p,
float capsule_radius, float tensor, float density, float capsule_radius, float tensor, float density,
float walk_divisor, float rundivisor) float walk_divisor, float rundivisor)
{ {
@ -210,6 +211,9 @@ namespace OpenSim.Region.Physics.OdePlugin
m_log.WarnFormat("[ODE CHARACTER]: Got NaN Position on Character Create for {0}", avName); m_log.WarnFormat("[ODE CHARACTER]: Got NaN Position on Character Create for {0}", avName);
} }
_velocity = vel;
m_taintTargetVelocity = vel;
_parent_scene = parent_scene; _parent_scene = parent_scene;
PID_D = pid_d; PID_D = pid_d;

View File

@ -1969,16 +1969,11 @@ namespace OpenSim.Region.Physics.OdePlugin
#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 velocity, Vector3 size, bool isFlying)
{ {
Vector3 pos;
pos.X = position.X;
pos.Y = position.Y;
pos.Z = position.Z;
OdeCharacter newAv OdeCharacter newAv
= new OdeCharacter( = new OdeCharacter(
avName, this, pos, size, avPIDD, avPIDP, avName, this, position, velocity, size, avPIDD, avPIDP,
avCapRadius, avStandupTensor, avDensity, avCapRadius, avStandupTensor, avDensity,
avMovementDivisorWalk, avMovementDivisorRun); avMovementDivisorWalk, avMovementDivisorRun);

View File

@ -58,7 +58,8 @@ namespace OpenSim.Region.Physics.POSPlugin
{ {
} }
public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) public override PhysicsActor AddAvatar(
string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
{ {
POSCharacter act = new POSCharacter(); POSCharacter act = new POSCharacter();
act.Position = position; act.Position = position;