private List <SensedEntity> doAgentSensor(SensorInfo ts) { List <SensedEntity> sensedEntities = new List <SensedEntity>(); // If nobody about quit fast if (m_CmdManager.m_ScriptEngine.World.GetRootAgentCount() == 0) { return(sensedEntities); } SceneObjectPart SensePoint = ts.host; Vector3 fromRegionPos = SensePoint.GetWorldPosition(); Quaternion q = SensePoint.GetWorldRotation(); if (SensePoint.ParentGroup.IsAttachment) { // In attachments, rotate the sensor cone with the // avatar rotation. This may include a nonzero elevation if // in mouselook. // This will not include the rotation and position of the // attachment point (e.g. your head when a sensor is in your // hair attached to your scull. Your hair will turn with // your head but the sensor will stay with your (global) // avatar rotation and position. // Position of a sensor in a child prim attached to an avatar // will be still wrong. ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); q = avatar.Rotation * q; } LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0); Vector3 toRegionPos; double dis; Action <ScenePresence> senseEntity = new Action <ScenePresence>(presence => { // m_log.DebugFormat( // "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", // presence.Name, presence.PresenceType, ts.name, ts.type); if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) { INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); if (npcData == null || !npcData.SenseAsAgent) { // m_log.DebugFormat( // "[SENSOR REPEAT]: Discarding NPC {0} from agent sense sweep for script item id {1}", // presence.Name, ts.itemID); return; } } if ((ts.type & AGENT) == 0) { if (presence.PresenceType == PresenceType.User) { return; } else { INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); if (npcData != null && npcData.SenseAsAgent) { // m_log.DebugFormat( // "[SENSOR REPEAT]: Discarding NPC {0} from non-agent sense sweep for script item id {1}", // presence.Name, ts.itemID); return; } } } if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0) { return; } // if the object the script is in is attached and the avatar is the owner // then this one is not wanted if (attached && presence.UUID == SensePoint.OwnerID) { return; } toRegionPos = presence.AbsolutePosition; dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos)); // Disabled for now since all osNpc* methods check for appropriate ownership permission. // Perhaps could be re-enabled as an NPC setting at some point since being able to make NPCs not // sensed might be useful. // if (presence.PresenceType == PresenceType.Npc && npcModule != null) // { // UUID npcOwner = npcModule.GetOwner(presence.UUID); // if (npcOwner != UUID.Zero && npcOwner != SensePoint.OwnerID) // return; // } // are they in range if (dis <= ts.range) { // Are they in the required angle of view if (ts.arc < Math.PI) { // not omni-directional. Can you see it ? // vec forward_dir = llRot2Fwd(llGetRot()) // vec obj_dir = toRegionPos-fromRegionPos // dot=dot(forward_dir,obj_dir) // mag_fwd = mag(forward_dir) // mag_obj = mag(obj_dir) // ang = acos(dot /(mag_fwd*mag_obj)) double ang_obj = 0; try { LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3( toRegionPos - fromRegionPos); double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); double mag_obj = LSL_Types.Vector3.Mag(obj_dir); ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); } catch { } if (ang_obj <= ts.arc) { sensedEntities.Add(new SensedEntity(dis, presence.UUID)); } } else { sensedEntities.Add(new SensedEntity(dis, presence.UUID)); } } }); // If this is an avatar sense by key try to get them directly // rather than getting a list to scan through if (ts.keyID != UUID.Zero) { ScenePresence sp; // Try direct lookup by UUID if (!m_CmdManager.m_ScriptEngine.World.TryGetScenePresence(ts.keyID, out sp)) { return(sensedEntities); } senseEntity(sp); } else if (ts.name != null && ts.name != "") { ScenePresence sp; // Try lookup by name will return if/when found if (((ts.type & AGENT) != 0) && m_CmdManager.m_ScriptEngine.World.TryGetAvatarByName(ts.name, out sp)) { senseEntity(sp); } if ((ts.type & AGENT_BY_USERNAME) != 0) { m_CmdManager.m_ScriptEngine.World.ForEachRootScenePresence( delegate(ScenePresence ssp) { if (ssp.Lastname == "Resident") { if (ssp.Firstname.ToLower() == ts.name) { senseEntity(ssp); } return; } if (ssp.Name.Replace(" ", ".").ToLower() == ts.name) { senseEntity(ssp); } } ); } return(sensedEntities); } else { m_CmdManager.m_ScriptEngine.World.ForEachRootScenePresence(senseEntity); } return(sensedEntities); }
public void Populate(Scene scene) { SceneObjectPart part = scene.GetSceneObjectPart(Key); if (part == null) // Avatar, maybe? { ScenePresence presence = scene.GetScenePresence(Key); if (presence == null) { return; } Name = presence.Firstname + " " + presence.Lastname; Owner = Key; Position = new LSL_Types.Vector3(presence.AbsolutePosition); Rotation = new LSL_Types.Quaternion( presence.Rotation.X, presence.Rotation.Y, presence.Rotation.Z, presence.Rotation.W); Velocity = new LSL_Types.Vector3(presence.Velocity); if (presence.PresenceType != PresenceType.Npc) { Type = AGENT; } else { Type = OS_NPC; INPCModule npcModule = scene.RequestModuleInterface <INPCModule>(); INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); if (npcData.SenseAsAgent) { Type |= AGENT; } } if (presence.Velocity != Vector3.Zero) { Type |= ACTIVE; } Group = presence.ControllingClient.ActiveGroupId; return; } part = part.ParentGroup.RootPart; // We detect objects only LinkNum = 0; // Not relevant Group = part.GroupID; Name = part.Name; Owner = part.OwnerID; if (part.Velocity == Vector3.Zero) { Type = PASSIVE; } else { Type = ACTIVE; } foreach (SceneObjectPart p in part.ParentGroup.Parts) { if (p.Inventory.ContainsScripts()) { Type |= SCRIPTED; // Scripted break; } } Position = new LSL_Types.Vector3(part.AbsolutePosition); Quaternion wr = part.ParentGroup.GroupRotation; Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W); Velocity = new LSL_Types.Vector3(part.Velocity); }