def test_pattern(self): """Test that the pattern of a material can change its color""" m = materials.Material(pattern=patterns.StripePattern( colors.Color( 0, 0, 0, ), colors.Color(1, 1, 1)), ambient=1, diffuse=0, specular=0) eyev = vectors.Vector(0, 0, -1) normalv = vectors.Vector(0, 0, -1) light = lights.PointLight(points.Point(0, 0, -10), colors.Color(1, 1, 1)) color_1 = m.lighting(light, points.Point(0.9, 0, 0), eyev, normalv, in_shadow=False) color_2 = m.lighting(light, points.Point(1.1, 0, 0), eyev, normalv, in_shadow=False) self.assertEqual(color_1, colors.Color(0, 0, 0)) self.assertEqual(color_2, colors.Color(1, 1, 1))
def test_dot_product(self): """Test dot product between two vectors""" a1 = vectors.Vector(1, 2, 3) a2 = vectors.Vector(2, 3, 4) self.assertEqual(a1.dot(a2), 20)
def merge( directionAstart, directionAend, directionBstart, newStart ): '''merges two different locomotes together - for example N and E to give a NE locomote''' #determine which ctrl set to use length = directionAend-directionAstart ctrlSet = names.matchNames(['body_ctrls'],cmd.ls(type='objectSet')) if not ctrlSet: raise Exception('control set not found') ctrlSet = ctrlSet[0] ctrls = cmd.sets(ctrlSet,q=True) #deal with the assets for the new animation vx = exportManagerCore.ExportManager() assetA = vx.exists(start=directionAstart,end=directionAend)[0] assetB = vx.exists(start=directionBstart,end=directionBstart+length)[0] exportSet = assetA.obj assetC = vx.exists(start=newStart,end=newStart+length) if not assetC: assetC = vx.createAsset(exportSet) assetC.setAttr('start', newStart) assetC.setAttr('end', newStart+length) assetC.setAttr('name', assetA.name + assetB.name) assetC.setAttr('type', exportManagerCore.ExportComponent.kANIM) #now start building the animations animationA = Animation(ctrls,directionAstart,directionAend) animationB = Animation(ctrls,directionBstart,directionBstart+length) animationB.offset(-directionBstart+directionAstart) animationC = animationA+animationB animationC.offset(newStart) #grab the list of ctrls we need to actually transform toFind = ['upperBodyControl','legControl_L','legControl_R'] xformCtrls = [name for name in names.matchNames(toFind,ctrls,parity=True,threshold=0.8) if name != ''] for ctrl in xformCtrls: motionA = motionList(ctrl,directionAstart,directionAend) motionB = motionList(ctrl,directionBstart,directionBstart+length) #make the time zero based times = [int(time)-newStart for time in animationC[ctrl].get_times(channels=['translateX','translateZ'])] times.sort() print times,len(motionA),len(motionB) for time in times: print motionA[time],motionB[time] newPos = vectors.Vector(motionA[time]) + vectors.Vector(motionB[time]) newPos *= 0.70710678118654757 #= math.cos(45degrees) tx = animationC[ctrl].translateX[time] tz = animationC[ctrl].translateZ[time] if tx: tx.keys[0] = newPos.x if tz: tz.keys[0] = newPos.z animationC.applyToObjs() #end
def test_subtraction__vector_vector(self): """test that we can subtract two vectors""" a1 = vectors.Vector(3, 2, 1) a2 = vectors.Vector(5, 6, 7) a3 = a1 - a2 self.assertEqual(a3, vectors.Vector(-2, -4, -6))
def test_cross_product(self): """Test cross product between two vectors""" a1 = vectors.Vector(1, 2, 3) a2 = vectors.Vector(2, 3, 4) self.assertEqual(a1.cross(a2), vectors.Vector(-1, 2, -1)) self.assertEqual(a2.cross(a1), vectors.Vector(1, -2, 1))
def test_lighting__shadow(self): """Test that we get the ambient color if we're in shadow""" m = materials.Material() p = points.Point(0, 0, 0) eyev = vectors.Vector(0, 0, -1) normalv = vectors.Vector(0, 0, -1) light = lights.PointLight(points.Point(0, 0, -10), colors.Color(1, 1, 1)) result = m.lighting(light, p, eyev, normalv, in_shadow=True) self.assertEqual(result, colors.Color(0.1, 0.1, 0.1))
def EulerToPlane(self): k = vectors.Vector( math.cos(self.yaw) * math.cos(self.pitch), math.sin(self.pitch), math.sin(self.yaw) * math.cos(self.pitch)) y = vectors.Vector(0, 1, 0) s = vectors.Vector.cross(k, y) v = vectors.Vector.cross(s, k) #vrot = v*math.cos(self.roll) +vectors.Vector.cross(k,v)*math.sin(self.roll) self.x = vpVec(k.x, k.y, k.z) self.y = vpVec(s.x, s.y, s.z) self.z = vpVec(v.x, v.y, v.z)
def test_local_normal_at(self): """Test that the local normal is always in the y direction""" p = shapes.Plane() self.assertEqual(p.local_normal_at(points.Point(0, 0, 0)), vectors.Vector(0, 1, 0)) self.assertEqual(p.local_normal_at(points.Point(10, 0, -10)), vectors.Vector(0, 1, 0)) self.assertEqual(p.local_normal_at(points.Point(-5, 0, 150)), vectors.Vector(0, 1, 0))
def test_normal_at__transformed(self): """Test we can calculate normal vectors on a transformed sphere""" s = shapes.Sphere() s.set_transform(transforms.Translate(0, 1, 0)) n = s.normal_at(points.Point(0, 1.70711, -0.70711)) self.assertEqual(n, vectors.Vector(0, 0.70711, -0.70711)) s.set_transform( transforms.Scale(1, 0.5, 1) * transforms.RotateZ(math.pi / 5)) n = s.normal_at(points.Point(0, math.sqrt(2) / 2, -math.sqrt(2) / 2)) self.assertEqual(n, vectors.Vector(0, 0.97014, -0.24254))
def test_ray_transforms(self): """Test that we can transform a ray""" origin = points.Point(1, 2, 3) direction = vectors.Vector(0, 1, 0) r = rays.Ray(origin, direction) r2 = r.transform(transforms.Translate(3, 4, 5)) self.assertEqual(r2.origin, points.Point(4, 6, 8)) self.assertEqual(r2.direction, vectors.Vector(0, 1, 0)) r3 = r.transform(transforms.Scale(2, 3, 4)) self.assertEqual(r3.origin, points.Point(2, 6, 12)) self.assertEqual(r3.direction, vectors.Vector(0, 3, 0))
def test_precompute__inside(self): """Test that we can precompute vectors for an intersection and ray when inside of a shape""" r = rays.Ray(points.Point(0, 0, 0), vectors.Vector(0, 0, 1)) s = shapes.Sphere() i = intersections.Intersection(s, 1) computations = i.precompute(r) self.assertEqual(computations.t, 1) self.assertEqual(computations.point, points.Point(0, 0, 1)) self.assertEqual(computations.eyev, vectors.Vector(0, 0, -1)) self.assertEqual(computations.normalv, vectors.Vector(0, 0, -1)) self.assertTrue(computations.inside)
def test_ray_for_pixel(self): """Test we can fire a ray through any pixel""" cam = cameras.Camera(201, 101, math.pi/2) # Middle of the screen ray = cam.ray_for_pixel(100, 50) self.assertEqual(ray.origin, points.Point(0, 0, 0)) self.assertEqual(ray.direction, vectors.Vector(0, 0, -1)) # A corner ray = cam.ray_for_pixel(0, 0) self.assertEqual(ray.origin, points.Point(0, 0, 0)) self.assertEqual(ray.direction, vectors.Vector(0.66519, 0.33259, -0.66851))
def test_simple_scaling(self): """Test that we can scale a point""" S = transforms.Scale(2, 3, 4) p = points.Point(-4, 6, 8) v = vectors.Vector(-4, 6, 8) p2 = S * p self.assertEqual(p2, points.Point(-8, 18, 32)) p3 = S * v self.assertEqual(p3, vectors.Vector(-8, 18, 32)) p4 = S.inverse() * p self.assertEqual(p4, points.Point(-2, 2, 2))
def test_precompute_reflectv(self): """Test that we can calculate the reflection vector""" p = shapes.Plane() r = rays.Ray(points.Point(0, 1, -1), vectors.Vector(0, -math.sqrt(2) / 2, math.sqrt(2) / 2)) i = intersections.Intersection(p, math.sqrt(2)) comps = i.precompute(r) self.assertEqual(comps.reflectv, vectors.Vector(0, math.sqrt(2) / 2, math.sqrt(2) / 2))
def test_lighting(self): """Tests on the lighting function for various angles and colors""" m = materials.Material() p = points.Point(0, 0, 0) #the eye is positioned directly between the light and the surface, with #the normal pointing at the eye. Expect ambient, diffuse, and specular #to all be at full strength. This means that the total intensity should #be 0.1 (the ambient value) + 0.9 (the diffuse value) + 0.9 (the #specular value), or 1.9 eyev = vectors.Vector(0, 0, -1) normalv = vectors.Vector(0, 0, -1) light = lights.PointLight(points.Point(0, 0, -10), colors.Color(1, 1, 1)) result = m.lighting(light, p, eyev, normalv) self.assertEqual(result, colors.Color(1.9, 1.9, 1.9)) eyev = vectors.Vector(0, math.sqrt(2) / 2, -math.sqrt(2) / 2) normalv = vectors.Vector(0, 0, -1) light = lights.PointLight(points.Point(0, 0, -10), colors.Color(1, 1, 1)) result = m.lighting(light, p, eyev, normalv) self.assertEqual(result, colors.Color(1.0, 1.0, 1.0)) eyev = vectors.Vector(0, 0, -1) normalv = vectors.Vector(0, 0, -1) light = lights.PointLight(points.Point(0, 10, -10), colors.Color(1, 1, 1)) result = m.lighting(light, p, eyev, normalv) self.assertEqual(result, colors.Color(0.7364, 0.7364, 0.7364)) eyev = vectors.Vector(0, -math.sqrt(2) / 2, -math.sqrt(2) / 2) normalv = vectors.Vector(0, 0, -1) light = lights.PointLight(points.Point(0, 10, -10), colors.Color(1, 1, 1)) result = m.lighting(light, p, eyev, normalv) self.assertEqual(result, colors.Color(1.6364, 1.6364, 1.6364)) # Light behind the object, its color should be the ambient value eyev = vectors.Vector(0, 0, -1) normalv = vectors.Vector(0, 0, -1) light = lights.PointLight(points.Point(0, 0, 10), colors.Color(1, 1, 1)) result = m.lighting(light, p, eyev, normalv) self.assertEqual(result, colors.Color(0.1, 0.1, 0.1))
def test_refraction__standard(self): """Test that we return the correct color under normal refraction""" world = copy.deepcopy(self.default_scene) # s1 = A s1 = world.objects[1] s1.material.ambient = 1.0 s1.material.pattern = patterns.TestPattern() # s2 = B s2 = world.objects[0] s2.material.transparency = 1.0 s2.material.refractive_index = 1.5 r = rays.Ray(points.Point(0, 0, 0.1), vectors.Vector(0, 1, 0)) xs = intersections.Intersections( intersections.Intersection(s1, -0.9899), intersections.Intersection(s2, -0.4899), intersections.Intersection(s2, 0.4899), intersections.Intersection(s1, 0.9899)) # Intersections[2] because the first two are behind the camera comps = xs.intersections[2].precompute(r, all_intersections=xs) result, _ = world.refracted_color(comps, 5) # Remember the test pattern returns the x, y, z coordinates of the # input point as the color so we can inspect positions self.assertEqual(result, colors.Color(0, 0.99888, 0.0475))
def test_render_scene(self): """Test we can render a pixel in a simple scene""" # Inner sphere size 0.5, centered on the origin s1 = shapes.Sphere() s1.set_transform(transforms.Scale(0.5,0.5,0.5)) # Outer sphere centered on the origin, size 1.0 s2 = shapes.Sphere() s2.material = materials.Material( color=colors.Color(0.8, 1.0, 0.6), diffuse=0.7, specular=0.2) l1 = lights.Light( position=points.Point(-10, 10, -10), intensity=colors.Color(1, 1, 1) ) scene = scenes.Scene( objects = [s1, s2], lights = [l1] ) cam = cameras.Camera(11, 11, math.pi/2) from_point = points.Point(0, 0, -5) to_point = points.Point(0, 0, 0) up = vectors.Vector(0, 1, 0) cam.transform = transforms.ViewTransform(from_point, to_point, up) image = cam.render(scene) self.assertEqual(image.get(5, 5), colors.Color(0.3807, 0.4758, 0.2855))
def test_reflection__reflective(self): """Test the reflection color of a reflective material is not black""" p = shapes.Plane(material=materials.Material(reflective=0.5)) p.set_transform(transforms.Translate(0, -1, 0)) world = copy.deepcopy(self.default_scene) world.objects.append(p) r = rays.Ray(points.Point(0, 0, -3), vectors.Vector(0, -math.sqrt(2) / 2, math.sqrt(2) / 2)) i = intersections.Intersection(p, math.sqrt(2)) comps = i.precompute(r) # Test reflected color alone result, _ = world.reflected_color(comps) self.assertEqual(result, colors.Color(0.19032, 0.2379, 0.14274)) # Now test the reflected color is added to the surface color result, _ = world.shade_hit(comps) self.assertEqual(result, colors.Color(0.87677, 0.92436, 0.82918))
def test_intersection_miss(self): """Test we handle the case where the ray misses the sphere""" s = shapes.Sphere() r = rays.Ray(points.Point(0, 2, -5), vectors.Vector(0, 0, 1)) self.assertEqual(s.intersect(r).intersections, [])
def test_create_base_engine_without_params(self): engine = engines.BaseEngine() self.assertEqual(engine.width, 1280) self.assertEqual(engine.height, 720) self.assertEqual(engine.size, vectors.Vector(1280, 720)) self.assertEqual(engine.fps, 25) self.assertEqual(engine.bg_color, colors.black)
def test_shadows__full_scene(self): """Test that we identify a shadow in a full scene""" # First sphere is at z=10 s1 = shapes.Sphere() s1.set_transform(transforms.Translate(0, 0, 10)) # Second sphere is at the origin s2 = shapes.Sphere() s2.material = materials.Material() # Light is at z=-10 l1 = lights.Light(position=points.Point(0, 0, -10), intensity=colors.Color(1, 1, 1)) scene = scenes.Scene(objects=[s1, s2], lights=[l1]) # The ray is at z=5 (i.e. between the spheres), pointing at the further # out sphere ray = rays.Ray(points.Point(0, 0, 5), vectors.Vector(0, 0, 1)) isection = intersections.Intersection(s2, 4) comps = isection.precompute(ray) result, _ = scene.shade_hit(comps) self.assertEqual(result, colors.Color(0.1, 0.1, 0.1))
def test_reflective_transparent_material(self): """Test shade_hit with a reflective, transparent material""" world = copy.deepcopy(self.default_scene) floor = shapes.Plane(material=materials.Material( reflective=0.5, transparency=0.5, refractive_index=1.5)) floor.set_transform(transforms.Translate(0, -1, 0)) ball = shapes.Sphere(material=materials.Material( color=colors.Color(1, 0, 0), ambient=0.5)) ball.set_transform(transforms.Translate(0, -3.5, -0.5)) r = rays.Ray(points.Point(0, 0, -3), vectors.Vector(0, -math.sqrt(2) / 2, math.sqrt(2) / 2)) xs = intersections.Intersections( intersections.Intersection(floor, math.sqrt(2))) world.add_object(floor) world.add_object(ball) comps = xs.intersections[0].precompute(r, all_intersections=xs) color, _ = world.shade_hit(comps, remaining=5) self.assertEqual(color, colors.Color(0.93391, 0.69643, 0.69243))
def test_refraction__total_internal_reflection(self): """Test that we return black if we hit total internal reflection""" world = copy.deepcopy(self.default_scene) s = world.objects[1] s.material.transparency = 1.0 s.material.refractive_index = 1.5 r = rays.Ray(points.Point(0, 0, math.sqrt(2) / 2), vectors.Vector(0, 1, 0)) xs = intersections.Intersections( intersections.Intersection(s, -math.sqrt(2) / 2), intersections.Intersection(s, math.sqrt(2) / 2)) # n.b. the camera is inside the inner-sphere so use the second # intersection comps = xs.intersections[1].precompute(r, all_intersections=xs) result, _ = world.refracted_color(comps, 5) self.assertEqual(result, colors.Color(0, 0, 0))
def test_magnitude(self): """Test that we can calculate the magnitude of a vector""" a1 = vectors.Vector(1, 2, 3) self.assertEqual(a1.magnitude(), math.sqrt(14)) a1 = vectors.Vector(-1, -2, -3) self.assertEqual(a1.magnitude(), math.sqrt(14)) a1 = vectors.Vector(1, 0, 0) self.assertEqual(a1.magnitude(), 1) a1 = vectors.Vector(0, 1, 0) self.assertEqual(a1.magnitude(), 1) a1 = vectors.Vector(0, 0, 1) self.assertEqual(a1.magnitude(), 1)
def test_translate_vector_is_noop(self): """Verify that translating a vector has no effect""" v = vectors.Vector(1, 2, 3) T = transforms.Translate(5, -3, 2) v2 = T * v self.assertEqual(v, v2)
def test_rotate_camera(self): """A view transformation matrix looking in the +ve z direction""" from_point = points.Point(0, 0, 0) to_point = points.Point(0, 0, 1) up = vectors.Vector(0, 1, 0) result = transforms.ViewTransform(from_point, to_point, up) self.assertEqual(result, transforms.Scale(-1, 1, -1))
def test_default_view(self): """Test that the view transform for the default view is identity""" from_point = points.Point(0, 0, 0) to_point = points.Point(0, 0, -1) up = vectors.Vector(0, 1, 0) result = transforms.ViewTransform(from_point, to_point, up) self.assertEqual(result, transforms.Identity(4))
def test_normal_at__non_transformed(self): """Test we can calculate normal vectors on the unit sphere""" s = shapes.Sphere() n = s.normal_at(points.Point(1, 0, 0)) self.assertEqual(n, vectors.Vector(1, 0, 0)) n = s.normal_at(points.Point(0, 1, 0)) self.assertEqual(n, vectors.Vector(0, 1, 0)) n = s.normal_at(points.Point(0, 0, 1)) self.assertEqual(n, vectors.Vector(0, 0, 1)) sqrt3d3 = math.sqrt(3) / 3 n = s.normal_at(points.Point(sqrt3d3, sqrt3d3, sqrt3d3)) self.assertEqual(n, vectors.Vector(sqrt3d3, sqrt3d3, sqrt3d3))
def __init__(self, width=1280, height=720, fps=25): self.width = width self.height = height self.size = vectors.Vector(width, height) self.fps = fps self.bg_color = colors.black self.fg_color = colors.white self.frame = 0 self.debug = False
def test_subtraction__vector_point(self): """test that we can subtract a vector from a point""" a1 = points.Point(3, 2, 1) a2 = vectors.Vector(5, 6, 7) a3 = a1 - a2 self.assertEqual(a3, points.Point(-2, -4, -6))