public override bool Hit(Ray ray, ref double tmin, ShadeRec sr) { Ray invRay = new Ray(MathUtils.TransformPoint(invMatrix, ray.O), MathUtils.TransformDirection(invMatrix, ray.D)); if (obj.Hit(invRay, ref tmin, sr)) { sr.Normal = MathUtils.TransformNormal(invMatrix, sr.Normal); if (obj.Material != null) { material = obj.Material; } if (!transformTheTexture) { sr.LocalHitPoint = ray.HitPoint(tmin); } return(true); } return(false); }
public override bool Hit(Ray ray, ref double tmin, ShadeRec sr) { if (!bbox.Hit(ray)) { return(false); } double ox = ray.O.X; double oy = ray.O.Y; double oz = ray.O.Z; double dx = ray.D.X; double dy = ray.D.Y; double dz = ray.D.Z; double x0 = bbox.x0; double y0 = bbox.y0; double z0 = bbox.z0; double x1 = bbox.x1; double y1 = bbox.y1; double z1 = bbox.z1; double txMin = 0, tyMin = 0, tzMin = 0; double txMax = 0, tyMax = 0, tzMax = 0; double a = 1.0 / dx; if (a >= 0) { txMin = (x0 - ox) * a; txMax = (x1 - ox) * a; } else { txMin = (x1 - ox) * a; txMax = (x0 - ox) * a; } double b = 1.0 / dy; if (b >= 0) { tyMin = (y0 - oy) * b; tyMax = (y1 - oy) * b; } else { tyMin = (y1 - oy) * b; tyMax = (y0 - oy) * b; } double c = 1.0 / dz; if (c >= 0) { tzMin = (z0 - oz) * c; tzMax = (z1 - oz) * c; } else { tzMin = (z1 - oz) * c; tzMax = (z0 - oz) * c; } double t0, t1; if (txMin > tyMin) { t0 = txMin; } else { t0 = tyMin; } if (tzMin > t0) { t0 = tzMin; } if (txMax < tyMax) { t1 = txMax; } else { t1 = tyMax; } if (tzMax < t1) { t1 = tzMax; } if (t0 > t1) { return(false); } int ix, iy, iz; if (bbox.Inside(ray.O)) { ix = (int)MathUtils.Clamp((ox - x0) * nx / (x1 - x0), 0, nx - 1); iy = (int)MathUtils.Clamp((oy - y0) * ny / (y1 - y0), 0, ny - 1); iz = (int)MathUtils.Clamp((oz - z0) * nz / (z1 - z0), 0, nz - 1); } else { Vec3 p = ray.HitPoint(t0); ix = (int)MathUtils.Clamp((p.X - x0) * nx / (x1 - x0), 0, nx - 1); iy = (int)MathUtils.Clamp((p.Y - y0) * ny / (y1 - y0), 0, ny - 1); iz = (int)MathUtils.Clamp((p.Z - z0) * nz / (z1 - z0), 0, nz - 1); } double dtx = (txMax - txMin) / nx; double dty = (tyMax - tyMin) / ny; double dtz = (tzMax - tzMin) / nz; double txNext, tyNext, tzNext; int ixStep, iyStep, izStep; int ixStop, iyStop, izStop; if (dx > 0) { txNext = txMin + (ix + 1) * dtx; ixStep = +1; ixStop = nx; } else { txNext = txMin + (nx - ix) * dtx; ixStep = -1; ixStop = -1; } if (dx == 0.0) { txNext = MathUtils.HugeValue; ixStep = -1; ixStop = -1; } if (dy > 0) { tyNext = tyMin + (iy + 1) * dty; iyStep = +1; iyStop = ny; } else { tyNext = tyMin + (ny - iy) * dty; iyStep = -1; iyStop = -1; } if (dy == 0.0) { tyNext = MathUtils.HugeValue; iyStep = -1; iyStop = -1; } if (dz > 0) { tzNext = tzMin + (iz + 1) * dtz; izStep = +1; izStop = nz; } else { tzNext = tzMin + (nz - iz) * dtz; izStep = -1; izStop = -1; } if (dz == 0.0) { tzNext = MathUtils.HugeValue; izStep = -1; izStop = -1; } while (true) { GeometricObject obj = cells[ix + nx * iy + nx * ny * iz]; if (txNext < tyNext && txNext < tzNext) { if (obj != null && obj.Hit(ray, ref tmin, sr) && tmin < txNext) { material = obj.Material; return(true); } txNext += dtx; ix += ixStep; if (ix == ixStop) { return(false); } } else { if (tyNext < tzNext) { if (obj != null && obj.Hit(ray, ref tmin, sr) && tmin < tyNext) { material = obj.Material; return(true); } tyNext += dty; iy += iyStep; if (iy == iyStop) { return(false); } } else { if (obj != null && obj.Hit(ray, ref tmin, sr) && tmin < tzNext) { material = obj.Material; return(true); } tzNext += dtz; iz += izStep; if (iz == izStop) { return(false); } } } } }
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); } } } } }