def test_linear(self): sphere = Sphere(Vector3(0.0, 0.0, 0.0), 2.0, 0) mgr = ShapeManager() mgr.add('sph1', sphere) sphere2 = Sphere(Vector3(0.0, 2.0, 0.0), 3.0, 0) mgr.add('sph2', sphere2) isector = LinearIsect(mgr) runtimes = [Runtime()] direction = Vector3(-1.0, -1.0, -1.0) direction.normalize() ray = Ray(Vector3(5.0, 5.0, 5.0), direction) isector.compile() isector.prepare(runtimes) code = """ min_dist = 99999.0 p1 = isect_scene(ray, hitpoint, min_dist) """ direction = Vector3(-1.0, -1.0, -1.0) direction.normalize() ray = Ray(Vector3(5.0, 5.0, 5.0), direction) hitpoint = HitPoint(0.0, Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0), 6, 0.0, 0.0) r_arg = StructArg('ray', ray) harg = StructArg('hitpoint', hitpoint) p1 = IntArg('p1', 6) args = [r_arg, harg, p1] shader = Shader(code=code, args=args) shader.compile([isector.shader]) shader.prepare(runtimes) hp2 = isector.isect(ray) shader.execute() hitpoint = shader.get_value('hitpoint') self.assertAlmostEqual(hp2.t, hitpoint.t, places=5) self.assertEqual(hp2.mat_idx, hitpoint.mat_idx) n1 = hp2.normal n2 = hitpoint.normal self.assertAlmostEqual(n1.x, n2.x) self.assertAlmostEqual(n1.y, n2.y, places=6) self.assertAlmostEqual(n1.z, n2.z) self.assertAlmostEqual(hitpoint.hit.x, hp2.hit.x, places=6) self.assertAlmostEqual(hitpoint.hit.y, hp2.hit.y, places=6) self.assertAlmostEqual(hitpoint.hit.z, hp2.hit.z, places=6) result = shader.get_value('p1') self.assertEqual(result, 1)
def isect_b_shader(cls, shader_name): code = """ temp = ray.origin - sphere.origin r_dir = ray.direction a = dot(r_dir, r_dir) b = dot(temp, r_dir) * 2.0 c = dot(temp, temp) - sphere.radius * sphere.radius disc = b * b - 4.0 * a * c if disc < 0.0: return 0 e = sqrt(disc) denom = 2.0 * a t = (-1.0 * b - e) / denom if t > 0.0005: if t < min_dist: return 1 t = (-1.0 * b + e) / denom if t > 0.0005: if t < min_dist: return 1 return 0 """ func_args = [StructArgPtr('ray', Ray.factory()), StructArgPtr('sphere', Sphere.factory()), FloatArg('min_dist', 0.0)] shader = Shader(code=code, args=[], name=shader_name, func_args=func_args, is_func=True) return DependencyShader(shader)
def test_mesh_b(mesh, nrays=1): dep_shader = type(mesh).isect_b_shader('ray_flat_mesh_b_isect') dep_shader.compile() runtimes = [Runtime()] dep_shader.prepare(runtimes) code = """ min_dist = 99999.0 ret = ray_flat_mesh_b_isect(ray, mesh, min_dist) """ origin = calculate_origin(mesh) rpoint = random_in_bbox(mesh._grid.bbox) direction = rpoint - origin direction.normalize() ray = Ray(origin, direction) r_arg = StructArg('ray', ray) mesh_arg = StructArg('mesh', mesh) ret = IntArg('ret', 6) args = [r_arg, mesh_arg, ret] shader = Shader(code=code, args=args) shader.compile([dep_shader.shader]) shader.prepare(runtimes) hp = mesh.isect_b(ray) shader.execute() print("Bool isect", hp, shader.get_value('ret'))
def test_isect_b_sph(self): sph_shader = Sphere.isect_b_shader('isect_b_sphere') sph_shader.compile() runtimes = [Runtime()] sph_shader.prepare(runtimes) code = """ min_dist = 99999.0 p1 = isect_b_sphere(ray, sphere, min_dist) """ direction = Vector3(-1.0, -1.0, -1.0) direction.normalize() ray = Ray(Vector3(5.0, 5.0, 5.0), direction) sphere = Sphere(Vector3(0.0, 0.0, 0.0), 2.0, 0) r_arg = StructArg('ray', ray) sph_arg = StructArg('sphere', sphere) p1 = IntArg('p1', 6) args = [r_arg, sph_arg, p1] shader = Shader(code=code, args=args) shader.compile([sph_shader.shader]) shader.prepare(runtimes) shader.execute() result = shader.get_value('p1') self.assertEqual(result, 1)
def load(self, shader_name): args = [] text = self._loader.load(shader_name, 'props.txt') if text is not None: args = parse_args(text) w = Vec3Arg('w', self._w) u = Vec3Arg('u', self._u) v = Vec3Arg('v', self._v) distance = FloatArg('distance', self._distance) eye = Vec3Arg('eye', self._eye) lookat = Vec3Arg('lookat', self._lookat) args.extend([w, u, v, distance, eye, lookat]) code = self._loader.load(shader_name, 'code.py') if code is None: raise ValueError("code.py in %s shader dont exist!" % shader_name) func_args = [ StructArgPtr('ray', Ray.factory()), StructArgPtr('sample', Sample.factory()) ] self._shader_name = shader_name self.shader = Shader(code=code, args=args, name='generate_ray', func_args=func_args, is_func=True)
def test_isect_b_rect(self): rect_shader = Rectangle.isect_b_shader('isect_b_rectangle') rect_shader.compile() runtimes = [Runtime()] rect_shader.prepare(runtimes) code = """ min_dist = 99999.0 p1 = isect_b_rectangle(ray, rectangle, min_dist) """ origin = Vector3(3.0, 2.5, 0.0) direction = Vector3(0.0, 0.1, 0.88) direction.normalize() ray = Ray(origin, direction) point = Vector3(0.0, 0.0, 55.92) e1 = Vector3(55.28, 0.0, 0.0) e2 = Vector3(0.0, 54.88, 0.0) normal = Vector3(0.0, 0.0, -1.0) rectangle = Rectangle(point, e1, e2, normal) r_arg = StructArg('ray', ray) sph_arg = StructArg('rectangle', rectangle) p1 = IntArg('p1', 6) args = [r_arg, sph_arg, p1] shader = Shader(code=code, args=args) shader.compile([rect_shader.shader]) shader.prepare(runtimes) shader.execute() result = shader.get_value('p1') self.assertEqual(result, 1)
def generate_ray(mesh): origin = calculate_origin(mesh) rpoint = random_in_bbox(mesh._grid.bbox) direction = rpoint - origin direction.normalize() ray = Ray(origin, direction) return ray
def generate_ray(self, sample): self._standalone.set_value('sample', sample) self._standalone.execute() origin = self._standalone.get_value('origin') direction = self._standalone.get_value('direction') ray = Ray(origin, direction) return ray
def generate_pinhole_ray(self, camera, sample): direction = camera._u * sample.x + camera._v *\ sample.y - camera._w * camera._distance direction.normalize() eye = camera._eye origin = Vector3(eye.x, eye.y, eye.z) return Ray(origin, direction)
def isect_shader(cls, shader_name): code = """ temp = ray.origin - sphere.origin r_dir = ray.direction a = dot(r_dir, r_dir) b = dot(temp, r_dir) * 2.0 c = dot(temp, temp) - sphere.radius * sphere.radius disc = b * b - 4.0 * a * c if disc < 0.0: return 0 e = sqrt(disc) denom = 2.0 * a t = (-1.0 * b - e) / denom if t > 0.0005: if t < min_dist: normal = (temp + r_dir * t) * (1.0 / sphere.radius) hit = ray.origin + r_dir * t hitpoint.t = t hitpoint.normal = normal hitpoint.hit = hit hitpoint.mat_idx = sphere.mat_idx hitpoint.light_id = sphere.light_id hitpoint.u = 0.0 hitpoint.v = 0.0 return 1 t = (-1.0 * b + e) / denom if t > 0.0005: if t < min_dist: normal = (temp + r_dir * t) * (1.0 / sphere.radius) hit = ray.origin + r_dir * t hitpoint.t = t hitpoint.normal = normal hitpoint.hit = hit hitpoint.mat_idx = sphere.mat_idx hitpoint.light_id = sphere.light_id hitpoint.u = 0.0 hitpoint.v = 0.0 return 1 return 0 """ func_args = [ StructArgPtr('ray', Ray.factory()), StructArgPtr('sphere', Sphere.factory()), StructArgPtr('hitpoint', HitPoint.factory()), FloatArg('min_dist', 0.0) ] shader = Shader(code=code, args=[], name=shader_name, func_args=func_args, is_func=True) return DependencyShader(shader)
def isect_shader(cls, shader_name): code = """ temp1 = dot(ray.direction, rectangle.normal) if temp1 == 0.0: return 0 tmp = rectangle.point - ray.origin t = dot(tmp, rectangle.normal) / temp1 if t < 0.00001: return 0 if t > min_dist: return 0 p = ray.origin + ray.direction * t d = p - rectangle.point ddota = dot(d, rectangle.edge_a) if ddota < 0.0: return 0 if ddota > rectangle.edge_a_squared: return 0 ddotb = dot(d, rectangle.edge_b) if ddotb < 0.0: return 0 if ddotb > rectangle.edge_b_squared: return 0 hitpoint.t = t hitpoint.normal = rectangle.normal hitpoint.hit = p hitpoint.mat_idx = rectangle.mat_idx hitpoint.light_id = rectangle.light_id hitpoint.u = 0.0 hitpoint.v = 0.0 return 1 """ func_args = [ StructArgPtr('ray', Ray.factory()), StructArgPtr('rectangle', Rectangle.factory()), StructArgPtr('hitpoint', HitPoint.factory()), FloatArg('min_dist', 0.0) ] shader = Shader(code=code, args=[], name=shader_name, func_args=func_args, is_func=True) return DependencyShader(shader)
def test_isect_rect(self): rect_shader = Rectangle.isect_shader('isect_rectangle') rect_shader.compile() runtimes = [Runtime()] rect_shader.prepare(runtimes) code = """ min_dist = 99999.0 p1 = isect_rectangle(ray, rectangle, hitpoint, min_dist) """ origin = Vector3(3.0, 2.5, 0.0) direction = Vector3(0.0, 0.1, 0.88) direction.normalize() ray = Ray(origin, direction) point = Vector3(0.0, 0.0, 55.92) e1 = Vector3(55.28, 0.0, 0.0) e2 = Vector3(0.0, 54.88, 0.0) normal = Vector3(0.0, 0.0, -1.0) rectangle = Rectangle(point, e1, e2, normal) hitpoint = HitPoint.factory() hitpoint.mat_idx = 5 r_arg = StructArg('ray', ray) sph_arg = StructArg('rectangle', rectangle) harg = StructArg('hitpoint', hitpoint) p1 = IntArg('p1', 6) args = [r_arg, sph_arg, harg, p1] shader = Shader(code=code, args=args) shader.compile([rect_shader.shader]) shader.prepare(runtimes) shader.execute() hp2 = rectangle.isect(ray) hitpoint = shader.get_value('hitpoint') self.assertAlmostEqual(hp2.t, hitpoint.t, places=5) self.assertEqual(hp2.mat_idx, hitpoint.mat_idx) n1 = hp2.normal n2 = hitpoint.normal self.assertAlmostEqual(n1.x, n2.x) self.assertAlmostEqual(n1.y, n2.y) self.assertAlmostEqual(n1.z, n2.z) self.assertAlmostEqual(hitpoint.hit.x, hp2.hit.x, places=5) self.assertAlmostEqual(hitpoint.hit.y, hp2.hit.y, places=5) self.assertAlmostEqual(hitpoint.hit.z, hp2.hit.z, places=5) result = shader.get_value('p1') self.assertEqual(result, 1)
def visibility(self, p1, p2): epsilon = 0.00001 direction = p2 - p1 distance = direction.length() - epsilon # self intersection!!! visiblity direction.normalize() ray = Ray(p1, direction) for shape in self.shp_mgr: hit = shape.isect_b(ray, distance) if hit: return False return True
def isect_shader(cls, shader_name): code = """ temp = ray.origin - sphere.origin r_dir = ray.direction a = dot(r_dir, r_dir) b = dot(temp, r_dir) * 2.0 c = dot(temp, temp) - sphere.radius * sphere.radius disc = b * b - 4.0 * a * c if disc < 0.0: return 0 e = sqrt(disc) denom = 2.0 * a t = (-1.0 * b - e) / denom if t > 0.0005: if t < min_dist: normal = (temp + r_dir * t) * (1.0 / sphere.radius) hit = ray.origin + r_dir * t hitpoint.t = t hitpoint.normal = normal hitpoint.hit = hit hitpoint.mat_idx = sphere.mat_idx hitpoint.light_id = sphere.light_id hitpoint.u = 0.0 hitpoint.v = 0.0 return 1 t = (-1.0 * b + e) / denom if t > 0.0005: if t < min_dist: normal = (temp + r_dir * t) * (1.0 / sphere.radius) hit = ray.origin + r_dir * t hitpoint.t = t hitpoint.normal = normal hitpoint.hit = hit hitpoint.mat_idx = sphere.mat_idx hitpoint.light_id = sphere.light_id hitpoint.u = 0.0 hitpoint.v = 0.0 return 1 return 0 """ func_args = [StructArgPtr('ray', Ray.factory()), StructArgPtr('sphere', Sphere.factory()), StructArgPtr('hitpoint', HitPoint.factory()), FloatArg('min_dist', 0.0)] shader = Shader(code=code, args=[], name=shader_name, func_args=func_args, is_func=True) return DependencyShader(shader)
def test_isect_flat_triangle1(self): runtimes = [Runtime()] tri_shader = FlatTriangle.isect_shader('isect_flat_triangle') tri_shader.compile() tri_shader.prepare(runtimes) p0 = Vector3(-0.0831229984, 0.0591476, -0.03213749) p1 = Vector3(-0.082775, 0.059025, -0.031787) p2 = Vector3(-0.0831229, 0.0591773, -0.031787) origin = Vector3(-0.21276909825205803, -0.021492251798510553, -0.09822520208358765) direction = Vector3(0.7788769269741005, 0.4843782624535974, 0.3984073687694737) ray = Ray(origin, direction) hitpoint = HitPoint(0.0, Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0), 6, 0.0, 0.0) t = FlatTriangle(p0, p1, p2) code = """ min_dist = 150.0 ret = isect_flat_triangle(ray, triangle, hitpoint, min_dist) """ r_arg = StructArg('ray', ray) tri_arg = StructArg('triangle', t) harg = StructArg('hitpoint', hitpoint) ret = IntArg('ret', 6) args = [r_arg, tri_arg, harg, ret] shader = Shader(code=code, args=args) shader.compile([tri_shader.shader]) shader.prepare(runtimes) shader.execute() min_dist = 150.0 hit = t.isect(ray, min_dist) hp = shader.get_value('hitpoint') self.assertAlmostEqual(hit.t, hp.t, places=6) self._almost_equal_vec3(hit.hit, hp.hit, places=6) self._almost_equal_vec3(hit.normal, hp.normal, places=6) self.assertEqual(hit.mat_idx, hp.mat_idx) self.assertAlmostEqual(hit.u, hp.u) self.assertAlmostEqual(hit.v, hp.v)
def test_isect_flat_triangle(self): runtimes = [Runtime()] tri_shader = FlatTriangle.isect_shader('isect_flat_triangle') tri_shader.compile() tri_shader.prepare(runtimes) p0 = Vector3(2.2, 4.4, 6.6) p1 = Vector3(1.1, 1.1, 1.1) p2 = Vector3(5.1, -1.1, 5.1) origin = Vector3(0.0, 0.0, 0.0) direction = Vector3(3, 3.0, 3.01) direction.normalize() ray = Ray(origin, direction) hitpoint = HitPoint(0.0, Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0), 6, 0.0, 0.0) t = FlatTriangle(p0, p1, p2) code = """ min_dist = 150.0 ret = isect_flat_triangle(ray, triangle, hitpoint, min_dist) """ r_arg = StructArg('ray', ray) tri_arg = StructArg('triangle', t) harg = StructArg('hitpoint', hitpoint) ret = IntArg('ret', 6) args = [r_arg, tri_arg, harg, ret] shader = Shader(code=code, args=args) shader.compile([tri_shader.shader]) shader.prepare(runtimes) shader.execute() min_dist = 150.0 hit = t.isect(ray, min_dist) hp = shader.get_value('hitpoint') self.assertAlmostEqual(hit.t, hp.t, places=6) self._almost_equal_vec3(hit.hit, hp.hit, places=6) self._almost_equal_vec3(hit.normal, hp.normal, places=6) self.assertEqual(hit.mat_idx, hp.mat_idx) self.assertAlmostEqual(hit.u, hp.u) self.assertAlmostEqual(hit.v, hp.v)
def isect_shader(cls, shader_name): code = """ temp1 = dot(ray.direction, rectangle.normal) if temp1 == 0.0: return 0 tmp = rectangle.point - ray.origin t = dot(tmp, rectangle.normal) / temp1 if t < 0.00001: return 0 if t > min_dist: return 0 p = ray.origin + ray.direction * t d = p - rectangle.point ddota = dot(d, rectangle.edge_a) if ddota < 0.0: return 0 if ddota > rectangle.edge_a_squared: return 0 ddotb = dot(d, rectangle.edge_b) if ddotb < 0.0: return 0 if ddotb > rectangle.edge_b_squared: return 0 hitpoint.t = t hitpoint.normal = rectangle.normal hitpoint.hit = p hitpoint.mat_idx = rectangle.mat_idx hitpoint.light_id = rectangle.light_id hitpoint.u = 0.0 hitpoint.v = 0.0 return 1 """ func_args = [StructArgPtr('ray', Ray.factory()), StructArgPtr('rectangle', Rectangle.factory()), StructArgPtr('hitpoint', HitPoint.factory()), FloatArg('min_dist', 0.0)] shader = Shader(code=code, args=[], name=shader_name, func_args=func_args, is_func=True) return DependencyShader(shader)
def isect_b_shader(cls, shader_name): label = 'ray_triangle_isect_b_%s' % id(cls) tri_isect = ray_triangle_isect_shader(label, isect_bool=True) code = """ return %s(ray, triangle.p0, triangle.p1, triangle.p2, min_dist) """ % label args = [] func_args = [StructArgPtr('ray', Ray.factory()), StructArgPtr('triangle', FlatTriangle.factory()), FloatArg('min_dist', 0.0)] shader = Shader(code=code, args=args, name=shader_name, func_args=func_args, is_func=True) isect_shader = DependencyShader(shader, [tri_isect]) return isect_shader
def test_isect_b_flat_triangle(self): runtimes = [Runtime()] tri_shader = FlatTriangle.isect_b_shader('isect_b_flat_triangle') tri_shader.compile() tri_shader.prepare(runtimes) p0 = Vector3(2.2, 4.4, 6.6) p1 = Vector3(1.1, 1.1, 1.1) p2 = Vector3(5.1, -1.1, 5.1) origin = Vector3(0.0, 0.0, 0.0) direction = Vector3(3, 3.0, 3.01) direction.normalize() ray = Ray(origin, direction) t = FlatTriangle(p0, p1, p2) code = """ min_dist = 150.0 ret = isect_b_flat_triangle(ray, triangle, min_dist) """ r_arg = StructArg('ray', ray) tri_arg = StructArg('triangle', t) ret = IntArg('ret', 6) args = [r_arg, tri_arg, ret] shader = Shader(code=code, args=args) shader.compile([tri_shader.shader]) shader.prepare(runtimes) shader.execute() min_dist = 150.0 hit = t.isect_b(ray, min_dist) hit2 = shader.get_value('ret') if hit2 == 0: hit2 = False elif hit2 == 1: hit2 = True else: raise ValueError("Unexpected value for isect flat triangle ", hit2) self.assertEqual(hit, hit2)
def test_isect_sph(self): sph_shader = Sphere.isect_shader('isect_sphere') sph_shader.compile() runtimes = [Runtime()] sph_shader.prepare(runtimes) code = """ min_dist = 99999.0 p1 = isect_sphere(ray, sphere, hitpoint, min_dist) """ direction = Vector3(-1.0, -1.0, -1.0) direction.normalize() ray = Ray(Vector3(5.0, 5.0, 5.0), direction) sphere = Sphere(Vector3(0.0, 0.0, 0.0), 2.0, 0) hitpoint = HitPoint(0.0, Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0), 6, 0.0, 0.0) r_arg = StructArg('ray', ray) sph_arg = StructArg('sphere', sphere) harg = StructArg('hitpoint', hitpoint) p1 = IntArg('p1', 6) args = [r_arg, sph_arg, harg, p1] shader = Shader(code=code, args=args) shader.compile([sph_shader.shader]) shader.prepare(runtimes) shader.execute() hp2 = sphere.isect(ray) hitpoint = shader.get_value('hitpoint') self.assertAlmostEqual(hp2.t, hitpoint.t) self.assertEqual(hp2.mat_idx, hitpoint.mat_idx) n1 = hp2.normal n2 = hitpoint.normal self.assertAlmostEqual(n1.x, n2.x) self.assertAlmostEqual(n1.y, n2.y) self.assertAlmostEqual(n1.z, n2.z) self.assertAlmostEqual(hitpoint.hit.x, hp2.hit.x) self.assertAlmostEqual(hitpoint.hit.y, hp2.hit.y) self.assertAlmostEqual(hitpoint.hit.z, hp2.hit.z) result = shader.get_value('p1') self.assertEqual(result, 1)
def test_linear_visiblity(self): sphere = Sphere(Vector3(0.0, 0.0, 0.0), 2.0, 0) mgr = ShapeManager() mgr.add('sph1', sphere) sphere2 = Sphere(Vector3(0.0, 2.0, 0.0), 3.0, 0) mgr.add('sph2', sphere2) isector = LinearIsect(mgr) runtimes = [Runtime()] direction = Vector3(-1.0, -1.0, -1.0) direction.normalize() ray = Ray(Vector3(5.0, 5.0, 5.0), direction) isector.compile() isector.prepare(runtimes) code = """ p1 = (9, 8, 7) p2 = (-2, -5, -3) ret = visibility(p1, p2) """ ret = IntArg('ret', 6) args = [ret] shader = Shader(code=code, args=args) shader.compile([isector.visible_shader]) shader.prepare(runtimes) p1 = Vector3(9.0, 8.0, 7.0) p2 = Vector3(-2.0, -5.0, -3.0) ret = isector.visibility(p1, p2) shader.execute() ret_s = shader.get_value('ret') if ret is True and ret_s == 0: raise ValueError("Linear visiblity is calculated wrong", ret, ret_s) if ret is False and ret_s == 1: raise ValueError("Linear visiblity is calculated wrong", ret, ret_s)
def load(self, shader_name): args = [] text = self._loader.load(shader_name, 'props.txt') if text is not None: args = parse_args(text) w = Vec3Arg('w', self._w) u = Vec3Arg('u', self._u) v = Vec3Arg('v', self._v) distance = FloatArg('distance', self._distance) eye = Vec3Arg('eye', self._eye) lookat = Vec3Arg('lookat', self._lookat) args.extend([w, u, v, distance, eye, lookat]) code = self._loader.load(shader_name, 'code.py') if code is None: raise ValueError("code.py in %s shader dont exist!" % shader_name) func_args = [StructArgPtr('ray', Ray.factory()), StructArgPtr('sample', Sample.factory())] self._shader_name = shader_name self.shader = Shader(code=code, args=args, name='generate_ray', func_args=func_args, is_func=True)
def isect_shader(self): origin = Vector3(0.0, 0.0, 0.0) direction = Vector3(0.0, 0.0, 0.0) ray = Ray(origin, direction) hitpoint = HitPoint(0.0, Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0), 0, 0.0, 0.0) func_args = [StructArgPtr('ray', ray), StructArgPtr('hitpoint', hitpoint), FloatArg('min_dist', 99999.0)] args = [] code = "hit_happend = 0\n" for shp_type in self.shp_mgr.shape_types(): code1, args1 = self._get_shape_code(shp_type) args.extend(args1) code += code1 code += "\nreturn hit_happend\n" shader = Shader(code=code, args=args, name='isect_scene', func_args=func_args, is_func=True) return shader
def isect_b_shader(cls, shader_name): code = """ temp = ray.origin - sphere.origin r_dir = ray.direction a = dot(r_dir, r_dir) b = dot(temp, r_dir) * 2.0 c = dot(temp, temp) - sphere.radius * sphere.radius disc = b * b - 4.0 * a * c if disc < 0.0: return 0 e = sqrt(disc) denom = 2.0 * a t = (-1.0 * b - e) / denom if t > 0.0005: if t < min_dist: return 1 t = (-1.0 * b + e) / denom if t > 0.0005: if t < min_dist: return 1 return 0 """ func_args = [ StructArgPtr('ray', Ray.factory()), StructArgPtr('sphere', Sphere.factory()), FloatArg('min_dist', 0.0) ] shader = Shader(code=code, args=[], name=shader_name, func_args=func_args, is_func=True) return DependencyShader(shader)
def isect_shader(cls, shader_name): label = 'ray_triangle_isect_%s' % id(cls) tri_isect = ray_triangle_isect_shader(label, isect_bool=False) code = """ ret = %s(ray, triangle.p0, triangle.p1, triangle.p2, min_dist, hitpoint) if ret: hitpoint.normal = triangle.normal hitpoint.u = 0.0 hitpoint.v = 0.0 hitpoint.mat_idx = triangle.mat_idx hitpoint.light_id = triangle.light_id return 1 else: return 0 """ % label args = [] origin = Vector3(0.0, 0.0, 0.0) direction = Vector3(0.0, 0.0, 0.0) ray = Ray(origin, direction) hitpoint = HitPoint(0.0, Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0), 0, 0.0, 0.0) triangle = FlatTriangle(Vector3(1.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), Vector3(0.0, 0.0, 1.0), 0) func_args = [StructArgPtr('ray', ray), StructArgPtr('triangle', triangle), StructArgPtr('hitpoint', hitpoint), FloatArg('min_dist', 0.0)] shader = Shader(code=code, args=args, name=shader_name, func_args=func_args, is_func=True) isect_shader = DependencyShader(shader, [tri_isect]) return isect_shader
def ray_triangle_isect_shader(name, isect_bool=False): code = """ origin = ray.origin direction = ray.direction a = p0[0] - p1[0] b = p0[0] - p2[0] c = direction[0] d = p0[0] - origin[0] e = p0[1] - p1[1] f = p0[1] - p2[1] g = direction[1] h = p0[1]- origin[1] i = p0[2] - p1[2] j = p0[2] - p2[2] k = direction[2] l = p0[2] - origin[2] m = f * k - g * j n = h * k - g * l p = f * l - h * j q = g * i - e * k s = e * j - f * i temp3 = a * m + b * q + c * s if temp3 == 0.0: return 0 inv_denom = 1.0 / temp3 e1 = d * m - b * n - c * p beta = e1 * inv_denom if beta < 0.0: return 0 r = e * l - h * i e2 = a * n + d * q + c * r gamma = e2 * inv_denom if gamma < 0.0: return 0 betagamma = beta + gamma if betagamma > 1.0: return 0 e3 = a * p - b * r + d * s t = e3 * inv_denom epsilon = 0.00001 if t < 0.00001: return 0 if t > min_dist: return 0 """ if isect_bool: code += """ return 1 """ else: code += """ hitpoint.t = t hitpoint.hit = direction * t + origin hitpoint.u = beta hitpoint.v = gamma return 1 """ ray_a = StructArgPtr('ray', Ray.factory()) p0 = Vec3Arg('p0', Vector3(0.0, 0.0, 0.0)) p1 = Vec3Arg('p1', Vector3(0.0, 0.0, 0.0)) p2 = Vec3Arg('p2', Vector3(0.0, 0.0, 0.0)) dist = FloatArg('min_dist', 0.0) hit_a = StructArgPtr('hitpoint', HitPoint.factory()) if isect_bool: func_args = [ray_a, p0, p1, p2, dist] else: func_args = [ray_a, p0, p1, p2, dist, hit_a] shader = Shader(code=code, args=[], name=name, func_args=func_args, is_func=True) return shader