-
Notifications
You must be signed in to change notification settings - Fork 61
/
object_3d.py
77 lines (60 loc) · 2.74 KB
/
object_3d.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import pygame as pg
from matrix_functions import *
from numba import njit
@njit(fastmath=True)
def any_func(arr, a, b):
return np.any((arr == a) | (arr == b))
class Object3D:
def __init__(self, render, vertices='', faces=''):
self.render = render
self.vertices = np.array(vertices)
self.faces = faces
self.translate([0.0001, 0.0001, 0.0001])
self.font = pg.font.SysFont('Arial', 30, bold=True)
self.color_faces = [(pg.Color('orange'), face) for face in self.faces]
self.movement_flag, self.draw_vertices = True, False
self.label = ''
def draw(self):
self.screen_projection()
self.movement()
def movement(self):
if self.movement_flag:
self.rotate_y(-(pg.time.get_ticks() % 0.005))
def screen_projection(self):
vertices = self.vertices @ self.render.camera.camera_matrix()
vertices = vertices @ self.render.projection.projection_matrix
vertices /= vertices[:, -1].reshape(-1, 1)
vertices[(vertices > 2) | (vertices < -2)] = 0
vertices = vertices @ self.render.projection.to_screen_matrix
vertices = vertices[:, :2]
for index, color_face in enumerate(self.color_faces):
color, face = color_face
polygon = vertices[face]
if not any_func(polygon, self.render.H_WIDTH, self.render.H_HEIGHT):
pg.draw.polygon(self.render.screen, color, polygon, 1)
if self.label:
text = self.font.render(self.label[index], True, pg.Color('white'))
self.render.screen.blit(text, polygon[-1])
if self.draw_vertices:
for vertex in vertices:
if not any_func(vertex, self.render.H_WIDTH, self.render.H_HEIGHT):
pg.draw.circle(self.render.screen, pg.Color('white'), vertex, 2)
def translate(self, pos):
self.vertices = self.vertices @ translate(pos)
def scale(self, scale_to):
self.vertices = self.vertices @ scale(scale_to)
def rotate_x(self, angle):
self.vertices = self.vertices @ rotate_x(angle)
def rotate_y(self, angle):
self.vertices = self.vertices @ rotate_y(angle)
def rotate_z(self, angle):
self.vertices = self.vertices @ rotate_z(angle)
class Axes(Object3D):
def __init__(self, render):
super().__init__(render)
self.vertices = np.array([(0, 0, 0, 1), (1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1)])
self.faces = np.array([(0, 1), (0, 2), (0, 3)])
self.colors = [pg.Color('red'), pg.Color('green'), pg.Color('blue')]
self.color_faces = [(color, face) for color, face in zip(self.colors, self.faces)]
self.draw_vertices = False
self.label = 'XYZ'