varregion: serious rework of TerrainChannel:
-- addition of varaible region size in X and Y -- internal storage of heightmap changed from double[] to short[] -- helper routines for handling internal structure while keeping existing API -- to and from XML that adds region size information (for downward compatibility, output in the legacy XML format if X and Y are 256) Updated and commented Constants.RegionSize but didn't change the name for compatibility.varregion
parent
7fa64cce7d
commit
fbc9072a5c
|
@ -30,9 +30,18 @@ namespace OpenSim.Framework
|
|||
{
|
||||
public class Constants
|
||||
{
|
||||
// 'RegionSize' captures the legacy region size.
|
||||
// DO NOT USE THIS FOR ANY NEW CODE. Use Scene.RegionSize[XYZ] as a region might not
|
||||
// be the legacy region size.
|
||||
public const uint RegionSize = 256;
|
||||
public const uint RegionHeight = 4096;
|
||||
|
||||
// Terrain heightmap is kept as shorts that are the float value times this compression factor
|
||||
public const float TerrainCompression = 100.0f;
|
||||
// Since terrain is stored in 16x16 heights, regions must be a multiple of this number and that is the minimum
|
||||
public const int MinRegionSize = 16;
|
||||
public const byte TerrainPatchSize = 16;
|
||||
|
||||
public const string DefaultTexture = "89556747-24cb-43ed-920b-47caed15465f";
|
||||
|
||||
public enum EstateAccessCodex : uint
|
||||
|
|
|
@ -472,7 +472,7 @@ namespace OpenSim.Framework
|
|||
/// The x co-ordinate of this region in map tiles (e.g. 1000).
|
||||
/// Coordinate is scaled as world coordinates divided by the legacy region size
|
||||
/// and is thus is the number of legacy regions.
|
||||
/// This entrypoint exists for downward compatability for external modules.
|
||||
/// DO NOT USE FOR NEW CODE! This entrypoint exists for downward compatability with external modules.
|
||||
/// </summary>
|
||||
public uint RegionLocX
|
||||
{
|
||||
|
@ -480,6 +480,18 @@ namespace OpenSim.Framework
|
|||
set { LegacyRegionLocX = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The y co-ordinate of this region in map tiles (e.g. 1000).
|
||||
/// Coordinate is scaled as world coordinates divided by the legacy region size
|
||||
/// and is thus is the number of legacy regions.
|
||||
/// DO NOT USE FOR NEW CODE! This entrypoint exists for downward compatability with external modules.
|
||||
/// </summary>
|
||||
public uint RegionLocY
|
||||
{
|
||||
get { return LegacyRegionLocY; }
|
||||
set { LegacyRegionLocY = value; }
|
||||
}
|
||||
|
||||
public void SetDefaultRegionSize()
|
||||
{
|
||||
RegionWorldLocX = 0;
|
||||
|
@ -490,19 +502,6 @@ namespace OpenSim.Framework
|
|||
RegionSizeZ = Constants.RegionHeight;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The y co-ordinate of this region in map tiles (e.g. 1000).
|
||||
/// Coordinate is scaled as world coordinates divided by the legacy region size
|
||||
/// and is thus is the number of legacy regions.
|
||||
/// This entrypoint exists for downward compatability for external modules.
|
||||
/// </summary>
|
||||
public uint RegionLocY
|
||||
{
|
||||
get { return LegacyRegionLocY; }
|
||||
set { LegacyRegionLocY = value; }
|
||||
}
|
||||
|
||||
// A unique region handle is created from the region's world coordinates.
|
||||
// This cannot be changed because some code expects to receive the region handle and then
|
||||
// compute the region coordinates from it.
|
||||
|
|
|
@ -1240,9 +1240,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
try
|
||||
{
|
||||
int[] patches = new int[] { py * 16 + px };
|
||||
float[] heightmap = (map.Length == 65536) ?
|
||||
map :
|
||||
LLHeightFieldMoronize(map);
|
||||
float[] heightmap = (map.Length == 65536) ? map : LLHeightFieldMoronize(map);
|
||||
|
||||
LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
|||
{
|
||||
using (Bitmap bitmap = new Bitmap(filename))
|
||||
{
|
||||
ITerrainChannel retval = new TerrainChannel(true);
|
||||
ITerrainChannel retval = new TerrainChannel(w, h);
|
||||
|
||||
for (int x = 0; x < retval.Width; x++)
|
||||
{
|
||||
|
|
|
@ -130,15 +130,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
|||
{
|
||||
if (m_scene.Heightmap == null)
|
||||
{
|
||||
m_channel = new TerrainChannel(m_InitialTerrain);
|
||||
m_channel = new TerrainChannel(m_InitialTerrain,
|
||||
m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY, m_scene.RegionInfo.RegionSizeZ);
|
||||
m_scene.Heightmap = m_channel;
|
||||
m_revert = new TerrainChannel();
|
||||
UpdateRevertMap();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_channel = m_scene.Heightmap;
|
||||
m_revert = new TerrainChannel();
|
||||
UpdateRevertMap();
|
||||
}
|
||||
|
||||
|
@ -532,6 +531,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
|||
/// </summary>
|
||||
public void UpdateRevertMap()
|
||||
{
|
||||
/*
|
||||
int x;
|
||||
for (x = 0; x < m_channel.Width; x++)
|
||||
{
|
||||
|
@ -541,6 +541,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
|||
m_revert[x, y] = m_channel[x, y];
|
||||
}
|
||||
}
|
||||
*/
|
||||
m_revert = m_channel.MakeCopy();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -134,26 +134,26 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
Dictionary<string, string> GetExtra(UUID regionID);
|
||||
|
||||
void Shutdown();
|
||||
}
|
||||
|
||||
// The terrain is stored as a blob in the database with a 'revision' field.
|
||||
// Some implementations of terrain storage would fill the revision field with
|
||||
// the time the terrain was stored. When real revisions were added and this
|
||||
// feature removed, that left some old entries with the time in the revision
|
||||
// field.
|
||||
// Thus, if revision is greater than 'RevisionHigh' then terrain db entry is
|
||||
// left over and it is presumed to be 'Legacy256'.
|
||||
// Numbers are arbitrary and are chosen to to reduce possible mis-interpretation.
|
||||
// If a revision does not match any of these, it is assumed to be Legacy256.
|
||||
public enum DBTerrainRevision
|
||||
{
|
||||
// Terrain is 'double[256,256]'
|
||||
Legacy256 = 11,
|
||||
// Terrain is 'int32, int32, float[,]' where the shorts are X and Y dimensions
|
||||
// The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
|
||||
Variable2D = 22,
|
||||
// A revision that is not listed above or any revision greater than this value is 'Legacy256'.
|
||||
RevisionHigh = 1234
|
||||
}
|
||||
|
||||
// The terrain is stored as a blob in the database with a 'revision' field.
|
||||
// Some implementations of terrain storage would fill the revision field with
|
||||
// the time the terrain was stored. When real revisions were added and this
|
||||
// feature removed, that left some old entries with the time in the revision
|
||||
// field.
|
||||
// Thus, if revision is greater than 'RevisionHigh' then terrain db entry is
|
||||
// left over and it is presumed to be 'Legacy256'.
|
||||
// Numbers are arbitrary and are chosen to to reduce possible mis-interpretation.
|
||||
// If a revision does not match any of these, it is assumed to be Legacy256.
|
||||
public enum DBTerrainRevision
|
||||
{
|
||||
// Terrain is 'double[256,256]'
|
||||
Legacy256 = 11,
|
||||
// Terrain is 'int32, int32, float[,]' where the shorts are X and Y dimensions
|
||||
// The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
|
||||
Variable2D = 22,
|
||||
// A revision that is not listed above or any revision greater than this value is 'Legacy256'.
|
||||
RevisionHigh = 1234
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,15 +29,21 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
{
|
||||
public interface ITerrainChannel
|
||||
{
|
||||
int Height { get; }
|
||||
int Width { get;} // X dimension
|
||||
int Height { get;} // Y dimension
|
||||
int Altitude { get;} // Z dimension
|
||||
|
||||
double this[int x, int y] { get; set; }
|
||||
int Width { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Squash the entire heightmap into a single dimensioned array
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
float[] GetFloatsSerialised();
|
||||
// Get version of map as a single dimensioned array and each value compressed
|
||||
// into an int (compressedHeight = (int)(floatHeight * Constants.TerrainCompression);)
|
||||
// This is done to make the map smaller as it can get pretty larger for variable sized regions.
|
||||
short[] GetCompressedMap();
|
||||
|
||||
double[,] GetDoubles();
|
||||
bool Tainted(int x, int y);
|
||||
|
|
|
@ -1905,13 +1905,13 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
|
||||
|
||||
m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain);
|
||||
Heightmap = new TerrainChannel(m_InitialTerrain);
|
||||
Heightmap = new TerrainChannel(m_InitialTerrain, RegionInfo.RegionSizeX, RegionInfo.RegionSizeY, RegionInfo.RegionSizeZ);
|
||||
|
||||
SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Heightmap = new TerrainChannel(map);
|
||||
Heightmap = new TerrainChannel(map, RegionInfo.RegionSizeZ);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
|
|
|
@ -40,132 +40,125 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </summary>
|
||||
public class TerrainChannel : ITerrainChannel
|
||||
{
|
||||
private readonly bool[,] taint;
|
||||
private double[,] map;
|
||||
protected bool[,] m_taint;
|
||||
protected short[] m_map;
|
||||
|
||||
public int Width { get; private set; } // X dimension
|
||||
// Unfortunately, for historical reasons, in this module 'Width' is X and 'Height' is Y
|
||||
public int Height { get; private set; } // Y dimension
|
||||
public int Altitude { get; private set; } // Y dimension
|
||||
|
||||
// Default, not-often-used builder
|
||||
public TerrainChannel()
|
||||
{
|
||||
map = new double[Constants.RegionSize, Constants.RegionSize];
|
||||
taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16];
|
||||
|
||||
PinHeadIsland();
|
||||
InitializeStructures(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight, false);
|
||||
FlatLand();
|
||||
// PinHeadIsland();
|
||||
}
|
||||
|
||||
public TerrainChannel(String type)
|
||||
// Create terrain of given size
|
||||
public TerrainChannel(int pX, int pY)
|
||||
{
|
||||
map = new double[Constants.RegionSize, Constants.RegionSize];
|
||||
taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16];
|
||||
InitializeStructures((uint)pX, (uint)pY, Constants.RegionHeight, true);
|
||||
}
|
||||
|
||||
// Create terrain of specified size and initialize with specified terrain.
|
||||
// TODO: join this with the terrain initializers.
|
||||
public TerrainChannel(String type, uint pX, uint pY, uint pZ)
|
||||
{
|
||||
InitializeStructures(pX, pY, pZ, false);
|
||||
if (type.Equals("flat"))
|
||||
FlatLand();
|
||||
else
|
||||
PinHeadIsland();
|
||||
}
|
||||
|
||||
public TerrainChannel(double[,] import)
|
||||
public TerrainChannel(double[,] pM, uint pH)
|
||||
{
|
||||
map = import;
|
||||
taint = new bool[import.GetLength(0),import.GetLength(1)];
|
||||
}
|
||||
|
||||
public TerrainChannel(bool createMap)
|
||||
{
|
||||
if (createMap)
|
||||
{
|
||||
map = new double[Constants.RegionSize,Constants.RegionSize];
|
||||
taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
|
||||
}
|
||||
}
|
||||
|
||||
public TerrainChannel(int w, int h)
|
||||
{
|
||||
map = new double[w,h];
|
||||
taint = new bool[w / 16,h / 16];
|
||||
InitializeStructures((uint)pM.GetLength(0), (uint)pM.GetLength(1), pH, false);
|
||||
int idx = 0;
|
||||
for (int ii = 0; ii < Height; ii++)
|
||||
for (int jj = 0; jj < Width; jj++)
|
||||
m_map[idx++] = ToCompressedHeight(pM[ii, jj]);
|
||||
}
|
||||
|
||||
#region ITerrainChannel Members
|
||||
|
||||
public int Width
|
||||
{
|
||||
get { return map.GetLength(0); }
|
||||
}
|
||||
|
||||
public int Height
|
||||
{
|
||||
get { return map.GetLength(1); }
|
||||
}
|
||||
|
||||
// ITerrainChannel.MakeCopy()
|
||||
public ITerrainChannel MakeCopy()
|
||||
{
|
||||
TerrainChannel copy = new TerrainChannel(false);
|
||||
copy.map = (double[,]) map.Clone();
|
||||
|
||||
return copy;
|
||||
return this.Copy();
|
||||
}
|
||||
|
||||
// ITerrainChannel.GetCompressedMap()
|
||||
public short[] GetCompressedMap()
|
||||
{
|
||||
return m_map;
|
||||
}
|
||||
|
||||
// ITerrainChannel.GetFloatsSerialized()
|
||||
public float[] GetFloatsSerialised()
|
||||
{
|
||||
// Move the member variables into local variables, calling
|
||||
// member variables 256*256 times gets expensive
|
||||
int w = Width;
|
||||
int h = Height;
|
||||
float[] heights = new float[w * h];
|
||||
int points = Width * Height;
|
||||
float[] heights = new float[points];
|
||||
|
||||
for (int ii = 0; ii < points; ii++)
|
||||
heights[ii] = FromCompressedHeight(m_map[ii]);
|
||||
|
||||
return heights;
|
||||
}
|
||||
|
||||
// ITerrainChannel.GetDoubles()
|
||||
public double[,] GetDoubles()
|
||||
{
|
||||
int w = Width;
|
||||
int l = Height;
|
||||
double[,] heights = new double[w, l];
|
||||
|
||||
int i, j; // map coordinates
|
||||
int idx = 0; // index into serialized array
|
||||
for (i = 0; i < h; i++)
|
||||
for (int ii = 0; ii < l; ii++)
|
||||
{
|
||||
for (j = 0; j < w; j++)
|
||||
for (int jj = 0; jj < w; jj++)
|
||||
{
|
||||
heights[idx++] = (float)map[j, i];
|
||||
heights[ii, jj] = (double)FromCompressedHeight(m_map[idx]);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
return heights;
|
||||
}
|
||||
|
||||
public double[,] GetDoubles()
|
||||
{
|
||||
return map;
|
||||
}
|
||||
|
||||
// ITerrainChannel.this[x,y]
|
||||
public double this[int x, int y]
|
||||
{
|
||||
get { return map[x, y]; }
|
||||
get { return m_map[x * Width + y]; }
|
||||
set
|
||||
{
|
||||
// Will "fix" terrain hole problems. Although not fantastically.
|
||||
if (Double.IsNaN(value) || Double.IsInfinity(value))
|
||||
return;
|
||||
|
||||
if (map[x, y] != value)
|
||||
int idx = x * Width + y;
|
||||
if (m_map[idx] != value)
|
||||
{
|
||||
taint[x / 16, y / 16] = true;
|
||||
map[x, y] = value;
|
||||
m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true;
|
||||
m_map[idx] = ToCompressedHeight(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ITerrainChannel.Tainted()
|
||||
public bool Tainted(int x, int y)
|
||||
{
|
||||
if (taint[x / 16, y / 16])
|
||||
if (m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize])
|
||||
{
|
||||
taint[x / 16, y / 16] = false;
|
||||
m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public TerrainChannel Copy()
|
||||
{
|
||||
TerrainChannel copy = new TerrainChannel(false);
|
||||
copy.map = (double[,]) map.Clone();
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
// ITerrainChannel.SaveToXmlString()
|
||||
public string SaveToXmlString()
|
||||
{
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
|
@ -181,13 +174,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
private void WriteXml(XmlWriter writer)
|
||||
{
|
||||
writer.WriteStartElement(String.Empty, "TerrainMap", String.Empty);
|
||||
ToXml(writer);
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
// ITerrainChannel.LoadFromXmlString()
|
||||
public void LoadFromXmlString(string data)
|
||||
{
|
||||
StringReader sr = new StringReader(data);
|
||||
|
@ -199,12 +186,89 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
sr.Close();
|
||||
}
|
||||
|
||||
private void ReadXml(XmlReader reader)
|
||||
#endregion
|
||||
|
||||
private void InitializeStructures(uint pX, uint pY, uint pZ, bool shouldInitializeHeightmap)
|
||||
{
|
||||
reader.ReadStartElement("TerrainMap");
|
||||
FromXml(reader);
|
||||
Width = (int)pX;
|
||||
Height = (int)pY;
|
||||
Altitude = (int)pZ;
|
||||
m_map = new short[Width * Height];
|
||||
m_taint = new bool[Width / Constants.TerrainPatchSize, Height / Constants.TerrainPatchSize];
|
||||
ClearTaint();
|
||||
if (shouldInitializeHeightmap)
|
||||
{
|
||||
FlatLand();
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearTaint()
|
||||
{
|
||||
for (int ii = 0; ii < Width / Constants.TerrainPatchSize; ii++)
|
||||
for (int jj = 0; jj < Height / Constants.TerrainPatchSize; jj++)
|
||||
m_taint[ii, jj] = false;
|
||||
}
|
||||
|
||||
// To save space (especially for large regions), keep the height as a short integer
|
||||
// that is coded as the float height times the compression factor (usually '100'
|
||||
// to make for two decimal points).
|
||||
public short ToCompressedHeight(double pHeight)
|
||||
{
|
||||
return (short)(pHeight * Constants.TerrainCompression);
|
||||
}
|
||||
|
||||
public float FromCompressedHeight(short pHeight)
|
||||
{
|
||||
return ((float)pHeight) / Constants.TerrainCompression;
|
||||
}
|
||||
|
||||
public TerrainChannel Copy()
|
||||
{
|
||||
TerrainChannel copy = new TerrainChannel();
|
||||
copy.m_map = (short[])m_map.Clone();
|
||||
copy.m_taint = (bool[,])m_taint.Clone();
|
||||
copy.Width = Width;
|
||||
copy.Height = Height;
|
||||
copy.Altitude = Altitude;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
private void WriteXml(XmlWriter writer)
|
||||
{
|
||||
if (Width == Constants.RegionSize && Height == Constants.RegionSize)
|
||||
{
|
||||
// Downward compatibility for legacy region terrain maps.
|
||||
// If region is exactly legacy size, return the old format XML.
|
||||
writer.WriteStartElement(String.Empty, "TerrainMap", String.Empty);
|
||||
ToXml(writer);
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
// New format XML that includes width and length.
|
||||
writer.WriteStartElement(String.Empty, "TerrainMap2", String.Empty);
|
||||
ToXml2(writer);
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadXml(XmlReader reader)
|
||||
{
|
||||
// Check the first element. If legacy element, use the legacy reader.
|
||||
if (reader.IsStartElement("TerrainMap"))
|
||||
{
|
||||
reader.ReadStartElement("TerrainMap");
|
||||
FromXml(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.ReadStartElement("TerrainMap2");
|
||||
FromXml2(reader);
|
||||
}
|
||||
}
|
||||
|
||||
// Write legacy terrain map. Presumed to be 256x256 of data encoded as floats in a byte array.
|
||||
private void ToXml(XmlWriter xmlWriter)
|
||||
{
|
||||
float[] mapData = GetFloatsSerialised();
|
||||
|
@ -218,6 +282,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
serializer.Serialize(xmlWriter, buffer);
|
||||
}
|
||||
|
||||
// Read legacy terrain map. Presumed to be 256x256 of data encoded as floats in a byte array.
|
||||
private void FromXml(XmlReader xmlReader)
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(byte[]));
|
||||
|
@ -236,35 +301,68 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
private class TerrainChannelXMLPackage
|
||||
{
|
||||
public int Version;
|
||||
public int SizeX;
|
||||
public int SizeY;
|
||||
public int SizeZ;
|
||||
public short[] Map;
|
||||
public TerrainChannelXMLPackage(int pX, int pY, int pZ, short[] pMap)
|
||||
{
|
||||
Version = 1;
|
||||
SizeX = pX;
|
||||
SizeY = pY;
|
||||
SizeZ = pZ;
|
||||
Map = pMap;
|
||||
}
|
||||
}
|
||||
|
||||
// New terrain serialization format that includes the width and length.
|
||||
private void ToXml2(XmlWriter xmlWriter)
|
||||
{
|
||||
TerrainChannelXMLPackage package = new TerrainChannelXMLPackage(Width, Height, Altitude, m_map);
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(TerrainChannelXMLPackage));
|
||||
serializer.Serialize(xmlWriter, package);
|
||||
}
|
||||
|
||||
// New terrain serialization format that includes the width and length.
|
||||
private void FromXml2(XmlReader xmlReader)
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(TerrainChannelXMLPackage));
|
||||
TerrainChannelXMLPackage package = (TerrainChannelXMLPackage)serializer.Deserialize(xmlReader);
|
||||
Width = package.SizeX;
|
||||
Height = package.SizeY;
|
||||
Altitude = package.SizeZ;
|
||||
m_map = package.Map;
|
||||
}
|
||||
|
||||
// Fill the heightmap with the center bump terrain
|
||||
private void PinHeadIsland()
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < Constants.RegionSize; x++)
|
||||
for (x = 0; x < Width; x++)
|
||||
{
|
||||
int y;
|
||||
for (y = 0; y < Constants.RegionSize; y++)
|
||||
for (y = 0; y < Height; y++)
|
||||
{
|
||||
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10;
|
||||
double spherFacA = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01;
|
||||
double spherFacB = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001;
|
||||
if (map[x, y] < spherFacA)
|
||||
map[x, y] = spherFacA;
|
||||
if (map[x, y] < spherFacB)
|
||||
map[x, y] = spherFacB;
|
||||
int idx = x * (int)Width + y;
|
||||
m_map[idx] = ToCompressedHeight(TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10);
|
||||
short spherFacA = ToCompressedHeight(TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01);
|
||||
short spherFacB = ToCompressedHeight(TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001);
|
||||
if (m_map[idx] < spherFacA)
|
||||
m_map[idx] = spherFacA;
|
||||
if (m_map[idx] < spherFacB)
|
||||
m_map[idx] = spherFacB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FlatLand()
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < Constants.RegionSize; x++)
|
||||
{
|
||||
int y;
|
||||
for (y = 0; y < Constants.RegionSize; y++)
|
||||
map[x, y] = 21;
|
||||
}
|
||||
short flatHeight = ToCompressedHeight(21);
|
||||
for (int ii = 0; ii < m_map.Length; ii++)
|
||||
m_map[ii] = flatHeight;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue