def test_simple_scene(self): scene = Scene("example") ruby_material = ColorMaterial(Color(255, 0, 0), Vector3d(0.1745, 0.01175, 0.01175), Vector3d(0.61424, 0.04136, 0.04136), Vector3d(0.727811, 0.626959, 0.626959), 76.8) scene.addObject( RenderableObject(Sphere(Vector3d(0, 0, 0), 3), ruby_material)) scene.addObject( RenderableObject(Sphere(Vector3d(4, 4, -4), 1), ruby_material)) scene.addLight(SpotLight(Vector3d(10, 10, -10))) scene.addLight(SpotLight(Vector3d(0, 10, -5))) scene.addCamera( Camera(Vector3d(0, 0, -15), Vector3d(0, 0, 0), Vector3d(0, 1, 0), 60, 4 / 3, 1)) image = Image(scene.frameWidth, scene.frameHeight) frames_cnt = 30 start = time.time() for i in range(frames_cnt): scene.getFrame(image) elapsed = time.time() - start print( "\nSimple case frames per second : Time = {}s, Frames = {}, FPS = {}" .format(round(elapsed, 4), frames_cnt, round(frames_cnt / elapsed, 4)), end="")
def test_custom_construtor(self): print("\nCustom constructor", end="") light = SpotLight(Vector3d(1, 2, 3), Color(0xff00ff), 23, False) self.assertEqual(light.location, Vector3d(1, 2, 3)) self.assertEqual(light.color, Color(0xff00ff)) self.assertEqual(light.intensity, 23) self.assertEqual(light.state, False)
def test_default_constructor(self): print("\nDefault constructor", end="") light = SpotLight(Vector3d(0, 0, 0)) self.assertEqual(light.location, Vector3d(0, 0, 0)) self.assertEqual(light.color, Color(0xffffff)) self.assertEqual(light.intensity, 1) self.assertEqual(light.state, True)
def test_serialization(self): print("\nSphere serialization", end = "") sphere = Sphere(Vector3d(0,0,0), 10) dict = json.loads(repr(sphere)) obj = dict["Sphere"] self.assertEqual(obj["Center"], json.loads(repr(Vector3d(0)))) self.assertEqual(obj["Radius"], 10)
def test_bounding_box(self): print("\nBounding box", end = "") sphere = Sphere(Vector3d(0,1,2), 5) bb = sphere.boundingBox self.assertEqual(bb.min, Vector3d(-5,-4,-3)) self.assertEqual(bb.max, Vector3d(5,6,7))
def test_deserialization(self): print("\nSphere deserialization", end = "") sphere = Sphere(Vector3d(0,0,0), 10) dict = json.loads(repr(sphere)) obj = Sphere.fromDict(dict) self.assertEqual(obj.center, Vector3d(0)) self.assertEqual(obj.radius, 10)
def test_deserialization(self): print("\nCamera deserialization", end = "") camera = Camera(Vector3d(0,0,0), Vector3d(0,0,1), Vector3d(0,1,0), 60, 4/3, 1) dict = json.loads(repr(camera)) cam = Camera.fromDict(dict) self.assertEqual(cam.location, Vector3d(0,0,0)) self.assertEqual(dict, json.loads(repr(cam)))
def test_deserialization(self): print("\nDeserialization", end="") bb = bbox(Vector3d(0), Vector3d(1)) dict = json.loads(repr(bb)) box = bbox.fromDict(dict) self.assertEqual(bb.min, box.min) self.assertEqual(bb.max, box.max)
def test_serialization(self): print("\nSerialization", end="") bb = bbox(Vector3d(0), Vector3d(1)) dict = json.loads(repr(bb)) box = dict["BoundingBox"] self.assertEqual(box["MinCorner"], json.loads(repr(Vector3d(0)))) self.assertEqual(box["MaxCorner"], json.loads(repr(Vector3d(1))))
def test_properties(self): print("\nProperties", end = "") sphere = Sphere(Vector3d(0,0,0), 10) sphere.center = Vector3d(1,2,3) self.assertEqual(sphere.center, Vector3d(1,2,3)) sphere.radius = 123 self.assertEqual(sphere.radius, 123)
def test_serialization(self): print("\nSpotLight serialization", end="") light = SpotLight(Vector3d(0)) dict = json.loads(repr(light)) splight = dict["SpotLight"] self.assertEqual(splight["Location"], json.loads(repr(Vector3d(0)))) self.assertEqual(splight["Color"], json.loads(repr(Color(0xffffff)))) self.assertEqual(splight["Intensity"], 1) self.assertEqual(splight["State"], True)
def test_deserialization(self): print("\nSpotLight deserialization", end="") light = SpotLight(Vector3d(0)) dict = json.loads(repr(light)) splight = SpotLight.fromDict(dict) self.assertEqual(splight.location, Vector3d(0)) self.assertEqual(splight.color, Color(0xffffff)) self.assertEqual(splight.intensity, 1) self.assertEqual(splight.state, True)
def test_simple_constructor(self): print("\nSimple constructor", end = "") cm = ColorMaterial(Color(0x00ff00)) self.assertEqual(cm.color, Color(0x00ff00)) self.assertEqual(cm.ambient, Vector3d(1,1,1)) self.assertEqual(cm.diffuse, Vector3d(1,1,1)) self.assertEqual(cm.specular, Vector3d(1,1,1)) self.assertEqual(cm.shinines, 1) self.assertEqual(cm.reflection, 0) self.assertEqual(cm.refraction, 0)
def test_tangent(self): print("\nTanget ray", end = "") sphere = Sphere(Vector3d(0,0,30), 10) ray = Ray(Vector3d(10,0,0),Vector3d(0,0,1)) intersection = IntersectionRecord() hitted = sphere.hitRay(intersection,ray) self.assertEqual(hitted, True) self.assertEqual(intersection.distance, 30) self.assertEqual(intersection.intersection, Vector3d(10,0,30)) self.assertEqual(intersection.normal, Vector3d(1,0,0))
def test_ray_box_intersection(self): print("\nRay Box Intersection", end="") min_corner = Vector3d(-1) max_corner = Vector3d(1) box = BoundingBox(min_corner, max_corner) ray = Ray(Vector3d(0, 0, -3), Vector3d(0, 0, 1)) intersection = RayBoxIntersectionRecord() rayBoxIntersection(ray, box, intersection) self.assertEqual(2, intersection.tmin) self.assertEqual(4, intersection.tmax)
def test_no_intersection(self): print("\nNo intersections", end = "") sphere = Sphere(Vector3d(0,0,30), 10) ray = Ray(Vector3d(0,0,0),Vector3d(0,0,-1)) intersection = IntersectionRecord() hitted = sphere.hitRay(intersection,ray) self.assertEqual(hitted, False) ray = Ray(Vector3d(10.0001,0,0),Vector3d(0,0,1)) hitted = sphere.hitRay(intersection,ray) self.assertEqual(hitted, False)
def test_containing_point(self): print("\nContaining point", end="") bb = bbox(Vector3d(0), Vector3d(5)) self.assertTrue(bb.contains(Vector3d(0))) self.assertTrue(bb.contains(Vector3d(5))) self.assertTrue(bb.contains(Vector3d(3))) self.assertTrue(bb.contains(Vector3d(3, 0, 0))) self.assertTrue(bb.contains(Vector3d(0, 3, 0))) self.assertTrue(bb.contains(Vector3d(0, 0, 3))) self.assertFalse(bb.contains(Vector3d(-1))) self.assertFalse(bb.contains(Vector3d(6)))
def test_simple_example(self): print("\nSimple example", end="") scene = Scene("example") self.assertEqual(scene.name, "example") ruby_material = ColorMaterial(Color(255, 0, 0), Vector3d(0.1745, 0.01175, 0.01175), Vector3d(0.61424, 0.04136, 0.04136), Vector3d(0.727811, 0.626959, 0.626959), 76.8) sphere = Sphere(Vector3d(0, 0, 0), 10) object = RenderableObject(sphere, ruby_material) light = SpotLight(Vector3d(10, 10, 10)) camera = Camera(Vector3d(0, 0, -10), Vector3d(0, 0, 0), Vector3d(0, 1, 0), 60, 4 / 3, 1) scene.addObject(object) self.assertEqual(scene.objCnt, 1) scene.clearObjects() self.assertEqual(scene.objCnt, 0) scene.addLight(light) self.assertEqual(scene.lightCnt, 1) self.assertTrue(light.state) scene.setOnOffLight(0, False) self.assertFalse(light.state) scene.clearLights() self.assertEqual(scene.lightCnt, 0) scene.addCamera(camera) self.assertEqual(scene.camCnt, 1) scene.clearCameras() self.assertEqual(scene.camCnt, 0)
def test_properties(self): print("\nProperties", end="") bb = bbox() self.assertEqual(bb.min, Vector3d(2147483647)) self.assertEqual(bb.max, Vector3d(-2147483648)) self.assertEqual(bb.center, Vector3d(-0.5)) with self.assertRaises(AttributeError): bb.min = Vector3d(0) with self.assertRaises(AttributeError): bb.max = Vector3d(0) with self.assertRaises(AttributeError): bb.center = Vector3d(0) bb = bbox(Vector3d(0, 1, 2), Vector3d(4, 6, 8)) self.assertEqual(bb.deltaX, 4) self.assertEqual(bb.deltaY, 5) self.assertEqual(bb.deltaZ, 6) with self.assertRaises(AttributeError): bb.deltaX = 0 with self.assertRaises(AttributeError): bb.deltaY = 0 with self.assertRaises(AttributeError): bb.deltaZ = 0
def test_two_intersections(self): print("\nRay intersects Sphere (two intersections)", end = "") sphere = Sphere(Vector3d(0,0,30), 10) ray = Ray(Vector3d(0,0,0),Vector3d(0,0,1)) intersection = IntersectionRecord() hitted = sphere.hitRay(intersection,ray) self.assertEqual(hitted, True) self.assertEqual(intersection.distance, 20) self.assertEqual(intersection.intersection, Vector3d(0,0,20)) self.assertEqual(intersection.normal, Vector3d(0,0,-1)) intersection = IntersectionRecord() sphere = Sphere(Vector3d(0,0,0), 1) x = 1/math.sqrt(2) ray = Ray(Vector3d(x,0,-5),Vector3d(0,0,1)) hitted = sphere.hitRay(intersection,ray) self.assertEqual(hitted, True) self.assertEqual(intersection.distance, 5-x) self.assertEqual(round(intersection.intersection.x,12), round(x,12)) self.assertEqual(intersection.intersection.y, 0) self.assertEqual(round(intersection.intersection.z,12), round(-x,12)) self.assertEqual(round(intersection.normal.x,12), round(x,12)) self.assertEqual(intersection.normal.y, 0) self.assertEqual(round(intersection.normal.z,12), round(-x,12))
def test_adding_point(self): print("\nAdd point", end="") bb = bbox() bb.addPoint(Vector3d(1)) self.assertFalse(bb.isValid()) bb.addPoint(Vector3d(0)) self.assertTrue(bb.isValid()) bb.addPoint(Vector3d(0.5)) self.assertEqual(bb.min, Vector3d(0)) self.assertEqual(bb.max, Vector3d(1))
def test_properties(self): print("\nProperties", end="") light = SpotLight(Vector3d(1)) light.location = Vector3d(1, 2, 3) self.assertEqual(light.location, Vector3d(1, 2, 3)) light.color = Color(0xff00ff) self.assertEqual(light.color, Color(0xff00ff)) light.intensity = 23 self.assertEqual(light.intensity, 23) light.state = False self.assertEqual(light.state, False)
def test_get_direction(self): print("\nGet direction", end = "") camera = Camera(Vector3d(0,0,0), Vector3d(0,0,1), Vector3d(0,1,0), 60, 4/3, 1) width, height = 800, 600 u, v = 400, 300 actual = camera.direction(u/width,v/height) expected = Vector3d(0,0,1) self.assertEqual(actual, expected) temp = camera.direction(0,v/height) self.assertTrue(temp.y == 0) self.assertTrue(temp.x != 0) temp = camera.direction(u/width,0) self.assertTrue(temp.y != 0) self.assertTrue(temp.x == 0)
def test_get_functions(self): print("\nSpotLight direction at point", end="") light = SpotLight(Vector3d(0)) self.assertEqual(light.direction(Vector3d(1, 0, 0)), Vector3d(1, 0, 0)) self.assertEqual(light.direction(Vector3d(0, 1, 0)), Vector3d(0, 1, 0)) self.assertEqual(light.direction(Vector3d(0, 0, 1)), Vector3d(0, 0, 1))
def test_normalization_in_constructor(self): print("\nConstructor with normalization", end="") ray = Ray(Vector3d(0, 0, 0), Vector3d(0, 0, 111)) self.assertEqual(ray.origin, Vector3d(0, 0, 0)) self.assertEqual(ray.direction, Vector3d(0, 0, 1)) ray = Ray(Vector3d(0, 0, 0), Vector3d(1, 1, 1)) self.assertEqual(ray.origin, Vector3d(0, 0, 0)) x = 1 / math.sqrt(3) self.assertEqual(ray.direction, Vector3d(x, x, x))
def test_color_get_functions(self): print("\nColorMaterial get color functions", end = "") ruby_material = ColorMaterial(Color(255, 0, 0) , Vector3d(0.1745, 0.01175, 0.01175) , Vector3d(0.61424, 0.04136, 0.04136) , Vector3d(0.727811, 0.626959, 0.626959) , 76.8) light = SpotLight(Vector3d(2,0,0)) light1 = SpotLight(Vector3d(4,0,0)) self.assertEqual( ruby_material.primitiveColor(), Color(255,0,0) * Vector3d(0.1745, 0.01175, 0.01175)) self.assertEqual( ruby_material.lightInfluence(Vector3d(0),Vector3d(1,0,0),light), Color(255,0,0) * Vector3d(0.61424, 0.04136, 0.04136))
def test_merge(self): print("\nMerge of boxes", end="") bb1 = bbox(Vector3d(0), Vector3d(1)) bb2 = bbox(Vector3d(0.5), Vector3d(1.5)) bb1.merge(bb2) self.assertEqual(bb1.min, Vector3d(0)) self.assertEqual(bb1.max, Vector3d(1.5))
def test_constructor_with_two_parameters(self): print("\nMinMax constructor", end="") bb = bbox(Vector3d(0), Vector3d(1)) self.assertEqual(bb.min, Vector3d(0)) self.assertEqual(bb.max, Vector3d(1)) self.assertTrue(bb.isValid()) bb = bbox(Vector3d(1), Vector3d(0)) self.assertFalse(bb.isValid())
def test_serialization(self): print("\nCamera serialization", end = "") camera = Camera(Vector3d(0,0,0), Vector3d(0,0,1), Vector3d(0,1,0), 60, 4/3, 1) dict = json.loads(repr(camera)) cam = dict["Camera"] self.assertEqual(cam["Location"], json.loads(repr(Vector3d(0,0,0)))) self.assertEqual(cam["LookAt"], json.loads(repr(Vector3d(0,0,1)))) self.assertEqual(cam["Up"], json.loads(repr(Vector3d(0,1,0)))) self.assertEqual(cam["FoV"], 60) self.assertEqual(cam["Aspect"], round(4/3,6)) self.assertEqual(cam["FocusDistance"], 1)
def create_scene_sample(camera_cnt=1, obj_cnt=1, light_cnt=1): scene = Scene("example") for i in range(camera_cnt): scene.addCamera( Camera(Vector3d(2 * i + 1, 3 * i + 1, 4 * i + 1), Vector3d(0, 0, 0), Vector3d(0, 1, 0), 60, 4 / 3, 1), True) ruby_material = ColorMaterial(Color(255, 0, 0), Vector3d(0.1745, 0.01175, 0.01175), Vector3d(0.61424, 0.04136, 0.04136), Vector3d(0.727811, 0.626959, 0.626959), 76.8) for i in range(obj_cnt): scene.addObject( RenderableObject(Sphere(Vector3d(i * 10), i * 5), ruby_material)) for i in range(light_cnt): scene.addLight(SpotLight(Vector3d(-i * 2, i * 4, i * 5))) return scene