Major ass changes to terrain (now uses libTerrain-BSD!) and all-round improvements to code quality. Terrain saving/loading may work now (running through setHeights1D and getHeights1D before DB4o) **WARNING: UNTESTED**

0.1-prestable
Adam Frisby 2007-04-11 05:19:27 +00:00
parent b5494438e5
commit adb56a46f4
19 changed files with 70 additions and 310 deletions

View File

@ -39,8 +39,8 @@ namespace OpenSim.Framework.Interfaces
void StorePrim(PrimData prim); void StorePrim(PrimData prim);
void RemovePrim(LLUUID primID); void RemovePrim(LLUUID primID);
void LoadPrimitives(ILocalStorageReceiver receiver); void LoadPrimitives(ILocalStorageReceiver receiver);
float[,] LoadWorld(); float[] LoadWorld();
void SaveMap(float[,] heightmap); void SaveMap(float[] heightmap);
void ShutDown(); void ShutDown();
} }

View File

@ -44,7 +44,7 @@ namespace OpenSim.world
OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Avatar.cs - Loading details from grid (DUMMY)"); OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Avatar.cs - Loading details from grid (DUMMY)");
ControllingClient = TheClient; ControllingClient = TheClient;
localid = 8880000 + (this.m_world._localNumber++); localid = 8880000 + (this.m_world._localNumber++);
Pos = new LLVector3(100.0f, 100.0f, m_world.Terrain.map[(int)Pos.X, (int)Pos.Y] + 1.0f); Pos = new LLVector3(100.0f, 100.0f, m_world.Terrain[(int)Pos.X, (int)Pos.Y] + 1.0f);
visualParams = new byte[218]; visualParams = new byte[218];
for (int i = 0; i < 218; i++) for (int i = 0; i < 218; i++)
{ {
@ -332,7 +332,7 @@ namespace OpenSim.world
public override void LandRenegerated() public override void LandRenegerated()
{ {
Pos = new LLVector3(100.0f, 100.0f, m_world.Terrain.map[(int)Pos.X, (int)Pos.Y] + 50.0f); Pos = new LLVector3(100.0f, 100.0f, m_world.Terrain[(int)Pos.X, (int)Pos.Y] + 50.0f);
} }
} }

View File

@ -198,7 +198,7 @@ namespace OpenSim.world
{ {
this.phyScene.SetTerrain(Terrain.getHeights1D()); this.phyScene.SetTerrain(Terrain.getHeights1D());
} }
this.localStorage.SaveMap(this.Terrain.map); this.localStorage.SaveMap(this.Terrain.getHeights1D());
foreach (SimClient client in m_clientThreads.Values) foreach (SimClient client in m_clientThreads.Values)
{ {
@ -213,12 +213,12 @@ namespace OpenSim.world
public void RegenerateTerrain(float[,] newMap) public void RegenerateTerrain(float[,] newMap)
{ {
this.Terrain.map = newMap; this.Terrain.setHeights2D(newMap);
lock (this.LockPhysicsEngine) lock (this.LockPhysicsEngine)
{ {
this.phyScene.SetTerrain(this.Terrain.getHeights1D()); this.phyScene.SetTerrain(this.Terrain.getHeights1D());
} }
this.localStorage.SaveMap(this.Terrain.map); this.localStorage.SaveMap(this.Terrain.getHeights1D());
foreach (SimClient client in m_clientThreads.Values) foreach (SimClient client in m_clientThreads.Values)
{ {
@ -239,7 +239,7 @@ namespace OpenSim.world
{ {
this.phyScene.SetTerrain(this.Terrain.getHeights1D()); this.phyScene.SetTerrain(this.Terrain.getHeights1D());
} }
this.localStorage.SaveMap(this.Terrain.map); this.localStorage.SaveMap(this.Terrain.getHeights1D());
foreach (SimClient client in m_clientThreads.Values) foreach (SimClient client in m_clientThreads.Values)
{ {
@ -252,7 +252,7 @@ namespace OpenSim.world
public void LoadWorldMap() public void LoadWorldMap()
{ {
float[,] map = this.localStorage.LoadWorld(); float[] map = this.localStorage.LoadWorld();
if (map == null) if (map == null)
{ {
this.Terrain.hills(); this.Terrain.hills();
@ -260,7 +260,7 @@ namespace OpenSim.world
} }
else else
{ {
this.Terrain.map = map; this.Terrain.setHeights1D(map);
} }
} }

View File

@ -118,11 +118,11 @@ namespace OpenSim.Storage.LocalStorageDb4o
} }
} }
public float[,] LoadWorld() public float[] LoadWorld()
{ {
OpenSim.Framework.Console.MainConsole.Instance.WriteLine("LoadWorld() - Loading world...."); OpenSim.Framework.Console.MainConsole.Instance.WriteLine("LoadWorld() - Loading world....");
//World blank = new World(); //World blank = new World();
float[,] heightmap = null; float[] heightmap = null;
OpenSim.Framework.Console.MainConsole.Instance.WriteLine("LoadWorld() - Looking for a heightmap in local DB"); OpenSim.Framework.Console.MainConsole.Instance.WriteLine("LoadWorld() - Looking for a heightmap in local DB");
IObjectSet world_result = db.Get(typeof(MapStorage)); IObjectSet world_result = db.Get(typeof(MapStorage));
if (world_result.Count > 0) if (world_result.Count > 0)
@ -150,7 +150,7 @@ namespace OpenSim.Storage.LocalStorageDb4o
return heightmap; return heightmap;
} }
public void SaveMap(float[,] heightmap) public void SaveMap(float[] heightmap)
{ {
IObjectSet world_result = db.Get(typeof(MapStorage)); IObjectSet world_result = db.Get(typeof(MapStorage));
if (world_result.Count > 0) if (world_result.Count > 0)

View File

@ -6,7 +6,7 @@ namespace OpenSim.Storage.LocalStorageDb4o
{ {
public class MapStorage public class MapStorage
{ {
public float[,] Map; public float[] Map;
public MapStorage() public MapStorage()
{ {

View File

@ -1,72 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenSim.Terrain.BasicTerrain
{
static class Hills
{
/// <summary>
/// Generates a series of spheres which are then either max()'d or added together. Inspired by suggestion from jh.
/// </summary>
/// <remarks>3-Clause BSD Licensed</remarks>
/// <param name="number">The number of hills to generate</param>
/// <param name="scale_min">The minimum size of each hill</param>
/// <param name="scale_range">The maximum size of each hill</param>
/// <param name="island">Whether to bias hills towards the center of the map</param>
/// <param name="additive">Whether to add hills together or to pick the largest value</param>
/// <param name="noisy">Generates hill-shaped noise instead of consistent hills</param>
public static void hillsSpheres(float[,] map,int seed, int number, double scale_min, double scale_range, bool island, bool additive, bool noisy)
{
Random random = new Random(seed);
int w = map.GetLength(0);
int h = map.GetLength(1);
int x, y;
int i;
for (i = 0; i < number; i++)
{
double rx = Math.Min(255.0, random.NextDouble() * w);
double ry = Math.Min(255.0, random.NextDouble() * h);
double rand = random.NextDouble();
if (island)
{
// Move everything towards the center
rx -= w / 2;
rx /= 2;
rx += w / 2;
ry -= h / 2;
ry /= 2;
ry += h / 2;
}
for (x = 0; x < w; x++)
{
for (y = 0; y < h; y++)
{
if (noisy)
rand = random.NextDouble();
double z = (scale_min + (scale_range * rand));
z *= z;
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
if (z < 0)
z = 0;
if (additive)
{
map[x, y] += (float)z;
}
else
{
map[x, y] = (float)Math.Max(map[x, y], z);
}
}
}
}
}
}
}

View File

@ -1,102 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenSim.Terrain.BasicTerrain
{
static class Normalise
{
/// <summary>
/// Converts the heightmap to values ranging from 0..1
/// </summary>
/// <param name="map">The heightmap to be normalised</param>
public static void normalise(float[,] map)
{
double max = findMax(map);
double min = findMin(map);
int w = map.GetLength(0);
int h = map.GetLength(1);
int x, y;
for (x = 0; x < w; x++)
{
for (y = 0; y < h; y++)
{
map[x, y] = (float)((map[x, y] - min) * (1.0 / (max - min)));
}
}
}
/// <summary>
/// Converts the heightmap to values ranging from 0..<newmax>
/// </summary>
/// <param name="map">The heightmap to be normalised</param>
/// <param name="newmax">The new maximum height value of the map</param>
public static void normalise(float[,] map, double newmax)
{
double max = findMax(map);
double min = findMin(map);
int w = map.GetLength(0);
int h = map.GetLength(1);
int x, y;
for (x = 0; x < w; x++)
{
for (y = 0; y < h; y++)
{
map[x, y] = (float)((map[x, y] - min) * (1.0 / (max - min)) * newmax);
}
}
}
/// <summary>
/// Finds the largest value in the heightmap
/// </summary>
/// <param name="map">The heightmap</param>
/// <returns>The highest value</returns>
public static double findMax(float[,] map)
{
int x, y;
int w = map.GetLength(0);
int h = map.GetLength(1);
double max = double.MinValue;
for (x = 0; x < w; x++)
{
for (y = 0; y < h; y++)
{
if (map[x, y] > max)
max = map[x, y];
}
}
return max;
}
/// <summary>
/// Finds the lowest value in a heightmap
/// </summary>
/// <param name="map">The heightmap</param>
/// <returns>The minimum value</returns>
public static double findMin(float[,] map)
{
int x, y;
int w = map.GetLength(0);
int h = map.GetLength(1);
double min = double.MaxValue;
for (x = 0; x < w; x++)
{
for (y = 0; y < h; y++)
{
if (map[x, y] < min)
min = map[x, y];
}
}
return min;
}
}
}

View File

@ -28,14 +28,12 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="libTerrain-BSD, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" />
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Hills.cs" />
<Compile Include="Normalise.cs" />
<Compile Include="RaiseLower.cs" />
<Compile Include="TerrainEngine.cs" /> <Compile Include="TerrainEngine.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>

View File

@ -1,91 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenSim.Terrain.BasicTerrain
{
static class RaiseLower
{
/// <summary>
/// Raises land around the selection
/// </summary>
/// <param name="rx">The center the X coordinate of where you wish to raise the land</param>
/// <param name="ry">The center the Y coordinate of where you wish to raise the land</param>
/// <param name="size">The radius of the dimple</param>
/// <param name="amount">How much impact to add to the terrain (0..2 usually)</param>
public static void raise(float[,] map, double rx, double ry, double size, double amount)
{
raiseSphere(map, rx, ry, size, amount);
}
/// <summary>
/// Raises land in a sphere around the selection
/// </summary>
/// <param name="rx">The center the X coordinate of where you wish to raise the land</param>
/// <param name="ry">The center the Y coordinate of where you wish to raise the land</param>
/// <param name="size">The radius of the sphere dimple</param>
/// <param name="amount">How much impact to add to the terrain (0..2 usually)</param>
public static void raiseSphere(float[,] map, double rx, double ry, double size, double amount)
{
int x, y;
int w = map.GetLength(0);
int h = map.GetLength(1);
for (x = 0; x < w; x++)
{
for (y = 0; y < h; y++)
{
double z = size;
z *= z;
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
if (z < 0)
z = 0;
map[x, y] += (float)(z * amount);
}
}
}
/// <summary>
/// Lowers land in a sphere around the selection
/// </summary>
/// <param name="rx">The center the X coordinate of where you wish to lower the land</param>
/// <param name="ry">The center the Y coordinate of where you wish to lower the land</param>
/// <param name="size">The radius of the sphere dimple</param>
/// <param name="amount">How much impact to remove from the terrain (0..2 usually)</param>
public static void lower(float[,] map, double rx, double ry, double size, double amount)
{
lowerSphere(map, rx, ry, size, amount);
}
/// <summary>
/// Lowers land in a sphere around the selection
/// </summary>
/// <param name="rx">The center the X coordinate of where you wish to lower the land</param>
/// <param name="ry">The center the Y coordinate of where you wish to lower the land</param>
/// <param name="size">The radius of the sphere dimple</param>
/// <param name="amount">How much impact to remove from the terrain (0..2 usually)</param>
public static void lowerSphere(float[,] map, double rx, double ry, double size, double amount)
{
int x, y;
int w = map.GetLength(0);
int h = map.GetLength(1);
for (x = 0; x < w; x++)
{
for (y = 0; y < h; y++)
{
double z = size;
z *= z;
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
if (z < 0)
z = 0;
map[x, y] -= (float)(z * amount);
}
}
}
}
}

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using OpenSim.Terrain.BasicTerrain; using libTerrain;
namespace OpenSim.Terrain namespace OpenSim.Terrain
{ {
@ -10,11 +10,8 @@ namespace OpenSim.Terrain
/// <summary> /// <summary>
/// A [normally] 256x256 heightmap /// A [normally] 256x256 heightmap
/// </summary> /// </summary>
public float[,] map; public Channel heightmap;
/// <summary>
/// A 256x256 heightmap storing water height values
/// </summary>
public float[,] water;
int w, h; int w, h;
/// <summary> /// <summary>
@ -24,8 +21,7 @@ namespace OpenSim.Terrain
{ {
w = 256; w = 256;
h = 256; h = 256;
map = new float[w, h]; heightmap = new Channel(w, h);
water = new float[w, h];
} }
@ -38,7 +34,21 @@ namespace OpenSim.Terrain
float[] heights = new float[w*h]; float[] heights = new float[w*h];
int i; int i;
for(i=0;i<w*h;i++) { for(i=0;i<w*h;i++) {
heights[i] = map[i / w, i % w]; heights[i] = (float)heightmap.map[i / w, i % w];
}
return heights;
}
public float[,] getHeights2D()
{
float[,] heights = new float[w, h];
int x, y;
for (x = 0; x < w; x++)
{
for (y = 0; y < h; y++)
{
heights[x, y] = (float)heightmap.map[x, y];
}
} }
return heights; return heights;
} }
@ -52,13 +62,27 @@ namespace OpenSim.Terrain
int i; int i;
for (i = 0; i < w * h; i++) for (i = 0; i < w * h; i++)
{ {
map[i / w, i % w] = heights[i]; heightmap.map[i / w, i % w] = heights[i];
} }
} }
public float[,] setHeights2D(float[,] heights)
{
int x, y;
for (x = 0; x < w; x++)
{
for (y = 0; y < h; y++)
{
heightmap.set(x,y,(double)heights[x,y]);
}
}
return heights;
}
/// <summary> /// <summary>
/// Loads a file consisting of 256x256 doubles and imports it as an array into the map. /// Loads a file consisting of 256x256 doubles and imports it as an array into the map.
/// </summary> /// </summary>
/// <remarks>TODO: Move this to libTerrain itself</remarks>
/// <param name="filename">The filename of the double array to import</param> /// <param name="filename">The filename of the double array to import</param>
public void loadFromFileF64(string filename) public void loadFromFileF64(string filename)
{ {
@ -70,21 +94,11 @@ namespace OpenSim.Terrain
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
map[x, y] = (float)bs.ReadDouble(); heightmap.map[x, y] = bs.ReadDouble();
} }
} }
} }
/// <summary>
/// Swaps the references between the height and water buffers to allow you to edit the water heightmap. Remember to swap back when you are done.
/// </summary>
public void swapWaterBuffer()
{
float[,] temp = map;
map = water;
water = temp;
}
/// <summary> /// <summary>
/// Raises land in a sphere around the specified coordinates /// Raises land in a sphere around the specified coordinates
/// </summary> /// </summary>
@ -94,9 +108,9 @@ namespace OpenSim.Terrain
/// <param name="amount">Scale the height of the sphere by this amount (recommended 0..2)</param> /// <param name="amount">Scale the height of the sphere by this amount (recommended 0..2)</param>
public void raise(double rx, double ry, double size, double amount) public void raise(double rx, double ry, double size, double amount)
{ {
lock (map) lock (heightmap)
{ {
RaiseLower.raiseSphere(this.map, rx, ry, size, amount); heightmap.raise(rx, ry, size, amount);
} }
} }
@ -109,9 +123,9 @@ namespace OpenSim.Terrain
/// <param name="amount">Scale the height of the sphere by this amount (recommended 0..2)</param> /// <param name="amount">Scale the height of the sphere by this amount (recommended 0..2)</param>
public void lower(double rx, double ry, double size, double amount) public void lower(double rx, double ry, double size, double amount)
{ {
lock (map) lock (heightmap)
{ {
RaiseLower.lowerSphere(this.map, rx, ry, size, amount); heightmap.lower(rx, ry, size, amount);
} }
} }
@ -120,12 +134,24 @@ namespace OpenSim.Terrain
/// </summary> /// </summary>
public void hills() public void hills()
{ {
lock (map) lock (heightmap)
{ {
Hills.hillsSpheres(this.map, 1337, 200, 20, 40, true, true, false); heightmap.hillsSpheres(200, 20, 40, true, true, false);
Normalise.normalise(this.map,60); heightmap.normalise();
heightmap *= 60.0; // Raise to 60m
} }
} }
public float this[int x, int y]
{
get
{
return (float)heightmap.get(x,y);
}
set
{
heightmap.set(x,y,(double)value);
}
}
} }
} }

Binary file not shown.

BIN
bin/libTerrain-BSD.dll Normal file

Binary file not shown.

View File

@ -379,6 +379,7 @@
</Configuration> </Configuration>
<ReferencePath>../bin/</ReferencePath> <ReferencePath>../bin/</ReferencePath>
<Reference name="libTerrain-BSD.dll"/>
<Reference name="System"/> <Reference name="System"/>
<Reference name="System.Data"/> <Reference name="System.Data"/>
<Reference name="System.Xml"/> <Reference name="System.Xml"/>