Compare commits
No commits in common. "2efc08d6c056f6c130467019a5d7f51338b9c63d" and "3493a798d10c1a7771362e0a49830a4c15f18e90" have entirely different histories.
2efc08d6c0
...
3493a798d1
@ -14,15 +14,10 @@ body {
|
|||||||
canvas {
|
canvas {
|
||||||
float: left;
|
float: left;
|
||||||
background-color: #020202;
|
background-color: #020202;
|
||||||
border: 1px solid #555;
|
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas:focus {
|
|
||||||
border-color: #aaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -34,12 +29,7 @@ canvas:focus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input[type="radio"] {
|
input[type="radio"] {
|
||||||
appearance: none;
|
display: none;
|
||||||
width: 0px;
|
|
||||||
height: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
outline: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-pane > label {
|
.tab-pane > label {
|
||||||
@ -56,16 +46,12 @@ input[type="radio"] {
|
|||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-pane > label:has(:focus-visible) {
|
|
||||||
outline: medium auto currentColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-pane > label:hover:not(:has(:checked)) {
|
.tab-pane > label:hover:not(:has(:checked)) {
|
||||||
border-color: #bbb;
|
border-color: #bbb;
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.control > span {
|
label {
|
||||||
width: 170px;
|
width: 170px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use nalgebra::DVector;
|
use nalgebra::DVector;
|
||||||
|
|
||||||
// the sphere with the given center and radius, with inward-pointing normals
|
|
||||||
pub fn sphere(center_x: f64, center_y: f64, center_z: f64, radius: f64) -> DVector<f64> {
|
pub fn sphere(center_x: f64, center_y: f64, center_z: f64, radius: f64) -> DVector<f64> {
|
||||||
let center_norm_sq = center_x * center_x + center_y * center_y + center_z * center_z;
|
let center_norm_sq = center_x * center_x + center_y * center_y + center_z * center_z;
|
||||||
DVector::from_column_slice(&[
|
DVector::from_column_slice(&[
|
||||||
@ -11,17 +10,3 @@ pub fn sphere(center_x: f64, center_y: f64, center_z: f64, radius: f64) -> DVect
|
|||||||
0.5 * (center_norm_sq / radius - radius)
|
0.5 * (center_norm_sq / radius - radius)
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
// the sphere of curvature `curv` whose closest point to the origin has position
|
|
||||||
// `off * dir` and normal `dir`, where `dir` is a unit vector. setting the
|
|
||||||
// curvature to zero gives a plane
|
|
||||||
pub fn sphere_with_offset(dir_x: f64, dir_y: f64, dir_z: f64, off: f64, curv: f64) -> DVector<f64> {
|
|
||||||
let norm_sp = 1.0 + off * curv;
|
|
||||||
DVector::from_column_slice(&[
|
|
||||||
norm_sp * dir_x,
|
|
||||||
norm_sp * dir_y,
|
|
||||||
norm_sp * dir_z,
|
|
||||||
0.5 * curv,
|
|
||||||
off * (1.0 + 0.5 * off * curv)
|
|
||||||
])
|
|
||||||
}
|
|
@ -110,37 +110,23 @@ taggedFrag sphere_shading(vecInv v, vec3 pt, vec3 base_color, int id) {
|
|||||||
|
|
||||||
// --- ray-casting ---
|
// --- ray-casting ---
|
||||||
|
|
||||||
// if `a/b` is less than this threshold, we approximate `a*u^2 + b*u + c` by
|
|
||||||
// the linear function `b*u + c`
|
|
||||||
const float DEG_THRESHOLD = 1e-9;
|
|
||||||
|
|
||||||
// the depths, represented as multiples of `dir`, where the line generated by
|
|
||||||
// `dir` hits the sphere represented by `v`. if both depths are positive, the
|
|
||||||
// smaller one is returned in the first component. if only one depth is
|
|
||||||
// positive, it could be returned in either component
|
|
||||||
vec2 sphere_cast(vecInv v, vec3 dir) {
|
vec2 sphere_cast(vecInv v, vec3 dir) {
|
||||||
float a = -v.lt.s * dot(dir, dir);
|
float a = -v.lt.s * dot(dir, dir);
|
||||||
float b = dot(v.sp, dir);
|
float b = dot(v.sp, dir);
|
||||||
float c = -v.lt.t;
|
float c = -v.lt.t;
|
||||||
|
|
||||||
|
float scale = -b/(2.*a);
|
||||||
float adjust = 4.*a*c/(b*b);
|
float adjust = 4.*a*c/(b*b);
|
||||||
|
|
||||||
if (adjust < 1.) {
|
if (adjust < 1.) {
|
||||||
// as long as `b` is non-zero, the linear approximation of
|
float offset = sqrt(1. - adjust);
|
||||||
//
|
return vec2(
|
||||||
// a*u^2 + b*u + c
|
scale * (1. - offset),
|
||||||
//
|
scale * (1. + offset)
|
||||||
// at `u = 0` will reach zero at a finite depth `u_lin`. the root of the
|
);
|
||||||
// quadratic adjacent to `u_lin` is stored in `lin_root`. if both roots
|
|
||||||
// have the same sign, `lin_root` will be the one closer to `u = 0`
|
|
||||||
float square_rect_ratio = 1. + sqrt(1. - adjust);
|
|
||||||
float lin_root = -(2.*c)/b / square_rect_ratio;
|
|
||||||
if (abs(a) > DEG_THRESHOLD * abs(b)) {
|
|
||||||
return vec2(lin_root, -b/(2.*a) * square_rect_ratio);
|
|
||||||
} else {
|
|
||||||
return vec2(lin_root, -1.);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// the line through `dir` misses the sphere completely
|
// these parameters describe points behind the camera, so the
|
||||||
|
// corresponding fragments won't be drawn
|
||||||
return vec2(-1., -1.);
|
return vec2(-1., -1.);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,13 +179,15 @@ void main() {
|
|||||||
if (debug_mode) {
|
if (debug_mode) {
|
||||||
// at the bottom of the screen, show the color scale instead of the
|
// at the bottom of the screen, show the color scale instead of the
|
||||||
// layer count
|
// layer count
|
||||||
if (gl_FragCoord.y < 10.) layer_cnt = int(16. * gl_FragCoord.x / resolution.x);
|
if (gl_FragCoord.y < 10.) layer_cnt = 2 * int(8. * gl_FragCoord.x / resolution.x);
|
||||||
|
|
||||||
// convert number to color
|
// convert number to color
|
||||||
ivec3 bits = layer_cnt / ivec3(1, 2, 4);
|
vec3 color;
|
||||||
vec3 color = mod(vec3(bits), 2.);
|
if (layer_cnt % 2 == 0) {
|
||||||
if (layer_cnt % 16 >= 8) {
|
ivec3 bits = layer_cnt / ivec3(2, 4, 8);
|
||||||
color = mix(color, vec3(0.5), 0.5);
|
color = mod(vec3(bits), 2.);
|
||||||
|
} else {
|
||||||
|
color = vec3(0.5);
|
||||||
}
|
}
|
||||||
outColor = vec4(color, 1.);
|
outColor = vec4(color, 1.);
|
||||||
return;
|
return;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
extern crate js_sys;
|
extern crate js_sys;
|
||||||
use core::array;
|
use core::array;
|
||||||
use nalgebra::{DMatrix, DVector};
|
use nalgebra::{DMatrix, DVector};
|
||||||
|
use std::f64::consts::FRAC_1_SQRT_2;
|
||||||
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};
|
||||||
|
|
||||||
@ -85,61 +86,30 @@ fn bind_vertex_attrib(
|
|||||||
|
|
||||||
fn push_gen_construction(
|
fn push_gen_construction(
|
||||||
sphere_vec: &mut Vec<DVector<f64>>,
|
sphere_vec: &mut Vec<DVector<f64>>,
|
||||||
color_vec: &mut Vec<[f32; 3]>,
|
|
||||||
construction_to_world: &DMatrix<f64>,
|
construction_to_world: &DMatrix<f64>,
|
||||||
ctrl_x: f64,
|
ctrl_x: f64,
|
||||||
ctrl_y: f64,
|
ctrl_y: f64,
|
||||||
radius_x: f64,
|
radius_x: f64,
|
||||||
radius_y: f64
|
radius_y: f64
|
||||||
) {
|
) {
|
||||||
// push spheres
|
|
||||||
sphere_vec.push(construction_to_world * engine::sphere(0.5, 0.5, ctrl_x, radius_x));
|
sphere_vec.push(construction_to_world * engine::sphere(0.5, 0.5, ctrl_x, radius_x));
|
||||||
sphere_vec.push(construction_to_world * engine::sphere(-0.5, -0.5, ctrl_y, radius_y));
|
sphere_vec.push(construction_to_world * engine::sphere(-0.5, -0.5, ctrl_y, radius_y));
|
||||||
sphere_vec.push(construction_to_world * engine::sphere(-0.5, 0.5, 0.0, 0.75));
|
sphere_vec.push(construction_to_world * engine::sphere(-0.5, 0.5, 0.0, 0.75));
|
||||||
sphere_vec.push(construction_to_world * engine::sphere(0.5, -0.5, 0.0, 0.5));
|
sphere_vec.push(construction_to_world * engine::sphere(0.5, -0.5, 0.0, 0.5));
|
||||||
sphere_vec.push(construction_to_world * engine::sphere(0.0, 0.15, 1.0, 0.25));
|
sphere_vec.push(construction_to_world * engine::sphere(0.0, 0.15, 1.0, 0.25));
|
||||||
sphere_vec.push(construction_to_world * engine::sphere(0.0, -0.15, -1.0, 0.25));
|
sphere_vec.push(construction_to_world * engine::sphere(0.0, -0.15, -1.0, 0.25));
|
||||||
|
|
||||||
// push colors
|
|
||||||
color_vec.push([1.00_f32, 0.25_f32, 0.00_f32]);
|
|
||||||
color_vec.push([0.00_f32, 0.25_f32, 1.00_f32]);
|
|
||||||
color_vec.push([0.25_f32, 0.00_f32, 1.00_f32]);
|
|
||||||
color_vec.push([0.25_f32, 1.00_f32, 0.00_f32]);
|
|
||||||
color_vec.push([0.75_f32, 0.75_f32, 0.00_f32]);
|
|
||||||
color_vec.push([0.00_f32, 0.75_f32, 0.50_f32]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_low_curv_construction(
|
fn push_low_curv_construction(
|
||||||
sphere_vec: &mut Vec<DVector<f64>>,
|
sphere_vec: &mut Vec<DVector<f64>>,
|
||||||
color_vec: &mut Vec<[f32; 3]>,
|
|
||||||
construction_to_world: &DMatrix<f64>,
|
construction_to_world: &DMatrix<f64>,
|
||||||
off1: f64,
|
curv_x: f64,
|
||||||
off2: f64,
|
curv_y: f64
|
||||||
off3: f64,
|
|
||||||
curv1: f64,
|
|
||||||
curv2: f64,
|
|
||||||
curv3: f64,
|
|
||||||
) {
|
) {
|
||||||
// push spheres
|
sphere_vec.push(construction_to_world * DVector::from_column_slice(&[0.0, -1.0, 0.0, 0.5*curv_x, 0.0]));
|
||||||
let a = 0.75_f64.sqrt();
|
sphere_vec.push(construction_to_world * DVector::from_column_slice(&[-FRAC_1_SQRT_2, 0.0, -FRAC_1_SQRT_2, 0.5*curv_y, 0.0]));
|
||||||
sphere_vec.push(construction_to_world * engine::sphere(0.0, 0.0, 0.0, 1.0));
|
sphere_vec.push(construction_to_world * engine::sphere(0.5, 0.0, 0.5, FRAC_1_SQRT_2));
|
||||||
sphere_vec.push(construction_to_world * engine::sphere_with_offset(0.0, 0.0, 1.0, 0.0, 0.0));
|
sphere_vec.push(construction_to_world * engine::sphere(-0.5, 0.0, -0.5, FRAC_1_SQRT_2));
|
||||||
sphere_vec.push(construction_to_world * engine::sphere_with_offset(1.0, 0.0, 0.0, off1, curv1));
|
|
||||||
sphere_vec.push(construction_to_world * engine::sphere_with_offset(-0.5, a, 0.0, off2, curv2));
|
|
||||||
sphere_vec.push(construction_to_world * engine::sphere_with_offset(-0.5, -a, 0.0, off3, curv3));
|
|
||||||
sphere_vec.push(construction_to_world * engine::sphere(-4.0/3.0, 0.0, 0.0, 1.0/3.0));
|
|
||||||
sphere_vec.push(construction_to_world * engine::sphere(2.0/3.0, -4.0/3.0 * a, 0.0, 1.0/3.0));
|
|
||||||
sphere_vec.push(construction_to_world * engine::sphere(2.0/3.0, 4.0/3.0 * a, 0.0, 1.0/3.0));
|
|
||||||
|
|
||||||
// push colors
|
|
||||||
color_vec.push([0.75_f32, 0.75_f32, 0.75_f32]);
|
|
||||||
color_vec.push([0.75_f32, 0.75_f32, 0.75_f32]);
|
|
||||||
color_vec.push([1.00_f32, 0.00_f32, 0.25_f32]);
|
|
||||||
color_vec.push([0.25_f32, 1.00_f32, 0.00_f32]);
|
|
||||||
color_vec.push([0.00_f32, 0.25_f32, 1.00_f32]);
|
|
||||||
color_vec.push([0.75_f32, 0.75_f32, 0.75_f32]);
|
|
||||||
color_vec.push([0.75_f32, 0.75_f32, 0.75_f32]);
|
|
||||||
color_vec.push([0.75_f32, 0.75_f32, 0.75_f32]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
@ -166,12 +136,8 @@ fn main() {
|
|||||||
|
|
||||||
// controls for low-curvature example
|
// controls for low-curvature example
|
||||||
let low_curv_controls = create_node_ref();
|
let low_curv_controls = create_node_ref();
|
||||||
let curv1 = create_signal(0.0);
|
let curv_x = create_signal(0.0);
|
||||||
let curv2 = create_signal(0.0);
|
let curv_y = create_signal(0.0);
|
||||||
let curv3 = create_signal(0.0);
|
|
||||||
let off1 = create_signal(1.0);
|
|
||||||
let off2 = create_signal(1.0);
|
|
||||||
let off3 = create_signal(1.0);
|
|
||||||
|
|
||||||
// shared controls
|
// shared controls
|
||||||
let opacity = create_signal(0.5);
|
let opacity = create_signal(0.5);
|
||||||
@ -202,12 +168,8 @@ fn main() {
|
|||||||
radius_y.track();
|
radius_y.track();
|
||||||
|
|
||||||
// track controls for low-curvature example
|
// track controls for low-curvature example
|
||||||
curv1.track();
|
curv_x.track();
|
||||||
curv2.track();
|
curv_y.track();
|
||||||
curv3.track();
|
|
||||||
off1.track();
|
|
||||||
off2.track();
|
|
||||||
off3.track();
|
|
||||||
|
|
||||||
// track shared controls
|
// track shared controls
|
||||||
opacity.track();
|
opacity.track();
|
||||||
@ -237,10 +199,17 @@ fn main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// create list of construction elements
|
// list construction elements
|
||||||
const SPHERE_MAX: usize = 200;
|
const SPHERE_MAX: usize = 200;
|
||||||
let mut sphere_vec = Vec::<DVector<f64>>::new();
|
let mut sphere_vec = Vec::<DVector<f64>>::new();
|
||||||
let mut color_vec = Vec::<[f32; 3]>::new();
|
let color_vec = vec![
|
||||||
|
[1.00_f32, 0.25_f32, 0.00_f32],
|
||||||
|
[0.00_f32, 0.25_f32, 1.00_f32],
|
||||||
|
[0.25_f32, 0.00_f32, 1.00_f32],
|
||||||
|
[0.25_f32, 1.00_f32, 0.00_f32],
|
||||||
|
[0.75_f32, 0.75_f32, 0.00_f32],
|
||||||
|
[0.00_f32, 0.75_f32, 0.50_f32],
|
||||||
|
];
|
||||||
|
|
||||||
// timing
|
// timing
|
||||||
let mut last_time = 0.0;
|
let mut last_time = 0.0;
|
||||||
@ -396,21 +365,17 @@ fn main() {
|
|||||||
|
|
||||||
// update the construction
|
// update the construction
|
||||||
sphere_vec.clear();
|
sphere_vec.clear();
|
||||||
color_vec.clear();
|
|
||||||
match tab_selection.get() {
|
match tab_selection.get() {
|
||||||
Tab::GenTab => push_gen_construction(
|
Tab::GenTab => push_gen_construction(
|
||||||
&mut sphere_vec,
|
&mut sphere_vec,
|
||||||
&mut color_vec,
|
|
||||||
&construction_to_world,
|
&construction_to_world,
|
||||||
ctrl_x.get(), ctrl_y.get(),
|
ctrl_x.get(), ctrl_y.get(),
|
||||||
radius_x.get(), radius_y.get()
|
radius_x.get(), radius_y.get()
|
||||||
),
|
),
|
||||||
Tab::LowCurvTab => push_low_curv_construction(
|
Tab::LowCurvTab => push_low_curv_construction(
|
||||||
&mut sphere_vec,
|
&mut sphere_vec,
|
||||||
&mut color_vec,
|
|
||||||
&construction_to_world,
|
&construction_to_world,
|
||||||
off1.get(), off2.get(), off3.get(),
|
curv_x.get(), curv_y.get()
|
||||||
curv1.get(), curv2.get(), curv3.get(),
|
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -482,42 +447,46 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
div { "Mean frame interval: " (mean_frame_interval.get()) " ms" }
|
div { "Mean frame interval: " (mean_frame_interval.get()) " ms" }
|
||||||
canvas(ref=display, width=600, height=600, tabindex=0)
|
canvas(ref=display, width="600", height="600")
|
||||||
div(ref=gen_controls) {
|
div(ref=gen_controls) {
|
||||||
label(class="control") {
|
div(class="control") {
|
||||||
span { "Sphere 0 depth" }
|
label(for="ctrl-x") { "Sphere 0 depth" }
|
||||||
input(
|
input(
|
||||||
type="range",
|
type="range",
|
||||||
|
id="ctrl-x",
|
||||||
min=-1.0,
|
min=-1.0,
|
||||||
max=1.0,
|
max=1.0,
|
||||||
step=0.001,
|
step=0.001,
|
||||||
bind:valueAsNumber=ctrl_x
|
bind:valueAsNumber=ctrl_x
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
label(class="control") {
|
div(class="control") {
|
||||||
span { "Sphere 1 depth" }
|
label(for="ctrl-y") { "Sphere 1 depth" }
|
||||||
input(
|
input(
|
||||||
type="range",
|
type="range",
|
||||||
|
id="ctrl-y",
|
||||||
min=-1.0,
|
min=-1.0,
|
||||||
max=1.0,
|
max=1.0,
|
||||||
step=0.001,
|
step=0.001,
|
||||||
bind:valueAsNumber=ctrl_y
|
bind:valueAsNumber=ctrl_y
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
label(class="control") {
|
div(class="control") {
|
||||||
span { "Sphere 0 radius" }
|
label(for="radius-x") { "Sphere 0 radius" }
|
||||||
input(
|
input(
|
||||||
type="range",
|
type="range",
|
||||||
|
id="radius-x",
|
||||||
min=0.5,
|
min=0.5,
|
||||||
max=1.5,
|
max=1.5,
|
||||||
step=0.001,
|
step=0.001,
|
||||||
bind:valueAsNumber=radius_x
|
bind:valueAsNumber=radius_x
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
label(class="control") {
|
div(class="control") {
|
||||||
span { "Sphere 1 radius" }
|
label(for="radius-y") { "Sphere 1 radius" }
|
||||||
input(
|
input(
|
||||||
type="range",
|
type="range",
|
||||||
|
id="radius-y",
|
||||||
min=0.5,
|
min=0.5,
|
||||||
max=1.5,
|
max=1.5,
|
||||||
step=0.001,
|
step=0.001,
|
||||||
@ -526,105 +495,72 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
div(ref=low_curv_controls) {
|
div(ref=low_curv_controls) {
|
||||||
label(class="control") {
|
div(class="control") {
|
||||||
span { "Sphere 1 offset" }
|
label(for="curv-x") { "Sphere 0 curvature" }
|
||||||
input(
|
|
||||||
type="range",
|
|
||||||
min=-1.0,
|
|
||||||
max=1.0,
|
|
||||||
step=0.001,
|
|
||||||
bind:valueAsNumber=off1
|
|
||||||
)
|
|
||||||
}
|
|
||||||
label(class="control") {
|
|
||||||
span { "Sphere 2 offset" }
|
|
||||||
input(
|
|
||||||
type="range",
|
|
||||||
min=-1.0,
|
|
||||||
max=1.0,
|
|
||||||
step=0.001,
|
|
||||||
bind:valueAsNumber=off2
|
|
||||||
)
|
|
||||||
}
|
|
||||||
label(class="control") {
|
|
||||||
span { "Sphere 3 offset" }
|
|
||||||
input(
|
|
||||||
type="range",
|
|
||||||
min=-1.0,
|
|
||||||
max=1.0,
|
|
||||||
step=0.001,
|
|
||||||
bind:valueAsNumber=off3
|
|
||||||
)
|
|
||||||
}
|
|
||||||
label(class="control") {
|
|
||||||
span { "Sphere 1 curvature" }
|
|
||||||
input(
|
input(
|
||||||
type="range",
|
type="range",
|
||||||
|
id="curv-x",
|
||||||
min=0.0,
|
min=0.0,
|
||||||
max=2.0,
|
max=2.0,
|
||||||
step=0.001,
|
step=0.001,
|
||||||
bind:valueAsNumber=curv1
|
bind:valueAsNumber=curv_x
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
label(class="control") {
|
div(class="control") {
|
||||||
span { "Sphere 2 curvature" }
|
label(for="curv-y") { "Sphere 1 curvature" }
|
||||||
input(
|
input(
|
||||||
type="range",
|
type="range",
|
||||||
|
id="curv-y",
|
||||||
min=0.0,
|
min=0.0,
|
||||||
max=2.0,
|
max=2.0,
|
||||||
step=0.001,
|
step=0.001,
|
||||||
bind:valueAsNumber=curv2
|
bind:valueAsNumber=curv_y
|
||||||
)
|
|
||||||
}
|
|
||||||
label(class="control") {
|
|
||||||
span { "Sphere 3 curvature" }
|
|
||||||
input(
|
|
||||||
type="range",
|
|
||||||
min=0.0,
|
|
||||||
max=2.0,
|
|
||||||
step=0.001,
|
|
||||||
bind:valueAsNumber=curv3
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
label(class="control") {
|
div(class="control") {
|
||||||
span { "Opacity" }
|
label(for="opacity") { "Opacity" }
|
||||||
input(
|
input(
|
||||||
type="range",
|
type="range",
|
||||||
|
id="opacity",
|
||||||
max=1.0,
|
max=1.0,
|
||||||
step=0.001,
|
step=0.001,
|
||||||
bind:valueAsNumber=opacity
|
bind:valueAsNumber=opacity
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
label(class="control") {
|
div(class="control") {
|
||||||
span { "Highlight" }
|
label(for="highlight") { "Highlight" }
|
||||||
input(
|
input(
|
||||||
type="range",
|
type="range",
|
||||||
|
id="highlight",
|
||||||
max=1.0,
|
max=1.0,
|
||||||
step=0.001,
|
step=0.001,
|
||||||
bind:valueAsNumber=highlight
|
bind:valueAsNumber=highlight
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
label(class="control") {
|
div(class="control") {
|
||||||
span { "Turntable" }
|
label(for="turntable") { "Turntable" }
|
||||||
input(
|
input(
|
||||||
type="checkbox",
|
type="checkbox",
|
||||||
|
id="turntable",
|
||||||
bind:checked=turntable
|
bind:checked=turntable
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
label(class="control") {
|
div(class="control") {
|
||||||
span { "Layer threshold" }
|
label(for="layer-threshold") { "Layer threshold" }
|
||||||
input(
|
input(
|
||||||
type="range",
|
type="range",
|
||||||
|
id="layer-threshold",
|
||||||
max=5.0,
|
max=5.0,
|
||||||
step=1.0,
|
step=1.0,
|
||||||
bind:valueAsNumber=layer_threshold
|
bind:valueAsNumber=layer_threshold
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
label(class="control") {
|
div(class="control") {
|
||||||
span { "Debug mode" }
|
label(for="debug-mode") { "Debug mode" }
|
||||||
input(
|
input(
|
||||||
type="checkbox",
|
type="checkbox",
|
||||||
|
id="debug-mode",
|
||||||
bind:checked=debug_mode
|
bind:checked=debug_mode
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user