def foundPixel(self): self.setColor(self.background) oldDistance = None for obj in self.engine.objectManager.objects: response = obj.isRayInRadius(self) if (response[0]): self.anyObject = True v = Vector(response[1].x - self.engine.camera.position.x, response[1].y - self.engine.camera.position.y, response[1].z - self.engine.camera.position.z) #pokud je objekt za kamerou if (v.angle(self.engine.camera.direction) > math.pi / 2): continue #poradi objektu v zavislosti na kamere distance = v.selfLength() if (oldDistance == None or oldDistance > distance): oldDistance = distance #vypocteni stinu light = self.engine.lightManager.lights[0] shadowRay = Ray( self.engine, Vector(light.x - response[1].x, light.y - response[1].y, light.z - response[1].z), response[1], self.background, self.level + 1) color = obj.getColor() #self.calcPixelColor(obj, light, response[1]) shadow = self.shootShadowRay(shadowRay, obj, light) #stin if ( shadow == 0 ): #pokud pixel neni zastíněn, tak se vypočte jeho barva bez stinu color = self.calcPixelColor(obj, light, response[1]) self.setColor((color[0] - shadow, color[1] - shadow, color[2] - shadow))
def drawScreen(self, index): x = index % self.width y = math.floor(index / self.width) oldPixel = self.pixelScreen[(x, y)] if (oldPixel[0] == 0 and oldPixel[1] == 255 and oldPixel[2] == 0): ray = Ray( self.engine, Vector(round(x - self.width / 2), round(y - self.height / 2), -1000), self.engine.camera.position) ray.foundPixel() return ray.getColor() return (0, 0, 0)
def isRayInRadius(self, ray, obj=None, light=None): s1 = self.x s2 = self.y s3 = self.z c1 = ray.startPoint.x c2 = ray.startPoint.y c3 = ray.startPoint.z u1 = ray.direction.x u2 = ray.direction.y u3 = ray.direction.z r = self.radius #koeficienty rovnice A = u1*u1 + u2*u2 + u3*u3 B = s1*u1 - c2*u2 - c3*u3 - c1*u1 + s2*u2 + s3*u3 D = (- c1*c1*u2*u2 - c1*c1*u3*u3 + 2*c1*c2*u1*u2 + 2*c1*c3*u1*u3 + 2*c1*s1*u2*u2 + 2*c1*s1*u3*u3 - 2*c1*s2*u1*u2 - 2*c1*s3*u1*u3 - c2*c2*u1*u1 - c2*c2*u3*u3 + 2*c2*c3*u2*u3 - 2*c2*s1*u1*u2 + 2*c2*s2*u1*u1 + 2*c2*s2*u3*u3 - 2*c2*s3*u2*u3 - c3*c3*u1*u1 - c3*c3*u2*u2 - 2*c3*s1*u1*u3 - 2*c3*s2*u2*u3 + 2*c3*s3*u1*u1 + 2*c3*s3*u2*u2 + r*r*u1*u1 + r*r*u2*u2 + r*r*u3*u3 - s1*s1*u2*u2 - s1*s1*u3*u3 + 2*s1*s2*u1*u2 + 2*s1*s3*u1*u3 - s2*s2*u1*u1 - s2*s2*u3*u3 + 2*s2*s3*u2*u3 - s3*s3*u1*u1 - s3*s3*u2*u2) if (A == 0 or D < 0): return (False, Vector(0, 0, 0)) elif (obj == self): #pokud se jedna o stejny objekt - stin je False return (False, Vector(0, 0, 0)) t1 = (B + math.sqrt(D)) / (A) t2 = (B - math.sqrt(D)) / (A) #prusecik koule 1 x1 = c1 + t1*u1 y1 = c2 + t1*u2 z1 = c3 + t1*u3 p1 = Vector(x1, y1, z1) #prusecik koule 2 x2 = c1 + t2*u1 y2 = c2 + t2*u2 z2 = c3 + t2*u3 p2 = Vector(x2, y2, z2) #vybere blizsi prusecik if (p1.distance(ray.startPoint) > p2.distance(ray.startPoint)): #p2 je bliz return (True, p2) return (True, p1)
def getPosition(self): return Vector(self.x, self.y, self.z)
import math from SnejkyEngine.engine import Engine from SnejkyEngine.camera import Camera from SnejkyEngine.vector import Vector from SnejkyEngine.light import Light from SnejkyEngine.ball import Ball if __name__ == "__main__": width = 800 height = 800 running = True camera = Camera(Vector(0, 0, 0), Vector(0, 0, -1)) engine = Engine(None, width, height, camera) #cervena koule = Ball(engine, 2, (0, 0, -50), (255, 20, 100)) engine.addComponent(koule) #velka modra koule = Ball(engine, 10, (0, -15, -50), (0, 255, 255)) engine.addComponent(koule) #modra koule = Ball(engine, 2, (10, 2, -50), (0, 255, 255)) engine.addComponent(koule) #zelena koule = Ball(engine, 2, (-10, 2, -45), (0, 255, 10)) engine.addComponent(koule)