コード例 #1
0
 public RenderItem CalculateHit(Ray ray, out double tHit, double maxT)
 {
     Point3 inter = new Point3(ray.Offset);
     tHit = maxT;
     double t = 0.0d;
     if(x0 > inter.X || inter.X > x1 || y0 > inter.Y || inter.Y > y1 || z0 > inter.Z || inter.Z > z1) {
         Utils.CalculateBoxHitpoint(ray, inter, out t, this.x0, this.x1, this.y0, this.y1, this.z0, this.z1);
         if(t > maxT) {
             return null;
         }
     }
     Point3 inter2 = new Point3(Maths.ZeroInv(ray.DX), Maths.ZeroInv(ray.DY), Maths.ZeroInv(ray.DZ));
     double tt = Maths.SoftInv(ray.DX)*(box[Maths.BinarySign(ray.DX)]-ray.X0);
     if(tt < tHit) {
         tHit = tt;
     }
     tt = Maths.SoftInv(ray.DY)*(box[Maths.BinarySign(ray.DY)+0x02]-ray.Y0);
     if(tt < tHit) {
         tHit = tt;
     }
     tt = Maths.SoftInv(ray.DZ)*(box[Maths.BinarySign(ray.DZ)+0x04]-ray.Z0);
     if(tt < tHit) {
         tHit = tt;
     }
     RenderItem ri = null;
     this.root.Hit(ray, inter2, inter, ref t, ref tHit, ref ri);
     return ri;
 }
コード例 #2
0
ファイル: OctTreeAccelerator.cs プロジェクト: KommuSoft/MoRen
		public RenderItem CalculateHit (Ray ray, out double tHit, double maxT) {
			Point3 inter = new Point3(ray.Offset);
			double t = 0.0d;
			tHit = maxT;
			if(x0 > inter.X || inter.X > x1 || y0 > inter.Y || inter.Y > y1 || z0 > inter.Z || inter.Z > z1) {
				Utils.CalculateBoxHitpoint(ray, inter, out t, this.x0, this.x1, this.y0, this.y1, this.z0, this.z1);
				if(t >= tHit) {
					return null;
				}
			}
			RenderItem ri = null;
			double[] seqxyz = new double[] {
				Maths.SoftInv(ray.DX),
				Maths.SoftInv(ray.DY),
				Maths.SoftInv(ray.DZ),
				x0,
				x1,
				x1,
				y0,
				y1,
				y1,
				z0,
				z1,
				z1
			};
			int dpos = Maths.BinarySign(ray.DX)|(Maths.BinarySign(ray.DY)<<0x02)|(Maths.BinarySign(ray.DZ)<<0x04);
			proceedSubTree(ray, dpos, seqxyz, inter, ref ri, ref t, ref tHit, this.root);
			return ri;
		}
コード例 #3
0
ファイル: TestParameters.cs プロジェクト: KommuSoft/MoRen
 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);
     }
 }
コード例 #4
0
 public Color GetColorAt(Ray ray)
 {
     Point3 p = new Point3(0.5d*ray.DX+0.5d, 0.5d*ray.DY+0.5d, 0.0d);
     if(ray.Z0 >= 0.0d) {
         return this.positiveZ(p);
     }
     else {
         return this.negativeZ(p);
     }
 }
コード例 #5
0
ファイル: Face.cs プロジェクト: KommuSoft/MoRen
 public override double HitAt(Ray ray)
 {
     double t = (D-Normal.X*ray.X0-Normal.Y*ray.Y0-Normal.Z*ray.Z0)/(Normal.X*ray.DX+Normal.Y*ray.DY+Normal.Z*ray.DZ);
     if(t > 0.0d) {
         return t;
     }
     else {
         return double.PositiveInfinity;
     }
 }
コード例 #6
0
ファイル: Face.cs プロジェクト: KommuSoft/MoRen
 public override void Cast(Ray ray, CastResult cr)
 {
     double t = (D-Normal.X*ray.X0-Normal.Y*ray.Y0-Normal.Z*ray.Z0)/(Normal.X*ray.DX+Normal.Y*ray.DY+Normal.Z*ray.DZ);
     if(t > 0.0d) {
         cr.Copy(t, Normal, 0.0d, 0.0d);
     }
     else {
         cr.SetNull();
     }
 }
コード例 #7
0
ファイル: NaiveAccelerator.cs プロジェクト: KommuSoft/MoRen
 public RenderItem CalculateHit(Ray ray, out double t, double maxT)
 {
     RenderItem current = null;
     double hit;
     foreach(RenderItem ri in this.items) {
         hit = ri.HitAt(ray);
         if(hit < maxT) {
             current = ri;
             maxT = hit;
         }
     }
     t = maxT;
     return current;
 }
コード例 #8
0
ファイル: RayTracer.cs プロジェクト: KommuSoft/MoRen
 public RayTracer(IAccelerator acc, Light[] lights, EnvironmentSettings settings)
 {
     this.acc = acc;
     this.maxDepth = settings.RecursionDepth;
     this.rayCache = new Ray[maxDepth+0x01];
     for(int i = 0x00; i < this.maxDepth+0x01; i++) {
         this.rayCache[i] = new Ray(0.0d, 0.0d, 0.0d, 0.0d, 0.0d, 0.0d);
     }
     this.lights = lights;
     this.ambientColor = settings.AmbientColor.Color;
     this.EnvironmentMap = EnvironmentMaps.GetOrBlack(settings.EnvironmentMap);
     this.lightTest = settings.LightTest;
     this.sr = new Ray(new Point3(0.0d, 0.0d, 0.0d), dis);
     this.distanceUnit = settings.DistanceUnit;
 }
コード例 #9
0
ファイル: Scene.cs プロジェクト: tomswedlund/Renderer
 public bool Intersect(Point frontEnd, Point backEnd)
 {
     Vector segment = frontEnd - backEnd;
     float actualT = segment.Magnitude();
     Normal normSeg = segment.Normalize();
     Point perturbBack = Math.Utils.Perturb(backEnd, normSeg);
     Ray ray = new Ray(perturbBack, normSeg);
     Intersection tempInt = null;
     if (this.Intersect(ray, out tempInt))
     {
         float newT = (tempInt.Point - backEnd).Magnitude();
         return Math.Utils.LessThan(newT, actualT);
     }
     return false;
 }
コード例 #10
0
ファイル: Sphere.cs プロジェクト: KommuSoft/MoRen
 public override void Cast(Ray ray, CastResult cr)
 {
     double x0 = ray.X0-Center.X;
     double y0 = ray.Y0-Center.Y;
     double z0 = ray.Z0-Center.Z;
     double dx = ray.DX;
     double dy = ray.DY;
     double dz = ray.DZ;
     double b_2 = dx*x0+dy*y0+dz*z0;
     double c = x0*x0+y0*y0+z0*z0-Radius*Radius;
     double D_4 = b_2*b_2-c;
     D_4 = Math.Sqrt(D_4);
     double t = Maths.MinGeqZero(-D_4-b_2, D_4-b_2);
     double normx = Rinv*(x0+t*dx);
     double normy = Rinv*(y0+t*dy);
     double normz = Rinv*(z0+t*dz);
     double phi = Math.Atan2(normx, -normz);
     double tu = 0.5d*phi/Math.PI+0.5d;
     double tv = 0.5d-Math.Asin(normy)/Math.PI;
     cr.Copy(t, normx, normy, normz, tu, tv, 0.0d, new Point3(-normz, normy, normx), new Point3(-normy, normx, normz));
 }
コード例 #11
0
ファイル: Scene.cs プロジェクト: tomswedlund/Renderer
 public bool Intersect(Ray ray, out Intersection intersection)
 {
     intersection = null;
     float minT = float.MaxValue;
     bool foundIntersection = false;
     foreach (IShape thisShape in this.Shapes)
     {
         Intersection tempInt = null;
         float tempT = 0;
         if (thisShape.Intersect(ray, out tempInt, out tempT))
         {
             if (tempT < minT)
             {
                 intersection = tempInt;
                 minT = tempT;
             }
             foundIntersection = true;
         }
     }
     return foundIntersection;
 }
コード例 #12
0
 public Color GetColorAt(Ray ray)
 {
     double ux = Math.Abs(ray.DX), uy = Math.Abs(ray.DY), uz = Math.Abs(ray.DZ);
     Point3 p = new Point3();
     switch(Maths.MaxIndex(ux, uy, uz)) {
         case 0x00://left-right
             ux = 1.0d/ux;
             p.Y = 0.5d-0.5d*ray.DY*ux;
             if(ray.DX < 0x00) {//left
                 p.X = 0.5d+0.5d*ray.DZ*ux;
                 return left(p);
             }
             else {//right
                 p.X = 0.5d-0.5d*ray.DZ*ux;
                 return right(p);
             }
         case 0x01://down-up
             uy = 1.0d/uy;
             p.X = 0.5d+0.5d*ray.DX*uy;
             if(ray.DY < 0x00) {//down
                 p.Y = 0.5d-0.5d*ray.DZ*uy;
                 return down(p);
             }
             else {//up
                 p.Y = 0.5d+0.5d*ray.DZ*uy;
                 return up(p);
             }
         default ://front-back
             uz = 1.0d/uz;
             p.Y = 0.5d-0.5d*ray.DY*uz;
             if(ray.DZ < 0x00) {//front
                 p.X = 0.5d-0.5d*ray.DX*uz;
                 return front(p);
             }
             else {//back
                 p.X = 0.5d+0.5d*ray.DX*uz;
                 return back(p);
             }
     }
 }
コード例 #13
0
 public Color GetColorAt(Ray ray)
 {
     double ux = Math.Abs(ray.DX), uy = Math.Abs(ray.DY), uz = Math.Abs(ray.DZ);
     Point3 p = new Point3();
     switch(Maths.MaxIndex(ux, uy, uz)) {
         case 0x00://left-right
             ux = 1.0d/ux;
             p.Y = 0.5d-0.5d*ray.DY*ux/3.0d;
             if(ray.DX < 0x00) {//left
                 p.X = 0.125d+0.125d*ray.DZ*ux;
             }
             else {//right
                 p.X = 0.625d-0.125d*ray.DZ*ux;
             }
             break;
         case 0x01://down-up
             uy = 1.0d/uy;
             p.X = 0.375d+0.125d*ray.DX*uy;
             if(ray.DY < 0x00) {//down
                 p.Y = (2.5d-0.5d*ray.DZ*uy)/3;
             }
             else {//up
                 p.Y = (0.5d+0.5d*ray.DZ*uy)/3;
             }
             break;
         default ://front-back
             uz = 1.0d/uz;
             p.Y = 0.5d-0.5d*ray.DY*uz/3.0d;
             if(ray.DZ < 0x00) {//front
                 p.X = 0.875d-0.125d*ray.DX*uz;
             }
             else {//back
                 p.X = 0.375d+0.125d*ray.DX*uz;
             }
             break;
     }
     return cross(p);
 }
コード例 #14
0
ファイル: Camera.cs プロジェクト: KommuSoft/MoRen
		private void CalculateImage (int yfrom, int yto) {
			double sd = this.screenDistance;
			double sh = 2.0d*sd*Math.Tan(0.5d*this.foVH);
			int w = this.Width;
			int h = this.Height;
			double sw = sh*w/h;
			double dwh = sw/w;
			Ray ray = new Ray(0.0d, 0.0d, 0.0d, 0.0d, 0.0d, 1.0d);
			uint[] pixel = this.raster.Pixel;
			int k = Width*yfrom, ks = Width*yto, kc;
			uint l, m;
			uint aasqrt = this.antialiasSqrt;
			uint aadsqrt = this.dispersionAntialiasSqrt;
			RayTracer rt = new RayTracer(this.acc, this.Lights, settings);
			uint aa = aasqrt*aasqrt, aac, aad = aadsqrt*aadsqrt, aadc;
			Point3 tmp = new Point3(0.0d, 0.0d, 0.0d);
			double focusLength = Point3.DiffLength(this.position, this.lookAt);
			double frac = 1.0d+focusLength/this.screenDistance;
			uint aaaad = aa*aad;
			double dwha = dwh/aasqrt;
			double dwhad = dispersion*dwh;
			double yp = dwh*yfrom-0.5d*sh-0.5d*dwha*aasqrt, xp;
			double yd, xd;
			double dis = this.displacement;
			ColorCache cc;
			#region PIXEL
			for(; k < ks;) {
				kc = k+Width;
				xp = -0.5d*sw-0.5d*dwha*aasqrt-dis;
				for(; k < kc;) {
					l = 0x00;
					cc = new ColorCache(0x00);
					#region ANTIALIASING
					for(; l < aa;) {
						aac = l+aasqrt;
						for(; l < aac; l++) {
							m = 0x00;
							tmp.SetValues(xp*frac, -yp*frac, focusLength);
							yd = -0.5d*dwhad*(aadsqrt-0x01);
							#region DISPERSION
							for(; m < aad;) {
								xd = -0.5d*dwhad*(aadsqrt-0x01);
								aadc = m+aadsqrt;
								for(; m < aadc; m++) {
									ray.Offset.SetValues(xp+xd, -yp-yd, 0.0d);
									ray.Direction.SetValues(ray.Offset, tmp);
									ray.Direction.Normalize();
									ray.NormalizeDirection();
									ray.Transform(this.matrix);
#if FAST_COLOR_INTERSECTION
									rt.CalculateColor(ray, 0, Color.White);
									cc.AddColor(new Color(ColorUtils.FromWavelength(350+5*(int)SystemDiagnostics.Intersections)));
									SystemDiagnostics.Intersections = 0x00;
#elif FAST_COLOR_MIGRATION
									rt.CalculateColor(ray, 0, Color.White);
									cc.AddColor(new Color(ColorUtils.FromWavelength(350+5*(int)SystemDiagnostics.Migrations)));
									SystemDiagnostics.Migrations = 0x00;
#else
									cc.AddColor(rt.CalculateColor(ray, 0, Color.White));
#endif
									xd += dwhad;
								}
								yd += dwhad;
							}
							#endregion
							xp += dwha;
						}
						yp += dwha;
						xp -= dwh;
					}
					#endregion
					yp -= dwh;
					xp += dwh;
					pixel[k++] = ColorUtils.AlphaChannel|cc.Mix(aaaad).RGB8;
				}
				#endregion
				yp += dwh;
			}
		}
コード例 #15
0
ファイル: Sphere.cs プロジェクト: KommuSoft/MoRen
 public override double HitAt(Ray ray)
 {
     double x0 = ray.X0-Center.X;
     double y0 = ray.Y0-Center.Y;
     double z0 = ray.Z0-Center.Z;
     double dx = ray.DX;
     double dy = ray.DY;
     double dz = ray.DZ;
     double b_2 = dx*x0+dy*y0+dz*z0;
     double c = x0*x0+y0*y0+z0*z0-Radius*Radius;
     double D_4 = b_2*b_2-c;
     if(D_4 >= 0.0d) {
         D_4 = Math.Sqrt(D_4);
         double t = Maths.MinGeqZero(-D_4-b_2, D_4-b_2);
         if(t > 0.0d) {
             return t;
         }
         else {
             return double.PositiveInfinity;
         }
     }
     else {
         return double.PositiveInfinity;
     }
 }
コード例 #16
0
ファイル: Triangle.cs プロジェクト: KommuSoft/MoRen
		public override void Cast (Ray ray, CastResult cr) {
			double j = ray.X0-p0.X;
			double k = ray.Y0-p0.Y;
			double l = ray.Z0-p0.Z;
			double dx01 = p1.X-p0.X;
			double dy01 = p1.Y-p0.Y;
			double dz01 = p1.Z-p0.Z;
			double dx02 = p2.X-p0.X;
			double dy02 = p2.Y-p0.Y;
			double dz02 = p2.Z-p0.Z;
			double M = 1.0d/(dx01*(ray.DY*dz02-dy02*ray.DZ)+dx02*(dy01*ray.DZ-ray.DY*dz01)+ray.DX*(dy02*dz01-dy01*dz02));
			double beta = (dx02*(ray.DZ*k-ray.DY*l)+ray.DX*(dy02*l-dz02*k)+(ray.DY*dz02-dy02*ray.DZ)*j)*M;
			double gamma = -(dx01*(ray.DZ*k-ray.DY*l)+ray.DX*(dy01*l-dz01*k)+(ray.DY*dz01-dy01*ray.DZ)*j)*M;
			double t = -(dx01*(dz02*k-dy02*l)+dx02*(dy01*l-dz01*k)+(dy02*dz01-dy01*dz02)*j)*M;
			double alpha = 1.0d-beta-gamma;
			cr.Copy(t,
			        alpha*n0.X+beta*n1.X+gamma*n2.X,
			        alpha*n0.Y+beta*n1.Y+gamma*n2.Y,
			        alpha*n0.Z+beta*n1.Z+gamma*n2.Z,
			        alpha*t0.X+beta*t1.X+gamma*t2.X,
			        alpha*t0.Y+beta*t1.Y+gamma*t2.Y,
			        alpha*t0.Z+beta*t1.Z+gamma*t2.Z,
			        this.bumpx,
			        this.bumpy);
			cr.NormalizeNormal();
		}
コード例 #17
0
ファイル: Triangle.cs プロジェクト: KommuSoft/MoRen
		public override double HitAt (Ray ray) {
#if FAST_COLOR_INTERSECTION
			SystemDiagnostics.Intersections++;
#endif
			double j = ray.X0-p0.X;
			double k = ray.Y0-p0.Y;
			double l = ray.Z0-p0.Z;
			double dx01 = p1.X-p0.X;
			double dy01 = p1.Y-p0.Y;
			double dz01 = p1.Z-p0.Z;
			double dx02 = p2.X-p0.X;
			double dy02 = p2.Y-p0.Y;
			double dz02 = p2.Z-p0.Z;
			double M = 1.0d/(dx01*(ray.DY*dz02-dy02*ray.DZ)+dx02*(dy01*ray.DZ-ray.DY*dz01)+ray.DX*(dy02*dz01-dy01*dz02));
			double beta = (dx02*(ray.DZ*k-ray.DY*l)+ray.DX*(dy02*l-dz02*k)+(ray.DY*dz02-dy02*ray.DZ)*j)*M;
			if(beta < 0.0d) {
				return double.PositiveInfinity;
			}
			double gamma = -(dx01*(ray.DZ*k-ray.DY*l)+ray.DX*(dy01*l-dz01*k)+(ray.DY*dz01-dy01*ray.DZ)*j)*M;
			if(gamma < 0.0d || beta+gamma >= 1.0d) {
				return double.PositiveInfinity;
			}
			double t = -(dx01*(dz02*k-dy02*l)+dx02*(dy01*l-dz01*k)+(dy02*dz01-dy01*dz02)*j)*M;
			if(t <= 0.0d) {
				return double.PositiveInfinity;
			}
			else {
				return t;
			}
		}
コード例 #18
0
ファイル: BSPAccelerator.cs プロジェクト: KommuSoft/MoRen
		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;
			}
		}
コード例 #19
0
ファイル: BSPAccelerator.cs プロジェクト: KommuSoft/MoRen
			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;
						}
					}
				}
			}
コード例 #20
0
ファイル: Ray.cs プロジェクト: KommuSoft/MoRen
 public Ray(Ray ray)
     : this(ray.X0,ray.Y0,ray.Z0,ray.DX,ray.DY,ray.DZ)
 {
 }
コード例 #21
0
ファイル: Ray.cs プロジェクト: KommuSoft/MoRen
 public static Ray Random()
 {
     Ray ray = new Ray(Maths.Random(), Maths.Random(), Maths.Random(), Maths.Random(), Maths.Random(), Maths.Random());
     ray.NormalizeDirection();
     return ray;
 }
コード例 #22
0
ファイル: RenderItem.cs プロジェクト: KommuSoft/MoRen
 public abstract void Cast(Ray ray, CastResult cr);
コード例 #23
0
ファイル: RenderItem.cs プロジェクト: KommuSoft/MoRen
 /// <summary>
 /// Calculates the T-value at which the given ray will hit the object. If the ray doesn't hit the object <see cref="Double.PositiveInfinity"/>
 /// is returned.
 /// </summary>
 /// <param name="ray">
 /// The given ray that intersects with the object.
 /// </param>
 /// <returns>
 /// The T-value of the ray at the point where the given ray hits the object or <see cref="Double.PositiveInfinity"/> if the ray doesn't hit the object.
 /// </returns>
 public abstract double HitAt(Ray ray);
コード例 #24
0
ファイル: OctTreeAccelerator.cs プロジェクト: KommuSoft/MoRen
		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);
			}
		}
コード例 #25
0
ファイル: RayTracer.cs プロジェクト: KommuSoft/MoRen
 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);
     }
 }
コード例 #26
0
 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;
             }
         }
     }
 }
コード例 #27
0
ファイル: BoundingBox.cs プロジェクト: KommuSoft/MoRen
 public double FirstT(Ray ray)
 {
     double x = ray.X0;
     double y = ray.X0;
     double z = ray.X0;
     double x0 = this.xyz0.X;
     double y0 = this.xyz0.Y;
     double z0 = this.xyz0.Z;
     double x1 = this.xyz1.X;
     double y1 = this.xyz1.Y;
     double z1 = this.xyz1.Z;
     double dxinv = Maths.SoftInv(ray.DX);
     double dyinv = Maths.SoftInv(ray.DY);
     double dzinv = Maths.SoftInv(ray.DZ);
     double t;
     if(x < x0) {
         if(double.IsNaN(dxinv) || dxinv < 0.0d) {//moving away from the box or neutral
             return double.PositiveInfinity;
         }
         else {
             //TODO: finish
             return double.NaN;
         }
     }
     else if(x > x0) {
         if(double.IsNaN(dxinv) || dyinv > 0.0d) {//moving away from the box or neutral
             return double.PositiveInfinity;
         }
         else {
             //TODO: finish
             return double.NaN;
         }
     }
     else {//x was between x0 and x1 the whole time
         if(y0 <= y && y <= y1 && z0 <= z && z <= z1) {//we were already in the box
             return 0.0d;
         }
         else {
             //TODO: finish
             return double.NaN;
         }
     }
 }