aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs87
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs34
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs13
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs162
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs2
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs23
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs62
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs571
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs288
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs15
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs253
14 files changed, 1070 insertions, 452 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index ee66485..7364f45 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -460,6 +460,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
460 } 460 }
461 461
462 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } 462 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
463
463 464
464 #endregion Properties 465 #endregion Properties
465 466
@@ -585,6 +586,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
585 // Disable UDP handling for this client 586 // Disable UDP handling for this client
586 m_udpClient.Shutdown(); 587 m_udpClient.Shutdown();
587 588
589
588 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 590 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
589 //GC.Collect(); 591 //GC.Collect();
590 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); 592 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -2750,8 +2752,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2750 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2752 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2751 return; 2753 return;
2752 } 2754 }
2755 int WearableOut = 0;
2756 bool isWearable = false;
2757
2758 if (req.AssetInf != null)
2759 isWearable =
2760 ((AssetType) req.AssetInf.Type ==
2761 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2753 2762
2754 //m_log.Debug("sending asset " + req.RequestAssetID); 2763
2764 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2765
2766
2767 //if (isWearable)
2768 // m_log.Debug((AssetType)req.AssetInf.Type);
2769
2755 TransferInfoPacket Transfer = new TransferInfoPacket(); 2770 TransferInfoPacket Transfer = new TransferInfoPacket();
2756 Transfer.TransferInfo.ChannelType = 2; 2771 Transfer.TransferInfo.ChannelType = 2;
2757 Transfer.TransferInfo.Status = 0; 2772 Transfer.TransferInfo.Status = 0;
@@ -2773,7 +2788,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2773 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2788 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2774 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2789 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2775 Transfer.Header.Zerocoded = true; 2790 Transfer.Header.Zerocoded = true;
2776 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2791 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset);
2777 2792
2778 if (req.NumPackets == 1) 2793 if (req.NumPackets == 1)
2779 { 2794 {
@@ -2784,7 +2799,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2784 TransferPacket.TransferData.Data = req.AssetInf.Data; 2799 TransferPacket.TransferData.Data = req.AssetInf.Data;
2785 TransferPacket.TransferData.Status = 1; 2800 TransferPacket.TransferData.Status = 1;
2786 TransferPacket.Header.Zerocoded = true; 2801 TransferPacket.Header.Zerocoded = true;
2787 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2802 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset);
2788 } 2803 }
2789 else 2804 else
2790 { 2805 {
@@ -2817,7 +2832,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2817 TransferPacket.TransferData.Status = 1; 2832 TransferPacket.TransferData.Status = 1;
2818 } 2833 }
2819 TransferPacket.Header.Zerocoded = true; 2834 TransferPacket.Header.Zerocoded = true;
2820 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2835 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset);
2821 2836
2822 processedLength += chunkSize; 2837 processedLength += chunkSize;
2823 packetNumber++; 2838 packetNumber++;
@@ -3572,24 +3587,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3572 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3587 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3573 AgentWearablesUpdatePacket.WearableDataBlock awb; 3588 AgentWearablesUpdatePacket.WearableDataBlock awb;
3574 int idx = 0; 3589 int idx = 0;
3575 for (int i = 0; i < wearables.Length; i++) 3590
3576 { 3591 for (int i = 0; i < wearables.Length; i++)
3577 for (int j = 0; j < wearables[i].Count; j++) 3592 {
3578 { 3593 for (int j = 0; j < wearables[i].Count; j++)
3579 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3594 {
3580 awb.WearableType = (byte)i; 3595 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3581 awb.AssetID = wearables[i][j].AssetID; 3596 awb.WearableType = (byte) i;
3582 awb.ItemID = wearables[i][j].ItemID; 3597 awb.AssetID = wearables[i][j].AssetID;
3583 aw.WearableData[idx] = awb; 3598 awb.ItemID = wearables[i][j].ItemID;
3584 idx++; 3599 aw.WearableData[idx] = awb;
3585 3600 idx++;
3586// m_log.DebugFormat( 3601
3587// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3602 // m_log.DebugFormat(
3588// awb.ItemID, awb.AssetID, i, Name); 3603 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3589 } 3604 // awb.ItemID, awb.AssetID, i, Name);
3590 } 3605 }
3606 }
3591 3607
3592 OutPacket(aw, ThrottleOutPacketType.Task); 3608 OutPacket(aw, ThrottleOutPacketType.State);
3593 } 3609 }
3594 3610
3595 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3611 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3614,7 +3630,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3614 avp.Sender.IsTrial = false; 3630 avp.Sender.IsTrial = false;
3615 avp.Sender.ID = agentID; 3631 avp.Sender.ID = agentID;
3616 //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); 3632 //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
3617 OutPacket(avp, ThrottleOutPacketType.Task); 3633 OutPacket(avp, ThrottleOutPacketType.State);
3618 } 3634 }
3619 3635
3620 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) 3636 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
@@ -6282,12 +6298,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6282 byte[] visualparams = new byte[appear.VisualParam.Length]; 6298 byte[] visualparams = new byte[appear.VisualParam.Length];
6283 for (int i = 0; i < appear.VisualParam.Length; i++) 6299 for (int i = 0; i < appear.VisualParam.Length; i++)
6284 visualparams[i] = appear.VisualParam[i].ParamValue; 6300 visualparams[i] = appear.VisualParam[i].ParamValue;
6285 6301 //var b = appear.WearableData[0];
6302
6286 Primitive.TextureEntry te = null; 6303 Primitive.TextureEntry te = null;
6287 if (appear.ObjectData.TextureEntry.Length > 1) 6304 if (appear.ObjectData.TextureEntry.Length > 1)
6288 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6305 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6306
6307 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6308 for (int i=0; i<appear.WearableData.Length;i++)
6309 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6310
6311
6289 6312
6290 handlerSetAppearance(sender, te, visualparams,avSize); 6313 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6291 } 6314 }
6292 catch (Exception e) 6315 catch (Exception e)
6293 { 6316 {
@@ -7798,6 +7821,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7798 // surrounding scene 7821 // surrounding scene
7799 if ((ImageType)block.Type == ImageType.Baked) 7822 if ((ImageType)block.Type == ImageType.Baked)
7800 args.Priority *= 2.0f; 7823 args.Priority *= 2.0f;
7824 int wearableout = 0;
7801 7825
7802 ImageManager.EnqueueReq(args); 7826 ImageManager.EnqueueReq(args);
7803 } 7827 }
@@ -11687,6 +11711,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11687 11711
11688 if (cachedtex.AgentData.SessionID != SessionId) 11712 if (cachedtex.AgentData.SessionID != SessionId)
11689 return false; 11713 return false;
11714
11690 11715
11691 // TODO: don't create new blocks if recycling an old packet 11716 // TODO: don't create new blocks if recycling an old packet
11692 cachedresp.AgentData.AgentID = AgentId; 11717 cachedresp.AgentData.AgentID = AgentId;
@@ -11696,6 +11721,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11696 cachedresp.WearableData = 11721 cachedresp.WearableData =
11697 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; 11722 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11698 11723
11724 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
11725 // var item = fac.GetBakedTextureFaces(AgentId);
11726 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
11727
11699 IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>(); 11728 IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
11700 if (cache == null) 11729 if (cache == null)
11701 { 11730 {
@@ -11703,7 +11732,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11703 { 11732 {
11704 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 11733 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11705 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; 11734 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11706 cachedresp.WearableData[i].TextureID = UUID.Zero; 11735 cachedresp.WearableData[i].TextureID = UUID.Zero; //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11707 cachedresp.WearableData[i].HostName = new byte[0]; 11736 cachedresp.WearableData[i].HostName = new byte[0];
11708 } 11737 }
11709 } 11738 }
@@ -11713,10 +11742,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11713 { 11742 {
11714 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 11743 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11715 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; 11744 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11716 if(cache.Check(cachedtex.WearableData[i].ID.ToString())) 11745
11746
11747
11748 if (cache.Check(cachedtex.WearableData[i].ID.ToString()))
11717 cachedresp.WearableData[i].TextureID = UUID.Zero; 11749 cachedresp.WearableData[i].TextureID = UUID.Zero;
11750 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11718 else 11751 else
11719 cachedresp.WearableData[i].TextureID = UUID.Zero; 11752 cachedresp.WearableData[i].TextureID = UUID.Zero; // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11720 cachedresp.WearableData[i].HostName = new byte[0]; 11753 cachedresp.WearableData[i].HostName = new byte[0];
11721 } 11754 }
11722 } 11755 }
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 3532b1d..3080023 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -140,18 +140,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
140 /// <param name="sp"></param> 140 /// <param name="sp"></param>
141 /// <param name="texture"></param> 141 /// <param name="texture"></param>
142 /// <param name="visualParam"></param> 142 /// <param name="visualParam"></param>
143 public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) 143 public void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems)
144 { 144 {
145 SetAppearance(sp, appearance.Texture, appearance.VisualParams); 145 SetAppearance(sp, appearance.Texture, appearance.VisualParams, cacheItems);
146 } 146 }
147 147
148 148
149 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize) 149 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
150 { 150 {
151 float oldoff = sp.Appearance.AvatarFeetOffset; 151 float oldoff = sp.Appearance.AvatarFeetOffset;
152 Vector3 oldbox = sp.Appearance.AvatarBoxSize; 152 Vector3 oldbox = sp.Appearance.AvatarBoxSize;
153 153
154 SetAppearance(sp, textureEntry, visualParams); 154 SetAppearance(sp, textureEntry, visualParams, cacheItems);
155 sp.Appearance.SetSize(avSize); 155 sp.Appearance.SetSize(avSize);
156 156
157 float off = sp.Appearance.AvatarFeetOffset; 157 float off = sp.Appearance.AvatarFeetOffset;
@@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
166 /// <param name="sp"></param> 166 /// <param name="sp"></param>
167 /// <param name="texture"></param> 167 /// <param name="texture"></param>
168 /// <param name="visualParam"></param> 168 /// <param name="visualParam"></param>
169 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) 169 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems)
170 { 170 {
171// m_log.DebugFormat( 171// m_log.DebugFormat(
172// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", 172// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
@@ -205,11 +205,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
205// ((ScenePresence)sp).SetSize(box,off); 205// ((ScenePresence)sp).SetSize(box,off);
206 206
207 } 207 }
208 208 //if (cacheItems.Length > 0)
209 //{
210 sp.Appearance.WearableCacheItems = cacheItems;
211 //}
209 // Process the baked texture array 212 // Process the baked texture array
210 if (textureEntry != null) 213 if (textureEntry != null)
211 { 214 {
212// m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); 215 m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
213 216
214// WriteBakedTexturesReport(sp, m_log.DebugFormat); 217// WriteBakedTexturesReport(sp, m_log.DebugFormat);
215 218
@@ -278,6 +281,19 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
278 return GetBakedTextureFaces(sp); 281 return GetBakedTextureFaces(sp);
279 } 282 }
280 283
284 public WearableCacheItem[] GetCachedItems(UUID agentId)
285 {
286 ScenePresence sp = m_scene.GetScenePresence(agentId);
287 Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp);
288
289 WearableCacheItem[] items = sp.Appearance.WearableCacheItems;
290 //foreach (WearableCacheItem item in items)
291 //{
292
293 //}
294 return items;
295 }
296
281 public bool SaveBakedTextures(UUID agentId) 297 public bool SaveBakedTextures(UUID agentId)
282 { 298 {
283 ScenePresence sp = m_scene.GetScenePresence(agentId); 299 ScenePresence sp = m_scene.GetScenePresence(agentId);
@@ -660,12 +676,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
660 /// <param name="client"></param> 676 /// <param name="client"></param>
661 /// <param name="texture"></param> 677 /// <param name="texture"></param>
662 /// <param name="visualParam"></param> 678 /// <param name="visualParam"></param>
663 private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize) 679 private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
664 { 680 {
665 // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); 681 // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
666 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 682 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
667 if (sp != null) 683 if (sp != null)
668 SetAppearance(sp, textureEntry, visualParams,avSize); 684 SetAppearance(sp, textureEntry, visualParams,avSize, cacheItems);
669 else 685 else
670 m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); 686 m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
671 } 687 }
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
index 1830d41..f090e15 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
61 for (byte i = 0; i < visualParams.Length; i++) 61 for (byte i = 0; i < visualParams.Length; i++)
62 visualParams[i] = i; 62 visualParams[i] = i;
63 63
64 afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); 64 afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams, new WearableCacheItem[0]);
65 65
66 // TODO: Check baked texture 66 // TODO: Check baked texture
67 Assert.AreEqual(visualParams, sp.Appearance.VisualParams); 67 Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
@@ -102,7 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
102 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex); 102 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
103 eyesFace.TextureID = eyesTextureId; 103 eyesFace.TextureID = eyesTextureId;
104 104
105 afm.SetAppearance(sp, bakedTextureEntry, visualParams); 105 afm.SetAppearance(sp, bakedTextureEntry, visualParams, new WearableCacheItem[0]);
106 afm.SaveBakedTextures(userId); 106 afm.SaveBakedTextures(userId);
107// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId); 107// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
108 108
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 8ddff99..07d00c0 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -442,6 +442,19 @@ namespace OpenSim.Region.CoreModules.World.Land
442 return false; 442 return false;
443 } 443 }
444 444
445 public bool CanBeOnThisLand(UUID avatar, float posHeight)
446 {
447 if (posHeight < LandChannel.BAN_LINE_SAFETY_HIEGHT && IsBannedFromLand(avatar))
448 {
449 return false;
450 }
451 else if (IsRestrictedFromLand(avatar))
452 {
453 return false;
454 }
455 return true;
456 }
457
445 public bool HasGroupAccess(UUID avatar) 458 public bool HasGroupAccess(UUID avatar)
446 { 459 {
447 if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) 460 if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
index 34aca33..d25c930 100644
--- a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
@@ -35,8 +35,8 @@ namespace OpenSim.Region.Framework.Interfaces
35 35
36 public interface IAvatarFactoryModule 36 public interface IAvatarFactoryModule
37 { 37 {
38 void SetAppearance(IScenePresence sp, AvatarAppearance appearance); 38 void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems);
39 void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams); 39 void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems);
40 40
41 /// <summary> 41 /// <summary>
42 /// Send the appearance of an avatar to others in the scene. 42 /// Send the appearance of an avatar to others in the scene.
@@ -52,6 +52,8 @@ namespace OpenSim.Region.Framework.Interfaces
52 /// <returns>An empty list if this agent has no baked textures (e.g. because it's a child agent)</returns> 52 /// <returns>An empty list if this agent has no baked textures (e.g. because it's a child agent)</returns>
53 Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId); 53 Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId);
54 54
55
56 WearableCacheItem[] GetCachedItems(UUID agentId);
55 /// <summary> 57 /// <summary>
56 /// Save the baked textures for the given agent permanently in the asset database. 58 /// Save the baked textures for the given agent permanently in the asset database.
57 /// </summary> 59 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index fa1a5af..b9cd3fc 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -923,6 +923,33 @@ namespace OpenSim.Region.Framework.Scenes
923 923
924 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 924 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
925 925
926 UUID groupUUID = UUID.Zero;
927 string GroupName = string.Empty;
928 ulong groupPowers = 0;
929
930 // ----------------------------------
931 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
932 try
933 {
934 if (gm != null)
935 {
936 groupUUID = ControllingClient.ActiveGroupId;
937 GroupRecord record = gm.GetGroupRecord(groupUUID);
938 if (record != null)
939 GroupName = record.GroupName;
940 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
941 if (groupMembershipData != null)
942 groupPowers = groupMembershipData.GroupPowers;
943 }
944 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
945 Grouptitle);
946 }
947 catch (Exception e)
948 {
949 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
950 }
951 // ------------------------------------
952
926 if (ParentID == 0) 953 if (ParentID == 0)
927 { 954 {
928 // Moved this from SendInitialData to ensure that Appearance is initialized 955 // Moved this from SendInitialData to ensure that Appearance is initialized
@@ -1961,7 +1988,8 @@ namespace OpenSim.Region.Framework.Scenes
1961// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 1988// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1962 1989
1963 MovingToTarget = false; 1990 MovingToTarget = false;
1964 MoveToPositionTarget = Vector3.Zero; 1991// MoveToPositionTarget = Vector3.Zero;
1992 m_forceToApply = null; // cancel possible last action
1965 1993
1966 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 1994 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
1967 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 1995 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2080,9 +2108,6 @@ namespace OpenSim.Region.Framework.Scenes
2080 if (part == null) 2108 if (part == null)
2081 return; 2109 return;
2082 2110
2083 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2084 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2085
2086 if (PhysicsActor != null) 2111 if (PhysicsActor != null)
2087 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f; 2112 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2088 2113
@@ -2101,25 +2126,8 @@ namespace OpenSim.Region.Framework.Scenes
2101 } 2126 }
2102 else 2127 else
2103 { 2128 {
2104// if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2129 if (PhysicsSit(part,offset)) // physics engine
2105// { 2130 return;
2106// m_log.DebugFormat(
2107// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2108// Name, part.Name, part.LocalId);
2109
2110 if (m_scene.PhysicsScene != null &&
2111 part.PhysActor != null &&
2112 Util.GetDistanceTo(AbsolutePosition, pos) <= 30)
2113 {
2114
2115 Vector3 camdif = CameraPosition - part.AbsolutePosition;
2116 camdif.Normalize();
2117
2118// m_log.InfoFormat("sit {0} {1}", offset.ToString(), camdif.ToString());
2119
2120 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2121 return;
2122 }
2123 2131
2124 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2132 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2125 { 2133 {
@@ -2127,22 +2135,22 @@ namespace OpenSim.Region.Framework.Scenes
2127 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2135 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2128 canSit = true; 2136 canSit = true;
2129 } 2137 }
2130// else
2131// {
2132// m_log.DebugFormat(
2133// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2134// Name, part.Name, part.LocalId);
2135// }
2136 } 2138 }
2137 2139
2138 if (canSit) 2140 if (canSit)
2139 { 2141 {
2142
2140 if (PhysicsActor != null) 2143 if (PhysicsActor != null)
2141 { 2144 {
2142 // We can remove the physicsActor until they stand up. 2145 // We can remove the physicsActor until they stand up.
2143 RemoveFromPhysicalScene(); 2146 RemoveFromPhysicalScene();
2144 } 2147 }
2145 2148
2149 if (MovingToTarget)
2150 ResetMoveToTarget();
2151
2152 Velocity = Vector3.Zero;
2153
2146 part.AddSittingAvatar(UUID); 2154 part.AddSittingAvatar(UUID);
2147 2155
2148 cameraAtOffset = part.GetCameraAtOffset(); 2156 cameraAtOffset = part.GetCameraAtOffset();
@@ -2179,14 +2187,6 @@ namespace OpenSim.Region.Framework.Scenes
2179 m_requestedSitTargetID = part.LocalId; 2187 m_requestedSitTargetID = part.LocalId;
2180 m_requestedSitTargetUUID = targetID; 2188 m_requestedSitTargetUUID = targetID;
2181 2189
2182// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2183
2184 if (m_scene.PhysicsScene.SupportsRayCast())
2185 {
2186 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2187 //SitRayCastAvatarPosition(part);
2188 //return;
2189 }
2190 } 2190 }
2191 else 2191 else
2192 { 2192 {
@@ -2196,28 +2196,87 @@ namespace OpenSim.Region.Framework.Scenes
2196 SendSitResponse(targetID, offset, Quaternion.Identity); 2196 SendSitResponse(targetID, offset, Quaternion.Identity);
2197 } 2197 }
2198 2198
2199 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation) 2199 // returns false if does not suport so older sit can be tried
2200 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2200 { 2201 {
2202 if (part == null || part.ParentGroup.IsAttachment)
2203 {
2204 return true;
2205 }
2201 2206
2202 if (status < 0) 2207 if ( m_scene.PhysicsScene == null)
2208 return false;
2209
2210 if (part.PhysActor == null)
2203 { 2211 {
2204 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2212 // none physcis shape
2205 return; 2213 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2214 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2215 else
2216 { // non physical phantom TODO
2217 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2218 return false;
2219 }
2220 return true;
2206 } 2221 }
2207 2222
2223
2224 // not doing autopilot
2225 m_requestedSitTargetID = 0;
2226
2227 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2228 return true;
2229
2230 return false;
2231 }
2232
2233
2234 private bool CanEnterLandPosition(Vector3 testPos)
2235 {
2236 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2237
2238 if (land == null || land.LandData.Name == "NO_LAND")
2239 return true;
2240
2241 return land.CanBeOnThisLand(UUID,testPos.Z);
2242 }
2243
2244 // status
2245 // < 0 ignore
2246 // 0 bad sit spot
2247 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2248 {
2249 if (status < 0)
2250 return;
2251
2208 if (status == 0) 2252 if (status == 0)
2253 {
2254 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2209 return; 2255 return;
2256 }
2210 2257
2211 SceneObjectPart part = m_scene.GetSceneObjectPart(partID); 2258 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2212 if (part == null || part.ParentGroup.IsAttachment) 2259 if (part == null)
2260 return;
2261
2262 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2263 if(!CanEnterLandPosition(targetPos))
2213 { 2264 {
2265 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2214 return; 2266 return;
2215 } 2267 }
2216
2217// m_log.InfoFormat("physsit {0} {1}", offset.ToString(),Orientation.ToString()); 2268// m_log.InfoFormat("physsit {0} {1}", offset.ToString(),Orientation.ToString());
2218 2269
2270 RemoveFromPhysicalScene();
2271
2272 if (MovingToTarget)
2273 ResetMoveToTarget();
2274
2275 Velocity = Vector3.Zero;
2276
2219 part.AddSittingAvatar(UUID); 2277 part.AddSittingAvatar(UUID);
2220 2278
2279
2221 Vector3 cameraAtOffset = part.GetCameraAtOffset(); 2280 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2222 Vector3 cameraEyeOffset = part.GetCameraEyeOffset(); 2281 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2223 bool forceMouselook = part.GetForceMouselook(); 2282 bool forceMouselook = part.GetForceMouselook();
@@ -2225,23 +2284,23 @@ namespace OpenSim.Region.Framework.Scenes
2225 ControllingClient.SendSitResponse( 2284 ControllingClient.SendSitResponse(
2226 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); 2285 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2227 2286
2228 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2287 // not using autopilot
2229
2230 // assuming no autopilot in use
2231 Velocity = Vector3.Zero;
2232 RemoveFromPhysicalScene();
2233 2288
2234 Rotation = Orientation; 2289 Rotation = Orientation;
2235 m_pos = offset; 2290 m_pos = offset;
2236 2291
2237 m_requestedSitTargetID = 0; // invalidate the viewer sit comand for now 2292 m_requestedSitTargetID = 0;
2238 part.ParentGroup.AddAvatar(UUID); 2293 part.ParentGroup.AddAvatar(UUID);
2239 2294
2240 ParentPart = part; 2295 ParentPart = part;
2241 ParentID = part.LocalId; 2296 ParentID = part.LocalId;
2242 2297 if(status == 3)
2243 Animator.TrySetMovementAnimation("SIT"); 2298 Animator.TrySetMovementAnimation("SIT_GROUND");
2299 else
2300 Animator.TrySetMovementAnimation("SIT");
2244 SendAvatarDataToAllAgents(); 2301 SendAvatarDataToAllAgents();
2302
2303 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2245 } 2304 }
2246 2305
2247 2306
@@ -2260,6 +2319,7 @@ namespace OpenSim.Region.Framework.Scenes
2260 return; 2319 return;
2261 } 2320 }
2262 2321
2322
2263 if (part.SitTargetAvatar == UUID) 2323 if (part.SitTargetAvatar == UUID)
2264 { 2324 {
2265 Vector3 sitTargetPos = part.SitTargetPosition; 2325 Vector3 sitTargetPos = part.SitTargetPosition;
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 1b4ed1e..5ac4e27 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -911,7 +911,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
911 // Mimicking LLClientView which gets always set appearance from client. 911 // Mimicking LLClientView which gets always set appearance from client.
912 AvatarAppearance appearance; 912 AvatarAppearance appearance;
913 m_scene.GetAvatarAppearance(this, out appearance); 913 m_scene.GetAvatarAppearance(this, out appearance);
914 OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(),appearance.AvatarSize); 914 OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(),appearance.AvatarSize, new WearableCacheItem[0]);
915 } 915 }
916 916
917 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) 917 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index a522277..365fd78 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -108,7 +108,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
108 // ScenePresence.SendInitialData() to reset our entire appearance. 108 // ScenePresence.SendInitialData() to reset our entire appearance.
109 m_scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); 109 m_scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId));
110 110
111 m_afMod.SetAppearance(sp, originalTe, null); 111 m_afMod.SetAppearance(sp, originalTe, null, new WearableCacheItem[0] );
112 112
113 UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance); 113 UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
114 114
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index a442cf0..d24ab2a 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -38,6 +38,9 @@ namespace OpenSim.Region.Physics.Manager
38 38
39 public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal); 39 public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal);
40 public delegate void RayCallback(List<ContactResult> list); 40 public delegate void RayCallback(List<ContactResult> list);
41 public delegate void ProbeBoxCallback(List<ContactResult> list);
42 public delegate void ProbeSphereCallback(List<ContactResult> list);
43 public delegate void ProbePlaneCallback(List<ContactResult> list);
41 public delegate void SitAvatarCallback(int status, uint partID, Vector3 offset, Quaternion Orientation); 44 public delegate void SitAvatarCallback(int status, uint partID, Vector3 offset, Quaternion Orientation);
42 45
43 public delegate void JointMoved(PhysicsJoint joint); 46 public delegate void JointMoved(PhysicsJoint joint);
@@ -56,6 +59,7 @@ namespace OpenSim.Region.Physics.Manager
56 volumedtc = 0x40, 59 volumedtc = 0x40,
57 60
58 // ray cast colision control (may only work for meshs) 61 // ray cast colision control (may only work for meshs)
62 ContactsUnImportant = 0x2000,
59 BackFaceCull = 0x4000, 63 BackFaceCull = 0x4000,
60 ClosestHit = 0x8000, 64 ClosestHit = 0x8000,
61 65
@@ -351,9 +355,22 @@ namespace OpenSim.Region.Physics.Manager
351 return false; 355 return false;
352 } 356 }
353 357
354 public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod){} 358 public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags)
355 public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { } 359 {
356 public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count) 360 return new List<ContactResult>();
361 }
362
363 public virtual List<ContactResult> BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags)
364 {
365 return new List<ContactResult>();
366 }
367
368 public virtual List<ContactResult> SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags)
369 {
370 return new List<ContactResult>();
371 }
372
373 public virtual List<ContactResult> PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags)
357 { 374 {
358 return new List<ContactResult>(); 375 return new List<ContactResult>();
359 } 376 }
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index bb04ea7..f7e4c1c 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -715,7 +715,17 @@ namespace OpenSim.Region.Physics.OdePlugin
715 Vector3 off = _velocity; 715 Vector3 off = _velocity;
716 float t = 0.5f * timeStep; 716 float t = 0.5f * timeStep;
717 off = off * t; 717 off = off * t;
718 d.Quaternion qtmp;
719 d.GeomCopyQuaternion(bbox, out qtmp);
720 Quaternion q;
721 q.X = qtmp.X;
722 q.Y = qtmp.Y;
723 q.Z = qtmp.Z;
724 q.W = qtmp.W;
725 off *= Quaternion.Conjugate(q);
726
718 d.GeomSetOffsetPosition(bbox, off.X, off.Y, off.Z); 727 d.GeomSetOffsetPosition(bbox, off.X, off.Y, off.Z);
728
719 off.X = 2.0f * (m_size.X + Math.Abs(off.X)); 729 off.X = 2.0f * (m_size.X + Math.Abs(off.X));
720 off.Y = 2.0f * (m_size.Y + Math.Abs(off.Y)); 730 off.Y = 2.0f * (m_size.Y + Math.Abs(off.Y));
721 off.Z = m_size.Z + 2.0f * Math.Abs(off.Z); 731 off.Z = m_size.Z + 2.0f * Math.Abs(off.Z);
@@ -741,6 +751,9 @@ namespace OpenSim.Region.Physics.OdePlugin
741 d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories); 751 d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories);
742 d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags); 752 d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags);
743 } 753 }
754 uint cat1 = d.GeomGetCategoryBits(bbox);
755 uint col1 = d.GeomGetCollideBits(bbox);
756
744 } 757 }
745 } 758 }
746 759
@@ -1527,8 +1540,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1527 { 1540 {
1528 if (CollisionEventsThisFrame != null) 1541 if (CollisionEventsThisFrame != null)
1529 { 1542 {
1530 CollisionEventsThisFrame.Clear(); 1543 lock (CollisionEventsThisFrame)
1531 CollisionEventsThisFrame = null; 1544 {
1545 CollisionEventsThisFrame.Clear();
1546 CollisionEventsThisFrame = null;
1547 }
1532 } 1548 }
1533 m_eventsubscription = 0; 1549 m_eventsubscription = 0;
1534 } 1550 }
@@ -1537,8 +1553,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1537 { 1553 {
1538 if (CollisionEventsThisFrame == null) 1554 if (CollisionEventsThisFrame == null)
1539 CollisionEventsThisFrame = new CollisionEventUpdate(); 1555 CollisionEventsThisFrame = new CollisionEventUpdate();
1540 CollisionEventsThisFrame.AddCollider(CollidedWith, contact); 1556 lock (CollisionEventsThisFrame)
1541 _parent_scene.AddCollisionEventReporting(this); 1557 {
1558 CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
1559 _parent_scene.AddCollisionEventReporting(this);
1560 }
1542 } 1561 }
1543 1562
1544 public void SendCollisions() 1563 public void SendCollisions()
@@ -1546,26 +1565,29 @@ namespace OpenSim.Region.Physics.OdePlugin
1546 if (CollisionEventsThisFrame == null) 1565 if (CollisionEventsThisFrame == null)
1547 return; 1566 return;
1548 1567
1549 if (m_cureventsubscription < m_eventsubscription) 1568 lock (CollisionEventsThisFrame)
1550 return; 1569 {
1551 1570 if (m_cureventsubscription < m_eventsubscription)
1552 m_cureventsubscription = 0; 1571 return;
1553 1572
1554 int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count; 1573 m_cureventsubscription = 0;
1555 1574
1556 if (!SentEmptyCollisionsEvent || ncolisions > 0) 1575 int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count;
1557 {
1558 base.SendCollisionUpdate(CollisionEventsThisFrame);
1559 1576
1560 if (ncolisions == 0) 1577 if (!SentEmptyCollisionsEvent || ncolisions > 0)
1561 {
1562 SentEmptyCollisionsEvent = true;
1563 _parent_scene.RemoveCollisionEventReporting(this);
1564 }
1565 else
1566 { 1578 {
1567 SentEmptyCollisionsEvent = false; 1579 base.SendCollisionUpdate(CollisionEventsThisFrame);
1568 CollisionEventsThisFrame.Clear(); 1580
1581 if (ncolisions == 0)
1582 {
1583 SentEmptyCollisionsEvent = true;
1584 _parent_scene.RemoveCollisionEventReporting(this);
1585 }
1586 else
1587 {
1588 SentEmptyCollisionsEvent = false;
1589 CollisionEventsThisFrame.Clear();
1590 }
1569 } 1591 }
1570 } 1592 }
1571 } 1593 }
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
index 561ab1c..6e9281b 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
@@ -56,8 +56,11 @@ namespace OpenSim.Region.Physics.OdePlugin
56 private OdeScene m_scene; 56 private OdeScene m_scene;
57 57
58 IntPtr ray; // the ray. we only need one for our lifetime 58 IntPtr ray; // the ray. we only need one for our lifetime
59 IntPtr Sphere;
60 IntPtr Box;
61 IntPtr Plane;
59 62
60 private const int ColisionContactGeomsPerTest = 5; 63 private int CollisionContactGeomsPerTest = 25;
61 private const int DefaultMaxCount = 25; 64 private const int DefaultMaxCount = 25;
62 private const int MaxTimePerCallMS = 30; 65 private const int MaxTimePerCallMS = 30;
63 66
@@ -65,6 +68,7 @@ namespace OpenSim.Region.Physics.OdePlugin
65 /// ODE near callback delegate 68 /// ODE near callback delegate
66 /// </summary> 69 /// </summary>
67 private d.NearCallback nearCallback; 70 private d.NearCallback nearCallback;
71 private d.NearCallback nearProbeCallback;
68 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 72 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
69 private List<ContactResult> m_contactResults = new List<ContactResult>(); 73 private List<ContactResult> m_contactResults = new List<ContactResult>();
70 private RayFilterFlags CurrentRayFilter; 74 private RayFilterFlags CurrentRayFilter;
@@ -74,155 +78,21 @@ namespace OpenSim.Region.Physics.OdePlugin
74 { 78 {
75 m_scene = pScene; 79 m_scene = pScene;
76 nearCallback = near; 80 nearCallback = near;
81 nearProbeCallback = nearProbe;
77 ray = d.CreateRay(IntPtr.Zero, 1.0f); 82 ray = d.CreateRay(IntPtr.Zero, 1.0f);
78 d.GeomSetCategoryBits(ray,0); 83 d.GeomSetCategoryBits(ray, 0);
84 Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f);
85 d.GeomSetCategoryBits(Box, 0);
86 Sphere = d.CreateSphere(IntPtr.Zero,1.0f);
87 d.GeomSetCategoryBits(Sphere, 0);
88 Plane = d.CreatePlane(IntPtr.Zero, 0f,0f,1f,1f);
89 d.GeomSetCategoryBits(Sphere, 0);
79 } 90 }
80 91
81 /// <summary> 92 public void QueueRequest(ODERayRequest req)
82 /// Queues request for a raycast to all world
83 /// </summary>
84 /// <param name="position">Origin of Ray</param>
85 /// <param name="direction">Ray direction</param>
86 /// <param name="length">Ray length</param>
87 /// <param name="retMethod">Return method to send the results</param>
88 public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod)
89 {
90 ODERayRequest req = new ODERayRequest();
91 req.geom = IntPtr.Zero;
92 req.callbackMethod = retMethod;
93 req.Count = DefaultMaxCount;
94 req.length = length;
95 req.Normal = direction;
96 req.Origin = position;
97 req.filter = RayFilterFlags.AllPrims;
98
99 m_PendingRequests.Enqueue(req);
100 }
101
102 /// <summary>
103 /// Queues request for a raycast to particular part
104 /// </summary>
105 /// <param name="position">Origin of Ray</param>
106 /// <param name="direction">Ray direction</param>
107 /// <param name="length">Ray length</param>
108 /// <param name="retMethod">Return method to send the results</param>
109 public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod)
110 {
111 ODERayRequest req = new ODERayRequest();
112 req.geom = geom;
113 req.callbackMethod = retMethod;
114 req.length = length;
115 req.Normal = direction;
116 req.Origin = position;
117 req.Count = DefaultMaxCount;
118 req.filter = RayFilterFlags.AllPrims;
119
120 m_PendingRequests.Enqueue(req);
121 }
122
123 public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
124 {
125 ODERayRequest req = new ODERayRequest();
126 req.geom = IntPtr.Zero;
127 req.callbackMethod = retMethod;
128 req.Count = DefaultMaxCount;
129 req.length = length;
130 req.Normal = direction;
131 req.Origin = position;
132 req.filter = RayFilterFlags.AllPrims | RayFilterFlags.land;
133
134 m_PendingRequests.Enqueue(req);
135 }
136
137 public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
138 { 93 {
139 ODERayRequest req = new ODERayRequest(); 94 if (req.Count == 0)
140 req.geom = geom; 95 req.Count = DefaultMaxCount;
141 req.callbackMethod = retMethod;
142 req.length = length;
143 req.Normal = direction;
144 req.Origin = position;
145 req.Count = DefaultMaxCount;
146 req.filter = RayFilterFlags.AllPrims;
147
148 m_PendingRequests.Enqueue(req);
149 }
150
151 /// <summary>
152 /// Queues a raycast
153 /// </summary>
154 /// <param name="position">Origin of Ray</param>
155 /// <param name="direction">Ray normal</param>
156 /// <param name="length">Ray length</param>
157 /// <param name="count"></param>
158 /// <param name="retMethod">Return method to send the results</param>
159 public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
160 {
161 ODERayRequest req = new ODERayRequest();
162 req.geom = IntPtr.Zero;
163 req.callbackMethod = retMethod;
164 req.length = length;
165 req.Normal = direction;
166 req.Origin = position;
167 req.Count = count;
168 req.filter = RayFilterFlags.AllPrims;
169
170 m_PendingRequests.Enqueue(req);
171 }
172
173
174 public void QueueRequest(Vector3 position, Vector3 direction, float length, int count,RayFilterFlags filter , RayCallback retMethod)
175 {
176 ODERayRequest req = new ODERayRequest();
177 req.geom = IntPtr.Zero;
178 req.callbackMethod = retMethod;
179 req.length = length;
180 req.Normal = direction;
181 req.Origin = position;
182 req.Count = count;
183 req.filter = filter;
184
185 m_PendingRequests.Enqueue(req);
186 }
187
188 public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
189 {
190 ODERayRequest req = new ODERayRequest();
191 req.geom = geom;
192 req.callbackMethod = retMethod;
193 req.length = length;
194 req.Normal = direction;
195 req.Origin = position;
196 req.Count = count;
197 req.filter = RayFilterFlags.AllPrims;
198
199 m_PendingRequests.Enqueue(req);
200 }
201
202 public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod)
203 {
204 ODERayRequest req = new ODERayRequest();
205 req.geom = IntPtr.Zero;
206 req.callbackMethod = retMethod;
207 req.length = length;
208 req.Normal = direction;
209 req.Origin = position;
210 req.Count = count;
211 req.filter = RayFilterFlags.AllPrims;
212
213 m_PendingRequests.Enqueue(req);
214 }
215
216 public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod)
217 {
218 ODERayRequest req = new ODERayRequest();
219 req.geom = geom;
220 req.callbackMethod = retMethod;
221 req.length = length;
222 req.Normal = direction;
223 req.Origin = position;
224 req.Count = count;
225 req.filter = RayFilterFlags.AllPrims;
226 96
227 m_PendingRequests.Enqueue(req); 97 m_PendingRequests.Enqueue(req);
228 } 98 }
@@ -258,21 +128,64 @@ namespace OpenSim.Region.Physics.OdePlugin
258 CurrentRayFilter = req.filter; 128 CurrentRayFilter = req.filter;
259 CurrentMaxCount = req.Count; 129 CurrentMaxCount = req.Count;
260 130
131 CollisionContactGeomsPerTest = req.Count & 0xffff;
132
261 closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1); 133 closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1);
262 backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1); 134 backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1);
263 135
264 d.GeomRaySetLength(ray, req.length); 136 if (req.callbackMethod is ProbeBoxCallback)
265 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); 137 {
266 d.GeomRaySetParams(ray, 0, backfacecull); 138 if (CollisionContactGeomsPerTest > 80)
267 d.GeomRaySetClosestHit(ray, closestHit); 139 CollisionContactGeomsPerTest = 80;
140 d.GeomBoxSetLengths(Box, req.Normal.X, req.Normal.Y, req.Normal.Z);
141 d.GeomSetPosition(Box, req.Origin.X, req.Origin.Y, req.Origin.Z);
142 d.Quaternion qtmp;
143 qtmp.X = req.orientation.X;
144 qtmp.Y = req.orientation.Y;
145 qtmp.Z = req.orientation.Z;
146 qtmp.W = req.orientation.W;
147 d.GeomSetQuaternion(Box, ref qtmp);
148 }
149 else if (req.callbackMethod is ProbeSphereCallback)
150 {
151 if (CollisionContactGeomsPerTest > 80)
152 CollisionContactGeomsPerTest = 80;
153
154 d.GeomSphereSetRadius(Sphere, req.length);
155 d.GeomSetPosition(Sphere, req.Origin.X, req.Origin.Y, req.Origin.Z);
156 }
157 else if (req.callbackMethod is ProbePlaneCallback)
158 {
159 if (CollisionContactGeomsPerTest > 80)
160 CollisionContactGeomsPerTest = 80;
161
162 d.GeomPlaneSetParams(Plane, req.Normal.X, req.Normal.Y, req.Normal.Z, req.length);
163 }
164
165 else
166 {
167 if (CollisionContactGeomsPerTest > 25)
168 CollisionContactGeomsPerTest = 25;
268 169
269 if (req.callbackMethod is RaycastCallback) 170 d.GeomRaySetLength(ray, req.length);
270 // if we only want one get only one per colision pair saving memory 171 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
271 CurrentRayFilter |= RayFilterFlags.ClosestHit; 172 d.GeomRaySetParams(ray, 0, backfacecull);
173 d.GeomRaySetClosestHit(ray, closestHit);
174
175 if (req.callbackMethod is RaycastCallback)
176 // if we only want one get only one per Collision pair saving memory
177 CurrentRayFilter |= RayFilterFlags.ClosestHit;
178 }
179
180 if ((CurrentRayFilter & RayFilterFlags.ContactsUnImportant) != 0)
181 unchecked
182 {
183 CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT;
184 }
272 185
273 if (req.geom == IntPtr.Zero) 186 if (req.geom == IntPtr.Zero)
274 { 187 {
275 // translate ray filter to colision flags 188 // translate ray filter to Collision flags
276 catflags = 0; 189 catflags = 0;
277 if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0) 190 if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0)
278 catflags |= CollisionCategories.VolumeDtc; 191 catflags |= CollisionCategories.VolumeDtc;
@@ -289,15 +202,48 @@ namespace OpenSim.Region.Physics.OdePlugin
289 202
290 if (catflags != 0) 203 if (catflags != 0)
291 { 204 {
292 d.GeomSetCollideBits(ray, (uint)catflags); 205 if (req.callbackMethod is ProbeBoxCallback)
293 doSpaceRay(req); 206 {
207 catflags |= CollisionCategories.Space;
208 d.GeomSetCollideBits(Box, (uint)catflags);
209 d.GeomSetCategoryBits(Box, (uint)catflags);
210 doProbe(req, Box);
211 }
212 else if (req.callbackMethod is ProbeSphereCallback)
213 {
214 catflags |= CollisionCategories.Space;
215 d.GeomSetCollideBits(Sphere, (uint)catflags);
216 d.GeomSetCategoryBits(Sphere, (uint)catflags);
217 doProbe(req, Sphere);
218 }
219 else if (req.callbackMethod is ProbePlaneCallback)
220 {
221 catflags |= CollisionCategories.Space;
222 d.GeomSetCollideBits(Plane, (uint)catflags);
223 d.GeomSetCategoryBits(Plane, (uint)catflags);
224 doPlane(req);
225 }
226 else
227 {
228 d.GeomSetCollideBits(ray, (uint)catflags);
229 doSpaceRay(req);
230 }
294 } 231 }
295 } 232 }
296 else 233 else
297 { 234 {
298 // if we select a geom don't use filters 235 // if we select a geom don't use filters
299 d.GeomSetCollideBits(ray, (uint)CollisionCategories.All); 236
300 doGeomRay(req); 237 if (req.callbackMethod is ProbePlaneCallback)
238 {
239 d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All);
240 doPlane(req);
241 }
242 else
243 {
244 d.GeomSetCollideBits(ray, (uint)CollisionCategories.All);
245 doGeomRay(req);
246 }
301 } 247 }
302 } 248 }
303 249
@@ -382,6 +328,61 @@ namespace OpenSim.Region.Physics.OdePlugin
382 } 328 }
383 } 329 }
384 330
331 private void doProbe(ODERayRequest req, IntPtr probe)
332 {
333 // Collide tests
334 if ((CurrentRayFilter & FilterActiveSpace) != 0)
335 {
336 d.SpaceCollide2(probe, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
337 d.SpaceCollide2(probe, m_scene.CharsSpace, IntPtr.Zero, nearCallback);
338 }
339 if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
340 d.SpaceCollide2(probe, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
341 if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount))
342 d.SpaceCollide2(probe, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
343
344 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
345 lock (m_PendingRequests)
346 {
347 cresult.AddRange(m_contactResults);
348 m_contactResults.Clear();
349 }
350 if (req.callbackMethod is ProbeBoxCallback)
351 ((ProbeBoxCallback)req.callbackMethod)(cresult);
352 else if (req.callbackMethod is ProbeSphereCallback)
353 ((ProbeSphereCallback)req.callbackMethod)(cresult);
354 }
355
356 private void doPlane(ODERayRequest req)
357 {
358 // Collide tests
359 if (req.geom == IntPtr.Zero)
360 {
361 if ((CurrentRayFilter & FilterActiveSpace) != 0)
362 {
363 d.SpaceCollide2(Plane, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
364 d.SpaceCollide2(Plane, m_scene.CharsSpace, IntPtr.Zero, nearCallback);
365 }
366 if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
367 d.SpaceCollide2(Plane, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
368 if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount))
369 d.SpaceCollide2(Plane, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
370 }
371 else
372 {
373 d.SpaceCollide2(Plane, req.geom, IntPtr.Zero, nearCallback);
374 }
375
376 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
377 lock (m_PendingRequests)
378 {
379 cresult.AddRange(m_contactResults);
380 m_contactResults.Clear();
381 }
382
383 ((ProbePlaneCallback)req.callbackMethod)(cresult);
384 }
385
385 /// <summary> 386 /// <summary>
386 /// Method that actually initiates the raycast with a geom 387 /// Method that actually initiates the raycast with a geom
387 /// </summary> 388 /// </summary>
@@ -436,7 +437,7 @@ namespace OpenSim.Region.Physics.OdePlugin
436 private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) 437 private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
437 { 438 {
438 IntPtr ContactgeomsArray = m_scene.ContactgeomsArray; 439 IntPtr ContactgeomsArray = m_scene.ContactgeomsArray;
439 if (ContactgeomsArray == IntPtr.Zero || index >= ColisionContactGeomsPerTest) 440 if (ContactgeomsArray == IntPtr.Zero || index >= CollisionContactGeomsPerTest)
440 return false; 441 return false;
441 442
442 IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf)); 443 IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf));
@@ -469,7 +470,7 @@ namespace OpenSim.Region.Physics.OdePlugin
469 int count = 0; 470 int count = 0;
470 try 471 try
471 { 472 {
472 count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); 473 count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
473 } 474 }
474 catch (Exception e) 475 catch (Exception e)
475 { 476 {
@@ -479,85 +480,211 @@ namespace OpenSim.Region.Physics.OdePlugin
479 480
480 if (count == 0) 481 if (count == 0)
481 return; 482 return;
482 483/*
484 uint cat1 = d.GeomGetCategoryBits(g1);
485 uint cat2 = d.GeomGetCategoryBits(g2);
486 uint col1 = d.GeomGetCollideBits(g1);
487 uint col2 = d.GeomGetCollideBits(g2);
488*/
489
483 uint ID = 0; 490 uint ID = 0;
484 PhysicsActor p2 = null; 491 PhysicsActor p2 = null;
485 492
486 m_scene.actor_name_map.TryGetValue(g2, out p2); 493 m_scene.actor_name_map.TryGetValue(g2, out p2);
487 494
488 if (p2 == null) 495 if (p2 == null)
489 {
490 /*
491 string name;
492
493 if (!m_scene.geom_name_map.TryGetValue(g2, out name))
494 return;
495
496 if (name == "Terrain")
497 {
498 // land colision
499 if ((CurrentRayFilter & RayFilterFlags.land) == 0)
500 return;
501 }
502 else if (name == "Water")
503 {
504 if ((CurrentRayFilter & RayFilterFlags.water) == 0)
505 return;
506 }
507 else
508 return;
509 */
510 return; 496 return;
511 } 497
512 else 498 switch (p2.PhysicsActorType)
513 { 499 {
514 switch (p2.PhysicsActorType) 500 case (int)ActorTypes.Prim:
515 {
516 case (int)ActorTypes.Prim:
517 501
518 RayFilterFlags thisFlags; 502 RayFilterFlags thisFlags;
519 503
520 if (p2.IsPhysical) 504 if (p2.IsPhysical)
521 thisFlags = RayFilterFlags.physical; 505 thisFlags = RayFilterFlags.physical;
522 else 506 else
523 thisFlags = RayFilterFlags.nonphysical; 507 thisFlags = RayFilterFlags.nonphysical;
524 508
525 if (p2.Phantom) 509 if (p2.Phantom)
526 thisFlags |= RayFilterFlags.phantom; 510 thisFlags |= RayFilterFlags.phantom;
527 511
528 if (p2.IsVolumeDtc) 512 if (p2.IsVolumeDtc)
529 thisFlags |= RayFilterFlags.volumedtc; 513 thisFlags |= RayFilterFlags.volumedtc;
530 514
531 if ((thisFlags & CurrentRayFilter) == 0) 515 if ((thisFlags & CurrentRayFilter) == 0)
532 return; 516 return;
533 517
534 ID = ((OdePrim)p2).LocalID; 518 ID = ((OdePrim)p2).LocalID;
535 break; 519 break;
536 520
537 case (int)ActorTypes.Agent: 521 case (int)ActorTypes.Agent:
538 522
539 if ((CurrentRayFilter & RayFilterFlags.agent) == 0) 523 if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
540 return; 524 return;
541 else 525 else
542 ID = ((OdeCharacter)p2).LocalID; 526 ID = ((OdeCharacter)p2).LocalID;
543 break; 527 break;
544 528
545 case (int)ActorTypes.Ground: 529 case (int)ActorTypes.Ground:
546 530
547 if ((CurrentRayFilter & RayFilterFlags.land) == 0) 531 if ((CurrentRayFilter & RayFilterFlags.land) == 0)
548 return; 532 return;
549 break; 533 break;
550 534
551 case (int)ActorTypes.Water: 535 case (int)ActorTypes.Water:
552 536
553 if ((CurrentRayFilter & RayFilterFlags.water) == 0) 537 if ((CurrentRayFilter & RayFilterFlags.water) == 0)
554 return; 538 return;
539 break;
540
541 default:
542 break;
543 }
544
545 d.ContactGeom curcontact = new d.ContactGeom();
546
547 // closestHit for now only works for meshs, so must do it for others
548 if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
549 {
550 // Loop all contacts, build results.
551 for (int i = 0; i < count; i++)
552 {
553 if (!GetCurContactGeom(i, ref curcontact))
555 break; 554 break;
556 555
557 default: 556 ContactResult collisionresult = new ContactResult();
557 collisionresult.ConsumerID = ID;
558 collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
559 collisionresult.Depth = curcontact.depth;
560 collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
561 curcontact.normal.Z);
562 lock (m_contactResults)
563 {
564 m_contactResults.Add(collisionresult);
565 if (m_contactResults.Count >= CurrentMaxCount)
566 return;
567 }
568 }
569 }
570 else
571 {
572 // keep only closest contact
573 ContactResult collisionresult = new ContactResult();
574 collisionresult.ConsumerID = ID;
575 collisionresult.Depth = float.MaxValue;
576
577 for (int i = 0; i < count; i++)
578 {
579 if (!GetCurContactGeom(i, ref curcontact))
558 break; 580 break;
581
582 if (curcontact.depth < collisionresult.Depth)
583 {
584 collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
585 collisionresult.Depth = curcontact.depth;
586 collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
587 curcontact.normal.Z);
588 }
589 }
590
591 if (collisionresult.Depth != float.MaxValue)
592 {
593 lock (m_contactResults)
594 m_contactResults.Add(collisionresult);
559 } 595 }
560 } 596 }
597 }
598
599 private void nearProbe(IntPtr space, IntPtr g1, IntPtr g2)
600 {
601 if (g1 == IntPtr.Zero || g1 == g2)
602 return;
603
604 if (m_contactResults.Count >= CurrentMaxCount)
605 return;
606
607 if (d.GeomIsSpace(g1))
608 {
609 try
610 {
611 d.SpaceCollide2(g1, g2, IntPtr.Zero, nearProbeCallback);
612 }
613 catch (Exception e)
614 {
615 m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
616 }
617 return;
618 }
619
620 int count = 0;
621 try
622 {
623 count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
624 }
625 catch (Exception e)
626 {
627 m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
628 return;
629 }
630
631 if (count == 0)
632 return;
633
634 uint ID = 0;
635 PhysicsActor p1 = null;
636
637 m_scene.actor_name_map.TryGetValue(g1, out p1);
638
639 if (p1 == null)
640 return;
641
642 switch (p1.PhysicsActorType)
643 {
644 case (int)ActorTypes.Prim:
645
646 RayFilterFlags thisFlags;
647
648 if (p1.IsPhysical)
649 thisFlags = RayFilterFlags.physical;
650 else
651 thisFlags = RayFilterFlags.nonphysical;
652
653 if (p1.Phantom)
654 thisFlags |= RayFilterFlags.phantom;
655
656 if (p1.IsVolumeDtc)
657 thisFlags |= RayFilterFlags.volumedtc;
658
659 if ((thisFlags & CurrentRayFilter) == 0)
660 return;
661
662 ID = ((OdePrim)p1).LocalID;
663 break;
664
665 case (int)ActorTypes.Agent:
666
667 if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
668 return;
669 else
670 ID = ((OdeCharacter)p1).LocalID;
671 break;
672
673 case (int)ActorTypes.Ground:
674
675 if ((CurrentRayFilter & RayFilterFlags.land) == 0)
676 return;
677 break;
678
679 case (int)ActorTypes.Water:
680
681 if ((CurrentRayFilter & RayFilterFlags.water) == 0)
682 return;
683 break;
684
685 default:
686 break;
687 }
561 688
562 d.ContactGeom curcontact = new d.ContactGeom(); 689 d.ContactGeom curcontact = new d.ContactGeom();
563 690
@@ -624,6 +751,21 @@ namespace OpenSim.Region.Physics.OdePlugin
624 d.GeomDestroy(ray); 751 d.GeomDestroy(ray);
625 ray = IntPtr.Zero; 752 ray = IntPtr.Zero;
626 } 753 }
754 if (Box != IntPtr.Zero)
755 {
756 d.GeomDestroy(Box);
757 Box = IntPtr.Zero;
758 }
759 if (Sphere != IntPtr.Zero)
760 {
761 d.GeomDestroy(Sphere);
762 Sphere = IntPtr.Zero;
763 }
764 if (Plane != IntPtr.Zero)
765 {
766 d.GeomDestroy(Plane);
767 Plane = IntPtr.Zero;
768 }
627 } 769 }
628 } 770 }
629 771
@@ -636,5 +778,6 @@ namespace OpenSim.Region.Physics.OdePlugin
636 public float length; 778 public float length;
637 public object callbackMethod; 779 public object callbackMethod;
638 public RayFilterFlags filter; 780 public RayFilterFlags filter;
781 public Quaternion orientation;
639 } 782 }
640} \ No newline at end of file 783} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
index 225bff8..ecc732a 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
@@ -52,6 +52,21 @@ namespace OpenSim.Region.Physics.OdePlugin
52 } 52 }
53 53
54 private static Vector3 SitAjust = new Vector3(0, 0, 0.4f); 54 private static Vector3 SitAjust = new Vector3(0, 0, 0.4f);
55 private const RayFilterFlags RaySitFlags = RayFilterFlags.AllPrims | RayFilterFlags.ClosestHit;
56
57 private void RotAroundZ(float x, float y, ref Quaternion ori)
58 {
59 double ang = Math.Atan2(y, x);
60 ang *= 0.5d;
61 float s = (float)Math.Sin(ang);
62 float c = (float)Math.Cos(ang);
63
64 ori.X = 0;
65 ori.Y = 0;
66 ori.Z = s;
67 ori.W = c;
68 }
69
55 70
56 public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse) 71 public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse)
57 { 72 {
@@ -63,88 +78,82 @@ namespace OpenSim.Region.Physics.OdePlugin
63 78
64 IntPtr geom = ((OdePrim)actor).prim_geom; 79 IntPtr geom = ((OdePrim)actor).prim_geom;
65 80
66 d.Vector3 dtmp = d.GeomGetPosition(geom); 81 Vector3 geopos = d.GeomGetPositionOMV(geom);
67 Vector3 geopos; 82 Quaternion geomOri = d.GeomGetQuaternionOMV(geom);
68 geopos.X = dtmp.X; 83 Quaternion geomInvOri = Quaternion.Conjugate(geomOri);
69 geopos.Y = dtmp.Y; 84
70 geopos.Z = dtmp.Z; 85 Quaternion ori = Quaternion.Identity;
71 86
72 87 Vector3 rayDir = geopos + offset - avCameraPosition;
73 d.AABB aabb; 88
74 Quaternion ori;
75 d.Quaternion qtmp;
76 d.GeomCopyQuaternion(geom, out qtmp);
77 Quaternion geomOri;
78 geomOri.X = qtmp.X;
79 geomOri.Y = qtmp.Y;
80 geomOri.Z = qtmp.Z;
81 geomOri.W = qtmp.W;
82 Quaternion geomInvOri;
83 geomInvOri.X = -qtmp.X;
84 geomInvOri.Y = -qtmp.Y;
85 geomInvOri.Z = -qtmp.Z;
86 geomInvOri.W = qtmp.W;
87
88 Vector3 target = geopos + offset;
89 Vector3 rayDir = target - avCameraPosition;
90 float raylen = rayDir.Length(); 89 float raylen = rayDir.Length();
90 if (raylen < 0.001f)
91 {
92 PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity);
93 return;
94 }
91 float t = 1 / raylen; 95 float t = 1 / raylen;
92 rayDir.X *= t; 96 rayDir.X *= t;
93 rayDir.Y *= t; 97 rayDir.Y *= t;
94 rayDir.Z *= t; 98 rayDir.Z *= t;
95 99
96 raylen += 0.5f; 100 raylen += 30f; // focal point may be far
97 List<ContactResult> rayResults; 101 List<ContactResult> rayResults;
98 102
99 rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir , raylen, 1); 103 rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir, raylen, 1, RaySitFlags);
100 if (rayResults.Count == 0 || rayResults[0].ConsumerID != actor.LocalID) 104 if (rayResults.Count == 0)
101 { 105 {
102 d.GeomGetAABB(geom,out aabb); 106/* if this fundamental ray failed, then just fail so user can try another spot and not be sitted far on a big prim
107 d.AABB aabb;
108 d.GeomGetAABB(geom, out aabb);
103 offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z); 109 offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z);
104 ori = geomInvOri; 110 ori = geomInvOri;
105 offset *= geomInvOri; 111 offset *= geomInvOri;
106
107 PhysicsSitResponse(1, actor.LocalID, offset, ori); 112 PhysicsSitResponse(1, actor.LocalID, offset, ori);
113*/
114 PhysicsSitResponse(0, actor.LocalID, offset, ori);
108 return; 115 return;
109 } 116 }
110 117
118 int status = 1;
111 offset = rayResults[0].Pos - geopos; 119 offset = rayResults[0].Pos - geopos;
112 double ang;
113 float s;
114 float c;
115 120
116 d.GeomClassID geoclass = d.GeomGetClass(geom); 121 d.GeomClassID geoclass = d.GeomGetClass(geom);
117 122
118 if (geoclass == d.GeomClassID.SphereClass) 123 if (geoclass == d.GeomClassID.SphereClass)
119 { 124 {
120 float r = d.GeomSphereGetRadius(geom); 125 float r = d.GeomSphereGetRadius(geom);
121 126
122 offset.Normalize(); 127 offset.Normalize();
123 offset *= r; 128 offset *= r;
124 129
125 ang = Math.Atan2(offset.Y, offset.X); 130 RotAroundZ(offset.X, offset.Y, ref ori);
126 ang *= 0.5d;
127 s = (float)Math.Sin(ang);
128 c = (float)Math.Cos(ang);
129
130 ori = new Quaternion(0, 0, s, c);
131 131
132 if (r < 0.4f) 132 if (r < 0.4f)
133 { 133 {
134 offset = new Vector3(0, 0, r); 134 offset = new Vector3(0, 0, r);
135 } 135 }
136 else if (offset.Z < 0.4f) 136 else
137 { 137 {
138 t = offset.Z; 138 if (offset.Z < 0.4f)
139 float rsq = r * r; 139 {
140 140 t = offset.Z;
141 t = 1.0f / (rsq - t * t); 141 float rsq = r * r;
142 offset.X *= t; 142
143 offset.Y *= t; 143 t = 1.0f / (rsq - t * t);
144 offset.Z = 0.4f; 144 offset.X *= t;
145 t = rsq - 0.16f; 145 offset.Y *= t;
146 offset.X *= t; 146 offset.Z = 0.4f;
147 offset.Y *= t; 147 t = rsq - 0.16f;
148 offset.X *= t;
149 offset.Y *= t;
150 }
151 else if (r > 0.8f && offset.Z > 0.8f * r)
152 {
153 status = 3;
154 avOffset.X = -avOffset.X;
155 avOffset.Z *= 1.6f;
156 }
148 } 157 }
149 158
150 offset += avOffset * ori; 159 offset += avOffset * ori;
@@ -152,26 +161,189 @@ namespace OpenSim.Region.Physics.OdePlugin
152 ori = geomInvOri * ori; 161 ori = geomInvOri * ori;
153 offset *= geomInvOri; 162 offset *= geomInvOri;
154 163
155 PhysicsSitResponse(1, actor.LocalID, offset, ori); 164 PhysicsSitResponse(status, actor.LocalID, offset, ori);
156 return; 165 return;
157 } 166 }
158 167
159 Vector3 norm = rayResults[0].Normal; 168 Vector3 norm = rayResults[0].Normal;
160 169
161 if (norm.Z < 0) 170 if (norm.Z < -0.4f)
162 { 171 {
163 PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity); 172 PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity);
164 return; 173 return;
165 } 174 }
166 175
167 ang = Math.Atan2(-rayDir.Y, -rayDir.X);
168 ang *= 0.5d;
169 s = (float)Math.Sin(ang);
170 c = (float)Math.Cos(ang);
171 176
172 ori = new Quaternion(0, 0, s, c); 177 float SitNormX = -rayDir.X;
178 float SitNormY = -rayDir.Y;
179
180 Vector3 pivot = geopos + offset;
181
182 float edgeNormalX = norm.X;
183 float edgeNormalY = norm.Y;
184 float edgeDirX = -rayDir.X;
185 float edgeDirY = -rayDir.Y;
186 Vector3 edgePos = rayResults[0].Pos;
187 float edgeDist = float.MaxValue;
188
189 bool foundEdge = false;
190
191 if (norm.Z < 0.5f)
192 {
193 float rayDist = 4.0f;
194 float curEdgeDist = 0.0f;
195
196 for (int i = 0; i < 6; i++)
197 {
198 pivot.X -= 0.005f * norm.X;
199 pivot.Y -= 0.005f * norm.Y;
200 pivot.Z -= 0.005f * norm.Z;
201
202 rayDir.X = -norm.X * norm.Z;
203 rayDir.Y = -norm.Y * norm.Z;
204 rayDir.Z = 1.0f - norm.Z * norm.Z;
205 rayDir.Normalize();
206
207 rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims);
208 if (rayResults.Count == 0)
209 break;
210
211 curEdgeDist += rayResults[0].Depth;
212
213 if (Math.Abs(rayResults[0].Normal.Z) < 0.7f)
214 {
215 rayDist -= rayResults[0].Depth;
216 if (rayDist < 0f)
217 break;
218
219 pivot = rayResults[0].Pos;
220 norm = rayResults[0].Normal;
221 edgeNormalX = norm.X;
222 edgeNormalY = norm.Y;
223 edgeDirX = -rayDir.X;
224 edgeDirY = -rayDir.Y;
225 }
226 else
227 {
228 foundEdge = true;
229 edgeDist = curEdgeDist;
230 edgePos = rayResults[0].Pos;
231 break;
232 }
233 }
234
235 if (!foundEdge)
236 {
237 PhysicsSitResponse(0, actor.LocalID, offset, ori);
238 return;
239 }
240 avOffset.X *= 0.5f;
241 }
242
243 else if (norm.Z > 0.866f)
244 {
245 float toCamBaseX = avCameraPosition.X - pivot.X;
246 float toCamBaseY = avCameraPosition.Y - pivot.Y;
247 float toCamX = toCamBaseX;
248 float toCamY = toCamBaseY;
249
250 for (int j = 0; j < 4; j++)
251 {
252 float rayDist = 1.0f;
253 float curEdgeDist = 0.0f;
254
255 for (int i = 0; i < 3; i++)
256 {
257 pivot.Z -= 0.005f;
258 rayDir.X = toCamX;
259 rayDir.Y = toCamY;
260 rayDir.Z = (-toCamX * norm.X - toCamY * norm.Y) / norm.Z;
261 rayDir.Normalize();
262
263 rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims);
264 if (rayResults.Count == 0)
265 break;
266
267 curEdgeDist += rayResults[0].Depth;
268
269 if (rayResults[0].Normal.Z > 0.5f)
270 {
271 rayDist -= rayResults[0].Depth;
272 if (rayDist < 0f)
273 break;
274
275 pivot = rayResults[0].Pos;
276 norm = rayResults[0].Normal;
277 }
278 else
279 {
280 foundEdge = true;
281 if (curEdgeDist < edgeDist)
282 {
283 edgeDist = curEdgeDist;
284 edgeNormalX = rayResults[0].Normal.X;
285 edgeNormalY = rayResults[0].Normal.Y;
286 edgeDirX = rayDir.X;
287 edgeDirY = rayDir.Y;
288 edgePos = rayResults[0].Pos;
289 }
290 break;
291 }
292 }
293 if (foundEdge && edgeDist < 0.2f)
294 break;
295
296 pivot = geopos + offset;
297
298 switch (j)
299 {
300 case 0:
301 toCamX = -toCamBaseY;
302 toCamY = toCamBaseX;
303 break;
304 case 1:
305 toCamX = toCamBaseY;
306 toCamY = -toCamBaseX;
307 break;
308 case 2:
309 toCamX = -toCamBaseX;
310 toCamY = -toCamBaseY;
311 break;
312 default:
313 break;
314 }
315 }
316
317 if (!foundEdge)
318 {
319 avOffset.X = -avOffset.X;
320 avOffset.Z *= 1.6f;
321
322 RotAroundZ(SitNormX, SitNormY, ref ori);
323
324 offset += avOffset * ori;
325
326 ori = geomInvOri * ori;
327 offset *= geomInvOri;
328
329 PhysicsSitResponse(3, actor.LocalID, offset, ori);
330 return;
331 }
332 avOffset.X *= 0.5f;
333 }
334
335 SitNormX = edgeNormalX;
336 SitNormY = edgeNormalY;
337 if (edgeDirX * SitNormX + edgeDirY * SitNormY < 0)
338 {
339 SitNormX = -SitNormX;
340 SitNormY = -SitNormY;
341 }
342
343 RotAroundZ(SitNormX, SitNormY, ref ori);
173 344
174 offset += avOffset * ori; 345 offset = edgePos + avOffset * ori;
346 offset -= geopos;
175 347
176 ori = geomInvOri * ori; 348 ori = geomInvOri * ori;
177 offset *= geomInvOri; 349 offset *= geomInvOri;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
index 403a4ce..10d7d50 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
@@ -44,7 +44,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44using System; 44using System;
45using System.Runtime.InteropServices; 45using System.Runtime.InteropServices;
46using System.Security; 46using System.Security;
47 47using OMV = OpenMetaverse;
48namespace OdeAPI 48namespace OdeAPI
49{ 49{
50//#if dDOUBLE 50//#if dDOUBLE
@@ -925,9 +925,20 @@ namespace OdeAPI
925 { 925 {
926 unsafe { return *(GeomGetPositionUnsafe(geom)); } 926 unsafe { return *(GeomGetPositionUnsafe(geom)); }
927 } 927 }
928 public static OMV.Vector3 GeomGetPositionOMV(IntPtr geom)
929 {
930 Vector3 vtmp = GeomGetPosition(geom);
931 return new OMV.Vector3(vtmp.X, vtmp.Y, vtmp.Z);
932 }
928 933
929 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity] 934 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity]
930 public static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q); 935 public static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q);
936 public static OMV.Quaternion GeomGetQuaternionOMV(IntPtr geom)
937 {
938 Quaternion qtmp;
939 GeomCopyQuaternion(geom, out qtmp);
940 return new OMV.Quaternion(qtmp.X, qtmp.Y, qtmp.Z, qtmp.W);
941 }
931 942
932 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity] 943 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity]
933 public static extern void GeomCopyQuaternion(IntPtr geom, out dReal X); 944 public static extern void GeomCopyQuaternion(IntPtr geom, out dReal X);
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index fbf2f0d..d045b59 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -2579,7 +2579,16 @@ namespace OpenSim.Region.Physics.OdePlugin
2579 { 2579 {
2580 if (retMethod != null) 2580 if (retMethod != null)
2581 { 2581 {
2582 m_rayCastManager.QueueRequest(position, direction, length, retMethod); 2582 ODERayRequest req = new ODERayRequest();
2583 req.geom = IntPtr.Zero;
2584 req.callbackMethod = retMethod;
2585 req.length = length;
2586 req.Normal = direction;
2587 req.Origin = position;
2588 req.Count = 0;
2589 req.filter = RayFilterFlags.All;
2590
2591 m_rayCastManager.QueueRequest(req);
2583 } 2592 }
2584 } 2593 }
2585 2594
@@ -2587,29 +2596,51 @@ namespace OpenSim.Region.Physics.OdePlugin
2587 { 2596 {
2588 if (retMethod != null) 2597 if (retMethod != null)
2589 { 2598 {
2590 m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); 2599 ODERayRequest req = new ODERayRequest();
2600 req.geom = IntPtr.Zero;
2601 req.callbackMethod = retMethod;
2602 req.length = length;
2603 req.Normal = direction;
2604 req.Origin = position;
2605 req.Count = Count;
2606 req.filter = RayFilterFlags.All;
2607
2608 m_rayCastManager.QueueRequest(req);
2591 } 2609 }
2592 } 2610 }
2593 2611
2594 // don't like this 2612
2595 public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) 2613 public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
2596 { 2614 {
2597 ContactResult[] ourResults = null; 2615 List<ContactResult> ourresults = new List<ContactResult>();
2616 object SyncObject = new object();
2617
2598 RayCallback retMethod = delegate(List<ContactResult> results) 2618 RayCallback retMethod = delegate(List<ContactResult> results)
2599 { 2619 {
2600 ourResults = new ContactResult[results.Count]; 2620 lock (SyncObject)
2601 results.CopyTo(ourResults, 0); 2621 {
2622 ourresults = results;
2623 Monitor.PulseAll(SyncObject);
2624 }
2602 }; 2625 };
2603 int waitTime = 0; 2626
2604 m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); 2627 ODERayRequest req = new ODERayRequest();
2605 while (ourResults == null && waitTime < 1000) 2628 req.geom = IntPtr.Zero;
2629 req.callbackMethod = retMethod;
2630 req.length = length;
2631 req.Normal = direction;
2632 req.Origin = position;
2633 req.Count = Count;
2634 req.filter = RayFilterFlags.All;
2635
2636 lock (SyncObject)
2606 { 2637 {
2607 Thread.Sleep(1); 2638 m_rayCastManager.QueueRequest(req);
2608 waitTime++; 2639 if (!Monitor.Wait(SyncObject, 500))
2640 return null;
2641 else
2642 return ourresults;
2609 } 2643 }
2610 if (ourResults == null)
2611 return new List<ContactResult>();
2612 return new List<ContactResult>(ourResults);
2613 } 2644 }
2614 2645
2615 public override bool SuportsRaycastWorldFiltered() 2646 public override bool SuportsRaycastWorldFiltered()
@@ -2631,9 +2662,18 @@ namespace OpenSim.Region.Physics.OdePlugin
2631 } 2662 }
2632 }; 2663 };
2633 2664
2665 ODERayRequest req = new ODERayRequest();
2666 req.geom = IntPtr.Zero;
2667 req.callbackMethod = retMethod;
2668 req.length = length;
2669 req.Normal = direction;
2670 req.Origin = position;
2671 req.Count = Count;
2672 req.filter = filter;
2673
2634 lock (SyncObject) 2674 lock (SyncObject)
2635 { 2675 {
2636 m_rayCastManager.QueueRequest(position, direction, length, Count,filter, retMethod); 2676 m_rayCastManager.QueueRequest(req);
2637 if (!Monitor.Wait(SyncObject, 500)) 2677 if (!Monitor.Wait(SyncObject, 500))
2638 return null; 2678 return null;
2639 else 2679 else
@@ -2641,74 +2681,163 @@ namespace OpenSim.Region.Physics.OdePlugin
2641 } 2681 }
2642 } 2682 }
2643 2683
2644 public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) 2684 public override List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags)
2645 { 2685 {
2646 if (retMethod != null && actor !=null) 2686 if (actor == null)
2687 return new List<ContactResult>();
2688
2689 IntPtr geom;
2690 if (actor is OdePrim)
2691 geom = ((OdePrim)actor).prim_geom;
2692 else if (actor is OdeCharacter)
2693 geom = ((OdePrim)actor).prim_geom;
2694 else
2695 return new List<ContactResult>();
2696
2697 if (geom == IntPtr.Zero)
2698 return new List<ContactResult>();
2699
2700 List<ContactResult> ourResults = null;
2701 object SyncObject = new object();
2702
2703 RayCallback retMethod = delegate(List<ContactResult> results)
2647 { 2704 {
2648 IntPtr geom; 2705 lock (SyncObject)
2649 if (actor is OdePrim) 2706 {
2650 geom = ((OdePrim)actor).prim_geom; 2707 ourResults = results;
2651 else if (actor is OdeCharacter) 2708 Monitor.PulseAll(SyncObject);
2652 geom = ((OdePrim)actor).prim_geom; 2709 }
2653 else 2710 };
2654 return; 2711
2655 if (geom == IntPtr.Zero) 2712 ODERayRequest req = new ODERayRequest();
2656 return; 2713 req.geom = geom;
2657 m_rayCastManager.QueueRequest(geom, position, direction, length, retMethod); 2714 req.callbackMethod = retMethod;
2715 req.length = length;
2716 req.Normal = direction;
2717 req.Origin = position;
2718 req.Count = Count;
2719 req.filter = flags;
2720
2721 lock (SyncObject)
2722 {
2723 m_rayCastManager.QueueRequest(req);
2724 if (!Monitor.Wait(SyncObject, 500))
2725 return new List<ContactResult>();
2658 } 2726 }
2727
2728 if (ourResults == null)
2729 return new List<ContactResult>();
2730 return ourResults;
2659 } 2731 }
2660 2732
2661 public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) 2733 public override List<ContactResult> BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags)
2662 { 2734 {
2663 if (retMethod != null && actor != null) 2735 List<ContactResult> ourResults = null;
2736 object SyncObject = new object();
2737
2738 ProbeBoxCallback retMethod = delegate(List<ContactResult> results)
2664 { 2739 {
2665 IntPtr geom; 2740 lock (SyncObject)
2666 if (actor is OdePrim) 2741 {
2667 geom = ((OdePrim)actor).prim_geom; 2742 ourResults = results;
2668 else if (actor is OdeCharacter) 2743 Monitor.PulseAll(SyncObject);
2669 geom = ((OdePrim)actor).prim_geom; 2744 }
2670 else 2745 };
2671 return; 2746
2672 if (geom == IntPtr.Zero) 2747 ODERayRequest req = new ODERayRequest();
2673 return; 2748 req.geom = IntPtr.Zero;
2749 req.callbackMethod = retMethod;
2750 req.Normal = size;
2751 req.Origin = position;
2752 req.orientation = orientation;
2753 req.Count = Count;
2754 req.filter = flags;
2755
2756 lock (SyncObject)
2757 {
2758 m_rayCastManager.QueueRequest(req);
2759 if (!Monitor.Wait(SyncObject, 500))
2760 return new List<ContactResult>();
2761 }
2762
2763 if (ourResults == null)
2764 return new List<ContactResult>();
2765 return ourResults;
2766 }
2767
2768 public override List<ContactResult> SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags)
2769 {
2770 List<ContactResult> ourResults = null;
2771 object SyncObject = new object();
2772
2773 ProbeSphereCallback retMethod = delegate(List<ContactResult> results)
2774 {
2775 ourResults = results;
2776 Monitor.PulseAll(SyncObject);
2777 };
2778
2779 ODERayRequest req = new ODERayRequest();
2780 req.geom = IntPtr.Zero;
2781 req.callbackMethod = retMethod;
2782 req.length = radius;
2783 req.Origin = position;
2784 req.Count = Count;
2785 req.filter = flags;
2674 2786
2675 m_rayCastManager.QueueRequest(geom,position, direction, length, Count, retMethod); 2787
2788 lock (SyncObject)
2789 {
2790 m_rayCastManager.QueueRequest(req);
2791 if (!Monitor.Wait(SyncObject, 500))
2792 return new List<ContactResult>();
2676 } 2793 }
2794
2795 if (ourResults == null)
2796 return new List<ContactResult>();
2797 return ourResults;
2677 } 2798 }
2678 2799
2679 // don't like this 2800 public override List<ContactResult> PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags)
2680 public override List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
2681 { 2801 {
2802 IntPtr geom = IntPtr.Zero;;
2803
2682 if (actor != null) 2804 if (actor != null)
2683 { 2805 {
2684 IntPtr geom;
2685 if (actor is OdePrim) 2806 if (actor is OdePrim)
2686 geom = ((OdePrim)actor).prim_geom; 2807 geom = ((OdePrim)actor).prim_geom;
2687 else if (actor is OdeCharacter) 2808 else if (actor is OdeCharacter)
2688 geom = ((OdePrim)actor).prim_geom; 2809 geom = ((OdePrim)actor).prim_geom;
2689 else 2810 }
2690 return new List<ContactResult>();
2691 if (geom == IntPtr.Zero)
2692 return new List<ContactResult>();
2693 2811
2694 ContactResult[] ourResults = null; 2812 List<ContactResult> ourResults = null;
2695 RayCallback retMethod = delegate(List<ContactResult> results) 2813 object SyncObject = new object();
2696 { 2814
2697 ourResults = new ContactResult[results.Count]; 2815 ProbePlaneCallback retMethod = delegate(List<ContactResult> results)
2698 results.CopyTo(ourResults, 0); 2816 {
2699 }; 2817 ourResults = results;
2700 int waitTime = 0; 2818 Monitor.PulseAll(SyncObject);
2701 m_rayCastManager.QueueRequest(geom,position, direction, length, Count, retMethod); 2819 };
2702 while (ourResults == null && waitTime < 1000) 2820
2703 { 2821 ODERayRequest req = new ODERayRequest();
2704 Thread.Sleep(1); 2822 req.geom = geom;
2705 waitTime++; 2823 req.callbackMethod = retMethod;
2706 } 2824 req.length = plane.W;
2707 if (ourResults == null) 2825 req.Normal.X = plane.X;
2826 req.Normal.Y = plane.Y;
2827 req.Normal.Z = plane.Z;
2828 req.Count = Count;
2829 req.filter = flags;
2830
2831 lock (SyncObject)
2832 {
2833 m_rayCastManager.QueueRequest(req);
2834 if (!Monitor.Wait(SyncObject, 500))
2708 return new List<ContactResult>(); 2835 return new List<ContactResult>();
2709 return new List<ContactResult>(ourResults);
2710 } 2836 }
2711 return new List<ContactResult>(); 2837
2838 if (ourResults == null)
2839 return new List<ContactResult>();
2840 return ourResults;
2712 } 2841 }
2713 2842
2714 public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse) 2843 public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse)