diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 4dd6f32383..76d5cb6421 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -181,7 +181,15 @@ namespace OpenSim.Region.Framework.Scenes public delegate void ScriptNotAtTargetEvent(uint localID); - public event ScriptNotAtTargetEvent OnScriptNotAtTargetEvent; + public event ScriptNotAtTargetEvent OnScriptNotAtTargetEvent; + + public delegate void ScriptAtRotTargetEvent(uint localID, uint handle, Quaternion targetrot, Quaternion atrot); + + public event ScriptAtRotTargetEvent OnScriptAtRotTargetEvent; + + public delegate void ScriptNotAtRotTargetEvent(uint localID); + + public event ScriptNotAtRotTargetEvent OnScriptNotAtRotTargetEvent; public delegate void ScriptColliding(uint localID, ColliderArgs colliders); @@ -383,7 +391,9 @@ namespace OpenSim.Region.Framework.Scenes private ScriptChangedEvent handlerScriptChangedEvent = null; //OnScriptChangedEvent; private ScriptAtTargetEvent handlerScriptAtTargetEvent = null; - private ScriptNotAtTargetEvent handlerScriptNotAtTargetEvent = null; + private ScriptNotAtTargetEvent handlerScriptNotAtTargetEvent = null; + private ScriptAtRotTargetEvent handlerScriptAtRotTargetEvent = null; + private ScriptNotAtRotTargetEvent handlerScriptNotAtRotTargetEvent = null; private ClientMovement handlerClientMovement = null; //OnClientMovement; private OnPermissionErrorDelegate handlerPermissionError = null; //OnPermissionError; private OnPluginConsoleDelegate handlerPluginConsole = null; //OnPluginConsole; @@ -849,6 +859,24 @@ namespace OpenSim.Region.Framework.Scenes { handlerScriptNotAtTargetEvent(localID); } + } + + public void TriggerAtRotTargetEvent(uint localID, uint handle, Quaternion targetrot, Quaternion currentrot) + { + handlerScriptAtRotTargetEvent = OnScriptAtRotTargetEvent; + if (handlerScriptAtRotTargetEvent != null) + { + handlerScriptAtRotTargetEvent(localID, handle, targetrot, currentrot); + } + } + + public void TriggerNotAtRotTargetEvent(uint localID) + { + handlerScriptNotAtRotTargetEvent = OnScriptNotAtRotTargetEvent; + if (handlerScriptNotAtRotTargetEvent != null) + { + handlerScriptNotAtRotTargetEvent(localID); + } } public void TriggerRequestChangeWaterHeight(float height) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 34d8b49c83..8050bf6092 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -56,7 +56,8 @@ namespace OpenSim.Region.Framework.Scenes land_collision = 2048, land_collision_end = 4096, land_collision_start = 8192, - at_target = 16384, + at_target = 16384, + at_rot_target = 16777216, listen = 32768, money = 65536, moving_end = 131072, @@ -79,6 +80,13 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 targetPos; public float tolerance; public uint handle; + } + + struct scriptRotTarget + { + public Quaternion targetRot; + public float tolerance; + public uint handle; } public delegate void PrimCountTaintedDelegate(); @@ -165,10 +173,14 @@ namespace OpenSim.Region.Framework.Scenes protected SceneObjectPart m_rootPart; // private Dictionary m_scriptEvents = new Dictionary(); - private Dictionary m_targets = new Dictionary(); + private Dictionary m_targets = new Dictionary(); + private Dictionary m_rotTargets = new Dictionary(); private bool m_scriptListens_atTarget = false; - private bool m_scriptListens_notAtTarget = false; + private bool m_scriptListens_notAtTarget = false; + + private bool m_scriptListens_atRotTarget = false; + private bool m_scriptListens_notAtRotTarget = false; internal Dictionary m_savedScriptState = null; @@ -1261,6 +1273,15 @@ namespace OpenSim.Region.Framework.Scenes lock (m_targets) m_targets.Clear(); m_scene.RemoveGroupTarget(this); + } + m_scriptListens_atRotTarget = ((aggregateScriptEvents & scriptEvents.at_rot_target) != 0); + m_scriptListens_notAtRotTarget = ((aggregateScriptEvents & scriptEvents.not_at_rot_target) != 0); + + if (!m_scriptListens_atRotTarget && !m_scriptListens_notAtRotTarget) + { + lock (m_rotTargets) + m_rotTargets.Clear(); + m_scene.RemoveGroupTarget(this); } ScheduleGroupForFullUpdate(); @@ -3157,6 +3178,30 @@ namespace OpenSim.Region.Framework.Scenes } } + } + public int registerRotTargetWaypoint(Quaternion target, float tolerance) + { + scriptRotTarget waypoint = new scriptRotTarget(); + waypoint.targetRot = target; + waypoint.tolerance = tolerance; + uint handle = m_scene.AllocateLocalId(); + waypoint.handle = handle; + lock (m_rotTargets) + { + m_rotTargets.Add(handle, waypoint); + } + m_scene.AddGroupTarget(this); + return (int)handle; + } + + public void unregisterRotTargetWaypoint(int handle) + { + lock (m_targets) + { + m_rotTargets.Remove((uint)handle); + if (m_targets.Count == 0) + m_scene.RemoveGroupTarget(this); + } } public int registerTargetWaypoint(Vector3 target, float tolerance) @@ -3263,6 +3308,85 @@ namespace OpenSim.Region.Framework.Scenes } } } + } + if (m_scriptListens_atRotTarget || m_scriptListens_notAtRotTarget) + { + if (m_rotTargets.Count > 0) + { + bool at_Rottarget = false; + Dictionary atRotTargets = new Dictionary(); + lock (m_rotTargets) + { + foreach (uint idx in m_rotTargets.Keys) + { + scriptRotTarget target = m_rotTargets[idx]; + double angle = Math.Acos(target.targetRot.X * m_rootPart.RotationOffset.X + target.targetRot.Y * m_rootPart.RotationOffset.Y + target.targetRot.Z * m_rootPart.RotationOffset.Z + target.targetRot.W * m_rootPart.RotationOffset.W) * 2; + if (angle < 0) angle = -angle; + if (angle > Math.PI) angle = (Math.PI * 2 - angle); + if (angle <= target.tolerance) + { + // trigger at_rot_target + if (m_scriptListens_atRotTarget) + { + at_Rottarget = true; + scriptRotTarget att = new scriptRotTarget(); + att.targetRot = target.targetRot; + att.tolerance = target.tolerance; + att.handle = target.handle; + atRotTargets.Add(idx, att); + } + } + } + } + + if (atRotTargets.Count > 0) + { + uint[] localids = new uint[0]; + lock (m_parts) + { + localids = new uint[m_parts.Count]; + int cntr = 0; + foreach (SceneObjectPart part in m_parts.Values) + { + localids[cntr] = part.LocalId; + cntr++; + } + } + + for (int ctr = 0; ctr < localids.Length; ctr++) + { + foreach (uint target in atRotTargets.Keys) + { + scriptRotTarget att = atRotTargets[target]; + m_scene.EventManager.TriggerAtRotTargetEvent( + localids[ctr], att.handle, att.targetRot, m_rootPart.RotationOffset); + } + } + + return; + } + + if (m_scriptListens_notAtRotTarget && !at_Rottarget) + { + //trigger not_at_target + uint[] localids = new uint[0]; + lock (m_parts) + { + localids = new uint[m_parts.Count]; + int cntr = 0; + foreach (SceneObjectPart part in m_parts.Values) + { + localids[cntr] = part.LocalId; + cntr++; + } + } + + for (int ctr = 0; ctr < localids.Length; ctr++) + { + m_scene.EventManager.TriggerNotAtRotTargetEvent(localids[ctr]); + } + } + } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 73f79b3751..177de476ff 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4078,6 +4078,23 @@ namespace OpenSim.Region.Framework.Scenes { m_parentGroup.unregisterTargetWaypoint(handle); } + } + + public int registerRotTargetWaypoint(Quaternion target, float tolerance) + { + if (m_parentGroup != null) + { + return m_parentGroup.registerRotTargetWaypoint(target, tolerance); + } + return 0; + } + + public void unregisterRotTargetWaypoint(int handle) + { + if (m_parentGroup != null) + { + m_parentGroup.unregisterRotTargetWaypoint(handle); + } } public void SetCameraAtOffset(Vector3 v) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 39b597e05d..856f8b6863 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2108,15 +2108,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llRotTarget(LSL_Rotation rot, double error) { - m_host.AddScriptLPS(1); - NotImplemented("llRotTarget"); - return 0; + m_host.AddScriptLPS(1); + return m_host.registerRotTargetWaypoint(new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error); } public void llRotTargetRemove(int number) { - m_host.AddScriptLPS(1); - NotImplemented("llRotTargetRemove"); + m_host.AddScriptLPS(1); + m_host.unregisterRotTargetWaypoint(number); } public void llMoveToTarget(LSL_Vector target, double tau) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs index 7f67599c92..fb8685021d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs @@ -61,7 +61,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase land_collision = 2048, land_collision_end = 4096, land_collision_start = 8192, - at_target = 16384, + at_target = 16384, + at_rot_target = 16777216, listen = 32768, money = 65536, moving_end = 131072, @@ -202,8 +203,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return; } - m_eventFlagsMap.Add("attach", scriptEvents.attach); - // m_eventFlagsMap.Add("at_rot_target",(long)scriptEvents.at_rot_target); + m_eventFlagsMap.Add("attach", scriptEvents.attach); + m_eventFlagsMap.Add("at_rot_target", scriptEvents.at_rot_target); m_eventFlagsMap.Add("at_target", scriptEvents.at_target); // m_eventFlagsMap.Add("changed",(long)scriptEvents.changed); m_eventFlagsMap.Add("collision", scriptEvents.collision); diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs index b2eab45837..ce22ba5419 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs @@ -58,7 +58,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine myScriptEngine.World.EventManager.OnObjectDeGrab += touch_end; myScriptEngine.World.EventManager.OnScriptChangedEvent += changed; myScriptEngine.World.EventManager.OnScriptAtTargetEvent += at_target; - myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target; + myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target; + myScriptEngine.World.EventManager.OnScriptAtRotTargetEvent += at_rot_target; + myScriptEngine.World.EventManager.OnScriptNotAtRotTargetEvent += not_at_rot_target; myScriptEngine.World.EventManager.OnScriptControlEvent += control; myScriptEngine.World.EventManager.OnScriptColliderStart += collision_start; myScriptEngine.World.EventManager.OnScriptColliding += collision; @@ -388,16 +390,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine myScriptEngine.PostObjectEvent(localID, new EventParams( "not_at_target",new object[0], new DetectParams[0])); - } - - public void at_rot_target(uint localID, UUID itemID) - { - myScriptEngine.PostObjectEvent(localID, new EventParams( - "at_rot_target",new object[0], + } + + public void at_rot_target(uint localID, uint handle, Quaternion targetrot, + Quaternion atrot) + { + myScriptEngine.PostObjectEvent(localID, new EventParams( + "at_rot_target", new object[] { + new LSL_Types.LSLInteger(handle), + new LSL_Types.Quaternion(targetrot.X,targetrot.Y,targetrot.Z,targetrot.W), + new LSL_Types.Quaternion(atrot.X,atrot.Y,atrot.Z,atrot.W) }, new DetectParams[0])); } - public void not_at_rot_target(uint localID, UUID itemID) + public void not_at_rot_target(uint localID) { myScriptEngine.PostObjectEvent(localID, new EventParams( "not_at_rot_target",new object[0],