Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import pygame, sys, os, math
- def rotate2d(pos,rad): x,y=pos; s,c = math.sin(rad),math.cos(rad); return x*c-y*s,y*c+x*s
- class Cam:
- def __init__(self,pos=(0,0,0),rot=(0,0)):
- self.pos = list(pos)
- self.rot = list(rot)
- def events(self,event):
- if event.type == pygame.MOUSEMOTION:
- x,y = event.rel; x/=200; y/=200
- self.rot[0]+=y; self.rot[1]+=x
- def update(self,dt,key):
- s = dt*4
- if key[pygame.K_q]: self.pos[1]+=s
- if key[pygame.K_e]: self.pos[1]-=s
- x,y = s*math.sin(self.rot[1]),s*math.cos(self.rot[1])
- if key[pygame.K_w]: self.pos[0]+=x; self.pos[2]+=y
- if key[pygame.K_s]: self.pos[0]-=x; self.pos[2]-=y
- if key[pygame.K_a]: self.pos[0]-=y; self.pos[2]+=x
- if key[pygame.K_d]: self.pos[0]+=y; self.pos[2]-=x
- # ------------------------- Generating Sphere --------------------------- #
- A,B = 9,18
- points = [(0,-1,0)]
- for zRot in range(A,180,A):
- X,y = rotate2d((0,-1),zRot/180*math.pi)
- for yRot in range(0,360,B):
- z,x = rotate2d((0,X),yRot/180*math.pi)
- points+=[(x,y,z)]
- points+=[(0,1,0)]
- a = len(range(A,180,A)); b = len(range(0,360,B))
- n = len(points)-1; n2 = b*(a-1)
- po = []
- for i in range(1,b+1):
- if i==b: po+=[(0,i,1)]
- else: po+=[(0,i,i+1)]
- for j in range(0,(a-1)*b,b):
- for i in range(1,b+1):
- if i==b: po+=[(i+j,i+b+j,i+1+j,1+j)]
- else: po+=[(i+j,i+b+j,i+b+1+j,i+1+j)]
- for i in range(1,b+1):
- if i==b: po+=[(n,i+n2,1+n2)]
- else: po+=[(n,i+n2,i+1+n2)]
- class Sphere:
- vertices = points
- faces = po
- colors = (255,0,0),(255,255,0),(0,255,255)
- def __init__(self,pos=(0,0,0)):
- x,y,z = pos
- self.verts = [(x+X/2,y+Y/2,z+Z/2) for X,Y,Z in self.vertices]
- # ------------------------- Generated Sphere --------------------------- #
- pygame.init()
- w,h = 800,600; cx,cy = w//2,h//2; fov = min(w,h)
- os.environ['SDL_VIDEO_CENTERED'] = '1'
- pygame.display.set_caption('3D Graphics')
- screen = pygame.display.set_mode((w,h))
- clock = pygame.time.Clock()
- cam = Cam((0,0,0),(math.pi/2,0))
- pygame.event.get(); pygame.mouse.get_rel()
- pygame.mouse.set_visible(0); pygame.event.set_grab(1)
- spheres = [Sphere((x,0,z)) for x,z in ((-1,0),(0,0),(1,0))]
- rot = 0
- while True:
- dt = clock.tick()/1000
- rot+=math.pi*dt*0.5
- for event in pygame.event.get():
- if event.type == pygame.QUIT: pygame.quit(); sys.exit()
- if event.type == pygame.KEYDOWN:
- if event.key == pygame.K_ESCAPE: pygame.quit(); sys.exit()
- cam.events(event)
- screen.fill((128,128,255))
- # need to go though all objects, get all faces...
- face_list = []; face_color = []; depth = [] # stores all face data
- for obj in spheres:
- vert_list = []; screen_coords = []
- for x,y,z in obj.verts:
- x,z = rotate2d((x,z),rot)
- x-=cam.pos[0]; y-=cam.pos[1]; z-=cam.pos[2]
- x,z = rotate2d((x,z),cam.rot[1])
- y,z = rotate2d((y,z),cam.rot[0])
- vert_list += [(x,y,z)]
- f = fov/z if z else fov; x,y = x*f,y*f
- screen_coords+=[(cx+int(x),cy+int(y))]
- for f in range(len(obj.faces)):
- face = obj.faces[f]
- on_screen = False
- for i in face:
- x,y = screen_coords[i]
- if vert_list[i][2]>0 and x>0 and x<w and y>0 and y<h: on_screen = True; break
- if on_screen:
- coords = [screen_coords[i] for i in face]
- face_list += [coords]
- face_color += [obj.colors[f%3]]
- depth += [sum(vert_list[i][2] for i in face)/len(face)]
- # final drawing part, all faces from all objects
- order = sorted(range(len(face_list)),key=lambda i:depth[i],reverse=1)
- for i in order:
- try: pygame.draw.polygon(screen,face_color[i],face_list[i])
- except: pass
- pygame.display.flip()
- key = pygame.key.get_pressed()
- cam.update(dt,key)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement