* Terrain Module code has been reformatted to comply with guidelines.

* Fixed a variety of code quality issues. (Yes, I've found ReSharper.)
0.6.0-stable
Adam Frisby 2008-04-21 06:39:16 +00:00
parent 20a4a402f6
commit 05e24c8f58
36 changed files with 753 additions and 671 deletions

View File

@ -26,12 +26,14 @@
*/ */
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Timers; using System.Timers;
using libsecondlife;
using Mono.Addins;
using Nini.Config; using Nini.Config;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Communications.Cache;
@ -46,13 +48,6 @@ using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.Physics.Manager; using OpenSim.Region.Physics.Manager;
using Timer = System.Timers.Timer; using Timer = System.Timers.Timer;
using System.Net;
using Nwc.XmlRpc;
using System.Collections;
using System.Reflection;
using libsecondlife;
using Mono.Addins;
using Mono.Addins.Description;
namespace OpenSim namespace OpenSim
{ {

View File

@ -25,22 +25,20 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections.Generic;
using System.Text;
using OpenSim.Region.Environment.Modules.Terrain;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
using OpenSim.Framework; using OpenSim.Region.Environment.Modules.Terrain.FloodBrushes;
using OpenSim.Region.Environment.Modules.Terrain.PaintBrushes;
namespace OpenSim.Region.Environment.Modules.Terrain.Effects namespace OpenSim.Region.Environment.Modules.Terrain.Effects
{ {
class CookieCutter : ITerrainEffect internal class CookieCutter : ITerrainEffect
{ {
#region ITerrainEffect Members #region ITerrainEffect Members
public void RunEffect(ITerrainChannel map) public void RunEffect(ITerrainChannel map)
{ {
FloodBrushes.SmoothArea smooth = new FloodBrushes.SmoothArea(); SmoothArea smooth = new SmoothArea();
ITerrainPaintableEffect eroder = new PaintBrushes.WeatherSphere(); ITerrainPaintableEffect eroder = new WeatherSphere();
bool[,] cliffMask = new bool[map.Width,map.Height]; bool[,] cliffMask = new bool[map.Width,map.Height];
bool[,] channelMask = new bool[map.Width,map.Height]; bool[,] channelMask = new bool[map.Width,map.Height];
@ -98,7 +96,10 @@ namespace OpenSim.Region.Environment.Modules.Terrain.Effects
//smooth.FloodEffect(map, smoothMask, 4.0); //smooth.FloodEffect(map, smoothMask, 4.0);
} }
private static void SetLowerChannel(ITerrainChannel map, bool[,] cliffMask, bool[,] channelMask, int x, int y, int numChannels, int channelWidth, int mapSize, int rp) #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++) for (int i = 0; i < numChannels; i++)
{ {
@ -119,7 +120,5 @@ namespace OpenSim.Region.Environment.Modules.Terrain.Effects
} }
} }
} }
#endregion
} }
} }

View File

@ -24,16 +24,12 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
using System.Collections.Generic;
using System.Text;
using OpenSim.Region.Environment.Modules.Terrain;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Modules.Terrain.Effects namespace OpenSim.Region.Environment.Modules.Terrain.Effects
{ {
class DefaultTerrainGenerator : ITerrainEffect internal class DefaultTerrainGenerator : ITerrainEffect
{ {
#region ITerrainEffect Members #region ITerrainEffect Members

View File

@ -24,8 +24,8 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
@ -36,7 +36,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
/// ///
/// Uses the System.Drawing filesystem loader. /// Uses the System.Drawing filesystem loader.
/// </summary> /// </summary>
class BMP : GenericSystemDrawing internal class BMP : GenericSystemDrawing
{ {
/// <summary> /// <summary>
/// Exports a file to a image on the disk using a System.Drawing exporter. /// Exports a file to a image on the disk using a System.Drawing exporter.
@ -47,7 +47,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
{ {
Bitmap colours = CreateGrayscaleBitmapFromMap(map); Bitmap colours = CreateGrayscaleBitmapFromMap(map);
colours.Save(filename, System.Drawing.Imaging.ImageFormat.Bmp); colours.Save(filename, ImageFormat.Bmp);
} }
/// <summary> /// <summary>

View File

@ -24,19 +24,19 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
{ {
class GIF : GenericSystemDrawing internal class GIF : GenericSystemDrawing
{ {
public override void SaveFile(string filename, ITerrainChannel map) public override void SaveFile(string filename, ITerrainChannel map)
{ {
Bitmap colours = CreateGrayscaleBitmapFromMap(map); Bitmap colours = CreateGrayscaleBitmapFromMap(map);
colours.Save(filename, System.Drawing.Imaging.ImageFormat.Gif); colours.Save(filename, ImageFormat.Gif);
} }
public override string ToString() public override string ToString()

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
@ -72,6 +73,20 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
throw new NotImplementedException(); throw new NotImplementedException();
} }
/// <summary>
/// Exports a file to a image on the disk using a System.Drawing exporter.
/// </summary>
/// <param name="filename">The target filename</param>
/// <param name="map">The terrain channel being saved</param>
public virtual void SaveFile(string filename, ITerrainChannel map)
{
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
colours.Save(filename, ImageFormat.Png);
}
#endregion
public override string ToString() public override string ToString()
{ {
return "SYS.DRAWING"; return "SYS.DRAWING";
@ -148,19 +163,5 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
} }
return bmp; return bmp;
} }
/// <summary>
/// Exports a file to a image on the disk using a System.Drawing exporter.
/// </summary>
/// <param name="filename">The target filename</param>
/// <param name="map">The terrain channel being saved</param>
public virtual void SaveFile(string filename, ITerrainChannel map)
{
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
colours.Save(filename, System.Drawing.Imaging.ImageFormat.Png);
}
#endregion
} }
} }

View File

@ -26,8 +26,8 @@
*/ */
using System; using System;
using System.IO;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
@ -46,6 +46,15 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
throw new NotImplementedException(); throw new NotImplementedException();
} }
public void SaveFile(string filename, ITerrainChannel map)
{
Bitmap colours = CreateBitmapFromMap(map);
colours.Save(filename, ImageFormat.Jpeg);
}
#endregion
public override string ToString() public override string ToString()
{ {
return "JPEG"; return "JPEG";
@ -76,14 +85,5 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
} }
return bmp; return bmp;
} }
public void SaveFile(string filename, ITerrainChannel map)
{
Bitmap colours = CreateBitmapFromMap(map);
colours.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg);
}
#endregion
} }
} }

View File

@ -58,11 +58,6 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
return retval; return retval;
} }
public override string ToString()
{
return "LL/SL RAW";
}
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
@ -138,5 +133,10 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
} }
#endregion #endregion
public override string ToString()
{
return "LL/SL RAW";
}
} }
} }

View File

@ -24,19 +24,19 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
{ {
class PNG : GenericSystemDrawing internal class PNG : GenericSystemDrawing
{ {
public override void SaveFile(string filename, ITerrainChannel map) public override void SaveFile(string filename, ITerrainChannel map)
{ {
Bitmap colours = CreateGrayscaleBitmapFromMap(map); Bitmap colours = CreateGrayscaleBitmapFromMap(map);
colours.Save(filename, System.Drawing.Imaging.ImageFormat.Png); colours.Save(filename, ImageFormat.Png);
} }
public override string ToString() public override string ToString()

View File

@ -25,7 +25,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
using System.IO; using System.IO;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
@ -57,11 +56,6 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
return retval; return retval;
} }
public override string ToString()
{
return "RAW32";
}
public ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight) public ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight)
{ {
TerrainChannel retval = new TerrainChannel(sectionWidth, sectionHeight); TerrainChannel retval = new TerrainChannel(sectionWidth, sectionHeight);
@ -117,8 +111,6 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
bs.ReadBytes(sectionWidth * 4); // 4 bytes = single bs.ReadBytes(sectionWidth * 4); // 4 bytes = single
currFileXOffset++; currFileXOffset++;
} }
} }
bs.Close(); bs.Close();
@ -147,5 +139,10 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
} }
#endregion #endregion
public override string ToString()
{
return "RAW32";
}
} }
} }

View File

@ -24,19 +24,19 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
{ {
class TIFF : GenericSystemDrawing internal class TIFF : GenericSystemDrawing
{ {
public override void SaveFile(string filename, ITerrainChannel map) public override void SaveFile(string filename, ITerrainChannel map)
{ {
Bitmap colours = CreateGrayscaleBitmapFromMap(map); Bitmap colours = CreateGrayscaleBitmapFromMap(map);
colours.Save(filename, System.Drawing.Imaging.ImageFormat.Tiff); colours.Save(filename, ImageFormat.Tiff);
} }
public override string ToString() public override string ToString()

View File

@ -37,7 +37,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
/// Built from specification at /// Built from specification at
/// http://www.planetside.co.uk/terragen/dev/tgterrain.html /// http://www.planetside.co.uk/terragen/dev/tgterrain.html
/// </summary> /// </summary>
class Terragen : ITerrainLoader internal class Terragen : ITerrainLoader
{ {
#region ITerrainLoader Members #region ITerrainLoader Members
@ -107,16 +107,16 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
throw new NotImplementedException(); throw new NotImplementedException();
} }
public override string ToString()
{
return "Terragen";
}
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
#endregion #endregion
public override string ToString()
{
return "Terragen";
}
} }
} }

View File

@ -25,10 +25,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
using System.Collections.Generic;
using System.Text;
using OpenSim.Region.Environment.Modules.Terrain;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
@ -41,14 +37,14 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
{ {
double sum = 0.0; double sum = 0.0;
double steps = 0.0; double steps = 0.0;
double avg = 0.0; double avg;
int x, y; int x, y;
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++)
{ {
if (fillArea[x, y] == true) if (fillArea[x, y])
{ {
sum += map[x, y]; sum += map[x, y];
steps += 1.0; steps += 1.0;
@ -64,7 +60,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
{ {
for (y = 0; y < map.Height; y++) for (y = 0; y < map.Height; y++)
{ {
if (fillArea[x, y] == true) if (fillArea[x, y])
map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str); map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str);
} }
} }

View File

@ -35,12 +35,13 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
{ {
int x, y; int x;
for (x = 0; x < map.Width; x++) for (x = 0; x < map.Width; x++)
{ {
int y;
for (y = 0; y < map.Height; y++) for (y = 0; y < map.Height; y++)
{ {
if (fillArea[x, y] == true) if (fillArea[x, y])
{ {
map[x, y] -= strength; map[x, y] -= strength;
} }

View File

@ -25,6 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using OpenSim.Framework;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
@ -40,9 +41,9 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
{ {
for (y = 0; y < map.Height; y++) for (y = 0; y < map.Height; y++)
{ {
if (fillArea[x, y] == true) if (fillArea[x, y])
{ {
double noise = TerrainUtil.PerlinNoise2D((double)x / (double)Framework.Constants.RegionSize, (double)y / (double)Framework.Constants.RegionSize, 8, 1.0); double noise = TerrainUtil.PerlinNoise2D((double) x / Constants.RegionSize, (double) y / Constants.RegionSize, 8, 1.0);
map[x, y] += noise * strength; map[x, y] += noise * strength;
} }

View File

@ -40,7 +40,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
{ {
for (y = 0; y < map.Height; y++) for (y = 0; y < map.Height; y++)
{ {
if (fillArea[x, y] == true) if (fillArea[x, y])
{ {
map[x, y] += strength; map[x, y] += strength;
} }

View File

@ -31,7 +31,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
{ {
public class RevertArea : ITerrainFloodEffect public class RevertArea : ITerrainFloodEffect
{ {
ITerrainChannel m_revertmap; private readonly ITerrainChannel m_revertmap;
public RevertArea(ITerrainChannel revertmap) public RevertArea(ITerrainChannel revertmap)
{ {
@ -47,7 +47,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
{ {
for (y = 0; y < map.Height; y++) for (y = 0; y < map.Height; y++)
{ {
if (fillArea[x, y] == true) if (fillArea[x, y])
{ {
map[x, y] = (map[x, y] * (1.0 - strength)) + (m_revertmap[x, y] * strength); map[x, y] = (map[x, y] * (1.0 - strength)) + (m_revertmap[x, y] * strength);
} }

View File

@ -31,7 +31,54 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
{ {
public class SmoothArea : ITerrainFloodEffect public class SmoothArea : ITerrainFloodEffect
{ {
private double GetBilinearInterpolate(double x, double y, ITerrainChannel map) #region ITerrainFloodEffect Members
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
{
double area = strength;
double step = strength / 4.0;
double[,] manipulate = new double[map.Width,map.Height];
int x, y;
for (x = 0; x < map.Width; x++)
{
for (y = 0; y < map.Height; y++)
{
if (!fillArea[x, y])
continue;
double average = 0.0;
int avgsteps = 0;
double n;
for (n = 0.0 - area; n < area; n += step)
{
double l;
for (l = 0.0 - area; l < area; l += step)
{
avgsteps++;
average += GetBilinearInterpolate(x + n, y + l, map);
}
}
manipulate[x, y] = average / avgsteps;
}
}
for (x = 0; x < map.Width; x++)
{
for (y = 0; y < map.Height; y++)
{
if (!fillArea[x, y])
continue;
map[x, y] = manipulate[x, y];
}
}
}
#endregion
private static double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
{ {
int w = map.Width; int w = map.Width;
int h = map.Height; int h = map.Height;
@ -63,51 +110,5 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz); double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
return hi; return hi;
} }
#region ITerrainFloodEffect Members
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
{
double area = strength;
double step = strength / 4.0;
double[,] manipulate = new double[map.Width, map.Height];
int x, y;
double n, l;
for (x = 0; x < map.Width; x++)
{
for (y = 0; y < map.Height; y++)
{
if (!fillArea[x, y])
continue;
double average = 0.0;
int avgsteps = 0;
for (n = 0.0 - area; n < area; n += step)
{
for (l = 0.0 - area; l < area; l += step)
{
avgsteps++;
average += GetBilinearInterpolate(x + n, y + l, map);
}
}
manipulate[x, y] = average / avgsteps;
}
}
for (x = 0; x < map.Width; x++)
{
for (y = 0; y < map.Height; y++)
{
if (!fillArea[x, y])
continue;
map[x, y] = manipulate[x, y];
}
}
}
#endregion
} }
} }

View File

@ -25,8 +25,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using OpenSim.Region.Environment.Interfaces;
using System; using System;
using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Modules.Terrain namespace OpenSim.Region.Environment.Modules.Terrain
{ {

View File

@ -1,5 +1,4 @@
using System; namespace OpenSim.Region.Environment.Modules.Terrain
namespace OpenSim.Region.Environment.Modules.Terrain
{ {
public interface ITerrainModule public interface ITerrainModule
{ {

View File

@ -26,20 +26,40 @@
*/ */
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using libsecondlife;
using Nini.Config; using Nini.Config;
using OpenSim.Framework; using OpenJPEGNet;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.Environment.Modules.ModuleFramework;
namespace OpenSim.Region.Environment.Modules.Terrain namespace OpenSim.Region.Environment.Modules.Terrain
{ {
class MapImageModule : IMapImageGenerator, IRegionModule internal class MapImageModule : IMapImageGenerator, IRegionModule
{ {
private Scene m_scene; private Scene m_scene;
#region IMapImageGenerator Members
public byte[] WriteJpeg2000Image(string gradientmap)
{
byte[] imageData = null;
Bitmap bmp = TerrainToBitmap(gradientmap);
try
{
imageData = OpenJPEG.EncodeFromImage(bmp, true);
}
catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke
{
Console.WriteLine("Failed generating terrain map: " + e);
}
return imageData;
}
#endregion
#region IRegionModule Members #region IRegionModule Members
public void Initialise(Scene scene, IConfigSource source) public void Initialise(Scene scene, IConfigSource source)
@ -66,24 +86,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain
get { return false; } get { return false; }
} }
#endregion
public byte[] WriteJpeg2000Image(string gradientmap)
{
byte[] imageData = null;
Bitmap bmp = TerrainToBitmap(gradientmap);
try
{
imageData = OpenJPEGNet.OpenJPEG.EncodeFromImage(bmp, true);
}
catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke
{
Console.WriteLine("Failed generating terrain map: " + e.ToString());
}
return imageData;
}
private void ShadeBuildings(ref Bitmap map) private void ShadeBuildings(ref Bitmap map)
{ {
@ -99,14 +102,16 @@ namespace OpenSim.Region.Environment.Modules.Terrain
foreach (SceneObjectPart primitive in sog.Children.Values) foreach (SceneObjectPart primitive in sog.Children.Values)
{ {
int x, y, w, h, dx, dy; int x, y, w, h;
x = (int) (primitive.AbsolutePosition.X - (primitive.Scale.X / 2)); x = (int) (primitive.AbsolutePosition.X - (primitive.Scale.X / 2));
y = (int) (primitive.AbsolutePosition.Y - (primitive.Scale.Y / 2)); y = (int) (primitive.AbsolutePosition.Y - (primitive.Scale.Y / 2));
w = (int) primitive.Scale.X; w = (int) primitive.Scale.X;
h = (int) primitive.Scale.Y; h = (int) primitive.Scale.Y;
int dx;
for (dx = x; dx < x + w; dx++) for (dx = x; dx < x + w; dx++)
{ {
int dy;
for (dy = y; dy < y + h; dy++) for (dy = y; dy < y + h; dy++)
{ {
if (x < 0 || y < 0) if (x < 0 || y < 0)
@ -117,8 +122,6 @@ namespace OpenSim.Region.Environment.Modules.Terrain
map.SetPixel(dx, dy, Color.DarkGray); map.SetPixel(dx, dy, Color.DarkGray);
} }
} }
} }
} }
} }
@ -161,7 +164,5 @@ namespace OpenSim.Region.Environment.Modules.Terrain
return bmp; return bmp;
} }
} }
#endregion
} }
} }

View File

@ -25,8 +25,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using OpenSim.Region.Environment.Interfaces;
using System; using System;
using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
{ {
@ -35,18 +35,12 @@ namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
/// </summary> /// </summary>
public class ErodeSphere : ITerrainPaintableEffect public class ErodeSphere : ITerrainPaintableEffect
{ {
NeighbourSystem type = NeighbourSystem.Moore; // Parameter private double rainHeight = 0.2;
private int rounds = 10;
double rainHeight = 0.2; private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
int rounds = 10; private double waterSaturation = 0.30; // Can carry 1% of water in height
double waterSaturation = 0.30; // Can carry 1% of water in height
#region Supporting Functions #region Supporting Functions
private enum NeighbourSystem
{
Moore,
VonNeumann
} ;
private int[] Neighbours(NeighbourSystem type, int index) private int[] Neighbours(NeighbourSystem type, int index)
{ {
@ -146,6 +140,12 @@ namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
return coord; return coord;
} }
private enum NeighbourSystem
{
Moore,
VonNeumann
} ;
#endregion #endregion
#region ITerrainPaintableEffect Members #region ITerrainPaintableEffect Members

View File

@ -31,12 +31,6 @@ namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
{ {
public class FlattenSphere : ITerrainPaintableEffect public class FlattenSphere : ITerrainPaintableEffect
{ {
private double SphericalFactor(double x, double y, double rx, double ry, double size)
{
double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
return z;
}
// TODO: unused // TODO: unused
// private double GetBilinearInterpolate(double x, double y, ITerrainChannel map) // private double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
// { // {
@ -123,5 +117,11 @@ namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
} }
#endregion #endregion
private double SphericalFactor(double x, double y, double rx, double ry, double size)
{
double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
return z;
}
} }
} }

View File

@ -57,7 +57,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
z *= z; z *= z;
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
double noise = TerrainUtil.PerlinNoise2D((double)x / (double)Framework.Constants.RegionSize, (double)y / (double)Framework.Constants.RegionSize, 8, 1.0); double noise = TerrainUtil.PerlinNoise2D((double) x / (double) Constants.RegionSize, (double) y / (double) Constants.RegionSize, 8, 1.0);
if (z > 0.0) if (z > 0.0)
map[x, y] += noise * z * duration; map[x, y] += noise * z * duration;

View File

@ -25,8 +25,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using OpenSim.Region.Environment.Interfaces;
using System; using System;
using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
{ {
@ -38,16 +38,10 @@ namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
/// </summary> /// </summary>
public class OlsenSphere : ITerrainPaintableEffect public class OlsenSphere : ITerrainPaintableEffect
{ {
NeighbourSystem type = NeighbourSystem.Moore; // Parameter private double nConst = 1024.0;
private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
double nConst = 1024.0;
#region Supporting Functions #region Supporting Functions
private enum NeighbourSystem
{
Moore,
VonNeumann
} ;
private int[] Neighbours(NeighbourSystem type, int index) private int[] Neighbours(NeighbourSystem type, int index)
{ {
@ -153,6 +147,12 @@ namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
return z; return z;
} }
private enum NeighbourSystem
{
Moore,
VonNeumann
} ;
#endregion #endregion
#region ITerrainPaintableEffect Members #region ITerrainPaintableEffect Members

View File

@ -32,7 +32,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
{ {
public class RevertSphere : ITerrainPaintableEffect public class RevertSphere : ITerrainPaintableEffect
{ {
ITerrainChannel m_revertmap; private ITerrainChannel m_revertmap;
public RevertSphere(ITerrainChannel revertmap) public RevertSphere(ITerrainChannel revertmap)
{ {

View File

@ -34,15 +34,10 @@ namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
/// </summary> /// </summary>
public class WeatherSphere : ITerrainPaintableEffect public class WeatherSphere : ITerrainPaintableEffect
{ {
NeighbourSystem type = NeighbourSystem.Moore; // Parameter private double talus = 0.2; // Number of meters max difference before stop eroding. Tweakage required.
double talus = 0.2; // Number of meters max difference before stop eroding. Tweakage required. private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
#region Supporting Functions #region Supporting Functions
private enum NeighbourSystem
{
Moore,
VonNeumann
} ;
private int[] Neighbours(NeighbourSystem type, int index) private int[] Neighbours(NeighbourSystem type, int index)
{ {
@ -142,6 +137,12 @@ namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
return coord; return coord;
} }
private enum NeighbourSystem
{
Moore,
VonNeumann
} ;
#endregion #endregion
#region ITerrainPaintableEffect Members #region ITerrainPaintableEffect Members

View File

@ -35,90 +35,18 @@ namespace OpenSim.Region.Environment.Modules.Terrain
/// </summary> /// </summary>
public class TerrainChannel : ITerrainChannel public class TerrainChannel : ITerrainChannel
{ {
private readonly bool[,] taint;
private double[,] map; private double[,] map;
private bool[,] taint;
public int Width
{
get { return map.GetLength(0); }
}
public int Height
{
get { return map.GetLength(1); }
}
public TerrainChannel Copy()
{
TerrainChannel copy = new TerrainChannel(false);
copy.map = (double[,])this.map.Clone();
return copy;
}
public ITerrainChannel MakeCopy()
{
TerrainChannel copy = new TerrainChannel(false);
copy.map = (double[,])this.map.Clone();
return copy;
}
public float[] GetFloatsSerialised()
{
float[] heights = new float[Width * Height];
int i;
for (i = 0; i < Width * Height; i++)
{
heights[i] = (float)map[i % Width, i / Width];
}
return heights;
}
public double[,] GetDoubles()
{
return map;
}
public double this[int x, int y]
{
get
{
return map[x, y];
}
set
{
if (map[x, y] != value)
{
taint[x / 16, y / 16] = true;
map[x, y] = value;
}
}
}
public bool Tainted(int x, int y)
{
if (taint[x / 16, y / 16] != false)
{
taint[x / 16, y / 16] = false;
return true;
}
else
{
return false;
}
}
public TerrainChannel() public TerrainChannel()
{ {
map = new double[Constants.RegionSize,Constants.RegionSize]; map = new double[Constants.RegionSize,Constants.RegionSize];
taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16]; taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
int x, y; int x;
for (x = 0; x < Constants.RegionSize; x++) for (x = 0; x < Constants.RegionSize; x++)
{ {
int y;
for (y = 0; y < Constants.RegionSize; y++) for (y = 0; y < Constants.RegionSize; y++)
{ {
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10; map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10;
@ -151,5 +79,79 @@ namespace OpenSim.Region.Environment.Modules.Terrain
map = new double[w,h]; map = new double[w,h];
taint = new bool[w / 16,h / 16]; taint = new bool[w / 16,h / 16];
} }
#region ITerrainChannel Members
public int Width
{
get { return map.GetLength(0); }
}
public int Height
{
get { return map.GetLength(1); }
}
public ITerrainChannel MakeCopy()
{
TerrainChannel copy = new TerrainChannel(false);
copy.map = (double[,]) map.Clone();
return copy;
}
public float[] GetFloatsSerialised()
{
float[] heights = new float[Width * Height];
int i;
for (i = 0; i < Width * Height; i++)
{
heights[i] = (float) map[i % Width, i / Width];
}
return heights;
}
public double[,] GetDoubles()
{
return map;
}
public double this[int x, int y]
{
get { return map[x, y]; }
set
{
if (map[x, y] != value)
{
taint[x / 16, y / 16] = true;
map[x, y] = value;
}
}
}
public bool Tainted(int x, int y)
{
if (taint[x / 16, y / 16])
{
taint[x / 16, y / 16] = false;
return true;
}
else
{
return false;
}
}
#endregion
public TerrainChannel Copy()
{
TerrainChannel copy = new TerrainChannel(false);
copy.map = (double[,]) map.Clone();
return copy;
}
} }
} }

View File

@ -27,18 +27,29 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.IO;
using System.Reflection;
using libsecondlife; using libsecondlife;
using log4net;
using Nini.Config; using Nini.Config;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.Environment.Modules.ModuleFramework; using OpenSim.Region.Environment.Modules.ModuleFramework;
using OpenSim.Region.Environment.Modules.Terrain.Effects;
using OpenSim.Region.Environment.Modules.Terrain.FileLoaders;
using OpenSim.Region.Environment.Modules.Terrain.FloodBrushes;
using OpenSim.Region.Environment.Modules.Terrain.PaintBrushes;
using OpenSim.Region.Environment.Scenes;
namespace OpenSim.Region.Environment.Modules.Terrain namespace OpenSim.Region.Environment.Modules.Terrain
{ {
public class TerrainModule : IRegionModule, ICommandableModule, OpenSim.Region.Environment.Modules.Terrain.ITerrainModule public class TerrainModule : IRegionModule, ICommandableModule, ITerrainModule
{ {
#region StandardTerrainEffects enum
/// <summary>
/// A standard set of terrain brushes and effects recognised by viewers
/// </summary>
public enum StandardTerrainEffects : byte public enum StandardTerrainEffects : byte
{ {
Flatten = 0, Flatten = 0,
@ -54,150 +65,44 @@ namespace OpenSim.Region.Environment.Modules.Terrain
Olsen = 253 Olsen = 253
} }
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); #endregion
private Commander m_commander = new Commander("Terrain"); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = private readonly Commander m_commander = new Commander("Terrain");
new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>();
private Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects = private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects =
new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>(); new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>();
private Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>();
Scene m_scene;
ITerrainChannel m_channel;
ITerrainChannel m_revert;
bool m_tainted = false;
private IConfigSource m_gConfig;
private void InstallDefaultEffects() private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>();
private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects =
new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>();
private ITerrainChannel m_channel;
private ITerrainChannel m_revert;
private Scene m_scene;
private bool m_tainted = false;
#region ICommandableModule Members
public ICommander CommandInterface
{ {
// Draggable Paint Brush Effects get { return m_commander; }
m_painteffects[StandardTerrainEffects.Raise] = new PaintBrushes.RaiseSphere();
m_painteffects[StandardTerrainEffects.Lower] = new PaintBrushes.LowerSphere();
m_painteffects[StandardTerrainEffects.Smooth] = new PaintBrushes.SmoothSphere();
m_painteffects[StandardTerrainEffects.Noise] = new PaintBrushes.NoiseSphere();
m_painteffects[StandardTerrainEffects.Flatten] = new PaintBrushes.FlattenSphere();
m_painteffects[StandardTerrainEffects.Revert] = new PaintBrushes.RevertSphere(m_revert);
m_painteffects[StandardTerrainEffects.Erode] = new PaintBrushes.ErodeSphere();
m_painteffects[StandardTerrainEffects.Weather] = new PaintBrushes.WeatherSphere();
m_painteffects[StandardTerrainEffects.Olsen] = new PaintBrushes.OlsenSphere();
// Area of effect selection effects
m_floodeffects[StandardTerrainEffects.Raise] = new FloodBrushes.RaiseArea();
m_floodeffects[StandardTerrainEffects.Lower] = new FloodBrushes.LowerArea();
m_floodeffects[StandardTerrainEffects.Smooth] = new FloodBrushes.SmoothArea();
m_floodeffects[StandardTerrainEffects.Noise] = new FloodBrushes.NoiseArea();
m_floodeffects[StandardTerrainEffects.Flatten] = new FloodBrushes.FlattenArea();
m_floodeffects[StandardTerrainEffects.Revert] = new FloodBrushes.RevertArea(m_revert);
// Filesystem load/save loaders
m_loaders[".r32"] = new FileLoaders.RAW32();
m_loaders[".f32"] = m_loaders[".r32"];
m_loaders[".ter"] = new FileLoaders.Terragen();
m_loaders[".raw"] = new FileLoaders.LLRAW();
m_loaders[".jpg"] = new FileLoaders.JPEG();
m_loaders[".jpeg"] = m_loaders[".jpg"];
m_loaders[".bmp"] = new FileLoaders.BMP();
m_loaders[".png"] = new FileLoaders.PNG();
m_loaders[".gif"] = new FileLoaders.GIF();
m_loaders[".tif"] = new FileLoaders.TIFF();
m_loaders[".tiff"] = m_loaders[".tif"];
} }
public void UpdateRevertMap() #endregion
{
int x, y;
for (x = 0; x < m_channel.Width; x++)
{
for (y = 0; y < m_channel.Height; y++)
{
m_revert[x, y] = m_channel[x, y];
}
}
}
public void LoadFromFile(string filename) #region IRegionModule Members
{
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
{
if (filename.EndsWith(loader.Key))
{
lock (m_scene)
{
try
{
ITerrainChannel channel = loader.Value.LoadFile(filename);
m_scene.Heightmap = channel;
m_channel = channel;
UpdateRevertMap();
}
catch (NotImplementedException)
{
m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value.ToString() + " parser does not support file loading. (May be save only)");
return;
}
catch (System.IO.FileNotFoundException)
{
m_log.Error("[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)");
return;
}
}
m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully");
return;
}
}
m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format.");
}
public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
{
int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX;
int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY;
if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight)
{
// this region is included in the tile request
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
{
if (filename.EndsWith(loader.Key))
{
lock (m_scene)
{
ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY,
fileWidth, fileHeight, (int)Constants.RegionSize, (int)Constants.RegionSize);
m_scene.Heightmap = channel;
m_channel = channel;
UpdateRevertMap();
}
return;
}
}
}
}
public void SaveToFile(string filename)
{
try
{
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
{
if (filename.EndsWith(loader.Key))
{
loader.Value.SaveFile(filename, m_channel);
return;
}
}
}
catch (NotImplementedException)
{
m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented.");
}
}
/// <summary>
/// Creates and initialises a terrain module for a region
/// </summary>
/// <param name="scene">Region initialising</param>
/// <param name="config">Config for the region</param>
public void Initialise(Scene scene, IConfigSource config) public void Initialise(Scene scene, IConfigSource config)
{ {
m_scene = scene; m_scene = scene;
m_gConfig = config;
// Install terrain module in the simulator // Install terrain module in the simulator
if (m_scene.Heightmap == null) if (m_scene.Heightmap == null)
@ -223,13 +128,318 @@ namespace OpenSim.Region.Environment.Modules.Terrain
m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick; m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick;
} }
void EventManager_OnTerrainTick() /// <summary>
/// Enables terrain module when called
/// </summary>
public void PostInitialise()
{
InstallDefaultEffects();
InstallInterfaces();
}
public void Close()
{
}
public string Name
{
get { return "TerrainModule"; }
}
public bool IsSharedModule
{
get { return false; }
}
#endregion
#region ITerrainModule Members
/// <summary>
/// Loads a terrain file from disk and installs it in the scene.
/// </summary>
/// <param name="filename">Filename to terrain file. Type is determined by extension.</param>
public void LoadFromFile(string filename)
{
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
{
if (filename.EndsWith(loader.Key))
{
lock (m_scene)
{
try
{
ITerrainChannel channel = loader.Value.LoadFile(filename);
m_scene.Heightmap = channel;
m_channel = channel;
UpdateRevertMap();
}
catch (NotImplementedException)
{
m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value +
" parser does not support file loading. (May be save only)");
return;
}
catch (FileNotFoundException)
{
m_log.Error(
"[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)");
return;
}
}
m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully");
return;
}
}
m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format.");
}
/// <summary>
/// Saves the current heightmap to a specified file.
/// </summary>
/// <param name="filename">The destination filename</param>
public void SaveToFile(string filename)
{
try
{
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
{
if (filename.EndsWith(loader.Key))
{
loader.Value.SaveFile(filename, m_channel);
return;
}
}
}
catch (NotImplementedException)
{
m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented.");
}
}
#endregion
/// <summary>
/// Installs into terrain module the standard suite of brushes
/// </summary>
private void InstallDefaultEffects()
{
// Draggable Paint Brush Effects
m_painteffects[StandardTerrainEffects.Raise] = new RaiseSphere();
m_painteffects[StandardTerrainEffects.Lower] = new LowerSphere();
m_painteffects[StandardTerrainEffects.Smooth] = new SmoothSphere();
m_painteffects[StandardTerrainEffects.Noise] = new NoiseSphere();
m_painteffects[StandardTerrainEffects.Flatten] = new FlattenSphere();
m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_revert);
m_painteffects[StandardTerrainEffects.Erode] = new ErodeSphere();
m_painteffects[StandardTerrainEffects.Weather] = new WeatherSphere();
m_painteffects[StandardTerrainEffects.Olsen] = new OlsenSphere();
// Area of effect selection effects
m_floodeffects[StandardTerrainEffects.Raise] = new RaiseArea();
m_floodeffects[StandardTerrainEffects.Lower] = new LowerArea();
m_floodeffects[StandardTerrainEffects.Smooth] = new SmoothArea();
m_floodeffects[StandardTerrainEffects.Noise] = new NoiseArea();
m_floodeffects[StandardTerrainEffects.Flatten] = new FlattenArea();
m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_revert);
// Filesystem load/save loaders
m_loaders[".r32"] = new RAW32();
m_loaders[".f32"] = m_loaders[".r32"];
m_loaders[".ter"] = new Terragen();
m_loaders[".raw"] = new LLRAW();
m_loaders[".jpg"] = new JPEG();
m_loaders[".jpeg"] = m_loaders[".jpg"];
m_loaders[".bmp"] = new BMP();
m_loaders[".png"] = new PNG();
m_loaders[".gif"] = new GIF();
m_loaders[".tif"] = new TIFF();
m_loaders[".tiff"] = m_loaders[".tif"];
}
/// <summary>
/// Saves the current state of the region into the revert map buffer.
/// </summary>
public void UpdateRevertMap()
{
int x;
for (x = 0; x < m_channel.Width; x++)
{
int y;
for (y = 0; y < m_channel.Height; y++)
{
m_revert[x, y] = m_channel[x, y];
}
}
}
/// <summary>
/// Loads a tile from a larger terrain file and installs it into the region.
/// </summary>
/// <param name="filename">The terrain file to load</param>
/// <param name="fileWidth">The width of the file in units</param>
/// <param name="fileHeight">The height of the file in units</param>
/// <param name="fileStartX">Where to begin our slice</param>
/// <param name="fileStartY">Where to begin our slice</param>
public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
{
int offsetX = (int) m_scene.RegionInfo.RegionLocX - fileStartX;
int offsetY = (int) m_scene.RegionInfo.RegionLocY - fileStartY;
if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight)
{
// this region is included in the tile request
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
{
if (filename.EndsWith(loader.Key))
{
lock (m_scene)
{
ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY,
fileWidth, fileHeight,
(int) Constants.RegionSize,
(int) Constants.RegionSize);
m_scene.Heightmap = channel;
m_channel = channel;
UpdateRevertMap();
}
return;
}
}
}
}
/// <summary>
/// Performs updates to the region periodically, synchronising physics and other heightmap aware sections
/// </summary>
private void EventManager_OnTerrainTick()
{ {
if (m_tainted) if (m_tainted)
{ {
m_tainted = false; m_tainted = false;
m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised()); m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised());
m_scene.SaveTerrain(); m_scene.SaveTerrain();
m_scene.CreateTerrainTexture(true);
}
}
/// <summary>
/// Processes commandline input. Do not call directly.
/// </summary>
/// <param name="args">Commandline arguments</param>
private void EventManager_OnPluginConsole(string[] args)
{
if (args[0] == "terrain")
{
string[] tmpArgs = new string[args.Length - 2];
int i;
for (i = 2; i < args.Length; i++)
tmpArgs[i - 2] = args[i];
m_commander.ProcessConsoleCommand(args[1], tmpArgs);
}
}
/// <summary>
/// Installs terrain brush hook to IClientAPI
/// </summary>
/// <param name="client"></param>
private void EventManager_OnNewClient(IClientAPI client)
{
client.OnModifyTerrain += client_OnModifyTerrain;
}
/// <summary>
/// Checks to see if the terrain has been modified since last check
/// </summary>
private void CheckForTerrainUpdates()
{
bool shouldTaint = false;
float[] serialised = m_channel.GetFloatsSerialised();
int x;
for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize)
{
int y;
for (y = 0; y < m_channel.Height; y += Constants.TerrainPatchSize)
{
if (m_channel.Tainted(x, y))
{
SendToClients(serialised, x, y);
shouldTaint = true;
}
}
}
if (shouldTaint)
{
m_tainted = true;
}
}
/// <summary>
/// Sends a copy of the current terrain to the scenes clients
/// </summary>
/// <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[] serialised, int x, int y)
{
m_scene.ForEachClient(
delegate(IClientAPI controller) { controller.SendLayerData(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised); });
}
private void client_OnModifyTerrain(float height, float seconds, byte size, byte action, float north, float west,
float south, float east, IClientAPI remoteClient)
{
// Not a good permissions check, if in area mode, need to check the entire area.
if (m_scene.PermissionsMngr.CanTerraform(remoteClient.AgentId, new LLVector3(north, west, 0)))
{
if (north == south && east == west)
{
if (m_painteffects.ContainsKey((StandardTerrainEffects) action))
{
m_painteffects[(StandardTerrainEffects) action].PaintEffect(
m_channel, west, south, size, seconds);
CheckForTerrainUpdates();
}
else
{
m_log.Debug("Unknown terrain brush type " + action);
}
}
else
{
if (m_floodeffects.ContainsKey((StandardTerrainEffects) action))
{
bool[,] fillArea = new bool[m_channel.Width,m_channel.Height];
fillArea.Initialize();
int x;
for (x = 0; x < m_channel.Width; x++)
{
int y;
for (y = 0; y < m_channel.Height; y++)
{
if (x < east && x > west)
{
if (y < north && y > south)
{
fillArea[x, y] = true;
}
}
}
}
m_floodeffects[(StandardTerrainEffects) action].FloodEffect(
m_channel, fillArea, size);
CheckForTerrainUpdates();
}
else
{
m_log.Debug("Unknown terrain flood type " + action);
}
}
} }
} }
@ -312,12 +522,13 @@ namespace OpenSim.Region.Environment.Modules.Terrain
{ {
double max = Double.MinValue; double max = Double.MinValue;
double min = double.MaxValue; double min = double.MaxValue;
double avg = 0; double avg;
double sum = 0; double sum = 0;
int x, y; int x;
for (x = 0; x < m_channel.Width; x++) for (x = 0; x < m_channel.Width; x++)
{ {
int y;
for (y = 0; y < m_channel.Height; y++) for (y = 0; y < m_channel.Height; y++)
{ {
sum += m_channel[x, y]; sum += m_channel[x, y];
@ -338,9 +549,9 @@ namespace OpenSim.Region.Environment.Modules.Terrain
{ {
if ((bool) args[0]) if ((bool) args[0])
{ {
m_painteffects[StandardTerrainEffects.Revert] = new PaintBrushes.WeatherSphere(); m_painteffects[StandardTerrainEffects.Revert] = new WeatherSphere();
m_painteffects[StandardTerrainEffects.Flatten] = new PaintBrushes.OlsenSphere(); m_painteffects[StandardTerrainEffects.Flatten] = new OlsenSphere();
m_painteffects[StandardTerrainEffects.Smooth] = new PaintBrushes.ErodeSphere(); m_painteffects[StandardTerrainEffects.Smooth] = new ErodeSphere();
} }
else else
{ {
@ -350,7 +561,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain
private void InterfacePerformEffectTest(Object[] args) private void InterfacePerformEffectTest(Object[] args)
{ {
Effects.CookieCutter cookie = new OpenSim.Region.Environment.Modules.Terrain.Effects.CookieCutter(); CookieCutter cookie = new CookieCutter();
cookie.RunEffect(m_channel); cookie.RunEffect(m_channel);
} }
@ -359,45 +570,68 @@ namespace OpenSim.Region.Environment.Modules.Terrain
// Load / Save // Load / Save
string supportedFileExtensions = ""; string supportedFileExtensions = "";
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
supportedFileExtensions += " " + loader.Key + " (" + loader.Value.ToString() + ")"; supportedFileExtensions += " " + loader.Key + " (" + loader.Value + ")";
Command loadFromFileCommand = new Command("load", InterfaceLoadFile, "Loads a terrain from a specified file."); Command loadFromFileCommand =
loadFromFileCommand.AddArgument("filename", "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " + supportedFileExtensions, "String"); new Command("load", InterfaceLoadFile, "Loads a terrain from a specified file.");
loadFromFileCommand.AddArgument("filename",
"The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " +
supportedFileExtensions, "String");
Command saveToFileCommand = new Command("save", InterfaceSaveFile, "Saves the current heightmap to a specified file."); Command saveToFileCommand =
saveToFileCommand.AddArgument("filename", "The destination filename for your heightmap, the file extension determines the format to save in. Supported extensions include: " + supportedFileExtensions, "String"); new Command("save", InterfaceSaveFile, "Saves the current heightmap to a specified file.");
saveToFileCommand.AddArgument("filename",
"The destination filename for your heightmap, the file extension determines the format to save in. Supported extensions include: " +
supportedFileExtensions, "String");
Command loadFromTileCommand = new Command("load-tile", InterfaceLoadTileFile, "Loads a terrain from a section of a larger file."); Command loadFromTileCommand =
loadFromTileCommand.AddArgument("filename", "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " + supportedFileExtensions, "String"); new Command("load-tile", InterfaceLoadTileFile, "Loads a terrain from a section of a larger file.");
loadFromTileCommand.AddArgument("filename",
"The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " +
supportedFileExtensions, "String");
loadFromTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer"); loadFromTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer");
loadFromTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer"); loadFromTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer");
loadFromTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file", "Integer"); loadFromTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file",
loadFromTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", "Integer"); "Integer");
loadFromTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file",
"Integer");
// Terrain adjustments // Terrain adjustments
Command fillRegionCommand = new Command("fill", InterfaceFillTerrain, "Fills the current heightmap with a specified value."); Command fillRegionCommand =
fillRegionCommand.AddArgument("value", "The numeric value of the height you wish to set your region to.", "Double"); new Command("fill", InterfaceFillTerrain, "Fills the current heightmap with a specified value.");
fillRegionCommand.AddArgument("value", "The numeric value of the height you wish to set your region to.",
"Double");
Command elevateCommand = new Command("elevate", InterfaceElevateTerrain, "Raises the current heightmap by the specified amount."); Command elevateCommand =
new Command("elevate", InterfaceElevateTerrain, "Raises the current heightmap by the specified amount.");
elevateCommand.AddArgument("amount", "The amount of height to add to the terrain in meters.", "Double"); elevateCommand.AddArgument("amount", "The amount of height to add to the terrain in meters.", "Double");
Command lowerCommand = new Command("lower", InterfaceLowerTerrain, "Lowers the current heightmap by the specified amount."); Command lowerCommand =
new Command("lower", InterfaceLowerTerrain, "Lowers the current heightmap by the specified amount.");
lowerCommand.AddArgument("amount", "The amount of height to remove from the terrain in meters.", "Double"); lowerCommand.AddArgument("amount", "The amount of height to remove from the terrain in meters.", "Double");
Command multiplyCommand = new Command("multiply", InterfaceMultiplyTerrain, "Multiplies the heightmap by the value specified."); Command multiplyCommand =
new Command("multiply", InterfaceMultiplyTerrain, "Multiplies the heightmap by the value specified.");
multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double"); multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double");
Command bakeRegionCommand = new Command("bake", InterfaceBakeTerrain, "Saves the current terrain into the regions revert map."); Command bakeRegionCommand =
Command revertRegionCommand = new Command("revert", InterfaceRevertTerrain, "Loads the revert map terrain into the regions heightmap."); new Command("bake", InterfaceBakeTerrain, "Saves the current terrain into the regions revert map.");
Command revertRegionCommand =
new Command("revert", InterfaceRevertTerrain, "Loads the revert map terrain into the regions heightmap.");
// Debug // Debug
Command showDebugStatsCommand = new Command("stats", InterfaceShowDebugStats, "Shows some information about the regions heightmap for debugging purposes."); Command showDebugStatsCommand =
new Command("stats", InterfaceShowDebugStats,
"Shows some information about the regions heightmap for debugging purposes.");
Command experimentalBrushesCommand = new Command("newbrushes", InterfaceEnableExperimentalBrushes, "Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time."); Command experimentalBrushesCommand =
new Command("newbrushes", 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"); experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean");
// Effects // Effects
Command effectsTestCommand = new Command("test", InterfacePerformEffectTest, "Performs an effects module test"); Command effectsTestCommand =
new Command("test", InterfacePerformEffectTest, "Performs an effects module test");
m_commander.RegisterCommand("load", loadFromFileCommand); m_commander.RegisterCommand("load", loadFromFileCommand);
m_commander.RegisterCommand("load-tile", loadFromTileCommand); m_commander.RegisterCommand("load-tile", loadFromTileCommand);
@ -417,147 +651,5 @@ namespace OpenSim.Region.Environment.Modules.Terrain
} }
#endregion #endregion
void EventManager_OnPluginConsole(string[] args)
{
if (args[0] == "terrain")
{
string[] tmpArgs = new string[args.Length - 2];
int i = 0;
for (i = 2; i < args.Length; i++)
tmpArgs[i - 2] = args[i];
m_commander.ProcessConsoleCommand(args[1], tmpArgs);
}
}
void EventManager_OnNewClient(IClientAPI client)
{
client.OnModifyTerrain += client_OnModifyTerrain;
}
void CheckForTerrainUpdates()
{
bool shouldTaint = false;
float[] serialised = m_channel.GetFloatsSerialised();
int x, y;
for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize)
{
for (y = 0; y < m_channel.Height; y += Constants.TerrainPatchSize)
{
if (m_channel.Tainted(x, y))
{
SendToClients(serialised, x, y);
shouldTaint = true;
}
}
}
if (shouldTaint)
{
m_tainted = true;
}
}
private void SendToClients(float[] serialised, int x, int y)
{
m_scene.ForEachClient(delegate(IClientAPI controller)
{
controller.SendLayerData(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised);
});
}
void client_OnModifyTerrain(float height, float seconds, byte size, byte action, float north, float west, float south, float east, IClientAPI remoteClient)
{
// Not a good permissions check, if in area mode, need to check the entire area.
if (m_scene.PermissionsMngr.CanTerraform(remoteClient.AgentId, new LLVector3(north, west, 0)))
{
if (north == south && east == west)
{
if (m_painteffects.ContainsKey((StandardTerrainEffects)action))
{
m_painteffects[(StandardTerrainEffects)action].PaintEffect(
m_channel, west, south, size, seconds);
bool usingTerrainModule = true;
if (usingTerrainModule)
{
CheckForTerrainUpdates();
}
}
else
{
m_log.Debug("Unknown terrain brush type " + action.ToString());
}
}
else
{
if (m_floodeffects.ContainsKey((StandardTerrainEffects)action))
{
bool[,] fillArea = new bool[m_channel.Width, m_channel.Height];
fillArea.Initialize();
int x, y;
for (x = 0; x < m_channel.Width; x++)
{
for (y = 0; y < m_channel.Height; y++)
{
if (x < east && x > west)
{
if (y < north && y > south)
{
fillArea[x, y] = true;
}
}
}
}
m_floodeffects[(StandardTerrainEffects)action].FloodEffect(
m_channel, fillArea, size);
bool usingTerrainModule = true;
if (usingTerrainModule)
{
CheckForTerrainUpdates();
}
}
else
{
m_log.Debug("Unknown terrain flood type " + action.ToString());
}
}
}
}
public void PostInitialise()
{
InstallDefaultEffects();
InstallInterfaces();
}
public void Close()
{
}
public string Name
{
get { return "TerrainModule"; }
}
public bool IsSharedModule
{
get { return false; }
}
#region ICommandable Members
public ICommander CommandInterface
{
get { return m_commander; }
}
#endregion
} }
} }

View File

@ -122,8 +122,8 @@ namespace OpenSim.Region.Environment.Modules.Terrain
for (int i = 0; i < octaves; i++) for (int i = 0; i < octaves; i++)
{ {
frequency = System.Math.Pow(2, i); frequency = Math.Pow(2, i);
amplitude = System.Math.Pow(persistence, i); amplitude = Math.Pow(persistence, i);
total += InterpolatedNoise(x * frequency, y * frequency) * amplitude; total += InterpolatedNoise(x * frequency, y * frequency) * amplitude;
} }