varregion: push TerrainData implementation up and down the database storage stack.

Implement both LoadTerrain and StoreTerrain for all DBs.
Move all database blob serialization/deserialization into TerrainData.
varregion
Robert Adams 2013-11-01 11:35:31 -07:00
parent 39777db8ef
commit ff5885ab23
12 changed files with 343 additions and 130 deletions

View File

@ -531,43 +531,43 @@ ELSE
/// <returns></returns>
public double[,] LoadTerrain(UUID regionID)
{
double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
terrain.Initialize();
TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
return terrData.GetDoubles();
}
public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
{
TerrainData terrData = null;
string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
// MySqlParameter param = new MySqlParameter();
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
int rev;
if (reader.Read())
// MySqlParameter param = new MySqlParameter();
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]);
BinaryReader br = new BinaryReader(str);
for (int x = 0; x < (int)Constants.RegionSize; x++)
int rev;
if (reader.Read())
{
for (int y = 0; y < (int)Constants.RegionSize; y++)
{
terrain[x, y] = br.ReadDouble();
}
rev = (int)reader["Revision"];
byte[] blob = (byte[])reader["Heightfield"];
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
}
rev = (int)reader["Revision"];
else
{
_Log.Info("[REGION DB]: No terrain found for region");
return null;
}
_Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
}
else
{
_Log.Info("[REGION DB]: No terrain found for region");
return null;
}
_Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
}
}
return terrain;
return terrData;
}
// Legacy entry point for when terrain was always a 256x256 hieghtmap
@ -600,13 +600,15 @@ ELSE
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
cmd.Parameters.Add(_Database.CreateParameter("@Revision", terrainDBRevision));
cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", terrainDBblob));
conn.Open();
cmd.ExecuteNonQuery();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
cmd.Parameters.Add(_Database.CreateParameter("@Revision", terrainDBRevision));
cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", terrainDBblob));
conn.Open();
cmd.ExecuteNonQuery();
}
}
_Log.InfoFormat("{0} Stored terrain revision r={1}", LogHeader, terrainDBRevision);

View File

@ -613,9 +613,16 @@ namespace OpenSim.Data.MySQL
}
}
// Legacy region loading
public double[,] LoadTerrain(UUID regionID)
{
double[,] terrain = null;
TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
return terrData.GetDoubles();
}
public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
{
TerrainData terrData = null;
lock (m_dbLock)
{
@ -635,32 +642,15 @@ namespace OpenSim.Data.MySQL
while (reader.Read())
{
int rev = Convert.ToInt32(reader["Revision"]);
terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
terrain.Initialize();
using (MemoryStream mstr = new MemoryStream((byte[])reader["Heightfield"]))
{
using (BinaryReader br = new BinaryReader(mstr))
{
for (int x = 0; x < (int)Constants.RegionSize; x++)
{
for (int y = 0; y < (int)Constants.RegionSize; y++)
{
terrain[x, y] = br.ReadDouble();
}
}
}
m_log.InfoFormat("[REGION DB]: Loaded terrain revision r{0}", rev);
}
byte[] blob = (byte[])reader["Heightfield"];
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
}
}
}
}
}
return terrain;
return terrData;
}
public void RemoveLandObject(UUID globalID)

View File

@ -132,15 +132,32 @@ namespace OpenSim.Data.Null
return new List<SceneObjectGroup>();
}
Dictionary<UUID, double[,]> m_terrains = new Dictionary<UUID, double[,]>();
public void StoreTerrain(double[,] ter, UUID regionID)
Dictionary<UUID, TerrainData> m_terrains = new Dictionary<UUID, TerrainData>();
public void StoreTerrain(TerrainData ter, UUID regionID)
{
if (m_terrains.ContainsKey(regionID))
m_terrains.Remove(regionID);
m_terrains.Add(regionID, ter);
}
// Legacy. Just don't do this.
public void StoreTerrain(double[,] ter, UUID regionID)
{
TerrainData terrData = new HeightmapTerrainData(ter);
StoreTerrain(terrData, regionID);
}
// Legacy. Just don't do this.
public double[,] LoadTerrain(UUID regionID)
{
if (m_terrains.ContainsKey(regionID))
{
return m_terrains[regionID].GetDoubles();
}
return null;
}
public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
{
if (m_terrains.ContainsKey(regionID))
{

View File

@ -524,44 +524,44 @@ namespace OpenSim.Data.PGSQL
/// <returns></returns>
public double[,] LoadTerrain(UUID regionID)
{
double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
terrain.Initialize();
TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
return terrData.GetDoubles();
}
public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
{
TerrainData terrData = null;
string sql = @"select ""RegionUUID"", ""Revision"", ""Heightfield"" from terrain
where ""RegionUUID"" = :RegionUUID order by ""Revision"" desc limit 1; ";
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
{
// PGSqlParameter param = new PGSqlParameter();
cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
conn.Open();
using (NpgsqlDataReader reader = cmd.ExecuteReader())
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
{
int rev;
if (reader.Read())
// PGSqlParameter param = new PGSqlParameter();
cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
conn.Open();
using (NpgsqlDataReader reader = cmd.ExecuteReader())
{
MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]);
BinaryReader br = new BinaryReader(str);
for (int x = 0; x < (int)Constants.RegionSize; x++)
int rev;
if (reader.Read())
{
for (int y = 0; y < (int)Constants.RegionSize; y++)
{
terrain[x, y] = br.ReadDouble();
}
rev = Convert.ToInt32(reader["Revision"]);
byte[] blob = (byte[])reader["Heightfield"];
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
}
rev = (int)reader["Revision"];
else
{
_Log.Info("[REGION DB]: No terrain found for region");
return null;
}
_Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
}
else
{
_Log.Info("[REGION DB]: No terrain found for region");
return null;
}
_Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
}
}
return terrain;
return terrData;
}
// Legacy entry point for when terrain was always a 256x256 heightmap

View File

@ -870,11 +870,16 @@ namespace OpenSim.Data.SQLite
/// <returns>Heightfield data</returns>
public double[,] LoadTerrain(UUID regionID)
{
TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
return terrData.GetDoubles();
}
public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
{
TerrainData terrData = null;
lock (ds)
{
double[,] terret = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
terret.Initialize();
String sql = "select RegionUUID, Revision, Heightfield from terrain" +
" where RegionUUID=:RegionUUID order by Revision desc";
@ -887,21 +892,9 @@ namespace OpenSim.Data.SQLite
int rev = 0;
if (row.Read())
{
// TODO: put this into a function
using (MemoryStream str = new MemoryStream((byte[])row["Heightfield"]))
{
using (BinaryReader br = new BinaryReader(str))
{
for (int x = 0; x < (int)Constants.RegionSize; x++)
{
for (int y = 0; y < (int)Constants.RegionSize; y++)
{
terret[x, y] = br.ReadDouble();
}
}
}
}
rev = Convert.ToInt32(row["Revision"]);
byte[] blob = (byte[])row["Heightfield"];
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
}
else
{
@ -912,8 +905,8 @@ namespace OpenSim.Data.SQLite
m_log.Debug("[SQLITE REGION DB]: Loaded terrain revision r" + rev.ToString());
}
}
return terret;
}
return terrData;
}
public void RemoveLandObject(UUID globalID)

View File

@ -43,6 +43,9 @@ namespace OpenSim.Framework
public int SizeY { get; protected set; }
public int SizeZ { get; protected set; }
// A height used when the user doesn't specify anything
public const float DefaultTerrainHeight = 21f;
public abstract float this[int x, int y] { get; set; }
// Someday terrain will have caves
public abstract float this[int x, int y, int z] { get; set; }
@ -51,15 +54,28 @@ namespace OpenSim.Framework
public abstract bool IsTaintedAt(int xx, int yy);
public abstract void ClearTaint();
public abstract void ClearLand();
public abstract void ClearLand(float height);
// Return a representation of this terrain for storing as a blob in the database.
// Returns 'true' to say blob was stored in the 'out' locations.
public abstract bool GetDatabaseBlob(out int DBFormatRevisionCode, out Array blob);
// Given a revision code and a blob from the database, create and return the right type of TerrainData.
// The sizes passed are the expected size of the region. The database info will be used to
// initialize the heightmap of that sized region with as much data is in the blob.
// Return created TerrainData or 'null' if unsuccessful.
public static TerrainData CreateFromDatabaseBlobFactory(int pSizeX, int pSizeY, int pSizeZ, int pFormatCode, byte[] pBlob)
{
// For the moment, there is only one implementation class
return new HeightmapTerrainData(pSizeX, pSizeY, pSizeZ, pFormatCode, pBlob);
}
// return a special compressed representation of the heightmap in shorts
public abstract short[] GetCompressedMap();
public abstract float CompressionFactor { get; }
public abstract void SetCompressedMap(short[] cmap, float pCompressionFactor);
public abstract double[,] GetDoubles();
public abstract TerrainData Clone();
}
@ -76,9 +92,14 @@ namespace OpenSim.Framework
{
// Terrain is 'double[256,256]'
Legacy256 = 11,
// Terrain is 'int32, int32, float[,]' where the shorts are X and Y dimensions
// Terrain is 'int32, int32, float[,]' where the ints are X and Y dimensions
// The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
Variable2D = 22,
// Terrain is 'int32, int32, int32, int16[]' where the ints are X and Y dimensions
// and third int is the 'compression factor'. The heights are compressed as
// "short compressedHeight = (short)(height * compressionFactor);"
// The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
Compressed2D = 27,
// A revision that is not listed above or any revision greater than this value is 'Legacy256'.
RevisionHigh = 1234
}
@ -124,6 +145,20 @@ namespace OpenSim.Framework
m_taint[ii, jj] = false;
}
// TerrainData.ClearLand
public override void ClearLand()
{
ClearLand(DefaultTerrainHeight);
}
// TerrainData.ClearLand(float)
public override void ClearLand(float pHeight)
{
short flatHeight = ToCompressedHeight(pHeight);
for (int xx = 0; xx < SizeX; xx++)
for (int yy = 0; yy < SizeY; yy++)
m_heightmap[xx, yy] = flatHeight;
}
public override bool IsTaintedAt(int xx, int yy)
{
return m_taint[xx / Constants.TerrainPatchSize, yy / Constants.TerrainPatchSize];
@ -134,7 +169,7 @@ namespace OpenSim.Framework
public override bool GetDatabaseBlob(out int DBRevisionCode, out Array blob)
{
DBRevisionCode = (int)DBTerrainRevision.Legacy256;
blob = LegacyTerrainSerialization();
blob = ToLegacyTerrainSerialization();
return false;
}
@ -155,17 +190,6 @@ namespace OpenSim.Framework
return newMap;
}
// TerrainData.SetCompressedMap
public override void SetCompressedMap(short[] cmap, float pCompressionFactor)
{
m_compressionFactor = pCompressionFactor;
int ind = 0;
for (int xx = 0; xx < SizeX; xx++)
for (int yy = 0; yy < SizeY; yy++)
m_heightmap[xx, yy] = cmap[ind++];
}
// TerrainData.Clone
public override TerrainData Clone()
{
@ -174,6 +198,18 @@ namespace OpenSim.Framework
return ret;
}
// TerrainData.GetDoubles
public override double[,] GetDoubles()
{
double[,] ret = new double[SizeX, SizeY];
for (int xx = 0; xx < SizeX; xx++)
for (int yy = 0; yy < SizeY; yy++)
ret[xx, yy] = FromCompressedHeight(m_heightmap[xx, yy]);
return ret;
}
// =============================================================
private short[,] m_heightmap;
@ -230,31 +266,140 @@ namespace OpenSim.Framework
public HeightmapTerrainData(short[] cmap, float pCompressionFactor, int pX, int pY, int pZ) : this(pX, pY, pZ)
{
SetCompressedMap(cmap, pCompressionFactor);
m_compressionFactor = pCompressionFactor;
int ind = 0;
for (int xx = 0; xx < SizeX; xx++)
for (int yy = 0; yy < SizeY; yy++)
m_heightmap[xx, yy] = cmap[ind++];
}
// Create a heighmap from a database blob
public HeightmapTerrainData(int pSizeX, int pSizeY, int pSizeZ, int pFormatCode, byte[] pBlob) : this(pSizeX, pSizeY, pSizeZ)
{
switch ((DBTerrainRevision)pFormatCode)
{
case DBTerrainRevision.Compressed2D:
FromCompressedTerrainSerialization(pBlob);
break;
default:
FromLegacyTerrainSerialization(pBlob);
break;
}
}
// Just create an array of doubles. Presumes the caller implicitly knows the size.
public Array LegacyTerrainSerialization()
public Array ToLegacyTerrainSerialization()
{
Array ret = null;
using (MemoryStream str = new MemoryStream(SizeX * SizeY * sizeof(double)))
using (MemoryStream str = new MemoryStream((int)Constants.RegionSize * (int)Constants.RegionSize * sizeof(double)))
{
using (BinaryWriter bw = new BinaryWriter(str))
{
// TODO: COMPATIBILITY - Add byte-order conversions
for (int ii = 0; ii < SizeX; ii++)
for (int jj = 0; jj < SizeY; jj++)
for (int xx = 0; xx < Constants.RegionSize; xx++)
{
double height = this[ii, jj];
if (height == 0.0)
height = double.Epsilon;
bw.Write(height);
for (int yy = 0; yy < Constants.RegionSize; yy++)
{
double height = this[xx, yy];
if (height == 0.0)
height = double.Epsilon;
bw.Write(height);
}
}
}
ret = str.ToArray();
}
return ret;
}
// Just create an array of doubles. Presumes the caller implicitly knows the size.
public void FromLegacyTerrainSerialization(byte[] pBlob)
{
// In case database info doesn't match real terrain size, initialize the whole terrain.
ClearLand();
using (MemoryStream mstr = new MemoryStream(pBlob))
{
using (BinaryReader br = new BinaryReader(mstr))
{
for (int xx = 0; xx < (int)Constants.RegionSize; xx++)
{
for (int yy = 0; yy < (int)Constants.RegionSize; yy++)
{
float val = (float)br.ReadDouble();
if (xx < SizeX && yy < SizeY)
m_heightmap[xx, yy] = ToCompressedHeight(val);
}
}
}
ClearTaint();
m_log.InfoFormat("{0} Loaded legacy heightmap. SizeX={1}, SizeY={2}", LogHeader, SizeX, SizeY);
}
}
// See the reader below.
public Array ToCompressedTerrainSerialization()
{
Array ret = null;
using (MemoryStream str = new MemoryStream((3 * sizeof(Int32)) + (SizeX * SizeY * sizeof(Int16))))
{
using (BinaryWriter bw = new BinaryWriter(str))
{
bw.Write((Int32)DBTerrainRevision.Compressed2D);
bw.Write((Int32)SizeX);
bw.Write((Int32)SizeY);
bw.Write((Int32)CompressionFactor);
for (int yy = 0; yy < SizeY; yy++)
for (int xx = 0; xx < SizeX; xx++)
{
bw.Write((Int16)m_heightmap[xx, yy]);
}
}
ret = str.ToArray();
}
return ret;
}
// Initialize heightmap from blob consisting of:
// int32, int32, int32, int32, int16[]
// where the first int32 is format code, next two int32s are the X and y of heightmap data and
// the forth int is the compression factor for the following int16s
// This is just sets heightmap info. The actual size of the region was set on this instance's
// creation and any heights not initialized by theis blob are set to the default height.
public void FromCompressedTerrainSerialization(byte[] pBlob)
{
Int32 hmFormatCode, hmSizeX, hmSizeY, hmCompressionFactor;
using (MemoryStream mstr = new MemoryStream(pBlob))
{
using (BinaryReader br = new BinaryReader(mstr))
{
hmFormatCode = br.ReadInt32();
hmSizeX = br.ReadInt32();
hmSizeY = br.ReadInt32();
hmCompressionFactor = br.ReadInt32();
m_compressionFactor = hmCompressionFactor;
// In case database info doesn't match real terrain size, initialize the whole terrain.
ClearLand();
for (int yy = 0; yy < hmSizeY; yy++)
{
for (int xx = 0; xx < hmSizeX; xx++)
{
Int16 val = br.ReadInt16();
if (xx < SizeX && yy < SizeY)
m_heightmap[xx, yy] = ToCompressedHeight(val);
}
}
}
ClearTaint();
m_log.InfoFormat("{0} Read compressed 2d heightmap. Heightmap size=<{1},{2}>. Region size={<{3},{4}>. CompFact={5}", LogHeader,
hmSizeX, hmSizeY, SizeX, SizeY, hmCompressionFactor);
}
}
}
}

View File

@ -68,13 +68,22 @@ namespace OpenSim.Region.Framework.Interfaces
/// </summary>
/// <param name="ter">HeightField data</param>
/// <param name="regionID">region UUID</param>
void StoreTerrain(TerrainData terrain, UUID regionID);
// Legacy version kept for downward compabibility
void StoreTerrain(double[,] terrain, UUID regionID);
/// <summary>
/// Load the latest terrain revision from region storage
/// </summary>
/// <param name="regionID">the region UUID</param>
/// <param name="sizeX">the X dimension of the region being filled</param>
/// <param name="sizeY">the Y dimension of the region being filled</param>
/// <param name="sizeZ">the Z dimension of the region being filled</param>
/// <returns>Heightfield data</returns>
TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ);
// Legacy version kept for downward compabibility
double[,] LoadTerrain(UUID regionID);
void StoreLandObject(ILandObject Parcel);

View File

@ -79,13 +79,22 @@ namespace OpenSim.Region.Framework.Interfaces
/// </summary>
/// <param name="ter">HeightField data</param>
/// <param name="regionID">region UUID</param>
void StoreTerrain(TerrainData terrain, UUID regionID);
// Legacy version kept for downward compabibility
void StoreTerrain(double[,] terrain, UUID regionID);
/// <summary>
/// Load the latest terrain revision from region storage
/// </summary>
/// <param name="regionID">the region UUID</param>
/// <param name="pSizeX">the X dimension of the terrain being filled</param>
/// <param name="pSizeY">the Y dimension of the terrain being filled</param>
/// <param name="pSizeZ">the Z dimension of the terrain being filled</param>
/// <returns>Heightfield data</returns>
TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ);
// Legacy version kept for downward compabibility
double[,] LoadTerrain(UUID regionID);
void StoreLandObject(ILandObject Parcel);

View File

@ -1894,7 +1894,7 @@ namespace OpenSim.Region.Framework.Scenes
{
try
{
double[,] map = SimulationDataService.LoadTerrain(RegionInfo.RegionID);
TerrainData map = SimulationDataService.LoadTerrain(RegionInfo.RegionID, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ);
if (map == null)
{
// This should be in the Terrain module, but it isn't because
@ -1911,7 +1911,7 @@ namespace OpenSim.Region.Framework.Scenes
}
else
{
Heightmap = new TerrainChannel(map, RegionInfo.RegionSizeZ);
Heightmap = new TerrainChannel(map);
}
}
catch (IOException e)

View File

@ -80,9 +80,26 @@ namespace OpenSim.Region.Framework.Scenes
PinHeadIsland();
}
public TerrainChannel(double[,] pM, uint pAltitude)
// Create channel passed a heightmap and expected dimensions of the region.
// The heightmap might not fit the passed size so accomodations must be made.
public TerrainChannel(double[,] pM, int pSizeX, int pSizeY, int pAltitude)
{
m_terrainData = new HeightmapTerrainData(pM);
int hmSizeX = pM.GetLength(0);
int hmSizeY = pM.GetLength(1);
m_terrainData = new HeightmapTerrainData(pSizeX, pSizeY, pAltitude);
for (int xx = 0; xx < pSizeX; xx++)
for (int yy = 0; yy < pSizeY; yy++)
if (xx > hmSizeX || yy > hmSizeY)
m_terrainData[xx, yy] = TerrainData.DefaultTerrainHeight;
else
m_terrainData[xx, yy] = (float)pM[xx, yy];
}
public TerrainChannel(TerrainData pTerrData)
{
m_terrainData = pTerrData;
}
#region ITerrainChannel Members
@ -247,7 +264,7 @@ namespace OpenSim.Region.Framework.Scenes
byte[] dataArray = (byte[])serializer.Deserialize(xmlReader);
int index = 0;
m_terrainData = new HeightmapTerrainData(Width, Height, Altitude);
m_terrainData = new HeightmapTerrainData((int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
for (int y = 0; y < Height; y++)
{
@ -317,9 +334,7 @@ namespace OpenSim.Region.Framework.Scenes
private void FlatLand()
{
for (int xx = 0; xx < Width; xx++)
for (int yy = 0; yy < Height; yy++)
m_terrainData[xx, yy] = 21;
m_terrainData.ClearLand();
}
}
}

View File

@ -100,6 +100,11 @@ namespace OpenSim.Services.Connectors
return m_database.LoadObjects(regionUUID);
}
public void StoreTerrain(TerrainData terrain, UUID regionID)
{
m_database.StoreTerrain(terrain, regionID);
}
public void StoreTerrain(double[,] terrain, UUID regionID)
{
m_database.StoreTerrain(terrain, regionID);
@ -110,6 +115,11 @@ namespace OpenSim.Services.Connectors
return m_database.LoadTerrain(regionID);
}
public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
{
return m_database.LoadTerrain(regionID, pSizeX, pSizeY, pSizeZ);
}
public void StoreLandObject(ILandObject Parcel)
{
m_database.StoreLandObject(Parcel);

View File

@ -69,11 +69,21 @@ namespace OpenSim.Data.Null
m_store.StoreTerrain(terrain, regionID);
}
public void StoreTerrain(TerrainData terrain, UUID regionID)
{
m_store.StoreTerrain(terrain, regionID);
}
public double[,] LoadTerrain(UUID regionID)
{
return m_store.LoadTerrain(regionID);
}
public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
{
return m_store.LoadTerrain(regionID, pSizeX, pSizeY, pSizeZ);
}
public void StoreLandObject(ILandObject Parcel)
{
m_store.StoreLandObject(Parcel);
@ -154,7 +164,7 @@ namespace OpenSim.Data.Null
protected Dictionary<UUID, SceneObjectPart> m_sceneObjectParts = new Dictionary<UUID, SceneObjectPart>();
protected Dictionary<UUID, ICollection<TaskInventoryItem>> m_primItems
= new Dictionary<UUID, ICollection<TaskInventoryItem>>();
protected Dictionary<UUID, double[,]> m_terrains = new Dictionary<UUID, double[,]>();
protected Dictionary<UUID, TerrainData> m_terrains = new Dictionary<UUID, TerrainData>();
protected Dictionary<UUID, LandData> m_landData = new Dictionary<UUID, LandData>();
public void Initialise(string dbfile)
@ -299,15 +309,28 @@ namespace OpenSim.Data.Null
return new List<SceneObjectGroup>(objects.Values);
}
public void StoreTerrain(double[,] ter, UUID regionID)
public void StoreTerrain(TerrainData ter, UUID regionID)
{
m_terrains[regionID] = ter;
}
public void StoreTerrain(double[,] ter, UUID regionID)
{
m_terrains[regionID] = new HeightmapTerrainData(ter);
}
public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
{
if (m_terrains.ContainsKey(regionID))
return m_terrains[regionID];
else
return null;
}
public double[,] LoadTerrain(UUID regionID)
{
if (m_terrains.ContainsKey(regionID))
return m_terrains[regionID];
return m_terrains[regionID].GetDoubles();
else
return null;
}