Advertisement
epitaque_

Untitled

Nov 23rd, 2018
392
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.38 KB | None | 0 0
  1.     /*
  2.         Ray Tracing methods
  3.         Returns a list of nodes that intersect a ray (in sorted order)
  4.      */
  5.     public List<SVONode> Trace(UnityEngine.Ray ray, List<uint> svo) {
  6.         List<Node> intersectedNodes = new List<Node>();
  7.         RayStep(ExpandSVO(svo), ray.origin, ray.direction, intersectedNodes);
  8.         return intersectedNodes.ConvertAll(node => (SVONode)node).ToList();
  9.     }
  10.  
  11.     private int FirstNode(double tx0, double ty0, double tz0, double txm, double tym, double tzm){
  12.         sbyte answer = 0;
  13.  
  14.         if(tx0 > ty0) {
  15.             if(tz0 > tx0) { // tz0 max. entry xy
  16.                 if(txm < tz0) answer |= 4;
  17.                 if(tym < tz0) answer |= 2;
  18.             }
  19.             else { //tx0 max. entry yz
  20.                 if(tym < tx0) answer |= 2;
  21.                 if(tzm < tx0) answer |= 1;
  22.             }
  23.         } else {
  24.             if(ty0 > tz0) { // ty0 max. entry xz
  25.                 if(txm < ty0) answer |= 4;
  26.                 if(tzm < ty0) answer |= 1;
  27.             } else { // tz0 max. entry XY
  28.                 if(txm < tz0) answer |= 4;
  29.                 if(tym < tz0) answer |= 2;
  30.             }
  31.         }
  32.         return (int) answer;
  33.     }
  34.  
  35.     private static int NewNode(double txm, int x, double tym, int y, double tzm, int z){
  36.         if(txm < tym){
  37.             if(txm < tzm){return x;}  // YZ plane
  38.         }
  39.         else{
  40.             if(tym < tzm){return y;} // XZ plane
  41.         }
  42.         return z; // XY plane;
  43.     }
  44.  
  45.     private class ParameterData {
  46.         public Vector3 t0;
  47.         public Vector3 t1;
  48.         public Node node;
  49.         public int currNode;
  50.  
  51.         public ParameterData(Vector3 t0, Vector3 t1, Node node, int currNode) {
  52.             this.t0 = t0;
  53.             this.t1 = t1;
  54.             this.node = node;
  55.             this.currNode = currNode;
  56.         }
  57.     }
  58.  
  59.     private void RayStep(Node root, Vector3 rayOrigin, Vector3 rayDirection, List<Node> intersectedNodes)  {
  60.         Vector3 nodeMax = root.Position + Vector3.one * (float)root.Size;
  61.  
  62.         if(root == null || rayDirection.x == 0 || rayDirection.y == 0 || rayDirection.z == 0) {
  63.             return;
  64.         }
  65.  
  66.         sbyte a = 0;
  67.         if(rayDirection.x < 0) {
  68.             rayOrigin.x = -rayOrigin.x;
  69.             rayDirection.x = -rayDirection.x;
  70.             a |= 4;
  71.         }
  72.         if(rayDirection.y < 0){        
  73.             rayOrigin.y = -rayOrigin.y;
  74.             rayDirection.y = -rayDirection.y;
  75.             a |= 2;
  76.         }
  77.         if(rayDirection.z < 0){        
  78.             rayOrigin.z =  -rayOrigin.z;
  79.             rayDirection.z = -rayDirection.z;
  80.             a |= 1;
  81.         }
  82.  
  83.         double divx = 1 / rayDirection.x; // IEEE stability fix
  84.         double divy = 1 / rayDirection.y;
  85.         double divz = 1 / rayDirection.z;
  86.         double tx0 = (root.Position.x - rayOrigin.x) * divx;
  87.         double tx1 = (nodeMax.x - rayOrigin.x) * divx;
  88.         double ty0 = (root.Position.y - rayOrigin.y) * divy;
  89.         double ty1 = (nodeMax.y - rayOrigin.y) * divy;
  90.         double tz0 = (root.Position.z - rayOrigin.z) * divz;
  91.         double tz1 = (nodeMax.z - rayOrigin.z) * divz;
  92.  
  93.         Vector3 t0 = new Vector3((float)tx0, (float)ty0, (float)tz0);
  94.         Vector3 t1 = new Vector3((float)tx1, (float)ty1, (float)tz1);
  95.  
  96.         ParameterData[] stack = new ParameterData[30];
  97.         int sf = 0;
  98.         stack[sf] = new ParameterData(t0, t1, root, -1);
  99.  
  100.         if(Mathd.Max(tx0,ty0,tz0) < Mathd.Min(tx1,ty1,tz1)){    
  101.             while(sf >= 0) {
  102.                 ParameterData data = stack[sf];
  103.                 Node node = data.node;
  104.                 t0 = data.t0;
  105.                 t1 = data.t1;
  106.  
  107.                 if(node == null || data.currNode > 7 || t1.x <= 0 || t1.y <= 0 || t1.z <= 0) {
  108.                     sf--;
  109.                     continue;
  110.                 }
  111.                 if(node.Leaf){
  112.                     intersectedNodes.Add(node);
  113.                     sf--;
  114.                     continue;
  115.                 }
  116.  
  117.                 Vector3 tm = 0.5f*(t0 + t1);
  118.                 data.currNode = data.currNode == -1 ? FirstNode(t0.x,t0.y,t0.z,tm.x,tm.y,tm.z) : data.currNode;
  119.                 ParameterData nextFrame = new ParameterData(getT0(t0, tm, data.currNode), getT1(tm, t1, data.currNode), data.node.Children[data.currNode^a], -1);
  120.                 data.currNode = getNewNode(tm, t1, data.currNode);             
  121.                 stack[++sf] = nextFrame;
  122.             }
  123.         }
  124.     }
  125.  
  126.     private static Vector3 getT0(Vector3 t0, Vector3 tm, int currNode) {
  127.         float[] arr = new float[] {t0.x, t0.y, t0.z, tm.x, tm.y, tm.z};
  128.         return new Vector3(arr[((currNode & 4) >> 2) * 3],  arr[1 + ((currNode & 2) >> 1) * 3], arr[2 + (currNode & 1) * 3]);
  129.     }
  130.     private static Vector3 getT1(Vector3 tm, Vector3 t1, int currNode) {
  131.         float[] arr = new float[] {tm.x, tm.y, tm.z, t1.x, t1.y, t1.z};
  132.         return new Vector3(arr[((currNode & 4) >> 2) * 3],  arr[1 + ((currNode & 2) >> 1) * 3], arr[2 + (currNode & 1) * 3]);
  133.     }
  134.     private static int getNewNode(Vector3 tm, Vector3 t1, int currNode) {
  135.         int[] arr = new int[] {4,2,1, 5,3,8, 6,8,3, 7,8,8, 8,6,5, 8,7,8, 8,8,7, 8,8,8};
  136.         Vector3 t = getT1(tm, t1, currNode);
  137.         return NewNode(t.x, arr[3 * currNode], t.y, arr[1 + 3*currNode], t.z, arr[2 + 3*currNode]);
  138.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement