diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ff9df37dba..85f4ee59e6 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2109,9 +2109,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; @@ -2130,25 +2127,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) { @@ -2156,12 +2136,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) @@ -2223,14 +2197,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 { @@ -2240,24 +2206,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 (status < 0) - { - ControllingClient.SendAlertMessage("Sit position no longer exists"); - return; - } - - if (status == 0) - return; - - SceneObjectPart part = m_scene.GetSceneObjectPart(partID); if (part == null || part.ParentGroup.IsAttachment) { + return true; + } + + if ( m_scene.PhysicsScene == null) + return false; + + if (part.PhysActor == null) + { + // 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; + } + + // 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; + + 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); @@ -2269,16 +2268,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; @@ -2286,6 +2283,8 @@ namespace OpenSim.Region.Framework.Scenes 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 a442cf0970..86e07133a8 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 561ab1c0aa..54a83c2de4 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 225bff8e65..fd3a3ba8ce 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) { @@ -93,10 +94,10 @@ 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); + 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; diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index fbf2f0dabd..d344d4d6a4 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);