Start of the OpenSim library , for now only contains a few textures.

afrisby
MW 2007-07-25 18:19:38 +00:00
parent 3641ef0fdd
commit 2b42ea0a42
35 changed files with 4839 additions and 4635 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,81 +1,81 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.IO; using System.IO;
using libsecondlife; using libsecondlife;
using OpenSim.Framework.Interfaces; using OpenSim.Framework.Interfaces;
using OpenSim.Framework.Types; using OpenSim.Framework.Types;
using OpenSim.Framework.Utilities; using OpenSim.Framework.Utilities;
using OpenSim.Framework.Data; using OpenSim.Framework.Data;
namespace OpenSim.Framework.Communications.Caches namespace OpenSim.Framework.Communications.Caches
{ {
public class AssetTransactionManager public class AssetTransactionManager
{ {
// Fields // Fields
public Dictionary<LLUUID, AgentAssetTransactions> AgentTransactions = new Dictionary<LLUUID, AgentAssetTransactions>(); public Dictionary<LLUUID, AgentAssetTransactions> AgentTransactions = new Dictionary<LLUUID, AgentAssetTransactions>();
// Methods // Methods
public AgentAssetTransactions AddUser(LLUUID userID) public AgentAssetTransactions AddUser(LLUUID userID)
{ {
if (!this.AgentTransactions.ContainsKey(userID)) if (!this.AgentTransactions.ContainsKey(userID))
{ {
AgentAssetTransactions transactions = new AgentAssetTransactions(userID); AgentAssetTransactions transactions = new AgentAssetTransactions(userID);
this.AgentTransactions.Add(userID, transactions); this.AgentTransactions.Add(userID, transactions);
return transactions; return transactions;
} }
return null; return null;
} }
public AgentAssetTransactions GetUserTransActions(LLUUID userID) public AgentAssetTransactions GetUserTransActions(LLUUID userID)
{ {
if (this.AgentTransactions.ContainsKey(userID)) if (this.AgentTransactions.ContainsKey(userID))
{ {
return this.AgentTransactions[userID]; return this.AgentTransactions[userID];
} }
return null; return null;
} }
public void HandleInventoryFromTransaction() public void HandleInventoryFromTransaction()
{ {
} }
public void HandleUDPUploadRequest() public void HandleUDPUploadRequest()
{ {
} }
public void HandleXfer(IClientAPI remoteClient, uint xferID, uint packetID, byte[] data) public void HandleXfer(IClientAPI remoteClient, uint xferID, uint packetID, byte[] data)
{ {
} }
} }
} }

View File

@ -1,275 +1,275 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.IO; using System.IO;
using libsecondlife; using libsecondlife;
using libsecondlife.Packets; using libsecondlife.Packets;
using OpenSim.Framework.Interfaces; using OpenSim.Framework.Interfaces;
using OpenSim.Framework.Types; using OpenSim.Framework.Types;
using OpenSim.Framework.Utilities; using OpenSim.Framework.Utilities;
using OpenSim.Region.Capabilities; using OpenSim.Region.Capabilities;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
namespace OpenSim.Framework.Communications.Caches namespace OpenSim.Framework.Communications.Caches
{ {
public class AgentAssetTransactions public class AgentAssetTransactions
{ {
// Fields // Fields
public List<AssetCapsUploader> CapsUploaders = new List<AssetCapsUploader>(); public List<AssetCapsUploader> CapsUploaders = new List<AssetCapsUploader>();
public List<NoteCardCapsUpdate> NotecardUpdaters = new List<NoteCardCapsUpdate>(); public List<NoteCardCapsUpdate> NotecardUpdaters = new List<NoteCardCapsUpdate>();
public LLUUID UserID; public LLUUID UserID;
public Dictionary<LLUUID, AssetXferUploader> XferUploaders = new Dictionary<LLUUID, AssetXferUploader>(); public Dictionary<LLUUID, AssetXferUploader> XferUploaders = new Dictionary<LLUUID, AssetXferUploader>();
// Methods // Methods
public AgentAssetTransactions(LLUUID agentID) public AgentAssetTransactions(LLUUID agentID)
{ {
this.UserID = agentID; this.UserID = agentID;
} }
public AssetCapsUploader RequestCapsUploader() public AssetCapsUploader RequestCapsUploader()
{ {
AssetCapsUploader uploader = new AssetCapsUploader(); AssetCapsUploader uploader = new AssetCapsUploader();
this.CapsUploaders.Add(uploader); this.CapsUploaders.Add(uploader);
return uploader; return uploader;
} }
public NoteCardCapsUpdate RequestNoteCardUpdater() public NoteCardCapsUpdate RequestNoteCardUpdater()
{ {
NoteCardCapsUpdate update = new NoteCardCapsUpdate(); NoteCardCapsUpdate update = new NoteCardCapsUpdate();
this.NotecardUpdaters.Add(update); this.NotecardUpdaters.Add(update);
return update; return update;
} }
public AssetXferUploader RequestXferUploader(LLUUID transactionID) public AssetXferUploader RequestXferUploader(LLUUID transactionID)
{ {
AssetXferUploader uploader = new AssetXferUploader(); AssetXferUploader uploader = new AssetXferUploader();
this.XferUploaders.Add(transactionID, uploader); this.XferUploaders.Add(transactionID, uploader);
return uploader; return uploader;
} }
// Nested Types // Nested Types
public class AssetCapsUploader public class AssetCapsUploader
{ {
// Fields // Fields
private BaseHttpServer httpListener; private BaseHttpServer httpListener;
private LLUUID inventoryItemID; private LLUUID inventoryItemID;
private string m_assetDescription = ""; private string m_assetDescription = "";
private string m_assetName = ""; private string m_assetName = "";
private LLUUID m_folderID; private LLUUID m_folderID;
private LLUUID newAssetID; private LLUUID newAssetID;
private bool SaveImages = false; private bool SaveImages = false;
private string uploaderPath = ""; private string uploaderPath = "";
// Events // Events
public event UpLoadedTexture OnUpLoad; public event UpLoadedTexture OnUpLoad;
// Methods // Methods
public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem, LLUUID folderID, string path, BaseHttpServer httpServer) public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem, LLUUID folderID, string path, BaseHttpServer httpServer)
{ {
this.m_assetName = assetName; this.m_assetName = assetName;
this.m_assetDescription = assetDescription; this.m_assetDescription = assetDescription;
this.m_folderID = folderID; this.m_folderID = folderID;
this.newAssetID = assetID; this.newAssetID = assetID;
this.inventoryItemID = inventoryItem; this.inventoryItemID = inventoryItem;
this.uploaderPath = path; this.uploaderPath = path;
this.httpListener = httpServer; this.httpListener = httpServer;
} }
private void SaveImageToFile(string filename, byte[] data) private void SaveImageToFile(string filename, byte[] data)
{ {
FileStream output = File.Create(filename); FileStream output = File.Create(filename);
BinaryWriter writer = new BinaryWriter(output); BinaryWriter writer = new BinaryWriter(output);
writer.Write(data); writer.Write(data);
writer.Close(); writer.Close();
output.Close(); output.Close();
} }
public string uploaderCaps(byte[] data, string path, string param) public string uploaderCaps(byte[] data, string path, string param)
{ {
LLUUID inventoryItemID = this.inventoryItemID; LLUUID inventoryItemID = this.inventoryItemID;
string text = ""; string text = "";
LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete();
complete.new_asset = this.newAssetID.ToStringHyphenated(); complete.new_asset = this.newAssetID.ToStringHyphenated();
complete.new_inventory_item = inventoryItemID; complete.new_inventory_item = inventoryItemID;
complete.state = "complete"; complete.state = "complete";
text = LLSDHelpers.SerialiseLLSDReply(complete); text = LLSDHelpers.SerialiseLLSDReply(complete);
this.httpListener.RemoveStreamHandler("POST", this.uploaderPath); this.httpListener.RemoveStreamHandler("POST", this.uploaderPath);
if (this.SaveImages) if (this.SaveImages)
{ {
this.SaveImageToFile(this.m_assetName + ".jp2", data); this.SaveImageToFile(this.m_assetName + ".jp2", data);
} }
if (this.OnUpLoad != null) if (this.OnUpLoad != null)
{ {
this.OnUpLoad(this.m_assetName, this.newAssetID, inventoryItemID, data); this.OnUpLoad(this.m_assetName, this.newAssetID, inventoryItemID, data);
} }
return text; return text;
} }
} }
public class AssetXferUploader public class AssetXferUploader
{ {
// Fields // Fields
public bool AddToInventory; public bool AddToInventory;
public AssetBase Asset; public AssetBase Asset;
public LLUUID InventFolder = LLUUID.Zero; public LLUUID InventFolder = LLUUID.Zero;
private IClientAPI ourClient; private IClientAPI ourClient;
public LLUUID TransactionID = LLUUID.Zero; public LLUUID TransactionID = LLUUID.Zero;
public bool UploadComplete; public bool UploadComplete;
public uint XferID; public uint XferID;
// Methods // Methods
public void HandleXferPacket(uint xferID, uint packetID, byte[] data) public void HandleXferPacket(uint xferID, uint packetID, byte[] data)
{ {
if (this.XferID == xferID) if (this.XferID == xferID)
{ {
if (this.Asset.Data.Length > 1) if (this.Asset.Data.Length > 1)
{ {
byte[] destinationArray = new byte[this.Asset.Data.Length + data.Length]; byte[] destinationArray = new byte[this.Asset.Data.Length + data.Length];
Array.Copy(this.Asset.Data, 0, destinationArray, 0, this.Asset.Data.Length); Array.Copy(this.Asset.Data, 0, destinationArray, 0, this.Asset.Data.Length);
Array.Copy(data, 0, destinationArray, this.Asset.Data.Length, data.Length); Array.Copy(data, 0, destinationArray, this.Asset.Data.Length, data.Length);
this.Asset.Data = destinationArray; this.Asset.Data = destinationArray;
} }
else else
{ {
byte[] buffer2 = new byte[data.Length - 4]; byte[] buffer2 = new byte[data.Length - 4];
Array.Copy(data, 4, buffer2, 0, data.Length - 4); Array.Copy(data, 4, buffer2, 0, data.Length - 4);
this.Asset.Data = buffer2; this.Asset.Data = buffer2;
} }
ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket(); ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket();
newPack.XferID.ID = xferID; newPack.XferID.ID = xferID;
newPack.XferID.Packet = packetID; newPack.XferID.Packet = packetID;
this.ourClient.OutPacket(newPack); this.ourClient.OutPacket(newPack);
if ((packetID & 0x80000000) != 0) if ((packetID & 0x80000000) != 0)
{ {
this.SendCompleteMessage(); this.SendCompleteMessage();
} }
} }
} }
public void Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data) public void Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data)
{ {
this.ourClient = remoteClient; this.ourClient = remoteClient;
this.Asset = new AssetBase(); this.Asset = new AssetBase();
this.Asset.FullID = assetID; this.Asset.FullID = assetID;
this.Asset.InvType = type; this.Asset.InvType = type;
this.Asset.Type = type; this.Asset.Type = type;
this.Asset.Data = data; this.Asset.Data = data;
this.Asset.Name = "blank"; this.Asset.Name = "blank";
this.Asset.Description = "empty"; this.Asset.Description = "empty";
this.TransactionID = transaction; this.TransactionID = transaction;
if (this.Asset.Data.Length > 2) if (this.Asset.Data.Length > 2)
{ {
this.SendCompleteMessage(); this.SendCompleteMessage();
} }
else else
{ {
this.ReqestStartXfer(); this.ReqestStartXfer();
} }
} }
protected void ReqestStartXfer() protected void ReqestStartXfer()
{ {
this.UploadComplete = false; this.UploadComplete = false;
this.XferID = Util.GetNextXferID(); this.XferID = Util.GetNextXferID();
RequestXferPacket newPack = new RequestXferPacket(); RequestXferPacket newPack = new RequestXferPacket();
newPack.XferID.ID = this.XferID; newPack.XferID.ID = this.XferID;
newPack.XferID.VFileType = this.Asset.Type; newPack.XferID.VFileType = this.Asset.Type;
newPack.XferID.VFileID = this.Asset.FullID; newPack.XferID.VFileID = this.Asset.FullID;
newPack.XferID.FilePath = 0; newPack.XferID.FilePath = 0;
newPack.XferID.Filename = new byte[0]; newPack.XferID.Filename = new byte[0];
this.ourClient.OutPacket(newPack); this.ourClient.OutPacket(newPack);
} }
protected void SendCompleteMessage() protected void SendCompleteMessage()
{ {
this.UploadComplete = true; this.UploadComplete = true;
AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
newPack.AssetBlock.Type = this.Asset.Type; newPack.AssetBlock.Type = this.Asset.Type;
newPack.AssetBlock.Success = true; newPack.AssetBlock.Success = true;
newPack.AssetBlock.UUID = this.Asset.FullID; newPack.AssetBlock.UUID = this.Asset.FullID;
this.ourClient.OutPacket(newPack); this.ourClient.OutPacket(newPack);
} }
} }
public class NoteCardCapsUpdate public class NoteCardCapsUpdate
{ {
// Fields // Fields
private BaseHttpServer httpListener; private BaseHttpServer httpListener;
private LLUUID inventoryItemID; private LLUUID inventoryItemID;
private string m_assetName = ""; private string m_assetName = "";
private LLUUID newAssetID; private LLUUID newAssetID;
private bool SaveImages = false; private bool SaveImages = false;
private string uploaderPath = ""; private string uploaderPath = "";
// Events // Events
public event UpLoadedTexture OnUpLoad; public event UpLoadedTexture OnUpLoad;
// Methods // Methods
public void Initialise(LLUUID inventoryItem, string path, BaseHttpServer httpServer) public void Initialise(LLUUID inventoryItem, string path, BaseHttpServer httpServer)
{ {
this.inventoryItemID = inventoryItem; this.inventoryItemID = inventoryItem;
this.uploaderPath = path; this.uploaderPath = path;
this.httpListener = httpServer; this.httpListener = httpServer;
this.newAssetID = LLUUID.Random(); this.newAssetID = LLUUID.Random();
} }
private void SaveImageToFile(string filename, byte[] data) private void SaveImageToFile(string filename, byte[] data)
{ {
FileStream output = File.Create(filename); FileStream output = File.Create(filename);
BinaryWriter writer = new BinaryWriter(output); BinaryWriter writer = new BinaryWriter(output);
writer.Write(data); writer.Write(data);
writer.Close(); writer.Close();
output.Close(); output.Close();
} }
public string uploaderCaps(byte[] data, string path, string param) public string uploaderCaps(byte[] data, string path, string param)
{ {
LLUUID inventoryItemID = this.inventoryItemID; LLUUID inventoryItemID = this.inventoryItemID;
string text = ""; string text = "";
LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete();
complete.new_asset = this.newAssetID.ToStringHyphenated(); complete.new_asset = this.newAssetID.ToStringHyphenated();
complete.new_inventory_item = inventoryItemID; complete.new_inventory_item = inventoryItemID;
complete.state = "complete"; complete.state = "complete";
text = LLSDHelpers.SerialiseLLSDReply(complete); text = LLSDHelpers.SerialiseLLSDReply(complete);
this.httpListener.RemoveStreamHandler("POST", this.uploaderPath); this.httpListener.RemoveStreamHandler("POST", this.uploaderPath);
if (this.SaveImages) if (this.SaveImages)
{ {
this.SaveImageToFile(this.m_assetName + "notecard.txt", data); this.SaveImageToFile(this.m_assetName + "notecard.txt", data);
} }
if (this.OnUpLoad != null) if (this.OnUpLoad != null)
{ {
this.OnUpLoad(this.m_assetName, this.newAssetID, inventoryItemID, data); this.OnUpLoad(this.m_assetName, this.newAssetID, inventoryItemID, data);
} }
return text; return text;
} }
} }
} }
} }

View File

@ -1,94 +1,94 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.IO; using System.IO;
using libsecondlife; using libsecondlife;
using OpenSim.Framework.Interfaces; using OpenSim.Framework.Interfaces;
using OpenSim.Framework.Types; using OpenSim.Framework.Types;
using OpenSim.Framework.Data; using OpenSim.Framework.Data;
using OpenSim.Framework.Utilities; using OpenSim.Framework.Utilities;
namespace OpenSim.Framework.Communications.Caches namespace OpenSim.Framework.Communications.Caches
{ {
public class CachedUserInfo public class CachedUserInfo
{ {
// Fields // Fields
public InventoryFolder RootFolder; public InventoryFolder RootFolder;
public UserProfileData UserProfile; public UserProfileData UserProfile;
// Methods // Methods
public void FolderReceive(LLUUID userID, InventoryFolder folderInfo) public void FolderReceive(LLUUID userID, InventoryFolder folderInfo)
{ {
if (userID == this.UserProfile.UUID) if (userID == this.UserProfile.UUID)
{ {
if (this.RootFolder == null) if (this.RootFolder == null)
{ {
if (folderInfo.parentID == LLUUID.Zero) if (folderInfo.parentID == LLUUID.Zero)
{ {
this.RootFolder = folderInfo; this.RootFolder = folderInfo;
} }
} }
else if (this.RootFolder.folderID == folderInfo.parentID) else if (this.RootFolder.folderID == folderInfo.parentID)
{ {
this.RootFolder.SubFolders.Add(folderInfo.folderID, folderInfo); this.RootFolder.SubFolders.Add(folderInfo.folderID, folderInfo);
} }
else else
{ {
InventoryFolder folder = this.RootFolder.HasSubFolder(folderInfo.parentID); InventoryFolder folder = this.RootFolder.HasSubFolder(folderInfo.parentID);
if (folder != null) if (folder != null)
{ {
folder.SubFolders.Add(folderInfo.folderID, folderInfo); folder.SubFolders.Add(folderInfo.folderID, folderInfo);
} }
} }
} }
} }
public void ItemReceive(LLUUID userID, InventoryItemBase itemInfo) public void ItemReceive(LLUUID userID, InventoryItemBase itemInfo)
{ {
if ((userID == this.UserProfile.UUID) && (this.RootFolder != null)) if ((userID == this.UserProfile.UUID) && (this.RootFolder != null))
{ {
if (itemInfo.parentFolderID == this.RootFolder.folderID) if (itemInfo.parentFolderID == this.RootFolder.folderID)
{ {
this.RootFolder.Items.Add(itemInfo.inventoryID, itemInfo); this.RootFolder.Items.Add(itemInfo.inventoryID, itemInfo);
} }
else else
{ {
InventoryFolder folder = this.RootFolder.HasSubFolder(itemInfo.parentFolderID); InventoryFolder folder = this.RootFolder.HasSubFolder(itemInfo.parentFolderID);
if (folder != null) if (folder != null)
{ {
folder.Items.Add(itemInfo.inventoryID, itemInfo); folder.Items.Add(itemInfo.inventoryID, itemInfo);
} }
} }
} }
} }
} }
} }

View File

@ -1,109 +1,109 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.IO; using System.IO;
using libsecondlife; using libsecondlife;
using OpenSim.Framework.Interfaces; using OpenSim.Framework.Interfaces;
using OpenSim.Framework.Data; using OpenSim.Framework.Data;
using OpenSim.Framework.Types; using OpenSim.Framework.Types;
using OpenSim.Framework.Utilities; using OpenSim.Framework.Utilities;
namespace OpenSim.Framework.Communications.Caches namespace OpenSim.Framework.Communications.Caches
{ {
public class InventoryFolder : InventoryFolderBase public class InventoryFolder : InventoryFolderBase
{ {
// Fields // Fields
public Dictionary<LLUUID, InventoryItemBase> Items = new Dictionary<LLUUID, InventoryItemBase>(); public Dictionary<LLUUID, InventoryItemBase> Items = new Dictionary<LLUUID, InventoryItemBase>();
public Dictionary<LLUUID, InventoryFolder> SubFolders = new Dictionary<LLUUID, InventoryFolder>(); public Dictionary<LLUUID, InventoryFolder> SubFolders = new Dictionary<LLUUID, InventoryFolder>();
// Methods // Methods
public InventoryFolder CreateNewSubFolder(LLUUID folderID, string folderName, ushort type) public InventoryFolder CreateNewSubFolder(LLUUID folderID, string folderName, ushort type)
{ {
InventoryFolder subFold = new InventoryFolder(); InventoryFolder subFold = new InventoryFolder();
subFold.name = folderName; subFold.name = folderName;
subFold.folderID = folderID; subFold.folderID = folderID;
subFold.type = type; subFold.type = (short) type;
subFold.parentID = this.folderID; subFold.parentID = this.folderID;
subFold.agentID = this.agentID; subFold.agentID = this.agentID;
this.SubFolders.Add(subFold.folderID, subFold); this.SubFolders.Add(subFold.folderID, subFold);
return subFold; return subFold;
} }
public InventoryItemBase HasItem(LLUUID itemID) public InventoryItemBase HasItem(LLUUID itemID)
{ {
InventoryItemBase base2 = null; InventoryItemBase base2 = null;
if (this.Items.ContainsKey(itemID)) if (this.Items.ContainsKey(itemID))
{ {
return this.Items[itemID]; return this.Items[itemID];
} }
foreach (InventoryFolder folder in this.SubFolders.Values) foreach (InventoryFolder folder in this.SubFolders.Values)
{ {
base2 = folder.HasItem(itemID); base2 = folder.HasItem(itemID);
if (base2 != null) if (base2 != null)
{ {
break; break;
} }
} }
return base2; return base2;
} }
public InventoryFolder HasSubFolder(LLUUID folderID) public InventoryFolder HasSubFolder(LLUUID folderID)
{ {
InventoryFolder returnFolder = null; InventoryFolder returnFolder = null;
if (this.SubFolders.ContainsKey(folderID)) if (this.SubFolders.ContainsKey(folderID))
{ {
returnFolder = this.SubFolders[folderID]; returnFolder = this.SubFolders[folderID];
} }
else else
{ {
foreach (InventoryFolder folder in this.SubFolders.Values) foreach (InventoryFolder folder in this.SubFolders.Values)
{ {
returnFolder = folder.HasSubFolder(folderID); returnFolder = folder.HasSubFolder(folderID);
if (returnFolder != null) if (returnFolder != null)
{ {
break; break;
} }
} }
} }
return returnFolder; return returnFolder;
} }
public List<InventoryItemBase> RequestListOfItems() public List<InventoryItemBase> RequestListOfItems()
{ {
List<InventoryItemBase> itemList = new List<InventoryItemBase>(); List<InventoryItemBase> itemList = new List<InventoryItemBase>();
foreach (InventoryItemBase item in this.Items.Values) foreach (InventoryItemBase item in this.Items.Values)
{ {
itemList.Add(item); itemList.Add(item);
} }
return itemList; return itemList;
} }
} }
} }

View File

@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Text;
using libsecondlife;
using OpenSim.Framework.Data;
namespace OpenSim.Framework.Communications.Caches
{
public class LibraryRootFolder : InventoryFolder
{
private LLUUID libOwner = new LLUUID("11111111-1111-0000-0000-000100bba000");
public LibraryRootFolder()
{
this.agentID = libOwner;
this.folderID = new LLUUID("00000112-000f-0000-0000-000100bba000");
this.name = "OpenSim Library";
this.parentID = LLUUID.Zero;
this.type = (short)-1;
this.version = (ushort) 1;
InventoryItemBase item = new InventoryItemBase();
item.avatarID = libOwner;
item.creatorsID = libOwner;
item.inventoryID = LLUUID.Random();
item.assetID = new LLUUID("00000000-0000-0000-9999-000000000002");
item.inventoryDescription = "Plywood texture";
item.inventoryName = "Plywood";
item.type =0;
item.parentFolderID = this.folderID;
item.inventoryCurrentPermissions = 2147483647;
item.inventoryNextPermissions = 2147483647;
this.Items.Add(item.inventoryID, item);
item = new InventoryItemBase();
item.avatarID = libOwner;
item.creatorsID = libOwner;
item.inventoryID = LLUUID.Random();
item.assetID = new LLUUID("00000000-0000-0000-9999-000000000003");
item.inventoryDescription = "Rocks texture";
item.inventoryName = "Rocks";
item.type = 0;
item.parentFolderID = this.folderID;
item.inventoryCurrentPermissions = 2147483647;
item.inventoryNextPermissions = 2147483647;
this.Items.Add(item.inventoryID, item);
item = new InventoryItemBase();
item.avatarID = libOwner;
item.creatorsID = libOwner;
item.inventoryID = LLUUID.Random();
item.assetID = new LLUUID("00000000-0000-0000-9999-000000000001");
item.inventoryDescription = "Bricks texture";
item.inventoryName = "Bricks";
item.type = 0;
item.parentFolderID = this.folderID;
item.inventoryCurrentPermissions = 2147483647;
item.inventoryNextPermissions = 2147483647;
this.Items.Add(item.inventoryID, item);
item = new InventoryItemBase();
item.avatarID = libOwner;
item.creatorsID = libOwner;
item.inventoryID = LLUUID.Random();
item.assetID = new LLUUID("00000000-0000-0000-9999-000000000004");
item.inventoryDescription = "Granite texture";
item.inventoryName = "Granite";
item.type = 0;
item.parentFolderID = this.folderID;
item.inventoryCurrentPermissions = 2147483647;
item.inventoryNextPermissions = 2147483647;
this.Items.Add(item.inventoryID, item);
item = new InventoryItemBase();
item.avatarID = libOwner;
item.creatorsID = libOwner;
item.inventoryID = LLUUID.Random();
item.assetID = new LLUUID("00000000-0000-0000-9999-000000000005");
item.inventoryDescription = "Hardwood texture";
item.inventoryName = "Hardwood";
item.type = 0;
item.parentFolderID = this.folderID;
item.inventoryCurrentPermissions = 2147483647;
item.inventoryNextPermissions = 2147483647;
this.Items.Add(item.inventoryID, item);
}
}
}

View File

@ -1,170 +1,216 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.IO; using System.IO;
using libsecondlife; using libsecondlife;
using OpenSim.Framework.Interfaces; using OpenSim.Framework.Interfaces;
using OpenSim.Framework.Types; using OpenSim.Framework.Types;
using OpenSim.Framework.Utilities; using OpenSim.Framework.Utilities;
using OpenSim.Framework.Data; using OpenSim.Framework.Data;
namespace OpenSim.Framework.Communications.Caches namespace OpenSim.Framework.Communications.Caches
{ {
public class UserProfileCache
public class UserProfileCache {
{ // Fields
// Fields private CommunicationsManager m_parent;
private CommunicationsManager m_parent; public Dictionary<LLUUID, CachedUserInfo> UserProfiles = new Dictionary<LLUUID, CachedUserInfo>();
public Dictionary<LLUUID, CachedUserInfo> UserProfiles = new Dictionary<LLUUID, CachedUserInfo>();
public LibraryRootFolder libraryRoot = new LibraryRootFolder();
// Methods
public UserProfileCache(CommunicationsManager parent) // Methods
{ public UserProfileCache(CommunicationsManager parent)
this.m_parent = parent; {
} this.m_parent = parent;
}
public void AddNewUser(LLUUID userID)
{ /// <summary>
if (!this.UserProfiles.ContainsKey(userID)) /// A new user has moved into a region in this instance
{ /// so get info from servers
CachedUserInfo userInfo = new CachedUserInfo(); /// </summary>
userInfo.UserProfile = this.RequestUserProfileForUser(userID); /// <param name="userID"></param>
if (userInfo.UserProfile != null) public void AddNewUser(LLUUID userID)
{ {
this.RequestInventoryForUser(userID, userInfo); if (!this.UserProfiles.ContainsKey(userID))
this.UserProfiles.Add(userID, userInfo); {
} CachedUserInfo userInfo = new CachedUserInfo();
else userInfo.UserProfile = this.RequestUserProfileForUser(userID);
{ if (userInfo.UserProfile != null)
Console.WriteLine("UserProfileCache.cs: user profile for user not found"); {
} this.RequestInventoryForUser(userID, userInfo);
} this.UserProfiles.Add(userID, userInfo);
} }
else
public void AddNewUser(string firstName, string lastName) {
{ Console.WriteLine("UserProfileCache.cs: user profile for user not found");
} }
}
public CachedUserInfo GetUserDetails(LLUUID userID) }
{
if (this.UserProfiles.ContainsKey(userID)) /// <summary>
{ /// A new user has moved into a region in this instance
return this.UserProfiles[userID]; /// so get info from servers
} /// </summary>
return null; /// <param name="firstName"></param>
} /// <param name="lastName"></param>
public void AddNewUser(string firstName, string lastName)
public void HandleCreateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort folderType, string folderName, LLUUID parentID) {
{ }
if (this.UserProfiles.ContainsKey(remoteClient.AgentId))
{ public CachedUserInfo GetUserDetails(LLUUID userID)
CachedUserInfo info = this.UserProfiles[remoteClient.AgentId]; {
if (info.RootFolder.folderID == parentID) if (this.UserProfiles.ContainsKey(userID))
{ {
info.RootFolder.CreateNewSubFolder(folderID, folderName, folderType); return this.UserProfiles[userID];
} }
else return null;
{ }
InventoryFolder folder = info.RootFolder.HasSubFolder(parentID);
if (folder != null) public void HandleCreateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort folderType, string folderName, LLUUID parentID)
{ {
folder.CreateNewSubFolder(folderID, folderName, folderType); if (this.UserProfiles.ContainsKey(remoteClient.AgentId))
} {
} CachedUserInfo info = this.UserProfiles[remoteClient.AgentId];
} if (info.RootFolder.folderID == parentID)
} {
info.RootFolder.CreateNewSubFolder(folderID, folderName, folderType);
public void HandleFecthInventoryDescendents(IClientAPI remoteClient, LLUUID folderID, LLUUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder) }
{ else
if (this.UserProfiles.ContainsKey(remoteClient.AgentId)) {
{ InventoryFolder folder = info.RootFolder.HasSubFolder(parentID);
CachedUserInfo info = this.UserProfiles[remoteClient.AgentId]; if (folder != null)
if (info.RootFolder.folderID == folderID) {
{ folder.CreateNewSubFolder(folderID, folderName, folderType);
if (fetchItems) }
{ }
remoteClient.SendInventoryFolderDetails(remoteClient.AgentId, folderID, info.RootFolder.RequestListOfItems()); }
} }
}
else public void HandleFecthInventoryDescendents(IClientAPI remoteClient, LLUUID folderID, LLUUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder)
{ {
InventoryFolder folder = info.RootFolder.HasSubFolder(folderID); if (folderID == libraryRoot.folderID )
if ((folder != null) && fetchItems) {
{ remoteClient.SendInventoryFolderDetails(libraryRoot.agentID, libraryRoot.folderID, libraryRoot.RequestListOfItems());
remoteClient.SendInventoryFolderDetails(remoteClient.AgentId, folderID, folder.RequestListOfItems()); }
} else if (this.UserProfiles.ContainsKey(remoteClient.AgentId))
} {
} CachedUserInfo info = this.UserProfiles[remoteClient.AgentId];
} if (info.RootFolder.folderID == folderID)
{
public void HandleFetchInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID ownerID) if (fetchItems)
{ {
if (this.UserProfiles.ContainsKey(remoteClient.AgentId)) remoteClient.SendInventoryFolderDetails(remoteClient.AgentId, folderID, info.RootFolder.RequestListOfItems());
{ }
InventoryItemBase item = this.UserProfiles[remoteClient.AgentId].RootFolder.HasItem(itemID); }
if (item != null) else
{ {
remoteClient.SendInventoryItemDetails(ownerID, item); InventoryFolder folder = info.RootFolder.HasSubFolder(folderID);
} if ((folder != null) && fetchItems)
} {
} remoteClient.SendInventoryFolderDetails(remoteClient.AgentId, folderID, folder.RequestListOfItems());
}
private void RequestInventoryForUser(LLUUID userID, CachedUserInfo userInfo) }
{ }
InventoryFolder folderInfo = new InventoryFolder(); }
folderInfo.agentID = userID;
folderInfo.folderID = userInfo.UserProfile.rootInventoryFolderID; public void HandleFetchInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID ownerID)
folderInfo.name = "My Inventory"; {
folderInfo.parentID = LLUUID.Zero; if (ownerID == libraryRoot.agentID)
folderInfo.type = 8; {
folderInfo.version = 1; //Console.WriteLine("request info for library item");
userInfo.FolderReceive(userID, folderInfo); }
} else if (this.UserProfiles.ContainsKey(remoteClient.AgentId))
{
private UserProfileData RequestUserProfileForUser(LLUUID userID) InventoryItemBase item = this.UserProfiles[remoteClient.AgentId].RootFolder.HasItem(itemID);
{ if (item != null)
return this.m_parent.UserServer.GetUserProfile(userID); {
} remoteClient.SendInventoryItemDetails(ownerID, item);
}
private void UpdateInventoryToServer(LLUUID userID) }
{ }
}
/// <summary>
private void UpdateUserProfileToServer(LLUUID userID) /// Request Iventory Info from Inventory server
{ /// </summary>
} /// <param name="userID"></param>
private void RequestInventoryForUser(LLUUID userID, CachedUserInfo userInfo)
public void UserLogOut(LLUUID userID) {
{ // this.m_parent.InventoryServer.RequestInventoryForUser(userID, userInfo.FolderReceive, userInfo.ItemReceive);
}
} //for now we manually create the root folder,
} // but should be requesting all inventory from inventory server.
InventoryFolder folderInfo = new InventoryFolder();
folderInfo.agentID = userID;
folderInfo.folderID = userInfo.UserProfile.rootInventoryFolderID;
folderInfo.name = "My Inventory";
folderInfo.parentID = LLUUID.Zero;
folderInfo.type = 8;
folderInfo.version = 1;
userInfo.FolderReceive(userID, folderInfo);
}
/// <summary>
/// Request the user profile from User server
/// </summary>
/// <param name="userID"></param>
private UserProfileData RequestUserProfileForUser(LLUUID userID)
{
return this.m_parent.UserServer.GetUserProfile(userID);
}
/// <summary>
/// Update Inventory data to Inventory server
/// </summary>
/// <param name="userID"></param>
private void UpdateInventoryToServer(LLUUID userID)
{
}
/// <summary>
/// Make sure UserProfile is updated on user server
/// </summary>
/// <param name="userID"></param>
private void UpdateUserProfileToServer(LLUUID userID)
{
}
/// <summary>
/// A user has left this instance
/// so make sure servers have been updated
/// Then remove cached info
/// </summary>
/// <param name="userID"></param>
public void UserLogOut(LLUUID userID)
{
}
}
}

View File

@ -44,7 +44,7 @@ namespace OpenSim.Framework.Communications
public IGridServices GridServer; public IGridServices GridServer;
public IInventoryServices InventoryServer; public IInventoryServices InventoryServer;
public IInterRegionCommunications InterRegion; public IInterRegionCommunications InterRegion;
public UserProfileCache UserProfilesCache; public UserProfileCache UserProfiles;
public AssetCache AssetCache; public AssetCache AssetCache;
public NetworkServersInfo ServersInfo; public NetworkServersInfo ServersInfo;
@ -52,21 +52,28 @@ namespace OpenSim.Framework.Communications
{ {
ServersInfo = serversInfo; ServersInfo = serversInfo;
this.AssetCache = assetCache; this.AssetCache = assetCache;
UserProfilesCache = new UserProfileCache(this); UserProfiles = new UserProfileCache(this);
} }
#region Packet Handlers #region Packet Handlers
public void HandleUUIDNameRequest(LLUUID uuid, IClientAPI remote_client) public void HandleUUIDNameRequest(LLUUID uuid, IClientAPI remote_client)
{ {
UserProfileData profileData = this.UserServer.GetUserProfile(uuid); if (uuid == UserProfiles.libraryRoot.agentID)
if (profileData != null)
{ {
LLUUID profileId = profileData.UUID; remote_client.SendNameReply(uuid , "Mr" , "OpenSim");
string firstname = profileData.username; }
string lastname = profileData.surname; else
{
UserProfileData profileData = this.UserServer.GetUserProfile(uuid);
if (profileData != null)
{
LLUUID profileId = profileData.UUID;
string firstname = profileData.username;
string lastname = profileData.surname;
remote_client.SendNameReply(profileId, firstname, lastname); remote_client.SendNameReply(profileId, firstname, lastname);
} }
}
} }
#endregion #endregion

View File

@ -101,7 +101,7 @@ namespace OpenSim.Framework.Data
/// <summary> /// <summary>
/// Tyep of Items normally stored in this folder /// Tyep of Items normally stored in this folder
/// </summary> /// </summary>
public ushort type; public short type;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>

View File

@ -50,7 +50,7 @@ namespace OpenSim.Framework.InventoryServiceBase
} }
/// <summary> /// <summary>
/// /// Returns the root folder plus any folders in root (so down one level in the Inventory folders tree)
/// </summary> /// </summary>
/// <param name="userID"></param> /// <param name="userID"></param>
/// <returns></returns> /// <returns></returns>

View File

@ -27,6 +27,8 @@ namespace OpenSim.Framework.UserManagement
private ArrayList inventoryRoot; private ArrayList inventoryRoot;
private ArrayList initialOutfit; private ArrayList initialOutfit;
private ArrayList agentInventory; private ArrayList agentInventory;
private ArrayList inventoryLibraryOwner;
private ArrayList inventoryLibrary;
private UserInfo userProfile; private UserInfo userProfile;
@ -87,6 +89,8 @@ namespace OpenSim.Framework.UserManagement
this.inventoryRoot = new ArrayList(); this.inventoryRoot = new ArrayList();
this.initialOutfit = new ArrayList(); this.initialOutfit = new ArrayList();
this.agentInventory = new ArrayList(); this.agentInventory = new ArrayList();
this.inventoryLibrary = new ArrayList();
this.inventoryLibraryOwner = new ArrayList();
this.xmlRpcResponse = new XmlRpcResponse(); this.xmlRpcResponse = new XmlRpcResponse();
this.defaultXmlRpcResponse = new XmlRpcResponse(); this.defaultXmlRpcResponse = new XmlRpcResponse();
@ -234,10 +238,10 @@ namespace OpenSim.Framework.UserManagement
responseData["ui-config"] = this.uiConfig; responseData["ui-config"] = this.uiConfig;
responseData["inventory-skeleton"] = this.agentInventory; responseData["inventory-skeleton"] = this.agentInventory;
responseData["inventory-skel-lib"] = new ArrayList(); // todo responseData["inventory-skel-lib"] = this.inventoryLibrary;
responseData["inventory-root"] = this.inventoryRoot; responseData["inventory-root"] = this.inventoryRoot;
responseData["gestures"] = new ArrayList(); // todo responseData["gestures"] = new ArrayList(); // todo
responseData["inventory-lib-owner"] = new ArrayList(); // todo responseData["inventory-lib-owner"] = this.inventoryLibraryOwner;
responseData["initial-outfit"] = this.initialOutfit; responseData["initial-outfit"] = this.initialOutfit;
responseData["start_location"] = this.startLocation; responseData["start_location"] = this.startLocation;
responseData["seed_capability"] = this.seedCapability; responseData["seed_capability"] = this.seedCapability;
@ -600,6 +604,30 @@ namespace OpenSim.Framework.UserManagement
} }
} }
public ArrayList InventoryLibrary
{
get
{
return this.inventoryLibrary;
}
set
{
this.inventoryLibrary = value;
}
}
public ArrayList InventoryLibraryOwner
{
get
{
return this.inventoryLibraryOwner;
}
set
{
this.inventoryLibraryOwner = value;
}
}
public string Home public string Home
{ {
get get

View File

@ -346,6 +346,38 @@ namespace OpenSim.Framework.UserManagement
return _config.DefaultStartupMsg; return _config.DefaultStartupMsg;
} }
/// <summary>
///
/// </summary>
/// <returns></returns>
protected virtual ArrayList GetInventoryLibrary()
{
//return new ArrayList();
Hashtable TempHash = new Hashtable();
TempHash["name"] = "OpenSim Library";
TempHash["parent_id"] = LLUUID.Zero.ToStringHyphenated();
TempHash["version"] = "1";
TempHash["type_default"] = "-1";
TempHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
ArrayList temp = new ArrayList();
temp.Add(TempHash);
return temp;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
protected virtual ArrayList GetLibraryOwner()
{
//for now create random inventory library owner
Hashtable TempHash = new Hashtable();
TempHash["agent_id"] = "11111111-1111-0000-0000-000100bba000";
ArrayList inventoryLibOwner = new ArrayList();
inventoryLibOwner.Add(TempHash);
return inventoryLibOwner;
}
/// <summary> /// <summary>
/// Customises the login response and fills in missing values. /// Customises the login response and fills in missing values.
/// </summary> /// </summary>
@ -446,6 +478,8 @@ namespace OpenSim.Framework.UserManagement
logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToStringHyphenated(); logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToStringHyphenated();
logResponse.InventoryRoot = InventoryRoot; logResponse.InventoryRoot = InventoryRoot;
logResponse.InventorySkeleton = AgentInventoryArray; logResponse.InventorySkeleton = AgentInventoryArray;
logResponse.InventoryLibrary = this.GetInventoryLibrary();
logResponse.InventoryLibraryOwner = this.GetLibraryOwner();
logResponse.CircuitCode = (Int32)circode; logResponse.CircuitCode = (Int32)circode;
//logResponse.RegionX = 0; //overwritten //logResponse.RegionX = 0; //overwritten
//logResponse.RegionY = 0; //overwritten //logResponse.RegionY = 0; //overwritten

View File

@ -669,7 +669,7 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="nextOwnerMask"></param> /// <param name="nextOwnerMask"></param>
public void CreateNewInventoryItem(IClientAPI remoteClient, LLUUID transActionID, LLUUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask) public void CreateNewInventoryItem(IClientAPI remoteClient, LLUUID transActionID, LLUUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask)
{ {
CachedUserInfo userInfo = commsManager.UserProfilesCache.GetUserDetails(remoteClient.AgentId); CachedUserInfo userInfo = commsManager.UserProfiles.GetUserDetails(remoteClient.AgentId);
if (userInfo != null) if (userInfo != null)
{ {
AssetBase asset = new AssetBase(); AssetBase asset = new AssetBase();

View File

@ -546,7 +546,7 @@ namespace OpenSim.Region.Environment.Scenes
m_estateManager.sendRegionHandshake(client); m_estateManager.sendRegionHandshake(client);
CreateAndAddScenePresence(client); CreateAndAddScenePresence(client);
m_LandManager.sendParcelOverlay(client); m_LandManager.sendParcelOverlay(client);
// commsManager.UserProfilesCache.AddNewUser(client.AgentId); //commsManager.UserProfiles.AddNewUser(client.AgentId);
} }
protected virtual void SubscribeToClientEvents(IClientAPI client) protected virtual void SubscribeToClientEvents(IClientAPI client)
@ -591,9 +591,9 @@ namespace OpenSim.Region.Environment.Scenes
client.OnEstateOwnerMessage += new EstateOwnerMessageRequest(m_estateManager.handleEstateOwnerMessage); client.OnEstateOwnerMessage += new EstateOwnerMessageRequest(m_estateManager.handleEstateOwnerMessage);
// client.OnCreateNewInventoryItem += CreateNewInventoryItem; // client.OnCreateNewInventoryItem += CreateNewInventoryItem;
// client.OnCreateNewInventoryFolder += commsManager.UserProfilesCache.HandleCreateInventoryFolder; //client.OnCreateNewInventoryFolder += commsManager.UserProfiles.HandleCreateInventoryFolder;
// client.OnFetchInventoryDescendents += commsManager.UserProfilesCache.HandleFecthInventoryDescendents; client.OnFetchInventoryDescendents += commsManager.UserProfiles.HandleFecthInventoryDescendents;
// client.OnRequestTaskInventory += RequestTaskInventory; client.OnRequestTaskInventory += RequestTaskInventory;
} }
protected ScenePresence CreateAndAddScenePresence(IClientAPI client) protected ScenePresence CreateAndAddScenePresence(IClientAPI client)

View File

@ -1,74 +1,74 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Drawing; using System.Drawing;
namespace libTerrain namespace libTerrain
{ {
class Raster class Raster
{ {
int w; int w;
int h; int h;
Bitmap bmp; Bitmap bmp;
public Raster(int width, int height) public Raster(int width, int height)
{ {
w = width; w = width;
h = height; h = height;
bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
} }
public Channel ToChannel() public Channel ToChannel()
{ {
Channel chan = new Channel(bmp.Width, bmp.Height); Channel chan = new Channel(bmp.Width, bmp.Height);
int x, y; int x, y;
for (x = 0; x < bmp.Width; x++) for (x = 0; x < bmp.Width; x++)
{ {
for (y = 0; y < bmp.Height; y++) for (y = 0; y < bmp.Height; y++)
{ {
Color val = bmp.GetPixel(x, y); Color val = bmp.GetPixel(x, y);
chan.map[x, y] = (((double)val.R + (double)val.G + (double)val.B) / 3.0) / 255.0; chan.map[x, y] = (((double)val.R + (double)val.G + (double)val.B) / 3.0) / 255.0;
} }
} }
return chan; return chan;
} }
public void DrawText(string txt, string font, double size) public void DrawText(string txt, string font, double size)
{ {
Graphics gd = Graphics.FromImage(bmp); Graphics gd = Graphics.FromImage(bmp);
//gd.DrawString(txt, //gd.DrawString(txt,
} }
} }
} }

View File

@ -1,66 +1,66 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
/* Channel /* Channel
* A channel is a single heightmap array * A channel is a single heightmap array
* */ * */
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
public double[,] map; public double[,] map;
public int[,] diff; public int[,] diff;
public int w; public int w;
public int h; public int h;
public int seed = 1338; // One better than 1337 public int seed = 1338; // One better than 1337
public Channel() public Channel()
{ {
w = 256; w = 256;
h = 256; h = 256;
map = new double[w, h]; map = new double[w, h];
diff = new int[(int)(w / 16), (int)(h / 16)]; diff = new int[(int)(w / 16), (int)(h / 16)];
} }
public Channel(int width, int height) public Channel(int width, int height)
{ {
w = width; w = width;
h = height; h = height;
map = new double[w, h]; map = new double[w, h];
diff = new int[(int)(w / 16), (int)(h / 16)]; diff = new int[(int)(w / 16), (int)(h / 16)];
} }
} }
} }

View File

@ -1,277 +1,277 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
public partial class Channel public partial class Channel
{ {
public int GetWidth() public int GetWidth()
{ {
return w; return w;
} }
public int GetHeight() public int GetHeight()
{ {
return h; return h;
} }
public Channel Copy() public Channel Copy()
{ {
Channel x = new Channel(w, h); Channel x = new Channel(w, h);
x.map = (double[,])this.map.Clone(); x.map = (double[,])this.map.Clone();
return x; return x;
} }
public void SetDiff() public void SetDiff()
{ {
SetDiff(1); SetDiff(1);
} }
public void SetDiff(int val) public void SetDiff(int val)
{ {
for (int x = 0; x < w / 16; x++) for (int x = 0; x < w / 16; x++)
{ {
for (int y = 0; y < h / 16; y++) for (int y = 0; y < h / 16; y++)
{ {
diff[x, y] = val; diff[x, y] = val;
} }
} }
} }
public void SetDiff(int x, int y) public void SetDiff(int x, int y)
{ {
diff[x / 16, y / 16]++; diff[x / 16, y / 16]++;
} }
public void Set(int x, int y, double val) public void Set(int x, int y, double val)
{ {
if (x >= w) if (x >= w)
throw new Exception("Bounds error while setting pixel (width)"); throw new Exception("Bounds error while setting pixel (width)");
if (y >= h) if (y >= h)
throw new Exception("Bounds error while setting pixel (height)"); throw new Exception("Bounds error while setting pixel (height)");
if (x < 0) if (x < 0)
throw new Exception("Bounds error while setting pixel (width)"); throw new Exception("Bounds error while setting pixel (width)");
if (y < 0) if (y < 0)
throw new Exception("Bounds error while setting pixel (height)"); throw new Exception("Bounds error while setting pixel (height)");
if (map[x, y] != val) if (map[x, y] != val)
{ {
SetDiff(x, y); SetDiff(x, y);
map[x, y] = val; map[x, y] = val;
} }
} }
public void SetClip(int x, int y, double val) public void SetClip(int x, int y, double val)
{ {
SetDiff(x, y); SetDiff(x, y);
if (x >= w) if (x >= w)
throw new Exception("Bounds error while setting pixel (width)"); throw new Exception("Bounds error while setting pixel (width)");
if (y >= h) if (y >= h)
throw new Exception("Bounds error while setting pixel (height)"); throw new Exception("Bounds error while setting pixel (height)");
if (x < 0) if (x < 0)
throw new Exception("Bounds error while setting pixel (width)"); throw new Exception("Bounds error while setting pixel (width)");
if (y < 0) if (y < 0)
throw new Exception("Bounds error while setting pixel (height)"); throw new Exception("Bounds error while setting pixel (height)");
if (val > 1.0) if (val > 1.0)
val = 1.0; val = 1.0;
if (val < 0.0) if (val < 0.0)
val = 0.0; val = 0.0;
map[x, y] = val; map[x, y] = val;
} }
private double GetBilinearInterpolate(double x, double y) private double GetBilinearInterpolate(double x, double y)
{ {
if (x > w - 2.0) if (x > w - 2.0)
x = w - 2.0; x = w - 2.0;
if (y > h - 2.0) if (y > h - 2.0)
y = h - 2.0; y = h - 2.0;
if (x < 0.0) if (x < 0.0)
x = 0.0; x = 0.0;
if (y < 0.0) if (y < 0.0)
y = 0.0; y = 0.0;
int stepSize = 1; int stepSize = 1;
double h00 = Get((int)x, (int)y); double h00 = Get((int)x, (int)y);
double h10 = Get((int)x + stepSize, (int)y); double h10 = Get((int)x + stepSize, (int)y);
double h01 = Get((int)x, (int)y + stepSize); double h01 = Get((int)x, (int)y + stepSize);
double h11 = Get((int)x + stepSize, (int)y + stepSize); double h11 = Get((int)x + stepSize, (int)y + stepSize);
double h1 = h00; double h1 = h00;
double h2 = h10; double h2 = h10;
double h3 = h01; double h3 = h01;
double h4 = h11; double h4 = h11;
double a00 = h1; double a00 = h1;
double a10 = h2 - h1; double a10 = h2 - h1;
double a01 = h3 - h1; double a01 = h3 - h1;
double a11 = h1 - h2 - h3 + h4; double a11 = h1 - h2 - h3 + h4;
double partialx = x - (int)x; double partialx = x - (int)x;
double partialz = y - (int)y; double partialz = y - (int)y;
double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz); double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
return hi; return hi;
} }
public double Get(int x, int y) public double Get(int x, int y)
{ {
if (x >= w) if (x >= w)
x = w - 1; x = w - 1;
if (y >= h) if (y >= h)
y = h - 1; y = h - 1;
if (x < 0) if (x < 0)
x = 0; x = 0;
if (y < 0) if (y < 0)
y = 0; y = 0;
return map[x, y]; return map[x, y];
} }
public void SetWrap(int x, int y, double val) public void SetWrap(int x, int y, double val)
{ {
SetDiff(x, y); SetDiff(x, y);
map[x % w, y % h] = val; map[x % w, y % h] = val;
} }
public void SetWrapClip(int x, int y, double val) public void SetWrapClip(int x, int y, double val)
{ {
SetDiff(x, y); SetDiff(x, y);
if (val > 1.0) if (val > 1.0)
val = 1.0; val = 1.0;
if (val < 0.0) if (val < 0.0)
val = 0.0; val = 0.0;
map[x % w, y % h] = val; map[x % w, y % h] = val;
} }
public void Fill(double val) public void Fill(double val)
{ {
SetDiff(); SetDiff();
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
map[x, y] = val; map[x, y] = val;
} }
} }
} }
public void Fill(double min, double max, double val) public void Fill(double min, double max, double val)
{ {
SetDiff(); SetDiff();
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (map[x, y] >= min && map[x, y] <= max) if (map[x, y] >= min && map[x, y] <= max)
map[x, y] = val; map[x, y] = val;
} }
} }
} }
public double FindMax() public double FindMax()
{ {
int x, y; int x, y;
double max = double.MinValue; double max = double.MinValue;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (map[x, y] > max) if (map[x, y] > max)
max = map[x, y]; max = map[x, y];
} }
} }
return max; return max;
} }
public double FindMin() public double FindMin()
{ {
int x, y; int x, y;
double min = double.MaxValue; double min = double.MaxValue;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (map[x, y] < min) if (map[x, y] < min)
min = map[x, y]; min = map[x, y];
} }
} }
return min; return min;
} }
public double Sum() public double Sum()
{ {
int x, y; int x, y;
double sum = 0.0; double sum = 0.0;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
sum += map[x, y]; sum += map[x, y];
} }
} }
return sum; return sum;
} }
public double Avg() public double Avg()
{ {
return Sum() / (w * h); return Sum() / (w * h);
} }
public bool ContainsNaN() public bool ContainsNaN()
{ {
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
double elm = map[x, y]; double elm = map[x, y];
if (Double.IsNaN(elm)) if (Double.IsNaN(elm))
return true; return true;
} }
} }
return false; return false;
} }
} }
} }

View File

@ -1,149 +1,149 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
/// <summary> /// <summary>
/// Flattens the area underneath rx,ry by moving it to the average of the area. Uses a spherical mask provided by the raise() function. /// Flattens the area underneath rx,ry by moving it to the average of the area. Uses a spherical mask provided by the raise() function.
/// </summary> /// </summary>
/// <param name="rx">The X coordinate of the terrain mask</param> /// <param name="rx">The X coordinate of the terrain mask</param>
/// <param name="ry">The Y coordinate of the terrain mask</param> /// <param name="ry">The Y coordinate of the terrain mask</param>
/// <param name="size">The size of the terrain mask</param> /// <param name="size">The size of the terrain mask</param>
/// <param name="amount">The scale of the terrain mask</param> /// <param name="amount">The scale of the terrain mask</param>
public void Flatten(double rx, double ry, double size, double amount) public void Flatten(double rx, double ry, double size, double amount)
{ {
FlattenSlow(rx, ry, size, amount); FlattenSlow(rx, ry, size, amount);
} }
private void FlattenSlow(double rx, double ry, double size, double amount) private void FlattenSlow(double rx, double ry, double size, double amount)
{ {
// Generate the mask // Generate the mask
Channel temp = new Channel(w, h); Channel temp = new Channel(w, h);
temp.Fill(0); temp.Fill(0);
temp.Raise(rx, ry, size, amount); temp.Raise(rx, ry, size, amount);
temp.Normalise(); temp.Normalise();
double total_mod = temp.Sum(); double total_mod = temp.Sum();
// Establish the average height under the area // Establish the average height under the area
Channel newmap = new Channel(w, h); Channel newmap = new Channel(w, h);
newmap.map = (double[,])map.Clone(); newmap.map = (double[,])map.Clone();
newmap *= temp; newmap *= temp;
double total_terrain = newmap.Sum(); double total_terrain = newmap.Sum();
double avg_height = total_terrain / total_mod; double avg_height = total_terrain / total_mod;
// Create a flat terrain using the average height // Create a flat terrain using the average height
Channel flat = new Channel(w, h); Channel flat = new Channel(w, h);
flat.Fill(avg_height); flat.Fill(avg_height);
// Blend the current terrain with the average height terrain // Blend the current terrain with the average height terrain
// using the "raised" empty terrain as a mask // using the "raised" empty terrain as a mask
Blend(flat, temp); Blend(flat, temp);
} }
private void FlattenFast(double rx, double ry, double size, double amount) private void FlattenFast(double rx, double ry, double size, double amount)
{ {
int x, y; int x, y;
double avg = 0; double avg = 0;
double div = 0; double div = 0;
int minX = Math.Max(0, (int)(rx - (size + 1))); int minX = Math.Max(0, (int)(rx - (size + 1)));
int maxX = Math.Min(w, (int)(rx + (size + 1))); int maxX = Math.Min(w, (int)(rx + (size + 1)));
int minY = Math.Max(0, (int)(ry - (size + 1))); int minY = Math.Max(0, (int)(ry - (size + 1)));
int maxY = Math.Min(h, (int)(ry + (size + 1))); int maxY = Math.Min(h, (int)(ry + (size + 1)));
for (x = minX; x < maxX; x++) for (x = minX; x < maxX; x++)
{ {
for (y = minY; y < maxY; y++) for (y = minY; y < maxY; y++)
{ {
double z = size; double z = size;
z *= z; z *= z;
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
if (z < 0) if (z < 0)
z = 0; z = 0;
avg += z * amount; avg += z * amount;
div += z; div += z;
} }
} }
double height = avg / div; double height = avg / div;
for (x = minX; x < maxX; x++) for (x = minX; x < maxX; x++)
{ {
for (y = minY; y < maxY; y++) for (y = minY; y < maxY; y++)
{ {
double z = size; double z = size;
z *= z; z *= z;
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
if (z < 0) if (z < 0)
z = 0; z = 0;
Set(x, y, Tools.linearInterpolate(map[x, y], height, z)); Set(x, y, Tools.linearInterpolate(map[x, y], height, z));
} }
} }
} }
public void Flatten(Channel mask, double amount) public void Flatten(Channel mask, double amount)
{ {
// Generate the mask // Generate the mask
Channel temp = mask * amount; Channel temp = mask * amount;
temp.Clip(0, 1); // Cut off out-of-bounds values temp.Clip(0, 1); // Cut off out-of-bounds values
double total_mod = temp.Sum(); double total_mod = temp.Sum();
// Establish the average height under the area // Establish the average height under the area
Channel map = new Channel(w, h); Channel map = new Channel(w, h);
map.map = (double[,])this.map.Clone(); map.map = (double[,])this.map.Clone();
map *= temp; map *= temp;
double total_terrain = map.Sum(); double total_terrain = map.Sum();
double avg_height = total_terrain / total_mod; double avg_height = total_terrain / total_mod;
// Create a flat terrain using the average height // Create a flat terrain using the average height
Channel flat = new Channel(w, h); Channel flat = new Channel(w, h);
flat.Fill(avg_height); flat.Fill(avg_height);
// Blend the current terrain with the average height terrain // Blend the current terrain with the average height terrain
// using the "raised" empty terrain as a mask // using the "raised" empty terrain as a mask
Blend(flat, temp); Blend(flat, temp);
} }
} }
} }

View File

@ -1,139 +1,139 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
/// <summary> /// <summary>
/// Raises land around the selection /// Raises land around the selection
/// </summary> /// </summary>
/// <param name="rx">The center the X coordinate of where you wish to raise the land</param> /// <param name="rx">The center the X coordinate of where you wish to raise the land</param>
/// <param name="ry">The center the Y coordinate of where you wish to raise the land</param> /// <param name="ry">The center the Y coordinate of where you wish to raise the land</param>
/// <param name="size">The radius of the dimple</param> /// <param name="size">The radius of the dimple</param>
/// <param name="amount">How much impact to add to the terrain (0..2 usually)</param> /// <param name="amount">How much impact to add to the terrain (0..2 usually)</param>
public void Raise(double rx, double ry, double size, double amount) public void Raise(double rx, double ry, double size, double amount)
{ {
RaiseSphere(rx, ry, size, amount); RaiseSphere(rx, ry, size, amount);
} }
/// <summary> /// <summary>
/// Raises land in a sphere around the selection /// Raises land in a sphere around the selection
/// </summary> /// </summary>
/// <param name="rx">The center the X coordinate of where you wish to raise the land</param> /// <param name="rx">The center the X coordinate of where you wish to raise the land</param>
/// <param name="ry">The center the Y coordinate of where you wish to raise the land</param> /// <param name="ry">The center the Y coordinate of where you wish to raise the land</param>
/// <param name="size">The radius of the sphere dimple</param> /// <param name="size">The radius of the sphere dimple</param>
/// <param name="amount">How much impact to add to the terrain (0..2 usually)</param> /// <param name="amount">How much impact to add to the terrain (0..2 usually)</param>
public void RaiseSphere(double rx, double ry, double size, double amount) public void RaiseSphere(double rx, double ry, double size, double amount)
{ {
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
double z = size; double z = size;
z *= z; z *= z;
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
if (z < 0) if (z < 0)
z = 0; z = 0;
Set(x, y, map[x, y] + (z * amount)); Set(x, y, map[x, y] + (z * amount));
} }
} }
} }
/// <summary> /// <summary>
/// Raises land in a cone around the selection /// Raises land in a cone around the selection
/// </summary> /// </summary>
/// <param name="rx">The center the X coordinate of where you wish to raise the land</param> /// <param name="rx">The center the X coordinate of where you wish to raise the land</param>
/// <param name="ry">The center the Y coordinate of where you wish to raise the land</param> /// <param name="ry">The center the Y coordinate of where you wish to raise the land</param>
/// <param name="size">The radius of the cone</param> /// <param name="size">The radius of the cone</param>
/// <param name="amount">How much impact to add to the terrain (0..2 usually)</param> /// <param name="amount">How much impact to add to the terrain (0..2 usually)</param>
public void RaiseCone(double rx, double ry, double size, double amount) public void RaiseCone(double rx, double ry, double size, double amount)
{ {
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
double z = size; double z = size;
z -= Math.Sqrt(((x - rx) * (x - rx)) + ((y - ry) * (y - ry))); z -= Math.Sqrt(((x - rx) * (x - rx)) + ((y - ry) * (y - ry)));
if (z < 0) if (z < 0)
z = 0; z = 0;
Set(x, y, map[x, y] + (z * amount)); Set(x, y, map[x, y] + (z * amount));
} }
} }
} }
/// <summary> /// <summary>
/// Lowers land in a sphere around the selection /// Lowers land in a sphere around the selection
/// </summary> /// </summary>
/// <param name="rx">The center the X coordinate of where you wish to lower the land</param> /// <param name="rx">The center the X coordinate of where you wish to lower the land</param>
/// <param name="ry">The center the Y coordinate of where you wish to lower the land</param> /// <param name="ry">The center the Y coordinate of where you wish to lower the land</param>
/// <param name="size">The radius of the sphere dimple</param> /// <param name="size">The radius of the sphere dimple</param>
/// <param name="amount">How much impact to remove from the terrain (0..2 usually)</param> /// <param name="amount">How much impact to remove from the terrain (0..2 usually)</param>
public void Lower(double rx, double ry, double size, double amount) public void Lower(double rx, double ry, double size, double amount)
{ {
LowerSphere(rx, ry, size, amount); LowerSphere(rx, ry, size, amount);
} }
/// <summary> /// <summary>
/// Lowers land in a sphere around the selection /// Lowers land in a sphere around the selection
/// </summary> /// </summary>
/// <param name="rx">The center the X coordinate of where you wish to lower the land</param> /// <param name="rx">The center the X coordinate of where you wish to lower the land</param>
/// <param name="ry">The center the Y coordinate of where you wish to lower the land</param> /// <param name="ry">The center the Y coordinate of where you wish to lower the land</param>
/// <param name="size">The radius of the sphere dimple</param> /// <param name="size">The radius of the sphere dimple</param>
/// <param name="amount">How much impact to remove from the terrain (0..2 usually)</param> /// <param name="amount">How much impact to remove from the terrain (0..2 usually)</param>
public void LowerSphere(double rx, double ry, double size, double amount) public void LowerSphere(double rx, double ry, double size, double amount)
{ {
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
double z = size; double z = size;
z *= z; z *= z;
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
if (z < 0) if (z < 0)
z = 0; z = 0;
Set(x, y, map[x, y] - (z * amount)); Set(x, y, map[x, y] - (z * amount));
} }
} }
} }
} }
} }

View File

@ -1,77 +1,77 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Drawing; using System.Drawing;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
public Channel LoadImage(string filename) public Channel LoadImage(string filename)
{ {
SetDiff(); SetDiff();
Bitmap bit = new Bitmap(filename); Bitmap bit = new Bitmap(filename);
Channel chan = new Channel(bit.Width, bit.Height); Channel chan = new Channel(bit.Width, bit.Height);
int x, y; int x, y;
for (x = 0; x < bit.Width; x++) for (x = 0; x < bit.Width; x++)
{ {
for (y = 0; y < bit.Height; y++) for (y = 0; y < bit.Height; y++)
{ {
Color val = bit.GetPixel(x, y); Color val = bit.GetPixel(x, y);
chan.map[x, y] = (((double)val.R + (double)val.G + (double)val.B) / 3.0) / 255.0; chan.map[x, y] = (((double)val.R + (double)val.G + (double)val.B) / 3.0) / 255.0;
} }
} }
return chan; return chan;
} }
public void SaveImage(string filename) public void SaveImage(string filename)
{ {
Channel outmap = this.Copy(); Channel outmap = this.Copy();
outmap.Normalise(); outmap.Normalise();
Bitmap bit = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format24bppRgb); Bitmap bit = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
int val = Math.Min(255, (int)(outmap.map[x,y] * 255)); int val = Math.Min(255, (int)(outmap.map[x,y] * 255));
Color col = Color.FromArgb(val,val,val); Color col = Color.FromArgb(val,val,val);
bit.SetPixel(x, y, col); bit.SetPixel(x, y, col);
} }
} }
bit.Save(filename); bit.Save(filename);
} }
} }
} }

View File

@ -1,145 +1,145 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
/// <summary> /// <summary>
/// Produces a set of coordinates defined by an edge point. Eg - 0 = 0,0. 256 = 0,256. 512 = 256,256 /// Produces a set of coordinates defined by an edge point. Eg - 0 = 0,0. 256 = 0,256. 512 = 256,256
/// Assumes a 256^2 heightmap. This needs fixing for input values of w,h /// Assumes a 256^2 heightmap. This needs fixing for input values of w,h
/// </summary> /// </summary>
/// <param name="val"></param> /// <param name="val"></param>
/// <param name="w"></param> /// <param name="w"></param>
/// <param name="h"></param> /// <param name="h"></param>
/// <returns></returns> /// <returns></returns>
private int[] RadialEdge256(int val) private int[] RadialEdge256(int val)
{ {
// Four cases: // Four cases:
// 1. 000..255 return 0,val // 1. 000..255 return 0,val
// 2. 256..511 return val - 256,255 // 2. 256..511 return val - 256,255
// 3. 512..767 return 255, val - 511 // 3. 512..767 return 255, val - 511
// 4. 768..1023 return val - 768,0 // 4. 768..1023 return val - 768,0
int[] ret = new int[2]; int[] ret = new int[2];
if (val < 256) if (val < 256)
{ {
ret[0] = 0; ret[0] = 0;
ret[1] = val; ret[1] = val;
return ret; return ret;
} }
if (val < 512) if (val < 512)
{ {
ret[0] = (val % 256); ret[0] = (val % 256);
ret[1] = 255; ret[1] = 255;
return ret; return ret;
} }
if (val < 768) if (val < 768)
{ {
ret[0] = 255; ret[0] = 255;
ret[1] = 255 - (val % 256); ret[1] = 255 - (val % 256);
return ret; return ret;
} }
if (val < 1024) if (val < 1024)
{ {
ret[0] = 255 - (val % 256); ret[0] = 255 - (val % 256);
ret[1] = 255; ret[1] = 255;
return ret; return ret;
} }
throw new Exception("Out of bounds parameter (val)"); throw new Exception("Out of bounds parameter (val)");
} }
public void Fracture(int number, double scalemin, double scalemax) public void Fracture(int number, double scalemin, double scalemax)
{ {
SetDiff(); SetDiff();
Random rand = new Random(seed); Random rand = new Random(seed);
for (int i = 0; i < number; i++) for (int i = 0; i < number; i++)
{ {
int[] a, b; int[] a, b;
a = RadialEdge256(rand.Next(1023)); // TODO: Broken a = RadialEdge256(rand.Next(1023)); // TODO: Broken
b = RadialEdge256(rand.Next(1023)); // TODO: Broken b = RadialEdge256(rand.Next(1023)); // TODO: Broken
double z = rand.NextDouble(); double z = rand.NextDouble();
double u = rand.NextDouble(); double u = rand.NextDouble();
double v = rand.NextDouble(); double v = rand.NextDouble();
for (int x = 0; x < w; x++) for (int x = 0; x < w; x++)
{ {
for (int y = 0; y < h; y++) for (int y = 0; y < h; y++)
{ {
double miny = Tools.linearInterpolate(a[1], b[1], (double)x / (double)w); double miny = Tools.linearInterpolate(a[1], b[1], (double)x / (double)w);
if (v >= 0.5) if (v >= 0.5)
{ {
if (u >= 0.5) if (u >= 0.5)
{ {
if (y > miny) if (y > miny)
{ {
map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z); map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z);
} }
} }
else else
{ {
if (y < miny) if (y < miny)
{ {
map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z); map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z);
} }
} }
} }
else else
{ {
if (u >= 0.5) if (u >= 0.5)
{ {
if (x > miny) if (x > miny)
{ {
map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z); map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z);
} }
} }
else else
{ {
if (x < miny) if (x < miny)
{ {
map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z); map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z);
} }
} }
} }
} }
} }
} }
Normalise(); Normalise();
} }
} }
} }

View File

@ -1,66 +1,66 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
public void GradientCube() public void GradientCube()
{ {
SetDiff(); SetDiff();
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
map[x, y] = x*y; map[x, y] = x*y;
} }
} }
Normalise(); Normalise();
} }
public void GradientStripe() public void GradientStripe()
{ {
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
map[x, y] = x; map[x, y] = x;
} }
} }
Normalise(); Normalise();
} }
} }
} }

View File

@ -1,283 +1,283 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
/// <summary> /// <summary>
/// Generates a series of spheres which are then either max()'d or added together. Inspired by suggestion from jh. /// Generates a series of spheres which are then either max()'d or added together. Inspired by suggestion from jh.
/// </summary> /// </summary>
/// <remarks>3-Clause BSD Licensed</remarks> /// <remarks>3-Clause BSD Licensed</remarks>
/// <param name="number">The number of hills to generate</param> /// <param name="number">The number of hills to generate</param>
/// <param name="scale_min">The minimum size of each hill</param> /// <param name="scale_min">The minimum size of each hill</param>
/// <param name="scale_range">The maximum size of each hill</param> /// <param name="scale_range">The maximum size of each hill</param>
/// <param name="island">Whether to bias hills towards the center of the map</param> /// <param name="island">Whether to bias hills towards the center of the map</param>
/// <param name="additive">Whether to add hills together or to pick the largest value</param> /// <param name="additive">Whether to add hills together or to pick the largest value</param>
/// <param name="noisy">Generates hill-shaped noise instead of consistent hills</param> /// <param name="noisy">Generates hill-shaped noise instead of consistent hills</param>
public void HillsSpheres(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy) public void HillsSpheres(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy)
{ {
SetDiff(); SetDiff();
Random random = new Random(seed); Random random = new Random(seed);
int x, y; int x, y;
int i; int i;
for (i = 0; i < number; i++) for (i = 0; i < number; i++)
{ {
double rx = Math.Min(255.0, random.NextDouble() * w); double rx = Math.Min(255.0, random.NextDouble() * w);
double ry = Math.Min(255.0, random.NextDouble() * h); double ry = Math.Min(255.0, random.NextDouble() * h);
double rand = random.NextDouble(); double rand = random.NextDouble();
if (island) if (island)
{ {
// Move everything towards the center // Move everything towards the center
rx -= w / 2; rx -= w / 2;
rx /= 2; rx /= 2;
rx += w / 2; rx += w / 2;
ry -= h / 2; ry -= h / 2;
ry /= 2; ry /= 2;
ry += h / 2; ry += h / 2;
} }
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (noisy) if (noisy)
rand = random.NextDouble(); rand = random.NextDouble();
double z = (scale_min + (scale_range * rand)); double z = (scale_min + (scale_range * rand));
z *= z; z *= z;
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
if (z < 0) if (z < 0)
z = 0; z = 0;
if (additive) if (additive)
{ {
map[x, y] += z; map[x, y] += z;
} }
else else
{ {
map[x, y] = Math.Max(map[x, y], z); map[x, y] = Math.Max(map[x, y], z);
} }
} }
} }
} }
Normalise(); Normalise();
} }
/// <summary> /// <summary>
/// Generates a series of cones which are then either max()'d or added together. Inspired by suggestion from jh. /// Generates a series of cones which are then either max()'d or added together. Inspired by suggestion from jh.
/// </summary> /// </summary>
/// <remarks>3-Clause BSD Licensed</remarks> /// <remarks>3-Clause BSD Licensed</remarks>
/// <param name="number">The number of hills to generate</param> /// <param name="number">The number of hills to generate</param>
/// <param name="scale_min">The minimum size of each hill</param> /// <param name="scale_min">The minimum size of each hill</param>
/// <param name="scale_range">The maximum size of each hill</param> /// <param name="scale_range">The maximum size of each hill</param>
/// <param name="island">Whether to bias hills towards the center of the map</param> /// <param name="island">Whether to bias hills towards the center of the map</param>
/// <param name="additive">Whether to add hills together or to pick the largest value</param> /// <param name="additive">Whether to add hills together or to pick the largest value</param>
/// <param name="noisy">Generates hill-shaped noise instead of consistent hills</param> /// <param name="noisy">Generates hill-shaped noise instead of consistent hills</param>
public void HillsCones(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy) public void HillsCones(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy)
{ {
SetDiff(); SetDiff();
Random random = new Random(seed); Random random = new Random(seed);
int x, y; int x, y;
int i; int i;
for (i = 0; i < number; i++) for (i = 0; i < number; i++)
{ {
double rx = Math.Min(255.0, random.NextDouble() * w); double rx = Math.Min(255.0, random.NextDouble() * w);
double ry = Math.Min(255.0, random.NextDouble() * h); double ry = Math.Min(255.0, random.NextDouble() * h);
double rand = random.NextDouble(); double rand = random.NextDouble();
if (island) if (island)
{ {
// Move everything towards the center // Move everything towards the center
rx -= w / 2; rx -= w / 2;
rx /= 2; rx /= 2;
rx += w / 2; rx += w / 2;
ry -= h / 2; ry -= h / 2;
ry /= 2; ry /= 2;
ry += h / 2; ry += h / 2;
} }
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (noisy) if (noisy)
rand = random.NextDouble(); rand = random.NextDouble();
double z = (scale_min + (scale_range * rand)); double z = (scale_min + (scale_range * rand));
z -= Math.Sqrt(((x - rx) * (x - rx)) + ((y - ry) * (y - ry))); z -= Math.Sqrt(((x - rx) * (x - rx)) + ((y - ry) * (y - ry)));
if (z < 0) if (z < 0)
z = 0; z = 0;
if (additive) if (additive)
{ {
map[x, y] += z; map[x, y] += z;
} }
else else
{ {
map[x, y] = Math.Max(map[x, y], z); map[x, y] = Math.Max(map[x, y], z);
} }
} }
} }
} }
Normalise(); Normalise();
} }
public void HillsBlocks(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy) public void HillsBlocks(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy)
{ {
SetDiff(); SetDiff();
Random random = new Random(seed); Random random = new Random(seed);
int x, y; int x, y;
int i; int i;
for (i = 0; i < number; i++) for (i = 0; i < number; i++)
{ {
double rx = Math.Min(255.0, random.NextDouble() * w); double rx = Math.Min(255.0, random.NextDouble() * w);
double ry = Math.Min(255.0, random.NextDouble() * h); double ry = Math.Min(255.0, random.NextDouble() * h);
double rand = random.NextDouble(); double rand = random.NextDouble();
if (island) if (island)
{ {
// Move everything towards the center // Move everything towards the center
rx -= w / 2; rx -= w / 2;
rx /= 2; rx /= 2;
rx += w / 2; rx += w / 2;
ry -= h / 2; ry -= h / 2;
ry /= 2; ry /= 2;
ry += h / 2; ry += h / 2;
} }
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (noisy) if (noisy)
rand = random.NextDouble(); rand = random.NextDouble();
double z = (scale_min + (scale_range * rand)); double z = (scale_min + (scale_range * rand));
z -= Math.Abs(x-rx) + Math.Abs(y-ry); z -= Math.Abs(x-rx) + Math.Abs(y-ry);
//z -= Math.Sqrt(((x - rx) * (x - rx)) + ((y - ry) * (y - ry))); //z -= Math.Sqrt(((x - rx) * (x - rx)) + ((y - ry) * (y - ry)));
if (z < 0) if (z < 0)
z = 0; z = 0;
if (additive) if (additive)
{ {
map[x, y] += z; map[x, y] += z;
} }
else else
{ {
map[x, y] = Math.Max(map[x, y], z); map[x, y] = Math.Max(map[x, y], z);
} }
} }
} }
} }
Normalise(); Normalise();
} }
public void HillsSquared(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy) public void HillsSquared(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy)
{ {
SetDiff(); SetDiff();
Random random = new Random(seed); Random random = new Random(seed);
int x, y; int x, y;
int i; int i;
for (i = 0; i < number; i++) for (i = 0; i < number; i++)
{ {
double rx = Math.Min(255.0, random.NextDouble() * w); double rx = Math.Min(255.0, random.NextDouble() * w);
double ry = Math.Min(255.0, random.NextDouble() * h); double ry = Math.Min(255.0, random.NextDouble() * h);
double rand = random.NextDouble(); double rand = random.NextDouble();
if (island) if (island)
{ {
// Move everything towards the center // Move everything towards the center
rx -= w / 2; rx -= w / 2;
rx /= 2; rx /= 2;
rx += w / 2; rx += w / 2;
ry -= h / 2; ry -= h / 2;
ry /= 2; ry /= 2;
ry += h / 2; ry += h / 2;
} }
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (noisy) if (noisy)
rand = random.NextDouble(); rand = random.NextDouble();
double z = (scale_min + (scale_range * rand)); double z = (scale_min + (scale_range * rand));
z *= z * z * z; z *= z * z * z;
double dx = Math.Abs(x - rx); double dx = Math.Abs(x - rx);
double dy = Math.Abs(y - ry); double dy = Math.Abs(y - ry);
z -= (dx * dx * dx * dx) + (dy * dy * dy * dy); z -= (dx * dx * dx * dx) + (dy * dy * dy * dy);
if (z < 0) if (z < 0)
z = 0; z = 0;
if (additive) if (additive)
{ {
map[x, y] += z; map[x, y] += z;
} }
else else
{ {
map[x, y] = Math.Max(map[x, y], z); map[x, y] = Math.Max(map[x, y], z);
} }
} }
} }
} }
Normalise(); Normalise();
} }
} }
} }

View File

@ -1,56 +1,56 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
/// <summary> /// <summary>
/// Fills a channel with 0..1 noise /// Fills a channel with 0..1 noise
/// </summary> /// </summary>
/// <remarks>3-Clause BSD Licensed</remarks> /// <remarks>3-Clause BSD Licensed</remarks>
public void Noise() public void Noise()
{ {
SetDiff(); SetDiff();
Random rand = new Random(seed); Random rand = new Random(seed);
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
map[x, y] = rand.NextDouble(); map[x, y] = rand.NextDouble();
} }
} }
} }
} }
} }

View File

@ -1,156 +1,156 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
private double[] CoordinatesToPolar(int x, int y) private double[] CoordinatesToPolar(int x, int y)
{ {
double theta = Math.Atan2(x - (w / 2), y - (h / 2)); double theta = Math.Atan2(x - (w / 2), y - (h / 2));
double rx = (double)x - ((double)w / 2); double rx = (double)x - ((double)w / 2);
double ry = (double)y - ((double)h / 2); double ry = (double)y - ((double)h / 2);
double r = Math.Sqrt((rx * rx) + (ry * ry)); double r = Math.Sqrt((rx * rx) + (ry * ry));
double[] coords = new double[2]; double[] coords = new double[2];
coords[0] = r; coords[0] = r;
coords[1] = theta; coords[1] = theta;
return coords; return coords;
} }
public int[] PolarToCoordinates(double r, double theta) { public int[] PolarToCoordinates(double r, double theta) {
double nx; double nx;
double ny; double ny;
nx = (double)r * Math.Cos(theta); nx = (double)r * Math.Cos(theta);
ny = (double)r * Math.Sin(theta); ny = (double)r * Math.Sin(theta);
nx += w / 2; nx += w / 2;
ny += h / 2; ny += h / 2;
if (nx >= w) if (nx >= w)
nx = w - 1; nx = w - 1;
if (ny >= h) if (ny >= h)
ny = h - 1; ny = h - 1;
if (nx < 0) if (nx < 0)
nx = 0; nx = 0;
if (ny < 0) if (ny < 0)
ny = 0; ny = 0;
int[] coords = new int[2]; int[] coords = new int[2];
coords[0] = (int)nx; coords[0] = (int)nx;
coords[1] = (int)ny; coords[1] = (int)ny;
return coords; return coords;
} }
public void Polar() public void Polar()
{ {
SetDiff(); SetDiff();
Channel n = this.Copy(); Channel n = this.Copy();
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
double[] coords = CoordinatesToPolar(x,y); double[] coords = CoordinatesToPolar(x,y);
coords[0] += w / 2.0; coords[0] += w / 2.0;
coords[1] += h / 2.0; coords[1] += h / 2.0;
map[x, y] = n.map[(int)coords[0] % n.w, (int)coords[1] % n.h]; map[x, y] = n.map[(int)coords[0] % n.w, (int)coords[1] % n.h];
} }
} }
} }
public void SpiralPlanter(int steps, double incAngle, double incRadius, double offsetRadius, double offsetAngle) public void SpiralPlanter(int steps, double incAngle, double incRadius, double offsetRadius, double offsetAngle)
{ {
SetDiff(); SetDiff();
int i; int i;
double r = offsetRadius; double r = offsetRadius;
double theta = offsetAngle; double theta = offsetAngle;
for (i = 0; i < steps; i++) for (i = 0; i < steps; i++)
{ {
r += incRadius; r += incRadius;
theta += incAngle; theta += incAngle;
int[] coords = PolarToCoordinates(r,theta); int[] coords = PolarToCoordinates(r,theta);
Raise(coords[0], coords[1], 20, 1); Raise(coords[0], coords[1], 20, 1);
} }
} }
public void SpiralCells(int steps, double incAngle, double incRadius, double offsetRadius, double offsetAngle, double[] c) public void SpiralCells(int steps, double incAngle, double incRadius, double offsetRadius, double offsetAngle, double[] c)
{ {
SetDiff(); SetDiff();
List<Point2D> points = new List<Point2D>(); List<Point2D> points = new List<Point2D>();
int i; int i;
double r = offsetRadius; double r = offsetRadius;
double theta = offsetAngle; double theta = offsetAngle;
for (i = 0; i < steps; i++) for (i = 0; i < steps; i++)
{ {
r += incRadius; r += incRadius;
theta += incAngle; theta += incAngle;
int[] coords = PolarToCoordinates(r, theta); int[] coords = PolarToCoordinates(r, theta);
points.Add(new Point2D(coords[0],coords[1])); points.Add(new Point2D(coords[0],coords[1]));
} }
VoronoiDiagram(points, c); VoronoiDiagram(points, c);
} }
public void Spiral(double wid, double hig, double offset) public void Spiral(double wid, double hig, double offset)
{ {
SetDiff(); SetDiff();
int x, y, z; int x, y, z;
z = 0; z = 0;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
z++; z++;
double dx = Math.Abs((w / 2) - x); double dx = Math.Abs((w / 2) - x);
double dy = Math.Abs((h / 2) - y); double dy = Math.Abs((h / 2) - y);
map[x, y] += Math.Sin(dx / wid) + Math.Cos(dy / hig); map[x, y] += Math.Sin(dx / wid) + Math.Cos(dy / hig);
} }
} }
Normalise(); Normalise();
} }
} }
} }

View File

@ -1,214 +1,214 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
/// <summary> /// <summary>
/// Generates a Voronoi diagram (sort of a stained glass effect) which will fill the entire channel /// Generates a Voronoi diagram (sort of a stained glass effect) which will fill the entire channel
/// </summary> /// </summary>
/// <remarks>3-Clause BSD Licensed</remarks> /// <remarks>3-Clause BSD Licensed</remarks>
/// <param name="pointsPerBlock">The number of generator points in each block</param> /// <param name="pointsPerBlock">The number of generator points in each block</param>
/// <param name="blockSize">A multiple of the channel width and height which will have voronoi points generated in it. /// <param name="blockSize">A multiple of the channel width and height which will have voronoi points generated in it.
/// <para>This is to ensure a more even distribution of the points than pure random allocation.</para></param> /// <para>This is to ensure a more even distribution of the points than pure random allocation.</para></param>
/// <param name="c">The Voronoi diagram type. Usually an array with values consisting of [-1,1]. Experiment with the chain, you can have as many values as you like.</param> /// <param name="c">The Voronoi diagram type. Usually an array with values consisting of [-1,1]. Experiment with the chain, you can have as many values as you like.</param>
public void VoronoiDiagram(int pointsPerBlock, int blockSize, double[] c) public void VoronoiDiagram(int pointsPerBlock, int blockSize, double[] c)
{ {
SetDiff(); SetDiff();
List<Point2D> points = new List<Point2D>(); List<Point2D> points = new List<Point2D>();
Random generator = new Random(seed); Random generator = new Random(seed);
// Generate the emitter points // Generate the emitter points
int x, y, i; int x, y, i;
for (x = -blockSize; x < w + blockSize; x += blockSize) for (x = -blockSize; x < w + blockSize; x += blockSize)
{ {
for (y = -blockSize; y < h + blockSize; y += blockSize) for (y = -blockSize; y < h + blockSize; y += blockSize)
{ {
for (i = 0; i < pointsPerBlock; i++) for (i = 0; i < pointsPerBlock; i++)
{ {
double pX = x + (generator.NextDouble() * (double)blockSize); double pX = x + (generator.NextDouble() * (double)blockSize);
double pY = y + (generator.NextDouble() * (double)blockSize); double pY = y + (generator.NextDouble() * (double)blockSize);
points.Add(new Point2D(pX, pY)); points.Add(new Point2D(pX, pY));
} }
} }
} }
double[] distances = new double[points.Count]; double[] distances = new double[points.Count];
// Calculate the distance each pixel is from an emitter // Calculate the distance each pixel is from an emitter
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
for (i = 0; i < points.Count; i++) for (i = 0; i < points.Count; i++)
{ {
double dx, dy; double dx, dy;
dx = Math.Abs((double)x - points[i].x); dx = Math.Abs((double)x - points[i].x);
dy = Math.Abs((double)y - points[i].y); dy = Math.Abs((double)y - points[i].y);
distances[i] = (dx * dx + dy * dy); distances[i] = (dx * dx + dy * dy);
} }
Array.Sort(distances); Array.Sort(distances);
double f = 0.0; double f = 0.0;
// Multiply the distances with their 'c' counterpart // Multiply the distances with their 'c' counterpart
// ordering the distances descending // ordering the distances descending
for (i = 0; i < c.Length; i++) for (i = 0; i < c.Length; i++)
{ {
if (i >= points.Count) if (i >= points.Count)
break; break;
f += c[i] * distances[i]; f += c[i] * distances[i];
} }
map[x, y] = f; map[x, y] = f;
} }
} }
// Normalise the result // Normalise the result
Normalise(); Normalise();
} }
public void VoronoiDiagram(List<Point2D> points, double[] c) public void VoronoiDiagram(List<Point2D> points, double[] c)
{ {
SetDiff(); SetDiff();
Random generator = new Random(seed); Random generator = new Random(seed);
int x, y, i; int x, y, i;
double[] distances = new double[points.Count]; double[] distances = new double[points.Count];
// Calculate the distance each pixel is from an emitter // Calculate the distance each pixel is from an emitter
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
for (i = 0; i < points.Count; i++) for (i = 0; i < points.Count; i++)
{ {
double dx, dy; double dx, dy;
dx = Math.Abs((double)x - points[i].x); dx = Math.Abs((double)x - points[i].x);
dy = Math.Abs((double)y - points[i].y); dy = Math.Abs((double)y - points[i].y);
distances[i] = (dx * dx + dy * dy); distances[i] = (dx * dx + dy * dy);
} }
Array.Sort(distances); Array.Sort(distances);
double f = 0.0; double f = 0.0;
// Multiply the distances with their 'c' counterpart // Multiply the distances with their 'c' counterpart
// ordering the distances descending // ordering the distances descending
for (i = 0; i < c.Length; i++) for (i = 0; i < c.Length; i++)
{ {
if (i >= points.Count) if (i >= points.Count)
break; break;
f += c[i] * distances[i]; f += c[i] * distances[i];
} }
map[x, y] = f; map[x, y] = f;
} }
} }
// Normalise the result // Normalise the result
Normalise(); Normalise();
} }
public void VoroflatDiagram(int pointsPerBlock, int blockSize) public void VoroflatDiagram(int pointsPerBlock, int blockSize)
{ {
SetDiff(); SetDiff();
List<Point2D> points = new List<Point2D>(); List<Point2D> points = new List<Point2D>();
Random generator = new Random(seed); Random generator = new Random(seed);
// Generate the emitter points // Generate the emitter points
int x, y, i; int x, y, i;
for (x = -blockSize; x < w + blockSize; x += blockSize) for (x = -blockSize; x < w + blockSize; x += blockSize)
{ {
for (y = -blockSize; y < h + blockSize; y += blockSize) for (y = -blockSize; y < h + blockSize; y += blockSize)
{ {
for (i = 0; i < pointsPerBlock; i++) for (i = 0; i < pointsPerBlock; i++)
{ {
double pX = x + (generator.NextDouble() * (double)blockSize); double pX = x + (generator.NextDouble() * (double)blockSize);
double pY = y + (generator.NextDouble() * (double)blockSize); double pY = y + (generator.NextDouble() * (double)blockSize);
points.Add(new Point2D(pX, pY)); points.Add(new Point2D(pX, pY));
} }
} }
} }
double[] distances = new double[points.Count]; double[] distances = new double[points.Count];
// Calculate the distance each pixel is from an emitter // Calculate the distance each pixel is from an emitter
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
for (i = 0; i < points.Count; i++) for (i = 0; i < points.Count; i++)
{ {
double dx, dy; double dx, dy;
dx = Math.Abs((double)x - points[i].x); dx = Math.Abs((double)x - points[i].x);
dy = Math.Abs((double)y - points[i].y); dy = Math.Abs((double)y - points[i].y);
distances[i] = (dx * dx + dy * dy); distances[i] = (dx * dx + dy * dy);
} }
//Array.Sort(distances); //Array.Sort(distances);
double f = 0.0; double f = 0.0;
double min = double.MaxValue; double min = double.MaxValue;
for (int j = 0; j < distances.Length;j++ ) for (int j = 0; j < distances.Length;j++ )
{ {
if (distances[j] < min) if (distances[j] < min)
{ {
min = distances[j]; min = distances[j];
f = j; f = j;
} }
} }
// Multiply the distances with their 'c' counterpart // Multiply the distances with their 'c' counterpart
// ordering the distances descending // ordering the distances descending
map[x, y] = f; map[x, y] = f;
} }
} }
// Normalise the result // Normalise the result
Normalise(); Normalise();
} }
} }
} }

View File

@ -1,74 +1,74 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
/// <summary> /// <summary>
/// Generates 'number' of worms which navigate randomly around the landscape creating terrain as they go. /// Generates 'number' of worms which navigate randomly around the landscape creating terrain as they go.
/// </summary> /// </summary>
/// <param name="number">The number of worms which will traverse the map</param> /// <param name="number">The number of worms which will traverse the map</param>
/// <param name="rounds">The number of steps each worm will traverse</param> /// <param name="rounds">The number of steps each worm will traverse</param>
/// <param name="movement">The maximum distance each worm will move each step</param> /// <param name="movement">The maximum distance each worm will move each step</param>
/// <param name="size">The size of the area around the worm modified</param> /// <param name="size">The size of the area around the worm modified</param>
/// <param name="centerspawn">Do worms start in the middle, or randomly?</param> /// <param name="centerspawn">Do worms start in the middle, or randomly?</param>
public void Worms(int number, int rounds, double movement, double size, bool centerspawn) public void Worms(int number, int rounds, double movement, double size, bool centerspawn)
{ {
SetDiff(); SetDiff();
Random random = new Random(seed); Random random = new Random(seed);
int i, j; int i, j;
for (i = 0; i < number; i++) for (i = 0; i < number; i++)
{ {
double rx, ry; double rx, ry;
if (centerspawn) if (centerspawn)
{ {
rx = w / 2.0; rx = w / 2.0;
ry = h / 2.0; ry = h / 2.0;
} }
else else
{ {
rx = random.NextDouble() * (w - 1); rx = random.NextDouble() * (w - 1);
ry = random.NextDouble() * (h - 1); ry = random.NextDouble() * (h - 1);
} }
for (j = 0; j < rounds; j++) for (j = 0; j < rounds; j++)
{ {
rx += (random.NextDouble() * movement) - (movement / 2.0); rx += (random.NextDouble() * movement) - (movement / 2.0);
ry += (random.NextDouble() * movement) - (movement / 2.0); ry += (random.NextDouble() * movement) - (movement / 2.0);
Raise(rx, ry, size, 1.0); Raise(rx, ry, size, 1.0);
} }
} }
} }
} }
} }

View File

@ -1,350 +1,350 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
public Channel Normalise() public Channel Normalise()
{ {
SetDiff(); SetDiff();
double max = FindMax(); double max = FindMax();
double min = FindMin(); double min = FindMin();
int x, y; int x, y;
if (max != min) if (max != min)
{ {
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
map[x, y] = (map[x, y] - min) * (1.0 / (max - min)); map[x, y] = (map[x, y] - min) * (1.0 / (max - min));
} }
} }
} }
else else
{ {
this.Fill(0.5); this.Fill(0.5);
} }
return this; return this;
} }
public Channel Normalise(double minv, double maxv) public Channel Normalise(double minv, double maxv)
{ {
SetDiff(); SetDiff();
double max = FindMax(); double max = FindMax();
double min = FindMin(); double min = FindMin();
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
double val = (map[x, y] - min) * (1.0 / max - min); double val = (map[x, y] - min) * (1.0 / max - min);
val *= maxv - minv; val *= maxv - minv;
val += minv; val += minv;
map[x, y] = val; map[x, y] = val;
} }
} }
return this; return this;
} }
public Channel Clip() public Channel Clip()
{ {
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
SetClip(x, y, map[x, y]); SetClip(x, y, map[x, y]);
} }
} }
return this; return this;
} }
public Channel Clip(double min, double max) public Channel Clip(double min, double max)
{ {
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
double val = map[x, y]; double val = map[x, y];
if (val > max) val = max; if (val > max) val = max;
if (val < min) val = min; if (val < min) val = min;
Set(x, y, val); Set(x, y, val);
} }
} }
return this; return this;
} }
public Channel Crop(int x1, int y1, int x2, int y2) public Channel Crop(int x1, int y1, int x2, int y2)
{ {
int width = x1 - x2 + 1; int width = x1 - x2 + 1;
int height = y1 - y2 + 1; int height = y1 - y2 + 1;
Channel chan = new Channel(width, height); Channel chan = new Channel(width, height);
int x, y; int x, y;
int nx, ny; int nx, ny;
nx = 0; nx = 0;
for (x = x1; x < x2; x++) for (x = x1; x < x2; x++)
{ {
ny = 0; ny = 0;
for (y = y1; y < y2; y++) for (y = y1; y < y2; y++)
{ {
chan.map[nx, ny] = map[x, y]; chan.map[nx, ny] = map[x, y];
ny++; ny++;
} }
nx++; nx++;
} }
return this; return this;
} }
public Channel AddClip(Channel other) public Channel AddClip(Channel other)
{ {
SetDiff(); SetDiff();
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
map[x, y] = other.map[x, y]; map[x, y] = other.map[x, y];
if (map[x, y] > 1) if (map[x, y] > 1)
map[x, y] = 1; map[x, y] = 1;
if (map[x, y] < 0) if (map[x, y] < 0)
map[x, y] = 0; map[x, y] = 0;
} }
} }
return this; return this;
} }
public void Smooth(double amount) public void Smooth(double amount)
{ {
SetDiff(); SetDiff();
double area = amount; double area = amount;
double step = amount / 4.0; double step = amount / 4.0;
double[,] manipulate = new double[w, h]; double[,] manipulate = new double[w, h];
int x, y; int x, y;
double n, l; double n, l;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
double average = 0.0; double average = 0.0;
int avgsteps = 0; int avgsteps = 0;
for (n = 0.0 - area; n < area; n += step) for (n = 0.0 - area; n < area; n += step)
{ {
for (l = 0.0 - area; l < area; l += step) for (l = 0.0 - area; l < area; l += step)
{ {
avgsteps++; avgsteps++;
average += GetBilinearInterpolate(x + n, y + l); average += GetBilinearInterpolate(x + n, y + l);
} }
} }
manipulate[x, y] = average / avgsteps; manipulate[x, y] = average / avgsteps;
} }
} }
map = manipulate; map = manipulate;
} }
public void Pertubation(double amount) public void Pertubation(double amount)
{ {
SetDiff(); SetDiff();
// Simple pertubation filter // Simple pertubation filter
double[,] manipulated = new double[w, h]; double[,] manipulated = new double[w, h];
Random generator = new Random(seed); // Seeds FTW! Random generator = new Random(seed); // Seeds FTW!
//double amount = 8.0; //double amount = 8.0;
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
double offset_x = (double)x + (generator.NextDouble() * amount) - (amount / 2.0); double offset_x = (double)x + (generator.NextDouble() * amount) - (amount / 2.0);
double offset_y = (double)y + (generator.NextDouble() * amount) - (amount / 2.0); double offset_y = (double)y + (generator.NextDouble() * amount) - (amount / 2.0);
double p = GetBilinearInterpolate(offset_x, offset_y); double p = GetBilinearInterpolate(offset_x, offset_y);
manipulated[x, y] = p; manipulated[x, y] = p;
} }
} }
map = manipulated; map = manipulated;
} }
public void PertubationMask(Channel mask) public void PertubationMask(Channel mask)
{ {
// Simple pertubation filter // Simple pertubation filter
double[,] manipulated = new double[w, h]; double[,] manipulated = new double[w, h];
Random generator = new Random(seed); // Seeds FTW! Random generator = new Random(seed); // Seeds FTW!
//double amount = 8.0; //double amount = 8.0;
double amount; double amount;
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
amount = mask.map[x, y]; amount = mask.map[x, y];
double offset_x = (double)x + (generator.NextDouble() * amount) - (amount / 2.0); double offset_x = (double)x + (generator.NextDouble() * amount) - (amount / 2.0);
double offset_y = (double)y + (generator.NextDouble() * amount) - (amount / 2.0); double offset_y = (double)y + (generator.NextDouble() * amount) - (amount / 2.0);
if (offset_x > w) if (offset_x > w)
offset_x = w - 1; offset_x = w - 1;
if (offset_y > h) if (offset_y > h)
offset_y = h - 1; offset_y = h - 1;
if (offset_y < 0) if (offset_y < 0)
offset_y = 0; offset_y = 0;
if (offset_x < 0) if (offset_x < 0)
offset_x = 0; offset_x = 0;
double p = GetBilinearInterpolate(offset_x, offset_y); double p = GetBilinearInterpolate(offset_x, offset_y);
manipulated[x, y] = p; manipulated[x, y] = p;
SetDiff(x, y); SetDiff(x, y);
} }
} }
map = manipulated; map = manipulated;
} }
public void Distort(Channel mask, double str) public void Distort(Channel mask, double str)
{ {
// Simple pertubation filter // Simple pertubation filter
double[,] manipulated = new double[w, h]; double[,] manipulated = new double[w, h];
double amount; double amount;
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
amount = mask.map[x, y]; amount = mask.map[x, y];
double offset_x = (double)x + (amount * str) - (0.5 * str); double offset_x = (double)x + (amount * str) - (0.5 * str);
double offset_y = (double)y + (amount * str) - (0.5 * str); double offset_y = (double)y + (amount * str) - (0.5 * str);
if (offset_x > w) if (offset_x > w)
offset_x = w - 1; offset_x = w - 1;
if (offset_y > h) if (offset_y > h)
offset_y = h - 1; offset_y = h - 1;
if (offset_y < 0) if (offset_y < 0)
offset_y = 0; offset_y = 0;
if (offset_x < 0) if (offset_x < 0)
offset_x = 0; offset_x = 0;
double p = GetBilinearInterpolate(offset_x, offset_y); double p = GetBilinearInterpolate(offset_x, offset_y);
manipulated[x, y] = p; manipulated[x, y] = p;
SetDiff(x, y); SetDiff(x, y);
} }
} }
map = manipulated; map = manipulated;
} }
public void Distort(Channel mask, Channel mask2, double str) public void Distort(Channel mask, Channel mask2, double str)
{ {
// Simple pertubation filter // Simple pertubation filter
double[,] manipulated = new double[w, h]; double[,] manipulated = new double[w, h];
double amountX; double amountX;
double amountY; double amountY;
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
amountX = mask.map[x, y]; amountX = mask.map[x, y];
amountY = mask2.map[x, y]; amountY = mask2.map[x, y];
double offset_x = (double)x + (amountX * str) - (0.5 * str); double offset_x = (double)x + (amountX * str) - (0.5 * str);
double offset_y = (double)y + (amountY * str) - (0.5 * str); double offset_y = (double)y + (amountY * str) - (0.5 * str);
if (offset_x > w) if (offset_x > w)
offset_x = w - 1; offset_x = w - 1;
if (offset_y > h) if (offset_y > h)
offset_y = h - 1; offset_y = h - 1;
if (offset_y < 0) if (offset_y < 0)
offset_y = 0; offset_y = 0;
if (offset_x < 0) if (offset_x < 0)
offset_x = 0; offset_x = 0;
double p = GetBilinearInterpolate(offset_x, offset_y); double p = GetBilinearInterpolate(offset_x, offset_y);
manipulated[x, y] = p; manipulated[x, y] = p;
SetDiff(x, y); SetDiff(x, y);
} }
} }
map = manipulated; map = manipulated;
} }
public Channel Blend(Channel other, double amount) public Channel Blend(Channel other, double amount)
{ {
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
Set(x, y, Tools.linearInterpolate(map[x, y], other.map[x, y], amount)); Set(x, y, Tools.linearInterpolate(map[x, y], other.map[x, y], amount));
} }
} }
return this; return this;
} }
public Channel Blend(Channel other, Channel amount) public Channel Blend(Channel other, Channel amount)
{ {
int x, y; int x, y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
Set(x, y, Tools.linearInterpolate(map[x, y], other.map[x, y], amount.map[x, y])); Set(x, y, Tools.linearInterpolate(map[x, y], other.map[x, y], amount.map[x, y]));
} }
} }
return this; return this;
} }
} }
} }

View File

@ -1,213 +1,213 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
// Ideas for Aerobic erosion // Ideas for Aerobic erosion
// //
// Unlike thermal (gravity) and hydraulic (water suspension) // Unlike thermal (gravity) and hydraulic (water suspension)
// aerobic erosion should displace mass by moving sediment // aerobic erosion should displace mass by moving sediment
// in "hops". The length of the hop being dictated by the // in "hops". The length of the hop being dictated by the
// presence of sharp cliffs and wind speed. // presence of sharp cliffs and wind speed.
// The ability to pickup sediment is defined by the total // The ability to pickup sediment is defined by the total
// surface area, such that: // surface area, such that:
// 0 0 0 // 0 0 0
// 0 1 0 // 0 1 0
// 0 0 0 // 0 0 0
// Would be the best possible value for sediment to be // Would be the best possible value for sediment to be
// picked up (total difference = 8) and flatter land // picked up (total difference = 8) and flatter land
// will erode less quickly. // will erode less quickly.
// Suspended particles assist the erosion process by hitting // Suspended particles assist the erosion process by hitting
// the surface and chiselling additional particles off faster // the surface and chiselling additional particles off faster
// than alone. // than alone.
// Particles are deposited when one of two conditions is met // Particles are deposited when one of two conditions is met
// First: // First:
// When particles hit a wall - such that the // When particles hit a wall - such that the
// wind direction points at a difference >= the // wind direction points at a difference >= the
// deposition mininum talus. // deposition mininum talus.
// Second: // Second:
// When wind speed is lowered to below the minimum // When wind speed is lowered to below the minimum
// required for transit. An idea for this is to // required for transit. An idea for this is to
// use the navier-stokes algorithms for simulating // use the navier-stokes algorithms for simulating
// pressure across the terrain. // pressure across the terrain.
/// <summary> /// <summary>
/// An experimental erosion algorithm developed by Adam. Moves sediment by factoring the surface area of each height point. /// An experimental erosion algorithm developed by Adam. Moves sediment by factoring the surface area of each height point.
/// </summary> /// </summary>
/// <param name="windspeed">0..1 The speed of the wind</param> /// <param name="windspeed">0..1 The speed of the wind</param>
/// <param name="pickup_talus_minimum">The minimum angle at which rock is eroded 0..1 (recommended: <= 0.30)</param> /// <param name="pickup_talus_minimum">The minimum angle at which rock is eroded 0..1 (recommended: <= 0.30)</param>
/// <param name="drop_talus_minimum">The minimum angle at which rock is dropped 0..1 (recommended: >= 0.00)</param> /// <param name="drop_talus_minimum">The minimum angle at which rock is dropped 0..1 (recommended: >= 0.00)</param>
/// <param name="carry">The percentage of rock which can be picked up to pickup 0..1</param> /// <param name="carry">The percentage of rock which can be picked up to pickup 0..1</param>
/// <param name="rounds">The number of erosion rounds (recommended: 25+)</param> /// <param name="rounds">The number of erosion rounds (recommended: 25+)</param>
/// <param name="lowest">Drop sediment at the lowest point?</param> /// <param name="lowest">Drop sediment at the lowest point?</param>
public void AerobicErosion(double windspeed, double pickupTalusMinimum, double dropTalusMinimum, double carry, int rounds, bool lowest, bool usingFluidDynamics) public void AerobicErosion(double windspeed, double pickupTalusMinimum, double dropTalusMinimum, double carry, int rounds, bool lowest, bool usingFluidDynamics)
{ {
bool debugImages = false; bool debugImages = false;
Channel wind = new Channel(w, h) ; Channel wind = new Channel(w, h) ;
Channel sediment = new Channel(w, h); Channel sediment = new Channel(w, h);
int x, y, i, j; int x, y, i, j;
this.Normalise(); this.Normalise();
wind = this.Copy(); wind = this.Copy();
wind.Noise(); wind.Noise();
if (debugImages) if (debugImages)
wind.SaveImage("testimg/wind_start.png"); wind.SaveImage("testimg/wind_start.png");
if (usingFluidDynamics) if (usingFluidDynamics)
{ {
wind.navierStokes(20, 0.1, 0.0, 0.0); wind.navierStokes(20, 0.1, 0.0, 0.0);
} }
else else
{ {
wind.Pertubation(30); wind.Pertubation(30);
} }
if (debugImages) if (debugImages)
wind.SaveImage("testimg/wind_begin.png"); wind.SaveImage("testimg/wind_begin.png");
for (i = 0; i < rounds; i++) for (i = 0; i < rounds; i++)
{ {
// Convert some rocks to sand // Convert some rocks to sand
for (x = 1; x < w - 1; x++) for (x = 1; x < w - 1; x++)
{ {
for (y = 1; y < h - 1; y++) for (y = 1; y < h - 1; y++)
{ {
double me = Get(x, y); double me = Get(x, y);
double surfacearea = 0.3; // Everything will erode even if it's flat. Just slower. double surfacearea = 0.3; // Everything will erode even if it's flat. Just slower.
for (j = 0; j < 9; j++) for (j = 0; j < 9; j++)
{ {
int[] coords = Neighbours(NeighbourSystem.Moore, j); int[] coords = Neighbours(NeighbourSystem.Moore, j);
double target = Get(x + coords[0], y + coords[1]); double target = Get(x + coords[0], y + coords[1]);
surfacearea += Math.Abs(target - me); surfacearea += Math.Abs(target - me);
} }
double amount = surfacearea * wind.map[x, y] * carry; double amount = surfacearea * wind.map[x, y] * carry;
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;
if (surfacearea > pickupTalusMinimum) if (surfacearea > pickupTalusMinimum)
{ {
Set(x, y, map[x, y] - amount); Set(x, y, map[x, y] - amount);
sediment.map[x, y] += amount; sediment.map[x, y] += amount;
} }
} }
} }
if (usingFluidDynamics) if (usingFluidDynamics)
{ {
sediment.navierStokes(7, 0.1, 0.0, 0.1); sediment.navierStokes(7, 0.1, 0.0, 0.1);
Channel noiseChan = new Channel(w, h); Channel noiseChan = new Channel(w, h);
noiseChan.Noise(); noiseChan.Noise();
wind.Blend(noiseChan, 0.01); wind.Blend(noiseChan, 0.01);
wind.navierStokes(10, 0.1, 0.01, 0.01); wind.navierStokes(10, 0.1, 0.01, 0.01);
sediment.Distort(wind, windspeed); sediment.Distort(wind, windspeed);
} }
else else
{ {
wind.Pertubation(15); // Can do better later wind.Pertubation(15); // Can do better later
wind.seed++; wind.seed++;
sediment.Pertubation(10); // Sediment is blown around a bit sediment.Pertubation(10); // Sediment is blown around a bit
sediment.seed++; sediment.seed++;
} }
if (debugImages) if (debugImages)
wind.SaveImage("testimg/wind_" + i.ToString() + ".png"); wind.SaveImage("testimg/wind_" + i.ToString() + ".png");
// Convert some sand to rock // Convert some sand to rock
for (x = 1; x < w - 1; x++) for (x = 1; x < w - 1; x++)
{ {
for (y = 1; y < h - 1; y++) for (y = 1; y < h - 1; y++)
{ {
double me = Get(x, y); double me = Get(x, y);
double surfacearea = 0.01; // Flat land does not get deposition double surfacearea = 0.01; // Flat land does not get deposition
double min = double.MaxValue; double min = double.MaxValue;
int[] minside = new int[2]; int[] minside = new int[2];
for (j = 0; j < 9; j++) for (j = 0; j < 9; j++)
{ {
int[] coords = Neighbours(NeighbourSystem.Moore, j); int[] coords = Neighbours(NeighbourSystem.Moore, j);
double target = Get(x + coords[0], y + coords[1]); double target = Get(x + coords[0], y + coords[1]);
surfacearea += Math.Abs(target - me); surfacearea += Math.Abs(target - me);
if (target < min && lowest) if (target < min && lowest)
{ {
minside = (int[])coords.Clone(); minside = (int[])coords.Clone();
min = target; min = target;
} }
} }
double amount = surfacearea * (1.0 - wind.map[x, y]) * carry; double amount = surfacearea * (1.0 - wind.map[x, y]) * carry;
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;
if (surfacearea > dropTalusMinimum) if (surfacearea > dropTalusMinimum)
{ {
Set(x + minside[0], y + minside[1], map[x + minside[0], y + minside[1]] + amount); Set(x + minside[0], y + minside[1], map[x + minside[0], y + minside[1]] + amount);
sediment.map[x, y] -= amount; sediment.map[x, y] -= amount;
} }
} }
} }
if (debugImages) if (debugImages)
sediment.SaveImage("testimg/sediment_" + i.ToString() + ".png"); sediment.SaveImage("testimg/sediment_" + i.ToString() + ".png");
wind.Normalise(); wind.Normalise();
wind *= windspeed; wind *= windspeed;
this.Normalise(); this.Normalise();
} }
Channel myself = this; Channel myself = this;
myself += sediment; myself += sediment;
myself.Normalise(); myself.Normalise();
if (debugImages) if (debugImages)
this.SaveImage("testimg/output.png"); this.SaveImage("testimg/output.png");
} }
} }
} }

View File

@ -1,146 +1,146 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
public void HydraulicErosion(Channel rain, double evaporation, double solubility, int frequency, int rounds) public void HydraulicErosion(Channel rain, double evaporation, double solubility, int frequency, int rounds)
{ {
SetDiff(); SetDiff();
Channel water = new Channel(w, h); Channel water = new Channel(w, h);
Channel sediment = new Channel(w, h); Channel sediment = new Channel(w, h);
Channel terrain = this; Channel terrain = this;
Channel waterFlow = new Channel(w, h); Channel waterFlow = new Channel(w, h);
NeighbourSystem type = NeighbourSystem.Moore; NeighbourSystem type = NeighbourSystem.Moore;
int NEIGHBOUR_ME = 4; int NEIGHBOUR_ME = 4;
int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
for (int i = 0; i < rounds; i++) for (int i = 0; i < rounds; i++)
{ {
water += rain; water += rain;
sediment = terrain * water; sediment = terrain * water;
terrain -= sediment; terrain -= sediment;
for (int x = 1; x < w - 1; x++) for (int x = 1; x < w - 1; x++)
{ {
for (int y = 1; y < h - 1; y++) for (int y = 1; y < h - 1; y++)
{ {
double[] heights = new double[NEIGHBOUR_MAX]; double[] heights = new double[NEIGHBOUR_MAX];
double[] diffs = new double[NEIGHBOUR_MAX]; double[] diffs = new double[NEIGHBOUR_MAX];
double heightCenter = map[x, y]; double heightCenter = map[x, y];
for (int j = 0; j < NEIGHBOUR_MAX; j++) for (int j = 0; j < NEIGHBOUR_MAX; j++)
{ {
if (j != NEIGHBOUR_ME) if (j != NEIGHBOUR_ME)
{ {
int[] coords = Neighbours(type, j); int[] coords = Neighbours(type, j);
coords[0] += x; coords[0] += x;
coords[1] += y; coords[1] += y;
heights[j] = map[coords[0], coords[1]] + water.map[coords[0], coords[1]] + sediment.map[coords[0], coords[1]]; heights[j] = map[coords[0], coords[1]] + water.map[coords[0], coords[1]] + sediment.map[coords[0], coords[1]];
diffs[j] = heightCenter - heights[j]; diffs[j] = heightCenter - heights[j];
} }
} }
double totalHeight = 0; double totalHeight = 0;
double totalHeightDiff = 0; double totalHeightDiff = 0;
int totalCellsCounted = 1; int totalCellsCounted = 1;
for (int j = 0; j < NEIGHBOUR_MAX; j++) for (int j = 0; j < NEIGHBOUR_MAX; j++)
{ {
if (j != NEIGHBOUR_ME) if (j != NEIGHBOUR_ME)
{ {
if (diffs[j] > 0) if (diffs[j] > 0)
{ {
totalHeight += heights[j]; totalHeight += heights[j];
totalHeightDiff += diffs[j]; totalHeightDiff += diffs[j];
totalCellsCounted++; totalCellsCounted++;
} }
} }
} }
if (totalCellsCounted == 1) if (totalCellsCounted == 1)
continue; continue;
double averageHeight = totalHeight / totalCellsCounted; double averageHeight = totalHeight / totalCellsCounted;
double waterAmount = Math.Min(water.map[x, y], heightCenter - averageHeight); double waterAmount = Math.Min(water.map[x, y], heightCenter - averageHeight);
// TODO: Check this. // TODO: Check this.
waterFlow.map[x, y] += waterFlow.map[x, y] - waterAmount; waterFlow.map[x, y] += waterFlow.map[x, y] - waterAmount;
double totalInverseDiff = waterAmount / totalHeightDiff; double totalInverseDiff = waterAmount / totalHeightDiff;
for (int j = 0; j < NEIGHBOUR_MAX; j++) for (int j = 0; j < NEIGHBOUR_MAX; j++)
{ {
if (j != NEIGHBOUR_ME) if (j != NEIGHBOUR_ME)
{ {
int[] coords = Neighbours(type, j); int[] coords = Neighbours(type, j);
coords[0] += x; coords[0] += x;
coords[1] += y; coords[1] += y;
if (diffs[j] > 0) if (diffs[j] > 0)
{ {
waterFlow.SetWrap(coords[0], coords[1], waterFlow.map[coords[0], coords[1]] + diffs[j] * totalInverseDiff); waterFlow.SetWrap(coords[0], coords[1], waterFlow.map[coords[0], coords[1]] + diffs[j] * totalInverseDiff);
} }
} }
} }
} }
} }
water += waterFlow; water += waterFlow;
waterFlow.Fill(0); waterFlow.Fill(0);
water *= evaporation; water *= evaporation;
for (int x = 0; x < w; x++) for (int x = 0; x < w; x++)
{ {
for (int y = 0; y < h; y++) for (int y = 0; y < h; y++)
{ {
double deposition = sediment.map[x, y] - water.map[x, y] * solubility; double deposition = sediment.map[x, y] - water.map[x, y] * solubility;
if (deposition > 0) if (deposition > 0)
{ {
sediment.map[x, y] -= deposition; sediment.map[x, y] -= deposition;
terrain.map[x, y] += deposition; terrain.map[x, y] += deposition;
} }
} }
} }
} }
} }
} }
} }

View File

@ -1,307 +1,307 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
// Navier Stokes Algorithms ported from // Navier Stokes Algorithms ported from
// "Real-Time Fluid Dynamics for Games" by Jos Stam. // "Real-Time Fluid Dynamics for Games" by Jos Stam.
// presented at GDC 2003. // presented at GDC 2003.
// Poorly ported from C++. (I gave up making it properly native somewhere after nsSetBnd) // Poorly ported from C++. (I gave up making it properly native somewhere after nsSetBnd)
private static int nsIX(int i, int j, int N) private static int nsIX(int i, int j, int N)
{ {
return ((i) + (N + 2) * (j)); return ((i) + (N + 2) * (j));
} }
private static void nsSwap(ref double x0, ref double x) private static void nsSwap(ref double x0, ref double x)
{ {
double tmp = x0; double tmp = x0;
x0 = x; x0 = x;
x = tmp; x = tmp;
} }
private static void nsSwap(ref double[] x0, ref double[] x) private static void nsSwap(ref double[] x0, ref double[] x)
{ {
double[] tmp = x0; double[] tmp = x0;
x0 = x; x0 = x;
x = tmp; x = tmp;
} }
private void nsAddSource(int N, ref double[] x, ref double[] s, double dt) private void nsAddSource(int N, ref double[] x, ref double[] s, double dt)
{ {
int i; int i;
int size = (N + 2) * (N + 2); int size = (N + 2) * (N + 2);
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
{ {
x[i] += dt * s[i]; x[i] += dt * s[i];
} }
} }
private void nsSetBnd(int N, int b, ref double[] x) private void nsSetBnd(int N, int b, ref double[] x)
{ {
int i; int i;
for (i = 0; i <= N; i++) for (i = 0; i <= N; i++)
{ {
x[nsIX(0, i, N)] = b == 1 ? -x[nsIX(1, i, N)] : x[nsIX(1, i, N)]; x[nsIX(0, i, N)] = b == 1 ? -x[nsIX(1, i, N)] : x[nsIX(1, i, N)];
x[nsIX(0, N + 1, N)] = b == 1 ? -x[nsIX(N, i, N)] : x[nsIX(N, i, N)]; x[nsIX(0, N + 1, N)] = b == 1 ? -x[nsIX(N, i, N)] : x[nsIX(N, i, N)];
x[nsIX(i, 0, N)] = b == 2 ? -x[nsIX(i, 1, N)] : x[nsIX(i, 1, N)]; x[nsIX(i, 0, N)] = b == 2 ? -x[nsIX(i, 1, N)] : x[nsIX(i, 1, N)];
x[nsIX(i, N + 1, N)] = b == 2 ? -x[nsIX(i, N, N)] : x[nsIX(i, N, N)]; x[nsIX(i, N + 1, N)] = b == 2 ? -x[nsIX(i, N, N)] : x[nsIX(i, N, N)];
} }
x[nsIX(0, 0, N)] = 0.5f * (x[nsIX(1, 0, N)] + x[nsIX(0, 1, N)]); x[nsIX(0, 0, N)] = 0.5f * (x[nsIX(1, 0, N)] + x[nsIX(0, 1, N)]);
x[nsIX(0, N + 1, N)] = 0.5f * (x[nsIX(1, N + 1, N)] + x[nsIX(0, N, N)]); x[nsIX(0, N + 1, N)] = 0.5f * (x[nsIX(1, N + 1, N)] + x[nsIX(0, N, N)]);
x[nsIX(N + 1, 0, N)] = 0.5f * (x[nsIX(N, 0, N)] + x[nsIX(N + 1, 1, N)]); x[nsIX(N + 1, 0, N)] = 0.5f * (x[nsIX(N, 0, N)] + x[nsIX(N + 1, 1, N)]);
x[nsIX(N + 1, N + 1, N)] = 0.5f * (x[nsIX(N, N + 1, N)] + x[nsIX(N + 1, N, N)]); x[nsIX(N + 1, N + 1, N)] = 0.5f * (x[nsIX(N, N + 1, N)] + x[nsIX(N + 1, N, N)]);
} }
private void nsLinSolve(int N, int b, ref double[] x, ref double[] x0, double a, double c) private void nsLinSolve(int N, int b, ref double[] x, ref double[] x0, double a, double c)
{ {
int i, j; int i, j;
for (i = 1; i <= N; i++) for (i = 1; i <= N; i++)
{ {
for (j = 1; j <= N; j++) for (j = 1; j <= N; j++)
{ {
x[nsIX(i, j, N)] = (x0[nsIX(i, j, N)] + a * x[nsIX(i, j, N)] = (x0[nsIX(i, j, N)] + a *
(x[nsIX(i - 1, j, N)] + (x[nsIX(i - 1, j, N)] +
x[nsIX(i + 1, j, N)] + x[nsIX(i + 1, j, N)] +
x[nsIX(i, j - 1, N)] + x[nsIX(i, j + 1, N)]) x[nsIX(i, j - 1, N)] + x[nsIX(i, j + 1, N)])
) / c; ) / c;
} }
} }
nsSetBnd(N, b, ref x); nsSetBnd(N, b, ref x);
} }
private void nsDiffuse(int N, int b, ref double[] x, ref double[] x0, double diff, double dt) private void nsDiffuse(int N, int b, ref double[] x, ref double[] x0, double diff, double dt)
{ {
double a = dt * diff * N * N; double a = dt * diff * N * N;
nsLinSolve(N, b, ref x, ref x0, a, 1 + 4 * a); nsLinSolve(N, b, ref x, ref x0, a, 1 + 4 * a);
} }
private void nsAdvect(int N, int b, ref double[] d, ref double[] d0, ref double[] u, ref double[] v, double dt) private void nsAdvect(int N, int b, ref double[] d, ref double[] d0, ref double[] u, ref double[] v, double dt)
{ {
int i, j, i0, j0, i1, j1; int i, j, i0, j0, i1, j1;
double x, y, s0, t0, s1, t1, dt0; double x, y, s0, t0, s1, t1, dt0;
dt0 = dt * N; dt0 = dt * N;
for (i = 1; i <= N; i++) for (i = 1; i <= N; i++)
{ {
for (j = 1; j <= N; j++) for (j = 1; j <= N; j++)
{ {
x = i - dt0 * u[nsIX(i, j, N)]; x = i - dt0 * u[nsIX(i, j, N)];
y = j - dt0 * v[nsIX(i, j, N)]; y = j - dt0 * v[nsIX(i, j, N)];
if (x < 0.5) if (x < 0.5)
x = 0.5; x = 0.5;
if (x > N + 0.5) if (x > N + 0.5)
x = N + 0.5; x = N + 0.5;
i0 = (int)x; i0 = (int)x;
i1 = i0 + 1; i1 = i0 + 1;
if (y < 0.5) if (y < 0.5)
y = 0.5; y = 0.5;
if (y > N + 0.5) if (y > N + 0.5)
y = N + 0.5; y = N + 0.5;
j0 = (int)y; j0 = (int)y;
j1 = j0 + 1; j1 = j0 + 1;
s1 = x - i0; s1 = x - i0;
s0 = 1 - s1; s0 = 1 - s1;
t1 = y - j0; t1 = y - j0;
t0 = 1 - t1; t0 = 1 - t1;
d[nsIX(i, j, N)] = s0 * (t0 * d0[nsIX(i0, j0, N)] + t1 * d0[nsIX(i0, j1, N)]) + d[nsIX(i, j, N)] = s0 * (t0 * d0[nsIX(i0, j0, N)] + t1 * d0[nsIX(i0, j1, N)]) +
s1 * (t0 * d0[nsIX(i1, j0, N)] + t1 * d0[nsIX(i1, j1, N)]); s1 * (t0 * d0[nsIX(i1, j0, N)] + t1 * d0[nsIX(i1, j1, N)]);
} }
} }
nsSetBnd(N, b, ref d); nsSetBnd(N, b, ref d);
} }
public void nsProject(int N, ref double[] u, ref double[] v, ref double[] p, ref double[] div) public void nsProject(int N, ref double[] u, ref double[] v, ref double[] p, ref double[] div)
{ {
int i, j; int i, j;
for (i = 1; i <= N; i++) for (i = 1; i <= N; i++)
{ {
for (j = 1; j <= N; j++) for (j = 1; j <= N; j++)
{ {
div[nsIX(i, j, N)] = -0.5 * (u[nsIX(i + 1, j, N)] - u[nsIX(i - 1, j, N)] + v[nsIX(i, j + 1, N)] - v[nsIX(i, j - 1, N)]) / N; div[nsIX(i, j, N)] = -0.5 * (u[nsIX(i + 1, j, N)] - u[nsIX(i - 1, j, N)] + v[nsIX(i, j + 1, N)] - v[nsIX(i, j - 1, N)]) / N;
p[nsIX(i, j, N)] = 0; p[nsIX(i, j, N)] = 0;
} }
} }
nsSetBnd(N, 0, ref div); nsSetBnd(N, 0, ref div);
nsSetBnd(N, 0, ref p); nsSetBnd(N, 0, ref p);
nsLinSolve(N, 0, ref p, ref div, 1, 4); nsLinSolve(N, 0, ref p, ref div, 1, 4);
for (i = 1; i <= N; i++) for (i = 1; i <= N; i++)
{ {
for (j = 1; j <= N; j++) for (j = 1; j <= N; j++)
{ {
u[nsIX(i, j, N)] -= 0.5 * N * (p[nsIX(i + 1, j, N)] - p[nsIX(i - 1, j, N)]); u[nsIX(i, j, N)] -= 0.5 * N * (p[nsIX(i + 1, j, N)] - p[nsIX(i - 1, j, N)]);
v[nsIX(i, j, N)] -= 0.5 * N * (p[nsIX(i, j + 1, N)] - p[nsIX(i, j - 1, N)]); v[nsIX(i, j, N)] -= 0.5 * N * (p[nsIX(i, j + 1, N)] - p[nsIX(i, j - 1, N)]);
} }
} }
nsSetBnd(N, 1, ref u); nsSetBnd(N, 1, ref u);
nsSetBnd(N, 2, ref v); nsSetBnd(N, 2, ref v);
} }
private void nsDensStep(int N, ref double[] x, ref double[] x0, ref double[] u, ref double[] v, double diff, double dt) private void nsDensStep(int N, ref double[] x, ref double[] x0, ref double[] u, ref double[] v, double diff, double dt)
{ {
nsAddSource(N, ref x, ref x0, dt); nsAddSource(N, ref x, ref x0, dt);
nsSwap(ref x0, ref x); nsSwap(ref x0, ref x);
nsDiffuse(N, 0, ref x, ref x0, diff, dt); nsDiffuse(N, 0, ref x, ref x0, diff, dt);
nsSwap(ref x0, ref x); nsSwap(ref x0, ref x);
nsAdvect(N, 0, ref x, ref x0, ref u, ref v, dt); nsAdvect(N, 0, ref x, ref x0, ref u, ref v, dt);
} }
private void nsVelStep(int N, ref double[] u, ref double[] v, ref double[] u0, ref double[] v0, double visc, double dt) private void nsVelStep(int N, ref double[] u, ref double[] v, ref double[] u0, ref double[] v0, double visc, double dt)
{ {
nsAddSource(N, ref u, ref u0, dt); nsAddSource(N, ref u, ref u0, dt);
nsAddSource(N, ref v, ref v0, dt); nsAddSource(N, ref v, ref v0, dt);
nsSwap(ref u0, ref u); nsSwap(ref u0, ref u);
nsDiffuse(N, 1, ref u, ref u0, visc, dt); nsDiffuse(N, 1, ref u, ref u0, visc, dt);
nsSwap(ref v0, ref v); nsSwap(ref v0, ref v);
nsDiffuse(N, 2, ref v, ref v0, visc, dt); nsDiffuse(N, 2, ref v, ref v0, visc, dt);
nsProject(N, ref u, ref v, ref u0, ref v0); nsProject(N, ref u, ref v, ref u0, ref v0);
nsSwap(ref u0, ref u); nsSwap(ref u0, ref u);
nsSwap(ref v0, ref v); nsSwap(ref v0, ref v);
nsAdvect(N, 1, ref u, ref u0, ref u0, ref v0, dt); nsAdvect(N, 1, ref u, ref u0, ref u0, ref v0, dt);
nsAdvect(N, 2, ref v, ref v0, ref u0, ref v0, dt); nsAdvect(N, 2, ref v, ref v0, ref u0, ref v0, dt);
nsProject(N, ref u, ref v, ref u0, ref v0); nsProject(N, ref u, ref v, ref u0, ref v0);
} }
private void nsBufferToDoubles(ref double[] dens, int N, ref double[,] doubles) private void nsBufferToDoubles(ref double[] dens, int N, ref double[,] doubles)
{ {
int i; int i;
int j; int j;
for (i = 1; i <= N; i++) for (i = 1; i <= N; i++)
{ {
for (j = 1; j <= N; j++) for (j = 1; j <= N; j++)
{ {
doubles[i - 1, j - 1] = dens[nsIX(i, j, N)]; doubles[i - 1, j - 1] = dens[nsIX(i, j, N)];
} }
} }
} }
private void nsDoublesToBuffer(double[,] doubles, int N, ref double[] dens) private void nsDoublesToBuffer(double[,] doubles, int N, ref double[] dens)
{ {
int i; int i;
int j; int j;
for (i = 1; i <= N; i++) for (i = 1; i <= N; i++)
{ {
for (j = 1; j <= N; j++) for (j = 1; j <= N; j++)
{ {
dens[nsIX(i, j, N)] = doubles[i - 1, j - 1]; dens[nsIX(i, j, N)] = doubles[i - 1, j - 1];
} }
} }
} }
private void nsSimulate(int N, int rounds, double dt, double diff, double visc) private void nsSimulate(int N, int rounds, double dt, double diff, double visc)
{ {
int size = (N * 2) * (N * 2); int size = (N * 2) * (N * 2);
double[] u = new double[size]; // Force, X axis double[] u = new double[size]; // Force, X axis
double[] v = new double[size]; // Force, Y axis double[] v = new double[size]; // Force, Y axis
double[] u_prev = new double[size]; double[] u_prev = new double[size];
double[] v_prev = new double[size]; double[] v_prev = new double[size];
double[] dens = new double[size]; double[] dens = new double[size];
double[] dens_prev = new double[size]; double[] dens_prev = new double[size];
nsDoublesToBuffer(this.map, N, ref dens); nsDoublesToBuffer(this.map, N, ref dens);
nsDoublesToBuffer(this.map, N, ref dens_prev); nsDoublesToBuffer(this.map, N, ref dens_prev);
for (int i = 0; i < rounds; i++) for (int i = 0; i < rounds; i++)
{ {
u_prev = u; u_prev = u;
v_prev = v; v_prev = v;
dens_prev = dens; dens_prev = dens;
nsVelStep(N, ref u, ref v, ref u_prev, ref v_prev, visc, dt); nsVelStep(N, ref u, ref v, ref u_prev, ref v_prev, visc, dt);
nsDensStep(N, ref dens, ref dens_prev, ref u, ref v, diff, dt); nsDensStep(N, ref dens, ref dens_prev, ref u, ref v, diff, dt);
} }
nsBufferToDoubles(ref dens, N, ref this.map); nsBufferToDoubles(ref dens, N, ref this.map);
} }
/// <summary> /// <summary>
/// Performs computational fluid dynamics on a channel /// Performs computational fluid dynamics on a channel
/// </summary> /// </summary>
/// <param name="rounds">The number of steps to perform (Recommended: 20)</param> /// <param name="rounds">The number of steps to perform (Recommended: 20)</param>
/// <param name="dt">Delta Time - The time between steps (Recommended: 0.1)</param> /// <param name="dt">Delta Time - The time between steps (Recommended: 0.1)</param>
/// <param name="diff">Fluid diffusion rate (Recommended: 0.0)</param> /// <param name="diff">Fluid diffusion rate (Recommended: 0.0)</param>
/// <param name="visc">Fluid viscosity (Recommended: 0.0)</param> /// <param name="visc">Fluid viscosity (Recommended: 0.0)</param>
public void navierStokes(int rounds, double dt, double diff, double visc) public void navierStokes(int rounds, double dt, double diff, double visc)
{ {
nsSimulate(this.h, rounds, dt, diff, visc); nsSimulate(this.h, rounds, dt, diff, visc);
} }
public void navierStokes(int rounds, double dt, double diff, double visc, ref double[,] uret, ref double[,] vret) public void navierStokes(int rounds, double dt, double diff, double visc, ref double[,] uret, ref double[,] vret)
{ {
int N = this.h; int N = this.h;
int size = (N * 2) * (N * 2); int size = (N * 2) * (N * 2);
double[] u = new double[size]; // Force, X axis double[] u = new double[size]; // Force, X axis
double[] v = new double[size]; // Force, Y axis double[] v = new double[size]; // Force, Y axis
double[] u_prev = new double[size]; double[] u_prev = new double[size];
double[] v_prev = new double[size]; double[] v_prev = new double[size];
double[] dens = new double[size]; double[] dens = new double[size];
double[] dens_prev = new double[size]; double[] dens_prev = new double[size];
nsDoublesToBuffer(this.map, N, ref dens); nsDoublesToBuffer(this.map, N, ref dens);
nsDoublesToBuffer(this.map, N, ref dens_prev); nsDoublesToBuffer(this.map, N, ref dens_prev);
for (int i = 0; i < rounds; i++) for (int i = 0; i < rounds; i++)
{ {
u_prev = u; u_prev = u;
v_prev = v; v_prev = v;
dens_prev = dens; dens_prev = dens;
nsVelStep(N, ref u, ref v, ref u_prev, ref v_prev, visc, dt); nsVelStep(N, ref u, ref v, ref u_prev, ref v_prev, visc, dt);
nsDensStep(N, ref dens, ref dens_prev, ref u, ref v, diff, dt); nsDensStep(N, ref dens, ref dens_prev, ref u, ref v, diff, dt);
} }
nsBufferToDoubles(ref u, N, ref uret); nsBufferToDoubles(ref u, N, ref uret);
nsBufferToDoubles(ref v, N, ref vret); nsBufferToDoubles(ref v, N, ref vret);
nsBufferToDoubles(ref dens, N, ref this.map); nsBufferToDoubles(ref dens, N, ref this.map);
} }
} }
} }

View File

@ -1,112 +1,112 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
/// <summary> /// <summary>
/// A thermal weathering implementation based on Musgrave's original 1989 algorithm. This is Adam's custom implementation which may differ slightly from the original. /// A thermal weathering implementation based on Musgrave's original 1989 algorithm. This is Adam's custom implementation which may differ slightly from the original.
/// </summary> /// </summary>
/// <param name="talus">The rock angle (represented as a dy/dx ratio) at which point it will be succeptible to breakage</param> /// <param name="talus">The rock angle (represented as a dy/dx ratio) at which point it will be succeptible to breakage</param>
/// <param name="rounds">The number of erosion rounds</param> /// <param name="rounds">The number of erosion rounds</param>
/// <param name="c">The amount of rock to carry each round</param> /// <param name="c">The amount of rock to carry each round</param>
public Channel ThermalWeathering(double talus, int rounds, double c) public Channel ThermalWeathering(double talus, int rounds, double c)
{ {
SetDiff(); SetDiff();
double[,] lastFrame; double[,] lastFrame;
double[,] thisFrame; double[,] thisFrame;
lastFrame = (double[,])map.Clone(); lastFrame = (double[,])map.Clone();
thisFrame = (double[,])map.Clone(); thisFrame = (double[,])map.Clone();
NeighbourSystem type = NeighbourSystem.Moore; // Using moore neighbourhood (twice as computationally expensive) NeighbourSystem type = NeighbourSystem.Moore; // Using moore neighbourhood (twice as computationally expensive)
int NEIGHBOUR_ME = 4; // I am always 4 in both systems. int NEIGHBOUR_ME = 4; // I am always 4 in both systems.
int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
int frames = rounds; // Number of thermal erosion iterations to run int frames = rounds; // Number of thermal erosion iterations to run
int i, j; int i, j;
int x, y; int x, y;
for (i = 0; i < frames; i++) for (i = 0; i < frames; i++)
{ {
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
for (j = 0; j < NEIGHBOUR_MAX; j++) for (j = 0; j < NEIGHBOUR_MAX; j++)
{ {
if (j != NEIGHBOUR_ME) if (j != NEIGHBOUR_ME)
{ {
int[] coords = Neighbours(type, j); int[] coords = Neighbours(type, j);
coords[0] += x; coords[0] += x;
coords[1] += y; coords[1] += y;
if (coords[0] > w - 1) if (coords[0] > w - 1)
coords[0] = w - 1; coords[0] = w - 1;
if (coords[1] > h - 1) if (coords[1] > h - 1)
coords[1] = h - 1; coords[1] = h - 1;
if (coords[0] < 0) if (coords[0] < 0)
coords[0] = 0; coords[0] = 0;
if (coords[1] < 0) if (coords[1] < 0)
coords[1] = 0; coords[1] = 0;
double heightF = thisFrame[x, y]; double heightF = thisFrame[x, y];
double target = thisFrame[coords[0], coords[1]]; double target = thisFrame[coords[0], coords[1]];
if (target > heightF + talus) if (target > heightF + talus)
{ {
double calc = c * ((target - heightF) - talus); double calc = c * ((target - heightF) - talus);
heightF += calc; heightF += calc;
target -= calc; target -= calc;
} }
thisFrame[x, y] = heightF; thisFrame[x, y] = heightF;
thisFrame[coords[0], coords[1]] = target; thisFrame[coords[0], coords[1]] = target;
} }
} }
} }
} }
lastFrame = (double[,])thisFrame.Clone(); lastFrame = (double[,])thisFrame.Clone();
} }
map = thisFrame; map = thisFrame;
Normalise(); // Just to guaruntee a smooth 0..1 value Normalise(); // Just to guaruntee a smooth 0..1 value
return this; return this;
} }
} }
} }

View File

@ -1,141 +1,141 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
enum NeighbourSystem enum NeighbourSystem
{ {
Moore, Moore,
VonNeumann VonNeumann
}; };
private int[] Neighbours(NeighbourSystem type, int index) private int[] Neighbours(NeighbourSystem type, int index)
{ {
int[] coord = new int[2]; int[] coord = new int[2];
index++; index++;
switch (type) switch (type)
{ {
case NeighbourSystem.Moore: case NeighbourSystem.Moore:
switch (index) switch (index)
{ {
case 1: case 1:
coord[0] = -1; coord[0] = -1;
coord[1] = -1; coord[1] = -1;
break; break;
case 2: case 2:
coord[0] = -0; coord[0] = -0;
coord[1] = -1; coord[1] = -1;
break; break;
case 3: case 3:
coord[0] = +1; coord[0] = +1;
coord[1] = -1; coord[1] = -1;
break; break;
case 4: case 4:
coord[0] = -1; coord[0] = -1;
coord[1] = -0; coord[1] = -0;
break; break;
case 5: case 5:
coord[0] = -0; coord[0] = -0;
coord[1] = -0; coord[1] = -0;
break; break;
case 6: case 6:
coord[0] = +1; coord[0] = +1;
coord[1] = -0; coord[1] = -0;
break; break;
case 7: case 7:
coord[0] = -1; coord[0] = -1;
coord[1] = +1; coord[1] = +1;
break; break;
case 8: case 8:
coord[0] = -0; coord[0] = -0;
coord[1] = +1; coord[1] = +1;
break; break;
case 9: case 9:
coord[0] = +1; coord[0] = +1;
coord[1] = +1; coord[1] = +1;
break; break;
default: default:
break; break;
} }
break; break;
case NeighbourSystem.VonNeumann: case NeighbourSystem.VonNeumann:
switch (index) switch (index)
{ {
case 1: case 1:
coord[0] = 0; coord[0] = 0;
coord[1] = -1; coord[1] = -1;
break; break;
case 2: case 2:
coord[0] = -1; coord[0] = -1;
coord[1] = 0; coord[1] = 0;
break; break;
case 3: case 3:
coord[0] = +1; coord[0] = +1;
coord[1] = 0; coord[1] = 0;
break; break;
case 4: case 4:
coord[0] = 0; coord[0] = 0;
coord[1] = +1; coord[1] = +1;
break; break;
case 5: case 5:
coord[0] = -0; coord[0] = -0;
coord[1] = -0; coord[1] = -0;
break; break;
default: default:
break; break;
} }
break; break;
} }
return coord; return coord;
} }
} }
} }

View File

@ -1,243 +1,243 @@
/* /*
* Copyright (c) Contributors, http://www.openmetaverse.org/ * Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
partial class Channel partial class Channel
{ {
/* Operator combination of channel datatypes */ /* Operator combination of channel datatypes */
public static Channel operator +(Channel A, Channel B) public static Channel operator +(Channel A, Channel B)
{ {
if (A.h != B.h) if (A.h != B.h)
throw new Exception("Cannot add heightmaps, of different height."); throw new Exception("Cannot add heightmaps, of different height.");
if (A.w != B.w) if (A.w != B.w)
throw new Exception("Cannot add heightmaps, of different width."); throw new Exception("Cannot add heightmaps, of different width.");
int x, y; int x, y;
for (x = 0; x < A.w; x++) for (x = 0; x < A.w; x++)
{ {
for (y = 0; y < A.h; y++) for (y = 0; y < A.h; y++)
{ {
if (B.map[x, y] != 0) if (B.map[x, y] != 0)
A.SetDiff(x, y); A.SetDiff(x, y);
A.map[x, y] += B.map[x, y]; A.map[x, y] += B.map[x, y];
} }
} }
return A; return A;
} }
public static Channel operator *(Channel A, Channel B) public static Channel operator *(Channel A, Channel B)
{ {
if (A.h != B.h) if (A.h != B.h)
throw new Exception("Cannot multiply heightmaps, of different height."); throw new Exception("Cannot multiply heightmaps, of different height.");
if (A.w != B.w) if (A.w != B.w)
throw new Exception("Cannot multiply heightmaps, of different width."); throw new Exception("Cannot multiply heightmaps, of different width.");
int x, y; int x, y;
for (x = 0; x < A.w; x++) for (x = 0; x < A.w; x++)
{ {
for (y = 0; y < A.h; y++) for (y = 0; y < A.h; y++)
{ {
A.map[x, y] *= B.map[x, y]; A.map[x, y] *= B.map[x, y];
} }
} }
A.SetDiff(); A.SetDiff();
return A; return A;
} }
public static Channel operator -(Channel A, Channel B) public static Channel operator -(Channel A, Channel B)
{ {
if (A.h != B.h) if (A.h != B.h)
throw new Exception("Cannot subtract heightmaps, of different height."); throw new Exception("Cannot subtract heightmaps, of different height.");
if (A.w != B.w) if (A.w != B.w)
throw new Exception("Cannot subtract heightmaps, of different width."); throw new Exception("Cannot subtract heightmaps, of different width.");
int x, y; int x, y;
for (x = 0; x < A.w; x++) for (x = 0; x < A.w; x++)
{ {
for (y = 0; y < A.h; y++) for (y = 0; y < A.h; y++)
{ {
if (B.map[x, y] != 0) if (B.map[x, y] != 0)
A.SetDiff(x, y); A.SetDiff(x, y);
A.map[x, y] -= B.map[x, y]; A.map[x, y] -= B.map[x, y];
} }
} }
return A; return A;
} }
public static Channel operator /(Channel A, Channel B) public static Channel operator /(Channel A, Channel B)
{ {
if (A.h != B.h) if (A.h != B.h)
throw new Exception("Cannot divide heightmaps, of different height."); throw new Exception("Cannot divide heightmaps, of different height.");
if (A.w != B.w) if (A.w != B.w)
throw new Exception("Cannot divide heightmaps, of different width."); throw new Exception("Cannot divide heightmaps, of different width.");
int x, y; int x, y;
for (x = 0; x < A.w; x++) for (x = 0; x < A.w; x++)
{ {
for (y = 0; y < A.h; y++) for (y = 0; y < A.h; y++)
{ {
A.map[x, y] /= B.map[x, y]; A.map[x, y] /= B.map[x, y];
} }
} }
A.SetDiff(); A.SetDiff();
return A; return A;
} }
public static Channel operator ^(Channel A, Channel B) public static Channel operator ^(Channel A, Channel B)
{ {
if (A.h != B.h) if (A.h != B.h)
throw new Exception("Cannot divide heightmaps, of different height."); throw new Exception("Cannot divide heightmaps, of different height.");
if (A.w != B.w) if (A.w != B.w)
throw new Exception("Cannot divide heightmaps, of different width."); throw new Exception("Cannot divide heightmaps, of different width.");
int x, y; int x, y;
for (x = 0; x < A.w; x++) for (x = 0; x < A.w; x++)
{ {
for (y = 0; y < A.h; y++) for (y = 0; y < A.h; y++)
{ {
A.map[x, y] = Math.Pow(A.map[x,y],B.map[x, y]); A.map[x, y] = Math.Pow(A.map[x,y],B.map[x, y]);
} }
} }
A.SetDiff(); A.SetDiff();
return A; return A;
} }
/* Operator combination of channel and double datatypes */ /* Operator combination of channel and double datatypes */
public static Channel operator +(Channel A, double B) public static Channel operator +(Channel A, double B)
{ {
int x, y; int x, y;
for (x = 0; x < A.w; x++) for (x = 0; x < A.w; x++)
{ {
for (y = 0; y < A.h; y++) for (y = 0; y < A.h; y++)
{ {
A.map[x, y] += B; A.map[x, y] += B;
} }
} }
if (B != 0) if (B != 0)
A.SetDiff(); A.SetDiff();
return A; return A;
} }
public static Channel operator -(Channel A, double B) public static Channel operator -(Channel A, double B)
{ {
int x, y; int x, y;
for (x = 0; x < A.w; x++) for (x = 0; x < A.w; x++)
{ {
for (y = 0; y < A.h; y++) for (y = 0; y < A.h; y++)
{ {
A.map[x, y] -= B; A.map[x, y] -= B;
} }
} }
if (B != 0) if (B != 0)
A.SetDiff(); A.SetDiff();
return A; return A;
} }
public static Channel operator *(Channel A, double B) public static Channel operator *(Channel A, double B)
{ {
int x, y; int x, y;
for (x = 0; x < A.w; x++) for (x = 0; x < A.w; x++)
{ {
for (y = 0; y < A.h; y++) for (y = 0; y < A.h; y++)
{ {
A.map[x, y] *= B; A.map[x, y] *= B;
} }
} }
if (B != 1) if (B != 1)
A.SetDiff(); A.SetDiff();
return A; return A;
} }
public static Channel operator /(Channel A, double B) public static Channel operator /(Channel A, double B)
{ {
int x, y; int x, y;
for (x = 0; x < A.w; x++) for (x = 0; x < A.w; x++)
{ {
for (y = 0; y < A.h; y++) for (y = 0; y < A.h; y++)
{ {
A.map[x, y] /= B; A.map[x, y] /= B;
} }
} }
if (B != 1) if (B != 1)
A.SetDiff(); A.SetDiff();
return A; return A;
} }
public static Channel operator ^(Channel A, double B) public static Channel operator ^(Channel A, double B)
{ {
int x, y; int x, y;
for (x = 0; x < A.w; x++) for (x = 0; x < A.w; x++)
{ {
for (y = 0; y < A.h; y++) for (y = 0; y < A.h; y++)
{ {
A.map[x, y] = Math.Pow(A.map[x,y],B); A.map[x, y] = Math.Pow(A.map[x,y],B);
} }
} }
A.SetDiff(); A.SetDiff();
return A; return A;
} }
} }
} }

View File

@ -1,49 +1,49 @@
/* /*
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided disclaimer in the documentation and/or other materials provided
with the distribution. with the distribution.
* Neither the name of libTerrain nor the names of * Neither the name of libTerrain nor the names of
its contributors may be used to endorse or promote products its contributors may be used to endorse or promote products
derived from this software without specific prior written derived from this software without specific prior written
permission. permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace libTerrain namespace libTerrain
{ {
public class Point2D public class Point2D
{ {
public double x; public double x;
public double y; public double y;
public Point2D(double X, double Y) public Point2D(double X, double Y)
{ {
x = X; x = X;
y = Y; y = Y;
} }
} }
} }