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; }
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; }
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 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); } }
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; } }
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(); } }
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; }
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; }
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; }
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)); }
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; }
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); } } }
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); }
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; } }
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; } }
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(); }
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; } }
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; } }
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 Ray(Ray ray) : this(ray.X0,ray.Y0,ray.Z0,ray.DX,ray.DY,ray.DZ) { }
public static Ray Random() { Ray ray = new Ray(Maths.Random(), Maths.Random(), Maths.Random(), Maths.Random(), Maths.Random(), Maths.Random()); ray.NormalizeDirection(); return ray; }
public abstract void Cast(Ray ray, CastResult cr);
/// <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);
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); } }
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; } } } }
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; } } }