change (not)at_(rot)target checks

master
UbitUmarov 2020-02-25 23:02:38 +00:00
parent d47ce25b5b
commit ceb9289f13
2 changed files with 81 additions and 107 deletions

View File

@ -88,6 +88,7 @@ namespace OpenSim.Region.Framework.Scenes
public Vector3 targetPos; public Vector3 targetPos;
public float tolerance; public float tolerance;
public int handle; public int handle;
public uint partLocalID;
} }
public struct scriptRotTarget public struct scriptRotTarget
@ -95,6 +96,7 @@ namespace OpenSim.Region.Framework.Scenes
public Quaternion targetRot; public Quaternion targetRot;
public float tolerance; public float tolerance;
public int handle; public int handle;
public uint partLocalID;
} }
public delegate void PrimCountTaintedDelegate(); public delegate void PrimCountTaintedDelegate();
@ -164,7 +166,7 @@ namespace OpenSim.Region.Framework.Scenes
if (Backup) if (Backup)
m_scene.SceneGraph.FireChangeBackup(this); m_scene.SceneGraph.FireChangeBackup(this);
PseudoCRC = (int)(DateTime.UtcNow.Ticks); ; PseudoCRC = (int)(DateTime.UtcNow.Ticks);
timeLastChanged = DateTime.UtcNow.Ticks; timeLastChanged = DateTime.UtcNow.Ticks;
if (!m_hasGroupChanged) if (!m_hasGroupChanged)
timeFirstChanged = timeLastChanged; timeFirstChanged = timeLastChanged;
@ -1600,6 +1602,7 @@ namespace OpenSim.Region.Framework.Scenes
/// Treats all prims as rectangular, so no shape (cut etc) is taken into account /// Treats all prims as rectangular, so no shape (cut etc) is taken into account
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
{ {
maxX = float.MinValue; maxX = float.MinValue;
@ -2186,51 +2189,52 @@ namespace OpenSim.Region.Framework.Scenes
public void aggregateScriptEvents() public void aggregateScriptEvents()
{ {
PrimFlags objectflagupdate = (PrimFlags)RootPart.GetEffectiveObjectFlags(); PrimFlags objectflagupdate = (PrimFlags)RootPart.GetEffectiveObjectFlags();
scriptEvents aggregatedScriptEvents = 0;
scriptEvents aggregateScriptEvents = 0;
SceneObjectPart[] parts = m_parts.GetArray(); SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++) for (int i = 0; i < parts.Length; i++)
{ {
SceneObjectPart part = parts[i]; SceneObjectPart part = parts[i];
if (part == null)
continue;
if (part != RootPart) if (part != RootPart)
part.Flags = objectflagupdate; part.Flags = objectflagupdate;
aggregateScriptEvents |= part.AggregateScriptEvents; aggregatedScriptEvents |= part.AggregatedScriptEvents;
} }
m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); m_scriptListens_atTarget = ((aggregatedScriptEvents & scriptEvents.at_target) != 0);
m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); m_scriptListens_notAtTarget = ((aggregatedScriptEvents & scriptEvents.not_at_target) != 0);
if (!m_scriptListens_atTarget && !m_scriptListens_notAtTarget) if (!m_scriptListens_atTarget && !m_scriptListens_notAtTarget)
{ {
lock (m_targets) lock (m_targets)
m_targets.Clear(); {
m_scene.RemoveGroupTarget(this); if (m_targets.Count > 0)
{
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);
m_scriptListens_atRotTarget = ((aggregatedScriptEvents & scriptEvents.at_rot_target) != 0);
m_scriptListens_notAtRotTarget = ((aggregatedScriptEvents & scriptEvents.not_at_rot_target) != 0);
if (!m_scriptListens_atRotTarget && !m_scriptListens_notAtRotTarget) if (!m_scriptListens_atRotTarget && !m_scriptListens_notAtRotTarget)
{ {
lock (m_rotTargets) lock (m_rotTargets)
m_rotTargets.Clear(); {
m_scene.RemoveGroupTarget(this); if (m_rotTargets.Count > 0)
{
m_rotTargets.Clear();
m_scene.RemoveGroupTarget(this);
}
}
} }
scriptEvents rootPartPhysEvents = RootPart.AggregateScriptEvents; scriptEvents rootPartPhysEvents = RootPart.AggregatedScriptEvents;
rootPartPhysEvents &= PhysicsNeeedSubsEvents; rootPartPhysEvents &= PhysicsNeeedSubsEvents;
if (rootPartPhysEvents != lastRootPartPhysEvents) if (rootPartPhysEvents != lastRootPartPhysEvents)
{ {
lastRootPartPhysEvents = rootPartPhysEvents; lastRootPartPhysEvents = rootPartPhysEvents;
for (int i = 0; i < parts.Length; i++) for (int i = 0; i < parts.Length; i++)
{ parts[i].UpdatePhysicsSubscribedEvents();
SceneObjectPart part = parts[i];
if (part == null)
continue;
part.UpdatePhysicsSubscribedEvents();
}
} }
ScheduleGroupForFullUpdate(); ScheduleGroupForFullUpdate();
@ -4798,11 +4802,12 @@ namespace OpenSim.Region.Framework.Scenes
return 0; return 0;
} }
public int registerRotTargetWaypoint(Quaternion target, float tolerance) public int registerRotTargetWaypoint(uint partLocalID, Quaternion target, float tolerance)
{ {
scriptRotTarget waypoint = new scriptRotTarget(); scriptRotTarget waypoint = new scriptRotTarget();
waypoint.targetRot = target; waypoint.targetRot = target;
waypoint.tolerance = tolerance; waypoint.tolerance = tolerance;
waypoint.partLocalID = partLocalID;
int handle = m_scene.AllocateIntId(); int handle = m_scene.AllocateIntId();
waypoint.handle = handle; waypoint.handle = handle;
lock (m_rotTargets) lock (m_rotTargets)
@ -4825,13 +4830,17 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public int registerTargetWaypoint(Vector3 target, float tolerance) public int registerTargetWaypoint(uint partLocalID, Vector3 target, float tolerance)
{ {
int handle = m_scene.AllocateIntId();
scriptPosTarget waypoint = new scriptPosTarget(); scriptPosTarget waypoint = new scriptPosTarget();
waypoint.targetPos = target; waypoint.targetPos = target;
waypoint.tolerance = tolerance; waypoint.tolerance = tolerance * tolerance;
int handle = m_scene.AllocateIntId(); waypoint.partLocalID = partLocalID;
waypoint.handle = handle; waypoint.handle = handle;
lock (m_targets) lock (m_targets)
{ {
if (m_targets.Count >= 8) if (m_targets.Count >= 8)
@ -4839,7 +4848,7 @@ namespace OpenSim.Region.Framework.Scenes
m_targets.Add(handle, waypoint); m_targets.Add(handle, waypoint);
} }
m_scene.AddGroupTarget(this); m_scene.AddGroupTarget(this);
return (int)handle; return handle;
} }
public void unregisterTargetWaypoint(int handle) public void unregisterTargetWaypoint(int handle)
@ -4854,126 +4863,92 @@ namespace OpenSim.Region.Framework.Scenes
public void checkAtTargets() public void checkAtTargets()
{ {
if (m_targets.Count > 0 && (m_scriptListens_atTarget || m_scriptListens_notAtTarget)) int targetsCount = m_targets.Count;
if (targetsCount > 0 && (m_scriptListens_atTarget || m_scriptListens_notAtTarget))
{ {
bool not_target = true; List<scriptPosTarget> atTargets = new List<scriptPosTarget>(targetsCount);
List<scriptPosTarget> notatTargets = new List<scriptPosTarget>(targetsCount);
List<scriptPosTarget> atTargets = new List<scriptPosTarget>(m_targets.Count); Vector3 pos = m_rootPart.GroupPosition;
lock (m_targets) lock (m_targets)
{ {
if (m_scriptListens_atTarget) foreach (scriptPosTarget target in m_targets.Values)
{ {
foreach (scriptPosTarget target in m_targets.Values) if (Vector3.DistanceSquared(target.targetPos, pos) <= target.tolerance)
{ {
if (Vector3.DistanceSquared(target.targetPos, m_rootPart.GroupPosition) <= target.tolerance * target.tolerance) if (m_scriptListens_atTarget)
{
not_target = false;
atTargets.Add(target); atTargets.Add(target);
}
} }
} else
else
{
foreach (scriptPosTarget target in m_targets.Values)
{ {
if (Vector3.DistanceSquared(target.targetPos, m_rootPart.GroupPosition) <= target.tolerance * target.tolerance) if (m_scriptListens_notAtTarget)
{ notatTargets.Add(target);
not_target = false;
break;
}
} }
} }
} }
if (atTargets.Count > 0) if (atTargets.Count > 0)
{ {
SceneObjectPart[] parts = m_parts.GetArray(); for (int target = 0; target < atTargets.Count; ++target)
for (int ctr = 0; ctr < parts.Length; ++ctr)
{ {
uint pid = parts[ctr].LocalId; scriptPosTarget att = atTargets[target];
for(int target = 0; target < atTargets.Count; ++target) m_scene.EventManager.TriggerAtTargetEvent(
{ att.partLocalID, (uint)att.handle, att.targetPos, pos);
scriptPosTarget att = atTargets[target];
m_scene.EventManager.TriggerAtTargetEvent(
pid, (uint)att.handle, att.targetPos, m_rootPart.GroupPosition);
}
} }
} }
if (not_target && m_scriptListens_notAtTarget) if (notatTargets.Count > 0)
{ {
//trigger not_at_target for (int target = 0; target < notatTargets.Count; ++target)
SceneObjectPart[] parts = m_parts.GetArray();
for (int ctr = 0; ctr < parts.Length; ctr++)
{ {
m_scene.EventManager.TriggerNotAtTargetEvent(parts[ctr].LocalId); m_scene.EventManager.TriggerNotAtTargetEvent(notatTargets[target].partLocalID);
} }
} }
} }
if (m_rotTargets.Count > 0 && (m_scriptListens_atRotTarget || m_scriptListens_notAtRotTarget)) targetsCount = m_rotTargets.Count;
if (targetsCount > 0 && (m_scriptListens_atRotTarget || m_scriptListens_notAtRotTarget))
{ {
bool not_Rottarget = true; List<scriptRotTarget> atRotTargets = new List<scriptRotTarget>(targetsCount);
List<scriptRotTarget> notatRotTargets = new List<scriptRotTarget>(targetsCount);
List<scriptRotTarget> atRotTargets = new List<scriptRotTarget>(m_rotTargets.Count); Quaternion rot = m_rootPart.RotationOffset;
lock (m_rotTargets) lock (m_rotTargets)
{ {
if (m_scriptListens_atRotTarget) foreach (scriptRotTarget target in m_rotTargets.Values)
{ {
foreach (scriptRotTarget target in m_rotTargets.Values) double angle = 2 * Math.Acos(Quaternion.Dot(target.targetRot, rot));
if (angle < 0)
angle = -angle;
if (angle > Math.PI)
angle = (2 * Math.PI - angle);
if (angle <= target.tolerance)
{ {
double angle = 2 * Math.Acos(Quaternion.Dot(target.targetRot, m_rootPart.RotationOffset)); if (m_scriptListens_atRotTarget)
if (angle < 0)
angle = -angle;
if (angle > Math.PI)
angle = (2 * Math.PI - angle);
if (angle <= target.tolerance)
{
// trigger at_rot_target
not_Rottarget = false;
atRotTargets.Add(target); atRotTargets.Add(target);
}
} }
} else
else
{
foreach (scriptRotTarget target in m_rotTargets.Values)
{ {
double angle = 2 * Math.Acos(Quaternion.Dot(target.targetRot, m_rootPart.RotationOffset)); if (m_scriptListens_notAtRotTarget)
if (angle < 0) notatRotTargets.Add(target);
angle = -angle;
if (angle > Math.PI)
angle = (2 * Math.PI - angle);
if (angle <= target.tolerance)
{
not_Rottarget = false;
break;
}
} }
} }
} }
if (atRotTargets.Count > 0) if (atRotTargets.Count > 0)
{ {
SceneObjectPart[] parts = m_parts.GetArray(); for (int target = 0; target < atRotTargets.Count; ++target)
for (int ctr = 0; ctr < parts.Length; ++ctr)
{ {
uint pid = parts[ctr].LocalId; scriptRotTarget att = atRotTargets[target];
for (int target = 0; target < atRotTargets.Count; ++target) m_scene.EventManager.TriggerAtRotTargetEvent(
{ att.partLocalID, (uint)att.handle, att.targetRot, rot);
scriptRotTarget att = atRotTargets[target];
m_scene.EventManager.TriggerAtRotTargetEvent(
pid, (uint)att.handle, att.targetRot, m_rootPart.RotationOffset);
}
} }
} }
if (not_Rottarget && m_scriptListens_notAtRotTarget) if (notatRotTargets.Count > 0)
{ {
//trigger not_at_target for (int target = 0; target < notatRotTargets.Count; ++target)
SceneObjectPart[] parts = m_parts.GetArray(); {
for (int ctr = 0; ctr < parts.Length; ++ctr) m_scene.EventManager.TriggerNotAtRotTargetEvent(notatRotTargets[target].partLocalID);
m_scene.EventManager.TriggerNotAtRotTargetEvent(parts[ctr].LocalId); }
} }
} }
} }

View File

@ -3035,8 +3035,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Integer llTarget(LSL_Vector position, double range) public LSL_Integer llTarget(LSL_Vector position, double range)
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
return m_host.ParentGroup.registerTargetWaypoint(position, return m_host.ParentGroup.registerTargetWaypoint(m_host.LocalId, position, (float)range);
(float)range);
} }
public void llTargetRemove(int number) public void llTargetRemove(int number)
@ -3048,7 +3047,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Integer llRotTarget(LSL_Rotation rot, double error) public LSL_Integer llRotTarget(LSL_Rotation rot, double error)
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
return m_host.ParentGroup.registerRotTargetWaypoint(rot, (float)error); return m_host.ParentGroup.registerRotTargetWaypoint(m_host.LocalId, rot, (float)error);
} }
public void llRotTargetRemove(int number) public void llRotTargetRemove(int number)