diff options
Diffstat (limited to 'OpenSim')
20 files changed, 1120 insertions, 456 deletions
diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs index 8849a59..4fa604f 100644 --- a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs | |||
@@ -117,7 +117,7 @@ namespace OpenSim.Capabilities.Handlers | |||
117 | /// <param name="data"></param> | 117 | /// <param name="data"></param> |
118 | private void BakedTextureUploaded(UUID assetID, byte[] data) | 118 | private void BakedTextureUploaded(UUID assetID, byte[] data) |
119 | { | 119 | { |
120 | // m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString()); | 120 | m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString()); |
121 | 121 | ||
122 | AssetBase asset; | 122 | AssetBase asset; |
123 | asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString()); | 123 | asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString()); |
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 2183fb6..4df4fb6 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs | |||
@@ -66,7 +66,7 @@ namespace OpenSim.Framework | |||
66 | protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f); | 66 | protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f); |
67 | protected float m_avatarFeetOffset = 0; | 67 | protected float m_avatarFeetOffset = 0; |
68 | protected float m_avatarAnimOffset = 0; | 68 | protected float m_avatarAnimOffset = 0; |
69 | 69 | protected WearableCacheItem[] cacheitems; | |
70 | public virtual int Serial | 70 | public virtual int Serial |
71 | { | 71 | { |
72 | get { return m_serial; } | 72 | get { return m_serial; } |
@@ -115,6 +115,12 @@ namespace OpenSim.Framework | |||
115 | get { return m_avatarHeight; } | 115 | get { return m_avatarHeight; } |
116 | set { m_avatarHeight = value; } | 116 | set { m_avatarHeight = value; } |
117 | } | 117 | } |
118 | |||
119 | public virtual WearableCacheItem[] WearableCacheItems | ||
120 | { | ||
121 | get { return cacheitems; } | ||
122 | set { cacheitems = value; } | ||
123 | } | ||
118 | 124 | ||
119 | public AvatarAppearance() | 125 | public AvatarAppearance() |
120 | { | 126 | { |
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index c9b67de..0465042 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -64,7 +64,7 @@ namespace OpenSim.Framework | |||
64 | 64 | ||
65 | public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); | 65 | public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); |
66 | 66 | ||
67 | public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 AvSize); | 67 | public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 AvSize, WearableCacheItem[] CacheItems); |
68 | 68 | ||
69 | public delegate void StartAnim(IClientAPI remoteClient, UUID animID); | 69 | public delegate void StartAnim(IClientAPI remoteClient, UUID animID); |
70 | 70 | ||
diff --git a/OpenSim/Framework/ILandObject.cs b/OpenSim/Framework/ILandObject.cs index 4f98d7b..7a24d1e 100644 --- a/OpenSim/Framework/ILandObject.cs +++ b/OpenSim/Framework/ILandObject.cs | |||
@@ -70,6 +70,7 @@ namespace OpenSim.Framework | |||
70 | void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client); | 70 | void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client); |
71 | bool IsEitherBannedOrRestricted(UUID avatar); | 71 | bool IsEitherBannedOrRestricted(UUID avatar); |
72 | bool IsBannedFromLand(UUID avatar); | 72 | bool IsBannedFromLand(UUID avatar); |
73 | bool CanBeOnThisLand(UUID avatar, float posHeight); | ||
73 | bool IsRestrictedFromLand(UUID avatar); | 74 | bool IsRestrictedFromLand(UUID avatar); |
74 | bool IsInLandAccessList(UUID avatar); | 75 | bool IsInLandAccessList(UUID avatar); |
75 | void SendLandUpdateToClient(IClientAPI remote_client); | 76 | void SendLandUpdateToClient(IClientAPI remote_client); |
diff --git a/OpenSim/Framework/WearableCacheItem.cs b/OpenSim/Framework/WearableCacheItem.cs new file mode 100644 index 0000000..83b1346 --- /dev/null +++ b/OpenSim/Framework/WearableCacheItem.cs | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using OpenMetaverse; | ||
30 | |||
31 | namespace OpenSim.Framework | ||
32 | { | ||
33 | public class WearableCacheItem | ||
34 | { | ||
35 | public uint TextureIndex { get; set; } | ||
36 | public UUID CacheId { get; set; } | ||
37 | public UUID TextureID { get; set; } | ||
38 | } | ||
39 | } | ||
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. | |||
44 | using System; | 44 | using System; |
45 | using System.Runtime.InteropServices; | 45 | using System.Runtime.InteropServices; |
46 | using System.Security; | 46 | using System.Security; |
47 | 47 | using OMV = OpenMetaverse; | |
48 | namespace OdeAPI | 48 | namespace 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) |
diff --git a/OpenSim/Tests/Performance/NPCPerformanceTests.cs b/OpenSim/Tests/Performance/NPCPerformanceTests.cs index 2026a88..fde1b91 100644 --- a/OpenSim/Tests/Performance/NPCPerformanceTests.cs +++ b/OpenSim/Tests/Performance/NPCPerformanceTests.cs | |||
@@ -144,7 +144,7 @@ namespace OpenSim.Tests.Performance | |||
144 | // ScenePresence.SendInitialData() to reset our entire appearance. | 144 | // ScenePresence.SendInitialData() to reset our entire appearance. |
145 | scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); | 145 | scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); |
146 | 146 | ||
147 | afm.SetAppearance(sp, originalTe, null); | 147 | afm.SetAppearance(sp, originalTe, null, new WearableCacheItem[0]); |
148 | 148 | ||
149 | INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); | 149 | INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); |
150 | 150 | ||