Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
commit
233b9ec4d7
|
@ -766,7 +766,7 @@ namespace OpenSim.Groups
|
|||
remoteClient.SendCreateGroupReply(UUID.Zero, false, "Insufficient funds to create a group.");
|
||||
return UUID.Zero;
|
||||
}
|
||||
money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, "Group Creation");
|
||||
money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate);
|
||||
}
|
||||
string reason = string.Empty;
|
||||
UUID groupID = m_groupData.CreateGroup(remoteClient.AgentId, name, charter, showInList, insigniaID, membershipFee, openEnrollment,
|
||||
|
|
|
@ -53,6 +53,7 @@ namespace OpenSim.Framework
|
|||
protected AvatarWearable[] m_wearables;
|
||||
protected Dictionary<int, List<AvatarAttachment>> m_attachments;
|
||||
protected float m_avatarHeight = 0;
|
||||
protected UUID[] m_texturehashes;
|
||||
|
||||
public virtual int Serial
|
||||
{
|
||||
|
@ -98,6 +99,8 @@ namespace OpenSim.Framework
|
|||
SetDefaultParams();
|
||||
SetHeight();
|
||||
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||
|
||||
ResetTextureHashes();
|
||||
}
|
||||
|
||||
public AvatarAppearance(OSDMap map)
|
||||
|
@ -108,32 +111,6 @@ namespace OpenSim.Framework
|
|||
SetHeight();
|
||||
}
|
||||
|
||||
public AvatarAppearance(AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
{
|
||||
// m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance");
|
||||
|
||||
m_serial = 0;
|
||||
|
||||
if (wearables != null)
|
||||
m_wearables = wearables;
|
||||
else
|
||||
SetDefaultWearables();
|
||||
|
||||
if (textureEntry != null)
|
||||
m_texture = textureEntry;
|
||||
else
|
||||
SetDefaultTexture();
|
||||
|
||||
if (visualParams != null)
|
||||
m_visualparams = visualParams;
|
||||
else
|
||||
SetDefaultParams();
|
||||
|
||||
SetHeight();
|
||||
|
||||
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||
}
|
||||
|
||||
public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true)
|
||||
{
|
||||
}
|
||||
|
@ -151,6 +128,8 @@ namespace OpenSim.Framework
|
|||
SetHeight();
|
||||
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||
|
||||
ResetTextureHashes();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -166,6 +145,10 @@ namespace OpenSim.Framework
|
|||
SetWearable(i,appearance.Wearables[i]);
|
||||
}
|
||||
|
||||
m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT];
|
||||
for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
||||
m_texturehashes[i] = new UUID(appearance.m_texturehashes[i]);
|
||||
|
||||
m_texture = null;
|
||||
if (appearance.Texture != null)
|
||||
{
|
||||
|
@ -200,6 +183,37 @@ namespace OpenSim.Framework
|
|||
}
|
||||
}
|
||||
|
||||
public void ResetTextureHashes()
|
||||
{
|
||||
m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT];
|
||||
for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
||||
m_texturehashes[i] = UUID.Zero;
|
||||
}
|
||||
|
||||
public UUID GetTextureHash(int textureIndex)
|
||||
{
|
||||
return m_texturehashes[NormalizeBakedTextureIndex(textureIndex)];
|
||||
}
|
||||
|
||||
public void SetTextureHash(int textureIndex, UUID textureHash)
|
||||
{
|
||||
m_texturehashes[NormalizeBakedTextureIndex(textureIndex)] = new UUID(textureHash);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes the texture index to the actual bake index, this is done to
|
||||
/// accommodate older viewers that send the BAKE_INDICES index rather than
|
||||
/// the actual texture index
|
||||
/// </summary>
|
||||
private int NormalizeBakedTextureIndex(int textureIndex)
|
||||
{
|
||||
// Earlier viewer send the index into the baked index array, just trying to be careful here
|
||||
if (textureIndex < BAKE_INDICES.Length)
|
||||
return BAKE_INDICES[textureIndex];
|
||||
|
||||
return textureIndex;
|
||||
}
|
||||
|
||||
public void ClearWearables()
|
||||
{
|
||||
m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES];
|
||||
|
@ -223,12 +237,7 @@ namespace OpenSim.Framework
|
|||
m_serial = 0;
|
||||
|
||||
SetDefaultTexture();
|
||||
|
||||
//for (int i = 0; i < BAKE_INDICES.Length; i++)
|
||||
// {
|
||||
// int idx = BAKE_INDICES[i];
|
||||
// m_texture.FaceTextures[idx].TextureID = UUID.Zero;
|
||||
// }
|
||||
ResetTextureHashes();
|
||||
}
|
||||
|
||||
protected virtual void SetDefaultParams()
|
||||
|
@ -598,6 +607,12 @@ namespace OpenSim.Framework
|
|||
data["serial"] = OSD.FromInteger(m_serial);
|
||||
data["height"] = OSD.FromReal(m_avatarHeight);
|
||||
|
||||
// Hashes
|
||||
OSDArray hashes = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
|
||||
for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
||||
hashes.Add(OSD.FromUUID(m_texturehashes[i]));
|
||||
data["hashes"] = hashes;
|
||||
|
||||
// Wearables
|
||||
OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
|
||||
for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
|
||||
|
@ -642,6 +657,25 @@ namespace OpenSim.Framework
|
|||
|
||||
try
|
||||
{
|
||||
// Hashes
|
||||
m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT];
|
||||
if ((data != null) && (data["hashes"] != null) && (data["hashes"]).Type == OSDType.Array)
|
||||
{
|
||||
OSDArray hashes = (OSDArray)(data["hashes"]);
|
||||
for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
||||
{
|
||||
UUID hashID = UUID.Zero;
|
||||
if (i < hashes.Count && hashes[i] != null)
|
||||
hashID = hashes[i].AsUUID();
|
||||
m_texturehashes[i] = hashID;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
||||
m_texturehashes[i] = UUID.Zero;
|
||||
}
|
||||
|
||||
// Wearables
|
||||
SetDefaultWearables();
|
||||
if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace OpenSim.Framework
|
|||
|
||||
public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest);
|
||||
|
||||
public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams);
|
||||
public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> cachedTextureData);
|
||||
|
||||
public delegate void StartAnim(IClientAPI remoteClient, UUID animID);
|
||||
|
||||
|
@ -1159,7 +1159,8 @@ namespace OpenSim.Framework
|
|||
void SendTeleportStart(uint flags);
|
||||
void SendTeleportProgress(uint flags, string message);
|
||||
|
||||
void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance);
|
||||
void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance, int transactionType, UUID sourceID, bool sourceIsGroup, UUID destID, bool destIsGroup, int amount, string item);
|
||||
|
||||
void SendPayPrice(UUID objectID, int[] payPrice);
|
||||
|
||||
void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations);
|
||||
|
@ -1254,8 +1255,6 @@ namespace OpenSim.Framework
|
|||
void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch,
|
||||
string[] buttonlabels);
|
||||
|
||||
bool AddMoney(int debit);
|
||||
|
||||
/// <summary>
|
||||
/// Update the client as to where the sun is currently located.
|
||||
/// </summary>
|
||||
|
|
|
@ -38,7 +38,8 @@ namespace OpenSim.Framework
|
|||
int GetBalance(UUID agentID);
|
||||
bool UploadCovered(UUID agentID, int amount);
|
||||
bool AmountCovered(UUID agentID, int amount);
|
||||
void ApplyCharge(UUID agentID, int amount, string text);
|
||||
void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type);
|
||||
void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData);
|
||||
void ApplyUploadCharge(UUID agentID, int amount, string text);
|
||||
|
||||
int UploadCharge { get; }
|
||||
|
|
|
@ -2136,7 +2136,7 @@ namespace OpenSim.Framework
|
|||
/// <param name="secret">the secret part</param>
|
||||
public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
|
||||
{
|
||||
uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
|
||||
uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "UserUPUUI"; secret = string.Empty;
|
||||
|
||||
string[] parts = value.Split(';');
|
||||
if (parts.Length >= 1)
|
||||
|
|
|
@ -345,7 +345,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
// protected HashSet<uint> m_attachmentsSent;
|
||||
|
||||
private int m_moneyBalance;
|
||||
private int m_animationSequenceNumber = 1;
|
||||
private bool m_SendLogoutPacketWhenClosing = true;
|
||||
|
||||
|
@ -420,7 +419,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
public string Name { get { return FirstName + " " + LastName; } }
|
||||
|
||||
public uint CircuitCode { get { return m_circuitCode; } }
|
||||
public int MoneyBalance { get { return m_moneyBalance; } }
|
||||
public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } }
|
||||
|
||||
/// <summary>
|
||||
|
@ -483,7 +481,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
m_firstName = sessionInfo.LoginInfo.First;
|
||||
m_lastName = sessionInfo.LoginInfo.Last;
|
||||
m_startpos = sessionInfo.LoginInfo.StartPos;
|
||||
m_moneyBalance = 1000;
|
||||
|
||||
m_udpServer = udpServer;
|
||||
m_udpClient = udpClient;
|
||||
|
@ -1538,7 +1535,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
OutPacket(tpProgress, ThrottleOutPacketType.Unknown);
|
||||
}
|
||||
|
||||
public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance)
|
||||
public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance, int transactionType, UUID sourceID, bool sourceIsGroup, UUID destID, bool destIsGroup, int amount, string item)
|
||||
{
|
||||
MoneyBalanceReplyPacket money = (MoneyBalanceReplyPacket)PacketPool.Instance.GetPacket(PacketType.MoneyBalanceReply);
|
||||
money.MoneyData.AgentID = AgentId;
|
||||
|
@ -1546,7 +1543,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
money.MoneyData.TransactionSuccess = success;
|
||||
money.MoneyData.Description = description;
|
||||
money.MoneyData.MoneyBalance = balance;
|
||||
money.TransactionInfo.ItemDescription = Util.StringToBytes256("NONE");
|
||||
money.TransactionInfo.TransactionType = transactionType;
|
||||
money.TransactionInfo.SourceID = sourceID;
|
||||
money.TransactionInfo.IsSourceGroup = sourceIsGroup;
|
||||
money.TransactionInfo.DestID = destID;
|
||||
money.TransactionInfo.IsDestGroup = destIsGroup;
|
||||
money.TransactionInfo.Amount = amount;
|
||||
money.TransactionInfo.ItemDescription = Util.StringToBytes256(item);
|
||||
|
||||
OutPacket(money, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
|
@ -2279,6 +2283,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
/// <returns></returns>
|
||||
public AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal)
|
||||
{
|
||||
// Prepend a slash to make the message come up in the top right
|
||||
// again.
|
||||
// Allow special formats to be sent from aware modules.
|
||||
if (!modal && !message.StartsWith("ALERT: ") && !message.StartsWith("NOTIFY: ") && message != "Home position set." && message != "You died and have been teleported to your home location")
|
||||
message = "/" + message;
|
||||
AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage);
|
||||
alertPack.AgentData.AgentID = AgentId;
|
||||
alertPack.AlertData.Message = Util.StringToBytes256(message);
|
||||
|
@ -6214,7 +6223,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
if (appear.ObjectData.TextureEntry.Length > 1)
|
||||
te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
|
||||
|
||||
handlerSetAppearance(sender, te, visualparams);
|
||||
List<CachedTextureRequestArg> hashes = new List<CachedTextureRequestArg>();
|
||||
for (int i = 0; i < appear.WearableData.Length; i++)
|
||||
{
|
||||
CachedTextureRequestArg arg = new CachedTextureRequestArg();
|
||||
arg.BakedTextureIndex = appear.WearableData[i].TextureIndex;
|
||||
arg.WearableHashID = appear.WearableData[i].CacheID;
|
||||
hashes.Add(arg);
|
||||
}
|
||||
|
||||
handlerSetAppearance(sender, te, visualparams, hashes);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -11487,11 +11505,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
requestArgs.Add(arg);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
|
||||
if (handlerCachedTextureRequest != null)
|
||||
{
|
||||
handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[CLIENT VIEW]: AgentTextureCached packet handler threw an exception, {0}", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -11916,17 +11942,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method);
|
||||
}
|
||||
|
||||
public bool AddMoney(int debit)
|
||||
{
|
||||
if (m_moneyBalance + debit >= 0)
|
||||
{
|
||||
m_moneyBalance += debit;
|
||||
SendMoneyBalance(UUID.Zero, true, Util.StringToBytes256("Poof Poof!"), m_moneyBalance);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void HandleAutopilot(Object sender, string method, List<String> args)
|
||||
{
|
||||
float locx = 0;
|
||||
|
|
|
@ -147,7 +147,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
/// <param name="visualParam"></param>
|
||||
public void SetAppearance(IScenePresence sp, AvatarAppearance appearance)
|
||||
{
|
||||
SetAppearance(sp, appearance.Texture, appearance.VisualParams);
|
||||
DoSetAppearance(sp, appearance.Texture, appearance.VisualParams, new List<CachedTextureRequestArg>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -157,6 +157,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
/// <param name="texture"></param>
|
||||
/// <param name="visualParam"></param>
|
||||
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
{
|
||||
DoSetAppearance(sp, textureEntry, visualParams, new List<CachedTextureRequestArg>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set appearance data (texture asset IDs and slider settings)
|
||||
/// </summary>
|
||||
/// <param name="sp"></param>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="visualParam"></param>
|
||||
protected void DoSetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
|
||||
|
@ -191,7 +202,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
if (textureEntry != null)
|
||||
{
|
||||
// m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
|
||||
|
||||
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
|
||||
|
||||
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
|
||||
|
@ -202,6 +212,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc))
|
||||
RequestRebake(sp, true);
|
||||
|
||||
// Save the wearble hashes in the appearance
|
||||
sp.Appearance.ResetTextureHashes();
|
||||
if (m_reusetextures)
|
||||
{
|
||||
foreach (CachedTextureRequestArg arg in hashes)
|
||||
sp.Appearance.SetTextureHash(arg.BakedTextureIndex,arg.WearableHashID);
|
||||
}
|
||||
|
||||
// This appears to be set only in the final stage of the appearance
|
||||
// update transaction. In theory, we should be able to do an immediate
|
||||
// appearance send and save here.
|
||||
|
@ -622,12 +640,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
/// <param name="client"></param>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="visualParam"></param>
|
||||
private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes)
|
||||
{
|
||||
// m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
if (sp != null)
|
||||
SetAppearance(sp, textureEntry, visualParams);
|
||||
DoSetAppearance(sp, textureEntry, visualParams, hashes);
|
||||
else
|
||||
m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
|
||||
}
|
||||
|
@ -684,7 +702,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
/// <param name="cachedTextureRequest"></param>
|
||||
private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest)
|
||||
{
|
||||
// m_log.WarnFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId);
|
||||
// m_log.DebugFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId);
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
|
||||
List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>();
|
||||
|
@ -695,23 +713,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
|
||||
if (m_reusetextures)
|
||||
{
|
||||
// this is the most insanely dumb way to do this... however it seems to
|
||||
// actually work. if the appearance has been reset because wearables have
|
||||
// changed then the texture entries are zero'd out until the bakes are
|
||||
// uploaded. on login, if the textures exist in the cache (eg if you logged
|
||||
// into the simulator recently, then the appearance will pull those and send
|
||||
// them back in the packet and you won't have to rebake. if the textures aren't
|
||||
// in the cache then the intial makeroot() call in scenepresence will zero
|
||||
// them out.
|
||||
//
|
||||
// a better solution (though how much better is an open question) is to
|
||||
// store the hashes in the appearance and compare them. Thats's coming.
|
||||
|
||||
if (sp.Appearance.GetTextureHash(index) == request.WearableHashID)
|
||||
{
|
||||
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index];
|
||||
if (face != null)
|
||||
texture = face.TextureID;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We know that that hash is wrong, null it out
|
||||
// and wait for the setappearance call
|
||||
sp.Appearance.SetTextureHash(index,UUID.Zero);
|
||||
}
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index);
|
||||
// m_log.WarnFormat("[AVFACTORY]: use texture {0} for index {1}; hash={2}",texture,index,request.WearableHashID);
|
||||
}
|
||||
|
||||
CachedTextureResponseArg response = new CachedTextureResponseArg();
|
||||
|
|
|
@ -371,7 +371,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
foreach (string fid in outstanding)
|
||||
{
|
||||
UUID fromAgentID;
|
||||
string firstname = "Unknown", lastname = "User";
|
||||
string firstname = "Unknown", lastname = "UserFMSFOIN";
|
||||
if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname))
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid);
|
||||
|
@ -397,7 +397,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
|
||||
protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
||||
{
|
||||
first = "Unknown"; last = "User";
|
||||
first = "Unknown"; last = "UserFMGAI";
|
||||
if (!UUID.TryParse(fid, out agentID))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -293,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
|
||||
protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
||||
{
|
||||
first = "Unknown"; last = "User";
|
||||
first = "Unknown"; last = "UserHGGAI";
|
||||
if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
|
||||
return true;
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
|
||||
public new void Initialise(IConfigSource config)
|
||||
{
|
||||
string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name);
|
||||
string umanmod = config.Configs["Modules"].GetString("UserManagementModule", null);
|
||||
if (umanmod == Name)
|
||||
{
|
||||
m_Enabled = true;
|
||||
|
|
|
@ -157,13 +157,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
}
|
||||
else
|
||||
{
|
||||
string[] names = GetUserNames(uuid);
|
||||
string[] names;
|
||||
bool foundRealName = TryGetUserNames(uuid, out names);
|
||||
|
||||
if (names.Length == 2)
|
||||
{
|
||||
//m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]);
|
||||
if (!foundRealName)
|
||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], uuid, remote_client.Name);
|
||||
|
||||
remote_client.SendNameReply(uuid, names[0], names[1]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,10 +249,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
}
|
||||
|
||||
// search the local cache
|
||||
lock (m_UserCache)
|
||||
{
|
||||
foreach (UserData data in m_UserCache.Values)
|
||||
{
|
||||
if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null &&
|
||||
(data.FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower())))
|
||||
users.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
AddAdditionalUsers(query, users);
|
||||
|
||||
|
@ -272,17 +280,24 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
}
|
||||
}
|
||||
|
||||
private string[] GetUserNames(UUID uuid)
|
||||
/// <summary>
|
||||
/// Try to get the names bound to the given uuid.
|
||||
/// </summary>
|
||||
/// <returns>True if the name was found, false if not.</returns>
|
||||
/// <param name='uuid'></param>
|
||||
/// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param>
|
||||
private bool TryGetUserNames(UUID uuid, out string[] names)
|
||||
{
|
||||
string[] returnstring = new string[2];
|
||||
names = new string[2];
|
||||
|
||||
lock (m_UserCache)
|
||||
{
|
||||
if (m_UserCache.ContainsKey(uuid))
|
||||
{
|
||||
returnstring[0] = m_UserCache[uuid].FirstName;
|
||||
returnstring[1] = m_UserCache[uuid].LastName;
|
||||
return returnstring;
|
||||
names[0] = m_UserCache[uuid].FirstName;
|
||||
names[1] = m_UserCache[uuid].LastName;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,8 +305,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
|
||||
if (account != null)
|
||||
{
|
||||
returnstring[0] = account.FirstName;
|
||||
returnstring[1] = account.LastName;
|
||||
names[0] = account.FirstName;
|
||||
names[1] = account.LastName;
|
||||
|
||||
UserData user = new UserData();
|
||||
user.FirstName = account.FirstName;
|
||||
|
@ -299,14 +314,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
|
||||
lock (m_UserCache)
|
||||
m_UserCache[uuid] = user;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
returnstring[0] = "Unknown";
|
||||
returnstring[1] = "User";
|
||||
}
|
||||
names[0] = "Unknown";
|
||||
names[1] = "UserUMMTGUN";
|
||||
|
||||
return returnstring;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#region IUserManagement
|
||||
|
@ -342,15 +359,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
|
||||
public string GetUserName(UUID uuid)
|
||||
{
|
||||
string[] names = GetUserNames(uuid);
|
||||
string[] names;
|
||||
TryGetUserNames(uuid, out names);
|
||||
|
||||
if (names.Length == 2)
|
||||
{
|
||||
string firstname = names[0];
|
||||
string lastname = names[1];
|
||||
|
||||
return firstname + " " + lastname;
|
||||
|
||||
}
|
||||
|
||||
return "(hippos)";
|
||||
}
|
||||
|
||||
|
@ -466,12 +485,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
//ignore updates without creator data
|
||||
return;
|
||||
}
|
||||
|
||||
//try update unknown users
|
||||
//and creator's home URL's
|
||||
if ((oldUser.FirstName == "Unknown" && !creatorData.Contains ("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith (oldUser.HomeURL)))
|
||||
{
|
||||
m_UserCache.Remove (id);
|
||||
// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData,oldUser.HomeURL);
|
||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData, oldUser.HomeURL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -516,7 +536,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
else
|
||||
{
|
||||
user.FirstName = "Unknown";
|
||||
user.LastName = "User";
|
||||
user.LastName = "UserUMMAU";
|
||||
}
|
||||
|
||||
AddUserInternal (user);
|
||||
|
@ -547,6 +567,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
|
||||
protected void RegisterConsoleCmds()
|
||||
{
|
||||
MainConsole.Instance.Commands.AddCommand("Users", true,
|
||||
"show name",
|
||||
"show name <uuid>",
|
||||
"Show the bindings between a single user UUID and a user name",
|
||||
String.Empty,
|
||||
HandleShowUser);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand("Users", true,
|
||||
"show names",
|
||||
"show names",
|
||||
|
@ -555,26 +582,54 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
HandleShowUsers);
|
||||
}
|
||||
|
||||
private void HandleShowUsers(string module, string[] cmd)
|
||||
private void HandleShowUser(string module, string[] cmd)
|
||||
{
|
||||
if (cmd.Length < 3)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Usage: show name <uuid>");
|
||||
return;
|
||||
}
|
||||
|
||||
UUID userId;
|
||||
if (!ConsoleUtil.TryParseConsoleUuid(MainConsole.Instance, cmd[2], out userId))
|
||||
return;
|
||||
|
||||
string[] names;
|
||||
|
||||
UserData ud;
|
||||
|
||||
lock (m_UserCache)
|
||||
{
|
||||
if (m_UserCache.Count == 0)
|
||||
if (!m_UserCache.TryGetValue(userId, out ud))
|
||||
{
|
||||
MainConsole.Instance.Output("No users found");
|
||||
MainConsole.Instance.OutputFormat("No name known for user with id {0}", userId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MainConsole.Instance.Output("UUID User Name");
|
||||
MainConsole.Instance.Output("-----------------------------------------------------------------------------");
|
||||
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
||||
cdt.AddColumn("UUID", 36);
|
||||
cdt.AddColumn("Name", 30);
|
||||
cdt.AddColumn("HomeURL", 40);
|
||||
cdt.AddRow(userId, string.Format("{0} {1}", ud.FirstName, ud.LastName), ud.HomeURL);
|
||||
|
||||
MainConsole.Instance.Output(cdt.ToString());
|
||||
}
|
||||
|
||||
private void HandleShowUsers(string module, string[] cmd)
|
||||
{
|
||||
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
||||
cdt.AddColumn("UUID", 36);
|
||||
cdt.AddColumn("Name", 30);
|
||||
cdt.AddColumn("HomeURL", 40);
|
||||
|
||||
lock (m_UserCache)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
|
||||
{
|
||||
MainConsole.Instance.Output(String.Format("{0} {1} {2} ({3})",
|
||||
kvp.Key, kvp.Value.FirstName, kvp.Value.LastName, kvp.Value.HomeURL));
|
||||
cdt.AddRow(kvp.Key, string.Format("{0} {1}", kvp.Value.FirstName, kvp.Value.LastName), kvp.Value.HomeURL);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
MainConsole.Instance.Output(cdt.ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -369,6 +369,15 @@ namespace OpenSim.Region.CoreModules.World.Sound
|
|||
});
|
||||
}
|
||||
|
||||
public void SetSoundQueueing(UUID objectID, bool shouldQueue)
|
||||
{
|
||||
SceneObjectPart part;
|
||||
if (!m_scene.TryGetSceneObjectPart(objectID, out part))
|
||||
return;
|
||||
|
||||
part.SoundQueueing = shouldQueue;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,6 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// <param name="sound">Sound asset ID</param>
|
||||
/// <param name="volume">Sound volume</param>
|
||||
/// <param name="triggered">Triggered or not.</param>
|
||||
/// <param name="flags"></param>
|
||||
/// <param name="radius">Sound radius</param>
|
||||
/// <param name="useMaster">Play using sound master</param>
|
||||
/// <param name="isMaster">Play as sound master</param>
|
||||
|
@ -123,5 +122,12 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// <param name="max">AABB top north-east corner</param>
|
||||
void TriggerSoundLimited(UUID objectID, UUID sound, double volume,
|
||||
Vector3 min, Vector3 max);
|
||||
|
||||
/// <summary>
|
||||
/// Set whether sounds on the given prim should be queued.
|
||||
/// </summary>
|
||||
/// <param name='objectID'></param>
|
||||
/// <param name='shouldQueue'></param>
|
||||
void SetSoundQueueing(UUID objectID, bool shouldQueue);
|
||||
}
|
||||
}
|
|
@ -1499,7 +1499,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (!userExposed)
|
||||
dupe.IsAttachment = true;
|
||||
|
||||
dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
|
||||
dupe.m_sittingAvatars = new List<UUID>();
|
||||
|
||||
if (!userExposed)
|
||||
{
|
||||
|
|
|
@ -219,6 +219,14 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public double SoundRadius;
|
||||
|
||||
/// <summary>
|
||||
/// Should sounds played from this prim be queued?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This should only be changed by sound modules. It is up to sound modules as to how they interpret this setting.
|
||||
/// </remarks>
|
||||
public bool SoundQueueing { get; set; }
|
||||
|
||||
public uint TimeStampFull;
|
||||
|
||||
public uint TimeStampLastActivity; // Will be used for AutoReturn
|
||||
|
@ -1791,6 +1799,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
|
||||
dupe.Shape.ExtraParams = extraP;
|
||||
|
||||
dupe.PayPrice = (int[])PayPrice.Clone();
|
||||
|
||||
dupe.DynAttrs.CopyFrom(DynAttrs);
|
||||
|
||||
if (userExposed)
|
||||
|
@ -2429,7 +2439,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (soundModule != null)
|
||||
{
|
||||
soundModule.SendSound(UUID, CollisionSound,
|
||||
CollisionSoundVolume, true, (byte)0, 0, false,
|
||||
CollisionSoundVolume, true, 0, 0, false,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2713,7 +2713,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// again here... this comes after the cached appearance check because the avatars
|
||||
// appearance goes into the avatar update packet
|
||||
SendAvatarDataToAllAgents();
|
||||
SendAppearanceToAgent(this);
|
||||
|
||||
// This invocation always shows up in the viewer logs as an error.
|
||||
// SendAppearanceToAgent(this);
|
||||
|
||||
// If we are using the the cached appearance then send it out to everyone
|
||||
if (cachedappearance)
|
||||
|
|
|
@ -907,7 +907,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
|||
// Mimicking LLClientView which gets always set appearance from client.
|
||||
AvatarAppearance appearance;
|
||||
m_scene.GetAvatarAppearance(this, out appearance);
|
||||
OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone());
|
||||
OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(), new List<CachedTextureRequestArg>());
|
||||
}
|
||||
|
||||
public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
|
||||
|
@ -1056,7 +1056,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
|||
{
|
||||
}
|
||||
|
||||
public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance)
|
||||
public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance, int transactionType, UUID sourceID, bool sourceIsGroup, UUID destID, bool destIsGroup, int amount, string item)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -1196,11 +1196,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
|||
|
||||
}
|
||||
|
||||
public bool AddMoney(int debit)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition)
|
||||
{
|
||||
|
||||
|
|
|
@ -764,7 +764,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
|||
remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group.");
|
||||
return UUID.Zero;
|
||||
}
|
||||
money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, "Group Creation");
|
||||
money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, MoneyTransactionType.GroupCreate);
|
||||
}
|
||||
UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient));
|
||||
|
||||
|
|
|
@ -191,9 +191,14 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule
|
|||
// Please do not refactor these to be just one method
|
||||
// Existing implementations need the distinction
|
||||
//
|
||||
public void ApplyCharge(UUID agentID, int amount, string text)
|
||||
public void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData)
|
||||
{
|
||||
}
|
||||
|
||||
public void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type)
|
||||
{
|
||||
}
|
||||
|
||||
public void ApplyUploadCharge(UUID agentID, int amount, string text)
|
||||
{
|
||||
}
|
||||
|
@ -322,7 +327,7 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule
|
|||
client.SendAlertMessage(e.Message + " ");
|
||||
}
|
||||
|
||||
client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds);
|
||||
client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds, 0, UUID.Zero, false, UUID.Zero, false, 0, String.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -385,12 +390,12 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule
|
|||
{
|
||||
if (sender != null)
|
||||
{
|
||||
sender.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(senderID));
|
||||
sender.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(senderID), 0, UUID.Zero, false, UUID.Zero, false, 0, String.Empty);
|
||||
}
|
||||
|
||||
if (receiver != null)
|
||||
{
|
||||
receiver.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(receiverID));
|
||||
receiver.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(receiverID), 0, UUID.Zero, false, UUID.Zero, false, 0, String.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -694,7 +694,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
|||
{
|
||||
}
|
||||
|
||||
public virtual void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance)
|
||||
public virtual void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance, int transactionType, UUID sourceID, bool sourceIsGroup, UUID destID, bool destIsGroup, int amount, string item)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -866,11 +866,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
|||
{
|
||||
}
|
||||
|
||||
public bool AddMoney(int debit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong time, uint dlen, uint ylen, float phase)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -251,6 +251,16 @@ public override BulletShape CreateMeshShape(BulletWorld world,
|
|||
BSPhysicsShapeType.SHAPE_MESH);
|
||||
}
|
||||
|
||||
public override BulletShape CreateGImpactShape(BulletWorld world,
|
||||
int indicesCount, int[] indices,
|
||||
int verticesCount, float[] vertices)
|
||||
{
|
||||
BulletWorldUnman worldu = world as BulletWorldUnman;
|
||||
return new BulletShapeUnman(
|
||||
BSAPICPP.CreateGImpactShape2(worldu.ptr, indicesCount, indices, verticesCount, vertices),
|
||||
BSPhysicsShapeType.SHAPE_GIMPACT);
|
||||
}
|
||||
|
||||
public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls)
|
||||
{
|
||||
BulletWorldUnman worldu = world as BulletWorldUnman;
|
||||
|
@ -1425,6 +1435,11 @@ public static extern IntPtr CreateMeshShape2(IntPtr world,
|
|||
int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
|
||||
int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices );
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateGImpactShape2(IntPtr world,
|
||||
int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
|
||||
int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices );
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateHullShape2(IntPtr world,
|
||||
int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls);
|
||||
|
|
|
@ -1475,7 +1475,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||
break;
|
||||
case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE:
|
||||
ret = BSPhysicsShapeType.SHAPE_MESH;
|
||||
ret = BSPhysicsShapeType.SHAPE_CONVEXHULL;
|
||||
break;
|
||||
case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE:
|
||||
ret = BSPhysicsShapeType.SHAPE_HULL;
|
||||
|
@ -1503,7 +1503,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
ret = BSPhysicsShapeType.SHAPE_CONE;
|
||||
break;
|
||||
case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE:
|
||||
ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||
ret = BSPhysicsShapeType.SHAPE_CONVEXHULL;
|
||||
break;
|
||||
case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE:
|
||||
ret = BSPhysicsShapeType.SHAPE_CYLINDER;
|
||||
|
@ -1547,7 +1547,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
break;
|
||||
///Used for GIMPACT Trimesh integration
|
||||
case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE:
|
||||
ret = BSPhysicsShapeType.SHAPE_MESH;
|
||||
ret = BSPhysicsShapeType.SHAPE_GIMPACT;
|
||||
break;
|
||||
///Multimaterial mesh
|
||||
case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE:
|
||||
|
@ -1820,6 +1820,11 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH);
|
||||
|
||||
}
|
||||
public override BulletShape CreateGImpactShape(BulletWorld pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats)
|
||||
{
|
||||
// TODO:
|
||||
return null;
|
||||
}
|
||||
public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount )
|
||||
{
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ public enum BSPhysicsShapeType
|
|||
SHAPE_HEIGHTMAP = 23,
|
||||
SHAPE_AVATAR = 24,
|
||||
SHAPE_CONVEXHULL= 25,
|
||||
SHAPE_GIMPACT = 26,
|
||||
};
|
||||
|
||||
// The native shapes have predefined shape hash keys
|
||||
|
@ -321,6 +322,10 @@ public abstract BulletShape CreateMeshShape(BulletWorld world,
|
|||
int indicesCount, int[] indices,
|
||||
int verticesCount, float[] vertices );
|
||||
|
||||
public abstract BulletShape CreateGImpactShape(BulletWorld world,
|
||||
int indicesCount, int[] indices,
|
||||
int verticesCount, float[] vertices );
|
||||
|
||||
public abstract BulletShape CreateHullShape(BulletWorld world,
|
||||
int hullCount, float[] hulls);
|
||||
|
||||
|
|
|
@ -483,8 +483,15 @@ public sealed class BSCharacter : BSPhysObject
|
|||
{
|
||||
// Bullet assumes we know what we are doing when forcing orientation
|
||||
// so it lets us go against all the rules and just compensates for them later.
|
||||
// This forces rotation to be only around the Z axis and doesn't change any of the other axis.
|
||||
// This keeps us from flipping the capsule over which the veiwer does not understand.
|
||||
ForceOrientation = new OMV.Quaternion(0, 0, _orientation.Z,0);
|
||||
float oRoll, oPitch, oYaw;
|
||||
_orientation.GetEulerAngles(out oRoll, out oPitch, out oYaw);
|
||||
OMV.Quaternion trimmedOrientation = OMV.Quaternion.CreateFromEulers(0f, 0f, oYaw);
|
||||
// DetailLog("{0},BSCharacter.setOrientation,taint,val={1},valDir={2},conv={3},convDir={4}",
|
||||
// LocalID, _orientation, OMV.Vector3.UnitX * _orientation,
|
||||
// trimmedOrientation, OMV.Vector3.UnitX * trimmedOrientation);
|
||||
ForceOrientation = trimmedOrientation;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -617,7 +617,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// Vehicles report collision events so we know when it's on the ground
|
||||
m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||
|
||||
ControllingPrim.Inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass);
|
||||
Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass);
|
||||
ControllingPrim.Inertia = inertia * BSParam.VehicleInertiaFactor;
|
||||
m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia);
|
||||
m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody);
|
||||
|
||||
|
|
|
@ -89,6 +89,8 @@ public static class BSParam
|
|||
public static bool ShouldRemoveZeroWidthTriangles { get; private set; }
|
||||
public static bool ShouldUseBulletHACD { get; set; }
|
||||
public static bool ShouldUseSingleConvexHullForPrims { get; set; }
|
||||
public static bool ShouldUseGImpactShapeForPrims { get; set; }
|
||||
public static bool ShouldUseAssetHulls { get; set; }
|
||||
|
||||
public static float TerrainImplementation { get; set; }
|
||||
public static int TerrainMeshMagnification { get; private set; }
|
||||
|
@ -146,6 +148,7 @@ public static class BSParam
|
|||
public static float VehicleRestitution { get; private set; }
|
||||
public static Vector3 VehicleLinearFactor { get; private set; }
|
||||
public static Vector3 VehicleAngularFactor { get; private set; }
|
||||
public static Vector3 VehicleInertiaFactor { get; private set; }
|
||||
public static float VehicleGroundGravityFudge { get; private set; }
|
||||
public static float VehicleAngularBankingTimescaleFudge { get; private set; }
|
||||
public static bool VehicleDebuggingEnable { get; private set; }
|
||||
|
@ -369,6 +372,10 @@ public static class BSParam
|
|||
false ),
|
||||
new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims",
|
||||
true ),
|
||||
new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists",
|
||||
false ),
|
||||
new ParameterDefn<bool>("ShouldUseAssetHulls", "If true, use hull if specified in the mesh asset info",
|
||||
true ),
|
||||
|
||||
new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions",
|
||||
5 ),
|
||||
|
@ -577,6 +584,8 @@ public static class BSParam
|
|||
new Vector3(1f, 1f, 1f) ),
|
||||
new ParameterDefn<Vector3>("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (<0,0,0> to <1,1,1>)",
|
||||
new Vector3(1f, 1f, 1f) ),
|
||||
new ParameterDefn<Vector3>("VehicleInertiaFactor", "Fraction of physical inertia applied (<0,0,0> to <1,1,1>)",
|
||||
new Vector3(1f, 1f, 1f) ),
|
||||
new ParameterDefn<float>("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)",
|
||||
0.0f ),
|
||||
new ParameterDefn<float>("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)",
|
||||
|
|
|
@ -511,7 +511,10 @@ public class BSPrim : BSPhysObject
|
|||
|
||||
PhysScene.TaintedObject("setVehicleType", delegate()
|
||||
{
|
||||
ZeroMotion(true /* inTaintTime */);
|
||||
// Some vehicle scripts change vehicle type on the fly as an easy way to
|
||||
// change all the parameters. Like a plane changing to CAR when on the
|
||||
// ground. In this case, don't want to zero motion.
|
||||
// ZeroMotion(true /* inTaintTime */);
|
||||
VehicleActor.ProcessTypeChange(type);
|
||||
ActivateIfPhysical(false);
|
||||
});
|
||||
|
|
|
@ -268,6 +268,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
// Do any replacements in the parameters
|
||||
m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
|
||||
}
|
||||
else
|
||||
{
|
||||
BulletEngineName = "BulletUnmanaged";
|
||||
m_physicsLoggingEnabled = false;
|
||||
VehicleLoggingEnabled = false;
|
||||
}
|
||||
|
||||
// The material characteristics.
|
||||
BSMaterials.InitializeFromDefaults(Params);
|
||||
|
@ -322,6 +328,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
BSParam.ShouldUseBulletHACD = false;
|
||||
m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader);
|
||||
BSParam.ShouldUseSingleConvexHullForPrims = false;
|
||||
m_log.InfoFormat("{0} Disabling ShouldUseGImpactShapeForPrims", LogHeader);
|
||||
BSParam.ShouldUseGImpactShapeForPrims = false;
|
||||
m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader);
|
||||
BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap;
|
||||
break;
|
||||
|
|
|
@ -230,6 +230,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
BSShape potentialHull = null;
|
||||
|
||||
PrimitiveBaseShape pbs = prim.BaseShape;
|
||||
// Use a simple, one section convex shape for prims that are probably convex (no cuts or twists)
|
||||
if (BSParam.ShouldUseSingleConvexHullForPrims
|
||||
&& pbs != null
|
||||
&& !pbs.SculptEntry
|
||||
|
@ -238,7 +239,17 @@ public sealed class BSShapeCollection : IDisposable
|
|||
{
|
||||
potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim);
|
||||
}
|
||||
else
|
||||
// Use the GImpact shape if it is a prim that has some concaveness
|
||||
if (potentialHull == null
|
||||
&& BSParam.ShouldUseGImpactShapeForPrims
|
||||
&& pbs != null
|
||||
&& !pbs.SculptEntry
|
||||
)
|
||||
{
|
||||
potentialHull = BSShapeGImpact.GetReference(m_physicsScene, false /* forceRebuild */, prim);
|
||||
}
|
||||
// If not any of the simple cases, just make a hull
|
||||
if (potentialHull == null)
|
||||
{
|
||||
potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
|
||||
}
|
||||
|
@ -261,7 +272,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
}
|
||||
else
|
||||
{
|
||||
// Update prim.BSShape to reference a mesh of this shape.
|
||||
// Non-physical objects should be just meshes.
|
||||
BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
|
||||
// If the current shape is not what is on the prim at the moment, time to change.
|
||||
if (!prim.PhysShape.HasPhysicalShape
|
||||
|
|
|
@ -31,6 +31,7 @@ using System.Text;
|
|||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using OpenSim.Region.Physics.Meshing;
|
||||
using OpenSim.Region.Physics.ConvexDecompositionDotNet;
|
||||
|
||||
using OMV = OpenMetaverse;
|
||||
|
@ -422,15 +423,32 @@ public class BSShapeMesh : BSShape
|
|||
outMesh = foundDesc;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public delegate BulletShape CreateShapeCall(BulletWorld world, int indicesCount, int[] indices, int verticesCount, float[] vertices );
|
||||
private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
|
||||
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
||||
{
|
||||
return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod,
|
||||
(w, iC, i, vC, v) => physicsScene.PE.CreateMeshShape(w, iC, i, vC, v) );
|
||||
}
|
||||
|
||||
// Code that uses the mesher to create the index/vertices info for a trimesh shape.
|
||||
// This is used by the passed 'makeShape' call to create the Bullet mesh shape.
|
||||
// The actual build call is passed so this logic can be used by several of the shapes that use a
|
||||
// simple mesh as their base shape.
|
||||
public static BulletShape CreatePhysicalMeshShape(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
|
||||
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod, CreateShapeCall makeShape)
|
||||
{
|
||||
BulletShape newShape = new BulletShape();
|
||||
|
||||
IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
|
||||
IMesh meshData = null;
|
||||
lock (physicsScene.mesher)
|
||||
{
|
||||
meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
|
||||
false, // say it is not physical so a bounding box is not built
|
||||
false // do not cache the mesh and do not use previously built versions
|
||||
);
|
||||
}
|
||||
|
||||
if (meshData != null)
|
||||
{
|
||||
|
@ -482,8 +500,7 @@ public class BSShapeMesh : BSShape
|
|||
|
||||
if (realIndicesIndex != 0)
|
||||
{
|
||||
newShape = physicsScene.PE.CreateMeshShape(physicsScene.World,
|
||||
realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats);
|
||||
newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -561,13 +578,74 @@ public class BSShapeHull : BSShape
|
|||
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
||||
{
|
||||
BulletShape newShape = new BulletShape();
|
||||
IntPtr hullPtr = IntPtr.Zero;
|
||||
|
||||
if (BSParam.ShouldUseBulletHACD)
|
||||
IMesh meshData = null;
|
||||
List<List<OMV.Vector3>> allHulls = null;
|
||||
lock (physicsScene.mesher)
|
||||
{
|
||||
// Pass true for physicalness as this prevents the creation of bounding box which is not needed
|
||||
meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
|
||||
|
||||
// If we should use the asset's hull info, fetch it out of the locked mesher
|
||||
if (meshData != null && BSParam.ShouldUseAssetHulls)
|
||||
{
|
||||
Meshmerizer realMesher = physicsScene.mesher as Meshmerizer;
|
||||
if (realMesher != null)
|
||||
{
|
||||
allHulls = realMesher.GetConvexHulls(size);
|
||||
}
|
||||
if (allHulls == null)
|
||||
{
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,noAssetHull", prim.LocalID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there is hull data in the mesh asset, build the hull from that
|
||||
if (allHulls != null && BSParam.ShouldUseAssetHulls)
|
||||
{
|
||||
int hullCount = allHulls.Count;
|
||||
int totalVertices = 1; // include one for the count of the hulls
|
||||
// Using the structure described for HACD hulls, create the memory sturcture
|
||||
// to pass the hull data to the creater.
|
||||
foreach (List<OMV.Vector3> hullVerts in allHulls)
|
||||
{
|
||||
totalVertices += 4; // add four for the vertex count and centroid
|
||||
totalVertices += hullVerts.Count * 3; // one vertex is three dimensions
|
||||
}
|
||||
float[] convHulls = new float[totalVertices];
|
||||
|
||||
convHulls[0] = (float)hullCount;
|
||||
int jj = 1;
|
||||
foreach (List<OMV.Vector3> hullVerts in allHulls)
|
||||
{
|
||||
convHulls[jj + 0] = hullVerts.Count;
|
||||
convHulls[jj + 1] = 0f; // centroid x,y,z
|
||||
convHulls[jj + 2] = 0f;
|
||||
convHulls[jj + 3] = 0f;
|
||||
jj += 4;
|
||||
foreach (OMV.Vector3 oneVert in hullVerts)
|
||||
{
|
||||
convHulls[jj + 0] = oneVert.X;
|
||||
convHulls[jj + 1] = oneVert.Y;
|
||||
convHulls[jj + 2] = oneVert.Z;
|
||||
jj += 3;
|
||||
}
|
||||
}
|
||||
|
||||
// create the hull data structure in Bullet
|
||||
newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
|
||||
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,hulls={1},totVert={2},shape={3}",
|
||||
prim.LocalID, hullCount, totalVertices, newShape);
|
||||
}
|
||||
|
||||
// If no hull specified in the asset and we should use Bullet's HACD approximation...
|
||||
if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD)
|
||||
{
|
||||
// Build the hull shape from an existing mesh shape.
|
||||
// The mesh should have already been created in Bullet.
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID);
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,entry", prim.LocalID);
|
||||
BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim);
|
||||
|
||||
if (meshShape.physShapeInfo.HasPhysicalShape)
|
||||
|
@ -585,19 +663,16 @@ public class BSShapeHull : BSShape
|
|||
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
|
||||
newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms);
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape);
|
||||
|
||||
// Now done with the mesh shape.
|
||||
meshShape.Dereference(physicsScene);
|
||||
}
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||
}
|
||||
if (!newShape.HasPhysicalShape)
|
||||
{
|
||||
// Build a new hull in the physical world using the C# HACD algorigthm.
|
||||
// Pass true for physicalness as this prevents the creation of bounding box which is not needed
|
||||
IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
|
||||
if (meshData != null)
|
||||
|
||||
// If no other hull specifications, use our HACD hull approximation.
|
||||
if (!newShape.HasPhysicalShape && meshData != null)
|
||||
{
|
||||
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
|
||||
{
|
||||
|
@ -707,7 +782,6 @@ public class BSShapeHull : BSShape
|
|||
newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
|
||||
}
|
||||
newShape.shapeKey = newHullKey;
|
||||
}
|
||||
return newShape;
|
||||
}
|
||||
// Callback from convex hull creater with a newly created hull.
|
||||
|
@ -803,6 +877,7 @@ public class BSShapeCompound : BSShape
|
|||
// Called at taint-time.
|
||||
private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape)
|
||||
{
|
||||
// TODO: figure a better way to go through all the shape types and find a possible instance.
|
||||
BSShapeMesh meshDesc;
|
||||
if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc))
|
||||
{
|
||||
|
@ -824,6 +899,14 @@ public class BSShapeCompound : BSShape
|
|||
}
|
||||
else
|
||||
{
|
||||
BSShapeGImpact gImpactDesc;
|
||||
if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc))
|
||||
{
|
||||
gImpactDesc.Dereference(physicsScene);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Didn't find it in the lists of specific types. It could be compound.
|
||||
if (physicsScene.PE.IsCompound(pShape))
|
||||
{
|
||||
BSShapeCompound recursiveCompound = new BSShapeCompound(pShape);
|
||||
|
@ -831,6 +914,7 @@ public class BSShapeCompound : BSShape
|
|||
}
|
||||
else
|
||||
{
|
||||
// If none of the above, maybe it is a simple native shape.
|
||||
if (physicsScene.PE.IsNativeShape(pShape))
|
||||
{
|
||||
BSShapeNative nativeShape = new BSShapeNative(pShape);
|
||||
|
@ -842,6 +926,7 @@ public class BSShapeCompound : BSShape
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================================================
|
||||
public class BSShapeConvexHull : BSShape
|
||||
|
@ -857,7 +942,7 @@ public class BSShapeConvexHull : BSShape
|
|||
float lod;
|
||||
System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||
|
||||
physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}",
|
||||
physicsScene.DetailLog("{0},BSShapeConvexHull,getReference,newKey={1},size={2},lod={3}",
|
||||
prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod);
|
||||
|
||||
BSShapeConvexHull retConvexHull = null;
|
||||
|
@ -937,6 +1022,98 @@ public class BSShapeConvexHull : BSShape
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
// ============================================================================================================
|
||||
public class BSShapeGImpact : BSShape
|
||||
{
|
||||
private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]";
|
||||
public static Dictionary<System.UInt64, BSShapeGImpact> GImpacts = new Dictionary<System.UInt64, BSShapeGImpact>();
|
||||
|
||||
public BSShapeGImpact(BulletShape pShape) : base(pShape)
|
||||
{
|
||||
}
|
||||
public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
|
||||
{
|
||||
float lod;
|
||||
System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||
|
||||
physicsScene.DetailLog("{0},BSShapeGImpact,getReference,newKey={1},size={2},lod={3}",
|
||||
prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod);
|
||||
|
||||
BSShapeGImpact retGImpact = null;
|
||||
lock (GImpacts)
|
||||
{
|
||||
if (GImpacts.TryGetValue(newMeshKey, out retGImpact))
|
||||
{
|
||||
// The mesh has already been created. Return a new reference to same.
|
||||
retGImpact.IncrementReference();
|
||||
}
|
||||
else
|
||||
{
|
||||
retGImpact = new BSShapeGImpact(new BulletShape());
|
||||
BulletShape newShape = retGImpact.CreatePhysicalGImpact(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod);
|
||||
|
||||
// Check to see if mesh was created (might require an asset).
|
||||
newShape = VerifyMeshCreated(physicsScene, newShape, prim);
|
||||
newShape.shapeKey = newMeshKey;
|
||||
if (!newShape.isNativeShape || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed)
|
||||
{
|
||||
// If a mesh was what was created, remember the built shape for later sharing.
|
||||
// Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh.
|
||||
GImpacts.Add(newMeshKey, retGImpact);
|
||||
}
|
||||
|
||||
retGImpact.physShapeInfo = newShape;
|
||||
}
|
||||
}
|
||||
return retGImpact;
|
||||
}
|
||||
|
||||
private BulletShape CreatePhysicalGImpact(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
|
||||
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
||||
{
|
||||
return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod,
|
||||
(w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) );
|
||||
}
|
||||
|
||||
public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim)
|
||||
{
|
||||
// Calling this reference means we want another handle to an existing shape
|
||||
// (usually linksets) so return this copy.
|
||||
IncrementReference();
|
||||
return this;
|
||||
}
|
||||
// Dereferencing a compound shape releases the hold on all the child shapes.
|
||||
public override void Dereference(BSScene physicsScene)
|
||||
{
|
||||
lock (GImpacts)
|
||||
{
|
||||
this.DecrementReference();
|
||||
physicsScene.DetailLog("{0},BSShapeGImpact.Dereference,shape={1}", BSScene.DetailLogZero, this);
|
||||
// TODO: schedule aging and destruction of unused meshes.
|
||||
}
|
||||
}
|
||||
// Loop through all the known hulls and return the description based on the physical address.
|
||||
public static bool TryGetGImpactByPtr(BulletShape pShape, out BSShapeGImpact outHull)
|
||||
{
|
||||
bool ret = false;
|
||||
BSShapeGImpact foundDesc = null;
|
||||
lock (GImpacts)
|
||||
{
|
||||
foreach (BSShapeGImpact sh in GImpacts.Values)
|
||||
{
|
||||
if (sh.physShapeInfo.ReferenceSame(pShape))
|
||||
{
|
||||
foundDesc = sh;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
outHull = foundDesc;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================================================
|
||||
public class BSShapeAvatar : BSShape
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
PROBLEMS TO LOOK INTO
|
||||
CURRENT PROBLEMS TO FIX AND/OR LOOK AT
|
||||
=================================================
|
||||
Nebadon vehicle ride, get up, ride again. Second time vehicle does not act correctly.
|
||||
Script changing rotation of child prim while vehicle moving (eg turning wheel) causes
|
||||
the wheel to appear to jump back. Looks like sending position from previous update.
|
||||
Vehicle ride, get up, ride again. Second time vehicle does not act correctly.
|
||||
Have to rez new vehicle and delete the old to fix situation.
|
||||
Hitting RESET on Nebadon's vehicle while riding causes vehicle to get into odd
|
||||
position state where it will not settle onto ground properly, etc
|
||||
Two of Nebadon vehicles in a sim max the CPU. This is new.
|
||||
A sitting, active vehicle bobs up and down a small amount.
|
||||
|
||||
CURRENT PRIORITIES
|
||||
=================================================
|
||||
Use the HACD convex hull routine in Bullet rather than the C# version.
|
||||
Speed up hullifying large meshes.
|
||||
Enable vehicle border crossings (at least as poorly as ODE)
|
||||
Terrain skirts
|
||||
Avatar created in previous region and not new region when crossing border
|
||||
|
@ -361,4 +357,6 @@ Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE.
|
|||
Nebadon vehicles turning funny in arena (DONE)
|
||||
Lock axis (DONE 20130401)
|
||||
Terrain detail: double terrain mesh detail (DONE)
|
||||
Use the HACD convex hull routine in Bullet rather than the C# version.
|
||||
Speed up hullifying large meshes. (DONE)
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
public class Meshmerizer : IMesher
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static string LogHeader = "[MESH]";
|
||||
|
||||
// Setting baseDir to a path will enable the dumping of raw files
|
||||
// raw files can be imported by blender so a visual inspection of the results can be done
|
||||
|
@ -72,6 +73,8 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
#else
|
||||
private const string baseDir = null; //"rawFiles";
|
||||
#endif
|
||||
// If 'true', lots of DEBUG logging of asset parsing details
|
||||
private bool debugDetail = false;
|
||||
|
||||
private bool cacheSculptMaps = true;
|
||||
private string decodedSculptMapPath = null;
|
||||
|
@ -80,6 +83,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
|
||||
|
||||
private List<List<Vector3>> mConvexHulls = null;
|
||||
private List<Vector3> mBoundingHull = null;
|
||||
|
||||
private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
|
||||
|
||||
|
@ -91,7 +95,10 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
|
||||
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
|
||||
if (mesh_config != null)
|
||||
{
|
||||
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
|
||||
debugDetail = mesh_config.GetBoolean("LogMeshDetails", debugDetail);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -321,6 +328,9 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
faces = new List<Face>();
|
||||
OSD meshOsd = null;
|
||||
|
||||
mConvexHulls = null;
|
||||
mBoundingHull = null;
|
||||
|
||||
if (primShape.SculptData.Length <= 0)
|
||||
{
|
||||
// XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this
|
||||
|
@ -357,29 +367,98 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
OSDMap physicsParms = null;
|
||||
OSDMap map = (OSDMap)meshOsd;
|
||||
if (map.ContainsKey("physics_shape"))
|
||||
{
|
||||
physicsParms = (OSDMap)map["physics_shape"]; // old asset format
|
||||
if (debugDetail) m_log.DebugFormat("{0} prim='{1}': using 'physics_shape' mesh data", LogHeader, primName);
|
||||
}
|
||||
else if (map.ContainsKey("physics_mesh"))
|
||||
{
|
||||
physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
|
||||
if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'physics_mesh' mesh data", LogHeader, primName);
|
||||
}
|
||||
else if (map.ContainsKey("medium_lod"))
|
||||
{
|
||||
physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh
|
||||
if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'medium_lod' mesh data", LogHeader, primName);
|
||||
}
|
||||
else if (map.ContainsKey("high_lod"))
|
||||
{
|
||||
physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :)
|
||||
if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'high_lod' mesh data", LogHeader, primName);
|
||||
}
|
||||
|
||||
if (map.ContainsKey("physics_convex"))
|
||||
{ // pull this out also in case physics engine can use it
|
||||
OSD convexBlockOsd = null;
|
||||
try
|
||||
{
|
||||
OSDMap convexBlock = (OSDMap)map["physics_convex"];
|
||||
if (convexBlock.ContainsKey("HullList"))
|
||||
{
|
||||
byte[] hullList = convexBlock["HullList"].AsBinary();
|
||||
int convexOffset = convexBlock["offset"].AsInteger() + (int)start;
|
||||
int convexSize = convexBlock["size"].AsInteger();
|
||||
|
||||
byte[] convexBytes = new byte[convexSize];
|
||||
|
||||
System.Buffer.BlockCopy(primShape.SculptData, convexOffset, convexBytes, 0, convexSize);
|
||||
|
||||
try
|
||||
{
|
||||
convexBlockOsd = DecompressOsd(convexBytes);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("{0} prim='{1}': exception decoding convex block: {2}", LogHeader, primName, e);
|
||||
//return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (convexBlockOsd != null && convexBlockOsd is OSDMap)
|
||||
{
|
||||
convexBlock = convexBlockOsd as OSDMap;
|
||||
|
||||
if (debugDetail)
|
||||
{
|
||||
string keys = LogHeader + " keys found in convexBlock: ";
|
||||
foreach (KeyValuePair<string, OSD> kvp in convexBlock)
|
||||
keys += "'" + kvp.Key + "' ";
|
||||
m_log.Debug(keys);
|
||||
}
|
||||
|
||||
Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f);
|
||||
if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3();
|
||||
Vector3 max = new Vector3(0.5f, 0.5f, 0.5f);
|
||||
if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3();
|
||||
|
||||
// decompress and decode hull points
|
||||
byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary();
|
||||
List<Vector3> boundingHull = null;
|
||||
|
||||
if (convexBlock.ContainsKey("BoundingVerts"))
|
||||
{
|
||||
byte[] boundingVertsBytes = convexBlock["BoundingVerts"].AsBinary();
|
||||
boundingHull = new List<Vector3>();
|
||||
for (int i = 0; i < boundingVertsBytes.Length; )
|
||||
{
|
||||
ushort uX = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
|
||||
ushort uY = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
|
||||
ushort uZ = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
|
||||
|
||||
Vector3 pos = new Vector3(
|
||||
Utils.UInt16ToFloat(uX, min.X, max.X),
|
||||
Utils.UInt16ToFloat(uY, min.Y, max.Y),
|
||||
Utils.UInt16ToFloat(uZ, min.Z, max.Z)
|
||||
);
|
||||
|
||||
boundingHull.Add(pos);
|
||||
}
|
||||
|
||||
mBoundingHull = boundingHull;
|
||||
if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed bounding hull. nVerts={2}", LogHeader, primName, mBoundingHull.Count);
|
||||
}
|
||||
|
||||
if (convexBlock.ContainsKey("HullList"))
|
||||
{
|
||||
byte[] hullList = convexBlock["HullList"].AsBinary();
|
||||
|
||||
byte[] posBytes = convexBlock["Positions"].AsBinary();
|
||||
|
||||
List<List<Vector3>> hulls = new List<List<Vector3>>();
|
||||
int posNdx = 0;
|
||||
|
@ -408,11 +487,17 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
}
|
||||
|
||||
mConvexHulls = hulls;
|
||||
if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed hulls. nHulls={2}", LogHeader, primName, mConvexHulls.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debugDetail) m_log.DebugFormat("{0} prim='{1}' has physics_convex but no HullList", LogHeader, primName);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("[MESH]: exception decoding convex block: {0}", e.Message);
|
||||
m_log.WarnFormat("{0} exception decoding convex block: {1}", LogHeader, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -438,7 +523,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString());
|
||||
m_log.ErrorFormat("{0} prim='{1}': exception decoding physical mesh: {2}", LogHeader, primName, e);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -455,6 +540,9 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
if (subMeshOsd is OSDMap)
|
||||
AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
|
||||
}
|
||||
if (debugDetail)
|
||||
m_log.DebugFormat("{0} {1}: mesh decoded. offset={2}, size={3}, nCoords={4}, nFaces={5}",
|
||||
LogHeader, primName, physOffset, physSize, coords.Count, faces.Count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -772,6 +860,23 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// temporary prototype code - please do not use until the interface has been finalized!
|
||||
/// </summary>
|
||||
/// <param name="size">value to scale the hull points by</param>
|
||||
/// <returns>a list of vertices in the bounding hull if it exists and has been successfully decoded, otherwise null</returns>
|
||||
public List<Vector3> GetBoundingHull(Vector3 size)
|
||||
{
|
||||
if (mBoundingHull == null)
|
||||
return null;
|
||||
|
||||
List<Vector3> verts = new List<Vector3>();
|
||||
foreach (var vert in mBoundingHull)
|
||||
verts.Add(vert * size);
|
||||
|
||||
return verts;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// temporary prototype code - please do not use until the interface has been finalized!
|
||||
/// </summary>
|
||||
|
@ -788,6 +893,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
List<Vector3> verts = new List<Vector3>();
|
||||
foreach (var vert in hull)
|
||||
verts.Add(vert * size);
|
||||
hulls.Add(verts);
|
||||
}
|
||||
|
||||
return hulls;
|
||||
|
|
|
@ -2474,8 +2474,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
// send the sound, once, to all clients in range
|
||||
if (m_SoundModule != null)
|
||||
{
|
||||
m_SoundModule.SendSound(m_host.UUID,
|
||||
ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0,
|
||||
m_SoundModule.SendSound(
|
||||
m_host.UUID,
|
||||
ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound),
|
||||
volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None,
|
||||
0, false, false);
|
||||
}
|
||||
}
|
||||
|
@ -11822,7 +11824,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
public void llSetSoundQueueing(int queue)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
NotImplemented("llSetSoundQueueing");
|
||||
|
||||
if (m_SoundModule != null)
|
||||
m_SoundModule.SetSoundQueueing(m_host.UUID, queue == ScriptBaseClass.TRUE.value);
|
||||
}
|
||||
|
||||
public void llCollisionSprite(string impact_sprite)
|
||||
|
|
|
@ -651,7 +651,7 @@ namespace OpenSim.Tests.Common.Mock
|
|||
{
|
||||
}
|
||||
|
||||
public virtual void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance)
|
||||
public virtual void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance, int transactionType, UUID sourceID, bool sourceIsGroup, UUID destID, bool destIsGroup, int amount, string item)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -875,11 +875,6 @@ namespace OpenSim.Tests.Common.Mock
|
|||
|
||||
}
|
||||
|
||||
public bool AddMoney(int debit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong time, uint dlen, uint ylen, float phase)
|
||||
{
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1753,6 +1753,7 @@
|
|||
<Reference name="OpenSim.Region.CoreModules"/>
|
||||
<Reference name="OpenSim.Framework.Console"/>
|
||||
<Reference name="OpenSim.Region.Physics.Manager"/>
|
||||
<Reference name="OpenSim.Region.Physics.Meshing" path="../../../../bin/Physics/"/>
|
||||
<Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/>
|
||||
<Reference name="BulletXNA.dll" path="../../../../bin/"/>
|
||||
<Reference name="log4net.dll" path="../../../../bin/"/>
|
||||
|
|
Loading…
Reference in New Issue