diff options
author | Diva Canto | 2013-05-28 20:59:54 -0700 |
---|---|---|
committer | Diva Canto | 2013-05-28 20:59:54 -0700 |
commit | 233b9ec4d7739f324360366079469f2026c4ce41 (patch) | |
tree | 61266ac4ceffef23a74bad1dbd15bbe4fd103f82 /OpenSim/Region | |
parent | First change in Vivox for ages! -- added a lock to serialize calls to vivox s... (diff) | |
parent | BulletSim: don't zero motion when changing vehicle type. (diff) | |
download | opensim-SC_OLD-233b9ec4d7739f324360366079469f2026c4ce41.zip opensim-SC_OLD-233b9ec4d7739f324360366079469f2026c4ce41.tar.gz opensim-SC_OLD-233b9ec4d7739f324360366079469f2026c4ce41.tar.bz2 opensim-SC_OLD-233b9ec4d7739f324360366079469f2026c4ce41.tar.xz |
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim/Region')
28 files changed, 745 insertions, 289 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index e014471..e47397d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -345,7 +345,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
345 | 345 | ||
346 | // protected HashSet<uint> m_attachmentsSent; | 346 | // protected HashSet<uint> m_attachmentsSent; |
347 | 347 | ||
348 | private int m_moneyBalance; | ||
349 | private int m_animationSequenceNumber = 1; | 348 | private int m_animationSequenceNumber = 1; |
350 | private bool m_SendLogoutPacketWhenClosing = true; | 349 | private bool m_SendLogoutPacketWhenClosing = true; |
351 | 350 | ||
@@ -420,7 +419,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
420 | public string Name { get { return FirstName + " " + LastName; } } | 419 | public string Name { get { return FirstName + " " + LastName; } } |
421 | 420 | ||
422 | public uint CircuitCode { get { return m_circuitCode; } } | 421 | public uint CircuitCode { get { return m_circuitCode; } } |
423 | public int MoneyBalance { get { return m_moneyBalance; } } | ||
424 | public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } | 422 | public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } |
425 | 423 | ||
426 | /// <summary> | 424 | /// <summary> |
@@ -483,7 +481,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
483 | m_firstName = sessionInfo.LoginInfo.First; | 481 | m_firstName = sessionInfo.LoginInfo.First; |
484 | m_lastName = sessionInfo.LoginInfo.Last; | 482 | m_lastName = sessionInfo.LoginInfo.Last; |
485 | m_startpos = sessionInfo.LoginInfo.StartPos; | 483 | m_startpos = sessionInfo.LoginInfo.StartPos; |
486 | m_moneyBalance = 1000; | ||
487 | 484 | ||
488 | m_udpServer = udpServer; | 485 | m_udpServer = udpServer; |
489 | m_udpClient = udpClient; | 486 | m_udpClient = udpClient; |
@@ -1538,7 +1535,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1538 | OutPacket(tpProgress, ThrottleOutPacketType.Unknown); | 1535 | OutPacket(tpProgress, ThrottleOutPacketType.Unknown); |
1539 | } | 1536 | } |
1540 | 1537 | ||
1541 | public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance) | 1538 | 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) |
1542 | { | 1539 | { |
1543 | MoneyBalanceReplyPacket money = (MoneyBalanceReplyPacket)PacketPool.Instance.GetPacket(PacketType.MoneyBalanceReply); | 1540 | MoneyBalanceReplyPacket money = (MoneyBalanceReplyPacket)PacketPool.Instance.GetPacket(PacketType.MoneyBalanceReply); |
1544 | money.MoneyData.AgentID = AgentId; | 1541 | money.MoneyData.AgentID = AgentId; |
@@ -1546,7 +1543,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1546 | money.MoneyData.TransactionSuccess = success; | 1543 | money.MoneyData.TransactionSuccess = success; |
1547 | money.MoneyData.Description = description; | 1544 | money.MoneyData.Description = description; |
1548 | money.MoneyData.MoneyBalance = balance; | 1545 | money.MoneyData.MoneyBalance = balance; |
1549 | money.TransactionInfo.ItemDescription = Util.StringToBytes256("NONE"); | 1546 | money.TransactionInfo.TransactionType = transactionType; |
1547 | money.TransactionInfo.SourceID = sourceID; | ||
1548 | money.TransactionInfo.IsSourceGroup = sourceIsGroup; | ||
1549 | money.TransactionInfo.DestID = destID; | ||
1550 | money.TransactionInfo.IsDestGroup = destIsGroup; | ||
1551 | money.TransactionInfo.Amount = amount; | ||
1552 | money.TransactionInfo.ItemDescription = Util.StringToBytes256(item); | ||
1553 | |||
1550 | OutPacket(money, ThrottleOutPacketType.Task); | 1554 | OutPacket(money, ThrottleOutPacketType.Task); |
1551 | } | 1555 | } |
1552 | 1556 | ||
@@ -2279,6 +2283,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2279 | /// <returns></returns> | 2283 | /// <returns></returns> |
2280 | public AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal) | 2284 | public AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal) |
2281 | { | 2285 | { |
2286 | // Prepend a slash to make the message come up in the top right | ||
2287 | // again. | ||
2288 | // Allow special formats to be sent from aware modules. | ||
2289 | if (!modal && !message.StartsWith("ALERT: ") && !message.StartsWith("NOTIFY: ") && message != "Home position set." && message != "You died and have been teleported to your home location") | ||
2290 | message = "/" + message; | ||
2282 | AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); | 2291 | AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); |
2283 | alertPack.AgentData.AgentID = AgentId; | 2292 | alertPack.AgentData.AgentID = AgentId; |
2284 | alertPack.AlertData.Message = Util.StringToBytes256(message); | 2293 | alertPack.AlertData.Message = Util.StringToBytes256(message); |
@@ -6214,7 +6223,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6214 | if (appear.ObjectData.TextureEntry.Length > 1) | 6223 | if (appear.ObjectData.TextureEntry.Length > 1) |
6215 | te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); | 6224 | te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); |
6216 | 6225 | ||
6217 | handlerSetAppearance(sender, te, visualparams); | 6226 | List<CachedTextureRequestArg> hashes = new List<CachedTextureRequestArg>(); |
6227 | for (int i = 0; i < appear.WearableData.Length; i++) | ||
6228 | { | ||
6229 | CachedTextureRequestArg arg = new CachedTextureRequestArg(); | ||
6230 | arg.BakedTextureIndex = appear.WearableData[i].TextureIndex; | ||
6231 | arg.WearableHashID = appear.WearableData[i].CacheID; | ||
6232 | hashes.Add(arg); | ||
6233 | } | ||
6234 | |||
6235 | handlerSetAppearance(sender, te, visualparams, hashes); | ||
6218 | } | 6236 | } |
6219 | catch (Exception e) | 6237 | catch (Exception e) |
6220 | { | 6238 | { |
@@ -11487,12 +11505,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11487 | requestArgs.Add(arg); | 11505 | requestArgs.Add(arg); |
11488 | } | 11506 | } |
11489 | 11507 | ||
11490 | CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest; | 11508 | try |
11491 | if (handlerCachedTextureRequest != null) | ||
11492 | { | 11509 | { |
11493 | handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs); | 11510 | CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest; |
11511 | if (handlerCachedTextureRequest != null) | ||
11512 | { | ||
11513 | handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs); | ||
11514 | } | ||
11494 | } | 11515 | } |
11495 | 11516 | catch (Exception e) | |
11517 | { | ||
11518 | m_log.ErrorFormat("[CLIENT VIEW]: AgentTextureCached packet handler threw an exception, {0}", e); | ||
11519 | return false; | ||
11520 | } | ||
11521 | |||
11496 | return true; | 11522 | return true; |
11497 | } | 11523 | } |
11498 | 11524 | ||
@@ -11916,17 +11942,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11916 | m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method); | 11942 | m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method); |
11917 | } | 11943 | } |
11918 | 11944 | ||
11919 | public bool AddMoney(int debit) | ||
11920 | { | ||
11921 | if (m_moneyBalance + debit >= 0) | ||
11922 | { | ||
11923 | m_moneyBalance += debit; | ||
11924 | SendMoneyBalance(UUID.Zero, true, Util.StringToBytes256("Poof Poof!"), m_moneyBalance); | ||
11925 | return true; | ||
11926 | } | ||
11927 | return false; | ||
11928 | } | ||
11929 | |||
11930 | protected void HandleAutopilot(Object sender, string method, List<String> args) | 11945 | protected void HandleAutopilot(Object sender, string method, List<String> args) |
11931 | { | 11946 | { |
11932 | float locx = 0; | 11947 | float locx = 0; |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index b640b48..aea768e 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -147,7 +147,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
147 | /// <param name="visualParam"></param> | 147 | /// <param name="visualParam"></param> |
148 | public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) | 148 | public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) |
149 | { | 149 | { |
150 | SetAppearance(sp, appearance.Texture, appearance.VisualParams); | 150 | DoSetAppearance(sp, appearance.Texture, appearance.VisualParams, new List<CachedTextureRequestArg>()); |
151 | } | 151 | } |
152 | 152 | ||
153 | /// <summary> | 153 | /// <summary> |
@@ -158,9 +158,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
158 | /// <param name="visualParam"></param> | 158 | /// <param name="visualParam"></param> |
159 | public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) | 159 | public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) |
160 | { | 160 | { |
161 | // m_log.DebugFormat( | 161 | DoSetAppearance(sp, textureEntry, visualParams, new List<CachedTextureRequestArg>()); |
162 | // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", | 162 | } |
163 | // sp.Name, textureEntry, visualParams); | 163 | |
164 | /// <summary> | ||
165 | /// Set appearance data (texture asset IDs and slider settings) | ||
166 | /// </summary> | ||
167 | /// <param name="sp"></param> | ||
168 | /// <param name="texture"></param> | ||
169 | /// <param name="visualParam"></param> | ||
170 | protected void DoSetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes) | ||
171 | { | ||
172 | // m_log.DebugFormat( | ||
173 | // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", | ||
174 | // sp.Name, textureEntry, visualParams); | ||
164 | 175 | ||
165 | // TODO: This is probably not necessary any longer, just assume the | 176 | // TODO: This is probably not necessary any longer, just assume the |
166 | // textureEntry set implies that the appearance transaction is complete | 177 | // textureEntry set implies that the appearance transaction is complete |
@@ -190,18 +201,25 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
190 | // Process the baked texture array | 201 | // Process the baked texture array |
191 | if (textureEntry != null) | 202 | if (textureEntry != null) |
192 | { | 203 | { |
193 | // m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); | 204 | // m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); |
194 | 205 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); | |
195 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); | ||
196 | 206 | ||
197 | changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; | 207 | changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; |
198 | 208 | ||
199 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); | 209 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); |
200 | 210 | ||
201 | // If bake textures are missing and this is not an NPC, request a rebake from client | 211 | // If bake textures are missing and this is not an NPC, request a rebake from client |
202 | if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) | 212 | if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) |
203 | RequestRebake(sp, true); | 213 | RequestRebake(sp, true); |
204 | 214 | ||
215 | // Save the wearble hashes in the appearance | ||
216 | sp.Appearance.ResetTextureHashes(); | ||
217 | if (m_reusetextures) | ||
218 | { | ||
219 | foreach (CachedTextureRequestArg arg in hashes) | ||
220 | sp.Appearance.SetTextureHash(arg.BakedTextureIndex,arg.WearableHashID); | ||
221 | } | ||
222 | |||
205 | // This appears to be set only in the final stage of the appearance | 223 | // This appears to be set only in the final stage of the appearance |
206 | // update transaction. In theory, we should be able to do an immediate | 224 | // update transaction. In theory, we should be able to do an immediate |
207 | // appearance send and save here. | 225 | // appearance send and save here. |
@@ -235,13 +253,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
235 | 253 | ||
236 | public bool SendAppearance(UUID agentId) | 254 | public bool SendAppearance(UUID agentId) |
237 | { | 255 | { |
238 | // m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); | 256 | // m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); |
239 | 257 | ||
240 | ScenePresence sp = m_scene.GetScenePresence(agentId); | 258 | ScenePresence sp = m_scene.GetScenePresence(agentId); |
241 | if (sp == null) | 259 | if (sp == null) |
242 | { | 260 | { |
243 | // This is expected if the user has gone away. | 261 | // This is expected if the user has gone away. |
244 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); | 262 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); |
245 | return false; | 263 | return false; |
246 | } | 264 | } |
247 | 265 | ||
@@ -318,7 +336,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
318 | /// <param name="agentId"></param> | 336 | /// <param name="agentId"></param> |
319 | public void QueueAppearanceSend(UUID agentid) | 337 | public void QueueAppearanceSend(UUID agentid) |
320 | { | 338 | { |
321 | // m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); | 339 | // m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); |
322 | 340 | ||
323 | // 10000 ticks per millisecond, 1000 milliseconds per second | 341 | // 10000 ticks per millisecond, 1000 milliseconds per second |
324 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); | 342 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); |
@@ -331,7 +349,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
331 | 349 | ||
332 | public void QueueAppearanceSave(UUID agentid) | 350 | public void QueueAppearanceSave(UUID agentid) |
333 | { | 351 | { |
334 | // m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid); | 352 | // m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid); |
335 | 353 | ||
336 | // 10000 ticks per millisecond, 1000 milliseconds per second | 354 | // 10000 ticks per millisecond, 1000 milliseconds per second |
337 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); | 355 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); |
@@ -356,9 +374,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
356 | if (face == null) | 374 | if (face == null) |
357 | continue; | 375 | continue; |
358 | 376 | ||
359 | // m_log.DebugFormat( | 377 | // m_log.DebugFormat( |
360 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", | 378 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", |
361 | // face.TextureID, idx, client.Name, client.AgentId); | 379 | // face.TextureID, idx, client.Name, client.AgentId); |
362 | 380 | ||
363 | // if the texture is one of the "defaults" then skip it | 381 | // if the texture is one of the "defaults" then skip it |
364 | // this should probably be more intelligent (skirt texture doesnt matter | 382 | // this should probably be more intelligent (skirt texture doesnt matter |
@@ -373,7 +391,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
373 | return false; | 391 | return false; |
374 | } | 392 | } |
375 | 393 | ||
376 | // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); | 394 | // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); |
377 | 395 | ||
378 | // If we only found default textures, then the appearance is not cached | 396 | // If we only found default textures, then the appearance is not cached |
379 | return (defonly ? false : true); | 397 | return (defonly ? false : true); |
@@ -392,9 +410,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
392 | if (face == null) | 410 | if (face == null) |
393 | continue; | 411 | continue; |
394 | 412 | ||
395 | // m_log.DebugFormat( | 413 | // m_log.DebugFormat( |
396 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", | 414 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", |
397 | // face.TextureID, idx, client.Name, client.AgentId); | 415 | // face.TextureID, idx, client.Name, client.AgentId); |
398 | 416 | ||
399 | // if the texture is one of the "defaults" then skip it | 417 | // if the texture is one of the "defaults" then skip it |
400 | // this should probably be more intelligent (skirt texture doesnt matter | 418 | // this should probably be more intelligent (skirt texture doesnt matter |
@@ -458,9 +476,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
458 | if (bakeType == BakeType.Unknown) | 476 | if (bakeType == BakeType.Unknown) |
459 | continue; | 477 | continue; |
460 | 478 | ||
461 | // m_log.DebugFormat( | 479 | // m_log.DebugFormat( |
462 | // "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", | 480 | // "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", |
463 | // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); | 481 | // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); |
464 | 482 | ||
465 | int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); | 483 | int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); |
466 | Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture | 484 | Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture |
@@ -484,7 +502,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
484 | UUID avatarID = kvp.Key; | 502 | UUID avatarID = kvp.Key; |
485 | long sendTime = kvp.Value; | 503 | long sendTime = kvp.Value; |
486 | 504 | ||
487 | // m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now); | 505 | // m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now); |
488 | 506 | ||
489 | if (sendTime < now) | 507 | if (sendTime < now) |
490 | { | 508 | { |
@@ -530,11 +548,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
530 | if (sp == null) | 548 | if (sp == null) |
531 | { | 549 | { |
532 | // This is expected if the user has gone away. | 550 | // This is expected if the user has gone away. |
533 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); | 551 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); |
534 | return; | 552 | return; |
535 | } | 553 | } |
536 | 554 | ||
537 | // m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); | 555 | // m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); |
538 | 556 | ||
539 | // This could take awhile since it needs to pull inventory | 557 | // This could take awhile since it needs to pull inventory |
540 | // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape | 558 | // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape |
@@ -622,12 +640,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
622 | /// <param name="client"></param> | 640 | /// <param name="client"></param> |
623 | /// <param name="texture"></param> | 641 | /// <param name="texture"></param> |
624 | /// <param name="visualParam"></param> | 642 | /// <param name="visualParam"></param> |
625 | private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) | 643 | private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes) |
626 | { | 644 | { |
627 | // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); | 645 | // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); |
628 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | 646 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
629 | if (sp != null) | 647 | if (sp != null) |
630 | SetAppearance(sp, textureEntry, visualParams); | 648 | DoSetAppearance(sp, textureEntry, visualParams, hashes); |
631 | else | 649 | else |
632 | m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); | 650 | m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); |
633 | } | 651 | } |
@@ -684,7 +702,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
684 | /// <param name="cachedTextureRequest"></param> | 702 | /// <param name="cachedTextureRequest"></param> |
685 | private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest) | 703 | private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest) |
686 | { | 704 | { |
687 | // m_log.WarnFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId); | 705 | // m_log.DebugFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId); |
688 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | 706 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
689 | 707 | ||
690 | List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>(); | 708 | List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>(); |
@@ -695,23 +713,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
695 | 713 | ||
696 | if (m_reusetextures) | 714 | if (m_reusetextures) |
697 | { | 715 | { |
698 | // this is the most insanely dumb way to do this... however it seems to | 716 | if (sp.Appearance.GetTextureHash(index) == request.WearableHashID) |
699 | // actually work. if the appearance has been reset because wearables have | 717 | { |
700 | // changed then the texture entries are zero'd out until the bakes are | 718 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index]; |
701 | // uploaded. on login, if the textures exist in the cache (eg if you logged | 719 | if (face != null) |
702 | // into the simulator recently, then the appearance will pull those and send | 720 | texture = face.TextureID; |
703 | // them back in the packet and you won't have to rebake. if the textures aren't | 721 | } |
704 | // in the cache then the intial makeroot() call in scenepresence will zero | 722 | else |
705 | // them out. | 723 | { |
706 | // | 724 | // We know that that hash is wrong, null it out |
707 | // a better solution (though how much better is an open question) is to | 725 | // and wait for the setappearance call |
708 | // store the hashes in the appearance and compare them. Thats's coming. | 726 | sp.Appearance.SetTextureHash(index,UUID.Zero); |
709 | 727 | } | |
710 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index]; | 728 | |
711 | if (face != null) | 729 | // m_log.WarnFormat("[AVFACTORY]: use texture {0} for index {1}; hash={2}",texture,index,request.WearableHashID); |
712 | texture = face.TextureID; | ||
713 | |||
714 | // m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index); | ||
715 | } | 730 | } |
716 | 731 | ||
717 | CachedTextureResponseArg response = new CachedTextureResponseArg(); | 732 | CachedTextureResponseArg response = new CachedTextureResponseArg(); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 8056030..4613344 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -371,7 +371,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
371 | foreach (string fid in outstanding) | 371 | foreach (string fid in outstanding) |
372 | { | 372 | { |
373 | UUID fromAgentID; | 373 | UUID fromAgentID; |
374 | string firstname = "Unknown", lastname = "User"; | 374 | string firstname = "Unknown", lastname = "UserFMSFOIN"; |
375 | if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname)) | 375 | if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname)) |
376 | { | 376 | { |
377 | m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid); | 377 | m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid); |
@@ -397,7 +397,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
397 | 397 | ||
398 | protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) | 398 | protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) |
399 | { | 399 | { |
400 | first = "Unknown"; last = "User"; | 400 | first = "Unknown"; last = "UserFMGAI"; |
401 | if (!UUID.TryParse(fid, out agentID)) | 401 | if (!UUID.TryParse(fid, out agentID)) |
402 | return false; | 402 | return false; |
403 | 403 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index bf5c0bb..b3e3aa2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | |||
@@ -293,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
293 | 293 | ||
294 | protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) | 294 | protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) |
295 | { | 295 | { |
296 | first = "Unknown"; last = "User"; | 296 | first = "Unknown"; last = "UserHGGAI"; |
297 | if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last)) | 297 | if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last)) |
298 | return true; | 298 | return true; |
299 | 299 | ||
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs index fac93e6..ad3cf15 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs | |||
@@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
54 | 54 | ||
55 | public new void Initialise(IConfigSource config) | 55 | public new void Initialise(IConfigSource config) |
56 | { | 56 | { |
57 | string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name); | 57 | string umanmod = config.Configs["Modules"].GetString("UserManagementModule", null); |
58 | if (umanmod == Name) | 58 | if (umanmod == Name) |
59 | { | 59 | { |
60 | m_Enabled = true; | 60 | m_Enabled = true; |
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 6847e57..a720d7b 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | |||
@@ -157,13 +157,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
157 | } | 157 | } |
158 | else | 158 | else |
159 | { | 159 | { |
160 | string[] names = GetUserNames(uuid); | 160 | string[] names; |
161 | bool foundRealName = TryGetUserNames(uuid, out names); | ||
162 | |||
161 | if (names.Length == 2) | 163 | if (names.Length == 2) |
162 | { | 164 | { |
163 | //m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]); | 165 | if (!foundRealName) |
166 | 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); | ||
167 | |||
164 | remote_client.SendNameReply(uuid, names[0], names[1]); | 168 | remote_client.SendNameReply(uuid, names[0], names[1]); |
165 | } | 169 | } |
166 | |||
167 | } | 170 | } |
168 | } | 171 | } |
169 | 172 | ||
@@ -246,10 +249,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
246 | } | 249 | } |
247 | 250 | ||
248 | // search the local cache | 251 | // search the local cache |
249 | foreach (UserData data in m_UserCache.Values) | 252 | lock (m_UserCache) |
250 | if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null && | 253 | { |
251 | (data.FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower()))) | 254 | foreach (UserData data in m_UserCache.Values) |
252 | users.Add(data); | 255 | { |
256 | if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null && | ||
257 | (data.FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower()))) | ||
258 | users.Add(data); | ||
259 | } | ||
260 | } | ||
253 | 261 | ||
254 | AddAdditionalUsers(query, users); | 262 | AddAdditionalUsers(query, users); |
255 | 263 | ||
@@ -272,17 +280,24 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
272 | } | 280 | } |
273 | } | 281 | } |
274 | 282 | ||
275 | private string[] GetUserNames(UUID uuid) | 283 | /// <summary> |
284 | /// Try to get the names bound to the given uuid. | ||
285 | /// </summary> | ||
286 | /// <returns>True if the name was found, false if not.</returns> | ||
287 | /// <param name='uuid'></param> | ||
288 | /// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param> | ||
289 | private bool TryGetUserNames(UUID uuid, out string[] names) | ||
276 | { | 290 | { |
277 | string[] returnstring = new string[2]; | 291 | names = new string[2]; |
278 | 292 | ||
279 | lock (m_UserCache) | 293 | lock (m_UserCache) |
280 | { | 294 | { |
281 | if (m_UserCache.ContainsKey(uuid)) | 295 | if (m_UserCache.ContainsKey(uuid)) |
282 | { | 296 | { |
283 | returnstring[0] = m_UserCache[uuid].FirstName; | 297 | names[0] = m_UserCache[uuid].FirstName; |
284 | returnstring[1] = m_UserCache[uuid].LastName; | 298 | names[1] = m_UserCache[uuid].LastName; |
285 | return returnstring; | 299 | |
300 | return true; | ||
286 | } | 301 | } |
287 | } | 302 | } |
288 | 303 | ||
@@ -290,8 +305,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
290 | 305 | ||
291 | if (account != null) | 306 | if (account != null) |
292 | { | 307 | { |
293 | returnstring[0] = account.FirstName; | 308 | names[0] = account.FirstName; |
294 | returnstring[1] = account.LastName; | 309 | names[1] = account.LastName; |
295 | 310 | ||
296 | UserData user = new UserData(); | 311 | UserData user = new UserData(); |
297 | user.FirstName = account.FirstName; | 312 | user.FirstName = account.FirstName; |
@@ -299,14 +314,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
299 | 314 | ||
300 | lock (m_UserCache) | 315 | lock (m_UserCache) |
301 | m_UserCache[uuid] = user; | 316 | m_UserCache[uuid] = user; |
317 | |||
318 | return true; | ||
302 | } | 319 | } |
303 | else | 320 | else |
304 | { | 321 | { |
305 | returnstring[0] = "Unknown"; | 322 | names[0] = "Unknown"; |
306 | returnstring[1] = "User"; | 323 | names[1] = "UserUMMTGUN"; |
307 | } | ||
308 | 324 | ||
309 | return returnstring; | 325 | return false; |
326 | } | ||
310 | } | 327 | } |
311 | 328 | ||
312 | #region IUserManagement | 329 | #region IUserManagement |
@@ -342,15 +359,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
342 | 359 | ||
343 | public string GetUserName(UUID uuid) | 360 | public string GetUserName(UUID uuid) |
344 | { | 361 | { |
345 | string[] names = GetUserNames(uuid); | 362 | string[] names; |
363 | TryGetUserNames(uuid, out names); | ||
364 | |||
346 | if (names.Length == 2) | 365 | if (names.Length == 2) |
347 | { | 366 | { |
348 | string firstname = names[0]; | 367 | string firstname = names[0]; |
349 | string lastname = names[1]; | 368 | string lastname = names[1]; |
350 | 369 | ||
351 | return firstname + " " + lastname; | 370 | return firstname + " " + lastname; |
352 | |||
353 | } | 371 | } |
372 | |||
354 | return "(hippos)"; | 373 | return "(hippos)"; |
355 | } | 374 | } |
356 | 375 | ||
@@ -466,12 +485,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
466 | //ignore updates without creator data | 485 | //ignore updates without creator data |
467 | return; | 486 | return; |
468 | } | 487 | } |
488 | |||
469 | //try update unknown users | 489 | //try update unknown users |
470 | //and creator's home URL's | 490 | //and creator's home URL's |
471 | if ((oldUser.FirstName == "Unknown" && !creatorData.Contains ("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith (oldUser.HomeURL))) | 491 | if ((oldUser.FirstName == "Unknown" && !creatorData.Contains ("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith (oldUser.HomeURL))) |
472 | { | 492 | { |
473 | m_UserCache.Remove (id); | 493 | m_UserCache.Remove (id); |
474 | // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData,oldUser.HomeURL); | 494 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData, oldUser.HomeURL); |
475 | } | 495 | } |
476 | else | 496 | else |
477 | { | 497 | { |
@@ -516,7 +536,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
516 | else | 536 | else |
517 | { | 537 | { |
518 | user.FirstName = "Unknown"; | 538 | user.FirstName = "Unknown"; |
519 | user.LastName = "User"; | 539 | user.LastName = "UserUMMAU"; |
520 | } | 540 | } |
521 | 541 | ||
522 | AddUserInternal (user); | 542 | AddUserInternal (user); |
@@ -548,6 +568,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
548 | protected void RegisterConsoleCmds() | 568 | protected void RegisterConsoleCmds() |
549 | { | 569 | { |
550 | MainConsole.Instance.Commands.AddCommand("Users", true, | 570 | MainConsole.Instance.Commands.AddCommand("Users", true, |
571 | "show name", | ||
572 | "show name <uuid>", | ||
573 | "Show the bindings between a single user UUID and a user name", | ||
574 | String.Empty, | ||
575 | HandleShowUser); | ||
576 | |||
577 | MainConsole.Instance.Commands.AddCommand("Users", true, | ||
551 | "show names", | 578 | "show names", |
552 | "show names", | 579 | "show names", |
553 | "Show the bindings between user UUIDs and user names", | 580 | "Show the bindings between user UUIDs and user names", |
@@ -555,26 +582,54 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
555 | HandleShowUsers); | 582 | HandleShowUsers); |
556 | } | 583 | } |
557 | 584 | ||
558 | private void HandleShowUsers(string module, string[] cmd) | 585 | private void HandleShowUser(string module, string[] cmd) |
559 | { | 586 | { |
587 | if (cmd.Length < 3) | ||
588 | { | ||
589 | MainConsole.Instance.OutputFormat("Usage: show name <uuid>"); | ||
590 | return; | ||
591 | } | ||
592 | |||
593 | UUID userId; | ||
594 | if (!ConsoleUtil.TryParseConsoleUuid(MainConsole.Instance, cmd[2], out userId)) | ||
595 | return; | ||
596 | |||
597 | string[] names; | ||
598 | |||
599 | UserData ud; | ||
600 | |||
560 | lock (m_UserCache) | 601 | lock (m_UserCache) |
561 | { | 602 | { |
562 | if (m_UserCache.Count == 0) | 603 | if (!m_UserCache.TryGetValue(userId, out ud)) |
563 | { | 604 | { |
564 | MainConsole.Instance.Output("No users found"); | 605 | MainConsole.Instance.OutputFormat("No name known for user with id {0}", userId); |
565 | return; | 606 | return; |
566 | } | 607 | } |
567 | 608 | } | |
568 | MainConsole.Instance.Output("UUID User Name"); | 609 | |
569 | MainConsole.Instance.Output("-----------------------------------------------------------------------------"); | 610 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); |
611 | cdt.AddColumn("UUID", 36); | ||
612 | cdt.AddColumn("Name", 30); | ||
613 | cdt.AddColumn("HomeURL", 40); | ||
614 | cdt.AddRow(userId, string.Format("{0} {1}", ud.FirstName, ud.LastName), ud.HomeURL); | ||
615 | |||
616 | MainConsole.Instance.Output(cdt.ToString()); | ||
617 | } | ||
618 | |||
619 | private void HandleShowUsers(string module, string[] cmd) | ||
620 | { | ||
621 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
622 | cdt.AddColumn("UUID", 36); | ||
623 | cdt.AddColumn("Name", 30); | ||
624 | cdt.AddColumn("HomeURL", 40); | ||
625 | |||
626 | lock (m_UserCache) | ||
627 | { | ||
570 | foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache) | 628 | foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache) |
571 | { | 629 | cdt.AddRow(kvp.Key, string.Format("{0} {1}", kvp.Value.FirstName, kvp.Value.LastName), kvp.Value.HomeURL); |
572 | MainConsole.Instance.Output(String.Format("{0} {1} {2} ({3})", | ||
573 | kvp.Key, kvp.Value.FirstName, kvp.Value.LastName, kvp.Value.HomeURL)); | ||
574 | } | ||
575 | |||
576 | return; | ||
577 | } | 630 | } |
631 | |||
632 | MainConsole.Instance.Output(cdt.ToString()); | ||
578 | } | 633 | } |
579 | } | 634 | } |
580 | } \ No newline at end of file | 635 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index 883045a..d093224 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs | |||
@@ -369,6 +369,15 @@ namespace OpenSim.Region.CoreModules.World.Sound | |||
369 | }); | 369 | }); |
370 | } | 370 | } |
371 | 371 | ||
372 | public void SetSoundQueueing(UUID objectID, bool shouldQueue) | ||
373 | { | ||
374 | SceneObjectPart part; | ||
375 | if (!m_scene.TryGetSceneObjectPart(objectID, out part)) | ||
376 | return; | ||
377 | |||
378 | part.SoundQueueing = shouldQueue; | ||
379 | } | ||
380 | |||
372 | #endregion | 381 | #endregion |
373 | } | 382 | } |
374 | } | 383 | } |
diff --git a/OpenSim/Region/Framework/Interfaces/ISoundModule.cs b/OpenSim/Region/Framework/Interfaces/ISoundModule.cs index 68af492..8372ddd 100644 --- a/OpenSim/Region/Framework/Interfaces/ISoundModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISoundModule.cs | |||
@@ -104,7 +104,6 @@ namespace OpenSim.Region.Framework.Interfaces | |||
104 | /// <param name="sound">Sound asset ID</param> | 104 | /// <param name="sound">Sound asset ID</param> |
105 | /// <param name="volume">Sound volume</param> | 105 | /// <param name="volume">Sound volume</param> |
106 | /// <param name="triggered">Triggered or not.</param> | 106 | /// <param name="triggered">Triggered or not.</param> |
107 | /// <param name="flags"></param> | ||
108 | /// <param name="radius">Sound radius</param> | 107 | /// <param name="radius">Sound radius</param> |
109 | /// <param name="useMaster">Play using sound master</param> | 108 | /// <param name="useMaster">Play using sound master</param> |
110 | /// <param name="isMaster">Play as sound master</param> | 109 | /// <param name="isMaster">Play as sound master</param> |
@@ -123,5 +122,12 @@ namespace OpenSim.Region.Framework.Interfaces | |||
123 | /// <param name="max">AABB top north-east corner</param> | 122 | /// <param name="max">AABB top north-east corner</param> |
124 | void TriggerSoundLimited(UUID objectID, UUID sound, double volume, | 123 | void TriggerSoundLimited(UUID objectID, UUID sound, double volume, |
125 | Vector3 min, Vector3 max); | 124 | Vector3 min, Vector3 max); |
125 | |||
126 | /// <summary> | ||
127 | /// Set whether sounds on the given prim should be queued. | ||
128 | /// </summary> | ||
129 | /// <param name='objectID'></param> | ||
130 | /// <param name='shouldQueue'></param> | ||
131 | void SetSoundQueueing(UUID objectID, bool shouldQueue); | ||
126 | } | 132 | } |
127 | } \ No newline at end of file | 133 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 38fa26a..df23cc5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -1499,7 +1499,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1499 | if (!userExposed) | 1499 | if (!userExposed) |
1500 | dupe.IsAttachment = true; | 1500 | dupe.IsAttachment = true; |
1501 | 1501 | ||
1502 | dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); | 1502 | dupe.m_sittingAvatars = new List<UUID>(); |
1503 | 1503 | ||
1504 | if (!userExposed) | 1504 | if (!userExposed) |
1505 | { | 1505 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 347a2b5..ea8c3c5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -219,6 +219,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
219 | 219 | ||
220 | public double SoundRadius; | 220 | public double SoundRadius; |
221 | 221 | ||
222 | /// <summary> | ||
223 | /// Should sounds played from this prim be queued? | ||
224 | /// </summary> | ||
225 | /// <remarks> | ||
226 | /// This should only be changed by sound modules. It is up to sound modules as to how they interpret this setting. | ||
227 | /// </remarks> | ||
228 | public bool SoundQueueing { get; set; } | ||
229 | |||
222 | public uint TimeStampFull; | 230 | public uint TimeStampFull; |
223 | 231 | ||
224 | public uint TimeStampLastActivity; // Will be used for AutoReturn | 232 | public uint TimeStampLastActivity; // Will be used for AutoReturn |
@@ -1791,6 +1799,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1791 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); | 1799 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); |
1792 | dupe.Shape.ExtraParams = extraP; | 1800 | dupe.Shape.ExtraParams = extraP; |
1793 | 1801 | ||
1802 | dupe.PayPrice = (int[])PayPrice.Clone(); | ||
1803 | |||
1794 | dupe.DynAttrs.CopyFrom(DynAttrs); | 1804 | dupe.DynAttrs.CopyFrom(DynAttrs); |
1795 | 1805 | ||
1796 | if (userExposed) | 1806 | if (userExposed) |
@@ -2429,7 +2439,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2429 | if (soundModule != null) | 2439 | if (soundModule != null) |
2430 | { | 2440 | { |
2431 | soundModule.SendSound(UUID, CollisionSound, | 2441 | soundModule.SendSound(UUID, CollisionSound, |
2432 | CollisionSoundVolume, true, (byte)0, 0, false, | 2442 | CollisionSoundVolume, true, 0, 0, false, |
2433 | false); | 2443 | false); |
2434 | } | 2444 | } |
2435 | } | 2445 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0c91e13..ab7fd5b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -2713,7 +2713,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2713 | // again here... this comes after the cached appearance check because the avatars | 2713 | // again here... this comes after the cached appearance check because the avatars |
2714 | // appearance goes into the avatar update packet | 2714 | // appearance goes into the avatar update packet |
2715 | SendAvatarDataToAllAgents(); | 2715 | SendAvatarDataToAllAgents(); |
2716 | SendAppearanceToAgent(this); | 2716 | |
2717 | // This invocation always shows up in the viewer logs as an error. | ||
2718 | // SendAppearanceToAgent(this); | ||
2717 | 2719 | ||
2718 | // If we are using the the cached appearance then send it out to everyone | 2720 | // If we are using the the cached appearance then send it out to everyone |
2719 | if (cachedappearance) | 2721 | if (cachedappearance) |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 384eb1f..3726191 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -907,7 +907,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
907 | // Mimicking LLClientView which gets always set appearance from client. | 907 | // Mimicking LLClientView which gets always set appearance from client. |
908 | AvatarAppearance appearance; | 908 | AvatarAppearance appearance; |
909 | m_scene.GetAvatarAppearance(this, out appearance); | 909 | m_scene.GetAvatarAppearance(this, out appearance); |
910 | OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone()); | 910 | OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(), new List<CachedTextureRequestArg>()); |
911 | } | 911 | } |
912 | 912 | ||
913 | public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) | 913 | public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) |
@@ -1056,7 +1056,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1056 | { | 1056 | { |
1057 | } | 1057 | } |
1058 | 1058 | ||
1059 | public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance) | 1059 | 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) |
1060 | { | 1060 | { |
1061 | 1061 | ||
1062 | } | 1062 | } |
@@ -1196,11 +1196,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1196 | 1196 | ||
1197 | } | 1197 | } |
1198 | 1198 | ||
1199 | public bool AddMoney(int debit) | ||
1200 | { | ||
1201 | return true; | ||
1202 | } | ||
1203 | |||
1204 | public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition) | 1199 | public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition) |
1205 | { | 1200 | { |
1206 | 1201 | ||
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 29f9591..32fb54b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | |||
@@ -764,7 +764,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
764 | remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group."); | 764 | remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group."); |
765 | return UUID.Zero; | 765 | return UUID.Zero; |
766 | } | 766 | } |
767 | money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, "Group Creation"); | 767 | money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, MoneyTransactionType.GroupCreate); |
768 | } | 768 | } |
769 | UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); | 769 | UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); |
770 | 770 | ||
diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs index 35f44d0..1345db9 100644 --- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs +++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs | |||
@@ -191,9 +191,14 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule | |||
191 | // Please do not refactor these to be just one method | 191 | // Please do not refactor these to be just one method |
192 | // Existing implementations need the distinction | 192 | // Existing implementations need the distinction |
193 | // | 193 | // |
194 | public void ApplyCharge(UUID agentID, int amount, string text) | 194 | public void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData) |
195 | { | 195 | { |
196 | } | 196 | } |
197 | |||
198 | public void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type) | ||
199 | { | ||
200 | } | ||
201 | |||
197 | public void ApplyUploadCharge(UUID agentID, int amount, string text) | 202 | public void ApplyUploadCharge(UUID agentID, int amount, string text) |
198 | { | 203 | { |
199 | } | 204 | } |
@@ -322,7 +327,7 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule | |||
322 | client.SendAlertMessage(e.Message + " "); | 327 | client.SendAlertMessage(e.Message + " "); |
323 | } | 328 | } |
324 | 329 | ||
325 | client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds); | 330 | client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds, 0, UUID.Zero, false, UUID.Zero, false, 0, String.Empty); |
326 | } | 331 | } |
327 | else | 332 | else |
328 | { | 333 | { |
@@ -385,12 +390,12 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule | |||
385 | { | 390 | { |
386 | if (sender != null) | 391 | if (sender != null) |
387 | { | 392 | { |
388 | sender.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(senderID)); | 393 | sender.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(senderID), 0, UUID.Zero, false, UUID.Zero, false, 0, String.Empty); |
389 | } | 394 | } |
390 | 395 | ||
391 | if (receiver != null) | 396 | if (receiver != null) |
392 | { | 397 | { |
393 | receiver.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(receiverID)); | 398 | receiver.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(receiverID), 0, UUID.Zero, false, UUID.Zero, false, 0, String.Empty); |
394 | } | 399 | } |
395 | } | 400 | } |
396 | } | 401 | } |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 553443f..592e4e1 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | |||
@@ -694,7 +694,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
694 | { | 694 | { |
695 | } | 695 | } |
696 | 696 | ||
697 | public virtual void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance) | 697 | 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) |
698 | { | 698 | { |
699 | } | 699 | } |
700 | 700 | ||
@@ -866,11 +866,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
866 | { | 866 | { |
867 | } | 867 | } |
868 | 868 | ||
869 | public bool AddMoney(int debit) | ||
870 | { | ||
871 | return false; | ||
872 | } | ||
873 | |||
874 | public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong time, uint dlen, uint ylen, float phase) | 869 | public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong time, uint dlen, uint ylen, float phase) |
875 | { | 870 | { |
876 | } | 871 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 231f0f8..12a0c17 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | |||
@@ -251,6 +251,16 @@ public override BulletShape CreateMeshShape(BulletWorld world, | |||
251 | BSPhysicsShapeType.SHAPE_MESH); | 251 | BSPhysicsShapeType.SHAPE_MESH); |
252 | } | 252 | } |
253 | 253 | ||
254 | public override BulletShape CreateGImpactShape(BulletWorld world, | ||
255 | int indicesCount, int[] indices, | ||
256 | int verticesCount, float[] vertices) | ||
257 | { | ||
258 | BulletWorldUnman worldu = world as BulletWorldUnman; | ||
259 | return new BulletShapeUnman( | ||
260 | BSAPICPP.CreateGImpactShape2(worldu.ptr, indicesCount, indices, verticesCount, vertices), | ||
261 | BSPhysicsShapeType.SHAPE_GIMPACT); | ||
262 | } | ||
263 | |||
254 | public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls) | 264 | public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls) |
255 | { | 265 | { |
256 | BulletWorldUnman worldu = world as BulletWorldUnman; | 266 | BulletWorldUnman worldu = world as BulletWorldUnman; |
@@ -1426,6 +1436,11 @@ public static extern IntPtr CreateMeshShape2(IntPtr world, | |||
1426 | int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); | 1436 | int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); |
1427 | 1437 | ||
1428 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 1438 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
1439 | public static extern IntPtr CreateGImpactShape2(IntPtr world, | ||
1440 | int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, | ||
1441 | int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); | ||
1442 | |||
1443 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
1429 | public static extern IntPtr CreateHullShape2(IntPtr world, | 1444 | public static extern IntPtr CreateHullShape2(IntPtr world, |
1430 | int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); | 1445 | int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); |
1431 | 1446 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 59780ae..6db5f5e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | |||
@@ -1475,7 +1475,7 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1475 | ret = BSPhysicsShapeType.SHAPE_UNKNOWN; | 1475 | ret = BSPhysicsShapeType.SHAPE_UNKNOWN; |
1476 | break; | 1476 | break; |
1477 | case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE: | 1477 | case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE: |
1478 | ret = BSPhysicsShapeType.SHAPE_MESH; | 1478 | ret = BSPhysicsShapeType.SHAPE_CONVEXHULL; |
1479 | break; | 1479 | break; |
1480 | case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: | 1480 | case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: |
1481 | ret = BSPhysicsShapeType.SHAPE_HULL; | 1481 | ret = BSPhysicsShapeType.SHAPE_HULL; |
@@ -1503,7 +1503,7 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1503 | ret = BSPhysicsShapeType.SHAPE_CONE; | 1503 | ret = BSPhysicsShapeType.SHAPE_CONE; |
1504 | break; | 1504 | break; |
1505 | case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE: | 1505 | case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE: |
1506 | ret = BSPhysicsShapeType.SHAPE_UNKNOWN; | 1506 | ret = BSPhysicsShapeType.SHAPE_CONVEXHULL; |
1507 | break; | 1507 | break; |
1508 | case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: | 1508 | case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: |
1509 | ret = BSPhysicsShapeType.SHAPE_CYLINDER; | 1509 | ret = BSPhysicsShapeType.SHAPE_CYLINDER; |
@@ -1547,7 +1547,7 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1547 | break; | 1547 | break; |
1548 | ///Used for GIMPACT Trimesh integration | 1548 | ///Used for GIMPACT Trimesh integration |
1549 | case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE: | 1549 | case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE: |
1550 | ret = BSPhysicsShapeType.SHAPE_MESH; | 1550 | ret = BSPhysicsShapeType.SHAPE_GIMPACT; |
1551 | break; | 1551 | break; |
1552 | ///Multimaterial mesh | 1552 | ///Multimaterial mesh |
1553 | case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE: | 1553 | case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE: |
@@ -1820,6 +1820,11 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1820 | return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH); | 1820 | return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH); |
1821 | 1821 | ||
1822 | } | 1822 | } |
1823 | public override BulletShape CreateGImpactShape(BulletWorld pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats) | ||
1824 | { | ||
1825 | // TODO: | ||
1826 | return null; | ||
1827 | } | ||
1823 | public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount ) | 1828 | public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount ) |
1824 | { | 1829 | { |
1825 | 1830 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 3378c93..6cdc112 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | |||
@@ -71,6 +71,7 @@ public enum BSPhysicsShapeType | |||
71 | SHAPE_HEIGHTMAP = 23, | 71 | SHAPE_HEIGHTMAP = 23, |
72 | SHAPE_AVATAR = 24, | 72 | SHAPE_AVATAR = 24, |
73 | SHAPE_CONVEXHULL= 25, | 73 | SHAPE_CONVEXHULL= 25, |
74 | SHAPE_GIMPACT = 26, | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | // The native shapes have predefined shape hash keys | 77 | // The native shapes have predefined shape hash keys |
@@ -321,6 +322,10 @@ public abstract BulletShape CreateMeshShape(BulletWorld world, | |||
321 | int indicesCount, int[] indices, | 322 | int indicesCount, int[] indices, |
322 | int verticesCount, float[] vertices ); | 323 | int verticesCount, float[] vertices ); |
323 | 324 | ||
325 | public abstract BulletShape CreateGImpactShape(BulletWorld world, | ||
326 | int indicesCount, int[] indices, | ||
327 | int verticesCount, float[] vertices ); | ||
328 | |||
324 | public abstract BulletShape CreateHullShape(BulletWorld world, | 329 | public abstract BulletShape CreateHullShape(BulletWorld world, |
325 | int hullCount, float[] hulls); | 330 | int hullCount, float[] hulls); |
326 | 331 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index ff5b6ab..48f842e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -483,8 +483,15 @@ public sealed class BSCharacter : BSPhysObject | |||
483 | { | 483 | { |
484 | // Bullet assumes we know what we are doing when forcing orientation | 484 | // Bullet assumes we know what we are doing when forcing orientation |
485 | // so it lets us go against all the rules and just compensates for them later. | 485 | // so it lets us go against all the rules and just compensates for them later. |
486 | // This keeps us from flipping the capsule over which the veiwer does not understand. | 486 | // This forces rotation to be only around the Z axis and doesn't change any of the other axis. |
487 | ForceOrientation = new OMV.Quaternion(0, 0, _orientation.Z,0); | 487 | // This keeps us from flipping the capsule over which the veiwer does not understand. |
488 | float oRoll, oPitch, oYaw; | ||
489 | _orientation.GetEulerAngles(out oRoll, out oPitch, out oYaw); | ||
490 | OMV.Quaternion trimmedOrientation = OMV.Quaternion.CreateFromEulers(0f, 0f, oYaw); | ||
491 | // DetailLog("{0},BSCharacter.setOrientation,taint,val={1},valDir={2},conv={3},convDir={4}", | ||
492 | // LocalID, _orientation, OMV.Vector3.UnitX * _orientation, | ||
493 | // trimmedOrientation, OMV.Vector3.UnitX * trimmedOrientation); | ||
494 | ForceOrientation = trimmedOrientation; | ||
488 | }); | 495 | }); |
489 | } | 496 | } |
490 | } | 497 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index c16b7d3..311cf4f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -617,7 +617,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
617 | // Vehicles report collision events so we know when it's on the ground | 617 | // Vehicles report collision events so we know when it's on the ground |
618 | m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); | 618 | m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); |
619 | 619 | ||
620 | ControllingPrim.Inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass); | 620 | Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass); |
621 | ControllingPrim.Inertia = inertia * BSParam.VehicleInertiaFactor; | ||
621 | m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia); | 622 | m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia); |
622 | m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody); | 623 | m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody); |
623 | 624 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index d33292f..2651e3b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -89,6 +89,8 @@ public static class BSParam | |||
89 | public static bool ShouldRemoveZeroWidthTriangles { get; private set; } | 89 | public static bool ShouldRemoveZeroWidthTriangles { get; private set; } |
90 | public static bool ShouldUseBulletHACD { get; set; } | 90 | public static bool ShouldUseBulletHACD { get; set; } |
91 | public static bool ShouldUseSingleConvexHullForPrims { get; set; } | 91 | public static bool ShouldUseSingleConvexHullForPrims { get; set; } |
92 | public static bool ShouldUseGImpactShapeForPrims { get; set; } | ||
93 | public static bool ShouldUseAssetHulls { get; set; } | ||
92 | 94 | ||
93 | public static float TerrainImplementation { get; set; } | 95 | public static float TerrainImplementation { get; set; } |
94 | public static int TerrainMeshMagnification { get; private set; } | 96 | public static int TerrainMeshMagnification { get; private set; } |
@@ -146,6 +148,7 @@ public static class BSParam | |||
146 | public static float VehicleRestitution { get; private set; } | 148 | public static float VehicleRestitution { get; private set; } |
147 | public static Vector3 VehicleLinearFactor { get; private set; } | 149 | public static Vector3 VehicleLinearFactor { get; private set; } |
148 | public static Vector3 VehicleAngularFactor { get; private set; } | 150 | public static Vector3 VehicleAngularFactor { get; private set; } |
151 | public static Vector3 VehicleInertiaFactor { get; private set; } | ||
149 | public static float VehicleGroundGravityFudge { get; private set; } | 152 | public static float VehicleGroundGravityFudge { get; private set; } |
150 | public static float VehicleAngularBankingTimescaleFudge { get; private set; } | 153 | public static float VehicleAngularBankingTimescaleFudge { get; private set; } |
151 | public static bool VehicleDebuggingEnable { get; private set; } | 154 | public static bool VehicleDebuggingEnable { get; private set; } |
@@ -369,6 +372,10 @@ public static class BSParam | |||
369 | false ), | 372 | false ), |
370 | new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims", | 373 | new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims", |
371 | true ), | 374 | true ), |
375 | new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists", | ||
376 | false ), | ||
377 | new ParameterDefn<bool>("ShouldUseAssetHulls", "If true, use hull if specified in the mesh asset info", | ||
378 | true ), | ||
372 | 379 | ||
373 | new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", | 380 | new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", |
374 | 5 ), | 381 | 5 ), |
@@ -577,6 +584,8 @@ public static class BSParam | |||
577 | new Vector3(1f, 1f, 1f) ), | 584 | new Vector3(1f, 1f, 1f) ), |
578 | new ParameterDefn<Vector3>("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (<0,0,0> to <1,1,1>)", | 585 | new ParameterDefn<Vector3>("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (<0,0,0> to <1,1,1>)", |
579 | new Vector3(1f, 1f, 1f) ), | 586 | new Vector3(1f, 1f, 1f) ), |
587 | new ParameterDefn<Vector3>("VehicleInertiaFactor", "Fraction of physical inertia applied (<0,0,0> to <1,1,1>)", | ||
588 | new Vector3(1f, 1f, 1f) ), | ||
580 | new ParameterDefn<float>("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)", | 589 | new ParameterDefn<float>("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)", |
581 | 0.0f ), | 590 | 0.0f ), |
582 | new ParameterDefn<float>("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)", | 591 | new ParameterDefn<float>("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)", |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index f5b0361..e11e365 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -511,7 +511,10 @@ public class BSPrim : BSPhysObject | |||
511 | 511 | ||
512 | PhysScene.TaintedObject("setVehicleType", delegate() | 512 | PhysScene.TaintedObject("setVehicleType", delegate() |
513 | { | 513 | { |
514 | ZeroMotion(true /* inTaintTime */); | 514 | // Some vehicle scripts change vehicle type on the fly as an easy way to |
515 | // change all the parameters. Like a plane changing to CAR when on the | ||
516 | // ground. In this case, don't want to zero motion. | ||
517 | // ZeroMotion(true /* inTaintTime */); | ||
515 | VehicleActor.ProcessTypeChange(type); | 518 | VehicleActor.ProcessTypeChange(type); |
516 | ActivateIfPhysical(false); | 519 | ActivateIfPhysical(false); |
517 | }); | 520 | }); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 3f407ce..39f5b0a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -268,6 +268,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
268 | // Do any replacements in the parameters | 268 | // Do any replacements in the parameters |
269 | m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); | 269 | m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); |
270 | } | 270 | } |
271 | else | ||
272 | { | ||
273 | BulletEngineName = "BulletUnmanaged"; | ||
274 | m_physicsLoggingEnabled = false; | ||
275 | VehicleLoggingEnabled = false; | ||
276 | } | ||
271 | 277 | ||
272 | // The material characteristics. | 278 | // The material characteristics. |
273 | BSMaterials.InitializeFromDefaults(Params); | 279 | BSMaterials.InitializeFromDefaults(Params); |
@@ -322,6 +328,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
322 | BSParam.ShouldUseBulletHACD = false; | 328 | BSParam.ShouldUseBulletHACD = false; |
323 | m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader); | 329 | m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader); |
324 | BSParam.ShouldUseSingleConvexHullForPrims = false; | 330 | BSParam.ShouldUseSingleConvexHullForPrims = false; |
331 | m_log.InfoFormat("{0} Disabling ShouldUseGImpactShapeForPrims", LogHeader); | ||
332 | BSParam.ShouldUseGImpactShapeForPrims = false; | ||
325 | m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader); | 333 | m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader); |
326 | BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap; | 334 | BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap; |
327 | break; | 335 | break; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 64aaa15..32bbc8f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -230,6 +230,7 @@ public sealed class BSShapeCollection : IDisposable | |||
230 | BSShape potentialHull = null; | 230 | BSShape potentialHull = null; |
231 | 231 | ||
232 | PrimitiveBaseShape pbs = prim.BaseShape; | 232 | PrimitiveBaseShape pbs = prim.BaseShape; |
233 | // Use a simple, one section convex shape for prims that are probably convex (no cuts or twists) | ||
233 | if (BSParam.ShouldUseSingleConvexHullForPrims | 234 | if (BSParam.ShouldUseSingleConvexHullForPrims |
234 | && pbs != null | 235 | && pbs != null |
235 | && !pbs.SculptEntry | 236 | && !pbs.SculptEntry |
@@ -238,7 +239,17 @@ public sealed class BSShapeCollection : IDisposable | |||
238 | { | 239 | { |
239 | potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim); | 240 | potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim); |
240 | } | 241 | } |
241 | else | 242 | // Use the GImpact shape if it is a prim that has some concaveness |
243 | if (potentialHull == null | ||
244 | && BSParam.ShouldUseGImpactShapeForPrims | ||
245 | && pbs != null | ||
246 | && !pbs.SculptEntry | ||
247 | ) | ||
248 | { | ||
249 | potentialHull = BSShapeGImpact.GetReference(m_physicsScene, false /* forceRebuild */, prim); | ||
250 | } | ||
251 | // If not any of the simple cases, just make a hull | ||
252 | if (potentialHull == null) | ||
242 | { | 253 | { |
243 | potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim); | 254 | potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim); |
244 | } | 255 | } |
@@ -261,7 +272,7 @@ public sealed class BSShapeCollection : IDisposable | |||
261 | } | 272 | } |
262 | else | 273 | else |
263 | { | 274 | { |
264 | // Update prim.BSShape to reference a mesh of this shape. | 275 | // Non-physical objects should be just meshes. |
265 | BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim); | 276 | BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim); |
266 | // If the current shape is not what is on the prim at the moment, time to change. | 277 | // If the current shape is not what is on the prim at the moment, time to change. |
267 | if (!prim.PhysShape.HasPhysicalShape | 278 | if (!prim.PhysShape.HasPhysicalShape |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 72d039b..81edc12 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | |||
@@ -31,6 +31,7 @@ using System.Text; | |||
31 | 31 | ||
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Physics.Manager; | 33 | using OpenSim.Region.Physics.Manager; |
34 | using OpenSim.Region.Physics.Meshing; | ||
34 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; | 35 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; |
35 | 36 | ||
36 | using OMV = OpenMetaverse; | 37 | using OMV = OpenMetaverse; |
@@ -422,15 +423,32 @@ public class BSShapeMesh : BSShape | |||
422 | outMesh = foundDesc; | 423 | outMesh = foundDesc; |
423 | return ret; | 424 | return ret; |
424 | } | 425 | } |
426 | |||
427 | public delegate BulletShape CreateShapeCall(BulletWorld world, int indicesCount, int[] indices, int verticesCount, float[] vertices ); | ||
425 | private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | 428 | private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, |
426 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 429 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
427 | { | 430 | { |
431 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, | ||
432 | (w, iC, i, vC, v) => physicsScene.PE.CreateMeshShape(w, iC, i, vC, v) ); | ||
433 | } | ||
434 | |||
435 | // Code that uses the mesher to create the index/vertices info for a trimesh shape. | ||
436 | // This is used by the passed 'makeShape' call to create the Bullet mesh shape. | ||
437 | // The actual build call is passed so this logic can be used by several of the shapes that use a | ||
438 | // simple mesh as their base shape. | ||
439 | public static BulletShape CreatePhysicalMeshShape(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
440 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod, CreateShapeCall makeShape) | ||
441 | { | ||
428 | BulletShape newShape = new BulletShape(); | 442 | BulletShape newShape = new BulletShape(); |
429 | 443 | ||
430 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, | 444 | IMesh meshData = null; |
431 | false, // say it is not physical so a bounding box is not built | 445 | lock (physicsScene.mesher) |
432 | false // do not cache the mesh and do not use previously built versions | 446 | { |
433 | ); | 447 | meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, |
448 | false, // say it is not physical so a bounding box is not built | ||
449 | false // do not cache the mesh and do not use previously built versions | ||
450 | ); | ||
451 | } | ||
434 | 452 | ||
435 | if (meshData != null) | 453 | if (meshData != null) |
436 | { | 454 | { |
@@ -482,8 +500,7 @@ public class BSShapeMesh : BSShape | |||
482 | 500 | ||
483 | if (realIndicesIndex != 0) | 501 | if (realIndicesIndex != 0) |
484 | { | 502 | { |
485 | newShape = physicsScene.PE.CreateMeshShape(physicsScene.World, | 503 | newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); |
486 | realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); | ||
487 | } | 504 | } |
488 | else | 505 | else |
489 | { | 506 | { |
@@ -561,13 +578,74 @@ public class BSShapeHull : BSShape | |||
561 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 578 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
562 | { | 579 | { |
563 | BulletShape newShape = new BulletShape(); | 580 | BulletShape newShape = new BulletShape(); |
564 | IntPtr hullPtr = IntPtr.Zero; | ||
565 | 581 | ||
566 | if (BSParam.ShouldUseBulletHACD) | 582 | IMesh meshData = null; |
583 | List<List<OMV.Vector3>> allHulls = null; | ||
584 | lock (physicsScene.mesher) | ||
585 | { | ||
586 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | ||
587 | meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */); | ||
588 | |||
589 | // If we should use the asset's hull info, fetch it out of the locked mesher | ||
590 | if (meshData != null && BSParam.ShouldUseAssetHulls) | ||
591 | { | ||
592 | Meshmerizer realMesher = physicsScene.mesher as Meshmerizer; | ||
593 | if (realMesher != null) | ||
594 | { | ||
595 | allHulls = realMesher.GetConvexHulls(size); | ||
596 | } | ||
597 | if (allHulls == null) | ||
598 | { | ||
599 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,noAssetHull", prim.LocalID); | ||
600 | } | ||
601 | } | ||
602 | } | ||
603 | |||
604 | // If there is hull data in the mesh asset, build the hull from that | ||
605 | if (allHulls != null && BSParam.ShouldUseAssetHulls) | ||
606 | { | ||
607 | int hullCount = allHulls.Count; | ||
608 | int totalVertices = 1; // include one for the count of the hulls | ||
609 | // Using the structure described for HACD hulls, create the memory sturcture | ||
610 | // to pass the hull data to the creater. | ||
611 | foreach (List<OMV.Vector3> hullVerts in allHulls) | ||
612 | { | ||
613 | totalVertices += 4; // add four for the vertex count and centroid | ||
614 | totalVertices += hullVerts.Count * 3; // one vertex is three dimensions | ||
615 | } | ||
616 | float[] convHulls = new float[totalVertices]; | ||
617 | |||
618 | convHulls[0] = (float)hullCount; | ||
619 | int jj = 1; | ||
620 | foreach (List<OMV.Vector3> hullVerts in allHulls) | ||
621 | { | ||
622 | convHulls[jj + 0] = hullVerts.Count; | ||
623 | convHulls[jj + 1] = 0f; // centroid x,y,z | ||
624 | convHulls[jj + 2] = 0f; | ||
625 | convHulls[jj + 3] = 0f; | ||
626 | jj += 4; | ||
627 | foreach (OMV.Vector3 oneVert in hullVerts) | ||
628 | { | ||
629 | convHulls[jj + 0] = oneVert.X; | ||
630 | convHulls[jj + 1] = oneVert.Y; | ||
631 | convHulls[jj + 2] = oneVert.Z; | ||
632 | jj += 3; | ||
633 | } | ||
634 | } | ||
635 | |||
636 | // create the hull data structure in Bullet | ||
637 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
638 | |||
639 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,hulls={1},totVert={2},shape={3}", | ||
640 | prim.LocalID, hullCount, totalVertices, newShape); | ||
641 | } | ||
642 | |||
643 | // If no hull specified in the asset and we should use Bullet's HACD approximation... | ||
644 | if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD) | ||
567 | { | 645 | { |
568 | // Build the hull shape from an existing mesh shape. | 646 | // Build the hull shape from an existing mesh shape. |
569 | // The mesh should have already been created in Bullet. | 647 | // The mesh should have already been created in Bullet. |
570 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID); | 648 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,entry", prim.LocalID); |
571 | BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim); | 649 | BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim); |
572 | 650 | ||
573 | if (meshShape.physShapeInfo.HasPhysicalShape) | 651 | if (meshShape.physShapeInfo.HasPhysicalShape) |
@@ -585,129 +663,125 @@ public class BSShapeHull : BSShape | |||
585 | 663 | ||
586 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); | 664 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); |
587 | newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); | 665 | newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); |
588 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | 666 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape); |
589 | 667 | ||
590 | // Now done with the mesh shape. | 668 | // Now done with the mesh shape. |
591 | meshShape.Dereference(physicsScene); | 669 | meshShape.Dereference(physicsScene); |
592 | } | 670 | } |
593 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | 671 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); |
594 | } | 672 | } |
595 | if (!newShape.HasPhysicalShape) | 673 | |
674 | // If no other hull specifications, use our HACD hull approximation. | ||
675 | if (!newShape.HasPhysicalShape && meshData != null) | ||
596 | { | 676 | { |
597 | // Build a new hull in the physical world using the C# HACD algorigthm. | 677 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) |
598 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | ||
599 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */); | ||
600 | if (meshData != null) | ||
601 | { | 678 | { |
602 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) | 679 | // Release the fetched asset data once it has been used. |
603 | { | 680 | pbs.SculptData = new byte[0]; |
604 | // Release the fetched asset data once it has been used. | 681 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown; |
605 | pbs.SculptData = new byte[0]; | 682 | } |
606 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown; | ||
607 | } | ||
608 | 683 | ||
609 | int[] indices = meshData.getIndexListAsInt(); | 684 | int[] indices = meshData.getIndexListAsInt(); |
610 | List<OMV.Vector3> vertices = meshData.getVertexList(); | 685 | List<OMV.Vector3> vertices = meshData.getVertexList(); |
611 | 686 | ||
612 | //format conversion from IMesh format to DecompDesc format | 687 | //format conversion from IMesh format to DecompDesc format |
613 | List<int> convIndices = new List<int>(); | 688 | List<int> convIndices = new List<int>(); |
614 | List<float3> convVertices = new List<float3>(); | 689 | List<float3> convVertices = new List<float3>(); |
615 | for (int ii = 0; ii < indices.GetLength(0); ii++) | 690 | for (int ii = 0; ii < indices.GetLength(0); ii++) |
616 | { | 691 | { |
617 | convIndices.Add(indices[ii]); | 692 | convIndices.Add(indices[ii]); |
618 | } | 693 | } |
619 | foreach (OMV.Vector3 vv in vertices) | 694 | foreach (OMV.Vector3 vv in vertices) |
620 | { | 695 | { |
621 | convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); | 696 | convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); |
622 | } | 697 | } |
623 | 698 | ||
624 | uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; | 699 | uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; |
625 | if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) | 700 | if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) |
701 | { | ||
702 | // Simple primitive shapes we know are convex so they are better implemented with | ||
703 | // fewer hulls. | ||
704 | // Check for simple shape (prim without cuts) and reduce split parameter if so. | ||
705 | if (BSShapeCollection.PrimHasNoCuts(pbs)) | ||
626 | { | 706 | { |
627 | // Simple primitive shapes we know are convex so they are better implemented with | 707 | maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes; |
628 | // fewer hulls. | ||
629 | // Check for simple shape (prim without cuts) and reduce split parameter if so. | ||
630 | if (BSShapeCollection.PrimHasNoCuts(pbs)) | ||
631 | { | ||
632 | maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes; | ||
633 | } | ||
634 | } | 708 | } |
709 | } | ||
710 | |||
711 | // setup and do convex hull conversion | ||
712 | m_hulls = new List<ConvexResult>(); | ||
713 | DecompDesc dcomp = new DecompDesc(); | ||
714 | dcomp.mIndices = convIndices; | ||
715 | dcomp.mVertices = convVertices; | ||
716 | dcomp.mDepth = maxDepthSplit; | ||
717 | dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; | ||
718 | dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; | ||
719 | dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices; | ||
720 | dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth; | ||
721 | ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); | ||
722 | // create the hull into the _hulls variable | ||
723 | convexBuilder.process(dcomp); | ||
724 | |||
725 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}", | ||
726 | BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count); | ||
727 | |||
728 | // Convert the vertices and indices for passing to unmanaged. | ||
729 | // The hull information is passed as a large floating point array. | ||
730 | // The format is: | ||
731 | // convHulls[0] = number of hulls | ||
732 | // convHulls[1] = number of vertices in first hull | ||
733 | // convHulls[2] = hull centroid X coordinate | ||
734 | // convHulls[3] = hull centroid Y coordinate | ||
735 | // convHulls[4] = hull centroid Z coordinate | ||
736 | // convHulls[5] = first hull vertex X | ||
737 | // convHulls[6] = first hull vertex Y | ||
738 | // convHulls[7] = first hull vertex Z | ||
739 | // convHulls[8] = second hull vertex X | ||
740 | // ... | ||
741 | // convHulls[n] = number of vertices in second hull | ||
742 | // convHulls[n+1] = second hull centroid X coordinate | ||
743 | // ... | ||
744 | // | ||
745 | // TODO: is is very inefficient. Someday change the convex hull generator to return | ||
746 | // data structures that do not need to be converted in order to pass to Bullet. | ||
747 | // And maybe put the values directly into pinned memory rather than marshaling. | ||
748 | int hullCount = m_hulls.Count; | ||
749 | int totalVertices = 1; // include one for the count of the hulls | ||
750 | foreach (ConvexResult cr in m_hulls) | ||
751 | { | ||
752 | totalVertices += 4; // add four for the vertex count and centroid | ||
753 | totalVertices += cr.HullIndices.Count * 3; // we pass just triangles | ||
754 | } | ||
755 | float[] convHulls = new float[totalVertices]; | ||
635 | 756 | ||
636 | // setup and do convex hull conversion | 757 | convHulls[0] = (float)hullCount; |
637 | m_hulls = new List<ConvexResult>(); | 758 | int jj = 1; |
638 | DecompDesc dcomp = new DecompDesc(); | 759 | foreach (ConvexResult cr in m_hulls) |
639 | dcomp.mIndices = convIndices; | 760 | { |
640 | dcomp.mVertices = convVertices; | 761 | // copy vertices for index access |
641 | dcomp.mDepth = maxDepthSplit; | 762 | float3[] verts = new float3[cr.HullVertices.Count]; |
642 | dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; | 763 | int kk = 0; |
643 | dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; | 764 | foreach (float3 ff in cr.HullVertices) |
644 | dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices; | ||
645 | dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth; | ||
646 | ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); | ||
647 | // create the hull into the _hulls variable | ||
648 | convexBuilder.process(dcomp); | ||
649 | |||
650 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}", | ||
651 | BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count); | ||
652 | |||
653 | // Convert the vertices and indices for passing to unmanaged. | ||
654 | // The hull information is passed as a large floating point array. | ||
655 | // The format is: | ||
656 | // convHulls[0] = number of hulls | ||
657 | // convHulls[1] = number of vertices in first hull | ||
658 | // convHulls[2] = hull centroid X coordinate | ||
659 | // convHulls[3] = hull centroid Y coordinate | ||
660 | // convHulls[4] = hull centroid Z coordinate | ||
661 | // convHulls[5] = first hull vertex X | ||
662 | // convHulls[6] = first hull vertex Y | ||
663 | // convHulls[7] = first hull vertex Z | ||
664 | // convHulls[8] = second hull vertex X | ||
665 | // ... | ||
666 | // convHulls[n] = number of vertices in second hull | ||
667 | // convHulls[n+1] = second hull centroid X coordinate | ||
668 | // ... | ||
669 | // | ||
670 | // TODO: is is very inefficient. Someday change the convex hull generator to return | ||
671 | // data structures that do not need to be converted in order to pass to Bullet. | ||
672 | // And maybe put the values directly into pinned memory rather than marshaling. | ||
673 | int hullCount = m_hulls.Count; | ||
674 | int totalVertices = 1; // include one for the count of the hulls | ||
675 | foreach (ConvexResult cr in m_hulls) | ||
676 | { | 765 | { |
677 | totalVertices += 4; // add four for the vertex count and centroid | 766 | verts[kk++] = ff; |
678 | totalVertices += cr.HullIndices.Count * 3; // we pass just triangles | ||
679 | } | 767 | } |
680 | float[] convHulls = new float[totalVertices]; | ||
681 | 768 | ||
682 | convHulls[0] = (float)hullCount; | 769 | // add to the array one hull's worth of data |
683 | int jj = 1; | 770 | convHulls[jj++] = cr.HullIndices.Count; |
684 | foreach (ConvexResult cr in m_hulls) | 771 | convHulls[jj++] = 0f; // centroid x,y,z |
772 | convHulls[jj++] = 0f; | ||
773 | convHulls[jj++] = 0f; | ||
774 | foreach (int ind in cr.HullIndices) | ||
685 | { | 775 | { |
686 | // copy vertices for index access | 776 | convHulls[jj++] = verts[ind].x; |
687 | float3[] verts = new float3[cr.HullVertices.Count]; | 777 | convHulls[jj++] = verts[ind].y; |
688 | int kk = 0; | 778 | convHulls[jj++] = verts[ind].z; |
689 | foreach (float3 ff in cr.HullVertices) | ||
690 | { | ||
691 | verts[kk++] = ff; | ||
692 | } | ||
693 | |||
694 | // add to the array one hull's worth of data | ||
695 | convHulls[jj++] = cr.HullIndices.Count; | ||
696 | convHulls[jj++] = 0f; // centroid x,y,z | ||
697 | convHulls[jj++] = 0f; | ||
698 | convHulls[jj++] = 0f; | ||
699 | foreach (int ind in cr.HullIndices) | ||
700 | { | ||
701 | convHulls[jj++] = verts[ind].x; | ||
702 | convHulls[jj++] = verts[ind].y; | ||
703 | convHulls[jj++] = verts[ind].z; | ||
704 | } | ||
705 | } | 779 | } |
706 | // create the hull data structure in Bullet | ||
707 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
708 | } | 780 | } |
709 | newShape.shapeKey = newHullKey; | 781 | // create the hull data structure in Bullet |
782 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
710 | } | 783 | } |
784 | newShape.shapeKey = newHullKey; | ||
711 | return newShape; | 785 | return newShape; |
712 | } | 786 | } |
713 | // Callback from convex hull creater with a newly created hull. | 787 | // Callback from convex hull creater with a newly created hull. |
@@ -803,6 +877,7 @@ public class BSShapeCompound : BSShape | |||
803 | // Called at taint-time. | 877 | // Called at taint-time. |
804 | private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) | 878 | private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) |
805 | { | 879 | { |
880 | // TODO: figure a better way to go through all the shape types and find a possible instance. | ||
806 | BSShapeMesh meshDesc; | 881 | BSShapeMesh meshDesc; |
807 | if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) | 882 | if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) |
808 | { | 883 | { |
@@ -824,17 +899,27 @@ public class BSShapeCompound : BSShape | |||
824 | } | 899 | } |
825 | else | 900 | else |
826 | { | 901 | { |
827 | if (physicsScene.PE.IsCompound(pShape)) | 902 | BSShapeGImpact gImpactDesc; |
903 | if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc)) | ||
828 | { | 904 | { |
829 | BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); | 905 | gImpactDesc.Dereference(physicsScene); |
830 | recursiveCompound.Dereference(physicsScene); | ||
831 | } | 906 | } |
832 | else | 907 | else |
833 | { | 908 | { |
834 | if (physicsScene.PE.IsNativeShape(pShape)) | 909 | // Didn't find it in the lists of specific types. It could be compound. |
910 | if (physicsScene.PE.IsCompound(pShape)) | ||
911 | { | ||
912 | BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); | ||
913 | recursiveCompound.Dereference(physicsScene); | ||
914 | } | ||
915 | else | ||
835 | { | 916 | { |
836 | BSShapeNative nativeShape = new BSShapeNative(pShape); | 917 | // If none of the above, maybe it is a simple native shape. |
837 | nativeShape.Dereference(physicsScene); | 918 | if (physicsScene.PE.IsNativeShape(pShape)) |
919 | { | ||
920 | BSShapeNative nativeShape = new BSShapeNative(pShape); | ||
921 | nativeShape.Dereference(physicsScene); | ||
922 | } | ||
838 | } | 923 | } |
839 | } | 924 | } |
840 | } | 925 | } |
@@ -857,7 +942,7 @@ public class BSShapeConvexHull : BSShape | |||
857 | float lod; | 942 | float lod; |
858 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | 943 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); |
859 | 944 | ||
860 | physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}", | 945 | physicsScene.DetailLog("{0},BSShapeConvexHull,getReference,newKey={1},size={2},lod={3}", |
861 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); | 946 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); |
862 | 947 | ||
863 | BSShapeConvexHull retConvexHull = null; | 948 | BSShapeConvexHull retConvexHull = null; |
@@ -937,6 +1022,98 @@ public class BSShapeConvexHull : BSShape | |||
937 | return ret; | 1022 | return ret; |
938 | } | 1023 | } |
939 | } | 1024 | } |
1025 | // ============================================================================================================ | ||
1026 | public class BSShapeGImpact : BSShape | ||
1027 | { | ||
1028 | private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]"; | ||
1029 | public static Dictionary<System.UInt64, BSShapeGImpact> GImpacts = new Dictionary<System.UInt64, BSShapeGImpact>(); | ||
1030 | |||
1031 | public BSShapeGImpact(BulletShape pShape) : base(pShape) | ||
1032 | { | ||
1033 | } | ||
1034 | public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | ||
1035 | { | ||
1036 | float lod; | ||
1037 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | ||
1038 | |||
1039 | physicsScene.DetailLog("{0},BSShapeGImpact,getReference,newKey={1},size={2},lod={3}", | ||
1040 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); | ||
1041 | |||
1042 | BSShapeGImpact retGImpact = null; | ||
1043 | lock (GImpacts) | ||
1044 | { | ||
1045 | if (GImpacts.TryGetValue(newMeshKey, out retGImpact)) | ||
1046 | { | ||
1047 | // The mesh has already been created. Return a new reference to same. | ||
1048 | retGImpact.IncrementReference(); | ||
1049 | } | ||
1050 | else | ||
1051 | { | ||
1052 | retGImpact = new BSShapeGImpact(new BulletShape()); | ||
1053 | BulletShape newShape = retGImpact.CreatePhysicalGImpact(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod); | ||
1054 | |||
1055 | // Check to see if mesh was created (might require an asset). | ||
1056 | newShape = VerifyMeshCreated(physicsScene, newShape, prim); | ||
1057 | newShape.shapeKey = newMeshKey; | ||
1058 | if (!newShape.isNativeShape || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) | ||
1059 | { | ||
1060 | // If a mesh was what was created, remember the built shape for later sharing. | ||
1061 | // Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh. | ||
1062 | GImpacts.Add(newMeshKey, retGImpact); | ||
1063 | } | ||
1064 | |||
1065 | retGImpact.physShapeInfo = newShape; | ||
1066 | } | ||
1067 | } | ||
1068 | return retGImpact; | ||
1069 | } | ||
1070 | |||
1071 | private BulletShape CreatePhysicalGImpact(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
1072 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | ||
1073 | { | ||
1074 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, | ||
1075 | (w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) ); | ||
1076 | } | ||
1077 | |||
1078 | public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim) | ||
1079 | { | ||
1080 | // Calling this reference means we want another handle to an existing shape | ||
1081 | // (usually linksets) so return this copy. | ||
1082 | IncrementReference(); | ||
1083 | return this; | ||
1084 | } | ||
1085 | // Dereferencing a compound shape releases the hold on all the child shapes. | ||
1086 | public override void Dereference(BSScene physicsScene) | ||
1087 | { | ||
1088 | lock (GImpacts) | ||
1089 | { | ||
1090 | this.DecrementReference(); | ||
1091 | physicsScene.DetailLog("{0},BSShapeGImpact.Dereference,shape={1}", BSScene.DetailLogZero, this); | ||
1092 | // TODO: schedule aging and destruction of unused meshes. | ||
1093 | } | ||
1094 | } | ||
1095 | // Loop through all the known hulls and return the description based on the physical address. | ||
1096 | public static bool TryGetGImpactByPtr(BulletShape pShape, out BSShapeGImpact outHull) | ||
1097 | { | ||
1098 | bool ret = false; | ||
1099 | BSShapeGImpact foundDesc = null; | ||
1100 | lock (GImpacts) | ||
1101 | { | ||
1102 | foreach (BSShapeGImpact sh in GImpacts.Values) | ||
1103 | { | ||
1104 | if (sh.physShapeInfo.ReferenceSame(pShape)) | ||
1105 | { | ||
1106 | foundDesc = sh; | ||
1107 | ret = true; | ||
1108 | break; | ||
1109 | } | ||
1110 | |||
1111 | } | ||
1112 | } | ||
1113 | outHull = foundDesc; | ||
1114 | return ret; | ||
1115 | } | ||
1116 | } | ||
940 | 1117 | ||
941 | // ============================================================================================================ | 1118 | // ============================================================================================================ |
942 | public class BSShapeAvatar : BSShape | 1119 | public class BSShapeAvatar : BSShape |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 5792ae6..df1da63 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | |||
@@ -1,16 +1,12 @@ | |||
1 | PROBLEMS TO LOOK INTO | 1 | CURRENT PROBLEMS TO FIX AND/OR LOOK AT |
2 | ================================================= | 2 | ================================================= |
3 | Nebadon vehicle ride, get up, ride again. Second time vehicle does not act correctly. | 3 | Script changing rotation of child prim while vehicle moving (eg turning wheel) causes |
4 | the wheel to appear to jump back. Looks like sending position from previous update. | ||
5 | Vehicle ride, get up, ride again. Second time vehicle does not act correctly. | ||
4 | Have to rez new vehicle and delete the old to fix situation. | 6 | Have to rez new vehicle and delete the old to fix situation. |
5 | Hitting RESET on Nebadon's vehicle while riding causes vehicle to get into odd | 7 | Hitting RESET on Nebadon's vehicle while riding causes vehicle to get into odd |
6 | position state where it will not settle onto ground properly, etc | 8 | position state where it will not settle onto ground properly, etc |
7 | Two of Nebadon vehicles in a sim max the CPU. This is new. | 9 | Two of Nebadon vehicles in a sim max the CPU. This is new. |
8 | A sitting, active vehicle bobs up and down a small amount. | ||
9 | |||
10 | CURRENT PRIORITIES | ||
11 | ================================================= | ||
12 | Use the HACD convex hull routine in Bullet rather than the C# version. | ||
13 | Speed up hullifying large meshes. | ||
14 | Enable vehicle border crossings (at least as poorly as ODE) | 10 | Enable vehicle border crossings (at least as poorly as ODE) |
15 | Terrain skirts | 11 | Terrain skirts |
16 | Avatar created in previous region and not new region when crossing border | 12 | 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. | |||
361 | Nebadon vehicles turning funny in arena (DONE) | 357 | Nebadon vehicles turning funny in arena (DONE) |
362 | Lock axis (DONE 20130401) | 358 | Lock axis (DONE 20130401) |
363 | Terrain detail: double terrain mesh detail (DONE) | 359 | Terrain detail: double terrain mesh detail (DONE) |
360 | Use the HACD convex hull routine in Bullet rather than the C# version. | ||
361 | Speed up hullifying large meshes. (DONE) | ||
364 | 362 | ||
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 79edc12..fc679e7 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -64,6 +64,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
64 | public class Meshmerizer : IMesher | 64 | public class Meshmerizer : IMesher |
65 | { | 65 | { |
66 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 66 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
67 | private static string LogHeader = "[MESH]"; | ||
67 | 68 | ||
68 | // Setting baseDir to a path will enable the dumping of raw files | 69 | // Setting baseDir to a path will enable the dumping of raw files |
69 | // raw files can be imported by blender so a visual inspection of the results can be done | 70 | // 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 | |||
72 | #else | 73 | #else |
73 | private const string baseDir = null; //"rawFiles"; | 74 | private const string baseDir = null; //"rawFiles"; |
74 | #endif | 75 | #endif |
76 | // If 'true', lots of DEBUG logging of asset parsing details | ||
77 | private bool debugDetail = false; | ||
75 | 78 | ||
76 | private bool cacheSculptMaps = true; | 79 | private bool cacheSculptMaps = true; |
77 | private string decodedSculptMapPath = null; | 80 | private string decodedSculptMapPath = null; |
@@ -80,6 +83,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
80 | private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh | 83 | private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh |
81 | 84 | ||
82 | private List<List<Vector3>> mConvexHulls = null; | 85 | private List<List<Vector3>> mConvexHulls = null; |
86 | private List<Vector3> mBoundingHull = null; | ||
83 | 87 | ||
84 | private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); | 88 | private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); |
85 | 89 | ||
@@ -90,8 +94,11 @@ namespace OpenSim.Region.Physics.Meshing | |||
90 | 94 | ||
91 | decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); | 95 | decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); |
92 | cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); | 96 | cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); |
93 | if(mesh_config != null) | 97 | if (mesh_config != null) |
98 | { | ||
94 | useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); | 99 | useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); |
100 | debugDetail = mesh_config.GetBoolean("LogMeshDetails", debugDetail); | ||
101 | } | ||
95 | 102 | ||
96 | try | 103 | try |
97 | { | 104 | { |
@@ -321,6 +328,9 @@ namespace OpenSim.Region.Physics.Meshing | |||
321 | faces = new List<Face>(); | 328 | faces = new List<Face>(); |
322 | OSD meshOsd = null; | 329 | OSD meshOsd = null; |
323 | 330 | ||
331 | mConvexHulls = null; | ||
332 | mBoundingHull = null; | ||
333 | |||
324 | if (primShape.SculptData.Length <= 0) | 334 | if (primShape.SculptData.Length <= 0) |
325 | { | 335 | { |
326 | // XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this | 336 | // XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this |
@@ -357,43 +367,79 @@ namespace OpenSim.Region.Physics.Meshing | |||
357 | OSDMap physicsParms = null; | 367 | OSDMap physicsParms = null; |
358 | OSDMap map = (OSDMap)meshOsd; | 368 | OSDMap map = (OSDMap)meshOsd; |
359 | if (map.ContainsKey("physics_shape")) | 369 | if (map.ContainsKey("physics_shape")) |
370 | { | ||
360 | physicsParms = (OSDMap)map["physics_shape"]; // old asset format | 371 | physicsParms = (OSDMap)map["physics_shape"]; // old asset format |
372 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}': using 'physics_shape' mesh data", LogHeader, primName); | ||
373 | } | ||
361 | else if (map.ContainsKey("physics_mesh")) | 374 | else if (map.ContainsKey("physics_mesh")) |
375 | { | ||
362 | physicsParms = (OSDMap)map["physics_mesh"]; // new asset format | 376 | physicsParms = (OSDMap)map["physics_mesh"]; // new asset format |
377 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'physics_mesh' mesh data", LogHeader, primName); | ||
378 | } | ||
363 | else if (map.ContainsKey("medium_lod")) | 379 | else if (map.ContainsKey("medium_lod")) |
380 | { | ||
364 | physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh | 381 | physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh |
382 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'medium_lod' mesh data", LogHeader, primName); | ||
383 | } | ||
365 | else if (map.ContainsKey("high_lod")) | 384 | else if (map.ContainsKey("high_lod")) |
385 | { | ||
366 | physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :) | 386 | physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :) |
387 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'high_lod' mesh data", LogHeader, primName); | ||
388 | } | ||
367 | 389 | ||
368 | if (map.ContainsKey("physics_convex")) | 390 | if (map.ContainsKey("physics_convex")) |
369 | { // pull this out also in case physics engine can use it | 391 | { // pull this out also in case physics engine can use it |
392 | OSD convexBlockOsd = null; | ||
370 | try | 393 | try |
371 | { | 394 | { |
372 | OSDMap convexBlock = (OSDMap)map["physics_convex"]; | 395 | OSDMap convexBlock = (OSDMap)map["physics_convex"]; |
373 | if (convexBlock.ContainsKey("HullList")) | ||
374 | { | 396 | { |
375 | byte[] hullList = convexBlock["HullList"].AsBinary(); | 397 | int convexOffset = convexBlock["offset"].AsInteger() + (int)start; |
398 | int convexSize = convexBlock["size"].AsInteger(); | ||
399 | |||
400 | byte[] convexBytes = new byte[convexSize]; | ||
401 | |||
402 | System.Buffer.BlockCopy(primShape.SculptData, convexOffset, convexBytes, 0, convexSize); | ||
403 | |||
404 | try | ||
405 | { | ||
406 | convexBlockOsd = DecompressOsd(convexBytes); | ||
407 | } | ||
408 | catch (Exception e) | ||
409 | { | ||
410 | m_log.ErrorFormat("{0} prim='{1}': exception decoding convex block: {2}", LogHeader, primName, e); | ||
411 | //return false; | ||
412 | } | ||
413 | } | ||
414 | |||
415 | if (convexBlockOsd != null && convexBlockOsd is OSDMap) | ||
416 | { | ||
417 | convexBlock = convexBlockOsd as OSDMap; | ||
418 | |||
419 | if (debugDetail) | ||
420 | { | ||
421 | string keys = LogHeader + " keys found in convexBlock: "; | ||
422 | foreach (KeyValuePair<string, OSD> kvp in convexBlock) | ||
423 | keys += "'" + kvp.Key + "' "; | ||
424 | m_log.Debug(keys); | ||
425 | } | ||
426 | |||
376 | Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f); | 427 | Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f); |
377 | if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3(); | 428 | if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3(); |
378 | Vector3 max = new Vector3(0.5f, 0.5f, 0.5f); | 429 | Vector3 max = new Vector3(0.5f, 0.5f, 0.5f); |
379 | if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3(); | 430 | if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3(); |
380 | 431 | ||
381 | // decompress and decode hull points | 432 | List<Vector3> boundingHull = null; |
382 | byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary(); | ||
383 | |||
384 | List<List<Vector3>> hulls = new List<List<Vector3>>(); | ||
385 | int posNdx = 0; | ||
386 | 433 | ||
387 | foreach (byte cnt in hullList) | 434 | if (convexBlock.ContainsKey("BoundingVerts")) |
388 | { | 435 | { |
389 | int count = cnt == 0 ? 256 : cnt; | 436 | byte[] boundingVertsBytes = convexBlock["BoundingVerts"].AsBinary(); |
390 | List<Vector3> hull = new List<Vector3>(); | 437 | boundingHull = new List<Vector3>(); |
391 | 438 | for (int i = 0; i < boundingVertsBytes.Length; ) | |
392 | for (int i = 0; i < count; i++) | ||
393 | { | 439 | { |
394 | ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | 440 | ushort uX = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2; |
395 | ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | 441 | ushort uY = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2; |
396 | ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | 442 | ushort uZ = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2; |
397 | 443 | ||
398 | Vector3 pos = new Vector3( | 444 | Vector3 pos = new Vector3( |
399 | Utils.UInt16ToFloat(uX, min.X, max.X), | 445 | Utils.UInt16ToFloat(uX, min.X, max.X), |
@@ -401,18 +447,57 @@ namespace OpenSim.Region.Physics.Meshing | |||
401 | Utils.UInt16ToFloat(uZ, min.Z, max.Z) | 447 | Utils.UInt16ToFloat(uZ, min.Z, max.Z) |
402 | ); | 448 | ); |
403 | 449 | ||
404 | hull.Add(pos); | 450 | boundingHull.Add(pos); |
405 | } | 451 | } |
406 | 452 | ||
407 | hulls.Add(hull); | 453 | mBoundingHull = boundingHull; |
454 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed bounding hull. nVerts={2}", LogHeader, primName, mBoundingHull.Count); | ||
408 | } | 455 | } |
409 | 456 | ||
410 | mConvexHulls = hulls; | 457 | if (convexBlock.ContainsKey("HullList")) |
458 | { | ||
459 | byte[] hullList = convexBlock["HullList"].AsBinary(); | ||
460 | |||
461 | byte[] posBytes = convexBlock["Positions"].AsBinary(); | ||
462 | |||
463 | List<List<Vector3>> hulls = new List<List<Vector3>>(); | ||
464 | int posNdx = 0; | ||
465 | |||
466 | foreach (byte cnt in hullList) | ||
467 | { | ||
468 | int count = cnt == 0 ? 256 : cnt; | ||
469 | List<Vector3> hull = new List<Vector3>(); | ||
470 | |||
471 | for (int i = 0; i < count; i++) | ||
472 | { | ||
473 | ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | ||
474 | ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | ||
475 | ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | ||
476 | |||
477 | Vector3 pos = new Vector3( | ||
478 | Utils.UInt16ToFloat(uX, min.X, max.X), | ||
479 | Utils.UInt16ToFloat(uY, min.Y, max.Y), | ||
480 | Utils.UInt16ToFloat(uZ, min.Z, max.Z) | ||
481 | ); | ||
482 | |||
483 | hull.Add(pos); | ||
484 | } | ||
485 | |||
486 | hulls.Add(hull); | ||
487 | } | ||
488 | |||
489 | mConvexHulls = hulls; | ||
490 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed hulls. nHulls={2}", LogHeader, primName, mConvexHulls.Count); | ||
491 | } | ||
492 | else | ||
493 | { | ||
494 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}' has physics_convex but no HullList", LogHeader, primName); | ||
495 | } | ||
411 | } | 496 | } |
412 | } | 497 | } |
413 | catch (Exception e) | 498 | catch (Exception e) |
414 | { | 499 | { |
415 | m_log.WarnFormat("[MESH]: exception decoding convex block: {0}", e.Message); | 500 | m_log.WarnFormat("{0} exception decoding convex block: {1}", LogHeader, e); |
416 | } | 501 | } |
417 | } | 502 | } |
418 | 503 | ||
@@ -431,14 +516,14 @@ namespace OpenSim.Region.Physics.Meshing | |||
431 | OSD decodedMeshOsd = new OSD(); | 516 | OSD decodedMeshOsd = new OSD(); |
432 | byte[] meshBytes = new byte[physSize]; | 517 | byte[] meshBytes = new byte[physSize]; |
433 | System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); | 518 | System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); |
434 | // byte[] decompressed = new byte[physSize * 5]; | 519 | // byte[] decompressed = new byte[physSize * 5]; |
435 | try | 520 | try |
436 | { | 521 | { |
437 | decodedMeshOsd = DecompressOsd(meshBytes); | 522 | decodedMeshOsd = DecompressOsd(meshBytes); |
438 | } | 523 | } |
439 | catch (Exception e) | 524 | catch (Exception e) |
440 | { | 525 | { |
441 | m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); | 526 | m_log.ErrorFormat("{0} prim='{1}': exception decoding physical mesh: {2}", LogHeader, primName, e); |
442 | return false; | 527 | return false; |
443 | } | 528 | } |
444 | 529 | ||
@@ -447,7 +532,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
447 | // physics_shape is an array of OSDMaps, one for each submesh | 532 | // physics_shape is an array of OSDMaps, one for each submesh |
448 | if (decodedMeshOsd is OSDArray) | 533 | if (decodedMeshOsd is OSDArray) |
449 | { | 534 | { |
450 | // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); | 535 | // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); |
451 | 536 | ||
452 | decodedMeshOsdArray = (OSDArray)decodedMeshOsd; | 537 | decodedMeshOsdArray = (OSDArray)decodedMeshOsd; |
453 | foreach (OSD subMeshOsd in decodedMeshOsdArray) | 538 | foreach (OSD subMeshOsd in decodedMeshOsdArray) |
@@ -455,6 +540,9 @@ namespace OpenSim.Region.Physics.Meshing | |||
455 | if (subMeshOsd is OSDMap) | 540 | if (subMeshOsd is OSDMap) |
456 | AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); | 541 | AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); |
457 | } | 542 | } |
543 | if (debugDetail) | ||
544 | m_log.DebugFormat("{0} {1}: mesh decoded. offset={2}, size={3}, nCoords={4}, nFaces={5}", | ||
545 | LogHeader, primName, physOffset, physSize, coords.Count, faces.Count); | ||
458 | } | 546 | } |
459 | } | 547 | } |
460 | 548 | ||
@@ -776,6 +864,23 @@ namespace OpenSim.Region.Physics.Meshing | |||
776 | /// temporary prototype code - please do not use until the interface has been finalized! | 864 | /// temporary prototype code - please do not use until the interface has been finalized! |
777 | /// </summary> | 865 | /// </summary> |
778 | /// <param name="size">value to scale the hull points by</param> | 866 | /// <param name="size">value to scale the hull points by</param> |
867 | /// <returns>a list of vertices in the bounding hull if it exists and has been successfully decoded, otherwise null</returns> | ||
868 | public List<Vector3> GetBoundingHull(Vector3 size) | ||
869 | { | ||
870 | if (mBoundingHull == null) | ||
871 | return null; | ||
872 | |||
873 | List<Vector3> verts = new List<Vector3>(); | ||
874 | foreach (var vert in mBoundingHull) | ||
875 | verts.Add(vert * size); | ||
876 | |||
877 | return verts; | ||
878 | } | ||
879 | |||
880 | /// <summary> | ||
881 | /// temporary prototype code - please do not use until the interface has been finalized! | ||
882 | /// </summary> | ||
883 | /// <param name="size">value to scale the hull points by</param> | ||
779 | /// <returns>a list of hulls if they exist and have been successfully decoded, otherwise null</returns> | 884 | /// <returns>a list of hulls if they exist and have been successfully decoded, otherwise null</returns> |
780 | public List<List<Vector3>> GetConvexHulls(Vector3 size) | 885 | public List<List<Vector3>> GetConvexHulls(Vector3 size) |
781 | { | 886 | { |
@@ -788,6 +893,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
788 | List<Vector3> verts = new List<Vector3>(); | 893 | List<Vector3> verts = new List<Vector3>(); |
789 | foreach (var vert in hull) | 894 | foreach (var vert in hull) |
790 | verts.Add(vert * size); | 895 | verts.Add(vert * size); |
896 | hulls.Add(verts); | ||
791 | } | 897 | } |
792 | 898 | ||
793 | return hulls; | 899 | return hulls; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 969243c..0b4b043 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -2474,9 +2474,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2474 | // send the sound, once, to all clients in range | 2474 | // send the sound, once, to all clients in range |
2475 | if (m_SoundModule != null) | 2475 | if (m_SoundModule != null) |
2476 | { | 2476 | { |
2477 | m_SoundModule.SendSound(m_host.UUID, | 2477 | m_SoundModule.SendSound( |
2478 | ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0, | 2478 | m_host.UUID, |
2479 | 0, false, false); | 2479 | ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), |
2480 | volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None, | ||
2481 | 0, false, false); | ||
2480 | } | 2482 | } |
2481 | } | 2483 | } |
2482 | 2484 | ||
@@ -11822,7 +11824,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11822 | public void llSetSoundQueueing(int queue) | 11824 | public void llSetSoundQueueing(int queue) |
11823 | { | 11825 | { |
11824 | m_host.AddScriptLPS(1); | 11826 | m_host.AddScriptLPS(1); |
11825 | NotImplemented("llSetSoundQueueing"); | 11827 | |
11828 | if (m_SoundModule != null) | ||
11829 | m_SoundModule.SetSoundQueueing(m_host.UUID, queue == ScriptBaseClass.TRUE.value); | ||
11826 | } | 11830 | } |
11827 | 11831 | ||
11828 | public void llCollisionSprite(string impact_sprite) | 11832 | public void llCollisionSprite(string impact_sprite) |