Beispiel #1
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);
     }
 }
Beispiel #2
0
		public RenderItem CalculateHit (Ray ray, out double t, double MaxT) {
			double tmin = 0.0d;
			t = MaxT;
			//first setting up the interval
			foreach(NormalInterval ni in intervals) {
				Utils.CloseInterval(ray, ni, ref tmin, ref t);
			}
			if(t > tmin) {//the ray passes through the bounding sheared box
				RenderItem ri = null;
				Point3 inter = new Point3();
				ray.PointAt(tmin, inter);
				this.root.Hit(ray, inter, ref ri, ref tmin, t, ref t);
				return ri;
			}
			else {
				return null;
			}
		}
Beispiel #3
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;
						}
					}
				}
			}
Beispiel #4
0
 public Color CalculateColor(Ray ray, int depth, Color intensityHint)
 {
     RenderItem best = null;
     double t, tdummy;
     best = acc.CalculateHit(ray, out t);
     if(best != null) {
         best.Cast(ray, nw);
         Point3 norm = nw.Normal;
         ray.PointAt(t, hp);
         Material mat = best.Material;
         Color ambient, diffuse, specular, reflectance, refraction;
         mat.ADSAtAndBump(nw, ray.Direction, out ambient, out diffuse, out specular, out reflectance, out refraction);
         Color clr = this.ambientColor*ambient;
         Point3.ReflectRefract(ray.Direction, nw.Normal, mat.NFactor, rl, rf);
         rayCache[depth].SetWithEpsilon(hp, rf);
         foreach(Light li in this.lights) {
             double len = Point3.DiffLength(hp, li.Position);
             double thetafrac = Math.PI-Math.Asin(li.Radius/len);
             uint light = 0x00;
             double lightD;
             dis.SetValues(hp, li.Position);
             dis.Normalize();
             if(Point3.CosAngleNorm(dis, norm) >= 0.0d) {
                 if(!double.IsNaN(thetafrac) && lightTest > 0x00) {
                     dis.SetValues(hp, li.Position);
                     dis.Normalize();
                     sr.SetOffsetWithEpsilon(hp);
                     if(this.acc.CalculateHit(sr, out tdummy, len-li.Radius) == null) {
                         light++;
                     }
                     for(int i = 1; i < lightTest; i++) {
                         lp.SetValues(li.Position, li.Radius);
                         dis.SetValues(hp, lp);
                         dis.Normalize();
                         sr.SetOffsetWithEpsilon(hp);
                         if(this.acc.CalculateHit(sr, out tdummy, len-li.Radius) == null) {
                             light++;
                         }
                     }
                     lightD = (double)light/lightTest;
                 }
                 else {
                     lightD = 1.0d;
                 }
                 if(lightD > 0.0d) {
                     dis.SetValues(hp, li.Position);
                     dis.Normalize();
                     Color clrl = (li.Color*diffuse)*Point3.CosAngleNorm(dis, norm);
                     clrl += (li.Color*specular)*Math.Max(0.0d, Math.Pow(Point3.CosAngleNorm(rl, dis), mat.Shininess));
                     clr += Color.LoseIntensity((clrl*lightD), distanceUnit, len);
                 }
             }
         }
         if(depth < maxDepth) {
             Color reflint = intensityHint*reflectance;
             if(reflint.IntensityTreshold) {
                 ray.SetWithEpsilon(hp, rl);
                 clr += this.CalculateColor(ray, depth+1, reflint)*reflectance;
             }
             Color refrint = intensityHint*refraction;
             if(refrint.IntensityTreshold) {
                 if(double.IsNaN(rayCache[depth].Direction.X)) {
                     ray.SetWithEpsilon(hp, rl);
                     clr += this.CalculateColor(ray, depth+1, refrint)*refraction;
                 }
                 else {
                     clr += this.CalculateColor(rayCache[depth], depth+1, refrint)*refraction;
                 }
             }
         }
         return Color.LoseIntensity(clr, distanceUnit, t);
     }
     else {
         return this.EnvironmentMap(ray);
     }
 }
 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;
             }
         }
     }
 }
Beispiel #6
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);
			}
		}