aether-engine 1.0.0__py3-none-any.whl

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.
Files changed (64) hide show
  1. aether/__init__.py +54 -0
  2. aether/audio/__init__.py +0 -0
  3. aether/audio/audio_manager.py +211 -0
  4. aether/audio/music.py +6 -0
  5. aether/audio/sound.py +6 -0
  6. aether/core/__init__.py +211 -0
  7. aether/core/achievement_system.py +304 -0
  8. aether/core/application.py +19 -0
  9. aether/core/config.py +75 -0
  10. aether/core/console.py +366 -0
  11. aether/core/engine.py +50 -0
  12. aether/core/event_bus.py +24 -0
  13. aether/core/input.py +58 -0
  14. aether/core/plugin_system.py +93 -0
  15. aether/core/save_system.py +409 -0
  16. aether/core/time_manager.py +25 -0
  17. aether/core/window.py +57 -0
  18. aether/graphics/__init__.py +0 -0
  19. aether/graphics/camera.py +69 -0
  20. aether/graphics/framebuffer.py +119 -0
  21. aether/graphics/light.py +32 -0
  22. aether/graphics/lod_system.py +170 -0
  23. aether/graphics/material.py +25 -0
  24. aether/graphics/mesh.py +83 -0
  25. aether/graphics/mesh_factory.py +67 -0
  26. aether/graphics/particle_system.py +268 -0
  27. aether/graphics/post_process.py +279 -0
  28. aether/graphics/renderer.py +135 -0
  29. aether/graphics/shader.py +61 -0
  30. aether/graphics/shader_library.py +157 -0
  31. aether/graphics/sky_atmosphere.py +309 -0
  32. aether/graphics/terrain.py +408 -0
  33. aether/graphics/texture.py +34 -0
  34. aether/graphics/water.py +432 -0
  35. aether/physics/__init__.py +0 -0
  36. aether/physics/bullet_backend.py +395 -0
  37. aether/physics/collider.py +22 -0
  38. aether/physics/physics_world.py +436 -0
  39. aether/physics/raycast.py +25 -0
  40. aether/physics/rigidbody.py +7 -0
  41. aether/resources/__init__.py +0 -0
  42. aether/resources/asset_database.py +76 -0
  43. aether/resources/resource_manager.py +147 -0
  44. aether/resources/serialization.py +114 -0
  45. aether/scene/__init__.py +0 -0
  46. aether/scene/component.py +368 -0
  47. aether/scene/entity.py +46 -0
  48. aether/scene/scene.py +33 -0
  49. aether/scene/scene_graph.py +252 -0
  50. aether/scene/scene_manager.py +191 -0
  51. aether/ui/__init__.py +0 -0
  52. aether/ui/button.py +297 -0
  53. aether/ui/canvas.py +11 -0
  54. aether/ui/text.py +286 -0
  55. aether/utils/__init__.py +0 -0
  56. aether/utils/logger.py +16 -0
  57. aether/utils/math_utils.py +31 -0
  58. aether/utils/object_pool.py +137 -0
  59. aether/utils/profiler.py +187 -0
  60. aether_engine-1.0.0.dist-info/METADATA +71 -0
  61. aether_engine-1.0.0.dist-info/RECORD +64 -0
  62. aether_engine-1.0.0.dist-info/WHEEL +5 -0
  63. aether_engine-1.0.0.dist-info/licenses/LICENSE +21 -0
  64. aether_engine-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,309 @@
1
+ """Система неба, атмосферы и освещения окружения"""
2
+ import numpy as np
3
+ from OpenGL.GL import *
4
+ from typing import Optional, Tuple
5
+ from aether.graphics.shader import Shader
6
+ from aether.graphics.mesh_factory import MeshFactory
7
+ from aether.graphics.mesh import Mesh
8
+ from aether.graphics.texture import Texture
9
+
10
+
11
+ class SkyDome:
12
+ """Купол неба с процедурной генерацией"""
13
+
14
+ def __init__(self, radius: float = 500.0):
15
+ self.radius = radius
16
+ self.mesh: Optional[Mesh] = None
17
+
18
+ # Параметры неба
19
+ self.sun_position = np.array([100.0, 100.0, 0.0], dtype=np.float32)
20
+ self.sun_color = np.array([1.0, 0.9, 0.7], dtype=np.float32)
21
+ self.sun_intensity = 1.5
22
+ self.sun_disk_size = 5.0
23
+
24
+ # Цвета неба
25
+ self.sky_top_color = np.array([0.3, 0.5, 0.9], dtype=np.float32)
26
+ self.sky_horizon_color = np.array([0.7, 0.8, 1.0], dtype=np.float32)
27
+ self.sky_bottom_color = np.array([0.4, 0.4, 0.5], dtype=np.float32)
28
+
29
+ # Атмосфера
30
+ self.atmosphere_density = 1.0
31
+ self.mie_scattering = 0.1
32
+ self.rayleigh_scattering = 0.5
33
+
34
+ # Генерация
35
+ self._generate_mesh()
36
+ self._setup_shader()
37
+
38
+ print(f"[SkyDome] Created (radius: {radius})")
39
+
40
+ def _generate_mesh(self):
41
+ """Генерирует сферу для неба"""
42
+ self.mesh = MeshFactory.create_sphere(self.radius, 64)
43
+
44
+ def _setup_shader(self):
45
+ """Настройка шейдера неба"""
46
+ vertex_shader = """
47
+ #version 460 core
48
+ layout(location = 0) in vec3 aPos;
49
+
50
+ out vec3 WorldPos;
51
+ out vec3 LocalPos;
52
+
53
+ uniform mat4 model;
54
+ uniform mat4 view;
55
+ uniform mat4 projection;
56
+
57
+ void main() {
58
+ vec4 worldPos = model * vec4(aPos, 1.0);
59
+ WorldPos = worldPos.xyz;
60
+ LocalPos = aPos;
61
+
62
+ // Отключаем трансляцию для неба
63
+ mat4 skyView = mat4(mat3(view));
64
+ gl_Position = projection * skyView * worldPos;
65
+ }
66
+ """
67
+
68
+ fragment_shader = """
69
+ #version 460 core
70
+ in vec3 WorldPos;
71
+ in vec3 LocalPos;
72
+
73
+ out vec4 FragColor;
74
+
75
+ uniform vec3 sunPosition;
76
+ uniform vec3 sunColor;
77
+ uniform float sunIntensity;
78
+ uniform float sunDiskSize;
79
+
80
+ uniform vec3 skyTopColor;
81
+ uniform vec3 skyHorizonColor;
82
+ uniform vec3 skyBottomColor;
83
+
84
+ uniform float atmosphereDensity;
85
+ uniform float mieScattering;
86
+ uniform float rayleighScattering;
87
+
88
+ void main() {
89
+ vec3 pos = normalize(LocalPos);
90
+ vec3 sunDir = normalize(sunPosition);
91
+
92
+ // Высота (для градиента неба)
93
+ float height = pos.y;
94
+ float horizonBlend = 1.0 - abs(height);
95
+ horizonBlend = pow(horizonBlend, 2.0);
96
+
97
+ // Базовый градиент неба
98
+ vec3 skyGradient;
99
+ if (height > 0.0) {
100
+ skyGradient = mix(skyHorizonColor, skyTopColor, pow(height, 0.5));
101
+ } else {
102
+ skyGradient = mix(skyBottomColor, skyHorizonColor, pow(abs(height), 0.5));
103
+ }
104
+
105
+ // Солнце
106
+ float sunAngle = dot(pos, sunDir);
107
+ float sunDisk = smoothstep(1.0 - sunDiskSize * 0.001,
108
+ 1.0 - sunDiskSize * 0.002,
109
+ sunAngle);
110
+
111
+ // Ореол вокруг солнца
112
+ float sunGlow = exp(sunAngle * 20.0 - 20.0) * 0.5;
113
+ float sunHalo = pow(max(sunAngle, 0.0), 100.0) * 0.3;
114
+
115
+ vec3 sunContribution = sunColor * sunIntensity * (sunDisk + sunGlow + sunHalo);
116
+
117
+ // Рэлеевское рассеяние (голубой цвет)
118
+ float rayleigh = pow(1.0 - abs(height), rayleighScattering * 5.0);
119
+ vec3 rayleighColor = vec3(0.3, 0.5, 0.9);
120
+
121
+ // Ми-рассеяние (белый цвет вокруг солнца)
122
+ float mie = exp(-(1.0 - sunAngle) * mieScattering * 10.0);
123
+ vec3 mieColor = vec3(1.0, 0.9, 0.7);
124
+
125
+ // Комбинируем
126
+ vec3 atmosphere = rayleighColor * rayleigh * atmosphereDensity;
127
+ atmosphere += mieColor * mie * atmosphereDensity * 0.5;
128
+
129
+ vec3 finalColor = skyGradient + atmosphere + sunContribution;
130
+
131
+ // HDR tonemapping
132
+ finalColor = finalColor / (finalColor + vec3(1.0));
133
+
134
+ FragColor = vec4(finalColor, 1.0);
135
+ }
136
+ """
137
+
138
+ from aether.graphics.shader import Shader
139
+ self.shader = Shader(vertex_shader, fragment_shader)
140
+
141
+ def set_time_of_day(self, time: float):
142
+ """Устанавливает время суток (0.0 - 24.0)"""
143
+ # Вычисляем позицию солнца
144
+ angle = (time - 6.0) * np.pi / 12.0 # Восход в 6, закат в 18
145
+
146
+ self.sun_position = np.array([
147
+ np.cos(angle) * 500.0,
148
+ np.sin(angle) * 500.0,
149
+ 0.0
150
+ ], dtype=np.float32)
151
+
152
+ # Меняем цвета в зависимости от времени
153
+ if 6 <= time <= 18: # День
154
+ t = (time - 6) / 12
155
+ self.sky_top_color = np.array([0.3, 0.5 + t * 0.2, 0.9], dtype=np.float32)
156
+ self.sun_intensity = 1.5
157
+ elif time < 6 or time > 18: # Ночь
158
+ night_factor = 1.0 if time < 4 or time > 20 else 0.5
159
+ self.sky_top_color = np.array([0.05, 0.05, 0.15 * night_factor + 0.1], dtype=np.float32)
160
+ self.sun_intensity = 0.1
161
+
162
+ def render(self, view: np.ndarray, projection: np.ndarray):
163
+ """Рендерит небо"""
164
+ if not self.mesh or not self.shader:
165
+ return
166
+
167
+ glDepthFunc(GL_LEQUAL)
168
+ glDepthMask(GL_FALSE)
169
+
170
+ self.shader.use()
171
+
172
+ model = np.identity(4, dtype=np.float32)
173
+ self.shader.set_mat4("model", model)
174
+ self.shader.set_mat4("view", view)
175
+ self.shader.set_mat4("projection", projection)
176
+
177
+ # Параметры солнца
178
+ self.shader.set_vec3("sunPosition", self.sun_position)
179
+ self.shader.set_vec3("sunColor", self.sun_color)
180
+ self.shader.set_float("sunIntensity", self.sun_intensity)
181
+ self.shader.set_float("sunDiskSize", self.sun_disk_size)
182
+
183
+ # Цвета неба
184
+ self.shader.set_vec3("skyTopColor", self.sky_top_color)
185
+ self.shader.set_vec3("skyHorizonColor", self.sky_horizon_color)
186
+ self.shader.set_vec3("skyBottomColor", self.sky_bottom_color)
187
+
188
+ # Атмосфера
189
+ self.shader.set_float("atmosphereDensity", self.atmosphere_density)
190
+ self.shader.set_float("mieScattering", self.mie_scattering)
191
+ self.shader.set_float("rayleighScattering", self.rayleigh_scattering)
192
+
193
+ self.mesh.draw()
194
+
195
+ glDepthFunc(GL_LESS)
196
+ glDepthMask(GL_TRUE)
197
+
198
+
199
+ class VolumetricClouds:
200
+ """Объёмные облака"""
201
+
202
+ def __init__(self, coverage: float = 0.5):
203
+ self.coverage = coverage
204
+ self.cloud_scale = 100.0
205
+ self.cloud_height = 200.0
206
+ self.cloud_thickness = 50.0
207
+
208
+ self.wind_direction = np.array([1.0, 0.0, 0.0], dtype=np.float32)
209
+ self.wind_speed = 10.0
210
+ self.time = 0.0
211
+
212
+ self._setup_shader()
213
+ print(f"[Clouds] Created (coverage: {coverage})")
214
+
215
+ def _setup_shader(self):
216
+ """Шейдер объёмных облаков"""
217
+ vertex_shader = """
218
+ #version 460 core
219
+ layout(location = 0) in vec3 aPos;
220
+ out vec3 WorldPos;
221
+ uniform mat4 model;
222
+ uniform mat4 view;
223
+ uniform mat4 projection;
224
+ void main() {
225
+ WorldPos = (model * vec4(aPos, 1.0)).xyz;
226
+ gl_Position = projection * view * vec4(WorldPos, 1.0);
227
+ }
228
+ """
229
+
230
+ fragment_shader = """
231
+ #version 460 core
232
+ in vec3 WorldPos;
233
+ out vec4 FragColor;
234
+
235
+ uniform float time;
236
+ uniform float coverage;
237
+ uniform float cloudScale;
238
+ uniform float cloudHeight;
239
+ uniform float cloudThickness;
240
+ uniform vec3 windDirection;
241
+ uniform float windSpeed;
242
+ uniform vec3 sunPosition;
243
+
244
+ // Шум (можно заменить на текстуру шума)
245
+ float hash(vec3 p) {
246
+ p = fract(p * 0.3183099 + 0.1);
247
+ p *= 17.0;
248
+ return fract(p.x * p.y * p.z * (p.x + p.y + p.z));
249
+ }
250
+
251
+ float noise(vec3 p) {
252
+ vec3 i = floor(p);
253
+ vec3 f = fract(p);
254
+ f = f * f * (3.0 - 2.0 * f);
255
+
256
+ return mix(
257
+ mix(mix(hash(i), hash(i + vec3(1,0,0)), f.x),
258
+ mix(hash(i + vec3(0,1,0)), hash(i + vec3(1,1,0)), f.x), f.y),
259
+ mix(mix(hash(i + vec3(0,0,1)), hash(i + vec3(1,0,1)), f.x),
260
+ mix(hash(i + vec3(0,1,1)), hash(i + vec3(1,1,1)), f.x), f.y), f.z);
261
+ }
262
+
263
+ float fbm(vec3 p) {
264
+ float value = 0.0;
265
+ float amplitude = 0.5;
266
+ float frequency = 1.0;
267
+
268
+ for (int i = 0; i < 4; i++) {
269
+ value += amplitude * noise(p * frequency);
270
+ frequency *= 2.0;
271
+ amplitude *= 0.5;
272
+ }
273
+
274
+ return value;
275
+ }
276
+
277
+ void main() {
278
+ vec3 pos = WorldPos / cloudScale;
279
+ pos += windDirection * time * windSpeed * 0.01;
280
+
281
+ // Сэмплируем облака
282
+ float heightFactor = smoothstep(cloudHeight - cloudThickness, cloudHeight, WorldPos.y) *
283
+ smoothstep(cloudHeight + cloudThickness, cloudHeight, WorldPos.y);
284
+
285
+ float cloud = fbm(pos);
286
+ cloud = (cloud - (1.0 - coverage)) / coverage;
287
+ cloud = clamp(cloud, 0.0, 1.0);
288
+ cloud *= heightFactor;
289
+
290
+ // Освещение от солнца
291
+ vec3 sunDir = normalize(sunPosition);
292
+ float sunLight = max(dot(vec3(0,1,0), sunDir), 0.0);
293
+
294
+ vec3 cloudColor = mix(vec3(0.8, 0.8, 0.8), vec3(1.0, 0.9, 0.7), sunLight * 0.3);
295
+ cloudColor *= 0.7 + sunLight * 0.3;
296
+
297
+ FragColor = vec4(cloudColor, cloud * 0.7);
298
+ }
299
+ """
300
+
301
+ from aether.graphics.shader import Shader
302
+ self.shader = Shader(vertex_shader, fragment_shader)
303
+
304
+ def update(self, dt: float):
305
+ self.time += dt
306
+
307
+ def render(self, view, projection):
308
+ """Рендерит облака"""
309
+ pass # Требует специального подхода к рендерингу