eulumdat_bevy/lib.rs
1//! Eulumdat 3D Scene Viewer Library
2//!
3//! This crate provides Bevy-based photometric lighting visualization.
4//!
5//! # Architecture
6//!
7//! The crate is organized into two main modules:
8//!
9//! - [`photometric`] - Generic photometric lighting for any Bevy application
10//! - `viewer` - Demo application with pre-built scenes and controls (requires `viewer` feature)
11//!
12//! # Feature Flags
13//!
14//! - `photometric` - Generic photometric lighting (minimal dependencies)
15//! - `viewer` - Full demo application with scenes, camera, controls (implies `photometric`)
16//! - `wasm-sync` - localStorage polling for WASM hot-reload (implies `viewer`)
17//! - `standalone` - Enable standalone binary (implies `wasm-sync`)
18//!
19//! # Usage as a Generic Photometric Plugin
20//!
21//! For embedding photometric lights in your own Bevy application:
22//!
23//! ```ignore
24//! use bevy::prelude::*;
25//! use eulumdat_bevy::photometric::*;
26//! use eulumdat_bevy::{EulumdatLight, EulumdatLightBundle};
27//!
28//! fn main() {
29//! App::new()
30//! .add_plugins(DefaultPlugins)
31//! .add_plugins(PhotometricPlugin::<eulumdat::Eulumdat>::default())
32//! .add_systems(Startup, setup)
33//! .run();
34//! }
35//!
36//! fn setup(mut commands: Commands) {
37//! // Your own camera
38//! commands.spawn(Camera3dBundle { ... });
39//!
40//! // Your own scene geometry
41//! commands.spawn(PbrBundle { ... });
42//!
43//! // Spawn a photometric light
44//! let ldt = eulumdat::Eulumdat::from_file("light.ldt").unwrap();
45//! commands.spawn(EulumdatLightBundle::new(ldt)
46//! .with_transform(Transform::from_xyz(0.0, 3.0, 0.0)));
47//! }
48//! ```
49//!
50//! # Usage as a Demo Viewer
51//!
52//! For the full demo experience with pre-built scenes:
53//!
54//! ```ignore
55//! use bevy::prelude::*;
56//! use eulumdat_bevy::viewer::*;
57//!
58//! fn main() {
59//! App::new()
60//! .add_plugins(DefaultPlugins)
61//! .add_plugins(EulumdatViewerPlugin::default())
62//! .run();
63//! }
64//! ```
65//!
66//! # Implementing PhotometricData for Custom Types
67//!
68//! To use photometric lighting with your own data format:
69//!
70//! ```ignore
71//! use eulumdat_bevy::photometric::PhotometricData;
72//!
73//! impl PhotometricData for MyLightData {
74//! fn sample(&self, c_angle: f64, g_angle: f64) -> f64 { ... }
75//! fn max_intensity(&self) -> f64 { ... }
76//! // ... implement other required methods
77//! }
78//!
79//! // Then use PhotometricPlugin with your type:
80//! app.add_plugins(PhotometricPlugin::<MyLightData>::default());
81//! ```
82
83// Generic photometric module (always available)
84pub mod photometric;
85
86// Eulumdat-specific implementation (always available)
87mod eulumdat_impl;
88pub use eulumdat_impl::{EulumdatLight, EulumdatLightBundle};
89
90// Viewer module (only with "viewer" feature)
91#[cfg(feature = "viewer")]
92pub mod viewer;
93
94// Re-export commonly used types at crate root for convenience
95pub use photometric::{
96 PhotometricData, PhotometricLight, PhotometricLightBundle, PhotometricPlugin,
97};
98
99// Re-export viewer types at crate root when available
100#[cfg(feature = "viewer")]
101pub use viewer::{EulumdatViewerPlugin, SceneType, ViewerSettings};
102
103// Legacy compatibility: re-export old names
104#[cfg(feature = "viewer")]
105pub use viewer::ViewerSettings as SceneSettings;
106
107// ============================================================================
108// Standalone app functions (for running as a separate binary)
109// ============================================================================
110
111/// Run the 3D viewer on a specific canvas element (WASM).
112///
113/// # Arguments
114/// * `canvas_selector` - CSS selector for the canvas element (e.g., "#bevy-canvas")
115#[cfg(all(target_arch = "wasm32", feature = "standalone"))]
116pub fn run_on_canvas(canvas_selector: &str) {
117 use bevy::prelude::*;
118
119 let mut app = App::new();
120
121 app.add_plugins(DefaultPlugins.set(WindowPlugin {
122 primary_window: Some(Window {
123 title: "Eulumdat 3D Viewer".to_string(),
124 canvas: Some(canvas_selector.to_string()),
125 fit_canvas_to_parent: true,
126 prevent_default_event_handling: false,
127 ..default()
128 }),
129 ..default()
130 }))
131 .add_plugins(viewer::EulumdatViewerPlugin::default());
132
133 app.run();
134}
135
136/// Run the 3D viewer as a native window (desktop).
137#[cfg(all(not(target_arch = "wasm32"), feature = "viewer"))]
138pub fn run_native() {
139 use bevy::prelude::*;
140
141 App::new()
142 .add_plugins(DefaultPlugins.set(WindowPlugin {
143 primary_window: Some(Window {
144 title: "Eulumdat 3D Viewer".to_string(),
145 resolution: (1280u32, 720u32).into(),
146 ..default()
147 }),
148 ..default()
149 }))
150 .add_plugins(viewer::EulumdatViewerPlugin::default())
151 .run();
152}
153
154#[cfg(all(target_arch = "wasm32", feature = "standalone"))]
155pub fn run_native() {
156 // On WASM, run_native falls back to a default canvas
157 run_on_canvas("#bevy-canvas");
158}
159
160#[cfg(all(not(target_arch = "wasm32"), feature = "standalone"))]
161pub fn run_on_canvas(_canvas_selector: &str) {
162 run_native();
163}