mirror of
https://github.com/opensim/opensim.git
synced 2026-08-09 18:55:58 +08:00
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
This commit is contained in:
@@ -149,8 +149,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
|
||||
m_scene.RegisterModuleInterface<ITerrainModule>(this);
|
||||
m_scene.EventManager.OnNewClient += EventManager_OnNewClient;
|
||||
m_scene.EventManager.OnClientClosed += EventManager_OnClientClosed;
|
||||
m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
|
||||
m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick;
|
||||
m_scene.EventManager.OnFrame += EventManager_OnFrame;
|
||||
}
|
||||
|
||||
InstallDefaultEffects();
|
||||
@@ -189,8 +191,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
// remove the commands
|
||||
m_scene.UnregisterModuleCommander(m_commander.Name);
|
||||
// remove the event-handlers
|
||||
m_scene.EventManager.OnFrame -= EventManager_OnFrame;
|
||||
m_scene.EventManager.OnTerrainTick -= EventManager_OnTerrainTick;
|
||||
m_scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole;
|
||||
m_scene.EventManager.OnClientClosed -= EventManager_OnClientClosed;
|
||||
m_scene.EventManager.OnNewClient -= EventManager_OnNewClient;
|
||||
// remove the interface
|
||||
m_scene.UnregisterModuleInterface<ITerrainModule>(this);
|
||||
@@ -266,7 +270,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
String.Format("Unable to load heightmap: {0}", e.Message));
|
||||
}
|
||||
}
|
||||
CheckForTerrainUpdates();
|
||||
m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully");
|
||||
return;
|
||||
}
|
||||
@@ -347,7 +350,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
}
|
||||
}
|
||||
|
||||
CheckForTerrainUpdates();
|
||||
m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully");
|
||||
return;
|
||||
}
|
||||
@@ -418,7 +420,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
|
||||
public void TaintTerrain ()
|
||||
{
|
||||
CheckForTerrainUpdates();
|
||||
m_channel.GetTerrainData().TaintAllTerrain();
|
||||
}
|
||||
|
||||
#region Plugin Loading Methods
|
||||
@@ -646,8 +648,40 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
m_scene.RegionInfo.RegionName, filename, m_supportFileExtensionsForTileSave);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called before processing of every simulation frame.
|
||||
/// This is used to check to see of any of the terrain is tainted and, if so, schedule
|
||||
/// updates for all the presences.
|
||||
/// This also checks to see if there are updates that need to be sent for each presence.
|
||||
/// This is where the logic is to send terrain updates to clients.
|
||||
/// </summary>
|
||||
private void EventManager_OnFrame()
|
||||
{
|
||||
TerrainData terrData = m_channel.GetTerrainData();
|
||||
|
||||
bool shouldTaint = false;
|
||||
for (int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize)
|
||||
{
|
||||
for (int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize)
|
||||
{
|
||||
if (terrData.IsTaintedAt(x, y))
|
||||
{
|
||||
// Found a patch that was modified. Push this flag into the clients.
|
||||
SendToClients(terrData, x, y);
|
||||
shouldTaint = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shouldTaint)
|
||||
{
|
||||
m_scene.EventManager.TriggerTerrainTainted();
|
||||
m_tainted = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs updates to the region periodically, synchronising physics and other heightmap aware sections
|
||||
/// Called infrequently (like every 5 seconds or so). Best used for storing terrain.
|
||||
/// </summary>
|
||||
private void EventManager_OnTerrainTick()
|
||||
{
|
||||
@@ -697,6 +731,22 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
client.OnUnackedTerrain += client_OnUnackedTerrain;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Installs terrain brush hook to IClientAPI
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
private void EventManager_OnClientClosed(UUID client, Scene scene)
|
||||
{
|
||||
ScenePresence presence = scene.GetScenePresence(client);
|
||||
if (presence != null)
|
||||
{
|
||||
presence.ControllingClient.OnModifyTerrain -= client_OnModifyTerrain;
|
||||
presence.ControllingClient.OnBakeTerrain -= client_OnBakeTerrain;
|
||||
presence.ControllingClient.OnLandUndo -= client_OnLandUndo;
|
||||
presence.ControllingClient.OnUnackedTerrain -= client_OnUnackedTerrain;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the terrain has been modified since last check
|
||||
/// but won't attempt to limit those changes to the limits specified in the estate settings
|
||||
@@ -717,36 +767,32 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
/// </summary>
|
||||
private void CheckForTerrainUpdates(bool respectEstateSettings)
|
||||
{
|
||||
bool shouldTaint = false;
|
||||
float[] terrHeights = m_channel.GetFloatsSerialised();
|
||||
int x;
|
||||
for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scan over changes in the terrain and limit height changes. This enforces the
|
||||
/// non-estate owner limits on rate of terrain editting.
|
||||
/// Returns 'true' if any heights were limited.
|
||||
/// </summary>
|
||||
private bool EnforceEstateLimits()
|
||||
{
|
||||
TerrainData terrData = m_channel.GetTerrainData();
|
||||
|
||||
bool wasLimited = false;
|
||||
for (int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize)
|
||||
{
|
||||
int y;
|
||||
for (y = 0; y < m_channel.Height; y += Constants.TerrainPatchSize)
|
||||
for (int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize)
|
||||
{
|
||||
if (m_channel.Tainted(x, y))
|
||||
{
|
||||
if (terrData.IsTaintedAt(x, y, false /* clearOnTest */))
|
||||
{
|
||||
// If we should respect the estate settings then
|
||||
// fixup and height deltas that don't respect them.
|
||||
// Note that LimitChannelChanges() modifies the TerrainChannel with the limited height values.
|
||||
if (respectEstateSettings && LimitChannelChanges(x, y))
|
||||
{
|
||||
// Terrain heights were modified. Refetch the terrain info.
|
||||
terrHeights = m_channel.GetFloatsSerialised();
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("{0} Patch modified. Sending (x,y) = ({1},{2})", LogHeader, x, y);
|
||||
SendToClients(terrHeights, x, y);
|
||||
shouldTaint = true;
|
||||
wasLimited |= LimitChannelChanges(terrData, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shouldTaint)
|
||||
{
|
||||
m_scene.EventManager.TriggerTerrainTainted();
|
||||
m_tainted = true;
|
||||
}
|
||||
return wasLimited;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -754,11 +800,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
/// are all within the current estate limits
|
||||
/// <returns>true if changes were limited, false otherwise</returns>
|
||||
/// </summary>
|
||||
private bool LimitChannelChanges(int xStart, int yStart)
|
||||
private bool LimitChannelChanges(TerrainData terrData, int xStart, int yStart)
|
||||
{
|
||||
bool changesLimited = false;
|
||||
double minDelta = m_scene.RegionInfo.RegionSettings.TerrainLowerLimit;
|
||||
double maxDelta = m_scene.RegionInfo.RegionSettings.TerrainRaiseLimit;
|
||||
float minDelta = (float)m_scene.RegionInfo.RegionSettings.TerrainLowerLimit;
|
||||
float maxDelta = (float)m_scene.RegionInfo.RegionSettings.TerrainRaiseLimit;
|
||||
|
||||
// loop through the height map for this patch and compare it against
|
||||
// the revert map
|
||||
@@ -766,19 +812,18 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
{
|
||||
for (int y = yStart; y < yStart + Constants.TerrainPatchSize; y++)
|
||||
{
|
||||
|
||||
double requestedHeight = m_channel[x, y];
|
||||
double bakedHeight = m_revert[x, y];
|
||||
double requestedDelta = requestedHeight - bakedHeight;
|
||||
float requestedHeight = terrData[x, y];
|
||||
float bakedHeight = (float)m_revert[x, y];
|
||||
float requestedDelta = requestedHeight - bakedHeight;
|
||||
|
||||
if (requestedDelta > maxDelta)
|
||||
{
|
||||
m_channel[x, y] = bakedHeight + maxDelta;
|
||||
terrData[x, y] = bakedHeight + maxDelta;
|
||||
changesLimited = true;
|
||||
}
|
||||
else if (requestedDelta < minDelta)
|
||||
{
|
||||
m_channel[x, y] = bakedHeight + minDelta; //as lower is a -ve delta
|
||||
terrData[x, y] = bakedHeight + minDelta; //as lower is a -ve delta
|
||||
changesLimited = true;
|
||||
}
|
||||
}
|
||||
@@ -806,11 +851,18 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
/// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param>
|
||||
/// <param name="x">The patch corner to send</param>
|
||||
/// <param name="y">The patch corner to send</param>
|
||||
private void SendToClients(float[] heightMap, int x, int y)
|
||||
private void SendToClients(TerrainData terrData, int x, int y)
|
||||
{
|
||||
// We know the actual terrain data passed is ignored. This kludge saves changing IClientAPI.
|
||||
//float[] heightMap = terrData.GetFloatsSerialized();
|
||||
float[] heightMap = new float[10];
|
||||
m_scene.ForEachClient(
|
||||
delegate(IClientAPI controller)
|
||||
{ controller.SendLayerData( x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, heightMap); }
|
||||
{
|
||||
controller.SendLayerData( x / Constants.TerrainPatchSize,
|
||||
y / Constants.TerrainPatchSize,
|
||||
heightMap);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -856,7 +908,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
m_painteffects[(StandardTerrainEffects) action].PaintEffect(
|
||||
m_channel, allowMask, west, south, height, size, seconds);
|
||||
|
||||
CheckForTerrainUpdates(!god); //revert changes outside estate limits
|
||||
//revert changes outside estate limits
|
||||
if (!god)
|
||||
EnforceEstateLimits();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -897,7 +951,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
m_floodeffects[(StandardTerrainEffects) action].FloodEffect(
|
||||
m_channel, fillArea, size);
|
||||
|
||||
CheckForTerrainUpdates(!god); //revert changes outside estate limits
|
||||
//revert changes outside estate limits
|
||||
if (!god)
|
||||
EnforceEstateLimits();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -921,7 +977,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
protected void client_OnUnackedTerrain(IClientAPI client, int patchX, int patchY)
|
||||
{
|
||||
//m_log.Debug("Terrain packet unacked, resending patch: " + patchX + " , " + patchY);
|
||||
client.SendLayerData(patchX, patchY, m_scene.Heightmap.GetFloatsSerialised());
|
||||
// SendLayerData does not use the heightmap parameter. This kludge is so as to not change IClientAPI.
|
||||
float[] heightMap = new float[10];
|
||||
client.SendLayerData(patchX, patchY, heightMap);
|
||||
}
|
||||
|
||||
private void StoreUndoState()
|
||||
@@ -948,7 +1006,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
private void InterfaceLoadFile(Object[] args)
|
||||
{
|
||||
LoadFromFile((string) args[0]);
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceLoadTileFile(Object[] args)
|
||||
@@ -958,7 +1015,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
(int) args[2],
|
||||
(int) args[3],
|
||||
(int) args[4]);
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceSaveFile(Object[] args)
|
||||
@@ -987,7 +1043,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
for (y = 0; y < m_channel.Height; y++)
|
||||
m_channel[x, y] = m_revert[x, y];
|
||||
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceFlipTerrain(Object[] args)
|
||||
@@ -1028,7 +1083,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
}
|
||||
|
||||
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceRescaleTerrain(Object[] args)
|
||||
@@ -1086,7 +1140,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
}
|
||||
}
|
||||
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1097,7 +1150,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
for (x = 0; x < m_channel.Width; x++)
|
||||
for (y = 0; y < m_channel.Height; y++)
|
||||
m_channel[x, y] += (double) args[0];
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceMultiplyTerrain(Object[] args)
|
||||
@@ -1106,7 +1158,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
for (x = 0; x < m_channel.Width; x++)
|
||||
for (y = 0; y < m_channel.Height; y++)
|
||||
m_channel[x, y] *= (double) args[0];
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceLowerTerrain(Object[] args)
|
||||
@@ -1115,7 +1166,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
for (x = 0; x < m_channel.Width; x++)
|
||||
for (y = 0; y < m_channel.Height; y++)
|
||||
m_channel[x, y] -= (double) args[0];
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceFillTerrain(Object[] args)
|
||||
@@ -1125,7 +1175,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
for (x = 0; x < m_channel.Width; x++)
|
||||
for (y = 0; y < m_channel.Height; y++)
|
||||
m_channel[x, y] = (double) args[0];
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceMinTerrain(Object[] args)
|
||||
@@ -1138,7 +1187,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
m_channel[x, y] = Math.Max((double)args[0], m_channel[x, y]);
|
||||
}
|
||||
}
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceMaxTerrain(Object[] args)
|
||||
@@ -1151,7 +1199,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
m_channel[x, y] = Math.Min((double)args[0], m_channel[x, y]);
|
||||
}
|
||||
}
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceShowDebugStats(Object[] args)
|
||||
@@ -1214,7 +1261,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
if (m_plugineffects.ContainsKey(firstArg))
|
||||
{
|
||||
m_plugineffects[firstArg].RunEffect(m_channel);
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user