Merge branch 'master' of ssh://opensimulator.org/var/git/opensim

Conflicts:
	OpenSim/Framework/Util.cs
This commit is contained in:
Diva Canto
2012-03-20 17:19:14 -07:00
32 changed files with 522 additions and 324 deletions

View File

@@ -761,7 +761,7 @@ namespace OpenSim.Region.ClientStack.Linden
SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
if (part != null)
{
TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
// TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID))
{
return LLSDHelpers.SerialiseLLSDReply(response);

View File

@@ -50,7 +50,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
m_regStatus = RegionStatus.Up;
}
public override void Update() {}
public override void Update(int frames) {}
public override void LoadWorldMap() {}
public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)

View File

@@ -93,8 +93,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
scene.RegisterModuleInterface<IAuthorizationService>(this);
m_Scene = scene;
scene.EventManager.OnLoginsEnabled += new EventManager.LoginsEnabled(OnLoginsEnabled);
}
public void RemoveRegion(Scene scene)
@@ -106,16 +104,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
if (!m_Enabled)
return;
m_AuthorizationService = new AuthorizationService(m_AuthorizationConfig, m_Scene);
m_log.InfoFormat(
"[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}",
scene.RegionInfo.RegionName);
}
private void OnLoginsEnabled(string regionName)
{
m_AuthorizationService = new AuthorizationService(m_AuthorizationConfig, m_Scene);
}
public bool IsAuthorizedForRegion(
string userID, string firstName, string lastName, string regionID, out string message)
{

View File

@@ -604,7 +604,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1)
{
uint ObjectLocalID;
SceneObjectPart part;
switch (cmd)
@@ -877,7 +876,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
return;
Dictionary<uint, float> sceneData = null;
List<UUID> uuidNameLookupList = new List<UUID>();
if (reportType == 1)
{

View File

@@ -481,6 +481,13 @@ namespace OpenSim.Region.Framework.Scenes
public event RegionHeartbeatEnd OnRegionHeartbeatEnd;
public delegate void LoginsEnabled(string regionName);
/// <summary>
/// This should only fire in all circumstances if the RegionReady module is active.
/// </summary>
/// <remarks>
/// TODO: Fire this even when the RegionReady module is not active.
/// </remarks>
public event LoginsEnabled OnLoginsEnabled;
public delegate void PrimsLoaded(Scene s);

View File

@@ -190,7 +190,11 @@ namespace OpenSim.Region.Framework.Scenes
private int backupMS;
private int terrainMS;
private int landMS;
private int lastCompletedFrame;
/// <summary>
/// Tick at which the last frame was processed.
/// </summary>
private int m_lastFrameTick;
/// <summary>
/// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
@@ -464,7 +468,7 @@ namespace OpenSim.Region.Framework.Scenes
public int MonitorBackupTime { get { return backupMS; } }
public int MonitorTerrainTime { get { return terrainMS; } }
public int MonitorLandTime { get { return landMS; } }
public int MonitorLastFrameTick { get { return lastCompletedFrame; } }
public int MonitorLastFrameTick { get { return m_lastFrameTick; } }
public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } }
public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } }
@@ -1175,18 +1179,15 @@ namespace OpenSim.Region.Framework.Scenes
// The first frame can take a very long time due to physics actors being added on startup. Therefore,
// don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
// alarms for scenes with many objects.
Update();
Update(1);
Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
while (!shuttingdown)
Update();
Update(-1);
m_lastUpdate = Util.EnvironmentTickCount();
m_firstHeartbeat = false;
}
catch (ThreadAbortException)
{
}
finally
{
Monitor.Pulse(m_heartbeatLock);
@@ -1196,188 +1197,207 @@ namespace OpenSim.Region.Framework.Scenes
Watchdog.RemoveThread();
}
public override void Update()
public override void Update(int frames)
{
long? endFrame = null;
if (frames >= 0)
endFrame = Frame + frames;
float physicsFPS = 0f;
int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS;
int previousFrameTick;
int maintc;
List<Vector3> coarseLocations;
List<UUID> avatarUUIDs;
int maintc = Util.EnvironmentTickCount();
int tmpFrameMS = maintc;
agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
++Frame;
while (!shuttingdown && (endFrame == null || Frame < endFrame))
{
maintc = Util.EnvironmentTickCount();
++Frame;
// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName);
try
{
int tmpPhysicsMS2 = Util.EnvironmentTickCount();
if ((Frame % m_update_physics == 0) && m_physics_enabled)
m_sceneGraph.UpdatePreparePhysics();
physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
// Apply any pending avatar force input to the avatar's velocity
int tmpAgentMS = Util.EnvironmentTickCount();
if (Frame % m_update_entitymovement == 0)
m_sceneGraph.UpdateScenePresenceMovement();
agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS);
// Perform the main physics update. This will do the actual work of moving objects and avatars according to their
// velocity
int tmpPhysicsMS = Util.EnvironmentTickCount();
if (Frame % m_update_physics == 0)
try
{
if (m_physics_enabled)
physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
if (SynchronizeScene != null)
SynchronizeScene(this);
}
physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
tmpAgentMS = Util.EnvironmentTickCount();
// Check if any objects have reached their targets
CheckAtTargets();
// Update SceneObjectGroups that have scheduled themselves for updates
// Objects queue their updates onto all scene presences
if (Frame % m_update_objects == 0)
m_sceneGraph.UpdateObjectGroups();
// Run through all ScenePresences looking for updates
// Presence updates and queued object updates for each presence are sent to clients
if (Frame % m_update_presences == 0)
m_sceneGraph.UpdatePresences();
// Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
if (Frame % m_update_coarse_locations == 0)
{
List<Vector3> coarseLocations;
List<UUID> avatarUUIDs;
SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
// Send coarse locations to clients
ForEachScenePresence(delegate(ScenePresence presence)
tmpPhysicsMS2 = Util.EnvironmentTickCount();
if ((Frame % m_update_physics == 0) && m_physics_enabled)
m_sceneGraph.UpdatePreparePhysics();
physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
// Apply any pending avatar force input to the avatar's velocity
tmpAgentMS = Util.EnvironmentTickCount();
if (Frame % m_update_entitymovement == 0)
m_sceneGraph.UpdateScenePresenceMovement();
agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS);
// Perform the main physics update. This will do the actual work of moving objects and avatars according to their
// velocity
tmpPhysicsMS = Util.EnvironmentTickCount();
if (Frame % m_update_physics == 0)
{
presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
});
}
agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS);
// Delete temp-on-rez stuff
if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
{
int tmpTempOnRezMS = Util.EnvironmentTickCount();
m_cleaningTemps = true;
Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
}
if (Frame % m_update_events == 0)
{
int evMS = Util.EnvironmentTickCount();
UpdateEvents();
eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
}
if (Frame % m_update_backup == 0)
{
int backMS = Util.EnvironmentTickCount();
UpdateStorageBackup();
backupMS = Util.EnvironmentTickCountSubtract(backMS);
}
if (Frame % m_update_terrain == 0)
{
int terMS = Util.EnvironmentTickCount();
UpdateTerrain();
terrainMS = Util.EnvironmentTickCountSubtract(terMS);
}
//if (Frame % m_update_land == 0)
//{
// int ldMS = Util.EnvironmentTickCount();
// UpdateLand();
// landMS = Util.EnvironmentTickCountSubtract(ldMS);
//}
frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
lastCompletedFrame = Util.EnvironmentTickCount();
// if (Frame%m_update_avatars == 0)
// UpdateInWorldTime();
StatsReporter.AddPhysicsFPS(physicsFPS);
StatsReporter.AddTimeDilation(TimeDilation);
StatsReporter.AddFPS(1);
StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
StatsReporter.addFrameMS(frameMS);
StatsReporter.addAgentMS(agentMS);
StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
StatsReporter.addOtherMS(otherMS);
StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
if (LoginsDisabled && Frame == 20)
{
// m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
// In 99.9% of cases it is a bad idea to manually force garbage collection. However,
// this is a rare case where we know we have just went through a long cycle of heap
// allocations, and there is no more work to be done until someone logs in
GC.Collect();
IConfig startupConfig = m_config.Configs["Startup"];
if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
{
// This handles a case of a region having no scripts for the RegionReady module
if (m_sceneGraph.GetActiveScriptsCount() == 0)
{
// need to be able to tell these have changed in RegionReady
LoginLock = false;
EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
}
m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
// For RegionReady lockouts
if(LoginLock == false)
{
LoginsDisabled = false;
}
m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
if (m_physics_enabled)
physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
if (SynchronizeScene != null)
SynchronizeScene(this);
}
else
physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
tmpAgentMS = Util.EnvironmentTickCount();
// Check if any objects have reached their targets
CheckAtTargets();
// Update SceneObjectGroups that have scheduled themselves for updates
// Objects queue their updates onto all scene presences
if (Frame % m_update_objects == 0)
m_sceneGraph.UpdateObjectGroups();
// Run through all ScenePresences looking for updates
// Presence updates and queued object updates for each presence are sent to clients
if (Frame % m_update_presences == 0)
m_sceneGraph.UpdatePresences();
// Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
if (Frame % m_update_coarse_locations == 0)
{
StartDisabled = true;
LoginsDisabled = true;
SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
// Send coarse locations to clients
ForEachScenePresence(delegate(ScenePresence presence)
{
presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
});
}
agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS);
// Delete temp-on-rez stuff
if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
{
tmpTempOnRezMS = Util.EnvironmentTickCount();
m_cleaningTemps = true;
Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
}
if (Frame % m_update_events == 0)
{
evMS = Util.EnvironmentTickCount();
UpdateEvents();
eventMS = Util.EnvironmentTickCountSubtract(evMS);
}
if (Frame % m_update_backup == 0)
{
backMS = Util.EnvironmentTickCount();
UpdateStorageBackup();
backupMS = Util.EnvironmentTickCountSubtract(backMS);
}
if (Frame % m_update_terrain == 0)
{
terMS = Util.EnvironmentTickCount();
UpdateTerrain();
terrainMS = Util.EnvironmentTickCountSubtract(terMS);
}
//if (Frame % m_update_land == 0)
//{
// int ldMS = Util.EnvironmentTickCount();
// UpdateLand();
// landMS = Util.EnvironmentTickCountSubtract(ldMS);
//}
frameMS = Util.EnvironmentTickCountSubtract(maintc);
otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
// if (Frame%m_update_avatars == 0)
// UpdateInWorldTime();
StatsReporter.AddPhysicsFPS(physicsFPS);
StatsReporter.AddTimeDilation(TimeDilation);
StatsReporter.AddFPS(1);
StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
// frameMS currently records work frame times, not total frame times (work + any required sleep to
// reach min frame time.
StatsReporter.addFrameMS(frameMS);
StatsReporter.addAgentMS(agentMS);
StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
StatsReporter.addOtherMS(otherMS);
StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
if (LoginsDisabled && Frame == 20)
{
// m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
// In 99.9% of cases it is a bad idea to manually force garbage collection. However,
// this is a rare case where we know we have just went through a long cycle of heap
// allocations, and there is no more work to be done until someone logs in
GC.Collect();
IConfig startupConfig = m_config.Configs["Startup"];
if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
{
// This handles a case of a region having no scripts for the RegionReady module
if (m_sceneGraph.GetActiveScriptsCount() == 0)
{
// need to be able to tell these have changed in RegionReady
LoginLock = false;
EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
}
m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
// For RegionReady lockouts
if(LoginLock == false)
{
LoginsDisabled = false;
}
m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
}
else
{
StartDisabled = true;
LoginsDisabled = true;
}
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[SCENE]: Failed on region {0} with exception {1}{2}",
RegionInfo.RegionName, e.Message, e.StackTrace);
}
EventManager.TriggerRegionHeartbeatEnd(this);
// Tell the watchdog that this thread is still alive
Watchdog.UpdateThread();
// previousFrameTick = m_lastFrameTick;
m_lastFrameTick = Util.EnvironmentTickCount();
maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc);
maintc = (int)(MinFrameTime * 1000) - maintc;
if (maintc > 0)
Thread.Sleep(maintc);
// Optionally warn if a frame takes double the amount of time that it should.
// if (Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2))
// m_log.WarnFormat(
// "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
// Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick),
// MinFrameTime * 1000,
// RegionInfo.RegionName);
}
catch (NotImplementedException)
{
throw;
}
catch (Exception e)
{
m_log.ErrorFormat(
"[SCENE]: Failed on region {0} with exception {1}{2}",
RegionInfo.RegionName, e.Message, e.StackTrace);
}
EventManager.TriggerRegionHeartbeatEnd(this);
maintc = Util.EnvironmentTickCountSubtract(maintc);
maintc = (int)(MinFrameTime * 1000) - maintc;
if (maintc > 0)
Thread.Sleep(maintc);
// Tell the watchdog that this thread is still alive
Watchdog.UpdateThread();
}
public void AddGroupTarget(SceneObjectGroup grp)

View File

@@ -149,9 +149,13 @@ namespace OpenSim.Region.Framework.Scenes
#region Update Methods
/// <summary>
/// Normally called once every frame/tick to let the world preform anything required (like running the physics simulation)
/// Called to update the scene loop by a number of frames and until shutdown.
/// </summary>
public abstract void Update();
/// <param name="frames">
/// Number of frames to update. Exits on shutdown even if there are frames remaining.
/// If -1 then updates until shutdown.
/// </param>
public abstract void Update(int frames);
#endregion

View File

@@ -2293,7 +2293,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (direc.Z > 2.0f)
{
direc.Z *= 3.0f;
direc.Z *= 2.6f;
// TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
Animator.TrySetMovementAnimation("PREJUMP");

View File

@@ -81,7 +81,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
// For now, we'll make the scene presence fly to simplify this test, but this needs to change.
sp.Flying = true;
m_scene.Update();
m_scene.Update(1);
Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
Vector3 targetPos = startPos + new Vector3(0, 10, 0);
@@ -91,7 +91,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(
sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
m_scene.Update();
m_scene.Update(1);
// We should really check the exact figure.
Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X));
@@ -99,8 +99,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X));
for (int i = 0; i < 10; i++)
m_scene.Update();
m_scene.Update(10);
double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move");
@@ -116,7 +115,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(
sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
m_scene.Update();
m_scene.Update(1);
// We should really check the exact figure.
Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X));
@@ -124,8 +123,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
for (int i = 0; i < 10; i++)
m_scene.Update();
m_scene.Update(10);
distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move");

View File

@@ -63,17 +63,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Thread testThread = new Thread(testClass.run);
try
{
// Seems kind of redundant to start a thread and then join it, however.. We need to protect against
// A thread abort exception in the simulator code.
testThread.Start();
testThread.Join();
}
catch (ThreadAbortException)
{
}
// Seems kind of redundant to start a thread and then join it, however.. We need to protect against
// A thread abort exception in the simulator code.
testThread.Start();
testThread.Join();
Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message);
// Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod());
}

View File

@@ -61,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
TestHelpers.InMethod();
Scene scene = SceneHelpers.SetupScene();
scene.Update();
scene.Update(1);
Assert.That(scene.Frame, Is.EqualTo(1));
}

View File

@@ -238,7 +238,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
// For now, we'll make the scene presence fly to simplify this test, but this needs to change.
npc.Flying = true;
m_scene.Update();
m_scene.Update(1);
Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
Vector3 targetPos = startPos + new Vector3(0, 10, 0);
@@ -249,7 +249,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Assert.That(
npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
m_scene.Update();
m_scene.Update(1);
// We should really check the exact figure.
Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X));
@@ -257,8 +257,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X));
for (int i = 0; i < 10; i++)
m_scene.Update();
m_scene.Update(10);
double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move");
@@ -275,7 +274,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Assert.That(
npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
m_scene.Update();
m_scene.Update(1);
// We should really check the exact figure.
Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X));
@@ -283,8 +282,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
for (int i = 0; i < 10; i++)
m_scene.Update();
m_scene.Update(10);
distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move");

View File

@@ -358,7 +358,7 @@ namespace OpenSim.Region.Physics.Meshing
if (physicsParms == null)
{
m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset");
m_log.WarnFormat("[MESH]: No recognized physics mesh found in mesh asset for {0}", primName);
return false;
}

View File

@@ -114,6 +114,11 @@ namespace OpenSim.Region.Physics.OdePlugin
private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes.
/// <summary>
/// Base movement for calculating tilt.
/// </summary>
private float m_tiltBaseMovement = (float)Math.Sqrt(2);
/// <summary>
/// Used to introduce a fixed tilt because a straight-up capsule falls through terrain, probably a bug in terrain collider
/// </summary>
@@ -524,14 +529,14 @@ namespace OpenSim.Region.Physics.OdePlugin
if (movementVector.Y > 0)
{
// northeast
movementVector.X = (float)Math.Sqrt(2.0);
movementVector.Y = (float)Math.Sqrt(2.0);
movementVector.X = m_tiltBaseMovement;
movementVector.Y = m_tiltBaseMovement;
}
else
{
// southeast
movementVector.X = (float)Math.Sqrt(2.0);
movementVector.Y = -(float)Math.Sqrt(2.0);
movementVector.X = m_tiltBaseMovement;
movementVector.Y = -m_tiltBaseMovement;
}
}
else
@@ -540,14 +545,14 @@ namespace OpenSim.Region.Physics.OdePlugin
if (movementVector.Y > 0)
{
// northwest
movementVector.X = -(float)Math.Sqrt(2.0);
movementVector.Y = (float)Math.Sqrt(2.0);
movementVector.X = -m_tiltBaseMovement;
movementVector.Y = m_tiltBaseMovement;
}
else
{
// southwest
movementVector.X = -(float)Math.Sqrt(2.0);
movementVector.Y = -(float)Math.Sqrt(2.0);
movementVector.X = -m_tiltBaseMovement;
movementVector.Y = -m_tiltBaseMovement;
}
}

View File

@@ -842,17 +842,23 @@ namespace OpenSim.Region.Physics.OdePlugin
mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
if (m_MeshToTriMeshMap.ContainsKey(mesh))
{
_triMeshData = m_MeshToTriMeshMap[mesh];
}
else
{
_triMeshData = d.GeomTriMeshDataCreate();
d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
d.GeomTriMeshDataPreprocess(_triMeshData);
m_MeshToTriMeshMap[mesh] = _triMeshData;
// We must lock here since m_MeshToTriMeshMap is static and multiple scene threads may call this method at
// the same time.
lock (m_MeshToTriMeshMap)
{
if (m_MeshToTriMeshMap.ContainsKey(mesh))
{
_triMeshData = m_MeshToTriMeshMap[mesh];
}
else
{
_triMeshData = d.GeomTriMeshDataCreate();
d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
d.GeomTriMeshDataPreprocess(_triMeshData);
m_MeshToTriMeshMap[mesh] = _triMeshData;
}
}
// _parent_scene.waitForSpaceUnlock(m_targetSpace);

View File

@@ -181,8 +181,15 @@ namespace OpenSim.Region.Physics.OdePlugin
private float avPIDP = 1400f;
private float avCapRadius = 0.37f;
private float avStandupTensor = 2000000f;
private bool avCapsuleTilted = true; // true = old compatibility mode with leaning capsule; false = new corrected mode
public bool IsAvCapsuleTilted { get { return avCapsuleTilted; } set { avCapsuleTilted = value; } }
/// <summary>
/// true = old compatibility mode with leaning capsule; false = new corrected mode
/// </summary>
/// <remarks>
/// Even when set to false, the capsule still tilts but this is done in a different way.
/// </remarks>
public bool IsAvCapsuleTilted { get; private set; }
private float avDensity = 80f;
// private float avHeightFudgeFactor = 0.52f;
private float avMovementDivisorWalk = 1.3f;
@@ -501,7 +508,7 @@ namespace OpenSim.Region.Physics.OdePlugin
avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f);
avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f);
avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f);
avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false);
IsAvCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false);
contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80);

View File

@@ -401,16 +401,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine
// sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count);
SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this);
sb.AppendFormat("Sensors : {0}\n", sr.SensorsCount);
sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0);
Dataserver ds = AsyncCommandManager.GetDataserverPlugin(this);
sb.AppendFormat("Dataserver requests : {0}\n", ds.DataserverRequestsCount);
sb.AppendFormat("Dataserver requests : {0}\n", ds != null ? ds.DataserverRequestsCount : 0);
Timer t = AsyncCommandManager.GetTimerPlugin(this);
sb.AppendFormat("Timers : {0}\n", t.TimersCount);
sb.AppendFormat("Timers : {0}\n", t != null ? t.TimersCount : 0);
Listener l = AsyncCommandManager.GetListenerPlugin(this);
sb.AppendFormat("Listeners : {0}\n", l.ListenerCount);
sb.AppendFormat("Listeners : {0}\n", l != null ? l.ListenerCount : 0);
return sb.ToString();
}