Application prototype #14

Merged
glen merged 101 commits from app-proto into main 2024-10-21 23:38:28 +00:00
Showing only changes of commit 01c2af6615 - Show all commits

View File

@ -9,7 +9,7 @@
extern crate js_sys; extern crate js_sys;
use core::array; use core::array;
use nalgebra::DVector; use nalgebra::{DMatrix, DVector};
use sycamore::{prelude::*, motion::create_raf, rt::{JsCast, JsValue}}; use sycamore::{prelude::*, motion::create_raf, rt::{JsCast, JsValue}};
use web_sys::{console, window, WebGl2RenderingContext, WebGlProgram, WebGlShader, WebGlUniformLocation}; use web_sys::{console, window, WebGl2RenderingContext, WebGlProgram, WebGlShader, WebGlUniformLocation};
@ -96,14 +96,15 @@ fn main() {
let radius_y = create_signal(1.0); let radius_y = create_signal(1.0);
let opacity = create_signal(0.5); let opacity = create_signal(0.5);
let highlight = create_signal(0.2); let highlight = create_signal(0.2);
let layer_threshold = create_signal(0.0); let turntable = create_signal(false);
let debug_mode = create_signal(false); let layer_threshold = create_signal(0.0); /* DEBUG */
let debug_mode = create_signal(false); /* DEBUG */
/* INSTRUMENTS */ /* INSTRUMENTS */
const SAMPLE_PERIOD: i32 = 20; const SAMPLE_PERIOD: i32 = 20;
let mut last_frame_moment = 0.0; let mut last_sample_time = 0.0;
let mut frames_since_last_sample = 0; let mut frames_since_last_sample = 0;
let frame_time = create_signal(0.0); let mean_frame_interval = create_signal(0.0);
// display // display
let display = create_node_ref(); let display = create_node_ref();
@ -117,6 +118,7 @@ fn main() {
radius_y.track(); radius_y.track();
opacity.track(); opacity.track();
highlight.track(); highlight.track();
turntable.track();
layer_threshold.track(); layer_threshold.track();
debug_mode.track(); debug_mode.track();
@ -133,6 +135,13 @@ fn main() {
[0.25_f32, 0.00_f32, 1.00_f32] [0.25_f32, 0.00_f32, 1.00_f32]
]; ];
// timing
let mut last_time = 0.0;
// scene parameters
const TURNTABLE_SPEED: f64 = 0.5;
let mut turntable_angle = 0.0;
/* INSTRUMENTS */ /* INSTRUMENTS */
let performance = window().unwrap().performance().unwrap(); let performance = window().unwrap().performance().unwrap();
@ -232,22 +241,57 @@ fn main() {
// set up a repainting routine // set up a repainting routine
let (_, start_animation_loop, _) = create_raf(move || { let (_, start_animation_loop, _) = create_raf(move || {
// get the time step
let time = performance.now();
let time_step = 0.001*(time - last_time);
last_time = time;
// move the turntable
let turntable_val = turntable.get();
if turntable_val {
turntable_angle += TURNTABLE_SPEED * time_step;
}
if scene_changed.get() { if scene_changed.get() {
/* INSTRUMENTS */ /* INSTRUMENTS */
// measure frame time // measure mean frame interval
frames_since_last_sample += 1; frames_since_last_sample += 1;
if frames_since_last_sample >= SAMPLE_PERIOD { if frames_since_last_sample >= SAMPLE_PERIOD {
let frame_moment = performance.now(); mean_frame_interval.set((time - last_sample_time) / (SAMPLE_PERIOD as f64));
frame_time.set((frame_moment - last_frame_moment) / (SAMPLE_PERIOD as f64)); last_sample_time = time;
last_frame_moment = frame_moment;
frames_since_last_sample = 0; frames_since_last_sample = 0;
} }
// set the orientation and translation
let orientation = {
let ang_cos = turntable_angle.cos();
let ang_sin = turntable_angle.sin();
DMatrix::from_column_slice(5, 5, &[
ang_cos, 0.0, ang_sin, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 0.0,
-ang_sin, 0.0, ang_cos, 0.0, 0.0,
0.0, 0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 0.0, 1.0
])
};
let translation = {
const LEN: f64 = -5.0;
const LEN_SQ: f64 = LEN*LEN;
DMatrix::from_column_slice(5, 5, &[
1.0, 0.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0, LEN,
0.0, 0.0, 2.0*LEN, 1.0, LEN_SQ,
0.0, 0.0, 0.0, 0.0, 1.0
])
};
let construction_to_world = &translation * orientation;
// update the construction // update the construction
sphere_vec.clear(); sphere_vec.clear();
sphere_vec.push(engine::sphere(0.5, 0.5, -5.0 + ctrl_x.get(), radius_x.get())); sphere_vec.push(&construction_to_world * engine::sphere(0.5, 0.5, ctrl_x.get(), radius_x.get()));
sphere_vec.push(engine::sphere(-0.5, -0.5, -5.0 + ctrl_y.get(), radius_y.get())); sphere_vec.push(&construction_to_world * engine::sphere(-0.5, -0.5, ctrl_y.get(), radius_y.get()));
sphere_vec.push(engine::sphere(-0.5, 0.5, -5.0, 0.75)); sphere_vec.push(&construction_to_world * engine::sphere(-0.5, 0.5, 0.0, 0.75));
// set the resolution // set the resolution
let width = canvas.width() as f32; let width = canvas.width() as f32;
@ -285,10 +329,10 @@ fn main() {
ctx.draw_arrays(WebGl2RenderingContext::TRIANGLES, 0, VERTEX_CNT as i32); ctx.draw_arrays(WebGl2RenderingContext::TRIANGLES, 0, VERTEX_CNT as i32);
// clear scene change flag // clear scene change flag
scene_changed.set(false); scene_changed.set(turntable_val);
} else { } else {
frames_since_last_sample = 0; frames_since_last_sample = 0;
frame_time.set(-1.0); mean_frame_interval.set(-1.0);
} }
}); });
start_animation_loop(); start_animation_loop();
@ -296,7 +340,7 @@ fn main() {
view! { view! {
div(id="app") { div(id="app") {
div { (frame_time.get()) " ms" } div { "Mean frame interval: " (mean_frame_interval.get()) " ms" }
canvas(ref=display, width="600", height="600") canvas(ref=display, width="600", height="600")
div(class="control") { div(class="control") {
label(for="ctrl-x") { "Sphere 0 depth" } label(for="ctrl-x") { "Sphere 0 depth" }
@ -362,6 +406,14 @@ fn main() {
bind:valueAsNumber=highlight bind:valueAsNumber=highlight
) )
} }
div(class="control") {
label(for="turntable") { "Turntable" }
input(
type="checkbox",
id="turntable",
bind:checked=turntable
)
}
div(class="control") { div(class="control") {
label(for="layer-threshold") { "Layer threshold" } label(for="layer-threshold") { "Layer threshold" }
input( input(