我想重现亚特兰蒂斯'在OpenSim上学失踪。到目前为止,我只是设法让水升起。我现在希望每次亚特兰蒂斯被置于水下时地形都会下降。这就是我到目前为止:我的代码出了什么问题?
// Place your methods here
private void InterfaceLoadFile(Object[] args)
{
LoadFromFile((string)args[0]);
}
private void InterfaceLoadTileFile(Object[] args)
{
LoadFromFile((string)args[0],
(int)args[1],
(int)args[2],
(int)args[3],
(int)args[4]);
}
private void InterfaceSaveFile(Object[] args)
{
SaveToFile((string)args[0]);
}
private void InterfaceSaveTileFile(Object[] args)
{
SaveToFile((string)args[0],
(int)args[1],
(int)args[2],
(int)args[3],
(int)args[4]);
}
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];
}
private void InterfaceFlipTerrain(Object[] args)
{
String direction = (String)args[0];
if (direction.ToLower().StartsWith("y"))
{
for(int x = 0; x < m_channel.Width; x++)
{
for(int y = 0; y < m_channel.Height / 2; y++)
{
double height = m_channel[x, y];
double flippedHeight = m_channel[x, (int)m_channel.Height - 1 - y];
m_channel[x, y] = flippedHeight;
m_channel[x, (int)m_channel.Height - 1 - y] = height;
}
}
}
else if (direction.ToLower().StartsWith("x"))
{
for(int y = 0; y < m_channel.Height; y++)
{
for(int x = 0; x < m_channel.Width / 2; x++)
{
double height = m_channel[x, y];
double flippedHeight = m_channel[(int)m_channel.Width - 1 - x, y];
m_channel[x, y] = flippedHeight;
m_channel[(int)m_channel.Width - 1 - x, y] = height;
}
}
}
else
{
MainConsole.Instance.OutputFormat("ERROR: Unrecognised direction {0} - need x or y", direction);
}
}
private void InterfaceRescaleTerrain(Object[] args)
{
double desiredMin = (double)args[0];
double desiredMax = (double)args[1];
// determine desired scaling factor
double desiredRange = desiredMax - desiredMin;
//m_log.InfoFormat("Desired {0}, {1} = {2}", new Object[] { desiredMin, desiredMax, desiredRange });
if (desiredRange == 0d)
{
// delta is zero so flatten at requested height
InterfaceFillTerrain(new Object[] { args[1] });
}
else
{
//work out current heightmap range
double currMin = double.MaxValue;
double currMax = double.MinValue;
int width = m_channel.Width;
int height = m_channel.Height;
for(int x = 0; x < width; x++)
{
for(int y = 0; y < height; y++)
{
double currHeight = m_channel[x, y];
if (currHeight < currMin)
{
currMin = currHeight;
}
else if (currHeight > currMax)
{
currMax = currHeight;
}
}
}
double currRange = currMax - currMin;
double scale = desiredRange / currRange;
//m_log.InfoFormat("Current {0}, {1} = {2}", new Object[] { currMin, currMax, currRange });
//m_log.InfoFormat("Scale = {0}", scale);
// scale the heightmap accordingly
for(int x = 0; x < width; x++)
{
for(int y = 0; y < height; y++)
{
double currHeight = m_channel[x, y] - currMin;
m_channel[x, y] = desiredMin + (currHeight * scale);
}
}
}
}
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];
}
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];
}
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];
}
public 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];
}
private void InterfaceMinTerrain(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] = Math.Max((double)args[0], m_channel[x, y]);
}
}
}
private void InterfaceMaxTerrain(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] = Math.Min((double)args[0], m_channel[x, y]);
}
}
}
private void InterfaceShow(Object[] args)
{
Vector2 point;
if (!ConsoleUtil.TryParseConsole2DVector((string)args[0], null, out point))
{
Console.WriteLine("ERROR: {0} is not a valid vector", args[0]);
return;
}
double height = m_channel[(int)point.X, (int)point.Y];
Console.WriteLine("Terrain height at {0} is {1}", point, height);
}
private void InterfaceShowDebugStats(Object[] args)
{
double max = Double.MinValue;
double min = double.MaxValue;
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];
}
}
double avg = sum / (m_channel.Height * m_channel.Width);
MainConsole.Instance.OutputFormat("Channel {0}x{1}", m_channel.Width, m_channel.Height);
MainConsole.Instance.OutputFormat("max/min/avg/sum: {0}/{1}/{2}/{3}", 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)
{
string firstArg = (string)args[0];
if (firstArg == "list")
{
MainConsole.Instance.Output("List of loaded plugins");
foreach(KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects)
{
MainConsole.Instance.Output(kvp.Key);
}
return;
}
if (firstArg == "reload")
{
LoadPlugins();
return;
}
if (m_plugineffects.ContainsKey(firstArg))
{
m_plugineffects[firstArg].RunEffect(m_channel);
}
else
{
MainConsole.Instance.Output("WARNING: No such plugin effect {0} loaded.", firstArg);
}
}
private void InstallInterfaces()
{
Command loadFromFileCommand =
new Command("load", CommandIntentions.COMMAND_HAZARDOUS, 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: " +
m_supportedFileExtensions, "String");
Command saveToFileCommand =
new Command("save", CommandIntentions.COMMAND_NON_HAZARDOUS, 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: " +
m_supportedFileExtensions, "String");
Command loadFromTileCommand =
new Command("load-tile", CommandIntentions.COMMAND_HAZARDOUS, 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: " +
m_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");
Command saveToTileCommand =
new Command("save-tile", CommandIntentions.COMMAND_HAZARDOUS, InterfaceSaveTileFile, "Saves the current heightmap to the larger file.");
saveToTileCommand.AddArgument("filename",
"The file you wish to save to, the file extension determines the loader to be used. Supported extensions include: " +
m_supportFileExtensionsForTileSave, "String");
saveToTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer");
saveToTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer");
saveToTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file",
"Integer");
saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first tile on the file\n"
+ "= Example =\n"
+ "To save a PNG file for a set of map tiles 2 regions wide and 3 regions high from map co-ordinate (9910,10234)\n"
+ " # terrain save-tile ST06.png 2 3 9910 10234\n",
"Integer");
// Terrain adjustments
Command fillRegionCommand =
new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, 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", CommandIntentions.COMMAND_HAZARDOUS, 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", CommandIntentions.COMMAND_HAZARDOUS, 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", CommandIntentions.COMMAND_HAZARDOUS, InterfaceMultiplyTerrain, "Multiplies the heightmap by the value specified.");
multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double");
Command bakeRegionCommand =
new Command("bake", CommandIntentions.COMMAND_HAZARDOUS, InterfaceBakeTerrain, "Saves the current terrain into the regions revert map.");
Command revertRegionCommand =
new Command("revert", CommandIntentions.COMMAND_HAZARDOUS, InterfaceRevertTerrain, "Loads the revert map terrain into the regions heightmap.");
Command flipCommand =
new Command("flip", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFlipTerrain, "Flips the current terrain about the X or Y axis");
flipCommand.AddArgument("direction", "[x|y] the direction to flip the terrain in", "String");
Command rescaleCommand =
new Command("rescale", CommandIntentions.COMMAND_HAZARDOUS, InterfaceRescaleTerrain, "Rescales the current terrain to fit between the given min and max heights");
rescaleCommand.AddArgument("min", "min terrain height after rescaling", "Double");
rescaleCommand.AddArgument("max", "max terrain height after rescaling", "Double");
Command minCommand = new Command("min", CommandIntentions.COMMAND_HAZARDOUS, InterfaceMinTerrain, "Sets the minimum terrain height to the specified value.");
minCommand.AddArgument("min", "terrain height to use as minimum", "Double");
Command maxCommand = new Command("max", CommandIntentions.COMMAND_HAZARDOUS, InterfaceMaxTerrain, "Sets the maximum terrain height to the specified value.");
maxCommand.AddArgument("min", "terrain height to use as maximum", "Double");
// Debug
Command showDebugStatsCommand =
new Command("stats", CommandIntentions.COMMAND_STATISTICAL, InterfaceShowDebugStats,
"Shows some information about the regions heightmap for debugging purposes.");
Command showCommand =
new Command("show", CommandIntentions.COMMAND_NON_HAZARDOUS, InterfaceShow,
"Shows terrain height at a given co-ordinate.");
showCommand.AddArgument("point", "point in <x>,<y> format with no spaces (e.g. 45,45)", "String");
Command experimentalBrushesCommand =
new Command("newbrushes", CommandIntentions.COMMAND_HAZARDOUS, 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", CommandIntentions.COMMAND_HAZARDOUS, 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("multiply", multiplyCommand);
m
// Add this to our scene so scripts can call these functions
m_scene.RegisterModuleCommander(m_commander);
// Add Modify command to Scene, since Command object requires fixed-length arglists
m_scene.AddCommand("Terrain", this, "terrain modify",
"terrain modify <operation> <value> [<area>] [<taper>]",
"Modifies the terrain as instructed." +
"\nEach operation can be limited to an area of effect:" +
"\n * -ell=x,y,rx[,ry] constrains the operation to an ellipse centred at x,y" +
"\n * -rec=x,y,dx[,dy] constrains the operation to a rectangle based at x,y" +
"\nEach operation can have its effect tapered based on distance from centre:" +
"\n * elliptical operations taper as cones" +
"\n * rectangular operations taper as pyramids"
,
ModifyCommand);
}
public 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];
}
private void InstallInterfaces()
{
Command multiplyCommand =
new Command("multiply", CommandIntentions.COMMAND_HAZARDOUS, InterfaceMultiplyTerrain, "Multiplies the heightmap by the value specified.");
multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double");
// Debug
Command showDebugStatsCommand =
new Command("stats", CommandIntentions.COMMAND_STATISTICAL, InterfaceShowDebugStats,
"Shows some information about the regions heightmap for debugging purposes.");
// Plugins
Command pluginRunCommand =
new Command("effect", CommandIntentions.COMMAND_HAZARDOUS, 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("multiply", multiplyCommand);
// Add this to our scene so scripts can call these functions
m_scene.RegisterModuleCommander(m_commander);
// Add Modify command to Scene, since Command object requires fixed-length arglists
m_scene.AddCommand("Terrain", this, "terrain modify",
"terrain modify <operation> <value> [<area>] [<taper>]",
"Modifies the terrain as instructed." +
"\nEach operation can be limited to an area of effect:" +
"\n * -ell=x,y,rx[,ry] constrains the operation to an ellipse centred at x,y" +
"\n * -rec=x,y,dx[,dy] constrains the operation to a rectangle based at x,y" +
"\nEach operation can have its effect tapered based on distance from centre:" +
"\n * elliptical operations taper as cones" +
"\n * rectangular operations taper as pyramids"
,
ModifyCommand);
}
public void UpdateTerrainWithTide()
{
InterfaceMultiplyTerrain(0.95);
multiplyCommand = 0.95;
multiplyCommand(0.95);
}
public void ModifyCommand(string module, string[] cmd)
{
string result;
Scene scene = SceneManager.Instance.CurrentScene;
if ((scene != null) && (scene != m_scene))
{
result = String.Empty;
}
else if (cmd.Length > 2)
{
string operationType = cmd[2];
ITerrainModifier operation;
if (!m_modifyOperations.TryGetValue(operationType, out operation))
{
result = String.Format("Terrain Modify \"{0}\" not found.", operationType);
}
else if ((cmd.Length > 3) && (cmd[3] == "usage"))
{
result = "Usage: " + operation.GetUsage();
}
else
{
result = operation.ModifyTerrain(m_channel, cmd);
}
if (result == String.Empty)
{
result = "Modified terrain";
m_log.DebugFormat("Performed terrain operation {0}", operationType);
}
}
else
{
result = "Usage: <operation-name> <arg1> <arg2>...";
}
if (result != String.Empty)
{
MainConsole.Instance.Output(result);
}
}
public void TideUpdate ()
{
ulong timeStamp;
double cyclePos; //cycles from 0.0000000001 to 0.999999999999
double cycleRadians;
double tideRange;
double tideMiddle;
string tideLevelMsg;
if (((m_frame++ % m_frameUpdateRate) != 0) || !m_ready) {
return;
}
timeStamp = (ulong) (DateTime.Now.Ticks);
cyclePos = (double)(timeStamp % (m_cycleTime * TICKS_PER_SECOND)) / (m_cycleTime * TICKS_PER_SECOND);
cycleRadians = cyclePos * Math.PI * 2;
if (cyclePos < 0.5) m_tideDirection = false; else m_tideDirection = true;
if (m_tideDirection != m_lastTideDirection)
{ //if the tide changes re-calculate the tide times
if (cyclePos < 0.5)
{ // tide just changed to be high->low
m_lowTideTime = DateTime.Now.AddSeconds((double)(m_cycleTime * (0.5 - cyclePos)));
m_highTideTime = m_lowTideTime.AddSeconds((double)(m_cycleTime / 2));
m_tideAnnounceMsg = "High Tide";
}
else
{ //tide just changed to be low->high
m_highTideTime = DateTime.Now.AddSeconds((double)(m_cycleTime * (1.0 - cyclePos)));
m_lowTideTime = m_highTideTime.AddSeconds((double)(m_cycleTime / 2));
m_tideAnnounceMsg = "Low Tide";
}
m_lastTideDirection = m_tideDirection;
}
tideRange = (double) (m_highTide - m_lowTide) / 2;
tideMiddle = (double) m_lowTide + tideRange;
m_tideLevel = (float) (Math.Cos(cycleRadians) * tideRange + tideMiddle);
tideLevelMsg = "Current Server Time: " + DateTime.Now.ToString("T") + "\n";
tideLevelMsg += "Current Tide Level: " + m_tideLevel.ToString() + "\n";
tideLevelMsg += "Low Tide Time: " + m_lowTideTime.ToString("T") + "\n";
tideLevelMsg += "Low Tide Level: " + m_lowTide.ToString() + "\n";
tideLevelMsg += "High Tide Time: " + m_highTideTime.ToString("T") + "\n";
tideLevelMsg += "High Tide Level: " + m_highTide.ToString() + "\n";
tideLevelMsg += "Tide Direction: " + ((m_tideDirection) ? "Coming In" : "Going Out") + "\n";
tideLevelMsg += "Cycle Position: " + cyclePos.ToString() + "\n";
if (m_tideAnnounceMsg != "")
{
if (m_tideAnnounceCounter++ > m_tideAnnounceCount)
{
m_tideAnnounceCounter = 0;
m_tideAnnounceMsg = "";
}
else
{
tideLevelMsg += "Tide Warning: " + m_tideAnnounceMsg + "\n";
}
}
if (m_tideInfoDebug) m_log.InfoFormat("[{0}]: Sea Level currently at {1}m in Region: {2}", m_name, m_tideLevel, m_scene.RegionInfo.RegionName);
if (m_tideInfoBroadcast && m_tideDirection)
{
m_scene.SimChatBroadcast(Utils.StringToBytes(tideLevelMsg), ChatTypeEnum.Region, m_tideInfoChannel, m_shoutPos, "TIDE", UUID.Zero, false);
m_scene.SimChatBroadcast(Utils.StringToBytes(m_tideLevel.ToString()), ChatTypeEnum.Region, m_tideLevelChannel, m_shoutPos, "TIDE", UUID.Zero, false);
}
if (m_tideInfoDebug) m_log.InfoFormat("[{0}]: Updating Region: {1}", m_name, m_scene.RegionInfo.RegionName);
m_scene.RegionInfo.RegionSettings.WaterHeight = m_tideLevel;
m_scene.EventManager.TriggerRequestChangeWaterHeight(m_tideLevel);
m_scene.EventManager.TriggerTerrainTick();
if (m_tideInfoBroadcast && !m_tideDirection)
{
m_scene.SimChatBroadcast(Utils.StringToBytes(tideLevelMsg), ChatTypeEnum.Region, m_tideInfoChannel, m_shoutPos, "TIDE", UUID.Zero, false);
m_scene.SimChatBroadcast(Utils.StringToBytes(m_tideLevel.ToString()), ChatTypeEnum.Region, m_tideLevelChannel, m_shoutPos, "TIDE", UUID.Zero, false);
}
}
答案 0 :(得分:0)
建议 - 开始搜索ossl实现的代码,然后对它们进行反向工程以确定地形如何工作。基本上它是修改位图(我认为)然后当刷新时差异被流式传输到客户端。
https://github.com/opensim/opensim/search?utf8=%E2%9C%93&q=osSetTerrainHeight
脚本版本:
default
{
touch_start()
{
osSetTerrainHeight(40, 101, 21.4);
osTerrainFlush();
}
}