1#![allow(dead_code, unused_variables, unused_imports, unused_mut, unused_parens, non_snake_case, unreachable_patterns, unused_assignments, unused_labels, unused_doc_comments, private_interfaces, clippy::all)]
2
3pub mod math;
32pub mod glyph;
33pub mod entity;
34pub mod particle;
35pub mod scene;
36pub mod render;
37pub mod audio;
38pub mod integration;
39pub mod input;
40pub mod config;
41pub mod tween;
42pub mod debug;
43pub mod ui;
44pub mod timeline;
45pub mod procedural;
46pub mod physics;
47pub mod combat;
48pub mod spatial;
49pub mod effects;
50pub mod anim;
51pub mod animation;
52pub mod ai;
53pub mod networking;
54pub mod replay;
55pub mod scripting;
56pub mod terrain;
57pub mod ecs;
58pub mod editor;
59pub mod asset;
60pub mod save;
61pub mod character;
62pub mod dsp;
63pub mod game;
64pub mod profiler;
65pub mod vfx;
66pub mod netcode;
67pub mod network;
68pub mod world;
69pub mod crafting;
70pub mod pathfinding;
71pub mod economy;
72pub mod behavior;
73pub mod weather;
74pub mod deferred;
75pub mod shader_graph;
76pub mod surfaces;
77pub mod rendergraph;
78pub mod compute;
79pub mod lighting;
80pub mod number_theory;
81pub mod graph;
82pub mod topology;
83pub mod stochastic;
84pub mod ml;
85pub mod wgpu_backend;
86pub mod geometry;
87pub mod symbolic;
88pub mod solver;
89pub mod fractal;
90pub mod worldgen;
91pub mod ecology;
92pub mod narrative;
93pub mod electromagnetic;
94pub mod relativistic;
95pub mod quantum;
96
97pub use config::EngineConfig;
98pub use math::{MathFunction, ForceField, Falloff, AttractorType};
99pub use glyph::{Glyph, RenderLayer, BlendMode};
100pub use entity::AmorphousEntity;
101pub use particle::{MathParticle, ParticleInteraction};
102pub use scene::SceneGraph;
103pub use render::camera::ProofCamera;
104pub use input::{InputState, Key};
105pub use render::pipeline::FrameStats;
106pub use audio::AudioEvent;
107
108pub struct ProofEngine {
110 pub config: EngineConfig,
111 pub scene: SceneGraph,
112 pub camera: ProofCamera,
113 pub input: InputState,
114 pub audio: Option<audio::AudioEngine>,
116 pipeline: Option<render::Pipeline>,
118}
119
120impl ProofEngine {
121 pub fn new(config: EngineConfig) -> Self {
122 let audio = if config.audio.enabled {
123 audio::AudioEngine::try_new()
124 } else {
125 None
126 };
127 Self {
128 camera: ProofCamera::new(&config),
129 scene: SceneGraph::new(),
130 input: InputState::new(),
131 audio,
132 config,
133 pipeline: None,
134 }
135 }
136
137 pub fn emit_audio(&self, event: audio::AudioEvent) {
139 if let Some(ref a) = self.audio {
140 a.emit(event);
141 }
142 }
143
144 pub fn run<F>(&mut self, mut update: F)
147 where
148 F: FnMut(&mut ProofEngine, f32),
149 {
150 self.run_with_overlay(move |engine, dt, _gl| {
151 update(engine, dt);
152 });
153 }
154
155 pub fn run_with_overlay<F>(&mut self, mut update: F)
159 where
160 F: FnMut(&mut ProofEngine, f32, &glow::Context),
161 {
162 let pipeline = render::Pipeline::init(&self.config);
163 self.pipeline = Some(pipeline);
164
165 let mut last = std::time::Instant::now();
166 loop {
167 let now = std::time::Instant::now();
168 let dt = now.duration_since(last).as_secs_f32().min(0.1);
169 last = now;
170
171 if let Some(ref mut p) = self.pipeline {
173 if !p.poll_events(&mut self.input) {
174 break;
175 }
176 }
177
178 self.scene.tick(dt);
180
181 let gl_ptr = self.pipeline.as_ref().map(|p| p.gl() as *const glow::Context);
185
186 if let Some(ref mut p) = self.pipeline {
188 p.render(&self.scene, &self.camera);
189 }
190
191 if let Some(ptr) = gl_ptr {
193 let gl_ref = unsafe { &*ptr };
194 update(self, dt, gl_ref);
195 }
196
197 if let Some(ref mut p) = self.pipeline {
199 if !p.swap() {
200 break;
201 }
202 }
203 }
204 }
205
206 pub fn add_field(&mut self, field: ForceField) -> scene::FieldId {
208 self.scene.add_field(field)
209 }
210
211 pub fn remove_field(&mut self, id: scene::FieldId) {
213 self.scene.remove_field(id)
214 }
215
216 pub fn spawn_glyph(&mut self, glyph: Glyph) -> glyph::GlyphId {
218 self.scene.spawn_glyph(glyph)
219 }
220
221 pub fn spawn_entity(&mut self, mut entity: AmorphousEntity) -> entity::EntityId {
223 if entity.formation.is_empty() {
225 use entity::formation::Formation;
226 let f = Formation::diamond(2);
227 entity.formation = f.positions;
228 entity.formation_chars = f.chars;
229 }
230 while entity.formation_colors.len() < entity.formation.len() {
232 entity.formation_colors.push(glam::Vec4::ONE);
233 }
234 for i in 0..entity.formation.len() {
236 let offset = entity.formation[i];
237 let ch = entity.formation_chars.get(i).copied().unwrap_or('◆');
238 let color = entity.formation_colors.get(i).copied().unwrap_or(glam::Vec4::ONE);
239 let id = self.scene.spawn_glyph(Glyph {
240 character: ch,
241 position: entity.position + offset,
242 color,
243 emission: 0.8,
244 glow_color: glam::Vec3::new(color.x, color.y, color.z),
245 glow_radius: 1.2,
246 mass: entity.entity_mass / entity.formation.len().max(1) as f32,
247 layer: RenderLayer::Entity,
248 ..Default::default()
249 });
250 entity.glyph_ids.push(id);
251 }
252 self.scene.spawn_entity(entity)
253 }
254
255 pub fn emit_particles(&mut self, emitter: particle::EmitterPreset, origin: glam::Vec3) {
257 particle::emit(&mut self.scene, emitter, origin);
258 }
259
260 pub fn add_trauma(&mut self, amount: f32) {
262 self.camera.add_trauma(amount);
263 }
264}
265
266impl ProofEngine {
268 pub fn request_quit(&mut self) {
269 self.input.quit_requested = true;
270 }
271
272 pub fn gl(&self) -> Option<&glow::Context> {
275 self.pipeline.as_ref().map(|p| p.gl())
276 }
277
278 pub fn window(&self) -> Option<&winit::window::Window> {
280 self.pipeline.as_ref().map(|p| p.window())
281 }
282
283 pub fn window_size(&self) -> (u32, u32) {
285 self.pipeline.as_ref().map(|p| p.window_size()).unwrap_or((1600, 1000))
286 }
287}
288
289pub mod prelude {
291 pub use crate::{
292 ProofEngine, EngineConfig,
293 MathFunction, ForceField, Falloff, AttractorType,
294 Glyph, RenderLayer, BlendMode,
295 AmorphousEntity,
296 MathParticle, ParticleInteraction,
297 AudioEvent,
298 particle::EmitterPreset,
299 render::camera::ProofCamera,
300 input::{InputState, Key},
301 scene::{SceneGraph, FieldId},
302 audio::MusicVibe,
303 tween::{Tween, Easing, TweenState, Tweens, AnimationGroup},
304 tween::easing::Easing as EasingFn,
305 tween::keyframe::{KeyframeTrack, Keyframe, CameraPath, ExtrapolateMode},
306 tween::sequence::{TweenSequence, TweenTimeline, SequenceBuilder},
307 debug::DebugOverlay,
308 render::pipeline::FrameStats,
309 };
310 pub use glam::{Vec2, Vec3, Vec4};
311}