public override bool Hit(Ray ray, ref float t, ref ShadeRec sr) { float ox = ray.Position.X; float oy = ray.Position.Y; float oz = ray.Position.Z; float dx = ray.Direction.X; float dy = ray.Direction.Y; float dz = ray.Direction.Z; float x0 = bbox.Min.X; float y0 = bbox.Min.Y; float z0 = bbox.Min.Z; float x1 = bbox.Max.X; float y1 = bbox.Max.Y; float z1 = bbox.Max.Z; float tx_min, ty_min, tz_min; float tx_max, ty_max, tz_max; float a = 1.0f / dx; if (a >= 0) { tx_min = (x0 - ox) * a; tx_max = (x1 - ox) * a; } else { tx_min = (x1 - ox) * a; tx_max = (x0 - ox) * a; } float b = 1.0f / dy; if (b >= 0) { ty_min = (y0 - oy) * b; ty_max = (y1 - oy) * b; } else { ty_min = (y1 - oy) * b; ty_max = (y0 - oy) * b; } float c = 1.0f / dz; if (c >= 0) { tz_min = (z0 - oz) * c; tz_max = (z1 - oz) * c; } else { tz_min = (z1 - oz) * c; tz_max = (z0 - oz) * c; } float t0, t1; if (tx_min > ty_min) { t0 = tx_min; } else { t0 = ty_min; } if (tz_min > t0) { t0 = tz_min; } if (tx_max < ty_max) { t1 = tx_max; } else { t1 = ty_max; } if (tz_max < t1) { t1 = tz_max; } if (t0 > t1) { return(false); } else { Console.WriteLine("wtf"); } int ix, iy, iz; if (bbox.Inside(ray.Position)) { // does the ray start inside the grid? ix = clamp((ox - x0) * nx / (x1 - x0), 0, nx - 1); iy = clamp((oy - y0) * ny / (y1 - y0), 0, ny - 1); iz = clamp((oz - z0) * nz / (z1 - z0), 0, nz - 1); } else { Vector3 p = ray.Position + t0 * ray.Direction; // initial hit point with grid's bounding box ix = clamp((p.X - x0) * nx / (x1 - x0), 0, nx - 1); iy = clamp((p.Y - y0) * ny / (y1 - y0), 0, ny - 1); iz = clamp((p.Z - z0) * nz / (z1 - z0), 0, nz - 1); } float dtx = (tx_max - tx_min) / nx; float dty = (ty_max - ty_min) / ny; float dtz = (tz_max - tz_min) / nz; float tx_next, ty_next, tz_next; int ix_step, iy_step, iz_step; int ix_stop, iy_stop, iz_stop; if (dx > 0) { tx_next = tx_min + (ix + 1) * dtx; ix_step = +1; ix_stop = nx; } else { tx_next = tx_min + (nx - ix) * dtx; ix_step = -1; ix_stop = -1; } if (dx == 0.0) { tx_next = float.MaxValue; ix_step = -1; ix_stop = -1; } if (dy > 0) { ty_next = ty_min + (iy + 1) * dty; iy_step = +1; iy_stop = ny; } else { ty_next = ty_min + (ny - iy) * dty; iy_step = -1; iy_stop = -1; } if (dy == 0.0) { ty_next = float.MaxValue; iy_step = -1; iy_stop = -1; } if (dz > 0) { tz_next = tz_min + (iz + 1) * dtz; iz_step = +1; iz_stop = nz; } else { tz_next = tz_min + (nz - iz) * dtz; iz_step = -1; iz_stop = -1; } if (dz == 0.0) { tz_next = float.MaxValue; iz_step = -1; iz_stop = -1; } while (true) { GeometricObject object_ptr = cells[ix + nx * iy + nx * ny * iz]; if (tx_next < ty_next && tx_next < tz_next) { if (object_ptr != null && object_ptr.Hit(ray, ref t, ref sr) && t < tx_next) { Material = object_ptr.GetMaterial(); return(true); } tx_next += dtx; ix += ix_step; if (ix == ix_stop) { return(false); } } else { if (ty_next < tz_next) { if (object_ptr != null && object_ptr.Hit(ray, ref t, ref sr) && t < ty_next) { Material = object_ptr.GetMaterial(); return(true); } ty_next += dty; iy += iy_step; if (iy == iy_stop) { return(false); } } else { if (object_ptr != null && object_ptr.Hit(ray, ref t, ref sr) && t < tz_next) { Material = object_ptr.GetMaterial(); return(true); } tz_next += dtz; iz += iz_step; if (iz == iz_stop) { return(false); } } } } }
public void SetObject(GeometricObject obj) { Object = obj; Material = Object.GetMaterial(); }