Aurora.ScriptEngine.AuroraDotNetEngine.APIs.LSL_Api.llCastRay C# (CSharp) Метод

llCastRay() публичный Метод

public llCastRay ( Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.Vector3 start, Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.Vector3 end, Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.list options ) : Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.list
start Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.Vector3
end Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.Vector3
options Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.list
Результат Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.list
        public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
        {
            Vector3 dir = new Vector3((float)(end - start).x, (float)(end - start).y, (float)(end - start).z);
            Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z);
            Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z);


            int count = 0;
            int detectPhantom = 0;
            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);
                }
                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);
                }
            }

            LSL_List list = new LSL_List();
            List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count);

            double distance = Util.GetDistanceTo(startvector, endvector);
            if (distance == 0)
                distance = 0.001;
            Vector3 posToCheck = startvector;
            ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
            List<IScenePresence> presences = new List<IScenePresence>(World.Entities.GetPresences(startvector, (float)distance));
            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);
            for (float i = 0; i <= distance; i += 0.1f)
            {
                posToCheck = startvector + (dir * (i / (float)distance));
                float groundHeight = channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)];
                if (checkTerrain && groundHeight > posToCheck.Z)
                {
                    ContactResult result = new ContactResult { ConsumerID = 0, Depth = 0, Normal = Vector3.Zero, Pos = posToCheck };
                    results.Add(result);
                    checkTerrain = false;
                }
                if (checkAgents)
                {
                    for (int presenceCount = 0; presenceCount < presences.Count; presenceCount++)
                    {
                        IScenePresence sp = presences[presenceCount];
                        if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
                        {
                            ContactResult result = new ContactResult
                                                       {
                                                           ConsumerID = sp.LocalId,
                                                           Depth = 0,
                                                           Normal = Vector3.Zero,
                                                           Pos = posToCheck
                                                       };
                            results.Add(result);
                            presences.RemoveAt(presenceCount);
                            if (presenceCount > 0)
                                presenceCount--; //Reset its position since we removed this one
                        }
                    }
                }
            }
            int refcount = 0;
            List<ContactResult> newResults = new List<ContactResult>();
            foreach (ContactResult result in results)
            {
                foreach (ContactResult r in newResults)
                    if (r.ConsumerID == result.ConsumerID)
                        newResults.Add(result);
            }
            castRaySort(startvector, ref newResults);
            foreach (ContactResult result in newResults)
            {
                if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND &&
                    result.ConsumerID == 0)
                    continue;

                IEntity entity = World.GetSceneObjectPart(result.ConsumerID);
                if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
                    entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents
                if (entity == null)
                {
                    list.Add(UUID.Zero);
                    if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
                        list.Add(0);
                    list.Add(result.Pos);
                    if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
                        list.Add(result.Normal);
                    refcount++;
                    continue; //Can't find it, so add UUID.Zero
                }

                /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
                    ((ISceneChildEntity)intersection.obj).PhysActor == null)
                    continue;*/
                //Can't do this ATM, physics engine knows only of non phantom objects

                if (entity is ISceneChildEntity && ((ISceneChildEntity)entity).PhysActor != null && ((ISceneChildEntity)entity).PhysActor.IsPhysical)
                {
                    if (!checkPhysical)
                        continue;
                }
                else if (entity is ISceneChildEntity)
                    if (!checkNonPhysical)
                        continue;

                refcount++;
                if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is ISceneChildEntity)
                    list.Add(((ISceneChildEntity)entity).ParentEntity.UUID);
                else
                    list.Add(entity.UUID);

                if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
                    if (entity is ISceneChildEntity)
                        list.Add(entity.LinkNum);
                    else
                        list.Add(0);

                list.Add(result.Pos);
                if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
                    list.Add(result.Normal);
            }

            list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED

            return list;
        }
LSL_Api