示例#1
0
 public ProxyTriangle(RenderItem t, Point3 pa, Point3 pb, Point3 pc)
     : base(t)
 {
     this.pa = pa;
     this.pb = pb;
     this.pc = pc;
 }
示例#2
0
 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);
     }
 }
示例#3
0
		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);
			}
		}
示例#4
0
			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;
						}
					}
				}
			}
示例#5
0
			public BSPNode (RenderItem[] items) {
				splitNormal = null;
				left = right = null;
				xa = xb = double.NaN;
				this.items = items;
			}
示例#6
0
 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;
 }
示例#9
0
		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);
			}
		}