neo_babylon/
core.rs

1use js_sys::{Function, Reflect};
2use wasm_bindgen::{prelude::{wasm_bindgen, Closure}, JsValue, JsCast, closure::WasmClosure};
3use web_sys::Element;
4
5use crate::prelude::{Color4, Camera};
6
7#[wasm_bindgen]
8extern "C" {
9    pub type Engine;
10    #[wasm_bindgen(constructor, js_namespace = BABYLON)]
11    pub fn new(canvas: &Element, b: bool) -> Engine;
12
13    #[wasm_bindgen(method)]
14    pub fn resize(this: &Engine, forceSetSize: Option<bool>);
15
16    #[wasm_bindgen(method)]
17    pub fn runRenderLoop(this: &Engine, renderFunction: &Function);
18
19
20    #[wasm_bindgen(method)]
21    pub fn getDeltaTime(this: &Engine) -> f64;
22}
23
24#[wasm_bindgen]
25extern "C" {
26    pub type Scene;
27
28    #[wasm_bindgen(constructor, js_namespace = BABYLON)]
29    pub fn new(engine: &Engine) -> Scene;
30
31    #[wasm_bindgen(method)]
32    pub fn createDefaultEnvironment(this: &Scene);
33
34    #[wasm_bindgen(method)]
35    pub fn render(this: &Scene, updateCameras: Option<bool>, ignoreAnimations: Option<bool>);
36
37    #[wasm_bindgen(method)]
38    pub fn getEngine(this: &Scene) -> Engine;
39
40    #[wasm_bindgen(method)]
41    pub fn createDefaultVRExperience(this: &Scene);
42}
43
44
45impl Scene {
46    /// Set the background color for rendering the Scene
47    pub fn set_clear_color(&self, color: Color4) {
48        Reflect::set(&self, &JsValue::from_str("clearColor"), &color).unwrap();
49    }
50
51    /// Gets the time spent between current and previous frame, in ms
52    pub fn get_delta_time(&self) -> f64 {
53        self.getEngine().getDeltaTime()
54    }
55
56    /// Add a Closure to run when an observable on the Scene changes
57    /// 
58    /// See "Properties" list on https://doc.babylonjs.com/typedoc/classes/BABYLON.Scene for names of observables
59    pub fn add_observable<F>(&self, name: &str, cb: Closure<F>)
60            where F: WasmClosure + ?Sized
61    {
62        let target = Reflect::get(self, &name.into()).expect("Observable not found");
63        let target_add = Reflect::get(&target, &"add".into()).expect("Target not observable").unchecked_into::<Function>();
64        target_add.call1(&target, &cb.into_js_value()).expect("Could not add observer callback");
65    }
66
67    /// add_observable special case for onKeyboardObservable
68    pub fn add_keyboard_observable(&self, cb: Closure<dyn FnMut(JsValue, JsValue)>) {
69        self.add_observable("onKeyboardObservable", cb);
70    }
71
72    /// add_observable special case for onBeforeRenderObservable
73    pub fn add_before_render_observable(&self,  cb: Closure<dyn FnMut()>) {
74        self.add_observable("onBeforeRenderObservable", cb);
75    }
76
77    pub fn set_active_camera(&self,val: &Camera){
78        Reflect::set(&self, &JsValue::from_str("activeCamera"), &val).expect(&format!("{} not found","activeCamera"));
79    }
80}