From 0e2b717b4d262363995b2b351b4afe7c84889342 Mon Sep 17 00:00:00 2001 From: teravus Date: Fri, 7 Dec 2012 20:15:32 -0500 Subject: * Should promote faster self appearance. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 52 ++++++++++++++-------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 8e0b72f..c261f32 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -459,6 +459,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } + private Dictionary agentWearables = new Dictionary(); #endregion Properties @@ -2749,8 +2750,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP req.AssetInf.ID, req.AssetInf.Metadata.ContentType); return; } - - //m_log.Debug("sending asset " + req.RequestAssetID); + UUID WearableOut = UUID.Zero; + bool isWearable = false; + isWearable = agentWearables.TryGetValue(req.RequestAssetID, out WearableOut); + // m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable); TransferInfoPacket Transfer = new TransferInfoPacket(); Transfer.TransferInfo.ChannelType = 2; Transfer.TransferInfo.Status = 0; @@ -2772,7 +2775,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Transfer.TransferInfo.Size = req.AssetInf.Data.Length; Transfer.TransferInfo.TransferID = req.TransferRequestID; Transfer.Header.Zerocoded = true; - OutPacket(Transfer, ThrottleOutPacketType.Asset); + OutPacket(Transfer, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset); if (req.NumPackets == 1) { @@ -2783,7 +2786,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP TransferPacket.TransferData.Data = req.AssetInf.Data; TransferPacket.TransferData.Status = 1; TransferPacket.Header.Zerocoded = true; - OutPacket(TransferPacket, ThrottleOutPacketType.Asset); + OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset); } else { @@ -2816,7 +2819,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP TransferPacket.TransferData.Status = 1; } TransferPacket.Header.Zerocoded = true; - OutPacket(TransferPacket, ThrottleOutPacketType.Asset); + OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset); processedLength += chunkSize; packetNumber++; @@ -3571,24 +3574,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; AgentWearablesUpdatePacket.WearableDataBlock awb; int idx = 0; - for (int i = 0; i < wearables.Length; i++) + lock (agentWearables) { - for (int j = 0; j < wearables[i].Count; j++) + agentWearables.Clear(); + for (int i = 0; i < wearables.Length; i++) { - awb = new AgentWearablesUpdatePacket.WearableDataBlock(); - awb.WearableType = (byte)i; - awb.AssetID = wearables[i][j].AssetID; - awb.ItemID = wearables[i][j].ItemID; - aw.WearableData[idx] = awb; - idx++; - -// m_log.DebugFormat( -// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", -// awb.ItemID, awb.AssetID, i, Name); + for (int j = 0; j < wearables[i].Count; j++) + { + awb = new AgentWearablesUpdatePacket.WearableDataBlock(); + awb.WearableType = (byte) i; + awb.AssetID = wearables[i][j].AssetID; + awb.ItemID = wearables[i][j].ItemID; + agentWearables.Add(awb.AssetID, awb.ItemID); + aw.WearableData[idx] = awb; + idx++; + + // m_log.DebugFormat( + // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", + // awb.ItemID, awb.AssetID, i, Name); + } } } - OutPacket(aw, ThrottleOutPacketType.Task); + OutPacket(aw, ThrottleOutPacketType.State); } public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) @@ -3613,7 +3621,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP avp.Sender.IsTrial = false; avp.Sender.ID = agentID; //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); - OutPacket(avp, ThrottleOutPacketType.Task); + OutPacket(avp, ThrottleOutPacketType.State); } public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) @@ -7770,6 +7778,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP if ((ImageType)block.Type == ImageType.Baked) args.Priority *= 2.0f; + UUID wearableout = UUID.Zero; + if (agentWearables.TryGetValue(block.Image, out wearableout)) + { + args.Priority *= 2.0f; + } + ImageManager.EnqueueReq(args); } -- cgit v1.1 From 6c1a852137e3a66db5befa4c6ec50b3a93268304 Mon Sep 17 00:00:00 2001 From: teravus Date: Sat, 8 Dec 2012 00:05:12 -0500 Subject: * This is a better way to do the last commit. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 63 +++++++++++----------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index c261f32..7cf6cf1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -459,7 +459,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } - private Dictionary agentWearables = new Dictionary(); + #endregion Properties @@ -585,6 +585,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Disable UDP handling for this client m_udpClient.Shutdown(); + //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); //GC.Collect(); //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); @@ -2750,10 +2751,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP req.AssetInf.ID, req.AssetInf.Metadata.ContentType); return; } - UUID WearableOut = UUID.Zero; + int WearableOut = 0; bool isWearable = false; - isWearable = agentWearables.TryGetValue(req.RequestAssetID, out WearableOut); - // m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable); + + if (req.AssetInf != null) + isWearable = + ((AssetType) req.AssetInf.Type == + AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing); + + + //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable); + + + //if (isWearable) + // m_log.Debug((AssetType)req.AssetInf.Type); + TransferInfoPacket Transfer = new TransferInfoPacket(); Transfer.TransferInfo.ChannelType = 2; Transfer.TransferInfo.Status = 0; @@ -3574,27 +3586,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; AgentWearablesUpdatePacket.WearableDataBlock awb; int idx = 0; - lock (agentWearables) - { - agentWearables.Clear(); - for (int i = 0; i < wearables.Length; i++) - { - for (int j = 0; j < wearables[i].Count; j++) + + for (int i = 0; i < wearables.Length; i++) { - awb = new AgentWearablesUpdatePacket.WearableDataBlock(); - awb.WearableType = (byte) i; - awb.AssetID = wearables[i][j].AssetID; - awb.ItemID = wearables[i][j].ItemID; - agentWearables.Add(awb.AssetID, awb.ItemID); - aw.WearableData[idx] = awb; - idx++; - - // m_log.DebugFormat( - // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", - // awb.ItemID, awb.AssetID, i, Name); - } - } - } + for (int j = 0; j < wearables[i].Count; j++) + { + awb = new AgentWearablesUpdatePacket.WearableDataBlock(); + awb.WearableType = (byte) i; + awb.AssetID = wearables[i][j].AssetID; + awb.ItemID = wearables[i][j].ItemID; + aw.WearableData[idx] = awb; + idx++; + + // m_log.DebugFormat( + // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", + // awb.ItemID, awb.AssetID, i, Name); + } + } OutPacket(aw, ThrottleOutPacketType.State); } @@ -7777,12 +7785,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // surrounding scene if ((ImageType)block.Type == ImageType.Baked) args.Priority *= 2.0f; - - UUID wearableout = UUID.Zero; - if (agentWearables.TryGetValue(block.Image, out wearableout)) - { - args.Priority *= 2.0f; - } + int wearableout = 0; ImageManager.EnqueueReq(args); } -- cgit v1.1 From 9089bc7e37879867756740cfbd0456ad51244ca0 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 17 Dec 2012 22:11:29 +0000 Subject: some clean up/fix --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 93 +++++++++++----------- .../Region/Physics/UbitOdePlugin/ODESitAvatar.cs | 2 +- 2 files changed, 47 insertions(+), 48 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7ff163b..646e0e2 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2082,9 +2082,6 @@ namespace OpenSim.Region.Framework.Scenes if (part == null) return; - // TODO: determine position to sit at based on scene geometry; don't trust offset from client - // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it - if (PhysicsActor != null) m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f; @@ -2103,25 +2100,8 @@ namespace OpenSim.Region.Framework.Scenes } else { -// if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) -// { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m", -// Name, part.Name, part.LocalId); - - if (m_scene.PhysicsScene != null && - part.PhysActor != null && - Util.GetDistanceTo(AbsolutePosition, pos) <= 30) - { - - Vector3 camdif = CameraPosition - part.AbsolutePosition; - camdif.Normalize(); - -// m_log.InfoFormat("sit {0} {1}", offset.ToString(), camdif.ToString()); - - if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0) - return; - } + if (PhysicsSit(part,offset)) // physics engine + return; if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) { @@ -2129,12 +2109,6 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); canSit = true; } -// else -// { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m", -// Name, part.Name, part.LocalId); -// } } if (canSit) @@ -2196,14 +2170,6 @@ namespace OpenSim.Region.Framework.Scenes m_requestedSitTargetID = part.LocalId; m_requestedSitTargetUUID = targetID; -// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); - - if (m_scene.PhysicsScene.SupportsRayCast()) - { - //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback()); - //SitRayCastAvatarPosition(part); - //return; - } } else { @@ -2213,24 +2179,57 @@ namespace OpenSim.Region.Framework.Scenes SendSitResponse(targetID, offset, Quaternion.Identity); } - public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation) + // returns false if does not suport so older sit can be tried + public bool PhysicsSit(SceneObjectPart part, Vector3 offset) { + if (part == null || part.ParentGroup.IsAttachment) + { + return true; + } - if (status < 0) + if ( m_scene.PhysicsScene == null) + return false; + + if (part.PhysActor == null) { - ControllingClient.SendAlertMessage("Sit position no longer exists"); - return; + // none physcis shape + if (part.PhysicsShapeType == (byte)PhysicsShapeType.None) + ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot."); + else + { // non physical phantom TODO + ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot."); + return false; + } + return true; } - if (status == 0) + // not doing autopilot + m_requestedSitTargetID = 0; + + if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0) + return true; + + return false; + } + + // status + // < 0 ignore + // 0 bad sit spot + public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation) + { + if (status < 0) return; - SceneObjectPart part = m_scene.GetSceneObjectPart(partID); - if (part == null || part.ParentGroup.IsAttachment) + if (status == 0) { + ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot."); return; } + SceneObjectPart part = m_scene.GetSceneObjectPart(partID); + if (part == null) + return; + // m_log.InfoFormat("physsit {0} {1}", offset.ToString(),Orientation.ToString()); part.AddSittingAvatar(UUID); @@ -2242,16 +2241,14 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient.SendSitResponse( part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); - part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); - - // assuming no autopilot in use + // not using autopilot Velocity = Vector3.Zero; RemoveFromPhysicalScene(); Rotation = Orientation; m_pos = offset; - m_requestedSitTargetID = 0; // invalidate the viewer sit comand for now + m_requestedSitTargetID = 0; part.ParentGroup.AddAvatar(UUID); ParentPart = part; @@ -2259,6 +2256,8 @@ namespace OpenSim.Region.Framework.Scenes Animator.TrySetMovementAnimation("SIT"); SendAvatarDataToAllAgents(); + + part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs index 225bff8..c1a0ca9 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs @@ -93,7 +93,7 @@ namespace OpenSim.Region.Physics.OdePlugin rayDir.Y *= t; rayDir.Z *= t; - raylen += 0.5f; + raylen += 30f; // focal point may be far List rayResults; rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir , raylen, 1); -- cgit v1.1 From f87af983f393526ab6cebfbd711abdacd979a6ff Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 18 Dec 2012 00:50:36 +0000 Subject: fix --- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 2 +- .../Physics/UbitOdePlugin/ODERayCastRequestManager.cs | 14 ++++++++++++++ OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs | 19 ++++++++++++------- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index a442cf0..86e0713 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -353,7 +353,7 @@ namespace OpenSim.Region.Physics.Manager public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod){} public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { } - public virtual List RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count) + public virtual List RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags) { return new List(); } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs index 561ab1c..54a83c2 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs @@ -199,6 +199,20 @@ namespace OpenSim.Region.Physics.OdePlugin m_PendingRequests.Enqueue(req); } + public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count,RayFilterFlags flags, RayCallback retMethod) + { + ODERayRequest req = new ODERayRequest(); + req.geom = geom; + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + req.Count = count; + req.filter = flags; + + m_PendingRequests.Enqueue(req); + } + public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod) { ODERayRequest req = new ODERayRequest(); diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs index c1a0ca9..fd3a3ba 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs @@ -52,6 +52,7 @@ namespace OpenSim.Region.Physics.OdePlugin } private static Vector3 SitAjust = new Vector3(0, 0, 0.4f); + private const RayFilterFlags RaySitFlags = RayFilterFlags.AllPrims | RayFilterFlags.ClosestHit; public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse) { @@ -96,7 +97,7 @@ namespace OpenSim.Region.Physics.OdePlugin raylen += 30f; // focal point may be far List rayResults; - rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir , raylen, 1); + rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir, raylen, 1, RaySitFlags); if (rayResults.Count == 0 || rayResults[0].ConsumerID != actor.LocalID) { d.GeomGetAABB(geom,out aabb); @@ -108,6 +109,7 @@ namespace OpenSim.Region.Physics.OdePlugin return; } + offset = rayResults[0].Pos - geopos; double ang; float s; @@ -156,13 +158,16 @@ namespace OpenSim.Region.Physics.OdePlugin return; } - Vector3 norm = rayResults[0].Normal; +/* + // contact normals aren't reliable on meshs or sculpts it seems + Vector3 norm = rayResults[0].Normal; - if (norm.Z < 0) - { - PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity); - return; - } + if (norm.Z < 0) + { + PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity); + return; + } +*/ ang = Math.Atan2(-rayDir.Y, -rayDir.X); ang *= 0.5d; -- cgit v1.1 From ed9cb18cf0cb5b76946d7afb79e3c8677110c41b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 18 Dec 2012 00:54:40 +0000 Subject: missing file --- OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index fbf2f0d..d344d4d 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -2675,9 +2675,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_rayCastManager.QueueRequest(geom,position, direction, length, Count, retMethod); } } - - // don't like this - public override List RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count) + + public override List RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags) { if (actor != null) { @@ -2698,7 +2697,7 @@ namespace OpenSim.Region.Physics.OdePlugin results.CopyTo(ourResults, 0); }; int waitTime = 0; - m_rayCastManager.QueueRequest(geom,position, direction, length, Count, retMethod); + m_rayCastManager.QueueRequest(geom,position, direction, length, Count, flags, retMethod); while (ourResults == null && waitTime < 1000) { Thread.Sleep(1); -- cgit v1.1 From f9051c22d8170bb2824d9a38540f2fdce4367f6e Mon Sep 17 00:00:00 2001 From: teravus Date: Wed, 19 Dec 2012 22:14:20 -0500 Subject: * Send an Unsolicited AgentDataUpdate packet upon Root Agent Status to synchronize with Agni. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7ff163b..70e7af5 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -925,6 +925,26 @@ namespace OpenSim.Region.Framework.Scenes m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); + UUID groupUUID = UUID.Zero; + string GroupName = string.Empty; + ulong groupPowers = 0; + + // ---------------------------------- + // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status + if (gm != null) + { + groupUUID = ControllingClient.ActiveGroupId; + GroupRecord record = gm.GetGroupRecord(groupUUID); + if (record != null) + GroupName = record.GroupName; + GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid); + if (groupMembershipData != null) + groupPowers = groupMembershipData.GroupPowers; + } + ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName, + Grouptitle); + // ------------------------------------ + if (ParentID == 0) { // Moved this from SendInitialData to ensure that Appearance is initialized -- cgit v1.1 From 77cc7ce399d1b1a710f3b3f4337932febdef66c8 Mon Sep 17 00:00:00 2001 From: teravus Date: Fri, 21 Dec 2012 19:12:30 -0500 Subject: * Partial Commit for Avatar Appearance to include the functionality of Cached Bakes. --- .../UploadBakedTextureHandler.cs | 2 +- OpenSim/Framework/AvatarAppearance.cs | 8 ++++- OpenSim/Framework/IClientAPI.cs | 2 +- OpenSim/Framework/WearableCacheItem.cs | 39 ++++++++++++++++++++++ .../Region/ClientStack/Linden/UDP/LLClientView.cs | 26 ++++++++++++--- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 34 ++++++++++++++----- .../Tests/AvatarFactoryModuleTests.cs | 4 +-- .../Framework/Interfaces/IAvatarFactoryModule.cs | 6 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 27 +++++++++------ .../Server/IRCClientView.cs | 2 +- .../World/NPC/Tests/NPCModuleTests.cs | 2 +- OpenSim/Tests/Performance/NPCPerformanceTests.cs | 2 +- 12 files changed, 120 insertions(+), 34 deletions(-) create mode 100644 OpenSim/Framework/WearableCacheItem.cs 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 /// private void BakedTextureUploaded(UUID assetID, byte[] data) { -// m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString()); + m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString()); AssetBase asset; 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 protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f); protected float m_avatarFeetOffset = 0; protected float m_avatarAnimOffset = 0; - + protected WearableCacheItem[] cacheitems; public virtual int Serial { get { return m_serial; } @@ -115,6 +115,12 @@ namespace OpenSim.Framework get { return m_avatarHeight; } set { m_avatarHeight = value; } } + + public virtual WearableCacheItem[] WearableCacheItems + { + get { return cacheitems; } + set { cacheitems = value; } + } public AvatarAppearance() { 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 public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); - public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 AvSize); + public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 AvSize, WearableCacheItem[] CacheItems); public delegate void StartAnim(IClientAPI remoteClient, UUID animID); 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 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using OpenMetaverse; + +namespace OpenSim.Framework +{ + public class WearableCacheItem + { + public uint TextureIndex { get; set; } + public UUID CacheId { get; set; } + public UUID TextureID { get; set; } + } +} diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 363ee54..d18b026 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -6298,12 +6298,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP byte[] visualparams = new byte[appear.VisualParam.Length]; for (int i = 0; i < appear.VisualParam.Length; i++) visualparams[i] = appear.VisualParam[i].ParamValue; - + //var b = appear.WearableData[0]; + Primitive.TextureEntry te = null; if (appear.ObjectData.TextureEntry.Length > 1) te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); + + WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length]; + for (int i=0; i(); + // var item = fac.GetBakedTextureFaces(AgentId); + //WearableCacheItem[] items = fac.GetCachedItems(AgentId); + IImprovedAssetCache cache = m_scene.RequestModuleInterface(); if (cache == null) { @@ -11720,7 +11732,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; - cachedresp.WearableData[i].TextureID = UUID.Zero; + cachedresp.WearableData[i].TextureID = UUID.Zero; //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); cachedresp.WearableData[i].HostName = new byte[0]; } } @@ -11730,10 +11742,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP { cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; - if(cache.Check(cachedtex.WearableData[i].ID.ToString())) + + + + if (cache.Check(cachedtex.WearableData[i].ID.ToString())) cachedresp.WearableData[i].TextureID = UUID.Zero; + //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); else - cachedresp.WearableData[i].TextureID = UUID.Zero; + cachedresp.WearableData[i].TextureID = UUID.Zero; // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); cachedresp.WearableData[i].HostName = new byte[0]; } } 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 /// /// /// - public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) + public void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems) { - SetAppearance(sp, appearance.Texture, appearance.VisualParams); + SetAppearance(sp, appearance.Texture, appearance.VisualParams, cacheItems); } - public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize) + public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) { float oldoff = sp.Appearance.AvatarFeetOffset; Vector3 oldbox = sp.Appearance.AvatarBoxSize; - SetAppearance(sp, textureEntry, visualParams); + SetAppearance(sp, textureEntry, visualParams, cacheItems); sp.Appearance.SetSize(avSize); float off = sp.Appearance.AvatarFeetOffset; @@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory /// /// /// - public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) + public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems) { // m_log.DebugFormat( // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", @@ -205,11 +205,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // ((ScenePresence)sp).SetSize(box,off); } - + //if (cacheItems.Length > 0) + //{ + sp.Appearance.WearableCacheItems = cacheItems; + //} // Process the baked texture array if (textureEntry != null) { -// m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); + m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); // WriteBakedTexturesReport(sp, m_log.DebugFormat); @@ -278,6 +281,19 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return GetBakedTextureFaces(sp); } + public WearableCacheItem[] GetCachedItems(UUID agentId) + { + ScenePresence sp = m_scene.GetScenePresence(agentId); + Dictionary bakedTextures = GetBakedTextureFaces(sp); + + WearableCacheItem[] items = sp.Appearance.WearableCacheItems; + //foreach (WearableCacheItem item in items) + //{ + + //} + return items; + } + public bool SaveBakedTextures(UUID agentId) { ScenePresence sp = m_scene.GetScenePresence(agentId); @@ -660,12 +676,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory /// /// /// - private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize) + private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) { // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp != null) - SetAppearance(sp, textureEntry, visualParams,avSize); + SetAppearance(sp, textureEntry, visualParams,avSize, cacheItems); else m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); } diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index 848b3bf..e21547c 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 for (byte i = 0; i < visualParams.Length; i++) visualParams[i] = i; - afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); + afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams, new WearableCacheItem[0]); // TODO: Check baked texture Assert.AreEqual(visualParams, sp.Appearance.VisualParams); @@ -102,7 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex); eyesFace.TextureID = eyesTextureId; - afm.SetAppearance(sp, bakedTextureEntry, visualParams); + afm.SetAppearance(sp, bakedTextureEntry, visualParams, new WearableCacheItem[0]); afm.SaveBakedTextures(userId); // Dictionary bakedTextures = afm.GetBakedTextureFaces(userId); 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 public interface IAvatarFactoryModule { - void SetAppearance(IScenePresence sp, AvatarAppearance appearance); - void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams); + void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems); + void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems); /// /// Send the appearance of an avatar to others in the scene. @@ -52,6 +52,8 @@ namespace OpenSim.Region.Framework.Interfaces /// An empty list if this agent has no baked textures (e.g. because it's a child agent) Dictionary GetBakedTextureFaces(UUID agentId); + + WearableCacheItem[] GetCachedItems(UUID agentId); /// /// Save the baked textures for the given agent permanently in the asset database. /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 70e7af5..ff9df37 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -931,18 +931,25 @@ namespace OpenSim.Region.Framework.Scenes // ---------------------------------- // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status - if (gm != null) + try + { + if (gm != null) + { + groupUUID = ControllingClient.ActiveGroupId; + GroupRecord record = gm.GetGroupRecord(groupUUID); + if (record != null) + GroupName = record.GroupName; + GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid); + if (groupMembershipData != null) + groupPowers = groupMembershipData.GroupPowers; + } + ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName, + Grouptitle); + } + catch (Exception e) { - groupUUID = ControllingClient.ActiveGroupId; - GroupRecord record = gm.GetGroupRecord(groupUUID); - if (record != null) - GroupName = record.GroupName; - GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid); - if (groupMembershipData != null) - groupPowers = groupMembershipData.GroupPowers; + m_log.Debug("[AGENTUPDATE]: " + e.ToString()); } - ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName, - Grouptitle); // ------------------------------------ if (ParentID == 0) 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 // Mimicking LLClientView which gets always set appearance from client. AvatarAppearance appearance; m_scene.GetAvatarAppearance(this, out appearance); - OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(),appearance.AvatarSize); + OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(),appearance.AvatarSize, new WearableCacheItem[0]); } 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 52ed846..ef4005b 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 // ScenePresence.SendInitialData() to reset our entire appearance. m_scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); - m_afMod.SetAppearance(sp, originalTe, null); + m_afMod.SetAppearance(sp, originalTe, null, new WearableCacheItem[0] ); UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance); diff --git a/OpenSim/Tests/Performance/NPCPerformanceTests.cs b/OpenSim/Tests/Performance/NPCPerformanceTests.cs index 627765b..afda574 100644 --- a/OpenSim/Tests/Performance/NPCPerformanceTests.cs +++ b/OpenSim/Tests/Performance/NPCPerformanceTests.cs @@ -144,7 +144,7 @@ namespace OpenSim.Tests.Performance // ScenePresence.SendInitialData() to reset our entire appearance. scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); - afm.SetAppearance(sp, originalTe, null); + afm.SetAppearance(sp, originalTe, null, new WearableCacheItem[0]); INPCModule npcModule = scene.RequestModuleInterface(); -- cgit v1.1 From 7980a1d8496b71e46eeead7d77382cd10ac9fa78 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 2 Jan 2013 19:39:46 +0000 Subject: *TEST* avatar unscripted sit. Some guessing/automation --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 +- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 21 +- .../Region/Physics/UbitOdePlugin/ODECharacter.cs | 13 + .../UbitOdePlugin/ODERayCastRequestManager.cs | 583 +++++++++++++-------- .../Region/Physics/UbitOdePlugin/ODESitAvatar.cs | 260 +++++++-- OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 254 ++++++--- 6 files changed, 805 insertions(+), 332 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 85f4ee5..2a39ffd 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2280,8 +2280,10 @@ namespace OpenSim.Region.Framework.Scenes ParentPart = part; ParentID = part.LocalId; - - Animator.TrySetMovementAnimation("SIT"); + if(status == 3) + Animator.TrySetMovementAnimation("SIT_GROUND"); + else + Animator.TrySetMovementAnimation("SIT"); SendAvatarDataToAllAgents(); part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 86e0713..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 public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal); public delegate void RayCallback(List list); + public delegate void ProbeBoxCallback(List list); + public delegate void ProbeSphereCallback(List list); + public delegate void ProbePlaneCallback(List list); public delegate void SitAvatarCallback(int status, uint partID, Vector3 offset, Quaternion Orientation); public delegate void JointMoved(PhysicsJoint joint); @@ -56,6 +59,7 @@ namespace OpenSim.Region.Physics.Manager volumedtc = 0x40, // ray cast colision control (may only work for meshs) + ContactsUnImportant = 0x2000, BackFaceCull = 0x4000, ClosestHit = 0x8000, @@ -351,13 +355,26 @@ namespace OpenSim.Region.Physics.Manager return false; } - public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod){} - public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { } public virtual List RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags) { return new List(); } + public virtual List BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags) + { + return new List(); + } + + public virtual List SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags) + { + return new List(); + } + + public virtual List PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags) + { + return new List(); + } + public virtual int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse) { return 0; diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index bb04ea7..e1d694e 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -715,7 +715,17 @@ namespace OpenSim.Region.Physics.OdePlugin Vector3 off = _velocity; float t = 0.5f * timeStep; off = off * t; + d.Quaternion qtmp; + d.GeomCopyQuaternion(bbox, out qtmp); + Quaternion q; + q.X = qtmp.X; + q.Y = qtmp.Y; + q.Z = qtmp.Z; + q.W = qtmp.W; + off *= Quaternion.Conjugate(q); + d.GeomSetOffsetPosition(bbox, off.X, off.Y, off.Z); + off.X = 2.0f * (m_size.X + Math.Abs(off.X)); off.Y = 2.0f * (m_size.Y + Math.Abs(off.Y)); off.Z = m_size.Z + 2.0f * Math.Abs(off.Z); @@ -741,6 +751,9 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories); d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags); } + uint cat1 = d.GeomGetCategoryBits(bbox); + uint col1 = d.GeomGetCollideBits(bbox); + } } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs index 54a83c2..31757a9 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs @@ -56,8 +56,11 @@ namespace OpenSim.Region.Physics.OdePlugin private OdeScene m_scene; IntPtr ray; // the ray. we only need one for our lifetime + IntPtr Sphere; + IntPtr Box; + IntPtr Plane; - private const int ColisionContactGeomsPerTest = 5; + private int CollisionContactGeomsPerTest = 25; private const int DefaultMaxCount = 25; private const int MaxTimePerCallMS = 30; @@ -65,6 +68,7 @@ namespace OpenSim.Region.Physics.OdePlugin /// ODE near callback delegate /// private d.NearCallback nearCallback; + private d.NearCallback nearProbeCallback; private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private List m_contactResults = new List(); private RayFilterFlags CurrentRayFilter; @@ -74,169 +78,21 @@ namespace OpenSim.Region.Physics.OdePlugin { m_scene = pScene; nearCallback = near; + nearProbeCallback = nearProbe; ray = d.CreateRay(IntPtr.Zero, 1.0f); - d.GeomSetCategoryBits(ray,0); + d.GeomSetCategoryBits(ray, 0); + Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f); + d.GeomSetCategoryBits(Box, 0); + Sphere = d.CreateSphere(IntPtr.Zero,1.0f); + d.GeomSetCategoryBits(Sphere, 0); + Plane = d.CreatePlane(IntPtr.Zero, 0f,0f,1f,1f); + d.GeomSetCategoryBits(Sphere, 0); } - /// - /// Queues request for a raycast to all world - /// - /// Origin of Ray - /// Ray direction - /// Ray length - /// Return method to send the results - public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod) - { - ODERayRequest req = new ODERayRequest(); - req.geom = IntPtr.Zero; - req.callbackMethod = retMethod; - req.Count = DefaultMaxCount; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.filter = RayFilterFlags.AllPrims; - - m_PendingRequests.Enqueue(req); - } - - /// - /// Queues request for a raycast to particular part - /// - /// Origin of Ray - /// Ray direction - /// Ray length - /// Return method to send the results - public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod) - { - ODERayRequest req = new ODERayRequest(); - req.geom = geom; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = DefaultMaxCount; - req.filter = RayFilterFlags.AllPrims; - - m_PendingRequests.Enqueue(req); - } - - public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) - { - ODERayRequest req = new ODERayRequest(); - req.geom = IntPtr.Zero; - req.callbackMethod = retMethod; - req.Count = DefaultMaxCount; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.filter = RayFilterFlags.AllPrims | RayFilterFlags.land; - - m_PendingRequests.Enqueue(req); - } - - public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) - { - ODERayRequest req = new ODERayRequest(); - req.geom = geom; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = DefaultMaxCount; - req.filter = RayFilterFlags.AllPrims; - - m_PendingRequests.Enqueue(req); - } - - /// - /// Queues a raycast - /// - /// Origin of Ray - /// Ray normal - /// Ray length - /// - /// Return method to send the results - public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod) - { - ODERayRequest req = new ODERayRequest(); - req.geom = IntPtr.Zero; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = count; - req.filter = RayFilterFlags.AllPrims; - - m_PendingRequests.Enqueue(req); - } - - - public void QueueRequest(Vector3 position, Vector3 direction, float length, int count,RayFilterFlags filter , RayCallback retMethod) - { - ODERayRequest req = new ODERayRequest(); - req.geom = IntPtr.Zero; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = count; - req.filter = filter; - - m_PendingRequests.Enqueue(req); - } - - public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod) - { - ODERayRequest req = new ODERayRequest(); - req.geom = geom; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = count; - req.filter = RayFilterFlags.AllPrims; - - m_PendingRequests.Enqueue(req); - } - - public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count,RayFilterFlags flags, RayCallback retMethod) - { - ODERayRequest req = new ODERayRequest(); - req.geom = geom; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = count; - req.filter = flags; - - m_PendingRequests.Enqueue(req); - } - - public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod) - { - ODERayRequest req = new ODERayRequest(); - req.geom = IntPtr.Zero; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = count; - req.filter = RayFilterFlags.AllPrims; - - m_PendingRequests.Enqueue(req); - } - - public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod) + public void QueueRequest(ODERayRequest req) { - ODERayRequest req = new ODERayRequest(); - req.geom = geom; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = count; - req.filter = RayFilterFlags.AllPrims; + if (req.Count == 0) + req.Count = DefaultMaxCount; m_PendingRequests.Enqueue(req); } @@ -272,21 +128,64 @@ namespace OpenSim.Region.Physics.OdePlugin CurrentRayFilter = req.filter; CurrentMaxCount = req.Count; + CollisionContactGeomsPerTest = req.Count & 0xffff; + closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1); backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1); - d.GeomRaySetLength(ray, req.length); - d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); - d.GeomRaySetParams(ray, 0, backfacecull); - d.GeomRaySetClosestHit(ray, closestHit); + if (req.callbackMethod is ProbeBoxCallback) + { + if (CollisionContactGeomsPerTest > 80) + CollisionContactGeomsPerTest = 80; + d.GeomBoxSetLengths(Box, req.Normal.X, req.Normal.Y, req.Normal.Z); + d.GeomSetPosition(Box, req.Origin.X, req.Origin.Y, req.Origin.Z); + d.Quaternion qtmp; + qtmp.X = req.orientation.X; + qtmp.Y = req.orientation.Y; + qtmp.Z = req.orientation.Z; + qtmp.W = req.orientation.W; + d.GeomSetOffsetWorldQuaternion(Box, ref qtmp); + } + else if (req.callbackMethod is ProbeSphereCallback) + { + if (CollisionContactGeomsPerTest > 80) + CollisionContactGeomsPerTest = 80; + + d.GeomSphereSetRadius(Sphere, req.length); + d.GeomSetPosition(Sphere, req.Origin.X, req.Origin.Y, req.Origin.Z); + } + else if (req.callbackMethod is ProbePlaneCallback) + { + if (CollisionContactGeomsPerTest > 80) + CollisionContactGeomsPerTest = 80; + + d.GeomPlaneSetParams(Plane, req.Normal.X, req.Normal.Y, req.Normal.Z, req.length); + } + + else + { + if (CollisionContactGeomsPerTest > 25) + CollisionContactGeomsPerTest = 25; - if (req.callbackMethod is RaycastCallback) - // if we only want one get only one per colision pair saving memory - CurrentRayFilter |= RayFilterFlags.ClosestHit; + d.GeomRaySetLength(ray, req.length); + d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); + d.GeomRaySetParams(ray, 0, backfacecull); + d.GeomRaySetClosestHit(ray, closestHit); + + if (req.callbackMethod is RaycastCallback) + // if we only want one get only one per Collision pair saving memory + CurrentRayFilter |= RayFilterFlags.ClosestHit; + } + + if ((CurrentRayFilter & RayFilterFlags.ContactsUnImportant) != 0) + unchecked + { + CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT; + } if (req.geom == IntPtr.Zero) { - // translate ray filter to colision flags + // translate ray filter to Collision flags catflags = 0; if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0) catflags |= CollisionCategories.VolumeDtc; @@ -303,15 +202,48 @@ namespace OpenSim.Region.Physics.OdePlugin if (catflags != 0) { - d.GeomSetCollideBits(ray, (uint)catflags); - doSpaceRay(req); + if (req.callbackMethod is ProbeBoxCallback) + { + catflags |= CollisionCategories.Space; + d.GeomSetCollideBits(Box, (uint)catflags); + d.GeomSetCategoryBits(Box, (uint)catflags); + doProbe(req, Box); + } + else if (req.callbackMethod is ProbeSphereCallback) + { + catflags |= CollisionCategories.Space; + d.GeomSetCollideBits(Sphere, (uint)catflags); + d.GeomSetCategoryBits(Sphere, (uint)catflags); + doProbe(req, Sphere); + } + else if (req.callbackMethod is ProbePlaneCallback) + { + catflags |= CollisionCategories.Space; + d.GeomSetCollideBits(Plane, (uint)catflags); + d.GeomSetCategoryBits(Plane, (uint)catflags); + doPlane(req); + } + else + { + d.GeomSetCollideBits(ray, (uint)catflags); + doSpaceRay(req); + } } } else { // if we select a geom don't use filters - d.GeomSetCollideBits(ray, (uint)CollisionCategories.All); - doGeomRay(req); + + if (req.callbackMethod is ProbePlaneCallback) + { + d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All); + doPlane(req); + } + else + { + d.GeomSetCollideBits(ray, (uint)CollisionCategories.All); + doGeomRay(req); + } } } @@ -396,6 +328,61 @@ namespace OpenSim.Region.Physics.OdePlugin } } + private void doProbe(ODERayRequest req, IntPtr probe) + { + // Collide tests + if ((CurrentRayFilter & FilterActiveSpace) != 0) + { + d.SpaceCollide2(probe, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); + d.SpaceCollide2(probe, m_scene.CharsSpace, IntPtr.Zero, nearCallback); + } + if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount)) + d.SpaceCollide2(probe, m_scene.StaticSpace, IntPtr.Zero, nearCallback); + if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount)) + d.SpaceCollide2(probe, m_scene.GroundSpace, IntPtr.Zero, nearCallback); + + List cresult = new List(m_contactResults.Count); + lock (m_PendingRequests) + { + cresult.AddRange(m_contactResults); + m_contactResults.Clear(); + } + if (req.callbackMethod is ProbeBoxCallback) + ((ProbeBoxCallback)req.callbackMethod)(cresult); + else if (req.callbackMethod is ProbeSphereCallback) + ((ProbeSphereCallback)req.callbackMethod)(cresult); + } + + private void doPlane(ODERayRequest req) + { + // Collide tests + if (req.geom == IntPtr.Zero) + { + if ((CurrentRayFilter & FilterActiveSpace) != 0) + { + d.SpaceCollide2(Plane, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); + d.SpaceCollide2(Plane, m_scene.CharsSpace, IntPtr.Zero, nearCallback); + } + if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount)) + d.SpaceCollide2(Plane, m_scene.StaticSpace, IntPtr.Zero, nearCallback); + if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount)) + d.SpaceCollide2(Plane, m_scene.GroundSpace, IntPtr.Zero, nearCallback); + } + else + { + d.SpaceCollide2(Plane, req.geom, IntPtr.Zero, nearCallback); + } + + List cresult = new List(m_contactResults.Count); + lock (m_PendingRequests) + { + cresult.AddRange(m_contactResults); + m_contactResults.Clear(); + } + + ((ProbePlaneCallback)req.callbackMethod)(cresult); + } + /// /// Method that actually initiates the raycast with a geom /// @@ -450,7 +437,7 @@ namespace OpenSim.Region.Physics.OdePlugin private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) { IntPtr ContactgeomsArray = m_scene.ContactgeomsArray; - if (ContactgeomsArray == IntPtr.Zero || index >= ColisionContactGeomsPerTest) + if (ContactgeomsArray == IntPtr.Zero || index >= CollisionContactGeomsPerTest) return false; IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf)); @@ -483,7 +470,7 @@ namespace OpenSim.Region.Physics.OdePlugin int count = 0; try { - count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); + count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); } catch (Exception e) { @@ -494,84 +481,210 @@ namespace OpenSim.Region.Physics.OdePlugin if (count == 0) return; + uint cat1 = d.GeomGetCategoryBits(g1); + uint cat2 = d.GeomGetCategoryBits(g2); + uint col1 = d.GeomGetCollideBits(g1); + uint col2 = d.GeomGetCollideBits(g2); + + uint ID = 0; PhysicsActor p2 = null; m_scene.actor_name_map.TryGetValue(g2, out p2); if (p2 == null) - { - /* - string name; - - if (!m_scene.geom_name_map.TryGetValue(g2, out name)) - return; - - if (name == "Terrain") - { - // land colision - if ((CurrentRayFilter & RayFilterFlags.land) == 0) - return; - } - else if (name == "Water") - { - if ((CurrentRayFilter & RayFilterFlags.water) == 0) - return; - } - else - return; - */ return; - } - else + + switch (p2.PhysicsActorType) { - switch (p2.PhysicsActorType) - { - case (int)ActorTypes.Prim: + case (int)ActorTypes.Prim: - RayFilterFlags thisFlags; + RayFilterFlags thisFlags; - if (p2.IsPhysical) - thisFlags = RayFilterFlags.physical; - else - thisFlags = RayFilterFlags.nonphysical; + if (p2.IsPhysical) + thisFlags = RayFilterFlags.physical; + else + thisFlags = RayFilterFlags.nonphysical; - if (p2.Phantom) - thisFlags |= RayFilterFlags.phantom; + if (p2.Phantom) + thisFlags |= RayFilterFlags.phantom; - if (p2.IsVolumeDtc) - thisFlags |= RayFilterFlags.volumedtc; + if (p2.IsVolumeDtc) + thisFlags |= RayFilterFlags.volumedtc; - if ((thisFlags & CurrentRayFilter) == 0) - return; + if ((thisFlags & CurrentRayFilter) == 0) + return; - ID = ((OdePrim)p2).LocalID; - break; + ID = ((OdePrim)p2).LocalID; + break; - case (int)ActorTypes.Agent: + case (int)ActorTypes.Agent: - if ((CurrentRayFilter & RayFilterFlags.agent) == 0) - return; - else - ID = ((OdeCharacter)p2).LocalID; - break; + if ((CurrentRayFilter & RayFilterFlags.agent) == 0) + return; + else + ID = ((OdeCharacter)p2).LocalID; + break; - case (int)ActorTypes.Ground: + case (int)ActorTypes.Ground: - if ((CurrentRayFilter & RayFilterFlags.land) == 0) - return; - break; + if ((CurrentRayFilter & RayFilterFlags.land) == 0) + return; + break; - case (int)ActorTypes.Water: + case (int)ActorTypes.Water: - if ((CurrentRayFilter & RayFilterFlags.water) == 0) - return; + if ((CurrentRayFilter & RayFilterFlags.water) == 0) + return; + break; + + default: + break; + } + + d.ContactGeom curcontact = new d.ContactGeom(); + + // closestHit for now only works for meshs, so must do it for others + if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0) + { + // Loop all contacts, build results. + for (int i = 0; i < count; i++) + { + if (!GetCurContactGeom(i, ref curcontact)) break; - default: + ContactResult collisionresult = new ContactResult(); + collisionresult.ConsumerID = ID; + collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z); + collisionresult.Depth = curcontact.depth; + collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y, + curcontact.normal.Z); + lock (m_contactResults) + { + m_contactResults.Add(collisionresult); + if (m_contactResults.Count >= CurrentMaxCount) + return; + } + } + } + else + { + // keep only closest contact + ContactResult collisionresult = new ContactResult(); + collisionresult.ConsumerID = ID; + collisionresult.Depth = float.MaxValue; + + for (int i = 0; i < count; i++) + { + if (!GetCurContactGeom(i, ref curcontact)) break; + + if (curcontact.depth < collisionresult.Depth) + { + collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z); + collisionresult.Depth = curcontact.depth; + collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y, + curcontact.normal.Z); + } + } + + if (collisionresult.Depth != float.MaxValue) + { + lock (m_contactResults) + m_contactResults.Add(collisionresult); } } + } + + private void nearProbe(IntPtr space, IntPtr g1, IntPtr g2) + { + if (g1 == IntPtr.Zero || g1 == g2) + return; + + if (m_contactResults.Count >= CurrentMaxCount) + return; + + if (d.GeomIsSpace(g1)) + { + try + { + d.SpaceCollide2(g1, g2, IntPtr.Zero, nearProbeCallback); + } + catch (Exception e) + { + m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message); + } + return; + } + + int count = 0; + try + { + count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); + } + catch (Exception e) + { + m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message); + return; + } + + if (count == 0) + return; + + uint ID = 0; + PhysicsActor p1 = null; + + m_scene.actor_name_map.TryGetValue(g1, out p1); + + if (p1 == null) + return; + + switch (p1.PhysicsActorType) + { + case (int)ActorTypes.Prim: + + RayFilterFlags thisFlags; + + if (p1.IsPhysical) + thisFlags = RayFilterFlags.physical; + else + thisFlags = RayFilterFlags.nonphysical; + + if (p1.Phantom) + thisFlags |= RayFilterFlags.phantom; + + if (p1.IsVolumeDtc) + thisFlags |= RayFilterFlags.volumedtc; + + if ((thisFlags & CurrentRayFilter) == 0) + return; + + ID = ((OdePrim)p1).LocalID; + break; + + case (int)ActorTypes.Agent: + + if ((CurrentRayFilter & RayFilterFlags.agent) == 0) + return; + else + ID = ((OdeCharacter)p1).LocalID; + break; + + case (int)ActorTypes.Ground: + + if ((CurrentRayFilter & RayFilterFlags.land) == 0) + return; + break; + + case (int)ActorTypes.Water: + + if ((CurrentRayFilter & RayFilterFlags.water) == 0) + return; + break; + + default: + break; + } d.ContactGeom curcontact = new d.ContactGeom(); @@ -638,6 +751,21 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomDestroy(ray); ray = IntPtr.Zero; } + if (Box != IntPtr.Zero) + { + d.GeomDestroy(Box); + Box = IntPtr.Zero; + } + if (Sphere != IntPtr.Zero) + { + d.GeomDestroy(Sphere); + Sphere = IntPtr.Zero; + } + if (Plane != IntPtr.Zero) + { + d.GeomDestroy(Plane); + Plane = IntPtr.Zero; + } } } @@ -650,5 +778,6 @@ namespace OpenSim.Region.Physics.OdePlugin public float length; public object callbackMethod; public RayFilterFlags filter; + public Quaternion orientation; } } \ No newline at end of file diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs index fd3a3ba..9e23763 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs @@ -54,6 +54,20 @@ namespace OpenSim.Region.Physics.OdePlugin private static Vector3 SitAjust = new Vector3(0, 0, 0.4f); private const RayFilterFlags RaySitFlags = RayFilterFlags.AllPrims | RayFilterFlags.ClosestHit; + private void RotAroundZ(float x, float y, ref Quaternion ori) + { + double ang = Math.Atan2(y, x); + ang *= 0.5d; + float s = (float)Math.Sin(ang); + float c = (float)Math.Cos(ang); + + ori.X = 0; + ori.Y = 0; + ori.Z = s; + ori.W = c; + } + + public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse) { if (!m_scene.haveActor(actor) || !(actor is OdePrim) || ((OdePrim)actor).prim_geom == IntPtr.Zero) @@ -72,7 +86,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.AABB aabb; - Quaternion ori; + Quaternion ori = Quaternion.Identity; d.Quaternion qtmp; d.GeomCopyQuaternion(geom, out qtmp); Quaternion geomOri; @@ -86,9 +100,14 @@ namespace OpenSim.Region.Physics.OdePlugin geomInvOri.Z = -qtmp.Z; geomInvOri.W = qtmp.W; - Vector3 target = geopos + offset; - Vector3 rayDir = target - avCameraPosition; + Vector3 rayDir = geopos + offset - avCameraPosition; float raylen = rayDir.Length(); + if (raylen < 0.001f) + { + PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity); + return; + } + float t = 1 / raylen; rayDir.X *= t; rayDir.Y *= t; @@ -98,9 +117,9 @@ namespace OpenSim.Region.Physics.OdePlugin List rayResults; rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir, raylen, 1, RaySitFlags); - if (rayResults.Count == 0 || rayResults[0].ConsumerID != actor.LocalID) + if (rayResults.Count == 0) { - d.GeomGetAABB(geom,out aabb); + d.GeomGetAABB(geom, out aabb); offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z); ori = geomInvOri; offset *= geomInvOri; @@ -109,44 +128,45 @@ namespace OpenSim.Region.Physics.OdePlugin return; } - offset = rayResults[0].Pos - geopos; - double ang; - float s; - float c; d.GeomClassID geoclass = d.GeomGetClass(geom); if (geoclass == d.GeomClassID.SphereClass) { - float r = d.GeomSphereGetRadius(geom); + int status = 1; + float r = d.GeomSphereGetRadius(geom); offset.Normalize(); offset *= r; - ang = Math.Atan2(offset.Y, offset.X); - ang *= 0.5d; - s = (float)Math.Sin(ang); - c = (float)Math.Cos(ang); - - ori = new Quaternion(0, 0, s, c); + RotAroundZ(offset.X, offset.Y, ref ori); if (r < 0.4f) { offset = new Vector3(0, 0, r); } - else if (offset.Z < 0.4f) + else { - t = offset.Z; - float rsq = r * r; - - t = 1.0f / (rsq - t * t); - offset.X *= t; - offset.Y *= t; - offset.Z = 0.4f; - t = rsq - 0.16f; - offset.X *= t; - offset.Y *= t; + if (offset.Z < 0.4f) + { + t = offset.Z; + float rsq = r * r; + + t = 1.0f / (rsq - t * t); + offset.X *= t; + offset.Y *= t; + offset.Z = 0.4f; + t = rsq - 0.16f; + offset.X *= t; + offset.Y *= t; + } + else if (r > 0.8f && offset.Z > 0.8f * r) + { + status = 3; + avOffset.X = -avOffset.X; + avOffset.Z += 0.4f; + } } offset += avOffset * ori; @@ -154,27 +174,189 @@ namespace OpenSim.Region.Physics.OdePlugin ori = geomInvOri * ori; offset *= geomInvOri; - PhysicsSitResponse(1, actor.LocalID, offset, ori); + PhysicsSitResponse(status, actor.LocalID, offset, ori); return; } -/* - // contact normals aren't reliable on meshs or sculpts it seems - Vector3 norm = rayResults[0].Normal; + Vector3 norm = rayResults[0].Normal; - if (norm.Z < 0) + if (norm.Z < -0.4f) + { + PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity); + return; + } + + float SitNormX = -rayDir.X; + float SitNormY = -rayDir.Y; + + Vector3 pivot = geopos + offset; + + float edgeNormalX = norm.X; + float edgeNormalY = norm.Y; + float edgeDirX = -rayDir.X; + float edgeDirY = -rayDir.Y; + Vector3 edgePos = rayResults[0].Pos; + float edgeDist = float.MaxValue; + + bool foundEdge = false; + + if (norm.Z < 0.5f) + { + float rayDist = 4.0f; + float curEdgeDist = 0.0f; + pivot = geopos + offset; + + for (int i = 0; i < 6; i++) { - PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity); + pivot.X -= 0.005f * norm.X; + pivot.Y -= 0.005f * norm.Y; + pivot.Z -= 0.005f * norm.Z; + + rayDir.X = -norm.X * norm.Z; + rayDir.Y = -norm.Y * norm.Z; + rayDir.Z = 1.0f - norm.Z * norm.Z; + rayDir.Normalize(); + + rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims); + if (rayResults.Count == 0) + break; + + curEdgeDist += rayResults[0].Depth; + + if (Math.Abs(rayResults[0].Normal.Z) < 0.7f) + { + rayDist -= rayResults[0].Depth; + if (rayDist < 0f) + break; + + pivot = rayResults[0].Pos; + norm = rayResults[0].Normal; + edgeNormalX = norm.X; + edgeNormalY = norm.Y; + edgeDirX = rayDir.X; + edgeDirY = rayDir.Y; + } + else + { + foundEdge = true; + if (curEdgeDist < edgeDist) + { + edgeDist = curEdgeDist; + edgePos = rayResults[0].Pos; + } + break; + } + } + + if (!foundEdge) + { + PhysicsSitResponse(0, actor.LocalID, offset, ori); return; } -*/ + avOffset.X *= 0.5f; + } - ang = Math.Atan2(-rayDir.Y, -rayDir.X); - ang *= 0.5d; - s = (float)Math.Sin(ang); - c = (float)Math.Cos(ang); + else if (norm.Z > 0.866f) + { + float toCamBaseX = avCameraPosition.X - pivot.X; + float toCamBaseY = avCameraPosition.Y - pivot.Y; + float toCamX = toCamBaseX; + float toCamY = toCamBaseY; + + for (int j = 0; j < 4; j++) + { + float rayDist = 1.0f; + float curEdgeDist = 0.0f; + pivot = geopos + offset; + + for (int i = 0; i < 3; i++) + { + pivot.Z -= 0.005f; + rayDir.X = toCamX; + rayDir.Y = toCamY; + rayDir.Z = (-toCamX * norm.X - toCamY * norm.Y) / norm.Z; + rayDir.Normalize(); + + rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims); + if (rayResults.Count == 0) + break; + + curEdgeDist += rayResults[0].Depth; + + if (rayResults[0].Normal.Z > 0.5f) + { + rayDist -= rayResults[0].Depth; + if (rayDist < 0f) + break; + + pivot = rayResults[0].Pos; + norm = rayResults[0].Normal; + } + else + { + foundEdge = true; + if (curEdgeDist < edgeDist) + { + edgeDist = curEdgeDist; + edgeNormalX = rayResults[0].Normal.X; + edgeNormalY = rayResults[0].Normal.Y; + edgeDirX = rayDir.X; + edgeDirY = rayDir.Y; + edgePos = rayResults[0].Pos; + } + break; + } + } + if (foundEdge && edgeDist < 0.2f) + break; + + switch (j) + { + case 0: + toCamX = -toCamBaseY; + toCamY = toCamBaseX; + break; + case 1: + toCamX = toCamBaseY; + toCamY = -toCamBaseX; + break; + case 2: + toCamX = -toCamBaseX; + toCamY = -toCamBaseY; + break; + default: + break; + } + } + + if (!foundEdge) + { + avOffset.X = -avOffset.X; + avOffset.Z += 0.4f; + + RotAroundZ(SitNormX, SitNormY, ref ori); + + offset += avOffset * ori; + + ori = geomInvOri * ori; + offset *= geomInvOri; + + PhysicsSitResponse(3, actor.LocalID, offset, ori); + return; + } + avOffset.X *= 0.5f; + } + + SitNormX = edgeNormalX; + SitNormY = edgeNormalY; + offset = edgePos - geopos; + if (edgeDirX * SitNormX + edgeDirY * SitNormY < 0) + { + SitNormX = -SitNormX; + SitNormY = -SitNormY; + } - ori = new Quaternion(0, 0, s, c); + RotAroundZ(SitNormX, SitNormY, ref ori); offset += avOffset * ori; diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index d344d4d..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 { if (retMethod != null) { - m_rayCastManager.QueueRequest(position, direction, length, retMethod); + ODERayRequest req = new ODERayRequest(); + req.geom = IntPtr.Zero; + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + req.Count = 0; + req.filter = RayFilterFlags.All; + + m_rayCastManager.QueueRequest(req); } } @@ -2587,29 +2596,51 @@ namespace OpenSim.Region.Physics.OdePlugin { if (retMethod != null) { - m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); + ODERayRequest req = new ODERayRequest(); + req.geom = IntPtr.Zero; + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + req.Count = Count; + req.filter = RayFilterFlags.All; + + m_rayCastManager.QueueRequest(req); } } - // don't like this + public override List RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) { - ContactResult[] ourResults = null; + List ourresults = new List(); + object SyncObject = new object(); + RayCallback retMethod = delegate(List results) { - ourResults = new ContactResult[results.Count]; - results.CopyTo(ourResults, 0); + lock (SyncObject) + { + ourresults = results; + Monitor.PulseAll(SyncObject); + } }; - int waitTime = 0; - m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); - while (ourResults == null && waitTime < 1000) + + ODERayRequest req = new ODERayRequest(); + req.geom = IntPtr.Zero; + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + req.Count = Count; + req.filter = RayFilterFlags.All; + + lock (SyncObject) { - Thread.Sleep(1); - waitTime++; + m_rayCastManager.QueueRequest(req); + if (!Monitor.Wait(SyncObject, 500)) + return null; + else + return ourresults; } - if (ourResults == null) - return new List(); - return new List(ourResults); } public override bool SuportsRaycastWorldFiltered() @@ -2631,9 +2662,18 @@ namespace OpenSim.Region.Physics.OdePlugin } }; + ODERayRequest req = new ODERayRequest(); + req.geom = IntPtr.Zero; + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + req.Count = Count; + req.filter = filter; + lock (SyncObject) { - m_rayCastManager.QueueRequest(position, direction, length, Count,filter, retMethod); + m_rayCastManager.QueueRequest(req); if (!Monitor.Wait(SyncObject, 500)) return null; else @@ -2641,73 +2681,163 @@ namespace OpenSim.Region.Physics.OdePlugin } } - public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) + public override List RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags) { - if (retMethod != null && actor !=null) + if (actor == null) + return new List(); + + IntPtr geom; + if (actor is OdePrim) + geom = ((OdePrim)actor).prim_geom; + else if (actor is OdeCharacter) + geom = ((OdePrim)actor).prim_geom; + else + return new List(); + + if (geom == IntPtr.Zero) + return new List(); + + List ourResults = null; + object SyncObject = new object(); + + RayCallback retMethod = delegate(List results) { - IntPtr geom; - if (actor is OdePrim) - geom = ((OdePrim)actor).prim_geom; - else if (actor is OdeCharacter) - geom = ((OdePrim)actor).prim_geom; - else - return; - if (geom == IntPtr.Zero) - return; - m_rayCastManager.QueueRequest(geom, position, direction, length, retMethod); + lock (SyncObject) + { + ourResults = results; + Monitor.PulseAll(SyncObject); + } + }; + + ODERayRequest req = new ODERayRequest(); + req.geom = geom; + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + req.Count = Count; + req.filter = flags; + + lock (SyncObject) + { + m_rayCastManager.QueueRequest(req); + if (!Monitor.Wait(SyncObject, 500)) + return new List(); } + + if (ourResults == null) + return new List(); + return ourResults; } - public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) + public override List BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags) { - if (retMethod != null && actor != null) + List ourResults = null; + object SyncObject = new object(); + + ProbeBoxCallback retMethod = delegate(List results) { - IntPtr geom; - if (actor is OdePrim) - geom = ((OdePrim)actor).prim_geom; - else if (actor is OdeCharacter) - geom = ((OdePrim)actor).prim_geom; - else - return; - if (geom == IntPtr.Zero) - return; + lock (SyncObject) + { + ourResults = results; + Monitor.PulseAll(SyncObject); + } + }; + + ODERayRequest req = new ODERayRequest(); + req.geom = IntPtr.Zero; + req.callbackMethod = retMethod; + req.Normal = size; + req.Origin = position; + req.orientation = orientation; + req.Count = Count; + req.filter = flags; - m_rayCastManager.QueueRequest(geom,position, direction, length, Count, retMethod); + lock (SyncObject) + { + m_rayCastManager.QueueRequest(req); + if (!Monitor.Wait(SyncObject, 500)) + return new List(); } + + if (ourResults == null) + return new List(); + return ourResults; } - - public override List RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags) + + public override List SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags) + { + List ourResults = null; + object SyncObject = new object(); + + ProbeSphereCallback retMethod = delegate(List results) + { + ourResults = results; + Monitor.PulseAll(SyncObject); + }; + + ODERayRequest req = new ODERayRequest(); + req.geom = IntPtr.Zero; + req.callbackMethod = retMethod; + req.length = radius; + req.Origin = position; + req.Count = Count; + req.filter = flags; + + + lock (SyncObject) + { + m_rayCastManager.QueueRequest(req); + if (!Monitor.Wait(SyncObject, 500)) + return new List(); + } + + if (ourResults == null) + return new List(); + return ourResults; + } + + public override List PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags) { + IntPtr geom = IntPtr.Zero;; + if (actor != null) { - IntPtr geom; if (actor is OdePrim) geom = ((OdePrim)actor).prim_geom; else if (actor is OdeCharacter) geom = ((OdePrim)actor).prim_geom; - else - return new List(); - if (geom == IntPtr.Zero) - return new List(); + } - ContactResult[] ourResults = null; - RayCallback retMethod = delegate(List results) - { - ourResults = new ContactResult[results.Count]; - results.CopyTo(ourResults, 0); - }; - int waitTime = 0; - m_rayCastManager.QueueRequest(geom,position, direction, length, Count, flags, retMethod); - while (ourResults == null && waitTime < 1000) - { - Thread.Sleep(1); - waitTime++; - } - if (ourResults == null) + List ourResults = null; + object SyncObject = new object(); + + ProbePlaneCallback retMethod = delegate(List results) + { + ourResults = results; + Monitor.PulseAll(SyncObject); + }; + + ODERayRequest req = new ODERayRequest(); + req.geom = geom; + req.callbackMethod = retMethod; + req.length = plane.W; + req.Normal.X = plane.X; + req.Normal.Y = plane.Y; + req.Normal.Z = plane.Z; + req.Count = Count; + req.filter = flags; + + lock (SyncObject) + { + m_rayCastManager.QueueRequest(req); + if (!Monitor.Wait(SyncObject, 500)) return new List(); - return new List(ourResults); } - return new List(); + + if (ourResults == null) + return new List(); + return ourResults; } public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse) -- cgit v1.1 From be6b6bf191718f7c674297a804fa1a6cb4196a5a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 2 Jan 2013 20:06:57 +0000 Subject: add a lock to CollisionEventsThisFrame --- .../Region/Physics/UbitOdePlugin/ODECharacter.cs | 49 +++++++++++++--------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index e1d694e..f7e4c1c 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -1540,8 +1540,11 @@ namespace OpenSim.Region.Physics.OdePlugin { if (CollisionEventsThisFrame != null) { - CollisionEventsThisFrame.Clear(); - CollisionEventsThisFrame = null; + lock (CollisionEventsThisFrame) + { + CollisionEventsThisFrame.Clear(); + CollisionEventsThisFrame = null; + } } m_eventsubscription = 0; } @@ -1550,8 +1553,11 @@ namespace OpenSim.Region.Physics.OdePlugin { if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate(); - CollisionEventsThisFrame.AddCollider(CollidedWith, contact); - _parent_scene.AddCollisionEventReporting(this); + lock (CollisionEventsThisFrame) + { + CollisionEventsThisFrame.AddCollider(CollidedWith, contact); + _parent_scene.AddCollisionEventReporting(this); + } } public void SendCollisions() @@ -1559,26 +1565,29 @@ namespace OpenSim.Region.Physics.OdePlugin if (CollisionEventsThisFrame == null) return; - if (m_cureventsubscription < m_eventsubscription) - return; + lock (CollisionEventsThisFrame) + { + if (m_cureventsubscription < m_eventsubscription) + return; - m_cureventsubscription = 0; + m_cureventsubscription = 0; - int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count; + int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count; - if (!SentEmptyCollisionsEvent || ncolisions > 0) - { - base.SendCollisionUpdate(CollisionEventsThisFrame); - - if (ncolisions == 0) + if (!SentEmptyCollisionsEvent || ncolisions > 0) { - SentEmptyCollisionsEvent = true; - _parent_scene.RemoveCollisionEventReporting(this); - } - else - { - SentEmptyCollisionsEvent = false; - CollisionEventsThisFrame.Clear(); + base.SendCollisionUpdate(CollisionEventsThisFrame); + + if (ncolisions == 0) + { + SentEmptyCollisionsEvent = true; + _parent_scene.RemoveCollisionEventReporting(this); + } + else + { + SentEmptyCollisionsEvent = false; + CollisionEventsThisFrame.Clear(); + } } } } -- cgit v1.1 From a504704071b5302601240854c32fcc3d3c5cd3b8 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 2 Jan 2013 21:59:19 +0000 Subject: i try to fix avatar orientation in some cases.. --- OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs index 9e23763..d6f6681 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs @@ -233,8 +233,8 @@ namespace OpenSim.Region.Physics.OdePlugin norm = rayResults[0].Normal; edgeNormalX = norm.X; edgeNormalY = norm.Y; - edgeDirX = rayDir.X; - edgeDirY = rayDir.Y; + edgeDirX = -rayDir.X; + edgeDirY = -rayDir.Y; } else { -- cgit v1.1 From d40cdd26496c267b7de4cf7005eb6c933d7ad238 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 3 Jan 2013 02:25:27 +0000 Subject: cancel MoveToTarget (viewer 'go here") on sits --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 2a39ffd..704bad8 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2140,12 +2140,21 @@ namespace OpenSim.Region.Framework.Scenes if (canSit) { + if (PhysicsActor != null) { // We can remove the physicsActor until they stand up. RemoveFromPhysicalScene(); } + if (MovingToTarget) + { + ResetMoveToTarget(); + m_forceToApply = null; + } + + Velocity = Vector3.Zero; + part.AddSittingAvatar(UUID); cameraAtOffset = part.GetCameraAtOffset(); @@ -2230,6 +2239,7 @@ namespace OpenSim.Region.Framework.Scenes return true; } + // not doing autopilot m_requestedSitTargetID = 0; @@ -2259,8 +2269,19 @@ namespace OpenSim.Region.Framework.Scenes // m_log.InfoFormat("physsit {0} {1}", offset.ToString(),Orientation.ToString()); + RemoveFromPhysicalScene(); + + if (MovingToTarget) + { + ResetMoveToTarget(); + m_forceToApply = null; + } + + Velocity = Vector3.Zero; + part.AddSittingAvatar(UUID); + Vector3 cameraAtOffset = part.GetCameraAtOffset(); Vector3 cameraEyeOffset = part.GetCameraEyeOffset(); bool forceMouselook = part.GetForceMouselook(); @@ -2269,8 +2290,6 @@ namespace OpenSim.Region.Framework.Scenes part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); // not using autopilot - Velocity = Vector3.Zero; - RemoveFromPhysicalScene(); Rotation = Orientation; m_pos = offset; @@ -2317,6 +2336,7 @@ namespace OpenSim.Region.Framework.Scenes return; } + if (part.SitTargetAvatar == UUID) { Vector3 sitTargetPos = part.SitTargetPosition; -- cgit v1.1 From 1665a0d636a0d4e97000e16bd7a2b482e966c446 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 3 Jan 2013 03:29:40 +0000 Subject: make ResetMoveToTarget cancel any 'force' waiting to be applied to avatar ( by the odd use of Velocity) --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 704bad8..c16c544 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1990,7 +1990,8 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); MovingToTarget = false; - MoveToPositionTarget = Vector3.Zero; +// MoveToPositionTarget = Vector3.Zero; + m_forceToApply = null; // cancel possible last action // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. @@ -2148,10 +2149,7 @@ namespace OpenSim.Region.Framework.Scenes } if (MovingToTarget) - { ResetMoveToTarget(); - m_forceToApply = null; - } Velocity = Vector3.Zero; @@ -2272,10 +2270,7 @@ namespace OpenSim.Region.Framework.Scenes RemoveFromPhysicalScene(); if (MovingToTarget) - { ResetMoveToTarget(); - m_forceToApply = null; - } Velocity = Vector3.Zero; -- cgit v1.1 From a285ff7e6942f9b55b18b00a765a5b4491fba011 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 3 Jan 2013 14:27:21 +0000 Subject: check land permitions on sit target for unscripted sits --- OpenSim/Framework/ILandObject.cs | 1 + OpenSim/Region/CoreModules/World/Land/LandObject.cs | 13 +++++++++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 17 +++++++++++++++++ 3 files changed, 31 insertions(+) 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 void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client); bool IsEitherBannedOrRestricted(UUID avatar); bool IsBannedFromLand(UUID avatar); + bool CanBeOnThisLand(UUID avatar, float posHeight); bool IsRestrictedFromLand(UUID avatar); bool IsInLandAccessList(UUID avatar); void SendLandUpdateToClient(IClientAPI remote_client); diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index d5b2adb..fdac418 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 return false; } + public bool CanBeOnThisLand(UUID avatar, float posHeight) + { + if (posHeight < LandChannel.BAN_LINE_SAFETY_HIEGHT && IsBannedFromLand(avatar)) + { + return false; + } + else if (IsRestrictedFromLand(avatar)) + { + return false; + } + return true; + } + public bool HasGroupAccess(UUID avatar) { if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c16c544..5087882 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2247,6 +2247,17 @@ namespace OpenSim.Region.Framework.Scenes return false; } + + private bool CanEnterLandPosition(Vector3 testPos) + { + ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y); + + if (land == null || land.LandData.Name == "NO_LAND") + return true; + + return land.CanBeOnThisLand(UUID,testPos.Z); + } + // status // < 0 ignore // 0 bad sit spot @@ -2265,6 +2276,12 @@ namespace OpenSim.Region.Framework.Scenes if (part == null) return; + Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation(); + if(!CanEnterLandPosition(targetPos)) + { + ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot"); + return; + } // m_log.InfoFormat("physsit {0} {1}", offset.ToString(),Orientation.ToString()); RemoveFromPhysicalScene(); -- cgit v1.1 From c961cfe19e6dfaf26a0117748edbd66fc2d92823 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 3 Jan 2013 21:53:21 +0000 Subject: bug fix, cleanup... --- .../UbitOdePlugin/ODERayCastRequestManager.cs | 6 +-- .../Region/Physics/UbitOdePlugin/ODESitAvatar.cs | 51 ++++++++-------------- OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs | 15 ++++++- 3 files changed, 34 insertions(+), 38 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs index 31757a9..6e9281b 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs @@ -144,7 +144,7 @@ namespace OpenSim.Region.Physics.OdePlugin qtmp.Y = req.orientation.Y; qtmp.Z = req.orientation.Z; qtmp.W = req.orientation.W; - d.GeomSetOffsetWorldQuaternion(Box, ref qtmp); + d.GeomSetQuaternion(Box, ref qtmp); } else if (req.callbackMethod is ProbeSphereCallback) { @@ -480,12 +480,12 @@ namespace OpenSim.Region.Physics.OdePlugin if (count == 0) return; - +/* uint cat1 = d.GeomGetCategoryBits(g1); uint cat2 = d.GeomGetCategoryBits(g2); uint col1 = d.GeomGetCollideBits(g1); uint col2 = d.GeomGetCollideBits(g2); - +*/ uint ID = 0; PhysicsActor p2 = null; diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs index d6f6681..ecc732a 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs @@ -78,36 +78,20 @@ namespace OpenSim.Region.Physics.OdePlugin IntPtr geom = ((OdePrim)actor).prim_geom; - d.Vector3 dtmp = d.GeomGetPosition(geom); - Vector3 geopos; - geopos.X = dtmp.X; - geopos.Y = dtmp.Y; - geopos.Z = dtmp.Z; + Vector3 geopos = d.GeomGetPositionOMV(geom); + Quaternion geomOri = d.GeomGetQuaternionOMV(geom); + Quaternion geomInvOri = Quaternion.Conjugate(geomOri); - - d.AABB aabb; Quaternion ori = Quaternion.Identity; - d.Quaternion qtmp; - d.GeomCopyQuaternion(geom, out qtmp); - Quaternion geomOri; - geomOri.X = qtmp.X; - geomOri.Y = qtmp.Y; - geomOri.Z = qtmp.Z; - geomOri.W = qtmp.W; - Quaternion geomInvOri; - geomInvOri.X = -qtmp.X; - geomInvOri.Y = -qtmp.Y; - geomInvOri.Z = -qtmp.Z; - geomInvOri.W = qtmp.W; Vector3 rayDir = geopos + offset - avCameraPosition; + float raylen = rayDir.Length(); if (raylen < 0.001f) { PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity); return; } - float t = 1 / raylen; rayDir.X *= t; rayDir.Y *= t; @@ -119,22 +103,25 @@ namespace OpenSim.Region.Physics.OdePlugin rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir, raylen, 1, RaySitFlags); if (rayResults.Count == 0) { +/* if this fundamental ray failed, then just fail so user can try another spot and not be sitted far on a big prim + d.AABB aabb; d.GeomGetAABB(geom, out aabb); offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z); ori = geomInvOri; offset *= geomInvOri; - PhysicsSitResponse(1, actor.LocalID, offset, ori); +*/ + PhysicsSitResponse(0, actor.LocalID, offset, ori); return; } + int status = 1; offset = rayResults[0].Pos - geopos; d.GeomClassID geoclass = d.GeomGetClass(geom); if (geoclass == d.GeomClassID.SphereClass) { - int status = 1; float r = d.GeomSphereGetRadius(geom); offset.Normalize(); @@ -165,7 +152,7 @@ namespace OpenSim.Region.Physics.OdePlugin { status = 3; avOffset.X = -avOffset.X; - avOffset.Z += 0.4f; + avOffset.Z *= 1.6f; } } @@ -186,6 +173,7 @@ namespace OpenSim.Region.Physics.OdePlugin return; } + float SitNormX = -rayDir.X; float SitNormY = -rayDir.Y; @@ -204,7 +192,6 @@ namespace OpenSim.Region.Physics.OdePlugin { float rayDist = 4.0f; float curEdgeDist = 0.0f; - pivot = geopos + offset; for (int i = 0; i < 6; i++) { @@ -239,11 +226,8 @@ namespace OpenSim.Region.Physics.OdePlugin else { foundEdge = true; - if (curEdgeDist < edgeDist) - { - edgeDist = curEdgeDist; - edgePos = rayResults[0].Pos; - } + edgeDist = curEdgeDist; + edgePos = rayResults[0].Pos; break; } } @@ -267,7 +251,6 @@ namespace OpenSim.Region.Physics.OdePlugin { float rayDist = 1.0f; float curEdgeDist = 0.0f; - pivot = geopos + offset; for (int i = 0; i < 3; i++) { @@ -310,6 +293,8 @@ namespace OpenSim.Region.Physics.OdePlugin if (foundEdge && edgeDist < 0.2f) break; + pivot = geopos + offset; + switch (j) { case 0: @@ -332,7 +317,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (!foundEdge) { avOffset.X = -avOffset.X; - avOffset.Z += 0.4f; + avOffset.Z *= 1.6f; RotAroundZ(SitNormX, SitNormY, ref ori); @@ -349,7 +334,6 @@ namespace OpenSim.Region.Physics.OdePlugin SitNormX = edgeNormalX; SitNormY = edgeNormalY; - offset = edgePos - geopos; if (edgeDirX * SitNormX + edgeDirY * SitNormY < 0) { SitNormX = -SitNormX; @@ -358,7 +342,8 @@ namespace OpenSim.Region.Physics.OdePlugin RotAroundZ(SitNormX, SitNormY, ref ori); - offset += avOffset * ori; + offset = edgePos + avOffset * ori; + offset -= geopos; ori = geomInvOri * ori; 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. using System; using System.Runtime.InteropServices; using System.Security; - +using OMV = OpenMetaverse; namespace OdeAPI { //#if dDOUBLE @@ -925,9 +925,20 @@ namespace OdeAPI { unsafe { return *(GeomGetPositionUnsafe(geom)); } } + public static OMV.Vector3 GeomGetPositionOMV(IntPtr geom) + { + Vector3 vtmp = GeomGetPosition(geom); + return new OMV.Vector3(vtmp.X, vtmp.Y, vtmp.Z); + } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q); + public static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q); + public static OMV.Quaternion GeomGetQuaternionOMV(IntPtr geom) + { + Quaternion qtmp; + GeomCopyQuaternion(geom, out qtmp); + return new OMV.Quaternion(qtmp.X, qtmp.Y, qtmp.Z, qtmp.W); + } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity] public static extern void GeomCopyQuaternion(IntPtr geom, out dReal X); -- cgit v1.1