MCPcopy Create free account
hub / github.com/ICE27182/Python-3D-renderer / Particles

Class Particles

particles.py:7–63  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

5random_table = [uniform(-1, 1) for _ in range(255)]
6
7class Particles:
8 def __init__(self, density=10, position=(0, 0, 0), size=1) -> None:
9 self.density = density
10 self.position = position
11 self.size = size
12 self.density_r = 1 / density
13 self.particles = [
14 [x * self.density_r + position[0], y * self.density_r + position[1], z * self.density_r + position[2],]
15 for x in range(density * size) for y in range(density * size) for z in range(density * size)
16 ]
17 for particle in self.particles:
18 particle[0] += random_table[int((particle[1] + particle[2]) * self.density) % 255] * self.density_r
19 particle[1] += random_table[int((particle[0] + particle[2]) * self.density) % 255] * self.density_r
20 particle[2] += random_table[int((particle[0] + particle[1]) * self.density) % 255] * self.density_r
21 particle[0] = (particle[0] - self.position[0]) % self.size + self.position[0]
22 particle[1] = (particle[1] - self.position[1]) % self.size + self.position[1]
23 particle[2] = (particle[2] - self.position[2]) % self.size + self.position[2]
24
25 def next_frame(self, time=0, percentage = 0.1):
26 start_index = int(len(self.particles) * random_table[time % 255])
27 end_index = int(len(self.particles) * percentage) + start_index
28 for index in range(start_index, end_index):
29 particle = self.particles[index % len(self.particles)]
30 particle[0] += random_table[int((particle[1] + particle[2]) * self.density) % 255] * self.density_r * 0.01
31 particle[1] += random_table[int((particle[0] + particle[2]) * self.density) % 255] * self.density_r * 0.01
32 particle[2] += random_table[int((particle[0] + particle[1]) * self.density) % 255] * self.density_r * 0.01
33 particle[0] = (particle[0] - self.position[0]) % self.size + self.position[0]
34 particle[1] = (particle[1] - self.position[1]) % self.size + self.position[1]
35 particle[2] = (particle[2] - self.position[2]) % self.size + self.position[2]
36
37 def add_to_frame(self, frame:list, lights:list, cam) -> list:
38
39 for particle in self.particles:
40 x = particle[0] - cam.x
41 y = particle[1] - cam.y
42 z = particle[2] - cam.z
43 x, y, z = (
44 x * cam.rotation[0][0] + y * cam.rotation[0][1] + z * cam.rotation[0][2],
45 x * cam.rotation[1][0] + y * cam.rotation[1][1] + z * cam.rotation[1][2],
46 x * cam.rotation[2][0] + y * cam.rotation[2][1] + z * cam.rotation[2][2],
47 )
48 if z <= cam.z_near:
49 continue
50
51 x2d = cam.width // 2 + int(x * cam.rendering_plane_z / z)
52 y2d = cam.height // 2 - int(y * cam.rendering_plane_z / z)
53 if not (0 <= x2d < cam.width and 0 <= y2d < cam.height):
54 continue
55
56
57 for light in lights:
58 distance_2 = (x - light.x_in_cam) * (x - light.x_in_cam) + (y - light.y_in_cam) * (y - light.y_in_cam) + (z - light.z_in_cam) * (z - light.z_in_cam)
59 if distance_2 < 400:
60 frame[y2d][x2d] = (min(255, int(frame[y2d][x2d][0] + 50 / distance_2)),
61 min(255, int(frame[y2d][x2d][1] + 50 / distance_2)),
62 min(255, int(frame[y2d][x2d][2] + 50 / distance_2)))
63 return frame
64

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected