* Change the order of Update so Physics processes a frame before the scene manipulates the physics Scene.cs

* Remove the draconic locking around adding an avatar to the Scene
* Handle an extreme error case when border crossing fails and user uses map to teleport to a different region on the same instance causing control commands to go to a child agent.
* Make the Set Appearance method use the proper 'remove from physics scene' method.
* It *may* help border crossings.   
* It *may* help the 'on avatar rez' lag, that people have been seeing the past week.
* It may also cause physics to crash more often on failed teleports (though..  I think I got the cases covered).
trunk
Teravus Ovares 2009-07-17 07:28:09 +00:00
parent 01446074b1
commit f74622c65f
2 changed files with 90 additions and 55 deletions

View File

@ -901,24 +901,7 @@ namespace OpenSim.Region.Framework.Scenes
if (m_frame == Int32.MaxValue)
m_frame = 0;
physicsMS2 = Environment.TickCount;
if ((m_frame % m_update_physics == 0) && m_physics_enabled)
m_sceneGraph.UpdatePreparePhysics();
physicsMS2 = Environment.TickCount - physicsMS2;
if (m_frame % m_update_entitymovement == 0)
m_sceneGraph.UpdateEntityMovement();
physicsMS = Environment.TickCount;
if ((m_frame % m_update_physics == 0) && m_physics_enabled)
physicsFPS = m_sceneGraph.UpdatePhysics(
Math.Max(SinceLastFrame.TotalSeconds, m_timespan)
);
if (m_frame % m_update_physics == 0 && SynchronizeScene != null)
SynchronizeScene(this);
physicsMS = Environment.TickCount - physicsMS;
physicsMS += physicsMS2;
otherMS = Environment.TickCount;
// run through all entities looking for updates (slow)
@ -949,6 +932,25 @@ namespace OpenSim.Region.Framework.Scenes
if (m_frame % m_update_presences == 0)
m_sceneGraph.UpdatePresences();
physicsMS2 = Environment.TickCount;
if ((m_frame % m_update_physics == 0) && m_physics_enabled)
m_sceneGraph.UpdatePreparePhysics();
physicsMS2 = Environment.TickCount - physicsMS2;
if (m_frame % m_update_entitymovement == 0)
m_sceneGraph.UpdateEntityMovement();
physicsMS = Environment.TickCount;
if ((m_frame % m_update_physics == 0) && m_physics_enabled)
physicsFPS = m_sceneGraph.UpdatePhysics(
Math.Max(SinceLastFrame.TotalSeconds, m_timespan)
);
if (m_frame % m_update_physics == 0 && SynchronizeScene != null)
SynchronizeScene(this);
physicsMS = Environment.TickCount - physicsMS;
physicsMS += physicsMS2;
// Delete temp-on-rez stuff
if (m_frame % m_update_backup == 0)
CleanTempObjects();

View File

@ -869,8 +869,6 @@ namespace OpenSim.Region.Framework.Scenes
private void RemoveFromPhysicalScene()
{
if (PhysicsActor != null)
{
lock (m_scene.SyncRoot)
{
m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
@ -879,7 +877,6 @@ namespace OpenSim.Region.Framework.Scenes
PhysicsActor = null;
}
}
}
/// <summary>
///
@ -999,7 +996,7 @@ namespace OpenSim.Region.Framework.Scenes
internal void SetHeight(float height)
{
m_avHeight = height;
if (PhysicsActor != null)
if (PhysicsActor != null && !IsChildAgent)
{
PhysicsVector SetSize = new PhysicsVector(0.45f, 0.6f, m_avHeight);
PhysicsActor.Size = SetSize;
@ -2219,7 +2216,35 @@ namespace OpenSim.Region.Framework.Scenes
{
if (m_isChildAgent)
{
m_log.Debug("DEBUG: AddNewMovement: child agent");
m_log.Debug("DEBUG: AddNewMovement: child agent, Making root agent!");
// we have to reset the user's child agent connections.
// Likely, here they've lost the eventqueue for other regions so border
// crossings will fail at this point unless we reset them.
List<ulong> regions = new List<ulong>(KnownChildRegionHandles);
regions.Remove(m_scene.RegionInfo.RegionHandle);
MakeRootAgent(new Vector3(127, 127, 127), true);
// Async command
if (m_scene.SceneGridService != null)
{
m_scene.SceneGridService.SendCloseChildAgentConnections(UUID, regions);
// Give the above command some time to try and close the connections.
// this is really an emergency.. so sleep, or we'll get all discombobulated.
System.Threading.Thread.Sleep(500);
}
if (m_scene.SceneGridService != null)
{
m_scene.SceneGridService.EnableNeighbourChildAgents(this, new List<RegionInfo>());
}
return;
}
@ -2553,12 +2578,20 @@ namespace OpenSim.Region.Framework.Scenes
public void SetAppearance(byte[] texture, List<byte> visualParam)
{
if (m_physicsActor != null)
{
if (!IsChildAgent)
{
// This may seem like it's redundant, remove the avatar from the physics scene
// just to add it back again, but it saves us from having to update
// 3 variables 10 times a second.
m_scene.PhysicsScene.RemoveAvatar(m_physicsActor);
AddToPhysicalScene(m_physicsActor.Flying);
bool flyingTemp = m_physicsActor.Flying;
RemoveFromPhysicalScene();
//m_scene.PhysicsScene.RemoveAvatar(m_physicsActor);
//PhysicsActor = null;
AddToPhysicalScene(flyingTemp);
}
}
m_appearance.SetAppearance(texture, visualParam);
if (m_appearance.AvatarHeight > 0)
@ -3188,14 +3221,14 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void AddToPhysicalScene(bool isFlying)
{
lock (m_scene.SyncRoot)
{
PhysicsScene scene = m_scene.PhysicsScene;
PhysicsVector pVec =
new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y,
AbsolutePosition.Z);
// Old bug where the height was in centimeters instead of meters
if (m_avHeight == 127.0f)
{
m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new PhysicsVector(0, 0, 1.56f),
@ -3211,7 +3244,7 @@ namespace OpenSim.Region.Framework.Scenes
m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
m_physicsActor.SubscribeEvents(1000);
m_physicsActor.LocalID = LocalId;
}
}
// Event called by the physics plugin to tell the avatar about a collision.