* Committing new terrain plugin effects system. Loads DLLs in /bin/Terrain/ as terrain module extensions. Committing sample plugin library.

* prebuild.xml changes.
0.6.0-stable
Adam Frisby 2008-04-22 07:53:32 +00:00
parent 385c1f5184
commit c8eb8d66fd
3 changed files with 175 additions and 10 deletions

View File

@ -35,7 +35,6 @@ using Nini.Config;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
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.FileLoaders;
using OpenSim.Region.Environment.Modules.Terrain.FloodBrushes; using OpenSim.Region.Environment.Modules.Terrain.FloodBrushes;
using OpenSim.Region.Environment.Modules.Terrain.PaintBrushes; using OpenSim.Region.Environment.Modules.Terrain.PaintBrushes;
@ -80,6 +79,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain
new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>();
private ITerrainChannel m_channel; private ITerrainChannel m_channel;
private Dictionary<string, ITerrainEffect> m_plugineffects;
private ITerrainChannel m_revert; private ITerrainChannel m_revert;
private Scene m_scene; private Scene m_scene;
private bool m_tainted = false; private bool m_tainted = false;
@ -135,6 +135,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain
{ {
InstallDefaultEffects(); InstallDefaultEffects();
InstallInterfaces(); InstallInterfaces();
LoadPlugins();
} }
public void Close() public void Close()
@ -184,7 +185,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain
{ {
m_log.Error( m_log.Error(
"[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)"); "[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)");
throw new Exception(String.Format("unable to load heightmap: file {0} not found (or permissions do not allow access", throw new Exception(String.Format("unable to load heightmap: file {0} not found (or permissions do not allow access",
filename)); filename));
} }
} }
@ -194,7 +195,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain
} }
} }
m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format."); m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format.");
throw new Exception(String.Format("unable to load heightmap from file {0}: no loader available for that format", throw new Exception(String.Format("unable to load heightmap from file {0}: no loader available for that format",
filename)); filename));
} }
@ -222,6 +223,46 @@ namespace OpenSim.Region.Environment.Modules.Terrain
} }
} }
#region Plugin Loading Methods
private void LoadPlugins()
{
m_plugineffects = new Dictionary<string, ITerrainEffect>();
// Load the files in the Terrain/ dir
string[] files = Directory.GetFiles("Terrain");
foreach (string file in files)
{
m_log.Info("Loading effects in " + file);
try
{
Assembly library = Assembly.LoadFrom(file);
foreach (Type pluginType in library.GetTypes())
{
try
{
if (pluginType.IsAbstract || pluginType.IsNotPublic)
continue;
if (pluginType.GetInterface("ITerrainEffect", false) != null)
{
ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString()));
m_plugineffects.Add(pluginType.Name, terEffect);
m_log.Info("... " + pluginType.Name);
}
}
catch (AmbiguousMatchException)
{
}
}
}
catch (BadImageFormatException)
{
}
}
}
#endregion
#endregion #endregion
/// <summary> /// <summary>
@ -564,10 +605,31 @@ namespace OpenSim.Region.Environment.Modules.Terrain
} }
} }
private void InterfacePerformEffectTest(Object[] args) private void InterfaceRunPluginEffect(Object[] args)
{ {
CookieCutter cookie = new CookieCutter(); if ((string) args[0] == "list")
cookie.RunEffect(m_channel); {
m_log.Info("List of loaded plugins");
foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects)
{
m_log.Info(kvp.Key);
}
return;
}
if ((string) args[0] == "reload")
{
LoadPlugins();
return;
}
if (m_plugineffects.ContainsKey((string) args[0]))
{
m_plugineffects[(string) args[0]].RunEffect(m_channel);
CheckForTerrainUpdates();
}
else
{
m_log.Warn("No such plugin effect loaded.");
}
} }
private void InstallInterfaces() private void InstallInterfaces()
@ -634,9 +696,10 @@ namespace OpenSim.Region.Environment.Modules.Terrain
"Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time."); "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 //Plugins
Command effectsTestCommand = Command pluginRunCommand =
new Command("test", InterfacePerformEffectTest, "Performs an effects module test"); new Command("effect", InterfaceRunPluginEffect, "Runs a specified plugin effect");
pluginRunCommand.AddArgument("name", "The plugin effect you wish to run, or 'list' to see all plugins", "String");
m_commander.RegisterCommand("load", loadFromFileCommand); m_commander.RegisterCommand("load", loadFromFileCommand);
m_commander.RegisterCommand("load-tile", loadFromTileCommand); m_commander.RegisterCommand("load-tile", loadFromTileCommand);
@ -648,8 +711,8 @@ namespace OpenSim.Region.Environment.Modules.Terrain
m_commander.RegisterCommand("bake", bakeRegionCommand); m_commander.RegisterCommand("bake", bakeRegionCommand);
m_commander.RegisterCommand("revert", revertRegionCommand); m_commander.RegisterCommand("revert", revertRegionCommand);
m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand); m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand);
m_commander.RegisterCommand("test", effectsTestCommand);
m_commander.RegisterCommand("stats", showDebugStatsCommand); m_commander.RegisterCommand("stats", showDebugStatsCommand);
m_commander.RegisterCommand("effect", pluginRunCommand);
// Add this to our scene so scripts can call these functions // Add this to our scene so scripts can call these functions
m_scene.RegisterModuleCommander("Terrain", m_commander); m_scene.RegisterModuleCommander("Terrain", m_commander);

View File

@ -0,0 +1,80 @@
using System;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Modules.Terrain;
using OpenSim.Region.Environment.Modules.Terrain.FloodBrushes;
namespace OpenSim.Region.Modules.Terrain.Extensions.DefaultEffects.Effects
{
public class ChannelDigger : ITerrainEffect
{
private readonly int num_h = 4;
private readonly int num_w = 4;
private readonly ITerrainFloodEffect raiseFunction = new RaiseArea();
private readonly ITerrainFloodEffect smoothFunction = new SmoothArea();
#region ITerrainEffect Members
public void RunEffect(ITerrainChannel map)
{
FillMap(map, 15);
BuildTiles(map, 7);
SmoothMap(map, 3);
}
#endregion
private void SmoothMap(ITerrainChannel map, int rounds)
{
Boolean[,] bitmap = new bool[map.Width,map.Height];
for (int x = 0; x < map.Width; x++)
{
for (int y = 0; y < map.Height; y++)
{
bitmap[x, y] = true;
}
}
for (int i = 0; i < rounds; i++)
{
smoothFunction.FloodEffect(map, bitmap, 1.0);
}
}
private void FillMap(ITerrainChannel map, double val)
{
for (int x = 0; x < map.Width; x++)
for (int y = 0; y < map.Height; y++)
map[x, y] = val;
}
private void BuildTiles(ITerrainChannel map, double height)
{
int channelWidth = (int) Math.Floor((map.Width / num_w) * 0.8);
int channelHeight = (int) Math.Floor((map.Height / num_h) * 0.8);
int channelXOffset = (map.Width / num_w) - channelWidth;
int channelYOffset = (map.Height / num_h) - channelHeight;
for (int x = 0; x < num_w; x++)
{
for (int y = 0; y < num_h; y++)
{
int xoff = ((channelXOffset + channelWidth) * x) + (channelXOffset / 2);
int yoff = ((channelYOffset + channelHeight) * y) + (channelYOffset / 2);
Boolean[,] bitmap = new bool[map.Width,map.Height];
for (int dx = 0; dx < channelWidth; dx++)
{
for (int dy = 0; dy < channelHeight; dy++)
{
bitmap[dx + xoff, dy + yoff] = true;
}
}
raiseFunction.FloodEffect(map, bitmap, height);
}
}
}
}
}

View File

@ -929,6 +929,28 @@
</Project> </Project>
<Project name="OpenSim.Region.Modules.Terrain.Extensions.DefaultEffects" path="OpenSim/Region/Modules/Terrain/Extensions/DefaultEffects" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../../../../bin/Terrain/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../../../../bin/Terrain/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../../../../bin/</ReferencePath>
<Reference name="System" localCopy="false"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Region.Environment"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
</Project>
<Project name="OpenSim.Region.Modules.SvnSerialiser" path="OpenSim/Region/Modules/SvnSerialiser" type="Library"> <Project name="OpenSim.Region.Modules.SvnSerialiser" path="OpenSim/Region/Modules/SvnSerialiser" type="Library">
<Configuration name="Debug"> <Configuration name="Debug">
<Options> <Options>