public OctTreeAccelerator (List<RenderItem> items, int maxDepth, SplitDimensionHeuristic sdh, int maxNodeItems = 8) { this.maxDepth = maxDepth; this.maxNodeItems = maxNodeItems; List<MarkedItem>[] buildingCaches = new List<MarkedItem>[Math.Max(0x02, maxDepth)+0x01]; for(int i = 0x00; i < buildingCaches.Length; i++) { buildingCaches[i] = new List<MarkedItem>(); } Utils.CalculateBoundingBox(items, out x0, out x1, out y0, out y1, out z0, out z1); buildingCaches[0x00].AddRange(items.Mark()); OctTreeNode otn = Order(sdh, buildingCaches, 0x00, x0, x1, y0, y1, z0, z1); FinalList fl = new FinalList(otn.PropagateSubLists()); this.root = new FastOctTreeNode(otn); this.ris = fl.list.Select(x => items[x]).ToArray(); }
private void proceedSubTree (Ray ray, int dpos, double[] seqxyz, Point3 inter, ref RenderItem ri, ref double t, ref double tHit, FastOctTreeNode fotn) { double tt; if(fotn.IsLeaf) { long refs = fotn.data; if(refs != 0x00) { long end = refs>>0x20; for(refs &= 0xffffffff; refs < end; refs++) { tt = ris[refs].HitAt(ray); if(tt < tHit) { tHit = tt; ri = ris[refs]; } } } } else if(t < tHit) { int pos = Maths.BinarySign(inter.X-fotn.x)|(Maths.BinarySign(inter.Y-fotn.y)<<0x02)|(Maths.BinarySign(inter.Z-fotn.z)<<0x04); double xt, yt, zt; int nextdim = 0x00; do { #if FAST_COLOR_MIGRATION SystemDiagnostics.Migrations++; #endif seqxyz[0x04] = fotn.x; seqxyz[0x07] = fotn.y; seqxyz[0x0a] = fotn.z; tt = double.PositiveInfinity; int pos2 = pos+dpos; calcDim(ref tt, ref nextdim, ray.X0, seqxyz[(pos2&0x03)+0x03], seqxyz[0x00], 0x00); calcDim(ref tt, ref nextdim, ray.Y0, seqxyz[((pos2&0x0c)>>0x02)+0x06], seqxyz[0x01], 0x02); calcDim(ref tt, ref nextdim, ray.Z0, seqxyz[((pos2&0x30)>>0x04)+0x09], seqxyz[0x02], 0x04); xt = seqxyz[0x05-((pos&0x01)<<0x01)]; yt = seqxyz[0x08-((pos&0x04)>>0x01)]; zt = seqxyz[0x0b-((pos&0x10)>>0x03)]; seqxyz[0x05-((pos&0x01)<<0x01)] = fotn.x; seqxyz[0x08-((pos&0x04)>>0x01)] = fotn.y; seqxyz[0x0b-((pos&0x10)>>0x03)] = fotn.z; proceedSubTree(ray, dpos, seqxyz, inter, ref ri, ref t, ref tHit, fotn.node[((pos&0x01)<<0x02)|((pos&0x04)>>0x01)|((pos&0x10)>>0x04)]); seqxyz[0x05-((pos&0x01)<<0x01)] = xt; seqxyz[0x08-((pos&0x04)>>0x01)] = yt; seqxyz[0x0b-((pos&0x10)>>0x03)] = zt; t = tt; ray.PointAt(t, inter); pos += (0x02*((dpos>>nextdim)&0x03)-0x01)<<nextdim; } while(t < tHit && (pos&ValidPositionMask) == 0x00); } }