Rotate and translate construction

In the process, write code to make updates that depend on the time
between frames.
This commit is contained in:
Aaron Fenyes 2024-08-27 18:39:58 -07:00
parent a40a110788
commit 01c2af6615

View File

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