/// <summary> /// A partial implementation. /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetBoundingBox /// So far only valid for standing/flying/ground sitting avatars and single prim objects. /// If the object has multiple prims and/or a sitting avatar then the bounding /// box is for the root prim only. /// </summary> public LSL_List llGetBoundingBox(string obj) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(new LSL_List()); } UUID objID = UUID.Zero; LSL_List result = new LSL_List(); if (!UUID.TryParse(obj, out objID)) { result.Add(new LSL_Vector()); result.Add(new LSL_Vector()); return(result); } IScenePresence presence = World.GetScenePresence(objID); if (presence != null) { if (presence.ParentID == UUID.Zero) // not sat on an object { LSL_Vector lower = new LSL_Vector(); LSL_Vector upper = new LSL_Vector(); if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) { // This is for ground sitting avatars IAvatarAppearanceModule appearance = presence.RequestModuleInterface <IAvatarAppearanceModule>(); if (appearance != null) { float height = appearance.Appearance.AvatarHeight / 2.66666667f; lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); } } else { // This is for standing/flying avatars IAvatarAppearanceModule appearance = presence.RequestModuleInterface <IAvatarAppearanceModule>(); if (appearance != null) { float height = appearance.Appearance.AvatarHeight / 2.0f; lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); } } result.Add(lower); result.Add(upper); return(result); } // sitting on an object so we need the bounding box of that // which should include the avatar so set the UUID to the // UUID of the object the avatar is sat on and allow it to fall through // to processing an object ISceneChildEntity p = World.GetSceneObjectPart(presence.ParentID); objID = p.UUID; } ISceneChildEntity part = World.GetSceneObjectPart(objID); // Currently only works for single prims without a sitting avatar if (part != null) { Vector3 halfSize = part.Scale * 0.5f; LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); result.Add(lower); result.Add(upper); return(result); } // Not found so return empty values result.Add(new LSL_Vector()); result.Add(new LSL_Vector()); return(result); }
public LSL_List llDeleteSubList(LSL_List src, int start, int end) { return(src.DeleteSublist(start, end)); }
public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return(new LSL_List()); } LSL_List list = new LSL_List(); Vector3 rayStart = start.ToVector3(); Vector3 rayEnd = end.ToVector3(); Vector3 dir = rayEnd - rayStart; float dist = Vector3.Mag(dir); int count = 1; bool detectPhantom = false; int dataFlags = 0; int rejectTypes = 0; for (int i = 0; i < options.Length; i += 2) { if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) { count = options.GetLSLIntegerItem(i + 1); } else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) { detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0); } else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) { dataFlags = options.GetLSLIntegerItem(i + 1); } else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) { rejectTypes = options.GetLSLIntegerItem(i + 1); } } if (count > 16) { count = 16; } else if (count <= 0) { Error("llCastRay", "You must request at least one result from llCastRay."); return(new LSL_List()); } List <ContactResult> results = new List <ContactResult>(); bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); if (checkAgents) { ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); foreach (ContactResult r in agentHits) { results.Add(r); } } if (checkPhysical || checkNonPhysical || detectPhantom) { ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom, count + 2); for (int iter = 0; iter < objectHits.Length; iter++) { // Redistance the Depth because the Scene RayCaster returns distance from center to make the rezzing code simpler. objectHits[iter].Depth = Vector3.Distance(objectHits[iter].Pos, rayStart); results.Add(objectHits[iter]); } } if (checkTerrain) { ContactResult?groundContact = GroundIntersection(rayStart, rayEnd); if (groundContact != null) { results.Add((ContactResult)groundContact); } } results.Sort(delegate(ContactResult a, ContactResult b) { return(a.Depth.CompareTo(b.Depth)); }); int values = 0; ISceneEntity thisgrp = m_host.ParentEntity; foreach (ContactResult result in results) { if (result.Depth > dist) { continue; } // physics ray can return colisions with host prim // this is supposed to happen if (m_host.LocalId == result.ConsumerID) { continue; } if (!checkTerrain && result.ConsumerID == 0) { continue; //Terrain } UUID itemID = UUID.Zero; int linkNum = 0; ISceneChildEntity part = World.GetSceneObjectPart(result.ConsumerID); // It's a prim! if (part != null) { // dont detect members of same object ??? if (part.ParentEntity == thisgrp) { continue; } if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY) { itemID = part.ParentEntity.UUID; } else { itemID = part.UUID; } linkNum = part.LinkNum; } else { IScenePresence sp = World.GetScenePresence(result.ConsumerID); /// It it a boy? a girl? if (sp != null) { itemID = sp.UUID; } } list.Add(new LSL_String(itemID.ToString())); if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) { list.Add(new LSL_Integer(linkNum)); } list.Add(new LSL_Vector(result.Pos)); if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) { Vector3 norm = result.Normal * -1; list.Add(new LSL_Vector(norm)); } values++; if (values >= count) { break; } } list.Add(new LSL_Integer(values)); return(list); }