Esempio n. 1
0
        /// <summary>
        /// A recursive method which trace a ray until its power is less than ray-minimum power thershold
        /// </summary>
        /// <param name="path">New PathFromTxToRy object.</param>
        /// <param name="ray">A starting ray (first ray)</param>
        /// <param name="lastIntersectPart">A world object which this ray last intersect, or start</param>
        /// <returns>PathFromTxToRy with True if it reaches receiver and False if it did not reach the receiver.</returns>
        public PathFromTxToRy traceRay(PathFromTxToRy path, Ray ray, SceneObjectPart lastIntersectPart)
        {
            EntityIntersectionWithPart nextHit = findNextHit(ray, transmitter.RootPart);

            if (nextHit.intersection.HitTF)
            {
                //Check for limit number of reflection allowed.
                if(path.getNoOfReflection() >= MAX_REFLECTIONS)
                {
                    path.reachesReceiver = false;
                    return path;
                }
                //drawRay(ray.Origin, nextHit.intersection.ipoint);
                else if (nextHit.intersectPart.Equals(receiver.RootPart)) //If it reaches the receiver
                {
                    path.reachesReceiver = true;
                    path.addNextPoint(nextHit.intersection.ipoint, receiver.RootPart.Material);
                    return path;
                }//if

                //recursive case, keep tracing this ray.
                else
                {
                    path.addNextPoint(nextHit.intersection.ipoint, nextHit.intersectPart.Material);
                    Vector3 reflectedVector = getReflectedVector(ray.Direction, nextHit.intersection.normal);
                    Ray newRay = new Ray(nextHit.intersection.ipoint, reflectedVector);
                    return traceRay(path, newRay, nextHit.intersectPart);
                }//else if
            }
            else //It didn't hit anything
            {
                path.reachesReceiver = false;
                return path;
            }//else
        }
Esempio n. 2
0
        /// <summary>
        /// Draw a given path (A given path may contains many rays). This method just get all the ray in the 
        /// given path and draw them sequentially.
        /// </summary>
        /// <param name="path"></param>
        public void drawRayPath(PathFromTxToRy path)
        {
            foreach(KeyValuePair<string, RayAsPathSection> ray in path.rayList)
            {
                //Note: Team KeyValuePair and Value are c# syntax for accessing dictionary element value and its key.
                // To get the key, we do section.Key. To get the value we do section.Value;

                string name = "ray_" + path.getNoOfReflection() + "_" + path.id + "_" + ray.Value.id;
                drawRay(ray.Value.startPoint, ray.Value.endPoint, name);
            }
        }
Esempio n. 3
0
        public void getOneReflection()
        {
            int worldPartsSize = worldObjects.Count();
            float toPercent = 100.0f / worldPartsSize;
            float currentElementIndex = 1.0f;
            Vector3 transmitterPos = transmitter.RootPart.AbsolutePosition;
            Vector3 receiverPos = receiver.RootPart.AbsolutePosition;

            //For each scenobjectpart, find the reflection point between the transmitter and the reciever. 

            foreach (SceneObjectPart part in worldObjects)
            {
                //Make sure that it doesn't reflect off the transmitter or the reciever
                if (!part.Equals(transmitter.RootPart) && !part.Equals(receiver.RootPart))
                {
                    //Check if the intersection point is found
                    ReflectionPoint reflectedPoint = findReflectionPoint(transmitterPos, receiverPos, part);
                    if (reflectedPoint.found)
                    {
                        string pathID = getPathID();
                        PathFromTxToRy newPath = new PathFromTxToRy(this, transmitter.RootPart.AbsolutePosition, pathID);
                        newPath.addNextPoint(reflectedPoint.reflectionPoint, reflectedPoint.surfaceMaterial);
                        newPath.addNextPoint(receiver.RootPart.AbsolutePosition, receiver.RootPart.Material);
                        newPath.reachesReceiver = true;
                        if (!checkPathIsDrawn(newPath))
                        {
                            pathHits[1].Add(pathID, newPath);
                        }//if
                    }//if
                }//if


                //Progress bar update
                if (currentElementIndex < worldPartsSize)
                {
                    updateProgressBar(currentElementIndex * toPercent);
                }
                else
                {
                    updateProgressBar(100.0f);
                }
                currentElementIndex++;
            }//forEachPart
        }
Esempio n. 4
0
 public void getLineOfSight()
 {
     string pathID = getPathID();
     PathFromTxToRy path = new PathFromTxToRy(this, transmitter.RootPart.AbsolutePosition, pathID);
     //Direction from transmitter to the reciever 
     Vector3 direction = receiver.RootPart.AbsolutePosition - transmitter.RootPart.AbsolutePosition;
     //Ray vector from transmitter to the receiver
     Ray ray = new Ray(transmitter.RootPart.AbsolutePosition, direction);
     //Get the first object the ray hit
     EntityIntersectionWithPart intersection = findNextHit(ray, transmitter.RootPart);
     path.addNextPoint(receiver.RootPart.AbsolutePosition, receiver.RootPart.Material);
     path.reachesReceiver = true;
     if (!checkPathIsDrawn(path))
     {
         pathHits[0].Add(pathID, path);
     }
 }
Esempio n. 5
0
        /// <summary>
        /// From the transmitter, we create a ray in all direction (with angle between ray = ANGLE_BETWEEN_RAY). For each
        /// of those ray, we 'trace/follow' them and find where they are heading. If they reaches the reciever, then 
        /// we store them in a list. 
        /// </summary>
        public void startRayTracerBrutefoce()
        {
            m_log.DebugFormat("[BARE BONES NON SHARED] Started Raytracing!");

            float lat, lon;
            float toPercent = 100.0f/360.0f;

            //For every lon and lat increase by ANGLE_BETWEEN_RAY
            for (lon = 0; lon < 360; lon += ANGLE_BETWEEN_RAY)
            {
                for (lat = 0; lat < 360; lat += ANGLE_BETWEEN_RAY)
                {
                    double lonr = lon * DEG_TO_RAD;
                    double latr = lat * DEG_TO_RAD;
                    
                    //Note: Lat = angle of elevation. Lon = angle around the z-axis
                    //To get a point on a sphere using 2 angle 
                    //Assuming Radius = 1 so we can get rid of multiplying radius. 
                    //http://stackoverflow.com/questions/969798/plotting-a-point-on-the-edge-of-a-sphere

                    float x = (float)(Math.Sin(latr) * Math.Cos(lonr));
                    float y = (float)(Math.Sin(latr) * Math.Sin(lonr));
                    float z = (float)(Math.Cos(latr));

                    Vector3 pointOnSphere = new Vector3(x, y, z);
                    pointOnSphere.Normalize();

                    Vector3 direction = pointOnSphere;
                    Ray ray = new Ray(transmitter.RootPart.AbsolutePosition, direction);

                    //Trace this ray
                    string pathID = getPathID();
                    PathFromTxToRy thisRayPath = new PathFromTxToRy(this, transmitter.RootPart.AbsolutePosition, pathID);
                    thisRayPath = traceRay(thisRayPath, ray, transmitter.RootPart);

                    //If it reaches the receiver, then add it to the hit list. 
                    if (thisRayPath.reachesReceiver && !checkPathIsDrawn(thisRayPath))
                    {
                        pathHits[thisRayPath.getNoOfReflection()].Add(pathID, thisRayPath);
                    }
                }
                //If lon < 359 then calculate the progress 
                if (lon < 359)
                {
                    updateProgressBar(lon * toPercent);
                }
                else //else it is completed so return 100%
                {
                    updateProgressBar(100.0f);
                }
           }//for
        }
Esempio n. 6
0
        /// <summary>
        /// Start a ray tracer from a given model. The model has 3 sections seperate by '//'
        /// First section: Just says 'RTModel' to indicate that this is a ray tracer model
        /// Second section: Variables section. This contians the variables which were set by the user
        /// Third section: Set of paths from transmitter to the receiver.
        /// </summary>
        public void RayTraceFromModel(string givenModel, Scene _scene, UUID _scriptID)
        {
            string[] tokens = Regex.Split(givenModel, "//");
            string section1 = tokens[0];
            string section2 = tokens[1];
            string section3 = tokens[2];

            //Do a small check on the file. To make this better, we can do a checksum and keep it in here
            //instead of 'RTModel'

            if (section1 != "RTModel")
            {
                throw new Exception("The given ray trace model is not compatible");
            }


            Initialise(_scene, section2, _scriptID);


            if (!sameTransmitter(section3))
            {
                throw new Exception("This model is invalid as the transmitter is moved");
            }


            //Each path is seperate by '#' so we split by '#' to get each path
            //It only goes up to pathList.Length -1 because the last element is the empty string. 

            string[] pathList = section3.Split('#');
            for(int i = 0; i < pathList.Length - 1; i++)
            {
                //Each position/point is seperate by '_' so we split path by '_'
                //It only goes up to listOfPoints.Length -1 because the last element is the empty string. 
                string[] listOfPoints = pathList[i].Split('_');
                //index 0 = starting point. 
                //Each coordinate (x, y, z) is seperate by ',' or we split this point by ','

                string[] pointElements = listOfPoints[0].Split(',');
                Vector3 currentPoint = new Vector3(float.Parse(pointElements[0]), float.Parse(pointElements[1]), float.Parse(pointElements[2]));
                string pathID = getPathID();
                PathFromTxToRy newPath = new PathFromTxToRy(this, currentPoint, pathID);
                for(int j = 1; j < listOfPoints.Length - 1; j++)
                {
                    pointElements = listOfPoints[j].Split(',');
                    currentPoint = new Vector3(float.Parse(pointElements[0]), float.Parse(pointElements[1]), float.Parse(pointElements[2]));
                    newPath.addNextPoint(currentPoint, float.Parse(pointElements[3]));
                }
                pathHits[newPath.getNoOfReflection()].Add(pathID, newPath);
            }//for

            RayTraceIsCalculated = true;
            packAndSendGETMessages(false);
            m_log.DebugFormat("[Finished Loaded a model]");
        }
Esempio n. 7
0
        /// <summary>
        /// There seems to be a bug that causes each path to be drawn twice. This function check, if the
        /// given path has already been drawn. This function should be called everytime before adding a path
        /// to a hit list. 
        /// </summary>
        /// <param name="path"></param>
        /// <returns>True = the path has already been drawn. False = the path hasn't been drawn</returns>
        bool checkPathIsDrawn(PathFromTxToRy path)
        {
            Vector3 midPoint = new Vector3();
            //To reduce the computation time, we only one ray from a path. i.e. break the loop when getting the first one. 
            foreach (KeyValuePair<string, RayAsPathSection> ray in path.rayList)
            {
                midPoint = ray.Value.endPoint - ray.Value.startPoint;
                midPoint.X = Math.Abs(midPoint.X);
                midPoint.Y = Math.Abs(midPoint.Y);
                midPoint.Z = Math.Abs(midPoint.Z);
                break;
            }//foreach

            //This loop will determine whether or not this path has been drawn before. It does this by 
            //compare the 'midPoint' against the list of other mid-points. 
            foreach (Vector3 pos in allRayPos)
            {
                if (pos.CompareTo(midPoint) == 0)
                {
                    return true;
                }//if
            }//foreach

            //Meaning that this path hasn't been drawm before. Add all of its ray's midpoint to the list
            foreach (KeyValuePair<string, RayAsPathSection> ray in path.rayList)
            {
                Vector3 newRayPos = new Vector3();
                newRayPos = ray.Value.endPoint - ray.Value.startPoint;
                newRayPos.X = Math.Abs(newRayPos.X);
                newRayPos.Y = Math.Abs(newRayPos.Y);
                newRayPos.Z = Math.Abs(newRayPos.Z);
                allRayPos.Add(newRayPos);
            }//foreach
            return false;
        }