stereokit_rust/
lib.rs

1//! StereoKit-rust is a binding for the [StereoKit](https://StereoKit.net) C API.
2//! If the name of this crate contains "_rust" (not great for a Rust crate, we agree) it is to emphasize the fact that
3//! StereoKit is first and foremost a C, C++, C# project.
4//! StereoKit allows you to create VR/MR applications with ease on every headset platforms that run OpenXR.
5//!
6//! <img src="https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/StereoKit-rust.png" alt="screenshot" width="300">
7//!
8//! [StereoKit-rust GitHub repository](https://github.com/mvvvv/StereoKit-rust/) /
9//! [StereoKit GitHub repository](https://github.com/StereoKit/StereoKit/)
10//!
11//! # How to read this documentation
12//! If you already know the name of what you are looking for, the fastest way to
13//! find it is to use the <a href="#" onclick="window.searchState.focus();">search
14//! bar</a> at the top of the page.
15//! Otherwise, you may want to jump to one of these useful sections:
16//! * [Installation](#installation)
17//! * [Usage](#usage)
18//! * [Examples](#examples)
19//! * [How to build and test your application](#how-to-build-and-test-your-application)
20//! * [StereoKit-rust modules](#modules)
21//! * [StereoKit-rust Macros](#macros)
22//!
23//! # Installation:
24//! StereoKit-rust is a binding and therefore requires some tools and libraries to compile StereoKitC:
25//! ### On `Windows`:
26//!   - Considering that you have already installed "`Visual Studio Build Tools 2022(Developpment Desktop C++)`" in order to
27//!     have `Rust` compiling with `stable-????-pc-windows-msvc` toolchain.
28//!   - Get the following tools and dev libraries : "`Git`", "`CMake`" and "`DotNet SDK v8+`".
29//!
30//! ### On `Linux`:
31//!   - Considering that you have already installed `Rust` with `stable-?????-unknown-linux-gnu` toolchain and the linux package
32//!     `build-essential`.
33//!   - Get the following tools and dev libraries : `git` `clang` `cmake` `lld` `ninja-build` `libx11-dev`
34//!     `libxfixes-dev` `libegl-dev` `libgbm-dev` `libfontconfig-dev` `libxkbcommon-x11-dev`.
35//!
36//! Installing the stereokit_rust tools with `cargo install -F no-event-loop stereokit-rust` should help you to check
37//! the missing dependencies.
38//!
39//! # Usage
40//! You have to chose between `event-loop` and `no-event-loop` features. The feature `no-event-loop` is the
41//! lighter but you can't use the [`framework`].
42//!
43//! Using `event-loop` your `Cargo.toml` should contain the following lines:
44//! ```toml
45//! [lib]
46//! crate-type = ["lib", "cdylib"]
47//!
48//! [dependencies]
49//! stereokit-rust = { version = "0.4.0", features= ["event-loop"] }
50//! winit = { version = "0.30", features = [ "android-native-activity" ] }
51//!
52//! [target.'cfg(target_os = "android")'.dependencies]
53//! stereokit-rust = { version = "0.4.0" , features = ["event-loop", "build-dynamic-openxr"] }
54//! log = "0.4"
55//! android_logger = "0.15"
56//! ndk-context = "0.1.1"
57//! ndk = "0.9.0"
58//! ```
59//!
60//! # Examples
61//! Here is a simple "Hello World" StereoKit-rust app for all platforms:
62//! ```bash
63//! cargo new --lib vr_app
64//! cd vr_app
65//! ```
66//!
67//! In `src/bin/main_vr_app.rs`, if you intend to build a PC VR/MR app:
68//! ```ignore
69//! #[allow(dead_code)]
70//! #[cfg(not(target_os = "android"))]
71//! fn main() {
72//!     use stereokit_rust::sk::{SkSettings, Sk};
73//!     use vr_app::the_main;
74//!     // Initialize StereoKit with default settings
75//!     let mut settings = SkSettings::default();
76//!     settings.app_name("Test");
77//!     # settings.mode(stereokit_rust::sk::AppMode::Offscreen);
78//!     let (sk, event_loop) = settings.init_with_event_loop()
79//!         .expect("Should initialize StereoKit");
80//!     the_main(sk, event_loop);
81//!     Sk::shutdown();
82//! }
83//!
84//! #[allow(dead_code)]
85//! #[cfg(target_os = "android")]
86//! //fake main fn for android as entry is lib.rs/android_main(...)
87//! fn main() {}
88//!
89//! # use stereokit_rust::prelude::*;
90//! # use winit::event_loop::EventLoop;
91//! # pub fn the_main(sk: Sk, event_loop: EventLoop<StepperAction>) {}
92//! ```
93//!
94//! In `src/lib.rs` where you can remove the `target_os = "android" code` if you don't want to build for Android:
95//! ```ignore
96//! use stereokit_rust::{framework::SkClosures, prelude::*, sk::Sk, ui::Ui};
97//! use winit::event_loop::EventLoop;
98//!
99//! #[cfg(target_os = "android")]
100//! use winit::platform::android::activity::AndroidApp;
101//!
102//! #[unsafe(no_mangle)]
103//! #[cfg(target_os = "android")]
104//! pub fn android_main(app: AndroidApp) {
105//!     use stereokit_rust::sk::SkSettings;
106//!     // Initialize StereoKit with default settings
107//!     let mut settings = SkSettings::default();
108//!     settings.app_name("Test");
109//!     android_logger::init_once(
110//!         android_logger::Config::default()
111//!               .with_max_level(log::LevelFilter::Debug)
112//!               .with_tag("STKit-rs"),
113//!     );
114//!     let (sk, event_loop) = settings.init_with_event_loop(app).unwrap();
115//!     the_main(sk, event_loop);
116//! }
117//!
118//! /// Main function for All!
119//! pub fn the_main(sk: Sk, event_loop: EventLoop<StepperAction>) {
120//!     // Create a grabbable window with a button to exit the application
121//!     let mut window_pose = Ui::popup_pose([0.0, -0.4, 0.0]);
122//!     // Main loop
123//!     SkClosures::new(sk, |sk, _token| {
124//!         // Exit button
125//!         Ui::window_begin("Hello world!", &mut window_pose, None, None, None);
126//!         if Ui::button("Exit", None) {
127//!             sk.quit(None)
128//!         }
129//!         Ui::window_end();
130//!     })
131//!     .run(event_loop);
132//! }
133//! ```
134//!
135//! Hundreds of examples (which are also unit tests) are available in this documentation. If you like to learn by
136//! examples, check out  the modules in the following order: [`sk`], [`mesh`], [`model`], [`maths`], [`ui`], [`framework`],
137//! [`tools`], [`sound`], [`interactor`], [`system`], [`material`], [`shader`], [`tex`], [`sprite`], [`font`], [`render_list`].
138//!
139//! # How to build and test your application:
140//!
141//! * [Building your PC VR/MR app](#building-your-pc-vrmr-app).
142//! * [Building your Android VR/MR app](#building-your-android-vrmr-app).
143//! * [Building your Windows GNU PC VR/MR app](#building-your-windows-gnu-pc-vrmr-app).
144//! * [Building your Linux AARCH64 PC VR/MR app](#building-your-linux-aarch64-pc-vrmr-app).
145//! * [Building your Linux X86_64 PC VR/MR app](#building-your-linux-x86_64-pc-vrmr-app).
146//!
147//! ## Building your PC VR/MR app:
148//! * Launch `cargo run --bin main_vr_app` to compile and run your app in debug mode on your PC with or without a headset.
149//!   (using Wayland on Linux may require to unset temporarily the DISPLAY variable: `DISPLAY= cargo run`)
150//! * Launch `cargo build_sk_rs --bin main_vr_app <build_directory>` to compile your app and assets in release mode for your PC.
151//!
152//! To test with your headset, make sure you have [OpenXR installed](https://www.khronos.org/openxr/) with an active
153//! runtine (SteamVR, Monado, WiVRn, ALVR ...).
154//!
155//! ## Building your Android VR/MR app:
156//! This can be done from a PC running Windows, Mac or Linux:
157//! * Install [sdkmanager](https://developer.android.com/studio/command-line/sdkmanager) (or Android Studio if you
158//!   intend to use it). You'll need a Java JDK (v17 is fine).
159//! * Using sdkmanager, install platform-tools(v32), latest build-tools and the latest ndk.
160//! * Set ANDROID_HOME environment variable to its path (this path contains the `build_tools` directory).
161//! * Set the NDK path (which ends with it's version number) into the ANDROID_NDK_ROOT environment variable.
162//! * Install [Ninja](https://ninja-build.org/)
163//! * Check that `adb` ($ANDROID_HOME/platform_tools/adb) is connecting to your headset.
164//! * Download the target: `rustup target add aarch64-linux-android` for most existing android headsets.
165//! * Create a keystore for signing your app (using keytool or Android Studio).
166//! ##### If you don't need some java/kotlin code, you can use cargo-apk  (cargo-xbuild is an alternative but lacks some documentation):
167//!   - Install: `cargo install cargo-apk`.
168//!   - The manifest file will be generated from the `Cargo.toml` (see the `package.metadata.android` section). Here are
169//!     some examples:
170//!     - [StereoKit-template](https://github.com/mvvvv/stereokit-template/blob/main/Cargo.toml#L27)
171//!     - [StereoKit-rust](https://github.com/mvvvv/StereoKit-rust/blob/master/Cargo.toml#L77)
172//!   - Create a res directory with the icons of your app (i.e. with <https://icon.kitchen>)
173//!   - Set the path and password to your keystore in the `Cargo.toml` [package.metadata.android.signing.release] or
174//!     in the `CARGO_APK_RELEASE_KEYSTORE` and  `CARGO_APK_RELEASE_KEYSTORE_PASSWORD` environment variables.
175//!   - Launch the debug on your headset: `cargo apk run --lib`
176//!   - Generate the release apk: `cargo apk build --lib --release`. The apk will be in `target/release/apk/`.
177//! ##### Otherwise, you have to use Gradle with cargo-ndk:
178//!   - Install: `cargo install cargo-ndk`.
179//!   - Clone or extract a ZIP of [gradle template](https://github.com/mvvvv/stereokit-template/tree/gradle).
180//!   - Name your project in the `package.name` entry in `Cargo.toml`.
181//!   - Set `cargo.libName` (same as `package.name` from `Cargo.toml`), `android.applicationId` and `android.main` in
182//!     `gradle.properties`.
183//!   - In `app/src/main/AndroidManifest.xml` delete or modify the path and package name of `MainActivity.java` (your
184//!     choice impacts android.main ↑ and android:hasCode attribute).
185//!   - Replace the content of the res directory with the icons of your app (i.e. with <https://icon.kitchen>)
186//!   - Store your keystore values in one of the hidden gradle properties files (ie. `~/.gradle/gradle.properties`)
187//!     to store and forget the confidential values:
188//!     - RELEASE_STORE_FILE=/home/**/**/my_release_key.keystore
189//!     - RELEASE_STORE_PASSWORD=******
190//!     - RELEASE_KEY_ALIAS=*****
191//!     - RELEASE_KEY_PASSWORD=******
192//!   - If any, remove the .git folder.
193//!   - Launch the debug on your connected headset:
194//!     - On Windows, launch: `./gradlew.bat run && cmd /c logcat.cmd` or `(./gradlew.bat run) -and (cmd /c logcat.cmd)`
195//!     - On others, launch: `./gradlew run && ./logcat.cmd`
196//!   - Generate the release apk: `./gradlew buildRelease`. The apk will be in `app/build/outputs/apk/release`
197//!
198//! ## Building your Windows GNU PC VR/MR app:
199//! Thanks to Steam Proton, you can run your Windows exe on Linux. It's even better than native build thanks to D3D11
200//! to Vulkan translation. Knowing that, we work to build Windows .exe files on Linux using GNU toolchain.
201//!
202//! Build your app for Windows_x64 using GNU toolchain from Linux and Windows (and probably Mac):
203//! * Install mingw-w64 (MSYS2 on windows).
204//! * Add the `Rust` target gnu for windows:`rustup target add x86_64-pc-windows-gnu`
205//! * On 'Non Windows OS': we need wine to compile the shaders:
206//!   - Add i386 architecture (i.e. `sudo dpkg --add-architecture i386` on Ubuntu).
207//!   - Install wine and winetricks.
208//!   - Install needed tools and libs: `winetricks corefonts d3dx9 d3dcompiler_47 dxvk`.
209//! * Create a directory where necessary libs will be stored (i.e. ../x64-mingw-libs/) then add a link to the DLLs or
210//!   static libs (*.a) the build will need after or during its creation. Example on Ubuntu 24.XX:
211//!   - If you want to use DLLs:
212//!      - `ln -s /usr/lib/gcc/x86_64-w64-mingw32/13-win32/libgcc_s_seh-1.dll ../x64-mingw-libs/`
213//!      - `ln -s /usr/lib/gcc/x86_64-w64-mingw32/13-win32/libstdc++-6.dll ../x64-mingw-libs/`
214//!   - If you want to use static libs:
215//!      - `ln -s /usr/lib/gcc/x86_64-w64-mingw32/13-win32/libgcc_eh.a ../x64-mingw-libs/`
216//!      - `ln -s /usr/lib/gcc/x86_64-w64-mingw32/13-win32/libstdc++.a ../x64-mingw-libs/`
217//! * Launch: `cargo build_sk_rs --bin main_vr_app --x64-win-gnu ../x64-mingw-libs/ <the path of your exportable repository>`
218//! * To run your_app.exe on Linux:
219//!   - Add a non-steam game to your library then launch it when WiVRn or SteamVR are started.
220//!   - If you only need the simulator: `wine your_app.exe`.
221//!
222//! ## Building your Linux aarch64 PC VR/MR app:
223//! If you are on aarch64 Linux, you just have to follow the instructions in [`Building your PC VR/MR app`](#building-your-pc-vrmr-app).
224//! If you are on a x86_64 architecture you are able to cross-compile your app for aarch64:
225//! * Install g++-aarch64-linux-gnu
226//! * Get the libraries `libx11-dev:arm64` `libxfixes-dev:arm64` `libegl-dev:arm64` `libgbm-dev:arm64` `libfontconfig-dev:arm64`.
227//!   On Ubuntu 24:XX this can be done by adding a foreign architecture `dpkg --add-architecture arm64` with depot
228//!   `http://ports.ubuntu.com/ubuntu-ports`. To avoid errors during `apt update` you'll have to specify the architectures
229//!   of all depots in `/etc/apt/sources.list.d/ubuntu.sources`
230//! * Add the rust target aarch64 for Linux:`rustup target add aarch64-unknown-linux-gnu`
231//! * Add a section `[target.aarch64-unknown-linux-gnu]` in your config.toml for setting `linker = "aarch64-linux-gnu-gcc"`
232//! * Launch `cargo build_sk_rs --bin main_vr_app --aarch64-linux <the path of your exportable repository>`
233//!
234//! ## Building your Linux x86_64 PC VR/MR app:
235//! If you are on x86_64 Linux, you just have to follow the instructions in [`Building your PC VR/MR app`](#building-your-pc-vrmr-app).
236//! If you are on aarch64 architecture you should be able to cross-compile for x86_64:
237//! (This hasn't been tested yet, if you are interested in testing it, please let us now)
238//! * Install g++-x86-64-linux-gnu
239//! * Get the libraries `libx11-dev:amd64` `libxfixes-dev:amd64` `libegl-dev:amd64` `libgbm-dev:amd64` `libfontconfig-dev:amd64`.
240//!   On Ubuntu 24:XX this can be done by adding a foreign architecture `dpkg --add-architecture amd64` with depot
241//!   `http://ports.ubuntu.com/ubuntu-ports`. To avoid errors during `apt update` you'll have to specify the architectures
242//!   of all depots in `/etc/apt/sources.list.d/ubuntu.sources`
243//! * Add the rust target aarch64 for linux:`rustup target add x86_64-unknown-linux-gnu`
244//! * Add a section `[target.x86_64-unknown-linux-gnu]` in your config.toml for setting `linker = "x86_64-linux-gnu-gcc"`
245//! * Launch `cargo build_sk_rs --bin main_vr_app --x64-linux <the path of your exportable repository>`.
246
247use std::{ffi::NulError, path::PathBuf};
248
249#[cfg(feature = "event-loop")]
250pub use stereokit_macros::IStepper;
251
252pub use stereokit_macros::include_asset_tree;
253
254#[cfg(feature = "event-loop")]
255pub use stereokit_macros::test_init_sk_event_loop as test_init_sk;
256#[cfg(feature = "no-event-loop")]
257pub use stereokit_macros::test_init_sk_no_event_loop as test_init_sk;
258
259#[cfg(feature = "event-loop")]
260pub use stereokit_macros::test_screenshot_event_loop as test_screenshot;
261#[cfg(feature = "no-event-loop")]
262pub use stereokit_macros::test_screenshot_no_event_loop as test_screenshot;
263
264#[cfg(feature = "event-loop")]
265pub use stereokit_macros::test_steps_event_loop as test_steps;
266#[cfg(feature = "no-event-loop")]
267pub use stereokit_macros::test_steps_no_event_loop as test_steps;
268
269/// Some of the errors you might encounter when using StereoKit-rust.
270use thiserror::Error;
271
272/// Anchor related structs and functions.
273///
274/// With examples which are also unit tests.
275pub mod anchor;
276
277/// Font related structs and functions.
278///
279/// ## Examples
280/// which are also unit tests:
281///
282/// [![Font](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/font.jpeg)](font::Font)
283pub mod font;
284
285/// A namespace containing features exclusive to the rust bindings for StereoKit.
286///
287/// These are higher level pieces of functionality that do not necessarily adhere to the same goals and restrictions as
288/// StereoKit’s core functionality does. This corresponds to the C# namespace:
289/// <https://stereokit.net/Pages/StereoKit.Framework.html>
290/// - An event loop manager based on Winit.
291/// - HandMenuRadial related structs, enums and functions.
292///
293/// At the core of this framework is the [`crate::IStepper`] derive macro, which allows you to create a stepper that can
294/// be run in the event loop.
295/// ## Examples
296/// which are also unit tests:
297/// ```
298/// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
299/// use stereokit_rust::{ font::Font, maths::{Matrix, Quat, Vec3},
300///                       system::{Text, TextStyle}, util::named_colors};
301///
302/// #[derive(IStepper)]
303/// pub struct MyStepper {
304///     id: StepperId,
305///     sk_info: Option<Rc<RefCell<SkInfo>>>,
306///
307///     transform: Matrix,
308///     pub text: String,
309///     text_style: Option<TextStyle>,
310/// }
311/// unsafe impl Send for MyStepper {}
312/// impl Default for MyStepper {
313///     fn default() -> Self {
314///         Self {
315///             id: "MyStepper".to_string(),
316///             sk_info: None,
317///
318///             transform: Matrix::IDENTITY,
319///             text: "IStepper\nderive\nmacro".to_owned(),
320///             text_style: None,
321///         }
322///     }
323/// }
324/// impl MyStepper {
325///     fn start(&mut self) -> bool {
326///         self.transform = Matrix::t_r([0.05, 0.0, -0.2], [0.0, 200.0, 0.0]);
327///         self.text_style = Some(Text::make_style(Font::default(), 0.3, named_colors::RED));
328///         true
329///     }
330///     fn check_event(&mut self, _id: &StepperId, _key: &str, _value: &str) {}
331///     fn draw(&mut self, token: &MainThreadToken) {
332///         Text::add_at(token, &self.text, self.transform, self.text_style,
333///                      None, None, None, None, None, None);
334///     }
335/// }
336///
337/// sk.send_event(StepperAction::add_default::<MyStepper>("My_Basic_Stepper_ID"));
338///
339/// filename_scr = "screenshots/istepper_macro.jpeg";
340/// test_screenshot!( // !!!! Get a proper main loop !!!!
341///     // No code here as we only use MyStepper
342/// );
343/// ```
344/// [![IStepper derive macro](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/istepper_macro.jpeg)](IStepper)
345///
346/// [![SkClosures](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sk_closures.jpeg)](framework::SkClosures)
347/// [![IStepper](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/a_stepper.jpeg)](framework::IStepper)
348/// [![StepperAction](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/stepper_actions.jpeg)](framework::StepperAction)
349/// [![Steppers](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/steppers.jpeg)](framework::Steppers)
350/// [![StepperClosures](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/stepper_closures.jpeg)](framework::StepperClosures)
351pub mod framework;
352
353/// Material specific structs, enums and functions.
354///
355/// ## Examples
356/// which are also unit tests:
357///
358/// [![Material](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/materials.jpeg)](material::Material)
359/// [![Material Transparency](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/material_transparency.jpeg)](material::Material::transparency)
360/// [![Material Face Cull](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/material_face_cull.jpeg)](material::Material::face_cull)
361/// [![Material Parameter Info](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/param_infos.jpeg)](material::ParamInfos)
362/// [![Material Parameter Info with id](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/param_infos_with_id.jpeg)](material::ParamInfos::set_data_with_id)
363pub mod material;
364
365/// Vec2, 3 and4, Quat and Matrix, Bounds, Plane and Ray related structs, enums and functions.
366///
367/// ## Examples
368/// which are also unit tests:
369///
370/// [![Matrix](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/matrix.jpeg)](maths::Matrix)
371/// [![Bounds](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/bounds.jpeg)](maths::Bounds)
372/// [![Plane](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/plane.jpeg)](maths::Plane)
373/// [![Pose](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/pose.jpeg)](maths::Pose)
374/// [![Sphere](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sphere.jpeg)](maths::Sphere)
375/// [![Ray](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ray.jpeg)](maths::Ray)
376/// [![Intersect Meshes](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/intersect_meshes.jpeg)](maths::Ray::intersect_mesh)
377/// [![Intersect Model](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/intersect_model.jpeg)](maths::Ray::intersect_model)
378pub mod maths;
379
380/// Mesh related structs, enums and functions.
381///
382/// ## Examples
383/// which are also unit tests:
384///
385/// [![Mesh](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/meshes.jpeg)](mesh::Mesh)
386/// [![Vertex](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/basic_mesh.jpeg)](mesh::Vertex)
387/// [![Mesh bounds](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/mesh_bounds.jpeg)](mesh::Mesh::bounds)
388/// [![Mesh set_verts](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/mesh_set_verts.jpeg)](mesh::Mesh::set_verts)
389/// [![Mesh set_inds](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/mesh_set_inds.jpeg)](mesh::Mesh::set_inds)
390/// [![Mesh draw](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/mesh_draw.jpeg)](mesh::Mesh::draw)
391/// [![Mesh intersect](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/mesh_intersect.jpeg)](mesh::Mesh::intersect)
392pub mod mesh;
393
394/// Model specific structs, enums and functions.
395///
396/// ## Examples
397/// which are also unit tests:
398///
399/// [![Model](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/model.jpeg)](model::Model)
400/// [![Model from memory](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/model_from_memory.jpeg)](model::Model::from_memory)
401/// [![Model from file](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/model_from_file.jpeg)](model::Model::from_file)
402/// [![Model from mesh](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/model_from_mesh.jpeg)](model::Model::from_mesh)
403/// [![Model bounds](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/model_bounds.jpeg)](model::Model::bounds)
404/// [![Model draw](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/model_draw.jpeg)](model::Model::draw)
405/// [![Model draw with material](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/model_draw_with_material.jpeg)](model::Model::draw_with_material)
406/// [![Model intersect](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/model_intersect.jpeg)](model::Model::intersect)
407/// [![Model Anims](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/anims.jpeg)](model::Anims)
408/// [![Model Nodes](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/model_nodes.jpeg)](model::Nodes)
409/// [![ModelNode](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/model_node.jpeg)](model::ModelNode)
410pub mod model;
411
412/// Prelude for StereoKit-rust. The basis for all StereoKit-rust programs.
413pub mod prelude;
414
415/// RenderList related structs, enums and functions.
416///
417/// ## Examples
418/// which are also unit tests:
419///
420/// [![RenderList](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/render_list.jpeg)](render_list::RenderList)
421/// [![RenderList add mesh](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/render_list_add_mesh.jpeg)](render_list::RenderList::add_mesh)
422/// [![RenderList add model](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/render_list_add_model.jpeg)](render_list::RenderList::add_model)
423/// [![RenderList draw now](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/render_list_draw_now.jpeg)](render_list::RenderList::draw_now)
424/// [![RenderList push](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/render_list_push.jpeg)](render_list::RenderList::push)
425pub mod render_list;
426
427/// Shader specific structs, enums and functions.
428///
429/// ## Examples
430/// which are also unit tests:
431///
432/// [![Shader](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/shaders.jpeg)](shader::Shader)
433pub mod shader;
434
435/// Sk related structs, enums and functions.
436///
437/// ## Examples
438/// which are also unit tests:
439///
440/// [![Sk basic example](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sk_basic_example.jpeg)](sk::SkSettings::init_with_event_loop)
441#[cfg(feature = "event-loop")]
442pub mod sk;
443
444/// StereoKit-rust specific structs, enums and functions.
445#[cfg(feature = "no-event-loop")]
446pub mod sk;
447
448/// Sound specific structs, enums and functions.
449///
450/// ## Examples
451/// which are also unit tests:
452///
453/// [![Sound](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sound.jpeg)](sound::Sound)
454/// [![SoundInst](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sound_inst.jpeg)](sound::SoundInst)
455pub mod sound;
456
457/// Sprite related structs, enums and functions.
458///
459/// ## Examples
460/// which are also unit tests:
461///
462/// [![Sprite](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite.jpeg)](sprite::Sprite)
463/// [![Sprite from Tex](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_from_tex.jpeg)](sprite::Sprite::from_tex)
464/// [![Sprite from File](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_from_file.jpeg)](sprite::Sprite::from_file)
465/// [![Sprite draw](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_draw.jpeg)](sprite::Sprite::draw)
466///
467/// [![Sprite grid](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_grid.jpeg)](sprite::Sprite::grid)
468/// [![Sprite list](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_list.jpeg)](sprite::Sprite::list)
469/// [![Sprite arrow left](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_arrow_left.jpeg)](sprite::Sprite::arrow_left)
470/// [![Sprite arrow right](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_arrow_right.jpeg)](sprite::Sprite::arrow_right)
471/// [![Sprite arrow up](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_arrow_up.jpeg)](sprite::Sprite::arrow_up)
472/// [![Sprite arrow down](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_arrow_down.jpeg)](sprite::Sprite::arrow_down)
473/// [![Sprite radio off](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_radio_off.jpeg)](sprite::Sprite::radio_off)
474/// [![Sprite radio on](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_radio_on.jpeg)](sprite::Sprite::radio_on)
475/// [![Sprite toggle off](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_toggle_off.jpeg)](sprite::Sprite::toggle_off)
476/// [![Sprite toggle on](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_toggle_on.jpeg)](sprite::Sprite::toggle_on)
477/// [![Sprite backspace](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_backspace.jpeg)](sprite::Sprite::backspace)
478/// [![Sprite close](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_close.jpeg)](sprite::Sprite::close)
479/// [![Sprite shift](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sprite_shift.jpeg)](sprite::Sprite::shift)
480pub mod sprite;
481
482/// Interactor related structs, enums and functions.
483///
484pub mod interactor;
485
486/// Sprite specific structs, enums and functions.
487///
488/// ## Examples
489/// which are also unit tests:
490///
491/// [![Assets](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/assets.jpeg)](system::Assets)
492/// [![Assets block for priority](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/assets_block_for_priority.jpeg)](system::Assets::block_for_priority)
493/// [![Hierarchy](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/hierarchy.jpeg)](system::Hierarchy)
494/// [![Hierarchy ray](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/hierarchy_ray.jpeg)](system::Hierarchy::to_local_ray)
495/// [![Hand](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/hand.jpeg)](system::Hand)
496/// [![Controller](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/controller.jpeg)](system::Controller)
497/// [![Lines](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/lines.jpeg)](system::Lines)
498/// [![Microphone](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/microphone.jpeg)](system::Microphone)
499/// [![Renderer](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/renderer.jpeg)](system::Renderer)
500/// [![Screenshots capture](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/screenshot_capture.jpeg)](system::Renderer::screenshot_capture)
501/// [![TextStyle](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/text_style.jpeg)](system::TextStyle)
502/// [![Text](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/text.jpeg)](system::Text)
503pub mod system;
504
505/// Tex related structs, enums and functions.
506///
507/// ## Examples
508/// which are also unit tests:
509///
510/// [![Tex](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/tex.jpeg)](tex::Tex)
511/// [![Tex from file](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/tex_from_file.jpeg)](tex::Tex::from_file)
512/// [![Tex gen_particle](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/tex_gen_particle.jpeg)](tex::Tex::gen_particle)
513/// [![SHCubemap](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sh_cubemap.jpeg)](tex::SHCubemap)
514pub mod tex;
515
516/// Many `non-canonical`` tools related structs, enums and functions.
517///
518/// ## Examples
519/// which are also unit tests:
520///
521/// [![FileBrowser](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/file_browser.jpeg)](tools::file_browser::FileBrowser)
522/// [![FlyOver](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/fly_over.jpeg)](tools::fly_over::FlyOver)
523/// [![Log window](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/log_window.jpeg)](tools::log_window::LogWindow)
524/// [![Hud Notification](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/hud_notification.jpeg)](tools::notif::HudNotification)
525/// [![Screenshot viewer](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/screenshot_viewer.jpeg)](tools::screenshot::ScreenshotViewer)
526/// [![Title](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/title.jpeg)](tools::title::Title)
527pub mod tools;
528
529/// The UI module is a collection of functions and structs that allow you to create a user interface.
530///
531/// ## Examples
532/// which are also unit tests:
533///
534/// [![Ui](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui.jpeg)](ui::Ui)
535/// [![Ui color_scheme](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_color_scheme.jpeg)](ui::Ui::color_scheme)
536/// [![Ui button](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_button.jpeg)](ui::Ui::button)
537/// [![Ui button_img](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_button_img.jpeg)](ui::Ui::button_img)
538/// [![Ui button_round](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_button_round.jpeg)](ui::Ui::button_round)
539/// [![Ui handle](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_handle.jpeg)](ui::Ui::handle)
540/// [![Ui handle_begin](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_handle_begin.jpeg)](ui::Ui::handle_begin)
541/// [![Ui hseparator](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_hseparator.jpeg)](ui::Ui::hseparator)
542/// [![Ui hslider](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_hslider.jpeg)](ui::Ui::hslider)
543/// [![Ui vslider](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_vslider.jpeg)](ui::Ui::vslider)
544/// [![Ui slider_behavior](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_slider_behavior.jpeg)](ui::Ui::slider_behavior)
545/// [![Ui image](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_image.jpeg)](ui::Ui::image)
546/// [![Ui input](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_input.jpeg)](ui::Ui::input)
547/// [![Ui label](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_label.jpeg)](ui::Ui::label)
548/// [![Ui layout_area](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_layout_area.jpeg)](ui::Ui::layout_area)
549/// [![Ui layout_push](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_layout_push.jpeg)](ui::Ui::layout_push)
550/// [![Ui model](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_model.jpeg)](ui::Ui::model)
551/// [![Ui panel_at](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_panel_at.jpeg)](ui::Ui::panel_at)
552/// [![Ui panel_begin](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_panel_begin.jpeg)](ui::Ui::panel_begin)
553/// [![Ui progress_bar_at](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_progress_bar_at.jpeg)](ui::Ui::progress_bar_at)
554/// [![Ui push_surface](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_push_surface.jpeg)](ui::Ui::push_surface)
555/// [![Ui push_text_style](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_push_text_style.jpeg)](ui::Ui::push_text_style)
556/// [![Ui push_tint](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_push_tint.jpeg)](ui::Ui::push_tint)
557/// [![Ui gen_quadrant_mesh](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_gen_quadrant_mesh.jpeg)](ui::Ui::gen_quadrant_mesh)
558/// [![Ui radio button](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_radio.jpeg)](ui::Ui::radio_img)
559/// [![Ui toggle](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_toggle.jpeg)](ui::Ui::toggle)
560/// [![Ui draw_element](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_draw_element.jpeg)](ui::Ui::draw_element)
561/// [![Ui set_theme_color](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_set_theme_color.jpeg)](ui::Ui::set_theme_color)
562/// [![Ui text](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_text.jpeg)](ui::Ui::text)
563/// [![Ui window](https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ui_window.jpeg)](ui::Ui::window_begin)
564pub mod ui;
565
566/// Many utility structs, enums and functions.
567pub mod util;
568
569/// Some of the errors you might encounter when using StereoKit-rust.
570#[derive(Error, Debug)]
571pub enum StereoKitError {
572    #[error("unable to create model from file path {0}")]
573    ModelFile(String),
574    #[error("unable to find model with id {0}")]
575    ModelFind(String),
576    #[error("failed to create model {0} from memory for reason {1}")]
577    ModelFromMem(String, String),
578    #[error("failed to create model {0} from file for reason {1}")]
579    ModelFromFile(PathBuf, String),
580    #[error("failed to generate mesh {0}")]
581    MeshGen(String),
582    #[error("failed to find mesh {0}")]
583    MeshFind(String),
584    #[error("failed to convert to CString {0} in mesh_find")]
585    MeshCString(String),
586    #[error("failed to convert to CString {0} in tex_find")]
587    TexCString(String),
588    #[error("failed to find tex {0}")]
589    TexFind(String),
590    #[error("failed to copy tex {0}")]
591    TexCopy(String),
592    #[error("failed to create a tex from raw memory")]
593    TexMemory,
594    #[error("failed to create a tex from file {0} for reason {1}")]
595    TexFile(PathBuf, String),
596    #[error("failed to create a tex from multiple files {0} for reason {1}")]
597    TexFiles(PathBuf, String),
598    #[error("failed to create a tex from color {0} for reason {1}")]
599    TexColor(String, String),
600    #[error("failed to create a tex rendertarget {0} for reason {1}")]
601    TexRenderTarget(String, String),
602    #[error("failed to find font {0} for reason {1}")]
603    FontFind(String, String),
604    #[error("failed to create font from file {0} for reason {1}")]
605    FontFile(PathBuf, String),
606    #[error("failed to create font from multiple files {0} for reason {1}")]
607    FontFiles(String, String),
608    #[error("failed to create font family {0} for reason {1}")]
609    FontFamily(String, String),
610    #[error("failed to find shader {0} for reason {1}")]
611    ShaderFind(String, String),
612    #[error("failed to create shader from file {0} for reason {1}")]
613    ShaderFile(PathBuf, String),
614    #[error("failed to create shader from raw memory")]
615    ShaderMem,
616    #[error("failed to find material {0} for reason {1}")]
617    MaterialFind(String, String),
618    #[error("failed to create sprite from texture")]
619    SpriteCreate,
620    #[error("failed to create sprite from file {0}")]
621    SpriteFile(PathBuf),
622    #[error("failed to find sprite {0} for reason {1}")]
623    SpriteFind(String, String),
624    #[error("failed to find sound {0} for reason {1}")]
625    SoundFind(String, String),
626    #[error("failed to find render list {0} for reason {1}")]
627    RenderListFind(String, String),
628    #[error("failed to create sound from file {0}")]
629    SoundFile(PathBuf),
630    #[error("failed to create sound streaming {0}")]
631    SoundCreate(String),
632    #[error("failed to create anchor {0}")]
633    AnchorCreate(String),
634    #[error("failed to find anchor {0} for reason {1}")]
635    AnchorFind(String, String),
636    #[error("failed to init stereokit with settings {0}")]
637    SkInit(String),
638    #[cfg(feature = "event-loop")]
639    #[error("failed to init stereokit event_loop")]
640    SkInitEventLoop(#[from] winit::error::EventLoopError),
641    #[error("failed to get a string from native C {0}")]
642    CStrError(String),
643    #[error("failed to read a file {0}: {1}")]
644    ReadFileError(PathBuf, String),
645    #[error("failed to write a file {0}: {1}")]
646    WriteFileError(PathBuf, String),
647    #[error("Directory {0} do not exist or is not a directory")]
648    DirectoryError(String),
649    #[error(transparent)]
650    Other(#[from] NulError),
651}