/// <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 }
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); } }
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 }
/// <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]"); }