threequick 0.0.0__tar.gz → 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {threequick-0.0.0/src/threequick.egg-info → threequick-0.0.1}/PKG-INFO +3 -3
- threequick-0.0.1/README.md +2 -0
- {threequick-0.0.0 → threequick-0.0.1}/pyproject.toml +1 -1
- threequick-0.0.1/scripts/example.py +95 -0
- {threequick-0.0.0 → threequick-0.0.1}/src/threequick/threequick.py +14 -13
- {threequick-0.0.0 → threequick-0.0.1/src/threequick.egg-info}/PKG-INFO +3 -3
- threequick-0.0.0/README.md +0 -2
- threequick-0.0.0/scripts/example.py +0 -68
- {threequick-0.0.0 → threequick-0.0.1}/.gitignore +0 -0
- {threequick-0.0.0 → threequick-0.0.1}/LICENSE +0 -0
- {threequick-0.0.0 → threequick-0.0.1}/scripts/build-install-test.sh +0 -0
- {threequick-0.0.0 → threequick-0.0.1}/setup.cfg +0 -0
- {threequick-0.0.0 → threequick-0.0.1}/src/threequick/__init__.py +0 -0
- {threequick-0.0.0 → threequick-0.0.1}/src/threequick.egg-info/SOURCES.txt +0 -0
- {threequick-0.0.0 → threequick-0.0.1}/src/threequick.egg-info/dependency_links.txt +0 -0
- {threequick-0.0.0 → threequick-0.0.1}/src/threequick.egg-info/requires.txt +0 -0
- {threequick-0.0.0 → threequick-0.0.1}/src/threequick.egg-info/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: threequick
|
|
3
|
-
Version: 0.0.
|
|
4
|
-
Summary: A simple python library for creating 3D visualisations
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A simple python library for creating 3D visualisations
|
|
5
5
|
Author-email: Hannah Baldwin <contact@hannahbaldwin.net>
|
|
6
6
|
License: GPL-3.0
|
|
7
7
|
Project-URL: Homepage, https://github.com/habaldwin01/threequick
|
|
@@ -16,4 +16,4 @@ Requires-Dist: pygame>=2.0.0
|
|
|
16
16
|
Dynamic: license-file
|
|
17
17
|
|
|
18
18
|
# threequick
|
|
19
|
-
A simple python library for creating 3D visualisations
|
|
19
|
+
A simple python library for creating 3D visualisations.
|
|
@@ -5,7 +5,7 @@ authors = [
|
|
|
5
5
|
{ name="Hannah Baldwin", email="contact@hannahbaldwin.net" },
|
|
6
6
|
]
|
|
7
7
|
license = { text="GPL-3.0" }
|
|
8
|
-
description = "A simple python library for creating 3D visualisations
|
|
8
|
+
description = "A simple python library for creating 3D visualisations"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.6"
|
|
11
11
|
classifiers = [
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import pygame
|
|
2
|
+
import numpy as np
|
|
3
|
+
import math
|
|
4
|
+
from threequick import CameraContext, Object3d, Cube, Sphere, PointCloud
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
window = pygame.display.set_mode((1280, 720), pygame.RESIZABLE)
|
|
8
|
+
pygame.display.set_caption("threequick test")
|
|
9
|
+
done = False
|
|
10
|
+
renderable_objects = []
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
tc = Cube(0.2)
|
|
14
|
+
# pitch roll yaw
|
|
15
|
+
# x y z
|
|
16
|
+
tc.set_rotation(30,10,60)
|
|
17
|
+
tc.set_position(1,0,0)
|
|
18
|
+
renderable_objects.append(tc)
|
|
19
|
+
|
|
20
|
+
sp = Sphere(16, 6+1, 1)
|
|
21
|
+
renderable_objects.append(sp)
|
|
22
|
+
|
|
23
|
+
#point_cloud = PointCloud()
|
|
24
|
+
#renderable_objects.append(point_cloud)
|
|
25
|
+
|
|
26
|
+
#point_cloud.add_point([0,0.25,0.25], [0,255,0])
|
|
27
|
+
|
|
28
|
+
cam_dist = 2
|
|
29
|
+
|
|
30
|
+
camera_context = CameraContext([0,-cam_dist,0], [70,0,30], 90, window)
|
|
31
|
+
camera_context.position[0] = (math.sin(math.radians(camera_context.rotation[2])) * -cam_dist) * math.sin(math.radians(camera_context.rotation[0]))
|
|
32
|
+
camera_context.position[1] = (math.cos(math.radians(camera_context.rotation[2])) * -cam_dist) * math.sin(math.radians(camera_context.rotation[0]))
|
|
33
|
+
camera_context.position[2] = math.cos(math.radians(camera_context.rotation[0])) * -cam_dist
|
|
34
|
+
|
|
35
|
+
cube_angle = 0
|
|
36
|
+
|
|
37
|
+
pygame.init()
|
|
38
|
+
|
|
39
|
+
last_ticks = pygame.time.get_ticks()
|
|
40
|
+
|
|
41
|
+
while not done:
|
|
42
|
+
current_ticks = pygame.time.get_ticks()
|
|
43
|
+
|
|
44
|
+
pygame.draw.rect(window, (0, 0, 0), (0, 0, window.get_width(), window.get_height()))
|
|
45
|
+
|
|
46
|
+
mx, my = pygame.mouse.get_pos()
|
|
47
|
+
for event in pygame.event.get():
|
|
48
|
+
if event.type == pygame.QUIT:
|
|
49
|
+
exit()
|
|
50
|
+
|
|
51
|
+
left_button, middle_button, right_button = pygame.mouse.get_pressed()
|
|
52
|
+
if not left_button:
|
|
53
|
+
last_rc_pos = (mx, my)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
if left_button:
|
|
57
|
+
camera_context.rotation[0] -= (my - last_rc_pos[1]) * 0.2
|
|
58
|
+
if camera_context.rotation[0] > 180:
|
|
59
|
+
camera_context.rotation[0] = 180
|
|
60
|
+
if camera_context.rotation[0] < 0:
|
|
61
|
+
camera_context.rotation[0] = 0
|
|
62
|
+
smx = (math.sin(math.radians(camera_context.rotation[0]))) + 0.5
|
|
63
|
+
camera_context.rotation[2] -= (mx - last_rc_pos[0]) * 0.2 / smx
|
|
64
|
+
last_rc_pos = (mx, my)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
orbital_period_s = 8
|
|
68
|
+
cube_angle = ((pygame.time.get_ticks() / 1000) / orbital_period_s) * 360
|
|
69
|
+
|
|
70
|
+
tc.set_rotation(30,10,60 + cube_angle)
|
|
71
|
+
tc.set_position(math.sin(math.radians(cube_angle)),-math.cos(math.radians(cube_angle)),0)
|
|
72
|
+
|
|
73
|
+
# Slow rotation of camera
|
|
74
|
+
#camera_context.rotation[2] += (last_ticks - current_ticks) / 80
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# Calculate camera position based off angle so it always points at 0,0,0
|
|
78
|
+
camera_context.position[0] = (math.sin(math.radians(camera_context.rotation[2])) * -cam_dist) * math.sin(math.radians(camera_context.rotation[0]))
|
|
79
|
+
camera_context.position[1] = (math.cos(math.radians(camera_context.rotation[2])) * -cam_dist) * math.sin(math.radians(camera_context.rotation[0]))
|
|
80
|
+
camera_context.position[2] = math.cos(math.radians(camera_context.rotation[0])) * -cam_dist
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
last_ticks = current_ticks
|
|
84
|
+
|
|
85
|
+
camera_context.update_screenspace()
|
|
86
|
+
for ro in renderable_objects:
|
|
87
|
+
ro.draw(camera_context)
|
|
88
|
+
|
|
89
|
+
for event in pygame.event.get():
|
|
90
|
+
if event.type == pygame.QUIT:
|
|
91
|
+
done = True
|
|
92
|
+
|
|
93
|
+
pygame.display.flip()
|
|
94
|
+
|
|
95
|
+
exit()
|
|
@@ -42,10 +42,12 @@ class CameraContext:
|
|
|
42
42
|
def __init__(self,
|
|
43
43
|
position: list[float],
|
|
44
44
|
rotation: list[float],
|
|
45
|
+
fov: float,
|
|
45
46
|
surface: pygame.Surface):
|
|
46
47
|
self.position = position
|
|
47
48
|
self.rotation = rotation
|
|
48
49
|
self.screen_size = (1,1)
|
|
50
|
+
self.fov = fov
|
|
49
51
|
self.frustum_width = 1
|
|
50
52
|
self.frustum_height = 1
|
|
51
53
|
self.surface = surface
|
|
@@ -54,13 +56,13 @@ class CameraContext:
|
|
|
54
56
|
self.screen_size = (self.surface.get_width(), self.surface.get_height())
|
|
55
57
|
|
|
56
58
|
self.min_render_distance = 0.1
|
|
57
|
-
self.frustum_width = self.min_render_distance
|
|
59
|
+
self.frustum_width = self.min_render_distance * math.radians(self.fov)
|
|
58
60
|
self.frustum_height = self.frustum_width * (self.screen_size[1] / self.screen_size[0])
|
|
59
61
|
#self.projection_matrix = [[nx/2, 0, 0, (nx-1)/2],
|
|
60
62
|
# [0, ny/2, 0, (ny-1)/2],
|
|
61
63
|
# [0, 0, 1/2, 1/2 ]]
|
|
62
64
|
|
|
63
|
-
f =
|
|
65
|
+
f = 10 # far
|
|
64
66
|
n = self.min_render_distance # near
|
|
65
67
|
r = self.frustum_width # width
|
|
66
68
|
t = self.frustum_height # height
|
|
@@ -105,28 +107,27 @@ class Object3d(Renderable):
|
|
|
105
107
|
vertices: list[list[float]],
|
|
106
108
|
edges: list[list[int]],
|
|
107
109
|
faces: list[list[int]]) -> None:
|
|
108
|
-
self.__mod_vertices = vertices
|
|
109
|
-
self.__mod_edges = edges
|
|
110
|
-
self.__mod_faces = faces
|
|
110
|
+
self.__mod_vertices = [None] * len(vertices)
|
|
111
|
+
#self.__mod_edges = edges
|
|
112
|
+
#self.__mod_faces = faces
|
|
111
113
|
self.vertices = vertices
|
|
112
114
|
self.edges = edges
|
|
113
115
|
self.faces = faces
|
|
114
|
-
self.position = [0,0,0]
|
|
115
|
-
self.rotation_matrix =
|
|
116
|
-
|
|
117
|
-
[0, 0, 1, 0],
|
|
118
|
-
[0, 0, 0, 1]]
|
|
116
|
+
self.position = [0, 0, 0]
|
|
117
|
+
self.rotation_matrix = pry_rot_to_4x4(0, 0, 0)
|
|
118
|
+
self.update_vertex_cache()
|
|
119
119
|
|
|
120
120
|
def set_rotation(self, pitch, roll, yaw):
|
|
121
121
|
self.rotation_matrix = pry_rot_to_4x4(pitch, roll, yaw)
|
|
122
|
-
|
|
123
|
-
for vindex, vertex in enumerate(self.vertices):
|
|
124
|
-
self.__mod_vertices[vindex] = transform_3d_point_4x4_mat(self.rotation_matrix, vertex)
|
|
122
|
+
self.update_vertex_cache()
|
|
125
123
|
|
|
126
124
|
def set_position(self, x, y, z):
|
|
127
125
|
self.position = [x, y, z]
|
|
126
|
+
self.update_vertex_cache()
|
|
128
127
|
|
|
128
|
+
def update_vertex_cache(self):
|
|
129
129
|
for vindex, vertex in enumerate(self.vertices):
|
|
130
|
+
vertex = transform_3d_point_4x4_mat(self.rotation_matrix, vertex)
|
|
130
131
|
self.__mod_vertices[vindex] = [vertex[0] + self.position[0], vertex[1] + self.position[1], vertex[2] + self.position[2]]
|
|
131
132
|
|
|
132
133
|
def draw(self, camera_context: CameraContext) -> None:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: threequick
|
|
3
|
-
Version: 0.0.
|
|
4
|
-
Summary: A simple python library for creating 3D visualisations
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A simple python library for creating 3D visualisations
|
|
5
5
|
Author-email: Hannah Baldwin <contact@hannahbaldwin.net>
|
|
6
6
|
License: GPL-3.0
|
|
7
7
|
Project-URL: Homepage, https://github.com/habaldwin01/threequick
|
|
@@ -16,4 +16,4 @@ Requires-Dist: pygame>=2.0.0
|
|
|
16
16
|
Dynamic: license-file
|
|
17
17
|
|
|
18
18
|
# threequick
|
|
19
|
-
A simple python library for creating 3D visualisations
|
|
19
|
+
A simple python library for creating 3D visualisations.
|
threequick-0.0.0/README.md
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import pygame
|
|
2
|
-
import numpy as np
|
|
3
|
-
import math
|
|
4
|
-
from threequick import CameraContext, Object3d, Cube, Sphere, PointCloud
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
window = pygame.display.set_mode((1280, 720), pygame.RESIZABLE)
|
|
8
|
-
pygame.display.set_caption("threequick test")
|
|
9
|
-
done = False
|
|
10
|
-
renderable_objects = []
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
tc = Cube(0.2)
|
|
14
|
-
# pitch roll yaw
|
|
15
|
-
# x y z
|
|
16
|
-
tc.set_rotation(30,10,60)
|
|
17
|
-
renderable_objects.append(tc)
|
|
18
|
-
|
|
19
|
-
sp = Sphere(16, 6+1, 1)
|
|
20
|
-
renderable_objects.append(sp)
|
|
21
|
-
|
|
22
|
-
point_cloud = PointCloud()
|
|
23
|
-
renderable_objects.append(point_cloud)
|
|
24
|
-
|
|
25
|
-
point_cloud.add_point([0,0.25,0.25], [0,255,0])
|
|
26
|
-
|
|
27
|
-
cam_dist = 2
|
|
28
|
-
|
|
29
|
-
camera_context = CameraContext([0,-cam_dist,0], [90,0,0], window)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
while not done:
|
|
33
|
-
pygame.draw.rect(window, (0, 0, 0), (0, 0, 1280, 720))
|
|
34
|
-
|
|
35
|
-
mx, my = pygame.mouse.get_pos()
|
|
36
|
-
for event in pygame.event.get():
|
|
37
|
-
if event.type == pygame.QUIT:
|
|
38
|
-
exit()
|
|
39
|
-
|
|
40
|
-
left_button, middle_button, right_button = pygame.mouse.get_pressed()
|
|
41
|
-
if not left_button:
|
|
42
|
-
last_rc_pos = (mx, my)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if left_button:
|
|
46
|
-
camera_context.rotation[0] -= (my - last_rc_pos[1]) * 0.2
|
|
47
|
-
if camera_context.rotation[0] > 180:
|
|
48
|
-
camera_context.rotation[0] = 180
|
|
49
|
-
if camera_context.rotation[0] < 0:
|
|
50
|
-
camera_context.rotation[0] = 0
|
|
51
|
-
smx = (math.sin(math.radians(camera_context.rotation[0]))) + 0.5
|
|
52
|
-
camera_context.rotation[2] -= (mx - last_rc_pos[0]) * 0.2 / smx
|
|
53
|
-
camera_context.position[0] = (math.sin(math.radians(camera_context.rotation[2])) * -cam_dist) * math.sin(math.radians(camera_context.rotation[0]))
|
|
54
|
-
camera_context.position[1] = (math.cos(math.radians(camera_context.rotation[2])) * -cam_dist) * math.sin(math.radians(camera_context.rotation[0]))
|
|
55
|
-
camera_context.position[2] = math.cos(math.radians(camera_context.rotation[0])) * -cam_dist
|
|
56
|
-
last_rc_pos = (mx, my)
|
|
57
|
-
|
|
58
|
-
camera_context.update_screenspace()
|
|
59
|
-
for ro in renderable_objects:
|
|
60
|
-
ro.draw(camera_context)
|
|
61
|
-
|
|
62
|
-
for event in pygame.event.get():
|
|
63
|
-
if event.type == pygame.QUIT:
|
|
64
|
-
done = True
|
|
65
|
-
|
|
66
|
-
pygame.display.flip()
|
|
67
|
-
|
|
68
|
-
exit()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|