private GeometricObject FindClosestShape(Ray r, Light l, GeometricObject theShape) { double dist = float.MaxValue; GeometricObject closest = null; foreach (GeometricObject shape in Shapes) { double t; if (shape is Cube) { Tuple<double, Triangle> temp = shape.intersectionCube(r); t = temp.Item1; } else { t = shape.intersection(r); } if (theShape != shape && t < dist && t > 0.0f && shape.surface.RefractionIndex < 1) { closest = shape; dist = t; } } foreach (Light light in Lights) { if (light != l) continue; double t = light.intersection(r); if (light.intersection(r) < dist) { closest = light; dist = t; } } return closest; }
private float isVisible(Light L, Vector3 hitPoint, Ray ray, GeometricObject theShape = null) { float retVal = 0.0f; float offset = 5; float numSegments = 1; float numAlongSegment = 1; Vector3 dir; Ray r; for (float i = 0; i <= 2 * Math.PI; i += 2.0f * (float)Math.PI / (numSegments)) { for (float j = 1; j <= numAlongSegment; j++) { dir = L.position + new Vector3((float)Math.Cos(i) * L.radius / j + offset * (Math.Cos(i) < 0 ? 1 : -1), (float)Math.Sin(i) * L.radius / j + offset * (Math.Sin(i) < 0 ? 1 : -1), 0); dir = dir - ray.Start; dir.Normalize(); r = new Ray(ray.Start, dir); if (FindClosestShape(r, L, theShape) == L) retVal += 1.0f / (numSegments * numAlongSegment); } } return Clamp(retVal, 0, 1); }