Skip to content

Commit

Permalink
Add skybox implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien de Charentenay committed Apr 24, 2022
1 parent 8c8a01e commit ee3e13c
Show file tree
Hide file tree
Showing 8 changed files with 469 additions and 32 deletions.
10 changes: 10 additions & 0 deletions rust/wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ js-sys = "0.3.51"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
wasm-bindgen-futures = "0.4"
futures = "0.3"
# serde-wasm-bindgen = "0.1"
simple-error = "0.2"
uuid = { version = "0.8", features = ["serde", "wasm-bindgen", "v4"] }
Expand All @@ -26,11 +28,18 @@ vortex-particle-simulation = { path = "../vortex-particle-simulation" }
[dependencies.web-sys]
version = "0.3"
features = [
'Blob',
'console',
'Document',
'Element',
'HtmlCanvasElement',
'HtmlImageElement',
'ImageBitmap',
'Performance',
'Request',
'RequestInit',
'RequestMode',
'Response',
'MouseEvent',
'Touch',
'TouchList',
Expand All @@ -41,6 +50,7 @@ features = [
'WebGlProgram',
'WebGlShader',
'WebGlUniformLocation',
'WebGlTexture',
'WheelEvent',
'Window',
]
Expand Down
12 changes: 10 additions & 2 deletions rust/wasm/src/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,21 @@ impl Camera {

impl Camera {
pub fn to_matrix4(&self) -> Result<Matrix4<f32>, Box<dyn Error>> {
let r = self.to_projection_matrix4()? * self.to_view_matrix4()?;
Ok(r)
}

pub fn to_view_matrix4(&self) -> Result<Matrix4<f32>, Box<dyn Error>> {
Ok(self.modifier * self.view)
}

pub fn to_projection_matrix4(&self) -> Result<Matrix4<f32>, Box<dyn Error>> {
let mut r = Matrix4::<f32>::identity();
if let Some(width) = self.width {
if let Some(height) = self.height {
let projection = Matrix4::<f32>::new_perspective(
r = Matrix4::<f32>::new_perspective(
width / height , self.fov,
0.1f32, 200f32);
r = projection * self.modifier * self.view;
}
}
Ok(r)
Expand Down
41 changes: 25 additions & 16 deletions rust/wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::default::Default;
use std::{
default::Default,
future::Future,
sync::{Arc, Mutex,},
};
use wasm_bindgen::{JsCast, JsValue, prelude::wasm_bindgen};
use js_sys::{ArrayBuffer, Uint8Array};
use web_sys::{console, MouseEvent, WheelEvent};
Expand All @@ -19,7 +23,7 @@ use camera::Camera;
pub struct Simulation {
parameters: Parameters,
solution: Option<Solution>,
viewer: Option<Viewer>,
viewer: Option<Arc<Mutex<Viewer>>>,
camera: Option<Camera>,
}

Expand Down Expand Up @@ -110,34 +114,42 @@ impl Simulation {
pub fn initialize_viewer(&mut self, element_id: &str) -> Result<(), JsValue> {
let viewer = Viewer::from_element_id(element_id)
.map_err(|e| JsValue::from_str(format!("Simulation::initialize_viewer - Error making viewer: {}", e).as_str()))?;
self.viewer = Some(viewer);
self.viewer = Some(Arc::new(Mutex::new(viewer)));
Ok(())
}

pub fn create_view(&mut self, data: &str) -> Result<JsValue, JsValue> {
pub fn create_view(&mut self, data: JsValue) -> js_sys::Promise { // impl Future<Output = Result<JsValue, JsValue>> {
if self.viewer.is_none() {
return Err(JsValue::from_str("Simulation::draw - Error: viewer is not initialised"));
return js_sys::Promise::reject(&JsValue::from_str("Simulation::draw - Error: view is not initialised"));
}
let viewer = Arc::clone(self.viewer.as_ref().unwrap());

match self.viewer.as_mut().unwrap()
.create_view(data) {
let data = data.as_string();
if data.is_none() {
return js_sys::Promise::reject(&JsValue::from_str(format!("Simulation::create_view - Error: data {:?} can not be converted to string", data).as_str()));
}
let data = data.unwrap();

wasm_bindgen_futures::future_to_promise(
async move {
match viewer.lock().unwrap().create_view(data.as_str()) {
Ok(uuid) => Ok(JsValue::from_str(uuid.to_hyphenated().to_string().as_str())),
Err(e) => Err(JsValue::from_str(format!("{}",e).as_str())),
}
}
)
}

pub fn draw(&mut self) -> Result<(), JsValue> {
if self.viewer.is_none() {
return Err(JsValue::from_str("Simulation::draw - Error: viewer is not initialised"));
}

if self.camera.is_none() {
self.camera
= Some(Camera::new()
.map_err(|e| JsValue::from_str(format!("Simulation::draw - Error creating camera: {:?}", e).as_str()))?);
}
let mut camera = self.camera.as_mut().unwrap();
let mut viewer = self.viewer.as_mut().unwrap();
let mut viewer = self.viewer.as_ref()
.ok_or_else(|| JsValue::from_str("Simulation::draw - Error: viewer is not initialised"))?
.lock().unwrap();

if camera.width().is_none()
|| camera.height().is_none()
Expand All @@ -148,10 +160,7 @@ impl Simulation {
}

if let Some(solution) = self.solution.as_ref() {
let matrix4 = camera.to_matrix4()
.map_err(|e| JsValue::from_str(format!("Simulation::draw - Error generating camera matrix: {}", e).as_str()))?;

viewer.draw(solution, &matrix4)
viewer.draw(solution, &camera)
.map_err(|e| JsValue::from_str(format!("Simulation::draw - Error: {}", e).as_str()))?;
}

Expand Down
21 changes: 13 additions & 8 deletions rust/wasm/src/viewer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use std::{
use wasm_bindgen::{JsValue, JsCast};
use web_sys::{
console,
HtmlCanvasElement, WebGl2RenderingContext, WebGlProgram, WebGlShader
HtmlCanvasElement,
WebGl2RenderingContext, WebGlProgram, WebGlShader,
};
use simple_error::SimpleError;
use serde::{Deserialize};
Expand All @@ -15,24 +16,27 @@ use nalgebra::Matrix4;

use vortex_particle_simulation::{Simulation};

use crate::{Solution};
use crate::{Solution, Camera};

mod program_vorton_render;
use program_vorton_render::ProgramVortonRender;
mod program_skybox;
use program_skybox::ProgramSkyBox;

mod webgl;
use webgl::{webgl_link_program, webgl_compile_vertex_shader, webgl_compile_fragment_shader};

pub trait View {
fn reset(&mut self) -> Result<(), Box<dyn Error>>;
fn draw(&mut self, context: &WebGl2RenderingContext, camera: &Matrix4<f32>, simulation: &Simulation) -> Result<(), Box<dyn Error>>;
fn redraw(&mut self, context: &WebGl2RenderingContext, camera: &Matrix4<f32>) -> Result<(), Box<dyn Error>>;
fn draw(&mut self, context: &WebGl2RenderingContext, camera: &Camera, simulation: &Simulation) -> Result<(), Box<dyn Error>>;
fn redraw(&mut self, context: &WebGl2RenderingContext, camera: &Camera) -> Result<(), Box<dyn Error>>;
}

#[derive(Deserialize)]
#[serde(tag = "type")]
enum ViewType {
VortonRender,
SkyBox,
}

pub struct Viewer {
Expand Down Expand Up @@ -60,10 +64,11 @@ impl Viewer {
*/

fn to_view(data: &str) -> Result<Box<dyn View>, Box<dyn Error>> {
let view = match serde_json::from_str(data)? {
ViewType::VortonRender => ProgramVortonRender::new()?,
let view: Box<dyn View> = match serde_json::from_str(data)? {
ViewType::VortonRender => Box::new(ProgramVortonRender::new()?),
ViewType::SkyBox => Box::new(ProgramSkyBox::new()?),
};
Ok(Box::new(view))
Ok(view)
}
}

Expand All @@ -88,7 +93,7 @@ impl Viewer {
})
}

pub fn draw(&mut self, solution: &Solution, camera: &Matrix4<f32>) -> Result<(), Box<dyn Error>> {
pub fn draw(&mut self, solution: &Solution, camera: &Camera) -> Result<(), Box<dyn Error>> {
let mut context: WebGl2RenderingContext
= self.canvas
.get_context("webgl2")
Expand Down
Loading

0 comments on commit ee3e13c

Please sign in to comment.