forked from StudioInfinity/dyna3
Deform the assembly
This seems like a good starting point, even though the code is messy and the deformation routine has some numerical quirks. Note that the translation direction is mixed up: the keys are for x, but the velocity field is for z.
This commit is contained in:
parent
7aa69bdfcd
commit
58e7587131
3 changed files with 111 additions and 7 deletions
|
|
@ -1,5 +1,5 @@
|
|||
use core::array;
|
||||
use nalgebra::{DMatrix, Rotation3, Vector3};
|
||||
use nalgebra::{DMatrix, DVector, Rotation3, Vector3};
|
||||
use sycamore::{prelude::*, motion::create_raf};
|
||||
use web_sys::{
|
||||
console,
|
||||
|
|
@ -123,6 +123,10 @@ pub fn Display() -> View {
|
|||
let zoom_out = create_signal(0.0);
|
||||
let turntable = create_signal(false); /* BENCHMARKING */
|
||||
|
||||
// manipulation
|
||||
let translate_neg_x = create_signal(0.0);
|
||||
let translate_pos_x = create_signal(0.0);
|
||||
|
||||
// change listener
|
||||
let scene_changed = create_signal(true);
|
||||
create_effect(move || {
|
||||
|
|
@ -141,6 +145,7 @@ pub fn Display() -> View {
|
|||
let mut frames_since_last_sample = 0;
|
||||
let mean_frame_interval = create_signal(0.0);
|
||||
|
||||
let assembly_for_raf = state.assembly.clone();
|
||||
on_mount(move || {
|
||||
// timing
|
||||
let mut last_time = 0.0;
|
||||
|
|
@ -153,6 +158,9 @@ pub fn Display() -> View {
|
|||
let mut rotation = DMatrix::<f64>::identity(5, 5);
|
||||
let mut location_z: f64 = 5.0;
|
||||
|
||||
// manipulation
|
||||
const TRANSLATION_SPEED: f64 = 0.15; // in length units per second
|
||||
|
||||
// display parameters
|
||||
const OPACITY: f32 = 0.5; /* SCAFFOLDING */
|
||||
const HIGHLIGHT: f32 = 0.2; /* SCAFFOLDING */
|
||||
|
|
@ -273,6 +281,10 @@ pub fn Display() -> View {
|
|||
let zoom_out_val = zoom_out.get();
|
||||
let turntable_val = turntable.get(); /* BENCHMARKING */
|
||||
|
||||
// get the manipulation state
|
||||
let translate_neg_x_val = translate_neg_x.get();
|
||||
let translate_pos_x_val = translate_pos_x.get();
|
||||
|
||||
// update the assembly's orientation
|
||||
let ang_vel = {
|
||||
let pitch = pitch_up_val - pitch_down_val;
|
||||
|
|
@ -298,6 +310,30 @@ pub fn Display() -> View {
|
|||
let zoom = zoom_out_val - zoom_in_val;
|
||||
location_z *= (time_step * ZOOM_SPEED * zoom).exp();
|
||||
|
||||
// manipulate the assembly
|
||||
if state.selection.with(|sel| sel.len() == 1) {
|
||||
let sel = state.selection.with(
|
||||
|sel| *sel.into_iter().next().unwrap()
|
||||
);
|
||||
let rep = state.assembly.elements.with_untracked(
|
||||
|elts| elts[sel].representation.get_clone_untracked()
|
||||
);
|
||||
let vel_field_z = DMatrix::from_column_slice(5, 5, &[
|
||||
0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 1.0,
|
||||
0.0, 0.0, 2.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0
|
||||
]);
|
||||
let translate_x = translate_pos_x_val - translate_neg_x_val;
|
||||
if translate_x != 0.0 {
|
||||
let vel = translate_x * vel_field_z * rep;
|
||||
let elt_motion: DVector<f64> = time_step * TRANSLATION_SPEED * vel;
|
||||
assembly_for_raf.deform(vec![(sel, elt_motion.as_view())]);
|
||||
scene_changed.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
if scene_changed.get() {
|
||||
/* INSTRUMENTS */
|
||||
// measure mean frame interval
|
||||
|
|
@ -416,7 +452,7 @@ pub fn Display() -> View {
|
|||
start_animation_loop();
|
||||
});
|
||||
|
||||
let set_nav_signal = move |event: KeyboardEvent, value: f64| {
|
||||
let set_nav_signal = move |event: &KeyboardEvent, value: f64| {
|
||||
let mut navigating = true;
|
||||
let shift = event.shift_key();
|
||||
match event.key().as_str() {
|
||||
|
|
@ -436,6 +472,18 @@ pub fn Display() -> View {
|
|||
}
|
||||
};
|
||||
|
||||
let set_manip_signal = move |event: &KeyboardEvent, value: f64| {
|
||||
let mut manipulating = true;
|
||||
match event.key().as_str() {
|
||||
"d" => translate_pos_x.set(value),
|
||||
"a" => translate_neg_x.set(value),
|
||||
_ => manipulating = false
|
||||
};
|
||||
if manipulating {
|
||||
event.prevent_default();
|
||||
}
|
||||
};
|
||||
|
||||
view! {
|
||||
/* TO DO */
|
||||
// switch back to integer-valued parameters when that becomes possible
|
||||
|
|
@ -460,7 +508,8 @@ pub fn Display() -> View {
|
|||
turntable.set_fn(|turn| !turn);
|
||||
scene_changed.set(true);
|
||||
}
|
||||
set_nav_signal(event, 1.0);
|
||||
set_nav_signal(&event, 1.0);
|
||||
set_manip_signal(&event, 1.0);
|
||||
}
|
||||
},
|
||||
on:keyup=move |event: KeyboardEvent| {
|
||||
|
|
@ -474,7 +523,8 @@ pub fn Display() -> View {
|
|||
zoom_in.set(0.0);
|
||||
zoom_out.set(0.0);
|
||||
} else {
|
||||
set_nav_signal(event, 0.0);
|
||||
set_nav_signal(&event, 0.0);
|
||||
set_manip_signal(&event, 0.0);
|
||||
}
|
||||
},
|
||||
on:blur=move |_| {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue