neo_babylon/
api.rs

1use std::{cell::RefCell, f64::consts::PI, rc::Rc};
2
3use wasm_bindgen::{
4    prelude::Closure,
5    JsCast,
6};
7use web_sys::window;
8
9use crate::prelude::*;
10
11#[wasm_bindgen]
12extern "C" {
13    pub type BABYLON;
14}
15
16/// Create a simple Scene in the canvas referred to by the selector.
17/// 
18/// The scene will have an ArcRotateCamera, a HemisphericLight, and a PointLight.
19pub fn create_basic_scene(selector: &str) -> Rc<RefCell<Scene>> {
20    let canvas = get_element(selector);
21
22    let scene = create_scene(selector);
23
24    // Add a camera to the scene and attach it to the canvas
25    let camera = ArcRotateCamera::new(
26        "Camera",
27        PI / 2.0,
28        PI / 2.0,
29        2.0,
30        Vector3::Zero(),
31        Some(&scene.borrow()),
32        Some(true),
33    );
34    camera.attachControl(canvas, true);
35
36    // Add lights to the scene
37    HemisphericLight::new("light1", Vector3::new(1.0, 1.0, 0.0), &scene.borrow());
38    PointLight::new("light2", Vector3::new(0.0, 1.0, -1.0), &scene.borrow());
39
40    scene
41}
42
43/// Create a barebones Scene in the canvas referred to by the selector.
44pub fn create_scene(selector: &str) -> Rc<RefCell<Scene>> {
45    let window = window().expect("should have a window in this context");
46    let canvas = get_element(selector);
47
48    let engine = Rc::new(RefCell::new(Engine::new(&canvas, true)));
49
50    let scene = Rc::new(RefCell::new(Scene::new(&engine.borrow())));
51
52    let closure_scene = scene.clone();
53    let renderloop_closure = Closure::<dyn FnMut()>::new(move || {
54        closure_scene.borrow().render(None, None);
55    });
56    engine
57        .borrow()
58        .runRenderLoop(renderloop_closure.into_js_value().unchecked_ref());
59
60    let resize_closure = Closure::<dyn FnMut()>::new(move || {
61        engine.borrow().resize(None);
62    });
63    window.set_onresize(Some(resize_closure.into_js_value().unchecked_ref()));
64
65    scene
66}
67
68pub fn setup_vr_experience(scene: &Scene) {
69    if Reflect::has(&window().unwrap().navigator().unchecked_into() as &JsValue, &"xr".into()).unwrap_or(false) {
70        scene.createDefaultVRExperience();
71    }
72}
73
74pub fn get_element(selector: &str) -> web_sys::Element {
75    let window = web_sys::window().expect("should have a window in this context");
76    let document = window.document().expect("window should have a document");
77    let e = document
78        .query_selector(selector)
79        .expect("Selector not found")
80        .expect("Selector not found");
81    e
82}
83