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

0.8.0.3
Justin Clark-Casey (justincc) 2014-03-11 23:39:07 +00:00
commit 86630a1b70
7 changed files with 150 additions and 72 deletions

View File

@ -114,6 +114,7 @@ what it is today.
* Kitto Flora
* KittyLiu
* Kurt Taylor (IBM)
* Lani Global
* lkalif
* lulurun
* M.Igarashi

View File

@ -50,8 +50,9 @@ namespace OpenSim.Framework
// Someday terrain will have caves
public abstract float this[int x, int y, int z] { get; set; }
public bool IsTainted { get; protected set; }
public abstract bool IsTaintedAt(int xx, int yy);
public abstract bool IsTaintedAt(int xx, int yy, bool clearOnTest);
public abstract void TaintAllTerrain();
public abstract void ClearTaint();
public abstract void ClearLand();
@ -75,6 +76,7 @@ namespace OpenSim.Framework
public abstract short[] GetCompressedMap();
public abstract float CompressionFactor { get; }
public abstract float[] GetFloatsSerialized();
public abstract double[,] GetDoubles();
public abstract TerrainData Clone();
}
@ -138,10 +140,20 @@ namespace OpenSim.Framework
// TerrainData.ClearTaint
public override void ClearTaint()
{
IsTainted = false;
SetAllTaint(false);
}
// TerrainData.TaintAllTerrain
public override void TaintAllTerrain()
{
SetAllTaint(true);
}
private void SetAllTaint(bool setting)
{
for (int ii = 0; ii < m_taint.GetLength(0); ii++)
for (int jj = 0; jj < m_taint.GetLength(1); jj++)
m_taint[ii, jj] = false;
m_taint[ii, jj] = setting;
}
// TerrainData.ClearLand
@ -158,15 +170,25 @@ namespace OpenSim.Framework
m_heightmap[xx, yy] = flatHeight;
}
public override bool IsTaintedAt(int xx, int yy)
// Return 'true' of the patch that contains these region coordinates has been modified.
// Note that checking the taint clears it.
// There is existing code that relies on this feature.
public override bool IsTaintedAt(int xx, int yy, bool clearOnTest)
{
int tx = xx / Constants.TerrainPatchSize;
int ty = yy / Constants.TerrainPatchSize;
bool ret = m_taint[tx, ty];
m_taint[tx, ty] = false;
if (ret && clearOnTest)
m_taint[tx, ty] = false;
return ret;
}
// Old form that clears the taint flag when we check it.
public override bool IsTaintedAt(int xx, int yy)
{
return IsTaintedAt(xx, yy, true /* clearOnTest */);
}
// TerrainData.GetDatabaseBlob
// The user wants something to store in the database.
public override bool GetDatabaseBlob(out int DBRevisionCode, out Array blob)
@ -212,6 +234,25 @@ namespace OpenSim.Framework
return ret;
}
// TerrainData.GetFloatsSerialized
// This one dimensional version is ordered so height = map[y*sizeX+x];
// DEPRECATED: don't use this function as it does not retain the dimensions of the terrain
// and the caller will probably do the wrong thing if the terrain is not the legacy 256x256.
public override float[] GetFloatsSerialized()
{
int points = SizeX * SizeY;
float[] heights = new float[points];
int idx = 0;
for (int jj = 0; jj < SizeY; jj++)
for (int ii = 0; ii < SizeX; ii++)
{
heights[idx++] = FromCompressedHeight(m_heightmap[ii, jj]);
}
return heights;
}
// TerrainData.GetDoubles
public override double[,] GetDoubles()
{

View File

@ -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
{

View File

@ -124,17 +124,7 @@ namespace OpenSim.Region.Framework.Scenes
// and the caller will probably do the wrong thing if the terrain is not the legacy 256x256.
public float[] GetFloatsSerialised()
{
int points = Width * Height;
float[] heights = new float[points];
int idx = 0;
for (int jj = 0; jj < Height; jj++)
for (int ii = 0; ii < Width; ii++)
{
heights[idx++] = m_terrainData[ii, jj];
}
return heights;
return m_terrainData.GetFloatsSerialized();
}
// ITerrainChannel.GetDoubles()

View File

@ -113,15 +113,15 @@
;; NonPhysicalPrimMax!).
; NonPhysicalPrimMax = 256
;# {PhysicalPrimMin} {} {Minimum size of physical prims?} {} 10
;# {PhysicalPrimMin} {} {Minimum size of physical prims?} {} 0.01
;; Maximum size where a prim can be physical. Affects resizing of
;; existing prims. This can be overriden in the region config file.
; PhysicalPrimMin = 0.01
;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10
;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 64
;; Maximum size where a prim can be physical. Affects resizing of
;; existing prims. This can be overriden in the region config file.
; PhysicalPrimMax = 10
; PhysicalPrimMax = 64
;# {ClampPrimSize} {} {Clamp viewer rezzed prims to max sizes?} {true false} false
;; If a viewer attempts to rez a prim larger than the non-physical or

View File

@ -97,7 +97,7 @@
NonPhysicalPrimMax = 256
; Maximum size of physical prims. Affects resizing of existing prims. This can be overriden in the region config file.
PhysicalPrimMax = 10
PhysicalPrimMax = 64
; If a viewer attempts to rez a prim larger than the non-physical or physical prim max, clamp the dimensions to the appropriate maximum
; This can be overriden in the region config file.

View File

@ -29,7 +29,7 @@ ExternalHostName = "SYSTEMIP"
; *
; NonphysicalPrimMax = 256
; PhysicalPrimMax = 10
; PhysicalPrimMax = 64
; ClampPrimSize = False
; MaxPrims = 15000
; MaxAgents = 100