public Option <RayHitpoint> TryHit(PositionableSphere positionableSphere, Ray ray, RayParameter bottomBoundary, RayParameter topBoundary) { var(positionable, sphere) = positionableSphere; var originToCenter = ray.Origin - positionable.Translation; var a = Vector3.Dot(ray.Direction, ray.Direction); var b = 2.0f * Vector3.Dot(originToCenter, ray.Direction); var c = Vector3.Dot(originToCenter, originToCenter) - sphere.Radius * sphere.Radius; var discriminant = b * b - 4 * a * c; if (discriminant < 0) { return(Option <RayHitpoint> .Empty); } var temp = new RayParameter((-b - (float)Math.Sqrt(discriminant)) / (2.0f * a)); if (temp < topBoundary.Value && temp > bottomBoundary.Value) { var hitPoint = ray.PointAt(temp); var normal = GetNormalAtPoint(hitPoint, positionableSphere); return(new Option <RayHitpoint>(new RayHitpoint(hitPoint, normal, temp))); } temp = new RayParameter((-b + (float)Math.Sqrt(discriminant)) / (2.0f * a)); if (temp < topBoundary.Value && temp > bottomBoundary.Value) { var hitPoint = ray.PointAt(temp); var normal = GetNormalAtPoint(hitPoint, positionableSphere); return(new Option <RayHitpoint>(new RayHitpoint(hitPoint, normal, temp))); } return(Option <RayHitpoint> .Empty); }
public bool Hit(Bounds bounds, Ray ray, RayParameter bottomBoundary, RayParameter topBoundary) { var tMin = bottomBoundary.Value; var tMax = topBoundary.Value; for (var i = 0; i < 3; ++i) { var invRayDir = 1 / ray.Direction.Enumerate(i); var t0 = (bounds.Minimum.Enumerate(i) - ray.Origin.Enumerate(i)) * invRayDir; var t1 = (bounds.Maximum.Enumerate(i) - ray.Origin.Enumerate(i)) * invRayDir; if (invRayDir < 0.0f) { Maths.Swap(ref t0, ref t1); } tMin = t0 > tMin ? t0 : tMin; tMax = t1 < tMax ? t1 : tMax; if (t0 > t1) { return(false); } } return(true); }
public Option <EntityRayHitpoint> TryHit(Ray ray, RayParameter bottomBoundary, RayParameter topBoundary) { if (!_hitableBoundsComputer.Hit(_bounds, ray, bottomBoundary, topBoundary)) { return(Option <EntityRayHitpoint> .Empty); } var leftHit = Left.TryHit(ray, bottomBoundary, topBoundary); var rightHit = Right.TryHit(ray, bottomBoundary, topBoundary); return(leftHit.HasValue switch { true when rightHit.HasValue => leftHit.Value.Hitpoint.T < rightHit.Value.Hitpoint.T ? leftHit : rightHit, true => leftHit, _ => rightHit.HasValue ? rightHit : Option <EntityRayHitpoint> .Empty });
private Color ThrowRay(Ray ray, RayParameter minParameter, RayParameter maxParameter, Color color, int depth) { var hitPoint = Scene.TryHit(ray, minParameter, maxParameter); if (hitPoint.HasValue) { // Scatter var rayScattered = Scene.Scatterables[hitPoint.Value.Id] .Scatter(ray, hitPoint.Value.Hitpoint, new Color(color.Value)); if (++depth > 50) { return(new Color(new Vector3(0.0f))); } return(ThrowRay(rayScattered.Scattered, minParameter, hitPoint.Value.Hitpoint.T, rayScattered.Color, depth)); } return(color); }
public Option <EntityRayHitpoint> TryHit(Ray ray, RayParameter bottomBoundary, RayParameter topBoundary) { var hasHit = false; var candidateParameter = topBoundary; var candidateHitpoint = new EntityRayHitpoint(); foreach (var(id, hitable) in _hitables) { var contact = hitable.TryHit(ray, bottomBoundary, topBoundary); if (contact.HasValue && contact.Value.T < candidateParameter) { candidateParameter = contact.Value.T; candidateHitpoint = new EntityRayHitpoint(id, contact); hasHit = true; } } return(hasHit ? new Option <EntityRayHitpoint>(candidateHitpoint) : Option <EntityRayHitpoint> .Empty); }
public bool Hit(Ray ray, RayParameter bottomBoundary, RayParameter topBoundary) { return(_computer.Hit(_bounds, ray, bottomBoundary, topBoundary)); }
public Option <EntityRayHitpoint> TryHit(Ray ray, RayParameter bottomBoundary, RayParameter topBoundary) { return(_hitableStructure.TryHit(ray, bottomBoundary, topBoundary)); }
public Option <RayHitpoint> TryHit(Ray ray, RayParameter bottomBoundary, RayParameter topBoundary) { return(_computer.TryHit(_sphere, ray, bottomBoundary, topBoundary)); }