public ProxyTriangle(RenderItem t, Point3 pa, Point3 pb, Point3 pc) : base(t) { this.pa = pa; this.pb = pb; this.pc = pc; }
public static void TestRIEqual(Ray ray, double ta, double tb, List<RenderItem> ris, RenderItem ria, RenderItem rib) { if(ria != rib) { Assert.AreEqual(ria, rib, string.Format("The hitpoint was {0}/{3} with ray {2} and scenario {1}", ray.PointAt(ta), string.Join(",", ris), ray, ray.PointAt(tb))); } else { Assert.AreEqual(ria, rib); } }
public static Tuple<ProxyRenderItem[], ProxyRenderItem[]> TriangleSplitAt (RenderItem parent, Point3 pa, Point3 pb, Point3 pc, double sweep, Point3 facenormal) { IComparer<Point3> co = new Point3.FaceComp(facenormal); Maths.Order(co, ref pa, ref pb); Maths.Order(co, ref pa, ref pc); Maths.Order(co, ref pb, ref pc); ProxyRenderItem[] la = new ProxyRenderItem[1], lb; double paf = pa[facenormal], pbf = pb[facenormal], pcf = pc[facenormal]; double fac = (sweep-paf)/(pcf-paf); double fad = 1.0d-fac; Point3 pac = new Point3(fac*pc.X+fad*pa.X, fac*pc.Y+fad*pa.Y, fac*pc.Z+fad*pa.Z), pabc; if(pbf != sweep) { lb = new ProxyRenderItem[2]; if(pbf > sweep) { fac = (sweep-paf)/(pbf-paf); fad = 1.0d-fac; pabc = new Point3(fac*pb.X+fad*pa.X, fac*pb.Y+fad*pa.Y, fac*pb.Z+fad*pa.Z); la[0x00] = new ProxyTriangle(parent, pa, pac, pabc); lb[0x00] = new ProxyTriangle(parent, pac, pb, pabc); lb[0x01] = new ProxyTriangle(parent, pac, pc, pb); return new Tuple<ProxyRenderItem[],ProxyRenderItem[]>(la, lb); } else { fac = (sweep-pbf)/(pcf-pbf); fad = 1.0d-fac; pabc = new Point3(fac*pc.X+fad*pb.X, fac*pc.Y+fad*pb.Y, fac*pc.Z+fad*pb.Z); la[0x00] = new ProxyTriangle(parent, pc, pac, pabc); lb[0x00] = new ProxyTriangle(parent, pac, pb, pabc); lb[0x01] = new ProxyTriangle(parent, pac, pa, pb); return new Tuple<ProxyRenderItem[],ProxyRenderItem[]>(lb, la); } } else { lb = new ProxyRenderItem[1]; la[0x00] = new ProxyTriangle(parent, pa, pac, pb); lb[0x00] = new ProxyTriangle(parent, pac, pc, pb); return new Tuple<ProxyRenderItem[],ProxyRenderItem[]>(la, lb); } }
public void Hit (Ray ray, Point3 inter, ref RenderItem item, ref double tcur, double tmig, ref double tmax) { if(this.splitNormal != null) {//we're not at a leaf double x = inter[this.splitNormal]; double dxi = Maths.SoftInv(ray.Direction[this.splitNormal]); if((x < xm && dxi <= 0.0d) || x > xM && dxi >= 0.0d) { return; } double x0 = ray.Offset[this.splitNormal]; double tt = tcur; double tmig0; if(x < xa) { if(dxi > 0.0d) { tt = tcur+dxi*(xb-x); tmig0 = Math.Min(tmig, dxi*(xa-x0)); this.left.Hit(ray, inter, ref item, ref tcur, tmig0, ref tmax); tmig = Math.Min(tmig, tmax); if(tt <= tmig) { #if FAST_COLOR_MIGRATION SystemDiagnostics.Migrations++; #endif tcur = tt; ray.PointAt(tcur, inter); this.right.Hit(ray, inter, ref item, ref tcur, tmig, ref tmax); } } else { this.left.Hit(ray, inter, ref item, ref tcur, tmig, ref tmax); } } else if(x > xb) { if(dxi < 0.0d) { tt = tcur+dxi*(xa-x); tmig0 = Math.Min(tmig, dxi*(xb-x0)); this.right.Hit(ray, inter, ref item, ref tcur, tmig0, ref tmax); tmig = Math.Min(tmig, tmax); if(tt <= tmig) { #if FAST_COLOR_MIGRATION SystemDiagnostics.Migrations++; #endif tcur = tt; ray.PointAt(tcur, inter); this.left.Hit(ray, inter, ref item, ref tcur, tmig, ref tmax); } } else { this.right.Hit(ray, inter, ref item, ref tcur, tmig, ref tmax); } } else {//in the death zone if(dxi < 0.0d) { #if FAST_COLOR_MIGRATION SystemDiagnostics.Migrations++; #endif tcur = dxi*(xa-x); ray.PointAt(tcur, inter); this.left.Hit(ray, inter, ref item, ref tcur, tmig, ref tmax); } else if(dxi > 0.0d) { #if FAST_COLOR_MIGRATION SystemDiagnostics.Migrations++; #endif tcur = dxi*(xb-x0); ray.PointAt(tcur, inter); this.right.Hit(ray, inter, ref item, ref tcur, tmig, ref tmax); } //else we cannot move in the death zone, thus go back one level } } else { double tt; foreach(RenderItem ri in items) { tt = ri.HitAt(ray); if(tt < tmax) { tmax = tt; item = ri; } } } }
public BSPNode (RenderItem[] items) { splitNormal = null; left = right = null; xa = xb = double.NaN; this.items = items; }
public ProxyRenderItemBase(RenderItem source) { this.Source = source; }
public void Hit(Ray ray, Point3 rayinv, Point3 inter, ref double t, ref double tHit, ref RenderItem ri) { double tt; if(this.tri == null) { if(t < tHit) { int cur = Math.Sign(inter[dim]-x); if(cur*Math.Sign(rayinv[dim]) < 0.0d) { tt = t+(x-inter[dim])*rayinv[dim]; double tt2 = Math.Min(tt, tHit); this.children[(cur+0x01)>>0x01].Hit(ray, rayinv, inter, ref t, ref tt2, ref ri); if(tt <= tt2) { t = tt; ray.PointAt(tt, inter); this.children[(0x01-cur)>>0x01].Hit(ray, rayinv, inter, ref t, ref tHit, ref ri); } else { tHit = tt2; } } else { this.children[(cur+0x01)>>0x01].Hit(ray, rayinv, inter, ref t, ref tHit, ref ri); } } } else { foreach(RenderItem rit in tri) { tt = rit.HitAt(ray); if(tt < tHit) { tHit = tt; ri = rit; } } } }
public BinarySpaceNode(RenderItem[] tris) { this.tri = tris; this.dim = 0x00; this.children = null; this.x = double.NaN; }
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); } }