Rotate and translate construction
In the process, write code to make updates that depend on the time between frames.
This commit is contained in:
parent
a40a110788
commit
01c2af6615
@ -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(
|
||||||
|
Loading…
Reference in New Issue
Block a user