terraforming changes: make sliders work, remove some brushs, etc. Feedback needed (run prebuild)

0.9.1.1
UbitUmarov 2019-11-09 23:59:19 +00:00
parent 4b5a3308ad
commit 53339d2970
30 changed files with 160 additions and 1184 deletions

View File

@ -60,9 +60,8 @@ namespace OpenSim.Framework
public delegate void ObjectAttach( public delegate void ObjectAttach(
IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent); IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent);
public delegate void ModifyTerrain(UUID user, public delegate void ModifyTerrain(UUID user, float height, float seconds, float brushSize,
float height, float seconds, byte size, byte action, float north, float west, float south, float east, byte action, float north, float west, float south, float east);
UUID agentId);
public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes);

View File

@ -5153,7 +5153,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int count = 0; int count = 0;
EntityUpdate eu; EntityUpdate eu;
for(int indx = 0; indx < objectUpdates.Count;++indx) for(int indx = 0; indx < objectUpdates.Count; ++indx)
{ {
eu = objectUpdates[indx]; eu = objectUpdates[indx];
lastpos = zc.Position; lastpos = zc.Position;
@ -8971,34 +8971,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool HandlerModifyLand(IClientAPI sender, Packet Pack) private bool HandlerModifyLand(IClientAPI sender, Packet Pack)
{ {
if (OnModifyTerrain == null)
return true;
ModifyLandPacket modify = (ModifyLandPacket)Pack; ModifyLandPacket modify = (ModifyLandPacket)Pack;
#region Packet Session and User Check if (modify.ParcelData.Length == 0)
if (modify.AgentData.SessionID != SessionId ||
modify.AgentData.AgentID != AgentId)
return true; return true;
#region Packet Session and User Check
if (modify.AgentData.SessionID != SessionId || modify.AgentData.AgentID != AgentId)
return true;
#endregion #endregion
//m_log.Info("[LAND]: LAND:" + modify.ToString()); //m_log.Info("[LAND]: LAND:" + modify.ToString());
if (modify.ParcelData.Length > 0) for (int i = 0; i < modify.ParcelData.Length; i++)
{ {
// Note: the ModifyTerrain event handler sends out updated packets before the end of this event. Therefore, OnModifyTerrain?.Invoke(AgentId, modify.ModifyBlock.Height, modify.ModifyBlock.Seconds,
// a simple boolean value should work and perhaps queue up just a few terrain patch packets at the end of the edit. modify.ModifyBlockExtended[i].BrushSize, modify.ModifyBlock.Action,
if (OnModifyTerrain != null) modify.ParcelData[i].North, modify.ParcelData[i].West,
{ modify.ParcelData[i].South, modify.ParcelData[i].East);
for (int i = 0; i < modify.ParcelData.Length; i++)
{
ModifyTerrain handlerModifyTerrain = OnModifyTerrain;
if (handlerModifyTerrain != null)
{
handlerModifyTerrain(AgentId, modify.ModifyBlock.Height, modify.ModifyBlock.Seconds,
modify.ModifyBlock.BrushSize,
modify.ModifyBlock.Action, modify.ParcelData[i].North,
modify.ParcelData[i].West, modify.ParcelData[i].South,
modify.ParcelData[i].East, AgentId);
}
}
}
} }
return true; return true;

View File

@ -64,7 +64,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Effects
for (int i = 0; i < rounds; i++) for (int i = 0; i < rounds; i++)
{ {
smoothFunction.FloodEffect(map, bitmap, 1.0, 0, map.Width - 1, 0, map.Height - 1); smoothFunction.FloodEffect(map, bitmap, -1f, 1.0f, 0, map.Width - 1, 0, map.Height - 1);
} }
} }
@ -99,7 +99,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Effects
} }
} }
raiseFunction.FloodEffect(map, bitmap, height, 0, map.Width - 1, 0, map.Height - 1); raiseFunction.FloodEffect(map, bitmap, -1f,(float)height, 0, map.Width - 1, 0, map.Height - 1);
} }
} }
} }

View File

@ -1,129 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenSim.Region.CoreModules.World.Terrain.PaintBrushes;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using log4net;
using System.Reflection;
namespace OpenSim.Region.CoreModules.World.Terrain.Effects
{
internal class CookieCutter : ITerrainEffect
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region ITerrainEffect Members
public void RunEffect(ITerrainChannel map)
{
ITerrainPaintableEffect eroder = new WeatherSphere();
bool[,] cliffMask = new bool[map.Width,map.Height];
bool[,] channelMask = new bool[map.Width,map.Height];
bool[,] smoothMask = new bool[map.Width,map.Height];
bool[,] allowMask = new bool[map.Width,map.Height];
m_log.Info("S1");
// Step one, generate rough mask
int x, y;
for (x = 0; x < map.Width; x++)
{
for (y = 0; y < map.Height; y++)
{
m_log.Info(".");
smoothMask[x, y] = true;
allowMask[x,y] = true;
// Start underwater
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 5;
// Add a little height. (terrain should now be above water, mostly.)
map[x, y] += 20;
const int channelsX = 4;
int channelWidth = (map.Width / channelsX / 4);
const int channelsY = 4;
int channelHeight = (map.Height / channelsY / 4);
SetLowerChannel(map, cliffMask, channelMask, x, y, channelsX, channelWidth, map.Width, x);
SetLowerChannel(map, cliffMask, channelMask, x, y, channelsY, channelHeight, map.Height, y);
}
}
m_log.Info("S2");
//smooth.FloodEffect(map, smoothMask, 4.0);
m_log.Info("S3");
for (x = 0; x < map.Width; x++)
{
for (y = 0; y < map.Height; y++)
{
if (cliffMask[x, y])
eroder.PaintEffect(map, allowMask, x, y, -1, 4, 0.1,0,map.Width - 1,0,map.Height - 1);
}
}
for (x = 0; x < map.Width; x += 2)
{
for (y = 0; y < map.Height; y += 2)
{
if (map[x, y] < 0.1)
map[x, y] = 0.1;
if (map[x, y] > 256)
map[x, y] = 256;
}
}
//smooth.FloodEffect(map, smoothMask, 4.0);
}
#endregion
private static void SetLowerChannel(ITerrainChannel map, bool[,] cliffMask, bool[,] channelMask, int x, int y, int numChannels, int channelWidth,
int mapSize, int rp)
{
for (int i = 0; i < numChannels; i++)
{
double distanceToLine = Math.Abs(rp - ((mapSize / numChannels) * i));
if (distanceToLine < channelWidth)
{
if (channelMask[x, y])
return;
// Remove channels
map[x, y] -= 10;
channelMask[x, y] = true;
}
if (distanceToLine < 1)
{
cliffMask[x, y] = true;
}
}
}
}
}

View File

@ -30,23 +30,27 @@ using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.CoreModules.World.Terrain.Effects namespace OpenSim.Region.CoreModules.World.Terrain.Effects
{ {
internal class DefaultTerrainGenerator : ITerrainEffect public class DefaultTerrainGenerator : ITerrainEffect
{ {
#region ITerrainEffect Members #region ITerrainEffect Members
public void RunEffect(ITerrainChannel map) public void RunEffect(ITerrainChannel map)
{ {
int x, y; int x, y;
int cx = map.Width / 2;
int cy = map.Height / 2;
float h;
float b;
for (x = 0; x < map.Width; x++) for (x = 0; x < map.Width; x++)
{ {
for (y = 0; y < map.Height; y++) for (y = 0; y < map.Height; y++)
{ {
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10; h = 25 * TerrainUtil.SphericalFactor(x - cx, y - cy, 50);
double spherFac = TerrainUtil.SphericalFactor(x, y, map.Width / 2, map.Height / 2, 50) * 0.01; b = 10 * TerrainUtil.SphericalFactor(x - cx, y - cy, 100);
if (map[x, y] < spherFac) if (h < b)
{ h = b;
map[x, y] = spherFac; map[x, y] = h;
}
} }
} }
} }

View File

@ -33,35 +33,20 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
{ {
#region ITerrainFloodEffect Members #region ITerrainFloodEffect Members
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength, public void FloodEffect(ITerrainChannel map, bool[,] fillArea, float height, float strength,
int startX, int endX, int startY, int endY) int startX, int endX, int startY, int endY)
{ {
double sum = 0.0;
double steps = 0.0;
int x, y; strength *= 0.04f;
for (x = startX; x <= endX; x++) if(strength > 1.0f)
strength = 1.0f;
for (int x = startX; x <= endX; x++)
{ {
for (y = startY; y <= endY; y++) for (int y = startY; y <= endY; y++)
{ {
if (fillArea[x, y]) if (fillArea[x, y])
{ map[x, y] = (map[x, y] * (1.0 - strength)) + (height * strength);
sum += map[x, y];
steps += 1.0;
}
}
}
double avg = sum / steps;
double str = 0.1 * strength; // == 0.2 in the default client
for (x = startX; x <= endX; x++)
{
for (y = startY; y <= endY; y++)
{
if (fillArea[x, y])
map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str);
} }
} }
} }

View File

@ -33,7 +33,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
{ {
#region ITerrainFloodEffect Members #region ITerrainFloodEffect Members
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength, public void FloodEffect(ITerrainChannel map, bool[,] fillArea, float height, float strength,
int startX, int endX, int startY, int endY) int startX, int endX, int startY, int endY)
{ {
int x,y; int x,y;
@ -44,6 +44,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
if (fillArea[x, y]) if (fillArea[x, y])
{ {
map[x, y] -= strength; map[x, y] -= strength;
if (map[x, y] < -100f)
map[x, y] = -100f;
} }
} }
} }

View File

@ -35,9 +35,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
{ {
#region ITerrainFloodEffect Members #region ITerrainFloodEffect Members
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength, public void FloodEffect(ITerrainChannel map, bool[,] fillArea, float height, float strength,
int startX, int endX, int startY, int endY) int startX, int endX, int startY, int endY)
{ {
strength *= 0.08f;
int x, y; int x, y;
for (x = startX; x <= endX; x++) for (x = startX; x <= endX; x++)
{ {

View File

@ -33,7 +33,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
{ {
#region ITerrainFloodEffect Members #region ITerrainFloodEffect Members
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength, public void FloodEffect(ITerrainChannel map, bool[,] fillArea, float height, float strength,
int startX, int endX, int startY, int endY) int startX, int endX, int startY, int endY)
{ {
int x,y; int x,y;

View File

@ -46,17 +46,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
/// <param name="map">the current heightmap</param> /// <param name="map">the current heightmap</param>
/// <param name="fillArea">array indicating which sections of the map are to be reverted</param> /// <param name="fillArea">array indicating which sections of the map are to be reverted</param>
/// <param name="strength">unused</param> /// <param name="strength">unused</param>
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength, public void FloodEffect(ITerrainChannel map, bool[,] fillArea, float height, float strength,
int startX, int endX, int startY, int endY) int startX, int endX, int startY, int endY)
{ {
int x, y; int x, y;
strength *= 2f;
if (strength > 1.0f)
strength = 1.0f;
for (x = startX; x <= endX; x++) for (x = startX; x <= endX; x++)
{ {
for (y = startY; y <= endY; y++) for (y = startY; y <= endY; y++)
{ {
if (fillArea[x, y]) if (fillArea[x, y])
{ {
map[x, y] = m_revertmap[x, y]; map[x, y] = map[x, y] * (1.0f - strength) + m_revertmap[x, y] * strength;
} }
} }
} }

View File

@ -33,11 +33,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
{ {
#region ITerrainFloodEffect Members #region ITerrainFloodEffect Members
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength, public void FloodEffect(ITerrainChannel map, bool[,] fillArea, float height, float strength,
int startX, int endX, int startY, int endY) int startX, int endX, int startY, int endY)
{ {
double area = strength; double area = 4;
double step = strength / 4.0; double step = 1;
strength *= 0.002f;
double[,] manipulate = new double[map.Width,map.Height]; double[,] manipulate = new double[map.Width,map.Height];
int x, y; int x, y;
@ -72,7 +74,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
if (!fillArea[x, y]) if (!fillArea[x, y])
continue; continue;
map[x, y] = manipulate[x, y]; map[x, y] = strength * manipulate[x, y];
} }
} }
} }

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenSim.Region.Framework.Interfaces;
namespace OpenSim.Region.CoreModules.World.Terrain
{
public interface ITerrainFeature
{
/// <summary>
/// Creates the feature.
/// </summary>
/// <returns>
/// Empty string if successful, otherwise error message.
/// </returns>
/// <param name='map'>
/// ITerrainChannel holding terrain data.
/// </param>
/// <param name='args'>
/// command-line arguments from console.
/// </param>
string CreateFeature(ITerrainChannel map, string[] args);
/// <summary>
/// Gets a string describing the usage.
/// </summary>
/// <returns>
/// A string describing parameters for creating the feature.
/// Format is "feature-name <arg1> <arg2> ..."
/// </returns>
string GetUsage();
}
}

View File

@ -32,7 +32,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
{ {
public interface ITerrainFloodEffect public interface ITerrainFloodEffect
{ {
void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, double strength, void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, float height, float strength,
int startX, int endX, int startY, int endY); int startX, int endX, int startY, int endY);
} }
} }

View File

@ -31,7 +31,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
{ {
public interface ITerrainPaintableEffect public interface ITerrainPaintableEffect
{ {
void PaintEffect(ITerrainChannel map, bool[,] allowMask, double x, double y, double z, void PaintEffect(ITerrainChannel map, bool[,] allowMask, float x, float y, float z,
double strength, double duration, int startX, int endX, int startY, int endY); float strength, float duration, int startX, int endX, int startY, int endY);
} }
} }

View File

@ -1,323 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
{
/// <summary>
/// Hydraulic Erosion Brush
/// </summary>
public class ErodeSphere : ITerrainPaintableEffect
{
private const double rainHeight = 0.2;
private const int rounds = 10;
private const NeighbourSystem type = NeighbourSystem.Moore;
private const double waterSaturation = 0.30;
#region Supporting Functions
private static int[] Neighbours(NeighbourSystem neighbourType, int index)
{
int[] coord = new int[2];
index++;
switch (neighbourType)
{
case NeighbourSystem.Moore:
switch (index)
{
case 1:
coord[0] = -1;
coord[1] = -1;
break;
case 2:
coord[0] = -0;
coord[1] = -1;
break;
case 3:
coord[0] = +1;
coord[1] = -1;
break;
case 4:
coord[0] = -1;
coord[1] = -0;
break;
case 5:
coord[0] = -0;
coord[1] = -0;
break;
case 6:
coord[0] = +1;
coord[1] = -0;
break;
case 7:
coord[0] = -1;
coord[1] = +1;
break;
case 8:
coord[0] = -0;
coord[1] = +1;
break;
case 9:
coord[0] = +1;
coord[1] = +1;
break;
default:
break;
}
break;
case NeighbourSystem.VonNeumann:
switch (index)
{
case 1:
coord[0] = 0;
coord[1] = -1;
break;
case 2:
coord[0] = -1;
coord[1] = 0;
break;
case 3:
coord[0] = +1;
coord[1] = 0;
break;
case 4:
coord[0] = 0;
coord[1] = +1;
break;
case 5:
coord[0] = -0;
coord[1] = -0;
break;
default:
break;
}
break;
}
return coord;
}
private enum NeighbourSystem
{
Moore,
VonNeumann
} ;
#endregion
#region ITerrainPaintableEffect Members
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
double strength, double duration, int startX, int endX, int startY, int endY)
{
strength = TerrainUtil.MetersToSphericalStrength(strength);
int x, y;
// Using one 'rain' round for this, so skipping a useless loop
// Will need to adapt back in for the Flood brush
ITerrainChannel water = new TerrainChannel(map.Width, map.Height);
ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height);
// Fill with rain
for (x = startX; x <= endX; x++)
{
for (y = startY; y <= endY; y++)
{
if (mask[x, y])
water[x, y] = Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration);
}
}
for (int i = 0; i < rounds; i++)
{
// Erode underlying terrain
for (x = startX; x <= endX; x++)
{
for (y = startY; y <= endY; y++)
{
if (mask[x, y])
{
const double solConst = (1.0 / rounds);
double sedDelta = water[x, y] * solConst;
map[x, y] -= sedDelta;
sediment[x, y] += sedDelta;
}
}
}
// Move water
for (x = startX; x <= endX; x++)
{
for (y = startY; y <= endY; y++)
{
if (water[x, y] <= 0)
continue;
// Step 1. Calculate average of neighbours
int neighbours = 0;
double altitudeTotal = 0.0;
double altitudeMe = map[x, y] + water[x, y];
const int NEIGHBOUR_ME = 4;
const int NEIGHBOUR_MAX = 9;
for (int j = 0; j < NEIGHBOUR_MAX; j++)
{
if (j != NEIGHBOUR_ME)
{
int[] coords = Neighbours(type, j);
coords[0] += x;
coords[1] += y;
if (coords[0] > map.Width - 1)
continue;
if (coords[1] > map.Height - 1)
continue;
if (coords[0] < 0)
continue;
if (coords[1] < 0)
continue;
// Calculate total height of this neighbour
double altitudeNeighbour = water[coords[0], coords[1]] + map[coords[0], coords[1]];
// If it's greater than me...
if (altitudeNeighbour - altitudeMe < 0)
{
// Add it to our calculations
neighbours++;
altitudeTotal += altitudeNeighbour;
}
}
}
if (neighbours == 0)
continue;
double altitudeAvg = altitudeTotal / neighbours;
// Step 2. Allocate water to neighbours.
for (int j = 0; j < NEIGHBOUR_MAX; j++)
{
if (j != NEIGHBOUR_ME)
{
int[] coords = Neighbours(type, j);
coords[0] += x;
coords[1] += y;
if (coords[0] > map.Width - 1)
continue;
if (coords[1] > map.Height - 1)
continue;
if (coords[0] < 0)
continue;
if (coords[1] < 0)
continue;
// Skip if we dont have water to begin with.
if (water[x, y] < 0)
continue;
// Calculate our delta average
double altitudeDelta = altitudeMe - altitudeAvg;
if (altitudeDelta < 0)
continue;
// Calculate how much water we can move
double waterMin = Math.Min(water[x, y], altitudeDelta);
double waterDelta = waterMin * ((water[coords[0], coords[1]] + map[coords[0], coords[1]])
/ altitudeTotal);
double sedimentDelta = sediment[x, y] * (waterDelta / water[x, y]);
if (sedimentDelta > 0)
{
sediment[x, y] -= sedimentDelta;
sediment[coords[0], coords[1]] += sedimentDelta;
}
}
}
}
}
// Evaporate
for (x = 0; x < water.Width; x++)
{
for (y = 0; y < water.Height; y++)
{
water[x, y] *= 1.0 - (rainHeight / rounds);
double waterCapacity = waterSaturation * water[x, y];
double sedimentDeposit = sediment[x, y] - waterCapacity;
if (sedimentDeposit > 0)
{
if (mask[x, y])
{
sediment[x, y] -= sedimentDeposit;
map[x, y] += sedimentDeposit;
}
}
}
}
}
// Deposit any remainder (should be minimal)
for (x = 0; x < water.Width; x++)
for (y = 0; y < water.Height; y++)
if (mask[x, y] && sediment[x, y] > 0)
map[x, y] += sediment[x, y];
}
#endregion
}
}

View File

@ -35,49 +35,29 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
{ {
#region ITerrainPaintableEffect Members #region ITerrainPaintableEffect Members
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, public void PaintEffect(ITerrainChannel map, bool[,] mask, float rx, float ry, float rz,
double strength, double duration, int startX, int endX, int startY, int endY) float size, float strength, int startX, int endX, int startY, int endY)
{ {
strength = TerrainUtil.MetersToSphericalStrength(strength);
int x, y; int x, y;
size *= 2;
float distancefactor;
// blend in map // blend in map
for (x = startX; x <= endX; x++) for (x = startX; x <= endX; ++x)
{ {
for (y = startY; y <= endY; y++) for (y = startY; y <= endY; ++y)
{ {
if (!mask[x,y]) if (!mask[x,y])
continue; continue;
double z; distancefactor = strength * TerrainUtil.SphericalFactor(x - rx, y - ry, size);
if (duration < 4.0)
{
z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * duration * 0.25;
}
else {
z = 1.0;
}
double delta = rz - map[x, y];
if (Math.Abs(delta) > 0.1)
{
if (z > 1.0)
{
z = 1.0;
}
else if (z < 0.0)
{
z = 0.0;
}
delta *= z;
}
if (delta != 0) // add in non-zero amount
{
map[x, y] += delta;
}
if(distancefactor >= 1.0f)
map[x, y] = rz;
else
map[x, y] += (rz - (float)map[x, y]) * distancefactor;
} }
} }
} }

View File

@ -34,11 +34,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
{ {
#region ITerrainPaintableEffect Members #region ITerrainPaintableEffect Members
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, public void PaintEffect(ITerrainChannel map, bool[,] mask, float rx, float ry, float rz,
double strength, double duration, int startX, int endX, int startY, int endY) float size, float strength, int startX, int endX, int startY, int endY)
{ {
int s = (int) (Math.Pow(2, strength) + 0.5); size = 0.5f * (float)Math.PI / size;
strength *= 2;
int x, y; int x, y;
for (x = startX; x <= endX; x++) for (x = startX; x <= endX; x++)
@ -49,19 +49,18 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
continue; continue;
// Calculate a cos-sphere and add it to the heighmap // Calculate a cos-sphere and add it to the heighmap
double r = Math.Sqrt((x-rx) * (x-rx) + ((y-ry) * (y-ry))); double r = Math.Sqrt((x - rx) * (x - rx) + (y - ry) * (y - ry));
double z = Math.Cos(r * Math.PI / (s * 2)); double distancefactor = Math.Cos(r * size);
if (z > 0.0) if (distancefactor > 0.0)
{ {
double newz = map[x, y] - z * duration; double newz = map[x, y] - distancefactor * strength;
if (newz < 0.0) if (newz <= -100f)
map[x, y] = 0.0; map[x, y] = -100f;
else else
map[x, y] = newz; map[x, y] = newz;
} }
} }
} }
} }
#endregion #endregion
} }

View File

@ -35,11 +35,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
{ {
#region ITerrainPaintableEffect Members #region ITerrainPaintableEffect Members
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, public void PaintEffect(ITerrainChannel map, bool[,] mask, float rx, float ry, float rz,
double strength, double duration, int startX, int endX, int startY, int endY) float size, float strength, int startX, int endX, int startY, int endY)
{ {
strength = TerrainUtil.MetersToSphericalStrength(strength);
int x, y; int x, y;
for (x = startX; x <= endX; x++) for (x = startX; x <= endX; x++)
@ -50,14 +48,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
continue; continue;
// Calculate a sphere and add it to the heighmap // Calculate a sphere and add it to the heighmap
double z = strength; float distancefactor = TerrainUtil.SphericalFactor(x - rx, y - ry, size);
z *= z;
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
double noise = TerrainUtil.PerlinNoise2D(x / (double) map.Width, y / (double) map.Height, 8, 1.0); double noise = TerrainUtil.PerlinNoise2D(x / (double) map.Width, y / (double) map.Height, 8, 1.0);
if (z > 0.0) if (distancefactor > 0.0)
map[x, y] += noise * z * duration; map[x, y] += noise * distancefactor * strength;
} }
} }
} }

View File

@ -1,223 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
{
/// <summary>
/// Speed-Optimised Hybrid Erosion Brush
///
/// As per Jacob Olsen's Paper
/// http://www.oddlabs.com/download/terrain_generation.pdf
/// </summary>
public class OlsenSphere : ITerrainPaintableEffect
{
private const double nConst = 1024.0;
private const NeighbourSystem type = NeighbourSystem.Moore;
#region Supporting Functions
private static int[] Neighbours(NeighbourSystem neighbourType, int index)
{
int[] coord = new int[2];
index++;
switch (neighbourType)
{
case NeighbourSystem.Moore:
switch (index)
{
case 1:
coord[0] = -1;
coord[1] = -1;
break;
case 2:
coord[0] = -0;
coord[1] = -1;
break;
case 3:
coord[0] = +1;
coord[1] = -1;
break;
case 4:
coord[0] = -1;
coord[1] = -0;
break;
case 5:
coord[0] = -0;
coord[1] = -0;
break;
case 6:
coord[0] = +1;
coord[1] = -0;
break;
case 7:
coord[0] = -1;
coord[1] = +1;
break;
case 8:
coord[0] = -0;
coord[1] = +1;
break;
case 9:
coord[0] = +1;
coord[1] = +1;
break;
default:
break;
}
break;
case NeighbourSystem.VonNeumann:
switch (index)
{
case 1:
coord[0] = 0;
coord[1] = -1;
break;
case 2:
coord[0] = -1;
coord[1] = 0;
break;
case 3:
coord[0] = +1;
coord[1] = 0;
break;
case 4:
coord[0] = 0;
coord[1] = +1;
break;
case 5:
coord[0] = -0;
coord[1] = -0;
break;
default:
break;
}
break;
}
return coord;
}
private enum NeighbourSystem
{
Moore,
VonNeumann
} ;
#endregion
#region ITerrainPaintableEffect Members
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
double strength, double duration, int startX, int endX, int startY, int endY)
{
strength = TerrainUtil.MetersToSphericalStrength(strength);
int x, y;
for (x = startX; x <= endX; x++)
{
for (y = startY; y <= endY; y++)
{
if (!mask[x, y])
continue;
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
if (z > 0) // add in non-zero amount
{
const int NEIGHBOUR_ME = 4;
const int NEIGHBOUR_MAX = 9;
double max = Double.MinValue;
int loc = 0;
for (int j = 0; j < NEIGHBOUR_MAX; j++)
{
if (j != NEIGHBOUR_ME)
{
int[] coords = Neighbours(type, j);
coords[0] += x;
coords[1] += y;
if (coords[0] > map.Width - 1)
continue;
if (coords[1] > map.Height - 1)
continue;
if (coords[0] < 0)
continue;
if (coords[1] < 0)
continue;
double cellmax = map[x, y] - map[coords[0], coords[1]];
if (cellmax > max)
{
max = cellmax;
loc = j;
}
}
}
double T = nConst / ((map.Width + map.Height) / 2.0);
// Apply results
if (0 < max && max <= T)
{
int[] maxCoords = Neighbours(type, loc);
double heightDelta = 0.5 * max * z * duration;
map[x, y] -= heightDelta;
map[x + maxCoords[0], y + maxCoords[1]] += heightDelta;
}
}
}
}
}
#endregion
}
}

View File

@ -35,12 +35,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
#region ITerrainPaintableEffect Members #region ITerrainPaintableEffect Members
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, public void PaintEffect(ITerrainChannel map, bool[,] mask, float rx, float ry, float rz,
double strength, double duration, int startX, int endX, int startY, int endY) float size, float strength, int startX, int endX, int startY, int endY)
{ {
int s = (int) (Math.Pow(2, strength) + 0.5); size = 0.5f *(float)Math.PI / size;
strength *= 2;
int x,y; int x, y;
for (x = startX; x <= endX; x++) for (x = startX; x <= endX; x++)
{ {
@ -50,10 +51,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
continue; continue;
// Calculate a cos-sphere and add it to the heighmap // Calculate a cos-sphere and add it to the heighmap
double r = Math.Sqrt((x - rx) * (x - rx) + ((y - ry) * (y - ry))); double r = Math.Sqrt((x - rx) * (x - rx) + (y - ry) * (y - ry));
double z = Math.Cos(r * Math.PI / (s * 2)); double distancefactor = Math.Cos(r * size);
if (z > 0.0) if (distancefactor > 0.0)
map[x, y] += z * duration; map[x, y] += distancefactor * strength;
} }
} }
} }

View File

@ -41,17 +41,15 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
#region ITerrainPaintableEffect Members #region ITerrainPaintableEffect Members
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, public void PaintEffect(ITerrainChannel map, bool[,] mask, float rx, float ry, float rz,
double strength, double duration, int startX, int endX, int startY, int endY) float size, float strength, int startX, int endX, int startY, int endY)
{ {
strength = TerrainUtil.MetersToSphericalStrength(strength); if (strength < 0)
duration = 0.03; //MCP Should be read from ini file
if (duration > 1.0)
duration = 1.0;
if (duration < 0)
return; return;
if (strength > 1.0f)
strength = 1.0f;
int x,y; int x,y;
for (x = startX; x <= endX; x++) for (x = startX; x <= endX; x++)
{ {
@ -61,14 +59,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
continue; continue;
// Calculate a sphere and add it to the heighmap // Calculate a sphere and add it to the heighmap
double z = strength; double distancefactor = TerrainUtil.SphericalFactor(x - rx, y - ry, size);
z *= z; if (distancefactor > 0.0)
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
if (z > 0.0)
{ {
z *= duration; distancefactor *= strength;
map[x, y] = (map[x, y] * (1.0 - z)) + (m_revertmap[x, y] * z); map[x, y] = (map[x, y] * (1.0 - distancefactor)) + (m_revertmap[x, y] * distancefactor);
} }
} }
} }

View File

@ -34,18 +34,16 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
{ {
#region ITerrainPaintableEffect Members #region ITerrainPaintableEffect Members
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, public void PaintEffect(ITerrainChannel map, bool[,] mask, float rx, float ry, float rz,
double strength, double duration, int startX, int endX, int startY, int endY) float size, float strengh, int startX, int endX, int startY, int endY)
{ {
strength = TerrainUtil.MetersToSphericalStrength(strength);
int x, y; int x, y;
double[,] tweak = new double[map.Width,map.Height]; double[,] tweak = new double[map.Width, map.Height];
double area = strength; double step = size / 4.0;
double step = strength / 4.0;
duration = 0.03; //MCP Should be read from ini file
if(strengh > 1.0f)
strengh = 1.0f;
// compute delta map // compute delta map
for (x = startX; x <= endX; x++) for (x = startX; x <= endX; x++)
@ -55,7 +53,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
if (!mask[x, y]) if (!mask[x, y])
continue; continue;
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); double z = TerrainUtil.SphericalFactor(x - rx, y - ry, size);
if (z > 0) // add in non-zero amount if (z > 0) // add in non-zero amount
{ {
@ -63,10 +61,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
int avgsteps = 0; int avgsteps = 0;
double n; double n;
for (n = 0.0 - area; n < area; n += step) for (n =- size; n < size; n += step)
{ {
double l; double l;
for (l = 0.0 - area; l < area; l += step) for (l = -size; l < size; l += step)
{ {
avgsteps++; avgsteps++;
average += TerrainUtil.GetBilinearInterpolate(x + n, y + l, map); average += TerrainUtil.GetBilinearInterpolate(x + n, y + l, map);
@ -84,13 +82,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
if (!mask[x, y]) if (!mask[x, y])
continue; continue;
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); float distancefactor = TerrainUtil.SphericalFactor(x - rx, y - ry, size);
if (z > 0) // add in non-zero amount if (distancefactor > 0) // add in non-zero amount
{ {
double da = z; double a = (map[x, y] - tweak[x, y]) * distancefactor;
double a = (map[x, y] - tweak[x, y]) * da; double newz = map[x, y] - (a * strengh);
double newz = map[x, y] - (a * duration);
if (newz > 0.0) if (newz > 0.0)
map[x, y] = newz; map[x, y] = newz;

View File

@ -1,211 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
{
/// <summary>
/// Thermal Weathering Paint Brush
/// </summary>
public class WeatherSphere : ITerrainPaintableEffect
{
private const double talus = 0.2;
private const NeighbourSystem type = NeighbourSystem.Moore;
#region Supporting Functions
private static int[] Neighbours(NeighbourSystem neighbourType, int index)
{
int[] coord = new int[2];
index++;
switch (neighbourType)
{
case NeighbourSystem.Moore:
switch (index)
{
case 1:
coord[0] = -1;
coord[1] = -1;
break;
case 2:
coord[0] = -0;
coord[1] = -1;
break;
case 3:
coord[0] = +1;
coord[1] = -1;
break;
case 4:
coord[0] = -1;
coord[1] = -0;
break;
case 5:
coord[0] = -0;
coord[1] = -0;
break;
case 6:
coord[0] = +1;
coord[1] = -0;
break;
case 7:
coord[0] = -1;
coord[1] = +1;
break;
case 8:
coord[0] = -0;
coord[1] = +1;
break;
case 9:
coord[0] = +1;
coord[1] = +1;
break;
default:
break;
}
break;
case NeighbourSystem.VonNeumann:
switch (index)
{
case 1:
coord[0] = 0;
coord[1] = -1;
break;
case 2:
coord[0] = -1;
coord[1] = 0;
break;
case 3:
coord[0] = +1;
coord[1] = 0;
break;
case 4:
coord[0] = 0;
coord[1] = +1;
break;
case 5:
coord[0] = -0;
coord[1] = -0;
break;
default:
break;
}
break;
}
return coord;
}
private enum NeighbourSystem
{
Moore,
VonNeumann
} ;
#endregion
#region ITerrainPaintableEffect Members
public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
double strength, double duration, int startX, int endX, int startY, int endY)
{
strength = TerrainUtil.MetersToSphericalStrength(strength);
int x,y;
for (x = startX; x <= endX; x++)
{
for (y = startY; y <= endY; y++)
{
if (!mask[x,y])
continue;
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
if (z > 0) // add in non-zero amount
{
const int NEIGHBOUR_ME = 4;
const int NEIGHBOUR_MAX = 9;
for (int j = 0; j < NEIGHBOUR_MAX; j++)
{
if (j != NEIGHBOUR_ME)
{
int[] coords = Neighbours(type, j);
coords[0] += x;
coords[1] += y;
if (coords[0] > map.Width - 1)
continue;
if (coords[1] > map.Height - 1)
continue;
if (coords[0] < 0)
continue;
if (coords[1] < 0)
continue;
double heightF = map[x, y];
double target = map[coords[0], coords[1]];
if (target > heightF + talus)
{
double calc = duration * ((target - heightF) - talus) * z;
heightF += calc;
target -= calc;
}
map[x, y] = heightF;
map[coords[0], coords[1]] = target;
}
}
}
}
}
}
#endregion
}
}

View File

@ -65,11 +65,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
Smooth = 3, Smooth = 3,
Noise = 4, Noise = 4,
Revert = 5, Revert = 5,
// Extended brushes
Erode = 255,
Weather = 254,
Olsen = 253
} }
#endregion #endregion
@ -81,13 +76,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain
#pragma warning restore 414 #pragma warning restore 414
private readonly Commander m_commander = new Commander("terrain"); private readonly Commander m_commander = new Commander("terrain");
private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>();
private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects = private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects =
new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>(); new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>();
private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>();
private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects =
new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>();
private Dictionary<string, ITerrainModifier> m_modifyOperations = private Dictionary<string, ITerrainModifier> m_modifyOperations = new Dictionary<string, ITerrainModifier>();
new Dictionary<string, ITerrainModifier>();
private Dictionary<string, ITerrainEffect> m_plugineffects; private Dictionary<string, ITerrainEffect> m_plugineffects;
private ITerrainChannel m_channel; private ITerrainChannel m_channel;
private ITerrainChannel m_baked; private ITerrainChannel m_baked;
@ -520,13 +514,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
/// <param name="size">The size of the brush (0=small, 1=medium, 2=large)</param> /// <param name="size">The size of the brush (0=small, 1=medium, 2=large)</param>
/// <param name="action">0=LAND_LEVEL, 1=LAND_RAISE, 2=LAND_LOWER, 3=LAND_SMOOTH, 4=LAND_NOISE, 5=LAND_REVERT</param> /// <param name="action">0=LAND_LEVEL, 1=LAND_RAISE, 2=LAND_LOWER, 3=LAND_SMOOTH, 4=LAND_NOISE, 5=LAND_REVERT</param>
/// <param name="agentId">UUID of script-owner</param> /// <param name="agentId">UUID of script-owner</param>
public void ModifyTerrain(UUID user, Vector3 pos, byte size, byte action, UUID agentId) public void ModifyTerrain(UUID user, Vector3 pos, byte size, byte action)
{ {
float duration = 0.25f; float duration = 0.25f;
if (action == 0) float brushSize = size + 1;
duration = 4.0f; if (brushSize > 2)
brushSize = 4;
client_OnModifyTerrain(user, (float)pos.Z, duration, size, action, pos.Y, pos.X, pos.Y, pos.X, agentId); client_OnModifyTerrain(user, pos.Z, duration, brushSize, action, pos.Y, pos.X, pos.Y, pos.X);
} }
/// <summary> /// <summary>
@ -686,9 +681,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
m_painteffects[StandardTerrainEffects.Noise] = new NoiseSphere(); m_painteffects[StandardTerrainEffects.Noise] = new NoiseSphere();
m_painteffects[StandardTerrainEffects.Flatten] = new FlattenSphere(); m_painteffects[StandardTerrainEffects.Flatten] = new FlattenSphere();
m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_baked); m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_baked);
m_painteffects[StandardTerrainEffects.Erode] = new ErodeSphere();
m_painteffects[StandardTerrainEffects.Weather] = new WeatherSphere();
m_painteffects[StandardTerrainEffects.Olsen] = new OlsenSphere();
// Area of effect selection effects // Area of effect selection effects
m_floodeffects[StandardTerrainEffects.Raise] = new RaiseArea(); m_floodeffects[StandardTerrainEffects.Raise] = new RaiseArea();
@ -1310,9 +1302,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
return ret; return ret;
} }
private void client_OnModifyTerrain(UUID user, float height, float seconds, byte size, byte action, private void client_OnModifyTerrain(UUID user, float height, float seconds, float brushSize, byte action,
float north, float west, float south, float east, UUID agentId) float north, float west, float south, float east)
{ {
m_log.DebugFormat("brushs {0} seconds {1} height {2}", brushSize, seconds, height);
bool god = m_scene.Permissions.IsGod(user); bool god = m_scene.Permissions.IsGod(user);
bool allowed = false; bool allowed = false;
if (north == south && east == west) if (north == south && east == west)
@ -1321,25 +1314,19 @@ namespace OpenSim.Region.CoreModules.World.Terrain
{ {
bool[,] allowMask = new bool[m_channel.Width, m_channel.Height]; bool[,] allowMask = new bool[m_channel.Width, m_channel.Height];
allowMask.Initialize(); allowMask.Initialize();
int n = size + 1;
if (n > 2)
n = 4;
int zx = (int)(west + 0.5); int startX = (int)(west - brushSize + 0.5);
int zy = (int)(north + 0.5);
int startX = zx - n;
if (startX < 0) if (startX < 0)
startX = 0; startX = 0;
int startY = zy - n; int startY = (int)(north - brushSize + 0.5);
if (startY < 0) if (startY < 0)
startY = 0; startY = 0;
int endX = zx + n; int endX = (int)(west + brushSize + 0.5);
if (endX >= m_channel.Width) if (endX >= m_channel.Width)
endX = m_channel.Width - 1; endX = m_channel.Width - 1;
int endY = zy + n; int endY = (int)(north + brushSize + 0.5);
if (endY >= m_channel.Height) if (endY >= m_channel.Height)
endY = m_channel.Height - 1; endY = m_channel.Height - 1;
@ -1349,7 +1336,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
{ {
for (y = startY; y <= endY; y++) for (y = startY; y <= endY; y++)
{ {
if (m_scene.Permissions.CanTerraformLand(agentId, new Vector3(x, y, 0))) if (m_scene.Permissions.CanTerraformLand(user, new Vector3(x, y, 0)))
{ {
allowMask[x, y] = true; allowMask[x, y] = true;
allowed = true; allowed = true;
@ -1360,7 +1347,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
{ {
StoreUndoState(); StoreUndoState();
m_painteffects[(StandardTerrainEffects) action].PaintEffect( m_painteffects[(StandardTerrainEffects) action].PaintEffect(
m_channel, allowMask, west, south, height, size, seconds, m_channel, allowMask, west, south, height, brushSize, seconds,
startX, endX, startY, endY); startX, endX, startY, endY);
//block changes outside estate limits //block changes outside estate limits
@ -1412,7 +1399,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
{ {
for (y = startY; y <= endY; y++) for (y = startY; y <= endY; y++)
{ {
if (m_scene.Permissions.CanTerraformLand(agentId, new Vector3(x, y, 0))) if (m_scene.Permissions.CanTerraformLand(user, new Vector3(x, y, 0)))
{ {
fillArea[x, y] = true; fillArea[x, y] = true;
allowed = true; allowed = true;
@ -1423,7 +1410,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
if (allowed) if (allowed)
{ {
StoreUndoState(); StoreUndoState();
m_floodeffects[(StandardTerrainEffects)action].FloodEffect(m_channel, fillArea, size, m_floodeffects[(StandardTerrainEffects)action].FloodEffect(m_channel, fillArea, height, seconds,
startX, endX, startY, endY); startX, endX, startY, endY);
//block changes outside estate limits //block changes outside estate limits
@ -1707,20 +1694,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
MainConsole.Instance.Output("max/min/avg/sum: {0}/{1}/{2}/{3}", max, min, avg, sum); MainConsole.Instance.Output("max/min/avg/sum: {0}/{1}/{2}/{3}", max, min, avg, sum);
} }
private void InterfaceEnableExperimentalBrushes(Object[] args)
{
if ((bool)args[0])
{
m_painteffects[StandardTerrainEffects.Revert] = new WeatherSphere();
m_painteffects[StandardTerrainEffects.Flatten] = new OlsenSphere();
m_painteffects[StandardTerrainEffects.Smooth] = new ErodeSphere();
}
else
{
InstallDefaultEffects();
}
}
private void InterfaceRunPluginEffect(Object[] args) private void InterfaceRunPluginEffect(Object[] args)
{ {
string firstArg = (string)args[0]; string firstArg = (string)args[0];
@ -1841,12 +1814,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
"Shows terrain height at a given co-ordinate."); "Shows terrain height at a given co-ordinate.");
showCommand.AddArgument("point", "point in <x>,<y> format with no spaces (e.g. 45,45)", "String"); showCommand.AddArgument("point", "point in <x>,<y> format with no spaces (e.g. 45,45)", "String");
Command experimentalBrushesCommand = // Plugins
new Command("newbrushes", CommandIntentions.COMMAND_HAZARDOUS, InterfaceEnableExperimentalBrushes,
"Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time.");
experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean");
// Plugins
Command pluginRunCommand = Command pluginRunCommand =
new Command("effect", CommandIntentions.COMMAND_HAZARDOUS, InterfaceRunPluginEffect, "Runs a specified plugin effect"); new Command("effect", CommandIntentions.COMMAND_HAZARDOUS, InterfaceRunPluginEffect, "Runs a specified plugin effect");
pluginRunCommand.AddArgument("name", "The plugin effect you wish to run, or 'list' to see all plugins", "String"); pluginRunCommand.AddArgument("name", "The plugin effect you wish to run, or 'list' to see all plugins", "String");
@ -1861,7 +1829,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
m_commander.RegisterCommand("multiply", multiplyCommand); m_commander.RegisterCommand("multiply", multiplyCommand);
m_commander.RegisterCommand("bake", bakeRegionCommand); m_commander.RegisterCommand("bake", bakeRegionCommand);
m_commander.RegisterCommand("revert", revertRegionCommand); m_commander.RegisterCommand("revert", revertRegionCommand);
m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand);
m_commander.RegisterCommand("show", showCommand); m_commander.RegisterCommand("show", showCommand);
m_commander.RegisterCommand("stats", showDebugStatsCommand); m_commander.RegisterCommand("stats", showDebugStatsCommand);
m_commander.RegisterCommand("effect", pluginRunCommand); m_commander.RegisterCommand("effect", pluginRunCommand);

View File

@ -60,7 +60,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Tests
TerrainChannel map = new TerrainChannel((int)Constants.RegionSize, (int)Constants.RegionSize); TerrainChannel map = new TerrainChannel((int)Constants.RegionSize, (int)Constants.RegionSize);
ITerrainPaintableEffect effect = new RaiseSphere(); ITerrainPaintableEffect effect = new RaiseSphere();
effect.PaintEffect(map, allowMask, midRegion, midRegion, -1.0, 2, 6.0, effect.PaintEffect(map, allowMask, midRegion, midRegion, -1.0f, 2, 6.0f,
0, midRegion - 1,0, (int)Constants.RegionSize -1); 0, midRegion - 1,0, (int)Constants.RegionSize -1);
Assert.That(map[127, midRegion] > 0.0, "Raise brush should raising value at this point (127,128)."); Assert.That(map[127, midRegion] > 0.0, "Raise brush should raising value at this point (127,128).");
Assert.That(map[125, midRegion] > 0.0, "Raise brush should raising value at this point (124,128)."); Assert.That(map[125, midRegion] > 0.0, "Raise brush should raising value at this point (124,128).");
@ -80,7 +80,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Tests
} }
effect = new LowerSphere(); effect = new LowerSphere();
effect.PaintEffect(map, allowMask, midRegion, midRegion, -1.0, 2, 6.0, effect.PaintEffect(map, allowMask, midRegion, midRegion, -1.0f, 2, 6.0f,
0, (int)Constants.RegionSize -1,0, (int)Constants.RegionSize -1); 0, (int)Constants.RegionSize -1,0, (int)Constants.RegionSize -1);
Assert.That(map[127, midRegion] >= 0.0, "Lower should not lowering value below 0.0 at this point (127,128)."); Assert.That(map[127, midRegion] >= 0.0, "Lower should not lowering value below 0.0 at this point (127,128).");
Assert.That(map[127, midRegion] == 0.0, "Lower brush should lowering value to 0.0 at this point (127,128)."); Assert.That(map[127, midRegion] == 0.0, "Lower brush should lowering value to 0.0 at this point (127,128).");

View File

@ -53,7 +53,8 @@ namespace OpenSim.Region.Framework.Interfaces
/// All add and remove attachment operations must synchronize on this for the lifetime of their operations. /// All add and remove attachment operations must synchronize on this for the lifetime of their operations.
/// </remarks> /// </remarks>
Object AttachmentsSyncLock { get; } Object AttachmentsSyncLock { get; }
int MaxNumberAttachments { get; }
int GetAttachmentsCount();
/// <summary> /// <summary>
/// The scene objects attached to this avatar. /// The scene objects attached to this avatar.
/// </summary> /// </summary>

View File

@ -35,7 +35,7 @@ namespace OpenSim.Region.Framework.Interfaces
{ {
void LoadFromFile(string filename); void LoadFromFile(string filename);
void SaveToFile(string filename); void SaveToFile(string filename);
void ModifyTerrain(UUID user, Vector3 pos, byte size, byte action, UUID agentId); void ModifyTerrain(UUID user, Vector3 pos, byte size, byte action);
/// <summary> /// <summary>
/// Taint the terrain. This will lead to sending the terrain data to the clients again. /// Taint the terrain. This will lead to sending the terrain data to the clients again.

View File

@ -2963,7 +2963,6 @@ namespace OpenSim.Region.Framework.Scenes
if (sceneObject.IsAttachmentCheckFull()) // Attachment if (sceneObject.IsAttachmentCheckFull()) // Attachment
{ {
sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
// sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
// Don't sent a full update here because this will cause full updates to be sent twice for // Don't sent a full update here because this will cause full updates to be sent twice for
// attachments on region crossings, resulting in viewer glitches. // attachments on region crossings, resulting in viewer glitches.
@ -2984,13 +2983,17 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat( // m_log.DebugFormat(
// "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); // "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition);
RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
// We must currently not resume scripts at this stage since AttachmentsModule does not have the // We must currently not resume scripts at this stage since AttachmentsModule does not have the
// information that this is due to a teleport/border cross rather than an ordinary attachment. // information that this is due to a teleport/border cross rather than an ordinary attachment.
// We currently do this in Scene.MakeRootAgent() instead. // We currently do this in Scene.MakeRootAgent() instead.
bool attached = false;
if (AttachmentsModule != null) if (AttachmentsModule != null)
AttachmentsModule.AttachObject(sp, grp, 0, false, false, true); attached = AttachmentsModule.AttachObject(sp, grp, 0, false, false, true);
if (attached)
RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
else
m_log.DebugFormat("[SCENE]: Attachment {0} arrived but failed to attach, setting to temp", sceneObject.UUID);
} }
else else
{ {

View File

@ -538,19 +538,15 @@ namespace OpenSim.Region.Framework.Scenes
{ {
float cx = m_terrainData.SizeX * 0.5f; float cx = m_terrainData.SizeX * 0.5f;
float cy = m_terrainData.SizeY * 0.5f; float cy = m_terrainData.SizeY * 0.5f;
float h; float h, b;
for (int x = 0; x < Width; x++) for (int x = 0; x < Width; x++)
{ {
for (int y = 0; y < Height; y++) for (int y = 0; y < Height; y++)
{ {
// h = (float)TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10; h = 25 * TerrainUtil.SphericalFactor(x - cx, y - cy, 50);
h = 1.0f; b = 10 * TerrainUtil.SphericalFactor(x - cx, y - cy, 100);
float spherFacA = (float)(TerrainUtil.SphericalFactor(x, y, cx, cy, 50) * 0.01d); if (h < b)
float spherFacB = (float)(TerrainUtil.SphericalFactor(x, y, cx, cy, 100) * 0.001d); h = b;
if (h < spherFacA)
h = spherFacA;
if (h < spherFacB)
h = spherFacB;
m_terrainData[x, y] = h; m_terrainData[x, y] = h;
} }
} }

View File

@ -32,15 +32,12 @@ namespace OpenSim.Region.Framework.Scenes
{ {
public static class TerrainUtil public static class TerrainUtil
{ {
public static double MetersToSphericalStrength(double size) public static float SphericalFactor(float dx, float dy, float size)
{ {
//return Math.Pow(2, size); float a = ((dx * dx) + (dy * dy))/ (size * size);
return (size + 1) * 1.35; // MCP: a more useful brush size range if( a >= 1.0f)
} return 0;
return 1.0f - a;
public static double SphericalFactor(double x, double y, double rx, double ry, double size)
{
return size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
} }
public static double GetBilinearInterpolate(double x, double y, ITerrainChannel map) public static double GetBilinearInterpolate(double x, double y, ITerrainChannel map)