* Commiting a bunch of missed files.
parent
8b0c795a5e
commit
4a8c1e4393
|
@ -0,0 +1,308 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using log4net;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.Framework
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A single function call encapsulated in a class which enforces arguments when passing around as Object[]'s.
|
||||||
|
/// Used for console commands and script API generation
|
||||||
|
/// </summary>
|
||||||
|
public class Command : ICommand
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private List<CommandArgument> m_args = new List<CommandArgument>();
|
||||||
|
|
||||||
|
private Action<object[]> m_command;
|
||||||
|
private string m_help;
|
||||||
|
private string m_name;
|
||||||
|
|
||||||
|
public Command(string name, Action<Object[]> command, string help)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
m_command = command;
|
||||||
|
m_help = help;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ICommand Members
|
||||||
|
|
||||||
|
public void AddArgument(string name, string helptext, string type)
|
||||||
|
{
|
||||||
|
m_args.Add(new CommandArgument(name, helptext, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return m_name; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Help
|
||||||
|
{
|
||||||
|
get { return m_help; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, string> Arguments
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Dictionary<string, string> tmp = new Dictionary<string, string>();
|
||||||
|
foreach (CommandArgument arg in m_args)
|
||||||
|
{
|
||||||
|
tmp.Add(arg.Name, arg.ArgumentType);
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowConsoleHelp()
|
||||||
|
{
|
||||||
|
m_log.Info("== " + Name + " ==");
|
||||||
|
m_log.Info(m_help);
|
||||||
|
m_log.Info("= Parameters =");
|
||||||
|
foreach (CommandArgument arg in m_args)
|
||||||
|
{
|
||||||
|
m_log.Info("* " + arg.Name + " (" + arg.ArgumentType + ")");
|
||||||
|
m_log.Info("\t" + arg.HelpText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Run(Object[] args)
|
||||||
|
{
|
||||||
|
Object[] cleanArgs = new Object[m_args.Count];
|
||||||
|
|
||||||
|
if (args.Length < cleanArgs.Length)
|
||||||
|
{
|
||||||
|
m_log.Error("Missing " + (cleanArgs.Length - args.Length) + " argument(s)");
|
||||||
|
ShowConsoleHelp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (args.Length > cleanArgs.Length)
|
||||||
|
{
|
||||||
|
m_log.Error("Too many arguments for this command. Type '<module> <command> help' for help.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
foreach (Object arg in args)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(arg.ToString()))
|
||||||
|
{
|
||||||
|
m_log.Error("Empty arguments are not allowed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (m_args[i].ArgumentType)
|
||||||
|
{
|
||||||
|
case "String":
|
||||||
|
m_args[i].ArgumentValue = arg.ToString();
|
||||||
|
break;
|
||||||
|
case "Integer":
|
||||||
|
m_args[i].ArgumentValue = Int32.Parse(arg.ToString());
|
||||||
|
break;
|
||||||
|
case "Double":
|
||||||
|
m_args[i].ArgumentValue = Double.Parse(arg.ToString());
|
||||||
|
break;
|
||||||
|
case "Boolean":
|
||||||
|
m_args[i].ArgumentValue = Boolean.Parse(arg.ToString());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_log.Error("Unknown desired type for argument " + m_args[i].Name + " on command " + m_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
m_log.Error("Argument number " + (i + 1) +
|
||||||
|
" (" + m_args[i].Name + ") must be a valid " +
|
||||||
|
m_args[i].ArgumentType.ToLower() + ".");
|
||||||
|
}
|
||||||
|
cleanArgs[i] = m_args[i].ArgumentValue;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_command.Invoke(cleanArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A single command argument, contains name, type and at runtime, value.
|
||||||
|
/// </summary>
|
||||||
|
public class CommandArgument
|
||||||
|
{
|
||||||
|
private string m_help;
|
||||||
|
private string m_name;
|
||||||
|
private string m_type;
|
||||||
|
private Object m_val;
|
||||||
|
|
||||||
|
public CommandArgument(string name, string help, string type)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
m_help = help;
|
||||||
|
m_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return m_name; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string HelpText
|
||||||
|
{
|
||||||
|
get { return m_help; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ArgumentType
|
||||||
|
{
|
||||||
|
get { return m_type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object ArgumentValue
|
||||||
|
{
|
||||||
|
get { return m_val; }
|
||||||
|
set { m_val = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A class to enable modules to register console and script commands, which enforces typing and valid input.
|
||||||
|
/// </summary>
|
||||||
|
public class Commander : ICommander
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private Dictionary<string, ICommand> m_commands = new Dictionary<string, ICommand>();
|
||||||
|
private string m_name;
|
||||||
|
|
||||||
|
public Commander(string name)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ICommander Members
|
||||||
|
|
||||||
|
public void RegisterCommand(string commandName, ICommand command)
|
||||||
|
{
|
||||||
|
m_commands[commandName] = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a runtime C# class which can be compiled and inserted via reflection to enable modules to register new script commands
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Returns C# source code to create a binding</returns>
|
||||||
|
public string GenerateRuntimeAPI()
|
||||||
|
{
|
||||||
|
string classSrc = "\n\tpublic class " + m_name + " {\n";
|
||||||
|
foreach (ICommand com in m_commands.Values)
|
||||||
|
{
|
||||||
|
classSrc += "\tpublic void " + EscapeRuntimeAPICommand(com.Name) + "( ";
|
||||||
|
foreach (KeyValuePair<string, string> arg in com.Arguments)
|
||||||
|
{
|
||||||
|
classSrc += arg.Value + " " + Util.Md5Hash(arg.Key) + ",";
|
||||||
|
}
|
||||||
|
classSrc = classSrc.Remove(classSrc.Length - 1); // Delete the last comma
|
||||||
|
classSrc += " )\n\t{\n";
|
||||||
|
classSrc += "\t\tObject[] args = new Object[" + com.Arguments.Count.ToString() + "];\n";
|
||||||
|
int i = 0;
|
||||||
|
foreach (KeyValuePair<string, string> arg in com.Arguments)
|
||||||
|
{
|
||||||
|
classSrc += "\t\targs[" + i.ToString() + "] = " + Util.Md5Hash(arg.Key) + " " + ";\n";
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
classSrc += "\t\tGetCommander(\"" + m_name + "\").Run(\"" + com.Name + "\", args);\n";
|
||||||
|
classSrc += "\t}\n";
|
||||||
|
}
|
||||||
|
classSrc += "}\n";
|
||||||
|
|
||||||
|
return classSrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs a specified function with attached arguments
|
||||||
|
/// *** <b>DO NOT CALL DIRECTLY.</b> ***
|
||||||
|
/// Call ProcessConsoleCommand instead if handling human input.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="function">The function name to call</param>
|
||||||
|
/// <param name="args">The function parameters</param>
|
||||||
|
public void Run(string function, object[] args)
|
||||||
|
{
|
||||||
|
m_commands[function].Run(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ProcessConsoleCommand(string function, string[] args)
|
||||||
|
{
|
||||||
|
if (m_commands.ContainsKey(function))
|
||||||
|
{
|
||||||
|
if (args.Length > 0 && args[0] == "help")
|
||||||
|
{
|
||||||
|
m_commands[function].ShowConsoleHelp();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_commands[function].Run(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (function != "help")
|
||||||
|
m_log.Error("Invalid command - No such command exists");
|
||||||
|
if (function == "api")
|
||||||
|
m_log.Info(GenerateRuntimeAPI());
|
||||||
|
ShowConsoleHelp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void ShowConsoleHelp()
|
||||||
|
{
|
||||||
|
m_log.Info("===" + m_name + "===");
|
||||||
|
foreach (ICommand com in m_commands.Values)
|
||||||
|
{
|
||||||
|
m_log.Info("* " + com.Name + " - " + com.Help);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string EscapeRuntimeAPICommand(string command)
|
||||||
|
{
|
||||||
|
command = command.Replace('-', '_');
|
||||||
|
StringBuilder tmp = new StringBuilder(command);
|
||||||
|
tmp[0] = tmp[0].ToString().ToUpper().ToCharArray()[0];
|
||||||
|
|
||||||
|
return tmp.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Modules.Framework;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.Framework
|
||||||
|
{
|
||||||
|
public class CommanderTestModule : IRegionModule, ICommandableModule
|
||||||
|
{
|
||||||
|
Commander m_commander = new Commander("CommanderTest");
|
||||||
|
Scene m_scene;
|
||||||
|
|
||||||
|
#region IRegionModule Members
|
||||||
|
|
||||||
|
public void Initialise(Scene scene, IConfigSource source)
|
||||||
|
{
|
||||||
|
m_scene = scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceHelloWorld(Object[] args)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hello World");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
Command testCommand = new Command("hello", InterfaceHelloWorld, "Says a simple debugging test string");
|
||||||
|
testCommand.AddArgument("world", "Write world here", "string");
|
||||||
|
|
||||||
|
m_commander.RegisterCommand("hello", testCommand);
|
||||||
|
|
||||||
|
// Register me
|
||||||
|
m_scene.RegisterModuleCommander("commandertest", m_commander);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "CommanderTestModule"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSharedModule
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ICommandableModule Members
|
||||||
|
|
||||||
|
public ICommander CommandInterface
|
||||||
|
{
|
||||||
|
get { throw new NotImplementedException(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Land;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Land
|
||||||
|
{
|
||||||
|
public class LandManagementModule : IRegionModule
|
||||||
|
{
|
||||||
|
private LandChannel landChannel;
|
||||||
|
private Scene m_scene;
|
||||||
|
|
||||||
|
#region IRegionModule Members
|
||||||
|
|
||||||
|
public void Initialise(Scene scene, IConfigSource source)
|
||||||
|
{
|
||||||
|
m_scene = scene;
|
||||||
|
landChannel = new LandChannel(scene);
|
||||||
|
|
||||||
|
m_scene.EventManager.OnParcelPrimCountAdd += landChannel.addPrimToLandPrimCounts;
|
||||||
|
m_scene.EventManager.OnParcelPrimCountUpdate += landChannel.updateLandPrimCounts;
|
||||||
|
m_scene.EventManager.OnAvatarEnteringNewParcel += new EventManager.AvatarEnteringNewParcel(landChannel.handleAvatarChangingParcel);
|
||||||
|
m_scene.EventManager.OnClientMovement += new EventManager.ClientMovement(landChannel.handleAnyClientMovement);
|
||||||
|
m_scene.EventManager.OnValidateLandBuy += landChannel.handleLandValidationRequest;
|
||||||
|
m_scene.EventManager.OnLandBuy += landChannel.handleLandBuyRequest;
|
||||||
|
|
||||||
|
lock (m_scene)
|
||||||
|
{
|
||||||
|
m_scene.LandChannel = (ILandChannel)landChannel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "LandManagementModule"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSharedModule
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,943 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using libsecondlife;
|
||||||
|
using libsecondlife.Packets;
|
||||||
|
using log4net;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Land;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Land
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Keeps track of a specific piece of land's information
|
||||||
|
/// </summary>
|
||||||
|
public class LandObject : ILandObject
|
||||||
|
{
|
||||||
|
#region Member Variables
|
||||||
|
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
protected LandData m_landData = new LandData();
|
||||||
|
protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
|
||||||
|
protected Scene m_scene;
|
||||||
|
|
||||||
|
private bool[,] m_landBitmap = new bool[64,64];
|
||||||
|
|
||||||
|
public bool[,] landBitmap
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_landBitmap;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_landBitmap = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ILandObject Members
|
||||||
|
|
||||||
|
public LandData landData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_landData;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_landData = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LLUUID regionUUID
|
||||||
|
{
|
||||||
|
get { return m_scene.RegionInfo.RegionID; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public LandObject(LLUUID owner_id, bool is_group_owned, Scene scene)
|
||||||
|
{
|
||||||
|
m_scene = scene;
|
||||||
|
landData.ownerID = owner_id;
|
||||||
|
landData.isGroupOwned = is_group_owned;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Member Functions
|
||||||
|
|
||||||
|
#region General Functions
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks to see if this land object contains a point
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x"></param>
|
||||||
|
/// <param name="y"></param>
|
||||||
|
/// <returns>Returns true if the piece of land contains the specified point</returns>
|
||||||
|
public bool containsPoint(int x, int y)
|
||||||
|
{
|
||||||
|
if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize)
|
||||||
|
{
|
||||||
|
return (landBitmap[x/4, y/4] == true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILandObject Copy()
|
||||||
|
{
|
||||||
|
ILandObject newLand = new LandObject(landData.ownerID, landData.isGroupOwned, m_scene);
|
||||||
|
|
||||||
|
//Place all new variables here!
|
||||||
|
newLand.landBitmap = (bool[,]) (landBitmap.Clone());
|
||||||
|
newLand.landData = landData.Copy();
|
||||||
|
|
||||||
|
return newLand;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Packet Request Handling
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends land properties as requested
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sequence_id">ID sent by client for them to keep track of</param>
|
||||||
|
/// <param name="snap_selection">Bool sent by client for them to use</param>
|
||||||
|
/// <param name="remote_client">Object representing the client</param>
|
||||||
|
public void sendLandProperties(int sequence_id, bool snap_selection, int request_result,
|
||||||
|
IClientAPI remote_client)
|
||||||
|
{
|
||||||
|
ParcelPropertiesPacket updatePacket = (ParcelPropertiesPacket) PacketPool.Instance.GetPacket(PacketType.ParcelProperties);
|
||||||
|
// TODO: don't create new blocks if recycling an old packet
|
||||||
|
|
||||||
|
updatePacket.ParcelData.AABBMax = landData.AABBMax;
|
||||||
|
updatePacket.ParcelData.AABBMin = landData.AABBMin;
|
||||||
|
updatePacket.ParcelData.Area = landData.area;
|
||||||
|
updatePacket.ParcelData.AuctionID = landData.auctionID;
|
||||||
|
updatePacket.ParcelData.AuthBuyerID = landData.authBuyerID; //unemplemented
|
||||||
|
|
||||||
|
updatePacket.ParcelData.Bitmap = landData.landBitmapByteArray;
|
||||||
|
|
||||||
|
updatePacket.ParcelData.Desc = Helpers.StringToField(landData.landDesc);
|
||||||
|
updatePacket.ParcelData.Category = (byte) landData.category;
|
||||||
|
updatePacket.ParcelData.ClaimDate = landData.claimDate;
|
||||||
|
updatePacket.ParcelData.ClaimPrice = landData.claimPrice;
|
||||||
|
updatePacket.ParcelData.GroupID = landData.groupID;
|
||||||
|
updatePacket.ParcelData.GroupPrims = landData.groupPrims;
|
||||||
|
updatePacket.ParcelData.IsGroupOwned = landData.isGroupOwned;
|
||||||
|
updatePacket.ParcelData.LandingType = (byte) landData.landingType;
|
||||||
|
updatePacket.ParcelData.LocalID = landData.localID;
|
||||||
|
if (landData.area > 0)
|
||||||
|
{
|
||||||
|
updatePacket.ParcelData.MaxPrims =
|
||||||
|
Convert.ToInt32(
|
||||||
|
Math.Round((Convert.ToDecimal(landData.area)/Convert.ToDecimal(65536))*m_scene.objectCapacity*
|
||||||
|
Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
updatePacket.ParcelData.MaxPrims = 0;
|
||||||
|
}
|
||||||
|
updatePacket.ParcelData.MediaAutoScale = landData.mediaAutoScale;
|
||||||
|
updatePacket.ParcelData.MediaID = landData.mediaID;
|
||||||
|
updatePacket.ParcelData.MediaURL = Helpers.StringToField(landData.mediaURL);
|
||||||
|
updatePacket.ParcelData.MusicURL = Helpers.StringToField(landData.musicURL);
|
||||||
|
updatePacket.ParcelData.Name = Helpers.StringToField(landData.landName);
|
||||||
|
updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented
|
||||||
|
updatePacket.ParcelData.OtherCount = 0; //unemplemented
|
||||||
|
updatePacket.ParcelData.OtherPrims = landData.otherPrims;
|
||||||
|
updatePacket.ParcelData.OwnerID = landData.ownerID;
|
||||||
|
updatePacket.ParcelData.OwnerPrims = landData.ownerPrims;
|
||||||
|
updatePacket.ParcelData.ParcelFlags = landData.landFlags;
|
||||||
|
updatePacket.ParcelData.ParcelPrimBonus = m_scene.RegionInfo.EstateSettings.objectBonusFactor;
|
||||||
|
updatePacket.ParcelData.PassHours = landData.passHours;
|
||||||
|
updatePacket.ParcelData.PassPrice = landData.passPrice;
|
||||||
|
updatePacket.ParcelData.PublicCount = 0; //unemplemented
|
||||||
|
|
||||||
|
uint regionFlags = (uint) m_scene.RegionInfo.EstateSettings.regionFlags;
|
||||||
|
updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint) Simulator.RegionFlags.DenyAnonymous) >
|
||||||
|
0);
|
||||||
|
updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint) Simulator.RegionFlags.DenyIdentified) >
|
||||||
|
0);
|
||||||
|
updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint) Simulator.RegionFlags.DenyTransacted) >
|
||||||
|
0);
|
||||||
|
updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint) Simulator.RegionFlags.RestrictPushObject) >
|
||||||
|
0);
|
||||||
|
|
||||||
|
updatePacket.ParcelData.RentPrice = 0;
|
||||||
|
updatePacket.ParcelData.RequestResult = request_result;
|
||||||
|
updatePacket.ParcelData.SalePrice = landData.salePrice;
|
||||||
|
updatePacket.ParcelData.SelectedPrims = landData.selectedPrims;
|
||||||
|
updatePacket.ParcelData.SelfCount = 0; //unemplemented
|
||||||
|
updatePacket.ParcelData.SequenceID = sequence_id;
|
||||||
|
if (landData.simwideArea > 0)
|
||||||
|
{
|
||||||
|
updatePacket.ParcelData.SimWideMaxPrims =
|
||||||
|
Convert.ToInt32(
|
||||||
|
Math.Round((Convert.ToDecimal(landData.simwideArea) / Convert.ToDecimal(65536)) * m_scene.objectCapacity *
|
||||||
|
Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
updatePacket.ParcelData.SimWideMaxPrims = 0;
|
||||||
|
}
|
||||||
|
updatePacket.ParcelData.SimWideTotalPrims = landData.simwidePrims;
|
||||||
|
updatePacket.ParcelData.SnapSelection = snap_selection;
|
||||||
|
updatePacket.ParcelData.SnapshotID = landData.snapshotID;
|
||||||
|
updatePacket.ParcelData.Status = (byte) landData.landStatus;
|
||||||
|
updatePacket.ParcelData.TotalPrims = landData.ownerPrims + landData.groupPrims + landData.otherPrims +
|
||||||
|
landData.selectedPrims;
|
||||||
|
updatePacket.ParcelData.UserLocation = landData.userLocation;
|
||||||
|
updatePacket.ParcelData.UserLookAt = landData.userLookAt;
|
||||||
|
remote_client.OutPacket((Packet) updatePacket, ThrottleOutPacketType.Task);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateLandProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client)
|
||||||
|
{
|
||||||
|
if (remote_client.AgentId == landData.ownerID)
|
||||||
|
{
|
||||||
|
//Needs later group support
|
||||||
|
LandData newData = landData.Copy();
|
||||||
|
newData.authBuyerID = packet.ParcelData.AuthBuyerID;
|
||||||
|
newData.category = (Parcel.ParcelCategory) packet.ParcelData.Category;
|
||||||
|
newData.landDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc);
|
||||||
|
newData.groupID = packet.ParcelData.GroupID;
|
||||||
|
newData.landingType = packet.ParcelData.LandingType;
|
||||||
|
newData.mediaAutoScale = packet.ParcelData.MediaAutoScale;
|
||||||
|
newData.mediaID = packet.ParcelData.MediaID;
|
||||||
|
newData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL);
|
||||||
|
newData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL);
|
||||||
|
newData.landName = Helpers.FieldToUTF8String(packet.ParcelData.Name);
|
||||||
|
newData.landFlags = packet.ParcelData.ParcelFlags;
|
||||||
|
newData.passHours = packet.ParcelData.PassHours;
|
||||||
|
newData.passPrice = packet.ParcelData.PassPrice;
|
||||||
|
newData.salePrice = packet.ParcelData.SalePrice;
|
||||||
|
newData.snapshotID = packet.ParcelData.SnapshotID;
|
||||||
|
newData.userLocation = packet.ParcelData.UserLocation;
|
||||||
|
newData.userLookAt = packet.ParcelData.UserLookAt;
|
||||||
|
|
||||||
|
m_scene.LandChannel.updateLandObject(landData.localID, newData);
|
||||||
|
|
||||||
|
sendLandUpdateToAvatarsOverMe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void updateLandSold(LLUUID avatarID, LLUUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area)
|
||||||
|
{
|
||||||
|
LandData newData = landData.Copy();
|
||||||
|
newData.ownerID = avatarID;
|
||||||
|
newData.groupID = groupID;
|
||||||
|
newData.isGroupOwned = groupOwned;
|
||||||
|
//newData.auctionID = AuctionID;
|
||||||
|
newData.claimDate = Util.UnixTimeSinceEpoch();
|
||||||
|
newData.claimPrice = claimprice;
|
||||||
|
newData.salePrice = 0;
|
||||||
|
newData.authBuyerID = LLUUID.Zero;
|
||||||
|
newData.landFlags &= ~(uint)(Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects);
|
||||||
|
m_scene.LandChannel.updateLandObject(landData.localID, newData);
|
||||||
|
|
||||||
|
sendLandUpdateToAvatarsOverMe();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isEitherBannedOrRestricted(LLUUID avatar)
|
||||||
|
{
|
||||||
|
if (isBannedFromLand(avatar))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (isRestrictedFromLand(avatar))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isBannedFromLand(LLUUID avatar)
|
||||||
|
{
|
||||||
|
if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseBanList) > 0)
|
||||||
|
{
|
||||||
|
ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
|
||||||
|
entry.AgentID = avatar;
|
||||||
|
entry.Flags = ParcelManager.AccessList.Ban;
|
||||||
|
entry.Time = new DateTime();
|
||||||
|
if (landData.parcelAccessList.Contains(entry))
|
||||||
|
{
|
||||||
|
//They are banned, so lets send them a notice about this parcel
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isRestrictedFromLand(LLUUID avatar)
|
||||||
|
{
|
||||||
|
if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseAccessList) > 0)
|
||||||
|
{
|
||||||
|
ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
|
||||||
|
entry.AgentID = avatar;
|
||||||
|
entry.Flags = ParcelManager.AccessList.Access;
|
||||||
|
entry.Time = new DateTime();
|
||||||
|
if (!landData.parcelAccessList.Contains(entry))
|
||||||
|
{
|
||||||
|
//They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendLandUpdateToClient(IClientAPI remote_client)
|
||||||
|
{
|
||||||
|
sendLandProperties(0, false, 0, remote_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendLandUpdateToAvatarsOverMe()
|
||||||
|
{
|
||||||
|
List<ScenePresence> avatars = m_scene.GetAvatars();
|
||||||
|
ILandObject over = null;
|
||||||
|
for (int i = 0; i < avatars.Count; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
over =
|
||||||
|
m_scene.LandChannel.getLandObject((int)Math.Max(255,Math.Min(0,Math.Round(avatars[i].AbsolutePosition.X))),
|
||||||
|
(int)Math.Max(255,Math.Min(0,Math.Round(avatars[i].AbsolutePosition.Y))));
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " + Math.Round(avatars[i].AbsolutePosition.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (over != null)
|
||||||
|
{
|
||||||
|
if (over.landData.localID == landData.localID)
|
||||||
|
{
|
||||||
|
sendLandUpdateToClient(avatars[i].ControllingClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region AccessList Functions
|
||||||
|
|
||||||
|
public ParcelAccessListReplyPacket.ListBlock[] createAccessListArrayByFlag(ParcelManager.AccessList flag)
|
||||||
|
{
|
||||||
|
List<ParcelAccessListReplyPacket.ListBlock> list = new List<ParcelAccessListReplyPacket.ListBlock>();
|
||||||
|
foreach (ParcelManager.ParcelAccessEntry entry in landData.parcelAccessList)
|
||||||
|
{
|
||||||
|
if (entry.Flags == flag)
|
||||||
|
{
|
||||||
|
ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock();
|
||||||
|
|
||||||
|
listBlock.Flags = (uint) 0;
|
||||||
|
listBlock.ID = entry.AgentID;
|
||||||
|
listBlock.Time = 0;
|
||||||
|
|
||||||
|
list.Add(listBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.Count == 0)
|
||||||
|
{
|
||||||
|
ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock();
|
||||||
|
|
||||||
|
listBlock.Flags = (uint) 0;
|
||||||
|
listBlock.ID = LLUUID.Zero;
|
||||||
|
listBlock.Time = 0;
|
||||||
|
|
||||||
|
list.Add(listBlock);
|
||||||
|
}
|
||||||
|
return list.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendAccessList(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID,
|
||||||
|
IClientAPI remote_client)
|
||||||
|
{
|
||||||
|
ParcelAccessListReplyPacket replyPacket;
|
||||||
|
|
||||||
|
if (flags == (uint) ParcelManager.AccessList.Access || flags == (uint) ParcelManager.AccessList.Both)
|
||||||
|
{
|
||||||
|
replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply);
|
||||||
|
replyPacket.Data.AgentID = agentID;
|
||||||
|
replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Access;
|
||||||
|
replyPacket.Data.LocalID = landData.localID;
|
||||||
|
replyPacket.Data.SequenceID = 0;
|
||||||
|
|
||||||
|
replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Access);
|
||||||
|
remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags == (uint) ParcelManager.AccessList.Ban || flags == (uint) ParcelManager.AccessList.Both)
|
||||||
|
{
|
||||||
|
replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply);
|
||||||
|
replyPacket.Data.AgentID = agentID;
|
||||||
|
replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Ban;
|
||||||
|
replyPacket.Data.LocalID = landData.localID;
|
||||||
|
replyPacket.Data.SequenceID = 0;
|
||||||
|
|
||||||
|
replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Ban);
|
||||||
|
remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client)
|
||||||
|
{
|
||||||
|
LandData newData = landData.Copy();
|
||||||
|
|
||||||
|
if (entries.Count == 1 && entries[0].AgentID == LLUUID.Zero)
|
||||||
|
{
|
||||||
|
entries.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>();
|
||||||
|
foreach (ParcelManager.ParcelAccessEntry entry in newData.parcelAccessList)
|
||||||
|
{
|
||||||
|
if (entry.Flags == (ParcelManager.AccessList) flags)
|
||||||
|
{
|
||||||
|
toRemove.Add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ParcelManager.ParcelAccessEntry entry in toRemove)
|
||||||
|
{
|
||||||
|
newData.parcelAccessList.Remove(entry);
|
||||||
|
}
|
||||||
|
foreach (ParcelManager.ParcelAccessEntry entry in entries)
|
||||||
|
{
|
||||||
|
ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry();
|
||||||
|
temp.AgentID = entry.AgentID;
|
||||||
|
temp.Time = new DateTime(); //Pointless? Yes.
|
||||||
|
temp.Flags = (ParcelManager.AccessList) flags;
|
||||||
|
|
||||||
|
if (!newData.parcelAccessList.Contains(temp))
|
||||||
|
{
|
||||||
|
newData.parcelAccessList.Add(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_scene.LandChannel.updateLandObject(landData.localID, newData);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Update Functions
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the AABBMin and AABBMax values after area/shape modification of the land object
|
||||||
|
/// </summary>
|
||||||
|
private void updateAABBAndAreaValues()
|
||||||
|
{
|
||||||
|
int min_x = 64;
|
||||||
|
int min_y = 64;
|
||||||
|
int max_x = 0;
|
||||||
|
int max_y = 0;
|
||||||
|
int tempArea = 0;
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < 64; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < 64; y++)
|
||||||
|
{
|
||||||
|
if (landBitmap[x, y] == true)
|
||||||
|
{
|
||||||
|
if (min_x > x) min_x = x;
|
||||||
|
if (min_y > y) min_y = y;
|
||||||
|
if (max_x < x) max_x = x;
|
||||||
|
if (max_y < y) max_y = y;
|
||||||
|
tempArea += 16; //16sqm peice of land
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int tx = min_x * 4;
|
||||||
|
if (tx > 255)
|
||||||
|
tx = 255;
|
||||||
|
int ty = min_y * 4;
|
||||||
|
if (ty > 255)
|
||||||
|
ty = 255;
|
||||||
|
landData.AABBMin =
|
||||||
|
new LLVector3((float)(min_x * 4), (float)(min_y * 4),
|
||||||
|
(float)m_scene.Heightmap[tx, ty]);
|
||||||
|
|
||||||
|
tx = max_x * 4;
|
||||||
|
if (tx > 255)
|
||||||
|
tx = 255;
|
||||||
|
ty = max_y * 4;
|
||||||
|
if (ty > 255)
|
||||||
|
ty = 255;
|
||||||
|
landData.AABBMax =
|
||||||
|
new LLVector3((float)(max_x * 4), (float)(max_y * 4),
|
||||||
|
(float)m_scene.Heightmap[tx, ty]);
|
||||||
|
landData.area = tempArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateLandBitmapByteArray()
|
||||||
|
{
|
||||||
|
landData.landBitmapByteArray = convertLandBitmapToBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update all settings in land such as area, bitmap byte array, etc
|
||||||
|
/// </summary>
|
||||||
|
public void forceUpdateLandInfo()
|
||||||
|
{
|
||||||
|
updateAABBAndAreaValues();
|
||||||
|
updateLandBitmapByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLandBitmapFromByteArray()
|
||||||
|
{
|
||||||
|
landBitmap = convertBytesToLandBitmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Land Bitmap Functions
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the land's bitmap manually
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bitmap">64x64 block representing where this land is on a map</param>
|
||||||
|
public void setLandBitmap(bool[,] bitmap)
|
||||||
|
{
|
||||||
|
if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
|
||||||
|
{
|
||||||
|
//Throw an exception - The bitmap is not 64x64
|
||||||
|
//throw new Exception("Error: Invalid Parcel Bitmap");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Valid: Lets set it
|
||||||
|
landBitmap = bitmap;
|
||||||
|
forceUpdateLandInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the land's bitmap manually
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool[,] getLandBitmap()
|
||||||
|
{
|
||||||
|
return landBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the land bitmap to a packet friendly byte array
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private byte[] convertLandBitmapToBytes()
|
||||||
|
{
|
||||||
|
byte[] tempConvertArr = new byte[512];
|
||||||
|
byte tempByte = 0;
|
||||||
|
int x, y, i, byteNum = 0;
|
||||||
|
i = 0;
|
||||||
|
for (y = 0; y < 64; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < 64; x++)
|
||||||
|
{
|
||||||
|
tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++%8));
|
||||||
|
if (i%8 == 0)
|
||||||
|
{
|
||||||
|
tempConvertArr[byteNum] = tempByte;
|
||||||
|
tempByte = (byte) 0;
|
||||||
|
i = 0;
|
||||||
|
byteNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tempConvertArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool[,] convertBytesToLandBitmap()
|
||||||
|
{
|
||||||
|
bool[,] tempConvertMap = new bool[64,64];
|
||||||
|
tempConvertMap.Initialize();
|
||||||
|
byte tempByte = 0;
|
||||||
|
int x = 0, y = 0, i = 0, bitNum = 0;
|
||||||
|
for (i = 0; i < 512; i++)
|
||||||
|
{
|
||||||
|
tempByte = landData.landBitmapByteArray[i];
|
||||||
|
for (bitNum = 0; bitNum < 8; bitNum++)
|
||||||
|
{
|
||||||
|
bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
|
||||||
|
tempConvertMap[x, y] = bit;
|
||||||
|
x++;
|
||||||
|
if (x > 63)
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tempConvertMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Full sim land object creation
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool[,] basicFullRegionLandBitmap()
|
||||||
|
{
|
||||||
|
return getSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to modify the bitmap between the x and y points. Points use 64 scale
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="start_x"></param>
|
||||||
|
/// <param name="start_y"></param>
|
||||||
|
/// <param name="end_x"></param>
|
||||||
|
/// <param name="end_y"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
|
||||||
|
{
|
||||||
|
bool[,] tempBitmap = new bool[64,64];
|
||||||
|
tempBitmap.Initialize();
|
||||||
|
|
||||||
|
tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
|
||||||
|
return tempBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Change a land bitmap at within a square and set those points to a specific value
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="land_bitmap"></param>
|
||||||
|
/// <param name="start_x"></param>
|
||||||
|
/// <param name="start_y"></param>
|
||||||
|
/// <param name="end_x"></param>
|
||||||
|
/// <param name="end_y"></param>
|
||||||
|
/// <param name="set_value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
|
||||||
|
bool set_value)
|
||||||
|
{
|
||||||
|
if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
|
||||||
|
{
|
||||||
|
//Throw an exception - The bitmap is not 64x64
|
||||||
|
//throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
|
||||||
|
}
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
for (y = 0; y < 64; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < 64; x++)
|
||||||
|
{
|
||||||
|
if (x >= start_x/4 && x < end_x/4
|
||||||
|
&& y >= start_y/4 && y < end_y/4)
|
||||||
|
{
|
||||||
|
land_bitmap[x, y] = set_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return land_bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Join the true values of 2 bitmaps together
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bitmap_base"></param>
|
||||||
|
/// <param name="bitmap_add"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
|
||||||
|
{
|
||||||
|
if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
|
||||||
|
{
|
||||||
|
//Throw an exception - The bitmap is not 64x64
|
||||||
|
throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps");
|
||||||
|
}
|
||||||
|
if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2)
|
||||||
|
{
|
||||||
|
//Throw an exception - The bitmap is not 64x64
|
||||||
|
throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
|
||||||
|
}
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
for (y = 0; y < 64; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < 64; x++)
|
||||||
|
{
|
||||||
|
if (bitmap_add[x, y])
|
||||||
|
{
|
||||||
|
bitmap_base[x, y] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bitmap_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Object Select and Object Owner Listing
|
||||||
|
|
||||||
|
public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client)
|
||||||
|
{
|
||||||
|
List<uint> resultLocalIDs = new List<uint>();
|
||||||
|
foreach (SceneObjectGroup obj in primsOverMe)
|
||||||
|
{
|
||||||
|
if (obj.LocalId > 0)
|
||||||
|
{
|
||||||
|
if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == landData.ownerID)
|
||||||
|
{
|
||||||
|
resultLocalIDs.Add(obj.LocalId);
|
||||||
|
}
|
||||||
|
// else if (request_type == LandManager.LAND_SELECT_OBJECTS_GROUP && ...) // TODO: group support
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER &&
|
||||||
|
obj.OwnerID != remote_client.AgentId)
|
||||||
|
{
|
||||||
|
resultLocalIDs.Add(obj.LocalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool firstCall = true;
|
||||||
|
int MAX_OBJECTS_PER_PACKET = 251;
|
||||||
|
ForceObjectSelectPacket pack = (ForceObjectSelectPacket) PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect);
|
||||||
|
// TODO: don't create new blocks if recycling an old packet
|
||||||
|
ForceObjectSelectPacket.DataBlock[] data;
|
||||||
|
while (resultLocalIDs.Count > 0)
|
||||||
|
{
|
||||||
|
if (firstCall)
|
||||||
|
{
|
||||||
|
pack._Header.ResetList = true;
|
||||||
|
firstCall = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pack._Header.ResetList = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET)
|
||||||
|
{
|
||||||
|
data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count];
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++)
|
||||||
|
{
|
||||||
|
data[i] = new ForceObjectSelectPacket.DataBlock();
|
||||||
|
data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]);
|
||||||
|
resultLocalIDs.RemoveAt(0);
|
||||||
|
}
|
||||||
|
pack.Data = data;
|
||||||
|
remote_client.OutPacket((Packet) pack, ThrottleOutPacketType.Task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes
|
||||||
|
/// aggreagete details such as the number of prims.
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="remote_client">
|
||||||
|
/// A <see cref="IClientAPI"/>
|
||||||
|
/// </param>
|
||||||
|
public void sendLandObjectOwners(IClientAPI remote_client)
|
||||||
|
{
|
||||||
|
Dictionary<LLUUID, int> primCount = new Dictionary<LLUUID, int>();
|
||||||
|
ParcelObjectOwnersReplyPacket pack
|
||||||
|
= (ParcelObjectOwnersReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
|
||||||
|
// TODO: don't create new blocks if recycling an old packet
|
||||||
|
|
||||||
|
foreach (SceneObjectGroup obj in primsOverMe)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!primCount.ContainsKey(obj.OwnerID))
|
||||||
|
{
|
||||||
|
primCount.Add(obj.OwnerID, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NullReferenceException)
|
||||||
|
{
|
||||||
|
m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
primCount[obj.OwnerID] += obj.PrimCount;
|
||||||
|
}
|
||||||
|
catch (KeyNotFoundException)
|
||||||
|
{
|
||||||
|
m_log.Error("[LAND]: Unable to match a prim with it's owner.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int notifyCount = primCount.Count;
|
||||||
|
|
||||||
|
if (notifyCount > 0)
|
||||||
|
{
|
||||||
|
if (notifyCount > 32)
|
||||||
|
{
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
|
||||||
|
+ " - a developer might want to investigate whether this is a hard limit", 32);
|
||||||
|
|
||||||
|
notifyCount = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
|
||||||
|
= new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
|
||||||
|
|
||||||
|
int num = 0;
|
||||||
|
foreach (LLUUID owner in primCount.Keys)
|
||||||
|
{
|
||||||
|
dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock();
|
||||||
|
dataBlock[num].Count = primCount[owner];
|
||||||
|
dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added
|
||||||
|
dataBlock[num].OnlineStatus = true; //TODO: fix me later
|
||||||
|
dataBlock[num].OwnerID = owner;
|
||||||
|
|
||||||
|
num++;
|
||||||
|
|
||||||
|
if (num >= notifyCount)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pack.Data = dataBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
remote_client.OutPacket(pack, ThrottleOutPacketType.Task);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<LLUUID, int> getLandObjectOwners()
|
||||||
|
{
|
||||||
|
Dictionary<LLUUID, int> ownersAndCount = new Dictionary<LLUUID, int>();
|
||||||
|
foreach (SceneObjectGroup obj in primsOverMe)
|
||||||
|
{
|
||||||
|
if (!ownersAndCount.ContainsKey(obj.OwnerID))
|
||||||
|
{
|
||||||
|
ownersAndCount.Add(obj.OwnerID, 0);
|
||||||
|
}
|
||||||
|
ownersAndCount[obj.OwnerID] += obj.PrimCount;
|
||||||
|
}
|
||||||
|
return ownersAndCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Object Returning
|
||||||
|
|
||||||
|
public void returnObject(SceneObjectGroup obj)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void returnLandObjects(int type, LLUUID owner)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Object Adding/Removing from Parcel
|
||||||
|
|
||||||
|
public void resetLandPrimCounts()
|
||||||
|
{
|
||||||
|
landData.groupPrims = 0;
|
||||||
|
landData.ownerPrims = 0;
|
||||||
|
landData.otherPrims = 0;
|
||||||
|
landData.selectedPrims = 0;
|
||||||
|
primsOverMe.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPrimToCount(SceneObjectGroup obj)
|
||||||
|
{
|
||||||
|
LLUUID prim_owner = obj.OwnerID;
|
||||||
|
int prim_count = obj.PrimCount;
|
||||||
|
|
||||||
|
if (obj.IsSelected)
|
||||||
|
{
|
||||||
|
landData.selectedPrims += prim_count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (prim_owner == landData.ownerID)
|
||||||
|
{
|
||||||
|
landData.ownerPrims += prim_count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
landData.otherPrims += prim_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
primsOverMe.Add(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePrimFromCount(SceneObjectGroup obj)
|
||||||
|
{
|
||||||
|
if (primsOverMe.Contains(obj))
|
||||||
|
{
|
||||||
|
LLUUID prim_owner = obj.OwnerID;
|
||||||
|
int prim_count = obj.PrimCount;
|
||||||
|
|
||||||
|
if (prim_owner == landData.ownerID)
|
||||||
|
{
|
||||||
|
landData.ownerPrims -= prim_count;
|
||||||
|
}
|
||||||
|
else if (prim_owner == landData.groupID)
|
||||||
|
{
|
||||||
|
landData.groupPrims -= prim_count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
landData.otherPrims -= prim_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
primsOverMe.Remove(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.ExportSerialiser
|
||||||
|
{
|
||||||
|
internal interface IFileSerialiser
|
||||||
|
{
|
||||||
|
string WriteToFile(Scene scene, string dir);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.ExportSerialiser
|
||||||
|
{
|
||||||
|
public interface IRegionSerialiser
|
||||||
|
{
|
||||||
|
List<string> SerialiseRegion(Scene scene, string saveDir);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.ExportSerialiser
|
||||||
|
{
|
||||||
|
internal class SerialiseObjects : IFileSerialiser
|
||||||
|
{
|
||||||
|
#region IFileSerialiser Members
|
||||||
|
|
||||||
|
public string WriteToFile(Scene scene, string dir)
|
||||||
|
{
|
||||||
|
string targetFileName = dir + "objects.xml";
|
||||||
|
|
||||||
|
SaveSerialisedToFile(targetFileName, scene);
|
||||||
|
|
||||||
|
return "objects.xml";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public void SaveSerialisedToFile(string fileName, Scene scene)
|
||||||
|
{
|
||||||
|
string xmlstream = GetObjectXml(scene);
|
||||||
|
|
||||||
|
MemoryStream stream = ReformatXmlString(xmlstream);
|
||||||
|
|
||||||
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
CreateXmlFile(stream, fileName);
|
||||||
|
|
||||||
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
CreateCompressedXmlFile(stream, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MemoryStream ReformatXmlString(string xmlstream)
|
||||||
|
{
|
||||||
|
MemoryStream stream = new MemoryStream();
|
||||||
|
XmlTextWriter formatter = new XmlTextWriter(stream, Encoding.UTF8);
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
|
||||||
|
doc.LoadXml(xmlstream);
|
||||||
|
formatter.Formatting = Formatting.Indented;
|
||||||
|
doc.WriteContentTo(formatter);
|
||||||
|
formatter.Flush();
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetObjectXml(Scene scene)
|
||||||
|
{
|
||||||
|
string xmlstream = "<scene>";
|
||||||
|
|
||||||
|
List<EntityBase> EntityList = scene.GetEntities();
|
||||||
|
List<string> EntityXml = new List<string>();
|
||||||
|
|
||||||
|
foreach (EntityBase ent in EntityList)
|
||||||
|
{
|
||||||
|
if (ent is SceneObjectGroup)
|
||||||
|
{
|
||||||
|
EntityXml.Add(((SceneObjectGroup) ent).ToXmlString2());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EntityXml.Sort();
|
||||||
|
|
||||||
|
foreach (string xml in EntityXml)
|
||||||
|
xmlstream += xml;
|
||||||
|
|
||||||
|
xmlstream += "</scene>";
|
||||||
|
return xmlstream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateXmlFile(MemoryStream xmlStream, string fileName)
|
||||||
|
{
|
||||||
|
FileStream objectsFile = new FileStream(fileName, FileMode.Create);
|
||||||
|
|
||||||
|
xmlStream.WriteTo(objectsFile);
|
||||||
|
objectsFile.Flush();
|
||||||
|
objectsFile.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateCompressedXmlFile(MemoryStream xmlStream, string fileName)
|
||||||
|
{
|
||||||
|
#region GZip Compressed Version
|
||||||
|
FileStream objectsFileCompressed = new FileStream(fileName + ".gzs", FileMode.Create);
|
||||||
|
MemoryStream gzipMSStream = new MemoryStream();
|
||||||
|
GZipStream gzipStream = new GZipStream(gzipMSStream, CompressionMode.Compress);
|
||||||
|
xmlStream.WriteTo(gzipStream);
|
||||||
|
gzipMSStream.WriteTo(objectsFileCompressed);
|
||||||
|
objectsFileCompressed.Flush();
|
||||||
|
objectsFileCompressed.Close();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Terrain;
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.ExportSerialiser
|
||||||
|
{
|
||||||
|
internal class SerialiseTerrain : IFileSerialiser
|
||||||
|
{
|
||||||
|
#region IFileSerialiser Members
|
||||||
|
|
||||||
|
public string WriteToFile(Scene scene, string dir)
|
||||||
|
{
|
||||||
|
ITerrainLoader fileSystemExporter = new RAW32();
|
||||||
|
string targetFileName = dir + "heightmap.r32";
|
||||||
|
|
||||||
|
lock (scene.Heightmap)
|
||||||
|
{
|
||||||
|
fileSystemExporter.SaveFile(targetFileName, scene.Heightmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "heightmap.r32";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,169 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Modules.ExportSerialiser;
|
||||||
|
using OpenSim.Region.Environment.Modules.Framework;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Serialiser
|
||||||
|
{
|
||||||
|
public class SerialiserModule : IRegionModule, IRegionSerialiser
|
||||||
|
{
|
||||||
|
private Commander m_commander = new Commander("Export");
|
||||||
|
private List<Scene> m_regions = new List<Scene>();
|
||||||
|
private string m_savedir = "exports" + "/";
|
||||||
|
private List<IFileSerialiser> m_serialisers = new List<IFileSerialiser>();
|
||||||
|
|
||||||
|
#region IRegionModule Members
|
||||||
|
|
||||||
|
public void Initialise(Scene scene, IConfigSource source)
|
||||||
|
{
|
||||||
|
scene.RegisterModuleCommander("Export", m_commander);
|
||||||
|
scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
|
||||||
|
scene.RegisterModuleInterface<IRegionSerialiser>(this);
|
||||||
|
|
||||||
|
lock (m_regions)
|
||||||
|
{
|
||||||
|
m_regions.Add(scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
lock (m_serialisers)
|
||||||
|
{
|
||||||
|
m_serialisers.Add(new SerialiseTerrain());
|
||||||
|
m_serialisers.Add(new SerialiseObjects());
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadCommanderCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
m_regions.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "ExportSerialisationModule"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSharedModule
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IRegionSerialiser Members
|
||||||
|
|
||||||
|
public List<string> SerialiseRegion(Scene scene, string saveDir)
|
||||||
|
{
|
||||||
|
List<string> results = new List<string>();
|
||||||
|
|
||||||
|
if (!Directory.Exists(saveDir))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(saveDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (m_serialisers)
|
||||||
|
{
|
||||||
|
foreach (IFileSerialiser serialiser in m_serialisers)
|
||||||
|
{
|
||||||
|
results.Add(serialiser.WriteToFile(scene, saveDir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextWriter regionInfoWriter = new StreamWriter(saveDir + "README.TXT");
|
||||||
|
regionInfoWriter.WriteLine("Region Name: " + scene.RegionInfo.RegionName);
|
||||||
|
regionInfoWriter.WriteLine("Region ID: " + scene.RegionInfo.RegionID.ToString());
|
||||||
|
regionInfoWriter.WriteLine("Backup Time: UTC " + DateTime.UtcNow.ToString());
|
||||||
|
regionInfoWriter.WriteLine("Serialise Version: 0.1");
|
||||||
|
regionInfoWriter.Close();
|
||||||
|
|
||||||
|
TextWriter manifestWriter = new StreamWriter(saveDir + "region.manifest");
|
||||||
|
foreach (string line in results)
|
||||||
|
{
|
||||||
|
manifestWriter.WriteLine(line);
|
||||||
|
}
|
||||||
|
manifestWriter.Close();
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void EventManager_OnPluginConsole(string[] args)
|
||||||
|
{
|
||||||
|
if (args[0] == "export")
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceSaveRegion(Object[] args)
|
||||||
|
{
|
||||||
|
foreach (Scene region in m_regions)
|
||||||
|
{
|
||||||
|
if (region.RegionInfo.RegionName == (string) args[0])
|
||||||
|
{
|
||||||
|
List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceSaveAllRegions(Object[] args)
|
||||||
|
{
|
||||||
|
foreach (Scene region in m_regions)
|
||||||
|
{
|
||||||
|
List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadCommanderCommands()
|
||||||
|
{
|
||||||
|
Command serialiseSceneCommand = new Command("save", InterfaceSaveRegion, "Saves the named region into the exports directory.");
|
||||||
|
serialiseSceneCommand.AddArgument("region-name", "The name of the region you wish to export", "String");
|
||||||
|
|
||||||
|
Command serialiseAllScenesCommand = new Command("save-all", InterfaceSaveAllRegions, "Saves all regions into the exports directory.");
|
||||||
|
|
||||||
|
m_commander.RegisterCommand("save", serialiseSceneCommand);
|
||||||
|
m_commander.RegisterCommand("save-all", serialiseAllScenesCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes;
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.Effects
|
||||||
|
{
|
||||||
|
internal class CookieCutter : ITerrainEffect
|
||||||
|
{
|
||||||
|
#region ITerrainEffect Members
|
||||||
|
|
||||||
|
public void RunEffect(ITerrainChannel map)
|
||||||
|
{
|
||||||
|
SmoothArea smooth = new SmoothArea();
|
||||||
|
ITerrainPaintableEffect eroder = new WeatherSphere();
|
||||||
|
|
||||||
|
bool[,] cliffMask = new bool[map.Width,map.Height];
|
||||||
|
bool[,] channelMask = new bool[map.Width,map.Height];
|
||||||
|
bool[,] smoothMask = new bool[map.Width,map.Height];
|
||||||
|
|
||||||
|
Console.WriteLine("S1");
|
||||||
|
|
||||||
|
// Step one, generate rough mask
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
Console.Write(".");
|
||||||
|
smoothMask[x, y] = true;
|
||||||
|
|
||||||
|
// Start underwater
|
||||||
|
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 5;
|
||||||
|
// Add a little height. (terrain should now be above water, mostly.)
|
||||||
|
map[x, y] += 20;
|
||||||
|
|
||||||
|
int channelsX = 4;
|
||||||
|
int channelWidth = (map.Width / channelsX / 4);
|
||||||
|
int channelsY = 4;
|
||||||
|
int channelHeight = (map.Height / channelsY / 4);
|
||||||
|
|
||||||
|
SetLowerChannel(map, cliffMask, channelMask, x, y, channelsX, channelWidth, map.Width, x);
|
||||||
|
SetLowerChannel(map, cliffMask, channelMask, x, y, channelsY, channelHeight, map.Height, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("S2");
|
||||||
|
//smooth.FloodEffect(map, smoothMask, 4.0);
|
||||||
|
|
||||||
|
Console.WriteLine("S3");
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
if (cliffMask[x, y] == true)
|
||||||
|
eroder.PaintEffect(map, x, y, 4, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x = 0; x < map.Width; x += 2)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y += 2)
|
||||||
|
{
|
||||||
|
if (map[x, y] < 0.1)
|
||||||
|
map[x, y] = 0.1;
|
||||||
|
if (map[x, y] > 256)
|
||||||
|
map[x, y] = 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//smooth.FloodEffect(map, smoothMask, 4.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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++)
|
||||||
|
{
|
||||||
|
double distanceToLine = Math.Abs(rp - ((mapSize / numChannels) * i));
|
||||||
|
|
||||||
|
if (distanceToLine < channelWidth)
|
||||||
|
{
|
||||||
|
if (channelMask[x, y])
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Remove channels
|
||||||
|
map[x, y] -= 10;
|
||||||
|
channelMask[x, y] = true;
|
||||||
|
}
|
||||||
|
if (distanceToLine < 1)
|
||||||
|
{
|
||||||
|
cliffMask[x, y] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.Effects
|
||||||
|
{
|
||||||
|
internal class DefaultTerrainGenerator : ITerrainEffect
|
||||||
|
{
|
||||||
|
#region ITerrainEffect Members
|
||||||
|
|
||||||
|
public void RunEffect(ITerrainChannel map)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10;
|
||||||
|
double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01;
|
||||||
|
if (map[x, y] < spherFac)
|
||||||
|
{
|
||||||
|
map[x, y] = spherFac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A generic windows bitmap loader.
|
||||||
|
/// Should be capable of handling 24-bit RGB images.
|
||||||
|
///
|
||||||
|
/// Uses the System.Drawing filesystem loader.
|
||||||
|
/// </summary>
|
||||||
|
internal class BMP : GenericSystemDrawing
|
||||||
|
{
|
||||||
|
/// <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 override void SaveFile(string filename, ITerrainChannel map)
|
||||||
|
{
|
||||||
|
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||||
|
|
||||||
|
colours.Save(filename, ImageFormat.Bmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The human readable version of the file format(s) this loader handles
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "BMP";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||||
|
{
|
||||||
|
internal class GIF : GenericSystemDrawing
|
||||||
|
{
|
||||||
|
public override void SaveFile(string filename, ITerrainChannel map)
|
||||||
|
{
|
||||||
|
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||||
|
|
||||||
|
colours.Save(filename, ImageFormat.Gif);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "GIF";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A virtual class designed to have methods overloaded,
|
||||||
|
/// this class provides an interface for a generic image
|
||||||
|
/// saving and loading mechanism, but does not specify the
|
||||||
|
/// format. It should not be insubstantiated directly.
|
||||||
|
/// </summary>
|
||||||
|
public class GenericSystemDrawing : ITerrainLoader
|
||||||
|
{
|
||||||
|
#region ITerrainLoader Members
|
||||||
|
|
||||||
|
public string FileExtension
|
||||||
|
{
|
||||||
|
get { return ".gsd"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads a file from a specified filename on the disk,
|
||||||
|
/// parses the image using the System.Drawing parsers
|
||||||
|
/// then returns a terrain channel. Values are
|
||||||
|
/// returned based on HSL brightness between 0m and 128m
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename">The target image to load</param>
|
||||||
|
/// <returns>A terrain channel generated from the image.</returns>
|
||||||
|
public virtual ITerrainChannel LoadFile(string filename)
|
||||||
|
{
|
||||||
|
Bitmap file = new Bitmap(filename);
|
||||||
|
|
||||||
|
ITerrainChannel retval = new TerrainChannel(file.Width, file.Height);
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < file.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < file.Height; y++)
|
||||||
|
{
|
||||||
|
retval[x, y] = file.GetPixel(x, y).GetBrightness() * 128;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
return "SYS.DRAWING";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Protected method, generates a grayscale bitmap
|
||||||
|
/// image from a specified terrain channel.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="map">The terrain channel to export to bitmap</param>
|
||||||
|
/// <returns>A System.Drawing.Bitmap containing a grayscale image</returns>
|
||||||
|
protected Bitmap CreateGrayscaleBitmapFromMap(ITerrainChannel map)
|
||||||
|
{
|
||||||
|
Bitmap bmp = new Bitmap(map.Width, map.Height);
|
||||||
|
|
||||||
|
int pallete = 256;
|
||||||
|
|
||||||
|
Color[] grays = new Color[pallete];
|
||||||
|
for (int i = 0; i < grays.Length; i++)
|
||||||
|
{
|
||||||
|
grays[i] = Color.FromArgb(i, i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
// 512 is the largest possible height before colours clamp
|
||||||
|
int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 128.0), 0.0) * (pallete - 1));
|
||||||
|
|
||||||
|
// Handle error conditions
|
||||||
|
if (colorindex > pallete - 1 || colorindex < 0)
|
||||||
|
bmp.SetPixel(x, map.Height - y - 1, Color.Red);
|
||||||
|
else
|
||||||
|
bmp.SetPixel(x, map.Height - y - 1, grays[colorindex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Protected method, generates a coloured bitmap
|
||||||
|
/// image from a specified terrain channel.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="map">The terrain channel to export to bitmap</param>
|
||||||
|
/// <returns>A System.Drawing.Bitmap containing a coloured image</returns>
|
||||||
|
protected Bitmap CreateBitmapFromMap(ITerrainChannel map)
|
||||||
|
{
|
||||||
|
Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
|
||||||
|
|
||||||
|
int pallete = gradientmapLd.Height;
|
||||||
|
|
||||||
|
Bitmap bmp = new Bitmap(map.Width, map.Height);
|
||||||
|
Color[] colours = new Color[pallete];
|
||||||
|
|
||||||
|
for (int i = 0; i < pallete; i++)
|
||||||
|
{
|
||||||
|
colours[i] = gradientmapLd.GetPixel(0, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
// 512 is the largest possible height before colours clamp
|
||||||
|
int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 512.0), 0.0) * (pallete - 1));
|
||||||
|
|
||||||
|
// Handle error conditions
|
||||||
|
if (colorindex > pallete - 1 || colorindex < 0)
|
||||||
|
bmp.SetPixel(x, map.Height - y - 1, Color.Red);
|
||||||
|
else
|
||||||
|
bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||||
|
{
|
||||||
|
public class JPEG : ITerrainLoader
|
||||||
|
{
|
||||||
|
#region ITerrainLoader Members
|
||||||
|
|
||||||
|
public string FileExtension
|
||||||
|
{
|
||||||
|
get { return ".jpg"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITerrainChannel LoadFile(string filename)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveFile(string filename, ITerrainChannel map)
|
||||||
|
{
|
||||||
|
Bitmap colours = CreateBitmapFromMap(map);
|
||||||
|
|
||||||
|
colours.Save(filename, ImageFormat.Jpeg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "JPEG";
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bitmap CreateBitmapFromMap(ITerrainChannel map)
|
||||||
|
{
|
||||||
|
Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
|
||||||
|
|
||||||
|
int pallete = gradientmapLd.Height;
|
||||||
|
|
||||||
|
Bitmap bmp = new Bitmap(map.Width, map.Height);
|
||||||
|
Color[] colours = new Color[pallete];
|
||||||
|
|
||||||
|
for (int i = 0; i < pallete; i++)
|
||||||
|
{
|
||||||
|
colours[i] = gradientmapLd.GetPixel(0, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
// 512 is the largest possible height before colours clamp
|
||||||
|
int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 512.0), 0.0) * (pallete - 1));
|
||||||
|
bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||||
|
{
|
||||||
|
public class LLRAW : ITerrainLoader
|
||||||
|
{
|
||||||
|
#region ITerrainLoader Members
|
||||||
|
|
||||||
|
public ITerrainChannel LoadFile(string filename)
|
||||||
|
{
|
||||||
|
TerrainChannel retval = new TerrainChannel();
|
||||||
|
|
||||||
|
FileInfo file = new FileInfo(filename);
|
||||||
|
FileStream s = file.Open(FileMode.Open, FileAccess.Read);
|
||||||
|
BinaryReader bs = new BinaryReader(s);
|
||||||
|
int x, y;
|
||||||
|
for (y = 0; y < retval.Height; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < retval.Width; x++)
|
||||||
|
{
|
||||||
|
retval[x, y] = (double) bs.ReadByte() * ((double) bs.ReadByte() / 127.0);
|
||||||
|
bs.ReadBytes(11); // Advance the stream to next bytes.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bs.Close();
|
||||||
|
s.Close();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveFile(string filename, ITerrainChannel map)
|
||||||
|
{
|
||||||
|
FileInfo file = new FileInfo(filename);
|
||||||
|
FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write);
|
||||||
|
BinaryWriter binStream = new BinaryWriter(s);
|
||||||
|
|
||||||
|
// Generate a smegging big lookup table to speed the operation up (it needs it)
|
||||||
|
double[] lookupHeightTable = new double[65536];
|
||||||
|
int i, j, x, y;
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 256; j++)
|
||||||
|
{
|
||||||
|
lookupHeightTable[i + (j * 256)] = ((double) i * ((double) j / 127.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output the calculated raw
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
double t = map[x, y];
|
||||||
|
double min = double.MaxValue;
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 65536; i++)
|
||||||
|
{
|
||||||
|
if (Math.Abs(t - lookupHeightTable[i]) < min)
|
||||||
|
{
|
||||||
|
min = Math.Abs(t - lookupHeightTable[i]);
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte red = (byte) (index & 0xFF);
|
||||||
|
byte green = (byte) ((index >> 8) & 0xFF);
|
||||||
|
byte blue = 20;
|
||||||
|
byte alpha1 = 0; // Land Parcels
|
||||||
|
byte alpha2 = 0; // For Sale Land
|
||||||
|
byte alpha3 = 0; // Public Edit Object
|
||||||
|
byte alpha4 = 0; // Public Edit Land
|
||||||
|
byte alpha5 = 255; // Safe Land
|
||||||
|
byte alpha6 = 255; // Flying Allowed
|
||||||
|
byte alpha7 = 255; // Create Landmark
|
||||||
|
byte alpha8 = 255; // Outside Scripts
|
||||||
|
byte alpha9 = red;
|
||||||
|
byte alpha10 = green;
|
||||||
|
|
||||||
|
binStream.Write(red);
|
||||||
|
binStream.Write(green);
|
||||||
|
binStream.Write(blue);
|
||||||
|
binStream.Write(alpha1);
|
||||||
|
binStream.Write(alpha2);
|
||||||
|
binStream.Write(alpha3);
|
||||||
|
binStream.Write(alpha4);
|
||||||
|
binStream.Write(alpha5);
|
||||||
|
binStream.Write(alpha6);
|
||||||
|
binStream.Write(alpha7);
|
||||||
|
binStream.Write(alpha8);
|
||||||
|
binStream.Write(alpha9);
|
||||||
|
binStream.Write(alpha10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binStream.Close();
|
||||||
|
s.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string FileExtension
|
||||||
|
{
|
||||||
|
get { return ".raw"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "LL/SL RAW";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||||
|
{
|
||||||
|
internal class PNG : GenericSystemDrawing
|
||||||
|
{
|
||||||
|
public override void SaveFile(string filename, ITerrainChannel map)
|
||||||
|
{
|
||||||
|
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||||
|
|
||||||
|
colours.Save(filename, ImageFormat.Png);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "PNG";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||||
|
{
|
||||||
|
public class RAW32 : ITerrainLoader
|
||||||
|
{
|
||||||
|
#region ITerrainLoader Members
|
||||||
|
|
||||||
|
public string FileExtension
|
||||||
|
{
|
||||||
|
get { return ".r32"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITerrainChannel LoadFile(string filename)
|
||||||
|
{
|
||||||
|
TerrainChannel retval = new TerrainChannel();
|
||||||
|
|
||||||
|
FileInfo file = new FileInfo(filename);
|
||||||
|
FileStream s = file.Open(FileMode.Open, FileAccess.Read);
|
||||||
|
BinaryReader bs = new BinaryReader(s);
|
||||||
|
int x, y;
|
||||||
|
for (y = 0; y < retval.Height; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < retval.Width; x++)
|
||||||
|
{
|
||||||
|
retval[x, y] = bs.ReadSingle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bs.Close();
|
||||||
|
s.Close();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight)
|
||||||
|
{
|
||||||
|
TerrainChannel retval = new TerrainChannel(sectionWidth, sectionHeight);
|
||||||
|
|
||||||
|
FileInfo file = new FileInfo(filename);
|
||||||
|
FileStream s = file.Open(FileMode.Open, FileAccess.Read);
|
||||||
|
BinaryReader bs = new BinaryReader(s);
|
||||||
|
|
||||||
|
int currFileXOffset = 0;
|
||||||
|
int currFileYOffset = 0;
|
||||||
|
|
||||||
|
// if our region isn't on the first Y section of the areas to be landscaped, then
|
||||||
|
// advance to our section of the file
|
||||||
|
while (currFileYOffset < offsetY)
|
||||||
|
{
|
||||||
|
// read a whole strip of regions
|
||||||
|
int heightsToRead = sectionHeight * (fileWidth * sectionWidth);
|
||||||
|
bs.ReadBytes(heightsToRead * 4); // because the floats are 4 bytes in the file
|
||||||
|
currFileYOffset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// got to the Y start offset within the file of our region
|
||||||
|
// so read the file bits associated with our region
|
||||||
|
int x, y;
|
||||||
|
// for each Y within our Y offset
|
||||||
|
for (y = 0; y < sectionHeight; y++)
|
||||||
|
{
|
||||||
|
currFileXOffset = 0;
|
||||||
|
|
||||||
|
// if our region isn't the first X section of the areas to be landscaped, then
|
||||||
|
// advance the stream to the X start pos of our section in the file
|
||||||
|
// i.e. eat X upto where we start
|
||||||
|
while (currFileXOffset < offsetX)
|
||||||
|
{
|
||||||
|
bs.ReadBytes(sectionWidth * 4); // 4 bytes = single
|
||||||
|
currFileXOffset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// got to our X offset, so write our regions X line
|
||||||
|
for (x = 0; x < sectionWidth; x++)
|
||||||
|
{
|
||||||
|
// Read a strip and continue
|
||||||
|
retval[x, y] = bs.ReadSingle();
|
||||||
|
}
|
||||||
|
// record that we wrote it
|
||||||
|
currFileXOffset++;
|
||||||
|
|
||||||
|
// if our region isn't the last X section of the areas to be landscaped, then
|
||||||
|
// advance the stream to the end of this Y column
|
||||||
|
while (currFileXOffset < fileWidth)
|
||||||
|
{
|
||||||
|
// eat the next regions x line
|
||||||
|
bs.ReadBytes(sectionWidth * 4); // 4 bytes = single
|
||||||
|
currFileXOffset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bs.Close();
|
||||||
|
s.Close();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveFile(string filename, ITerrainChannel map)
|
||||||
|
{
|
||||||
|
FileInfo file = new FileInfo(filename);
|
||||||
|
FileStream s = file.Open(FileMode.Create, FileAccess.Write);
|
||||||
|
BinaryWriter bs = new BinaryWriter(s);
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
bs.Write((float) map[x, y]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bs.Close();
|
||||||
|
s.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "RAW32";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||||
|
{
|
||||||
|
internal class TIFF : GenericSystemDrawing
|
||||||
|
{
|
||||||
|
public override void SaveFile(string filename, ITerrainChannel map)
|
||||||
|
{
|
||||||
|
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||||
|
|
||||||
|
colours.Save(filename, ImageFormat.Tiff);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "TIFF";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Terragen File Format Loader
|
||||||
|
/// Built from specification at
|
||||||
|
/// http://www.planetside.co.uk/terragen/dev/tgterrain.html
|
||||||
|
/// </summary>
|
||||||
|
internal class Terragen : ITerrainLoader
|
||||||
|
{
|
||||||
|
#region ITerrainLoader Members
|
||||||
|
|
||||||
|
public ITerrainChannel LoadFile(string filename)
|
||||||
|
{
|
||||||
|
TerrainChannel retval = new TerrainChannel();
|
||||||
|
|
||||||
|
FileInfo file = new FileInfo(filename);
|
||||||
|
FileStream s = file.Open(FileMode.Open, FileAccess.Read);
|
||||||
|
BinaryReader bs = new BinaryReader(s);
|
||||||
|
|
||||||
|
bool eof = false;
|
||||||
|
if (ASCIIEncoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ")
|
||||||
|
{
|
||||||
|
// Terragen file
|
||||||
|
while (eof == false)
|
||||||
|
{
|
||||||
|
int w = 256;
|
||||||
|
int h = 256;
|
||||||
|
string tmp = ASCIIEncoding.ASCII.GetString(bs.ReadBytes(4));
|
||||||
|
switch (tmp)
|
||||||
|
{
|
||||||
|
case "SIZE":
|
||||||
|
int sztmp = bs.ReadInt16() + 1;
|
||||||
|
w = sztmp;
|
||||||
|
h = sztmp;
|
||||||
|
bs.ReadInt16();
|
||||||
|
break;
|
||||||
|
case "XPTS":
|
||||||
|
w = bs.ReadInt16();
|
||||||
|
bs.ReadInt16();
|
||||||
|
break;
|
||||||
|
case "YPTS":
|
||||||
|
h = bs.ReadInt16();
|
||||||
|
bs.ReadInt16();
|
||||||
|
break;
|
||||||
|
case "ALTW":
|
||||||
|
eof = true;
|
||||||
|
Int16 heightScale = bs.ReadInt16();
|
||||||
|
Int16 baseHeight = bs.ReadInt16();
|
||||||
|
retval = new TerrainChannel(w, h);
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
retval[x, y] = (double) baseHeight + (double) bs.ReadInt16() * (double) heightScale / 65536.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bs.ReadInt32();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bs.Close();
|
||||||
|
s.Close();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveFile(string filename, ITerrainChannel map)
|
||||||
|
{
|
||||||
|
char[] header = "TERRAGENTERRAIN".ToCharArray();
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FileExtension
|
||||||
|
{
|
||||||
|
get { return ".ter"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "Terragen";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||||
|
{
|
||||||
|
public class FlattenArea : ITerrainFloodEffect
|
||||||
|
{
|
||||||
|
#region ITerrainFloodEffect Members
|
||||||
|
|
||||||
|
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||||
|
{
|
||||||
|
double sum = 0.0;
|
||||||
|
double steps = 0.0;
|
||||||
|
double avg;
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
if (fillArea[x, y])
|
||||||
|
{
|
||||||
|
sum += map[x, y];
|
||||||
|
steps += 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
avg = sum / steps;
|
||||||
|
|
||||||
|
double str = 0.1 * strength; // == 0.2 in the default client
|
||||||
|
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
if (fillArea[x, y])
|
||||||
|
map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||||
|
{
|
||||||
|
public class LowerArea : ITerrainFloodEffect
|
||||||
|
{
|
||||||
|
#region ITerrainFloodEffect Members
|
||||||
|
|
||||||
|
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
if (fillArea[x, y])
|
||||||
|
{
|
||||||
|
map[x, y] -= strength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||||
|
{
|
||||||
|
public class NoiseArea : ITerrainFloodEffect
|
||||||
|
{
|
||||||
|
#region ITerrainFloodEffect Members
|
||||||
|
|
||||||
|
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
if (fillArea[x, y])
|
||||||
|
{
|
||||||
|
double noise = TerrainUtil.PerlinNoise2D((double) x / Constants.RegionSize, (double) y / Constants.RegionSize, 8, 1.0);
|
||||||
|
|
||||||
|
map[x, y] += noise * strength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||||
|
{
|
||||||
|
public class RaiseArea : ITerrainFloodEffect
|
||||||
|
{
|
||||||
|
#region ITerrainFloodEffect Members
|
||||||
|
|
||||||
|
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
if (fillArea[x, y])
|
||||||
|
{
|
||||||
|
map[x, y] += strength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||||
|
{
|
||||||
|
public class RevertArea : ITerrainFloodEffect
|
||||||
|
{
|
||||||
|
private readonly ITerrainChannel m_revertmap;
|
||||||
|
|
||||||
|
public RevertArea(ITerrainChannel revertmap)
|
||||||
|
{
|
||||||
|
m_revertmap = revertmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ITerrainFloodEffect Members
|
||||||
|
|
||||||
|
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
if (fillArea[x, y])
|
||||||
|
{
|
||||||
|
map[x, y] = (map[x, y] * (1.0 - strength)) + (m_revertmap[x, y] * strength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||||
|
{
|
||||||
|
public class SmoothArea : ITerrainFloodEffect
|
||||||
|
{
|
||||||
|
#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 h = map.Height;
|
||||||
|
|
||||||
|
if (x > w - 2.0)
|
||||||
|
x = w - 2.0;
|
||||||
|
if (y > h - 2.0)
|
||||||
|
y = h - 2.0;
|
||||||
|
if (x < 0.0)
|
||||||
|
x = 0.0;
|
||||||
|
if (y < 0.0)
|
||||||
|
y = 0.0;
|
||||||
|
|
||||||
|
int stepSize = 1;
|
||||||
|
double h00 = map[(int) x, (int) y];
|
||||||
|
double h10 = map[(int) x + stepSize, (int) y];
|
||||||
|
double h01 = map[(int) x, (int) y + stepSize];
|
||||||
|
double h11 = map[(int) x + stepSize, (int) y + stepSize];
|
||||||
|
double h1 = h00;
|
||||||
|
double h2 = h10;
|
||||||
|
double h3 = h01;
|
||||||
|
double h4 = h11;
|
||||||
|
double a00 = h1;
|
||||||
|
double a10 = h2 - h1;
|
||||||
|
double a01 = h3 - h1;
|
||||||
|
double a11 = h1 - h2 - h3 + h4;
|
||||||
|
double partialx = x - (int) x;
|
||||||
|
double partialz = y - (int) y;
|
||||||
|
double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
|
||||||
|
return hi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||||
|
{
|
||||||
|
public interface ITerrainEffect
|
||||||
|
{
|
||||||
|
void RunEffect(ITerrainChannel map);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||||
|
{
|
||||||
|
public interface ITerrainFloodEffect
|
||||||
|
{
|
||||||
|
void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, double strength);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||||
|
{
|
||||||
|
public interface ITerrainLoader
|
||||||
|
{
|
||||||
|
string FileExtension { get; }
|
||||||
|
ITerrainChannel LoadFile(string filename);
|
||||||
|
ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight);
|
||||||
|
void SaveFile(string filename, ITerrainChannel map);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||||
|
{
|
||||||
|
public interface ITerrainModule
|
||||||
|
{
|
||||||
|
void LoadFromFile(string filename);
|
||||||
|
void SaveToFile(string filename);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||||
|
{
|
||||||
|
public interface ITerrainPaintableEffect
|
||||||
|
{
|
||||||
|
void PaintEffect(ITerrainChannel map, double x, double y, double strength, double duration);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenJPEGNet;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||||
|
{
|
||||||
|
internal class MapImageModule : IMapImageGenerator, IRegionModule
|
||||||
|
{
|
||||||
|
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
|
||||||
|
|
||||||
|
public void Initialise(Scene scene, IConfigSource source)
|
||||||
|
{
|
||||||
|
m_scene = scene;
|
||||||
|
m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "MapImageModule"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSharedModule
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void ShadeBuildings(ref Bitmap map)
|
||||||
|
{
|
||||||
|
lock (map)
|
||||||
|
{
|
||||||
|
lock (m_scene.Entities)
|
||||||
|
{
|
||||||
|
foreach (EntityBase entity in m_scene.Entities.Values)
|
||||||
|
{
|
||||||
|
if (entity is SceneObjectGroup)
|
||||||
|
{
|
||||||
|
SceneObjectGroup sog = (SceneObjectGroup) entity;
|
||||||
|
|
||||||
|
foreach (SceneObjectPart primitive in sog.Children.Values)
|
||||||
|
{
|
||||||
|
int x, y, w, h;
|
||||||
|
x = (int) (primitive.AbsolutePosition.X - (primitive.Scale.X / 2));
|
||||||
|
y = (int) (primitive.AbsolutePosition.Y - (primitive.Scale.Y / 2));
|
||||||
|
w = (int) primitive.Scale.X;
|
||||||
|
h = (int) primitive.Scale.Y;
|
||||||
|
|
||||||
|
int dx;
|
||||||
|
for (dx = x; dx < x + w; dx++)
|
||||||
|
{
|
||||||
|
int dy;
|
||||||
|
for (dy = y; dy < y + h; dy++)
|
||||||
|
{
|
||||||
|
if (x < 0 || y < 0)
|
||||||
|
continue;
|
||||||
|
if (x >= map.Width || y >= map.Height)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
map.SetPixel(dx, dy, Color.DarkGray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bitmap TerrainToBitmap(string gradientmap)
|
||||||
|
{
|
||||||
|
Bitmap gradientmapLd = new Bitmap(gradientmap);
|
||||||
|
|
||||||
|
int pallete = gradientmapLd.Height;
|
||||||
|
|
||||||
|
Bitmap bmp = new Bitmap(m_scene.Heightmap.Width, m_scene.Heightmap.Height);
|
||||||
|
Color[] colours = new Color[pallete];
|
||||||
|
|
||||||
|
for (int i = 0; i < pallete; i++)
|
||||||
|
{
|
||||||
|
colours[i] = gradientmapLd.GetPixel(0, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (m_scene.Heightmap)
|
||||||
|
{
|
||||||
|
ITerrainChannel copy = m_scene.Heightmap;
|
||||||
|
for (int y = 0; y < copy.Height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < copy.Width; x++)
|
||||||
|
{
|
||||||
|
// 512 is the largest possible height before colours clamp
|
||||||
|
int colorindex = (int) (Math.Max(Math.Min(1.0, copy[x, y] / 512.0), 0.0) * (pallete - 1));
|
||||||
|
|
||||||
|
// Handle error conditions
|
||||||
|
if (colorindex > pallete - 1 || colorindex < 0)
|
||||||
|
bmp.SetPixel(x, copy.Height - y - 1, Color.Red);
|
||||||
|
else
|
||||||
|
bmp.SetPixel(x, copy.Height - y - 1, colours[colorindex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ShadeBuildings(ref bmp);
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,312 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Hydraulic Erosion Brush
|
||||||
|
/// </summary>
|
||||||
|
public class ErodeSphere : ITerrainPaintableEffect
|
||||||
|
{
|
||||||
|
private double rainHeight = 0.2;
|
||||||
|
private int rounds = 10;
|
||||||
|
private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
|
||||||
|
private double waterSaturation = 0.30; // Can carry 1% of water in height
|
||||||
|
|
||||||
|
#region Supporting Functions
|
||||||
|
|
||||||
|
private int[] Neighbours(NeighbourSystem type, int index)
|
||||||
|
{
|
||||||
|
int[] coord = new int[2];
|
||||||
|
|
||||||
|
index++;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case NeighbourSystem.Moore:
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
coord[0] = -1;
|
||||||
|
coord[1] = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
coord[0] = -0;
|
||||||
|
coord[1] = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
coord[0] = +1;
|
||||||
|
coord[1] = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
coord[0] = -1;
|
||||||
|
coord[1] = -0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
coord[0] = -0;
|
||||||
|
coord[1] = -0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
coord[0] = +1;
|
||||||
|
coord[1] = -0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
coord[0] = -1;
|
||||||
|
coord[1] = +1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
coord[0] = -0;
|
||||||
|
coord[1] = +1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 9:
|
||||||
|
coord[0] = +1;
|
||||||
|
coord[1] = +1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NeighbourSystem.VonNeumann:
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
coord[0] = 0;
|
||||||
|
coord[1] = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
coord[0] = -1;
|
||||||
|
coord[1] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
coord[0] = +1;
|
||||||
|
coord[1] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
coord[0] = 0;
|
||||||
|
coord[1] = +1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
coord[0] = -0;
|
||||||
|
coord[1] = -0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return coord;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum NeighbourSystem
|
||||||
|
{
|
||||||
|
Moore,
|
||||||
|
VonNeumann
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ITerrainPaintableEffect Members
|
||||||
|
|
||||||
|
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||||
|
{
|
||||||
|
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
// Using one 'rain' round for this, so skipping a useless loop
|
||||||
|
// Will need to adapt back in for the Flood brush
|
||||||
|
|
||||||
|
ITerrainChannel water = new TerrainChannel(map.Width, map.Height);
|
||||||
|
ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height);
|
||||||
|
|
||||||
|
// Fill with rain
|
||||||
|
for (x = 0; x < water.Width; x++)
|
||||||
|
for (y = 0; y < water.Height; y++)
|
||||||
|
water[x, y] = Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration);
|
||||||
|
|
||||||
|
for (int i = 0; i < rounds; i++)
|
||||||
|
{
|
||||||
|
// Erode underlying terrain
|
||||||
|
for (x = 0; x < water.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < water.Height; y++)
|
||||||
|
{
|
||||||
|
double solConst = (1.0 / rounds);
|
||||||
|
double sedDelta = water[x, y] * solConst;
|
||||||
|
map[x, y] -= sedDelta;
|
||||||
|
sediment[x, y] += sedDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move water
|
||||||
|
for (x = 0; x < water.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < water.Height; y++)
|
||||||
|
{
|
||||||
|
if (water[x, y] <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Step 1. Calculate average of neighbours
|
||||||
|
|
||||||
|
int neighbours = 0;
|
||||||
|
double altitudeTotal = 0.0;
|
||||||
|
double altitudeMe = map[x, y] + water[x, y];
|
||||||
|
|
||||||
|
int NEIGHBOUR_ME = 4;
|
||||||
|
|
||||||
|
int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
|
||||||
|
|
||||||
|
for (int j = 0; j < NEIGHBOUR_MAX; j++)
|
||||||
|
{
|
||||||
|
if (j != NEIGHBOUR_ME)
|
||||||
|
{
|
||||||
|
int[] coords = Neighbours(type, j);
|
||||||
|
|
||||||
|
coords[0] += x;
|
||||||
|
coords[1] += y;
|
||||||
|
|
||||||
|
if (coords[0] > map.Width - 1)
|
||||||
|
continue;
|
||||||
|
if (coords[1] > map.Height - 1)
|
||||||
|
continue;
|
||||||
|
if (coords[0] < 0)
|
||||||
|
continue;
|
||||||
|
if (coords[1] < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Calculate total height of this neighbour
|
||||||
|
double altitudeNeighbour = water[coords[0], coords[1]] + map[coords[0], coords[1]];
|
||||||
|
|
||||||
|
// If it's greater than me...
|
||||||
|
if (altitudeNeighbour - altitudeMe < 0)
|
||||||
|
{
|
||||||
|
// Add it to our calculations
|
||||||
|
neighbours++;
|
||||||
|
altitudeTotal += altitudeNeighbour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (neighbours == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
double altitudeAvg = altitudeTotal / neighbours;
|
||||||
|
|
||||||
|
// Step 2. Allocate water to neighbours.
|
||||||
|
for (int j = 0; j < NEIGHBOUR_MAX; j++)
|
||||||
|
{
|
||||||
|
if (j != NEIGHBOUR_ME)
|
||||||
|
{
|
||||||
|
int[] coords = Neighbours(type, j);
|
||||||
|
|
||||||
|
coords[0] += x;
|
||||||
|
coords[1] += y;
|
||||||
|
|
||||||
|
if (coords[0] > map.Width - 1)
|
||||||
|
continue;
|
||||||
|
if (coords[1] > map.Height - 1)
|
||||||
|
continue;
|
||||||
|
if (coords[0] < 0)
|
||||||
|
continue;
|
||||||
|
if (coords[1] < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Skip if we dont have water to begin with.
|
||||||
|
if (water[x, y] < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Calculate our delta average
|
||||||
|
double altitudeDelta = altitudeMe - altitudeAvg;
|
||||||
|
|
||||||
|
if (altitudeDelta < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Calculate how much water we can move
|
||||||
|
double waterMin = Math.Min(water[x, y], altitudeDelta);
|
||||||
|
double waterDelta = waterMin * ((water[coords[0], coords[1]] + map[coords[0], coords[1]])
|
||||||
|
/ altitudeTotal);
|
||||||
|
|
||||||
|
double sedimentDelta = sediment[x, y] * (waterDelta / water[x, y]);
|
||||||
|
|
||||||
|
if (sedimentDelta > 0)
|
||||||
|
{
|
||||||
|
sediment[x, y] -= sedimentDelta;
|
||||||
|
sediment[coords[0], coords[1]] += sedimentDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaporate
|
||||||
|
|
||||||
|
for (x = 0; x < water.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < water.Height; y++)
|
||||||
|
{
|
||||||
|
water[x, y] *= 1.0 - (rainHeight / rounds);
|
||||||
|
|
||||||
|
double waterCapacity = waterSaturation * water[x, y];
|
||||||
|
|
||||||
|
double sedimentDeposit = sediment[x, y] - waterCapacity;
|
||||||
|
if (sedimentDeposit > 0)
|
||||||
|
{
|
||||||
|
sediment[x, y] -= sedimentDeposit;
|
||||||
|
map[x, y] += sedimentDeposit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deposit any remainder (should be minimal)
|
||||||
|
for (x = 0; x < water.Width; x++)
|
||||||
|
for (y = 0; y < water.Height; y++)
|
||||||
|
if (sediment[x, y] > 0)
|
||||||
|
map[x, y] += sediment[x, y];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||||
|
{
|
||||||
|
public class FlattenSphere : ITerrainPaintableEffect
|
||||||
|
{
|
||||||
|
// TODO: unused
|
||||||
|
// private double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
|
||||||
|
// {
|
||||||
|
// int w = map.Width;
|
||||||
|
// int h = map.Height;
|
||||||
|
|
||||||
|
// if (x > w - 2.0)
|
||||||
|
// x = w - 2.0;
|
||||||
|
// if (y > h - 2.0)
|
||||||
|
// y = h - 2.0;
|
||||||
|
// if (x < 0.0)
|
||||||
|
// x = 0.0;
|
||||||
|
// if (y < 0.0)
|
||||||
|
// y = 0.0;
|
||||||
|
|
||||||
|
// int stepSize = 1;
|
||||||
|
// double h00 = map[(int)x, (int)y];
|
||||||
|
// double h10 = map[(int)x + stepSize, (int)y];
|
||||||
|
// double h01 = map[(int)x, (int)y + stepSize];
|
||||||
|
// double h11 = map[(int)x + stepSize, (int)y + stepSize];
|
||||||
|
// double h1 = h00;
|
||||||
|
// double h2 = h10;
|
||||||
|
// double h3 = h01;
|
||||||
|
// double h4 = h11;
|
||||||
|
// double a00 = h1;
|
||||||
|
// double a10 = h2 - h1;
|
||||||
|
// double a01 = h3 - h1;
|
||||||
|
// double a11 = h1 - h2 - h3 + h4;
|
||||||
|
// double partialx = x - (int)x;
|
||||||
|
// double partialz = y - (int)y;
|
||||||
|
// double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
|
||||||
|
// return hi;
|
||||||
|
// }
|
||||||
|
|
||||||
|
#region ITerrainPaintableEffect Members
|
||||||
|
|
||||||
|
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||||
|
{
|
||||||
|
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
double[,] tweak = new double[map.Width,map.Height];
|
||||||
|
|
||||||
|
double area = strength;
|
||||||
|
double step = strength / 4.0;
|
||||||
|
|
||||||
|
double sum = 0.0;
|
||||||
|
double step2 = 0.0;
|
||||||
|
double avg = 0.0;
|
||||||
|
|
||||||
|
// compute delta map
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
double z = SphericalFactor(x, y, rx, ry, strength);
|
||||||
|
|
||||||
|
if (z > 0) // add in non-zero amount
|
||||||
|
{
|
||||||
|
sum += map[x, y] * z;
|
||||||
|
step2 += z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
avg = sum / step2;
|
||||||
|
|
||||||
|
// blend in map
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
double z = SphericalFactor(x, y, rx, ry, strength) * duration;
|
||||||
|
|
||||||
|
if (z > 0) // add in non-zero amount
|
||||||
|
{
|
||||||
|
if (z > 1.0)
|
||||||
|
z = 1.0;
|
||||||
|
|
||||||
|
map[x, y] = (map[x, y] * (1.0 - z)) + (avg * z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||||
|
{
|
||||||
|
public class LowerSphere : ITerrainPaintableEffect
|
||||||
|
{
|
||||||
|
#region ITerrainPaintableEffect Members
|
||||||
|
|
||||||
|
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||||
|
{
|
||||||
|
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
// Skip everything unlikely to be affected
|
||||||
|
if (Math.Abs(x - rx) > strength * 1.1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
// Skip everything unlikely to be affected
|
||||||
|
if (Math.Abs(y - ry) > strength * 1.1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Calculate a sphere and add it to the heighmap
|
||||||
|
double z = strength;
|
||||||
|
z *= z;
|
||||||
|
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
|
||||||
|
|
||||||
|
if (z > 0.0)
|
||||||
|
map[x, y] -= z * duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||||
|
{
|
||||||
|
public class NoiseSphere : ITerrainPaintableEffect
|
||||||
|
{
|
||||||
|
#region ITerrainPaintableEffect Members
|
||||||
|
|
||||||
|
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||||
|
{
|
||||||
|
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
// Skip everything unlikely to be affected
|
||||||
|
if (Math.Abs(x - rx) > strength * 1.1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
// Skip everything unlikely to be affected
|
||||||
|
if (Math.Abs(y - ry) > strength * 1.1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Calculate a sphere and add it to the heighmap
|
||||||
|
double z = strength;
|
||||||
|
z *= z;
|
||||||
|
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
|
||||||
|
|
||||||
|
double noise = TerrainUtil.PerlinNoise2D((double) x / (double) Constants.RegionSize, (double) y / (double) Constants.RegionSize, 8, 1.0);
|
||||||
|
|
||||||
|
if (z > 0.0)
|
||||||
|
map[x, y] += noise * z * duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Speed-Optimised Hybrid Erosion Brush
|
||||||
|
///
|
||||||
|
/// As per Jacob Olsen's Paper
|
||||||
|
/// http://www.oddlabs.com/download/terrain_generation.pdf
|
||||||
|
/// </summary>
|
||||||
|
public class OlsenSphere : ITerrainPaintableEffect
|
||||||
|
{
|
||||||
|
private double nConst = 1024.0;
|
||||||
|
private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
|
||||||
|
|
||||||
|
#region Supporting Functions
|
||||||
|
|
||||||
|
private int[] Neighbours(NeighbourSystem type, int index)
|
||||||
|
{
|
||||||
|
int[] coord = new int[2];
|
||||||
|
|
||||||
|
index++;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case NeighbourSystem.Moore:
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
coord[0] = -1;
|
||||||
|
coord[1] = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
coord[0] = -0;
|
||||||
|
coord[1] = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
coord[0] = +1;
|
||||||
|
coord[1] = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
coord[0] = -1;
|
||||||
|
coord[1] = -0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
coord[0] = -0;
|
||||||
|
coord[1] = -0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
coord[0] = +1;
|
||||||
|
coord[1] = -0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
coord[0] = -1;
|
||||||
|
coord[1] = +1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
coord[0] = -0;
|
||||||
|
coord[1] = +1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 9:
|
||||||
|
coord[0] = +1;
|
||||||
|
coord[1] = +1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NeighbourSystem.VonNeumann:
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
coord[0] = 0;
|
||||||
|
coord[1] = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
coord[0] = -1;
|
||||||
|
coord[1] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
coord[0] = +1;
|
||||||
|
coord[1] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
coord[0] = 0;
|
||||||
|
coord[1] = +1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
coord[0] = -0;
|
||||||
|
coord[1] = -0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return coord;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum NeighbourSystem
|
||||||
|
{
|
||||||
|
Moore,
|
||||||
|
VonNeumann
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ITerrainPaintableEffect Members
|
||||||
|
|
||||||
|
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||||
|
{
|
||||||
|
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
double z = SphericalFactor(x, y, rx, ry, strength);
|
||||||
|
|
||||||
|
if (z > 0) // add in non-zero amount
|
||||||
|
{
|
||||||
|
int NEIGHBOUR_ME = 4;
|
||||||
|
int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
|
||||||
|
|
||||||
|
double max = Double.MinValue;
|
||||||
|
int loc = 0;
|
||||||
|
double cellmax = 0;
|
||||||
|
|
||||||
|
|
||||||
|
for (int j = 0; j < NEIGHBOUR_MAX; j++)
|
||||||
|
{
|
||||||
|
if (j != NEIGHBOUR_ME)
|
||||||
|
{
|
||||||
|
int[] coords = Neighbours(type, j);
|
||||||
|
|
||||||
|
coords[0] += x;
|
||||||
|
coords[1] += y;
|
||||||
|
|
||||||
|
if (coords[0] > map.Width - 1)
|
||||||
|
continue;
|
||||||
|
if (coords[1] > map.Height - 1)
|
||||||
|
continue;
|
||||||
|
if (coords[0] < 0)
|
||||||
|
continue;
|
||||||
|
if (coords[1] < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cellmax = map[x, y] - map[coords[0], coords[1]];
|
||||||
|
if (cellmax > max)
|
||||||
|
{
|
||||||
|
max = cellmax;
|
||||||
|
loc = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double T = nConst / ((map.Width + map.Height) / 2);
|
||||||
|
// Apply results
|
||||||
|
if (0 < max && max <= T)
|
||||||
|
{
|
||||||
|
int[] maxCoords = Neighbours(type, loc);
|
||||||
|
double heightDelta = 0.5 * max * z * duration;
|
||||||
|
map[x, y] -= heightDelta;
|
||||||
|
map[x + maxCoords[0], y + maxCoords[1]] += heightDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||||
|
{
|
||||||
|
public class RaiseSphere : ITerrainPaintableEffect
|
||||||
|
{
|
||||||
|
#region ITerrainPaintableEffect Members
|
||||||
|
|
||||||
|
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||||
|
{
|
||||||
|
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
// Skip everything unlikely to be affected
|
||||||
|
if (Math.Abs(x - rx) > strength * 1.1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
// Skip everything unlikely to be affected
|
||||||
|
if (Math.Abs(y - ry) > strength * 1.1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Calculate a sphere and add it to the heighmap
|
||||||
|
double z = strength;
|
||||||
|
z *= z;
|
||||||
|
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
|
||||||
|
|
||||||
|
if (z > 0.0)
|
||||||
|
map[x, y] += z * duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||||
|
{
|
||||||
|
public class RevertSphere : ITerrainPaintableEffect
|
||||||
|
{
|
||||||
|
private ITerrainChannel m_revertmap;
|
||||||
|
|
||||||
|
public RevertSphere(ITerrainChannel revertmap)
|
||||||
|
{
|
||||||
|
m_revertmap = revertmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ITerrainPaintableEffect Members
|
||||||
|
|
||||||
|
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||||
|
{
|
||||||
|
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||||
|
|
||||||
|
if (duration > 1.0)
|
||||||
|
duration = 1.0;
|
||||||
|
if (duration < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
// Skip everything unlikely to be affected
|
||||||
|
if (Math.Abs(x - rx) > strength * 1.1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
// Skip everything unlikely to be affected
|
||||||
|
if (Math.Abs(y - ry) > strength * 1.1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Calculate a sphere and add it to the heighmap
|
||||||
|
double z = strength;
|
||||||
|
z *= z;
|
||||||
|
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
|
||||||
|
|
||||||
|
if (z > 0.0)
|
||||||
|
{
|
||||||
|
z *= duration;
|
||||||
|
map[x, y] += (map[x, y] * (1.0 - z)) + (m_revertmap[x, y] * z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||||
|
{
|
||||||
|
public class SmoothSphere : ITerrainPaintableEffect
|
||||||
|
{
|
||||||
|
#region ITerrainPaintableEffect Members
|
||||||
|
|
||||||
|
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||||
|
{
|
||||||
|
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
double[,] tweak = new double[map.Width,map.Height];
|
||||||
|
|
||||||
|
double n, l;
|
||||||
|
double area = strength;
|
||||||
|
double step = strength / 4.0;
|
||||||
|
|
||||||
|
// compute delta map
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
|
||||||
|
|
||||||
|
if (z > 0) // add in non-zero amount
|
||||||
|
{
|
||||||
|
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 += TerrainUtil.GetBilinearInterpolate(x + n, y + l, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tweak[x, y] = average / avgsteps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// blend in map
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
|
||||||
|
|
||||||
|
if (z > 0) // add in non-zero amount
|
||||||
|
{
|
||||||
|
double da = z;
|
||||||
|
double a = (map[x, y] - tweak[x, y]) * da;
|
||||||
|
double newz = map[x, y] - (a * duration);
|
||||||
|
|
||||||
|
if (newz > 0.0)
|
||||||
|
map[x, y] = newz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,207 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Thermal Weathering Paint Brush
|
||||||
|
/// </summary>
|
||||||
|
public class WeatherSphere : ITerrainPaintableEffect
|
||||||
|
{
|
||||||
|
private double talus = 0.2; // Number of meters max difference before stop eroding. Tweakage required.
|
||||||
|
private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
|
||||||
|
|
||||||
|
#region Supporting Functions
|
||||||
|
|
||||||
|
private int[] Neighbours(NeighbourSystem type, int index)
|
||||||
|
{
|
||||||
|
int[] coord = new int[2];
|
||||||
|
|
||||||
|
index++;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case NeighbourSystem.Moore:
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
coord[0] = -1;
|
||||||
|
coord[1] = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
coord[0] = -0;
|
||||||
|
coord[1] = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
coord[0] = +1;
|
||||||
|
coord[1] = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
coord[0] = -1;
|
||||||
|
coord[1] = -0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
coord[0] = -0;
|
||||||
|
coord[1] = -0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
coord[0] = +1;
|
||||||
|
coord[1] = -0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
coord[0] = -1;
|
||||||
|
coord[1] = +1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
coord[0] = -0;
|
||||||
|
coord[1] = +1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 9:
|
||||||
|
coord[0] = +1;
|
||||||
|
coord[1] = +1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NeighbourSystem.VonNeumann:
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
coord[0] = 0;
|
||||||
|
coord[1] = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
coord[0] = -1;
|
||||||
|
coord[1] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
coord[0] = +1;
|
||||||
|
coord[1] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
coord[0] = 0;
|
||||||
|
coord[1] = +1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
coord[0] = -0;
|
||||||
|
coord[1] = -0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return coord;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum NeighbourSystem
|
||||||
|
{
|
||||||
|
Moore,
|
||||||
|
VonNeumann
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ITerrainPaintableEffect Members
|
||||||
|
|
||||||
|
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||||
|
{
|
||||||
|
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
for (x = 0; x < map.Width; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < map.Height; y++)
|
||||||
|
{
|
||||||
|
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
|
||||||
|
|
||||||
|
if (z > 0) // add in non-zero amount
|
||||||
|
{
|
||||||
|
int NEIGHBOUR_ME = 4;
|
||||||
|
|
||||||
|
int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
|
||||||
|
|
||||||
|
for (int j = 0; j < NEIGHBOUR_MAX; j++)
|
||||||
|
{
|
||||||
|
if (j != NEIGHBOUR_ME)
|
||||||
|
{
|
||||||
|
int[] coords = Neighbours(type, j);
|
||||||
|
|
||||||
|
coords[0] += x;
|
||||||
|
coords[1] += y;
|
||||||
|
|
||||||
|
if (coords[0] > map.Width - 1)
|
||||||
|
continue;
|
||||||
|
if (coords[1] > map.Height - 1)
|
||||||
|
continue;
|
||||||
|
if (coords[0] < 0)
|
||||||
|
continue;
|
||||||
|
if (coords[1] < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
double heightF = map[x, y];
|
||||||
|
double target = map[coords[0], coords[1]];
|
||||||
|
|
||||||
|
if (target > heightF + talus)
|
||||||
|
{
|
||||||
|
double calc = duration * ((target - heightF) - talus) * z;
|
||||||
|
heightF += calc;
|
||||||
|
target -= calc;
|
||||||
|
}
|
||||||
|
|
||||||
|
map[x, y] = heightF;
|
||||||
|
map[coords[0], coords[1]] = target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A new version of the old Channel class, simplified
|
||||||
|
/// </summary>
|
||||||
|
public class TerrainChannel : ITerrainChannel
|
||||||
|
{
|
||||||
|
private readonly bool[,] taint;
|
||||||
|
private double[,] map;
|
||||||
|
|
||||||
|
public TerrainChannel()
|
||||||
|
{
|
||||||
|
map = new double[Constants.RegionSize,Constants.RegionSize];
|
||||||
|
taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
|
||||||
|
|
||||||
|
int x;
|
||||||
|
for (x = 0; x < Constants.RegionSize; x++)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
for (y = 0; y < Constants.RegionSize; y++)
|
||||||
|
{
|
||||||
|
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10;
|
||||||
|
double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01;
|
||||||
|
if (map[x, y] < spherFac)
|
||||||
|
{
|
||||||
|
map[x, y] = spherFac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerrainChannel(double[,] import)
|
||||||
|
{
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||||
|
{
|
||||||
|
public class TerrainException : Exception
|
||||||
|
{
|
||||||
|
public TerrainException() : base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerrainException(string msg) : base(msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerrainException(string msg, Exception e) : base(msg, e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,737 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using libsecondlife;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Modules.Framework;
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Terrain;
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes;
|
||||||
|
using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
Flatten = 0,
|
||||||
|
Raise = 1,
|
||||||
|
Lower = 2,
|
||||||
|
Smooth = 3,
|
||||||
|
Noise = 4,
|
||||||
|
Revert = 5,
|
||||||
|
|
||||||
|
// Extended brushes
|
||||||
|
Erode = 255,
|
||||||
|
Weather = 254,
|
||||||
|
Olsen = 253
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private readonly Commander m_commander = new Commander("Terrain");
|
||||||
|
|
||||||
|
private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects =
|
||||||
|
new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>();
|
||||||
|
|
||||||
|
private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>();
|
||||||
|
|
||||||
|
private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects =
|
||||||
|
new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>();
|
||||||
|
|
||||||
|
private Dictionary<Location, ITerrainChannel> m_channels;
|
||||||
|
|
||||||
|
private ITerrainChannel m_channel;
|
||||||
|
private Dictionary<string, ITerrainEffect> m_plugineffects;
|
||||||
|
private ITerrainChannel m_revert;
|
||||||
|
private Scene m_scene;
|
||||||
|
private bool m_tainted = false;
|
||||||
|
|
||||||
|
#region ICommandableModule Members
|
||||||
|
|
||||||
|
public ICommander CommandInterface
|
||||||
|
{
|
||||||
|
get { return m_commander; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IRegionModule Members
|
||||||
|
|
||||||
|
/// <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)
|
||||||
|
{
|
||||||
|
m_scene = scene;
|
||||||
|
|
||||||
|
// Install terrain module in the simulator
|
||||||
|
if (m_scene.Heightmap == null)
|
||||||
|
{
|
||||||
|
lock (m_scene)
|
||||||
|
{
|
||||||
|
m_channel = new TerrainChannel();
|
||||||
|
m_scene.Heightmap = m_channel;
|
||||||
|
m_revert = new TerrainChannel();
|
||||||
|
UpdateRevertMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_channel = m_scene.Heightmap;
|
||||||
|
m_revert = new TerrainChannel();
|
||||||
|
UpdateRevertMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_scene.RegisterModuleInterface<ITerrainModule>(this);
|
||||||
|
m_scene.EventManager.OnNewClient += EventManager_OnNewClient;
|
||||||
|
m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
|
||||||
|
m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables terrain module when called
|
||||||
|
/// </summary>
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
InstallDefaultEffects();
|
||||||
|
InstallInterfaces();
|
||||||
|
LoadPlugins();
|
||||||
|
}
|
||||||
|
|
||||||
|
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)");
|
||||||
|
throw new TerrainException(String.Format("unable to load heightmap: parser {0} does not support loading", loader.Value));
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
m_log.Error(
|
||||||
|
"[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)");
|
||||||
|
throw new TerrainException(
|
||||||
|
String.Format("unable to load heightmap: file {0} not found (or permissions do not allow access", filename));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CheckForTerrainUpdates();
|
||||||
|
m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format.");
|
||||||
|
throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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.");
|
||||||
|
throw new TerrainException(String.Format("Unable to save heightmap: saving of this file format not implemented"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#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()));
|
||||||
|
if (!m_plugineffects.ContainsKey(pluginType.Name))
|
||||||
|
{
|
||||||
|
m_plugineffects.Add(pluginType.Name, terEffect);
|
||||||
|
m_log.Info("E ... " + pluginType.Name);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
m_log.Warn("E ... " + pluginType.Name + " (Already added)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pluginType.GetInterface("ITerrainLoader", false) != null)
|
||||||
|
{
|
||||||
|
ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString()));
|
||||||
|
m_loaders[terLoader.FileExtension] = terLoader;
|
||||||
|
m_log.Info("L ... " + pluginType.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (AmbiguousMatchException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (BadImageFormatException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
m_tainted = false;
|
||||||
|
m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised());
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Console Commands
|
||||||
|
|
||||||
|
private void InterfaceLoadFile(Object[] args)
|
||||||
|
{
|
||||||
|
LoadFromFile((string) args[0]);
|
||||||
|
CheckForTerrainUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceLoadTileFile(Object[] args)
|
||||||
|
{
|
||||||
|
LoadFromFile((string) args[0],
|
||||||
|
(int) args[1],
|
||||||
|
(int) args[2],
|
||||||
|
(int) args[3],
|
||||||
|
(int) args[4]);
|
||||||
|
CheckForTerrainUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceSaveFile(Object[] args)
|
||||||
|
{
|
||||||
|
SaveToFile((string) args[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceBakeTerrain(Object[] args)
|
||||||
|
{
|
||||||
|
UpdateRevertMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceRevertTerrain(Object[] args)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < m_channel.Width; x++)
|
||||||
|
for (y = 0; y < m_channel.Height; y++)
|
||||||
|
m_channel[x, y] = m_revert[x, y];
|
||||||
|
|
||||||
|
CheckForTerrainUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceElevateTerrain(Object[] args)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < m_channel.Width; x++)
|
||||||
|
for (y = 0; y < m_channel.Height; y++)
|
||||||
|
m_channel[x, y] += (double) args[0];
|
||||||
|
CheckForTerrainUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceMultiplyTerrain(Object[] args)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < m_channel.Width; x++)
|
||||||
|
for (y = 0; y < m_channel.Height; y++)
|
||||||
|
m_channel[x, y] *= (double) args[0];
|
||||||
|
CheckForTerrainUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceLowerTerrain(Object[] args)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
for (x = 0; x < m_channel.Width; x++)
|
||||||
|
for (y = 0; y < m_channel.Height; y++)
|
||||||
|
m_channel[x, y] -= (double) args[0];
|
||||||
|
CheckForTerrainUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceFillTerrain(Object[] args)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
for (x = 0; x < m_channel.Width; x++)
|
||||||
|
for (y = 0; y < m_channel.Height; y++)
|
||||||
|
m_channel[x, y] = (double) args[0];
|
||||||
|
CheckForTerrainUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceShowDebugStats(Object[] args)
|
||||||
|
{
|
||||||
|
double max = Double.MinValue;
|
||||||
|
double min = double.MaxValue;
|
||||||
|
double avg;
|
||||||
|
double sum = 0;
|
||||||
|
|
||||||
|
int x;
|
||||||
|
for (x = 0; x < m_channel.Width; x++)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
for (y = 0; y < m_channel.Height; y++)
|
||||||
|
{
|
||||||
|
sum += m_channel[x, y];
|
||||||
|
if (max < m_channel[x, y])
|
||||||
|
max = m_channel[x, y];
|
||||||
|
if (min > m_channel[x, y])
|
||||||
|
min = m_channel[x, y];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
avg = sum / (m_channel.Height * m_channel.Width);
|
||||||
|
|
||||||
|
m_log.Info("Channel " + m_channel.Width + "x" + m_channel.Height);
|
||||||
|
m_log.Info("max/min/avg/sum: " + max + "/" + min + "/" + avg + "/" + sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceEnableExperimentalBrushes(Object[] args)
|
||||||
|
{
|
||||||
|
if ((bool) args[0])
|
||||||
|
{
|
||||||
|
m_painteffects[StandardTerrainEffects.Revert] = new WeatherSphere();
|
||||||
|
m_painteffects[StandardTerrainEffects.Flatten] = new OlsenSphere();
|
||||||
|
m_painteffects[StandardTerrainEffects.Smooth] = new ErodeSphere();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InstallDefaultEffects();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterfaceRunPluginEffect(Object[] args)
|
||||||
|
{
|
||||||
|
if ((string) args[0] == "list")
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
// Load / Save
|
||||||
|
string supportedFileExtensions = "";
|
||||||
|
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
|
||||||
|
supportedFileExtensions += " " + loader.Key + " (" + loader.Value + ")";
|
||||||
|
|
||||||
|
Command loadFromFileCommand =
|
||||||
|
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.");
|
||||||
|
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.");
|
||||||
|
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 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 Y tile", "The Y region coordinate of the first section on the file",
|
||||||
|
"Integer");
|
||||||
|
|
||||||
|
// Terrain adjustments
|
||||||
|
Command fillRegionCommand =
|
||||||
|
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.");
|
||||||
|
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.");
|
||||||
|
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.");
|
||||||
|
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 revertRegionCommand =
|
||||||
|
new Command("revert", InterfaceRevertTerrain, "Loads the revert map terrain into the regions heightmap.");
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
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.");
|
||||||
|
experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean");
|
||||||
|
|
||||||
|
//Plugins
|
||||||
|
Command pluginRunCommand =
|
||||||
|
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-tile", loadFromTileCommand);
|
||||||
|
m_commander.RegisterCommand("save", saveToFileCommand);
|
||||||
|
m_commander.RegisterCommand("fill", fillRegionCommand);
|
||||||
|
m_commander.RegisterCommand("elevate", elevateCommand);
|
||||||
|
m_commander.RegisterCommand("lower", lowerCommand);
|
||||||
|
m_commander.RegisterCommand("multiply", multiplyCommand);
|
||||||
|
m_commander.RegisterCommand("bake", bakeRegionCommand);
|
||||||
|
m_commander.RegisterCommand("revert", revertRegionCommand);
|
||||||
|
m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand);
|
||||||
|
m_commander.RegisterCommand("stats", showDebugStatsCommand);
|
||||||
|
m_commander.RegisterCommand("effect", pluginRunCommand);
|
||||||
|
|
||||||
|
// Add this to our scene so scripts can call these functions
|
||||||
|
m_scene.RegisterModuleCommander("Terrain", m_commander);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||||
|
{
|
||||||
|
public static class TerrainUtil
|
||||||
|
{
|
||||||
|
public static double MetersToSphericalStrength(double size)
|
||||||
|
{
|
||||||
|
return Math.Pow(2, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double SphericalFactor(double x, double y, double rx, double ry, double size)
|
||||||
|
{
|
||||||
|
return size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
|
||||||
|
{
|
||||||
|
int w = map.Width;
|
||||||
|
int h = map.Height;
|
||||||
|
|
||||||
|
if (x > w - 2.0)
|
||||||
|
x = w - 2.0;
|
||||||
|
if (y > h - 2.0)
|
||||||
|
y = h - 2.0;
|
||||||
|
if (x < 0.0)
|
||||||
|
x = 0.0;
|
||||||
|
if (y < 0.0)
|
||||||
|
y = 0.0;
|
||||||
|
|
||||||
|
int stepSize = 1;
|
||||||
|
double h00 = map[(int) x, (int) y];
|
||||||
|
double h10 = map[(int) x + stepSize, (int) y];
|
||||||
|
double h01 = map[(int) x, (int) y + stepSize];
|
||||||
|
double h11 = map[(int) x + stepSize, (int) y + stepSize];
|
||||||
|
double h1 = h00;
|
||||||
|
double h2 = h10;
|
||||||
|
double h3 = h01;
|
||||||
|
double h4 = h11;
|
||||||
|
double a00 = h1;
|
||||||
|
double a10 = h2 - h1;
|
||||||
|
double a01 = h3 - h1;
|
||||||
|
double a11 = h1 - h2 - h3 + h4;
|
||||||
|
double partialx = x - (int) x;
|
||||||
|
double partialz = y - (int) y;
|
||||||
|
double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
|
||||||
|
return hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double Noise(double x, double y)
|
||||||
|
{
|
||||||
|
int n = (int) x + (int) (y * 749);
|
||||||
|
n = (n << 13) ^ n;
|
||||||
|
return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double SmoothedNoise1(double x, double y)
|
||||||
|
{
|
||||||
|
double corners = (Noise(x - 1, y - 1) + Noise(x + 1, y - 1) + Noise(x - 1, y + 1) + Noise(x + 1, y + 1)) / 16;
|
||||||
|
double sides = (Noise(x - 1, y) + Noise(x + 1, y) + Noise(x, y - 1) + Noise(x, y + 1)) / 8;
|
||||||
|
double center = Noise(x, y) / 4;
|
||||||
|
return corners + sides + center;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double Interpolate(double x, double y, double z)
|
||||||
|
{
|
||||||
|
return (x * (1.0 - z)) + (y * z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double InterpolatedNoise(double x, double y)
|
||||||
|
{
|
||||||
|
int integer_X = (int) (x);
|
||||||
|
double fractional_X = x - integer_X;
|
||||||
|
|
||||||
|
int integer_Y = (int) y;
|
||||||
|
double fractional_Y = y - integer_Y;
|
||||||
|
|
||||||
|
double v1 = SmoothedNoise1(integer_X, integer_Y);
|
||||||
|
double v2 = SmoothedNoise1(integer_X + 1, integer_Y);
|
||||||
|
double v3 = SmoothedNoise1(integer_X, integer_Y + 1);
|
||||||
|
double v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1);
|
||||||
|
|
||||||
|
double i1 = Interpolate(v1, v2, fractional_X);
|
||||||
|
double i2 = Interpolate(v3, v4, fractional_X);
|
||||||
|
|
||||||
|
return Interpolate(i1, i2, fractional_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double PerlinNoise2D(double x, double y, int octaves, double persistence)
|
||||||
|
{
|
||||||
|
double frequency = 0.0;
|
||||||
|
double amplitude = 0.0;
|
||||||
|
double total = 0.0;
|
||||||
|
|
||||||
|
for (int i = 0; i < octaves; i++)
|
||||||
|
{
|
||||||
|
frequency = Math.Pow(2, i);
|
||||||
|
amplitude = Math.Pow(persistence, i);
|
||||||
|
|
||||||
|
total += InterpolatedNoise(x * frequency, y * frequency) * amplitude;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue