This repository has been archived by the owner on May 30, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
object_3d.py
124 lines (82 loc) · 3.48 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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# !/usr/bin/env python3
# -*- coding: utf-8 -*-
# ,_ _
# |\\_,-~/
# / _ _ | ,--.
# ( @ @ ) / ,-' ___ __ __ __
# \ _T_/-._( ( / | / /_ ____/ /__ / /
# / `. \ / /| | / __ \/ __ / _ \/ /
# | _ \ | / ___ |/ /_/ / /_/ / __/ /
# \ \ , / | /_/ |_/_.___/\__,_/\___/_/
# || |-_\__ / © 2022
# ((_/`(____,-'
# 3D ENGINE @v0.0.1
from matrix import *
from constants import *
import pygame as pg
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([np.array(v) for v in vertices])
self.faces = np.array([np.array(face) for face in faces], dtype=object)
self.translate([0.0001, 0.0001, 0.0001])
self.font = pg.font.Font(
"resources/IBMPlexMono-Regular.ttf", 30, bold=True)
self.color_faces = [(pg.Color("orange"), face) for face in self.faces]
self.label = ""
def draw(self):
self.screen_projection()
self.movement()
def movement(self):
if get_value("MOVEMENT_FLAG") == "True":
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
try:
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])
except:
pass
if get_value("DRAW_VERTICES") == "True":
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)]
set_value("DRAW_VERTICES", "False")
self.label = "XYZ"