diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..f0ca720 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,40 @@ +on: [push, pull_request] + +name: Rust + +jobs: + fmt-crank-check-test: + name: format + check + test + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + + - uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.72.0 + + - name: cache + uses: Swatinem/rust-cache@v2 + + - name: fmt + run: cargo fmt --all -- --check + + - name: install cargo-cranky + uses: baptiste0928/cargo-install@v1 + with: + crate: cargo-cranky + + - name: check --all-features + run: cargo check --all-features --all-targets + + - name: test doc-tests + run: cargo test --doc --all-features + + - name: test + run: cargo test --all-features + + - name: cranky + run: cargo cranky --all-targets --all-features -- -D warnings + + - name: cranky --release + run: cargo cranky --all-targets --all-features --release -- -D warnings \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 6733db6..9078cfa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,3 +24,156 @@ mint = "0.5" [profile.release] opt-level = "s" lto = "thin" + +[lints] +workspace = true + +[workspace.lints.rust] +elided_lifetimes_in_paths = "allow" +future_incompatible = "deny" +nonstandard_style = "deny" +rust_2018_idioms = "warn" +rust_2021_prelude_collisions = "deny" +semicolon_in_expressions_from_macros = "deny" +trivial_numeric_casts = "deny" +unsafe_op_in_unsafe_fn = "deny" +unused_extern_crates = "deny" +unused_import_braces = "deny" +unused_lifetimes = "deny" +unsafe_code = "deny" + +[workspace.lints.clippy] +all = "deny" +as_ptr_cast_mut = "deny" +await_holding_lock = "deny" +bool_to_int_with_if = "deny" +branches_sharing_code = "deny" +char_lit_as_u8 = "deny" +checked_conversions = "deny" +clear_with_drain = "deny" +cloned_instead_of_copied = "deny" +dbg_macro = "deny" +debug_assert_with_mut_call = "deny" +default_union_representation = "deny" +derive_partial_eq_without_eq = "deny" +disallowed_macros = "deny" +disallowed_methods = "deny" +disallowed_names = "deny" +disallowed_script_idents = "deny" +disallowed_types = "deny" +doc_link_with_quotes = "deny" +doc_markdown = "deny" +empty_enum = "deny" +empty_line_after_outer_attr = "deny" +enum_glob_use = "deny" +equatable_if_let = "deny" +exit = "deny" +expl_impl_clone_on_copy = "deny" +explicit_deref_methods = "deny" +explicit_into_iter_loop = "deny" +explicit_iter_loop = "deny" +fallible_impl_from = "deny" +filter_map_next = "deny" +flat_map_option = "deny" +float_cmp_const = "deny" +fn_params_excessive_bools = "deny" +fn_to_numeric_cast_any = "deny" +from_iter_instead_of_collect = "deny" +get_unwrap = "deny" +if_let_mutex = "deny" +implicit_clone = "deny" +imprecise_flops = "deny" +index_refutable_slice = "deny" +inefficient_to_string = "deny" +invalid_upcast_comparisons = "deny" +iter_not_returning_iterator = "deny" +iter_on_empty_collections = "deny" +iter_on_single_items = "deny" +large_digit_groups = "deny" +large_include_file = "deny" +large_stack_arrays = "deny" +large_stack_frames = "deny" +large_types_passed_by_value = "deny" +let_unit_value = "deny" +linkedlist = "deny" +lossy_float_literal = "deny" +macro_use_imports = "deny" +manual_assert = "deny" +manual_clamp = "deny" +manual_instant_elapsed = "deny" +manual_let_else = "deny" +manual_ok_or = "deny" +manual_string_new = "deny" +map_err_ignore = "deny" +map_flatten = "deny" +map_unwrap_or = "deny" +match_on_vec_items = "deny" +match_same_arms = "deny" +match_wild_err_arm = "deny" +match_wildcard_for_single_variants = "deny" +mem_forget = "deny" +mismatched_target_os = "deny" +mismatching_type_param_order = "deny" +missing_enforced_import_renames = "deny" +missing_safety_doc = "deny" +mut_mut = "deny" +mutex_integer = "deny" +needless_borrow = "deny" +needless_continue = "deny" +needless_for_each = "deny" +needless_pass_by_value = "deny" +negative_feature_names = "deny" +nonstandard_macro_braces = "deny" +option_option = "deny" +path_buf_push_overwrite = "deny" +print_stdout = "deny" +ptr_as_ptr = "deny" +ptr_cast_constness = "deny" +pub_without_shorthand = "deny" +rc_mutex = "deny" +redundant_type_annotations = "deny" +ref_option_ref = "deny" +rest_pat_in_fully_bound_structs = "deny" +same_functions_in_if_condition = "deny" +semicolon_if_nothing_returned = "deny" +significant_drop_tightening = "deny" +single_match_else = "deny" +str_to_string = "deny" +string_add_assign = "deny" +string_add = "deny" +string_lit_as_bytes = "deny" +string_to_string = "deny" +suspicious_command_arg_space = "deny" +suspicious_xor_used_as_pow = "deny" +todo = "deny" +trailing_empty_array = "deny" +trait_duplication_in_bounds = "deny" +transmute_ptr_to_ptr = "deny" +tuple_array_conversions = "deny" +unchecked_duration_subtraction = "deny" +unimplemented = "deny" +uninlined_format_args = "deny" +unnecessary_box_returns = "deny" +unnecessary_safety_comment = "deny" +unnecessary_safety_doc = "deny" +unnecessary_self_imports = "deny" +unnecessary_struct_initialization = "deny" +unnecessary_wraps = "deny" +unnested_or_patterns = "deny" +unused_peekable = "deny" +unused_rounding = "deny" +unused_self = "deny" +use_self = "deny" +useless_transmute = "deny" +verbose_file_reads = "deny" +wildcard_dependencies = "deny" +zero_sized_map_values = "deny" +let_underscore_untyped = "allow" +missing_assert_message = "allow" +missing_errors_doc = "allow" +too_many_lines = "allow" +undocumented_unsafe_blocks = "allow" +unwrap_used = "allow" +wildcard_imports = "allow" +large-types-passed-by-value = "allow" +needless-pass-by-value = "allow" \ No newline at end of file diff --git a/demo/Cargo.toml b/demo/Cargo.toml index c9253ed..9a13386 100644 --- a/demo/Cargo.toml +++ b/demo/Cargo.toml @@ -20,3 +20,6 @@ rev="bc3dd1559e24ca0178ed1d2dfef07cb784437505" [dependencies.bevy_infinite_grid] git = "https://github.com/pcwalton/bevy_infinite_grid.git" rev = "c752a23063b2b05163e307889eb276d6574115ab" + +[lints] +workspace = true \ No newline at end of file diff --git a/demo/build_web.sh b/demo/build_web.sh deleted file mode 100755 index aeade30..0000000 --- a/demo/build_web.sh +++ /dev/null @@ -1 +0,0 @@ -trunk build --config Trunk.toml --release diff --git a/demo/src/camera.rs b/demo/src/camera.rs index edc61bc..2bac8f0 100644 --- a/demo/src/camera.rs +++ b/demo/src/camera.rs @@ -12,7 +12,7 @@ pub struct PanOrbitCamera { impl Default for PanOrbitCamera { fn default() -> Self { - PanOrbitCamera { + Self { focus: Vec3::ZERO, radius: 5.0, upside_down: false, @@ -75,7 +75,7 @@ pub fn update_camera( orbit_button_changed = true; } - for (mut pan_orbit, mut transform, projection) in query.iter_mut() { + for (mut pan_orbit, mut transform, projection) in &mut query { if orbit_button_changed { // only check for upside down when orbiting started or ended this frame // if the camera is "upside" down, panning horizontally would be inverted, so invert the input to make it correct diff --git a/docs/egui-gizmo-demo.js b/docs/egui-gizmo-demo.js index 73ba3f1..71d400d 100644 --- a/docs/egui-gizmo-demo.js +++ b/docs/egui-gizmo-demo.js @@ -1 +1 @@ -let a5=4,T=null,Q=`undefined`,a0=`boolean`,a9=51485,_=`function`,a1=`string`,W=0,Y=1,a2=`Object`,U=`utf-8`,$=`number`,S=Array,V=Error,a4=Float32Array,Z=Int32Array,a3=JSON.stringify,a7=Object,a8=Reflect,a6=Uint32Array,X=Uint8Array,R=undefined;var F=((a,b)=>{a=a>>>W;return E().subarray(a/a5,a/a5+ b)});var v=(a=>{const b=typeof a;if(b==$||b==a0||a==T){return `${a}`};if(b==a1){return `"${a}"`};if(b==`symbol`){const b=a.description;if(b==T){return `Symbol`}else{return `Symbol(${b})`}};if(b==_){const b=a.name;if(typeof b==a1&&b.length>W){return `Function(${b})`}else{return `Function`}};if(S.isArray(a)){const b=a.length;let c=`[`;if(b>W){c+=v(a[W])};for(let d=Y;dY){d=c[Y]}else{return toString.call(a)};if(d==a2){try{return `Object(`+ a3(a)+ `)`}catch(a){return a2}};if(a instanceof V){return `${a.name}: ${a.message}\n${a.stack}`};return d});var E=(()=>{if(D===T||D.byteLength===W){D=new a4(b.memory.buffer)};return D});var M=((a,b)=>{});var y=((a,c,d)=>{b._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h01894152668a573b(a,c,l(d))});function C(a,c){try{return a.apply(this,c)}catch(a){b.__wbindgen_exn_store(l(a))}}var m=(a=>a===R||a===T);var d=(a=>c[a]);var o=(()=>{if(n===T||n.byteLength===W){n=new Float64Array(b.memory.buffer)};return n});var L=(()=>{const c={};c.wbg={};c.wbg.__wbindgen_cb_drop=(a=>{const b=g(a).original;if(b.cnt--==Y){b.a=W;return !0};const c=!1;return c});c.wbg.__wbindgen_object_drop_ref=(a=>{g(a)});c.wbg.__wbg_stringify_e1b19966d964d242=function(){return C((a=>{const b=a3(d(a));return l(b)}),arguments)};c.wbg.__wbg_fetch_1f9eb1a6c5433fb7=((a,b,c)=>{const e=d(a).fetch(k(b,c));return l(e)});c.wbg.__wbg_instanceof_Response_4c3b1446206114d1=(a=>{let b;try{b=d(a) instanceof Response}catch(a){b=!1}const c=b;return c});c.wbg.__wbg_status_d6d47ad2837621eb=(a=>{const b=d(a).status;return b});c.wbg.__wbg_arrayBuffer_5b2688e3dd873fed=function(){return C((a=>{const b=d(a).arrayBuffer();return l(b)}),arguments)};c.wbg.__wbg_new_8f67e318f15d7254=(a=>{const b=new X(d(a));return l(b)});c.wbg.__wbg_mark_40e050a77cc39fea=((a,b)=>{performance.mark(k(a,b))});c.wbg.__wbg_log_c9486ca5d8e2cbe8=((a,c)=>{let d;let e;try{d=a;e=c;console.log(k(a,c))}finally{b.__wbindgen_free(d,e,Y)}});c.wbg.__wbg_log_aba5996d9bde071f=((a,c,d,e,f,g,h,i)=>{let j;let l;try{j=a;l=c;console.log(k(a,c),k(d,e),k(f,g),k(h,i))}finally{b.__wbindgen_free(j,l,Y)}});c.wbg.__wbg_width_cfc58d9656d60465=(a=>{const b=d(a).width;return b});c.wbg.__wbg_height_1ba9072bd4001d19=(a=>{const b=d(a).height;return b});c.wbg.__wbg_matchMedia_7fbd33cb577fe4ad=function(){return C(((a,b,c)=>{const e=d(a).matchMedia(k(b,c));return m(e)?W:l(e)}),arguments)};c.wbg.__wbg_matches_4cc0ff05af669dc3=(a=>{const b=d(a).matches;return b});c.wbg.__wbg_requestAnimationFrame_74309aadebde12fa=function(){return C(((a,b)=>{const c=d(a).requestAnimationFrame(d(b));return c}),arguments)};c.wbg.__wbg_setTimeout_06458eba2b40711c=function(){return C(((a,b,c)=>{const e=d(a).setTimeout(d(b),c);return e}),arguments)};c.wbg.__wbg_removeEventListener_70ee8cc1640c97d7=function(){return C(((a,b,c,e,f)=>{d(a).removeEventListener(k(b,c),d(e),d(f))}),arguments)};c.wbg.__wbindgen_string_new=((a,b)=>{const c=k(a,b);return l(c)});c.wbg.__wbg_error_cd2ee9c1f33e07e2=((a,b)=>{console.error(d(a),d(b))});c.wbg.__wbindgen_object_clone_ref=(a=>{const b=d(a);return l(b)});c.wbg.__wbg_addEventListener_374cbfd2bbc19ccf=function(){return C(((a,b,c,e,f)=>{d(a).addEventListener(k(b,c),d(e),d(f))}),arguments)};c.wbg.__wbg_addEventListener_9bf60ea8a362e5e4=function(){return C(((a,b,c,e)=>{d(a).addEventListener(k(b,c),d(e))}),arguments)};c.wbg.__wbg_new_9fb8d994e1c0aaac=(()=>{const a=new a7();return l(a)});c.wbg.__wbg_document_d609202d16c38224=(a=>{const b=d(a).document;return m(b)?W:l(b)});c.wbg.__wbg_querySelector_c72dce5ac4b6bc3e=function(){return C(((a,b,c)=>{const e=d(a).querySelector(k(b,c));return m(e)?W:l(e)}),arguments)};c.wbg.__wbg_instanceof_HtmlCanvasElement_fba0ac991170cc00=(a=>{let b;try{b=d(a) instanceof HTMLCanvasElement}catch(a){b=!1}const c=b;return c});c.wbg.__wbg_body_64abc9aba1891e91=(a=>{const b=d(a).body;return m(b)?W:l(b)});c.wbg.__wbg_appendChild_d30e6b83791d04c0=function(){return C(((a,b)=>{const c=d(a).appendChild(d(b));return l(c)}),arguments)};c.wbg.__wbg_requestPointerLock_1a4ef1990ed6cc1b=(a=>{d(a).requestPointerLock()});c.wbg.__wbg_parentElement_72e144c2e8d9e0b5=(a=>{const b=d(a).parentElement;return m(b)?W:l(b)});c.wbg.__wbg_getBoundingClientRect_4167ccfa40cf88fc=(a=>{const b=d(a).getBoundingClientRect();return l(b)});c.wbg.__wbg_width_1ccae8ab185a4192=(a=>{const b=d(a).width;return b});c.wbg.__wbg_height_415b4e67932f43c9=(a=>{const b=d(a).height;return b});c.wbg.__wbg_stopPropagation_b7a931152e09c2ab=(a=>{d(a).stopPropagation()});c.wbg.__wbg_cancelBubble_976cfdf7ac449a6c=(a=>{const b=d(a).cancelBubble;return b});c.wbg.__wbg_matches_9502c0f8ac0be969=(a=>{const b=d(a).matches;return b});c.wbg.__wbg_preventDefault_7f821f72e7c6b5d4=(a=>{d(a).preventDefault()});c.wbg.__wbg_target_52ddf6955f636bf5=(a=>{const b=d(a).target;return m(b)?W:l(b)});c.wbg.__wbg_is_ff7acd231c75c0e4=((a,b)=>{const c=a7.is(d(a),d(b));return c});c.wbg.__wbg_offsetX_e8c2e5379a90ae29=(a=>{const b=d(a).offsetX;return b});c.wbg.__wbg_offsetY_b8587366f6d36a25=(a=>{const b=d(a).offsetY;return b});c.wbg.__wbg_movementX_0a37286f5ab0f3d1=(a=>{const b=d(a).movementX;return b});c.wbg.__wbg_movementY_e32c630fded47131=(a=>{const b=d(a).movementY;return b});c.wbg.__wbg_requestFullscreen_3c582ffcaaffe1fd=function(){return C((a=>{d(a).requestFullscreen()}),arguments)};c.wbg.__wbg_buttons_45faa2de9fb9d23b=(a=>{const b=d(a).buttons;return b});c.wbg.__wbg_pointerType_07ad77393049c448=((a,c)=>{const e=d(c).pointerType;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_pointerId_32f8345c9e0f0ed8=(a=>{const b=d(a).pointerId;return b});c.wbg.__wbg_clientX_1a01963cb1caa614=(a=>{const b=d(a).clientX;return b});c.wbg.__wbg_clientY_c370190d4150fba9=(a=>{const b=d(a).clientY;return b});c.wbg.__wbg_pressure_b9f7c7decc59eb11=(a=>{const b=d(a).pressure;return b});c.wbg.__wbg_key_cf8022c18f47869e=((a,c)=>{const e=d(c).key;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_ctrlKey_977280484bcead08=(a=>{const b=d(a).ctrlKey;return b});c.wbg.__wbg_altKey_bf16cace6fb79198=(a=>{const b=d(a).altKey;return b});c.wbg.__wbg_getModifierState_bdeffc8dda44d6dd=((a,b,c)=>{const e=d(a).getModifierState(k(b,c));return e});c.wbg.__wbg_keyCode_48fe24f81bbcf215=(a=>{const b=d(a).keyCode;return b});c.wbg.__wbg_charCode_702eeeb047f6dad2=(a=>{const b=d(a).charCode;return b});c.wbg.__wbg_setPointerCapture_ba1b525b85454761=function(){return C(((a,b)=>{d(a).setPointerCapture(b)}),arguments)};c.wbg.__wbg_new_abda76e883ba8a5f=(()=>{const a=new V();return l(a)});c.wbg.__wbg_stack_658279fe44541cf6=((a,c)=>{const e=d(c).stack;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_error_f851667af71bcfc6=((a,c)=>{let d;let e;try{d=a;e=c;console.error(k(a,c))}finally{b.__wbindgen_free(d,e,Y)}});c.wbg.__wbg_resume_61e2f63e5d5444cd=function(){return C((a=>{const b=d(a).resume();return l(b)}),arguments)};c.wbg.__wbg_close_b87bff143de234d5=function(){return C((a=>{const b=d(a).close();return l(b)}),arguments)};c.wbg.__wbg_eval_0b93354704a20351=function(){return C(((a,b)=>{const c=eval(k(a,b));return l(c)}),arguments)};c.wbg.__wbindgen_boolean_get=(a=>{const b=d(a);const c=typeof b===a0?(b?Y:W):2;return c});c.wbg.__wbg_crypto_c48a774b022d20ac=(a=>{const b=d(a).crypto;return l(b)});c.wbg.__wbindgen_is_object=(a=>{const b=d(a);const c=typeof b===`object`&&b!==T;return c});c.wbg.__wbg_process_298734cf255a885d=(a=>{const b=d(a).process;return l(b)});c.wbg.__wbg_versions_e2e78e134e3e5d01=(a=>{const b=d(a).versions;return l(b)});c.wbg.__wbg_node_1cd7a5d853dbea79=(a=>{const b=d(a).node;return l(b)});c.wbg.__wbindgen_is_string=(a=>{const b=typeof d(a)===a1;return b});c.wbg.__wbg_require_8f08ceecec0f4fee=function(){return C((()=>{const a=module.require;return l(a)}),arguments)};c.wbg.__wbindgen_is_function=(a=>{const b=typeof d(a)===_;return b});c.wbg.__wbg_call_5da1969d7cd31ccd=function(){return C(((a,b,c)=>{const e=d(a).call(d(b),d(c));return l(e)}),arguments)};c.wbg.__wbg_msCrypto_bcb970640f50a1e8=(a=>{const b=d(a).msCrypto;return l(b)});c.wbg.__wbg_newwithlength_6c2df9e2f3028c43=(a=>{const b=new X(a>>>W);return l(b)});c.wbg.__wbg_randomFillSync_dc1e9a60c158336d=function(){return C(((a,b)=>{d(a).randomFillSync(g(b))}),arguments)};c.wbg.__wbg_subarray_2e940e41c0f5a1d9=((a,b,c)=>{const e=d(a).subarray(b>>>W,c>>>W);return l(e)});c.wbg.__wbg_getRandomValues_37fa2ca9e4e07fab=function(){return C(((a,b)=>{d(a).getRandomValues(d(b))}),arguments)};c.wbg.__wbg_connected_b7635f1ca65b9aed=(a=>{const b=d(a).connected;return b});c.wbg.__wbg_now_096aa89623f72d50=(()=>{const a=Date.now();return a});c.wbg.__wbindgen_number_get=((a,b)=>{const c=d(b);const e=typeof c===$?c:R;o()[a/8+ Y]=m(e)?W:e;q()[a/a5+ W]=!m(e)});c.wbg.__wbindgen_is_null=(a=>{const b=d(a)===T;return b});c.wbg.__wbg_id_5dc2c54ac7e4e03d=((a,c)=>{const e=d(c).id;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_buttons_db34e12152ea40cb=(a=>{const b=d(a).buttons;return l(b)});c.wbg.__wbg_length_1009b1af0c481d7b=(a=>{const b=d(a).length;return b});c.wbg.__wbg_axes_d0d77b474ee9ca9b=(a=>{const b=d(a).axes;return l(b)});c.wbg.__wbg_mapping_f5c841b5e4d3469b=(a=>{const b=d(a).mapping;return l(b)});c.wbg.__wbg_get_f01601b5a68d10e3=((a,b)=>{const c=d(a)[b>>>W];return l(c)});c.wbg.__wbg_pressed_e69db502a61fa2d8=(a=>{const b=d(a).pressed;return b});c.wbg.__wbg_value_06cba5b7a5b72e36=(a=>{const b=d(a).value;return b});c.wbg.__wbg_isSecureContext_4d5c40709f7f7559=(a=>{const b=d(a).isSecureContext;return b});c.wbg.__wbg_navigator_96ba491902f8f083=(a=>{const b=d(a).navigator;return l(b)});c.wbg.__wbg_getGamepads_d4130931a826d504=function(){return C((a=>{const b=d(a).getGamepads();return l(b)}),arguments)};c.wbg.__wbg_index_6b2865fd145fa48d=(a=>{const b=d(a).index;return b});c.wbg.__wbg_instanceof_DomException_b6a266bb8c76af9e=(a=>{let b;try{b=d(a) instanceof DOMException}catch(a){b=!1}const c=b;return c});c.wbg.__wbg_message_3915f683795a43d9=((a,c)=>{const e=d(c).message;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_getExtension_b32d1f4b44a2464b=function(){return C(((a,b,c)=>{const e=d(a).getExtension(k(b,c));return m(e)?W:l(e)}),arguments)};c.wbg.__wbg_getSupportedExtensions_24ca3063e6cb52dc=(a=>{const b=d(a).getSupportedExtensions();return m(b)?W:l(b)});c.wbg.__wbg_getParameter_92e1c06daec0a5db=function(){return C(((a,b)=>{const c=d(a).getParameter(b>>>W);return l(c)}),arguments)};c.wbg.__wbindgen_string_get=((a,c)=>{const e=d(c);const f=typeof e===a1?e:R;var g=m(f)?W:u(f,b.__wbindgen_malloc,b.__wbindgen_realloc);var h=r;q()[a/a5+ Y]=h;q()[a/a5+ W]=g});c.wbg.__wbg_texSubImage2D_009f28c178ac0ef3=function(){return C(((a,b,c,e,f,g,h,i,j,k)=>{d(a).texSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j>>>W,d(k))}),arguments)};c.wbg.__wbg_texSubImage2D_09f65ee13c9715c2=function(){return C(((a,b,c,e,f,g,h,i,j,k)=>{d(a).texSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j>>>W,d(k))}),arguments)};c.wbg.__wbg_texSubImage2D_586bd03abd8b9645=function(){return C(((a,b,c,e,f,g,h,i,j,k)=>{d(a).texSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j>>>W,d(k))}),arguments)};c.wbg.__wbg_texSubImage3D_b3b3c1e1aaaa99a9=function(){return C(((a,b,c,e,f,g,h,i,j,k,l,m)=>{d(a).texSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,l>>>W,d(m))}),arguments)};c.wbg.__wbg_texSubImage3D_1629275aaeddba7f=function(){return C(((a,b,c,e,f,g,h,i,j,k,l,m)=>{d(a).texSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,l>>>W,d(m))}),arguments)};c.wbg.__wbg_texSubImage3D_55f32eefc1c80c07=function(){return C(((a,b,c,e,f,g,h,i,j,k,l,m)=>{d(a).texSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,l>>>W,d(m))}),arguments)};c.wbg.__wbg_framebufferTextureMultiviewOVR_6ec7a85f3367d20e=((a,b,c,e,f,g,h)=>{d(a).framebufferTextureMultiviewOVR(b>>>W,c>>>W,d(e),f,g,h)});c.wbg.__wbg_bindFramebuffer_33174ee82d938627=((a,b,c)=>{d(a).bindFramebuffer(b>>>W,d(c))});c.wbg.__wbg_bindFramebuffer_80ab0501951cc2c3=((a,b,c)=>{d(a).bindFramebuffer(b>>>W,d(c))});c.wbg.__wbg_getSupportedProfiles_25ed88a41293cb71=(a=>{const b=d(a).getSupportedProfiles();return m(b)?W:l(b)});c.wbg.__wbg_new_ffc6d4d085022169=(()=>{const a=new S();return l(a)});c.wbg.__wbg_includes_cafdff20dd66763c=((a,b,c)=>{const e=d(a).includes(d(b),c);return e});c.wbg.__wbg_createFramebuffer_1b0ce659f44b2562=(a=>{const b=d(a).createFramebuffer();return m(b)?W:l(b)});c.wbg.__wbg_createFramebuffer_66918f52f84fb0a9=(a=>{const b=d(a).createFramebuffer();return m(b)?W:l(b)});c.wbg.__wbg_createQuery_3a315cf1eec44e3d=(a=>{const b=d(a).createQuery();return m(b)?W:l(b)});c.wbg.__wbg_createRenderbuffer_cd7b8379638f7c64=(a=>{const b=d(a).createRenderbuffer();return m(b)?W:l(b)});c.wbg.__wbg_createRenderbuffer_6d6e37cbb502ca33=(a=>{const b=d(a).createRenderbuffer();return m(b)?W:l(b)});c.wbg.__wbg_createSampler_3a2ddaedd95dc2c5=(a=>{const b=d(a).createSampler();return m(b)?W:l(b)});c.wbg.__wbg_createShader_25391a4dceb30291=((a,b)=>{const c=d(a).createShader(b>>>W);return m(c)?W:l(c)});c.wbg.__wbg_createShader_a56f470ffa1c92a5=((a,b)=>{const c=d(a).createShader(b>>>W);return m(c)?W:l(c)});c.wbg.__wbg_createTexture_fc71efc6d11fdbcb=(a=>{const b=d(a).createTexture();return m(b)?W:l(b)});c.wbg.__wbg_createTexture_0a5d95233724c9fb=(a=>{const b=d(a).createTexture();return m(b)?W:l(b)});c.wbg.__wbg_deleteShader_c10a3e2a689f8115=((a,b)=>{d(a).deleteShader(d(b))});c.wbg.__wbg_deleteShader_40389978f329df9f=((a,b)=>{d(a).deleteShader(d(b))});c.wbg.__wbg_shaderSource_8581035b723a56a7=((a,b,c,e)=>{d(a).shaderSource(d(b),k(c,e))});c.wbg.__wbg_shaderSource_f58b7f19ccf7f292=((a,b,c,e)=>{d(a).shaderSource(d(b),k(c,e))});c.wbg.__wbg_compileShader_df38c9b4d109df2c=((a,b)=>{d(a).compileShader(d(b))});c.wbg.__wbg_compileShader_710b082356f5014b=((a,b)=>{d(a).compileShader(d(b))});c.wbg.__wbg_getShaderParameter_d5af258ca8110f13=((a,b,c)=>{const e=d(a).getShaderParameter(d(b),c>>>W);return l(e)});c.wbg.__wbg_getShaderParameter_033044aa2910ba65=((a,b,c)=>{const e=d(a).getShaderParameter(d(b),c>>>W);return l(e)});c.wbg.__wbg_createProgram_76ddcf5596a96a1a=(a=>{const b=d(a).createProgram();return m(b)?W:l(b)});c.wbg.__wbg_createProgram_36349c11c5d787f1=(a=>{const b=d(a).createProgram();return m(b)?W:l(b)});c.wbg.__wbg_deleteProgram_ffe51c2159e56aeb=((a,b)=>{d(a).deleteProgram(d(b))});c.wbg.__wbg_deleteProgram_100d1c04b7f0f6ee=((a,b)=>{d(a).deleteProgram(d(b))});c.wbg.__wbg_attachShader_289e2f1d24149257=((a,b,c)=>{d(a).attachShader(d(b),d(c))});c.wbg.__wbg_attachShader_184a61d345c20d42=((a,b,c)=>{d(a).attachShader(d(b),d(c))});c.wbg.__wbg_linkProgram_1ab5d0990c565f87=((a,b)=>{d(a).linkProgram(d(b))});c.wbg.__wbg_linkProgram_79a9e7719a86a93e=((a,b)=>{d(a).linkProgram(d(b))});c.wbg.__wbg_getProgramParameter_ac16a850d3f251f3=((a,b,c)=>{const e=d(a).getProgramParameter(d(b),c>>>W);return l(e)});c.wbg.__wbg_getProgramParameter_69a29687a127f713=((a,b,c)=>{const e=d(a).getProgramParameter(d(b),c>>>W);return l(e)});c.wbg.__wbg_getActiveUniform_f9072bcc7895dac1=((a,b,c)=>{const e=d(a).getActiveUniform(d(b),c>>>W);return m(e)?W:l(e)});c.wbg.__wbg_size_5818c0d8de7ee6ea=(a=>{const b=d(a).size;return b});c.wbg.__wbg_type_a25c4f950b3b3797=(a=>{const b=d(a).type;return b});c.wbg.__wbg_name_89f5e0e88ec3b968=((a,c)=>{const e=d(c).name;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_getActiveUniform_4f96fab0067ee961=((a,b,c)=>{const e=d(a).getActiveUniform(d(b),c>>>W);return m(e)?W:l(e)});c.wbg.__wbg_useProgram_45855699f032d49a=((a,b)=>{d(a).useProgram(d(b))});c.wbg.__wbg_useProgram_667ebfb0fb0de4c0=((a,b)=>{d(a).useProgram(d(b))});c.wbg.__wbg_createBuffer_993ecd2e92aabe3c=(a=>{const b=d(a).createBuffer();return m(b)?W:l(b)});c.wbg.__wbg_createBuffer_210de590ff501232=(a=>{const b=d(a).createBuffer();return m(b)?W:l(b)});c.wbg.__wbg_bindBuffer_a0055fe364603e72=((a,b,c)=>{d(a).bindBuffer(b>>>W,d(c))});c.wbg.__wbg_bindBuffer_c71ed62c7c21bed0=((a,b,c)=>{d(a).bindBuffer(b>>>W,d(c))});c.wbg.__wbg_bindBufferRange_d9f0a9fc3adda248=((a,b,c,e,f,g)=>{d(a).bindBufferRange(b>>>W,c>>>W,d(e),f,g)});c.wbg.__wbg_bindRenderbuffer_248119e9b6532f19=((a,b,c)=>{d(a).bindRenderbuffer(b>>>W,d(c))});c.wbg.__wbg_bindRenderbuffer_0c7738e79a575fdb=((a,b,c)=>{d(a).bindRenderbuffer(b>>>W,d(c))});c.wbg.__wbg_blitFramebuffer_df3bca038546840e=((a,b,c,e,f,g,h,i,j,k,l)=>{d(a).blitFramebuffer(b,c,e,f,g,h,i,j,k>>>W,l>>>W)});c.wbg.__wbg_createVertexArrayOES_528c4cd10c985d11=(a=>{const b=d(a).createVertexArrayOES();return m(b)?W:l(b)});c.wbg.__wbg_createVertexArray_7466a685c3b93a65=(a=>{const b=d(a).createVertexArray();return m(b)?W:l(b)});c.wbg.__wbg_deleteVertexArray_56114a4faffe5e22=((a,b)=>{d(a).deleteVertexArray(d(b))});c.wbg.__wbg_deleteVertexArrayOES_09c67a658698d158=((a,b)=>{d(a).deleteVertexArrayOES(d(b))});c.wbg.__wbg_bindVertexArray_7b37e9d04dfd27d9=((a,b)=>{d(a).bindVertexArray(d(b))});c.wbg.__wbg_bindVertexArrayOES_d0c90ddc7c6360d2=((a,b)=>{d(a).bindVertexArrayOES(d(b))});c.wbg.__wbg_pixelStorei_48bb580e625ac760=((a,b,c)=>{d(a).pixelStorei(b>>>W,c)});c.wbg.__wbg_pixelStorei_b4b6c5d89e9b5f96=((a,b,c)=>{d(a).pixelStorei(b>>>W,c)});c.wbg.__wbg_bufferData_9f6454cde4211a84=((a,b,c,e)=>{d(a).bufferData(b>>>W,c,e>>>W)});c.wbg.__wbg_bufferData_7afee98828aad464=((a,b,c,e)=>{d(a).bufferData(b>>>W,c,e>>>W)});c.wbg.__wbg_bufferData_11f5ff31cb447750=((a,b,c,e)=>{d(a).bufferData(b>>>W,d(c),e>>>W)});c.wbg.__wbg_bufferData_a05a44a5492e757f=((a,b,c,e)=>{d(a).bufferData(b>>>W,d(c),e>>>W)});c.wbg.__wbg_bufferSubData_361bebad2e19dbcf=((a,b,c,e)=>{d(a).bufferSubData(b>>>W,c,d(e))});c.wbg.__wbg_bufferSubData_07b03f17d75b6db7=((a,b,c,e)=>{d(a).bufferSubData(b>>>W,c,d(e))});c.wbg.__wbg_getBufferSubData_3d5a446fc6edc0d6=((a,b,c,e)=>{d(a).getBufferSubData(b>>>W,c,d(e))});c.wbg.__wbg_clearBufferiv_e26fb1758242f7f4=((a,b,c,e,f)=>{d(a).clearBufferiv(b>>>W,c,G(e,f))});c.wbg.__wbg_clearBufferuiv_75891c672ddef82a=((a,b,c,e,f)=>{d(a).clearBufferuiv(b>>>W,c,J(e,f))});c.wbg.__wbg_clearBufferfv_ddf1d2c0a5f293c5=((a,b,c,e,f)=>{d(a).clearBufferfv(b>>>W,c,F(e,f))});c.wbg.__wbg_clearBufferfi_d57bee264d59476a=((a,b,c,e,f)=>{d(a).clearBufferfi(b>>>W,c,e,f)});c.wbg.__wbg_clientWaitSync_31956a1ff24ab2d7=((a,b,c,e)=>{const f=d(a).clientWaitSync(d(b),c>>>W,e>>>W);return f});c.wbg.__wbg_copyBufferSubData_926f5ccd6e693b1f=((a,b,c,e,f,g)=>{d(a).copyBufferSubData(b>>>W,c>>>W,e,f,g)});c.wbg.__wbg_copyTexSubImage2D_66766abee23288ff=((a,b,c,e,f,g,h,i,j)=>{d(a).copyTexSubImage2D(b>>>W,c,e,f,g,h,i,j)});c.wbg.__wbg_copyTexSubImage2D_bc4fe74768b6add0=((a,b,c,e,f,g,h,i,j)=>{d(a).copyTexSubImage2D(b>>>W,c,e,f,g,h,i,j)});c.wbg.__wbg_copyTexSubImage3D_d694f427199991b8=((a,b,c,e,f,g,h,i,j,k)=>{d(a).copyTexSubImage3D(b>>>W,c,e,f,g,h,i,j,k)});c.wbg.__wbg_deleteBuffer_f4994a64cdd473a3=((a,b)=>{d(a).deleteBuffer(d(b))});c.wbg.__wbg_deleteBuffer_3129e4f30c465a14=((a,b)=>{d(a).deleteBuffer(d(b))});c.wbg.__wbg_deleteFramebuffer_2cc015c1b281e8a1=((a,b)=>{d(a).deleteFramebuffer(d(b))});c.wbg.__wbg_deleteFramebuffer_33112863fa4f3eb0=((a,b)=>{d(a).deleteFramebuffer(d(b))});c.wbg.__wbg_deleteQuery_d51a96512c6c3f3f=((a,b)=>{d(a).deleteQuery(d(b))});c.wbg.__wbg_deleteRenderbuffer_80239f946eea133d=((a,b)=>{d(a).deleteRenderbuffer(d(b))});c.wbg.__wbg_deleteRenderbuffer_5229b7175bb0b009=((a,b)=>{d(a).deleteRenderbuffer(d(b))});c.wbg.__wbg_deleteSampler_e33ef80c17eb0896=((a,b)=>{d(a).deleteSampler(d(b))});c.wbg.__wbg_deleteSync_3e63862ea7783216=((a,b)=>{d(a).deleteSync(d(b))});c.wbg.__wbg_deleteTexture_b8458a96b71a0a04=((a,b)=>{d(a).deleteTexture(d(b))});c.wbg.__wbg_deleteTexture_ad998c535ddaaf67=((a,b)=>{d(a).deleteTexture(d(b))});c.wbg.__wbg_disable_8938e1da156fa7d9=((a,b)=>{d(a).disable(b>>>W)});c.wbg.__wbg_disable_483aff0769a6f791=((a,b)=>{d(a).disable(b>>>W)});c.wbg.__wbg_disableVertexAttribArray_b196e82af1f9e794=((a,b)=>{d(a).disableVertexAttribArray(b>>>W)});c.wbg.__wbg_disableVertexAttribArray_0c9e77abfba9ee15=((a,b)=>{d(a).disableVertexAttribArray(b>>>W)});c.wbg.__wbg_drawArrays_4ae5359a7c3c5279=((a,b,c,e)=>{d(a).drawArrays(b>>>W,c,e)});c.wbg.__wbg_drawArrays_ac75b6b4a565dfde=((a,b,c,e)=>{d(a).drawArrays(b>>>W,c,e)});c.wbg.__wbg_drawArraysInstancedANGLE_efcd706fccb1a8f0=((a,b,c,e,f)=>{d(a).drawArraysInstancedANGLE(b>>>W,c,e,f)});c.wbg.__wbg_drawArraysInstanced_f7080bf0ad1d976e=((a,b,c,e,f)=>{d(a).drawArraysInstanced(b>>>W,c,e,f)});c.wbg.__wbindgen_number_new=(a=>{const b=a;return l(b)});c.wbg.__wbg_push_901f3914205d44de=((a,b)=>{const c=d(a).push(d(b));return c});c.wbg.__wbg_of_c36972ad824ef061=(a=>{const b=S.of(d(a));return l(b)});c.wbg.__wbg_drawBuffersWEBGL_7b1f12f2ee6598f5=((a,b)=>{d(a).drawBuffersWEBGL(d(b))});c.wbg.__wbg_drawBuffers_770b4e7949774930=((a,b)=>{d(a).drawBuffers(d(b))});c.wbg.__wbg_drawElementsInstancedANGLE_924b2ff704a740e7=((a,b,c,e,f,g)=>{d(a).drawElementsInstancedANGLE(b>>>W,c,e>>>W,f,g)});c.wbg.__wbg_drawElementsInstanced_1f828577186777cb=((a,b,c,e,f,g)=>{d(a).drawElementsInstanced(b>>>W,c,e>>>W,f,g)});c.wbg.__wbg_enable_e39f53a946b9e3a0=((a,b)=>{d(a).enable(b>>>W)});c.wbg.__wbg_enable_c5caba1636ec3c96=((a,b)=>{d(a).enable(b>>>W)});c.wbg.__wbg_enableVertexAttribArray_f8678d164c294659=((a,b)=>{d(a).enableVertexAttribArray(b>>>W)});c.wbg.__wbg_enableVertexAttribArray_0424d3842911d8b6=((a,b)=>{d(a).enableVertexAttribArray(b>>>W)});c.wbg.__wbg_framebufferRenderbuffer_6b4d1a1c53ccc57d=((a,b,c,e,f)=>{d(a).framebufferRenderbuffer(b>>>W,c>>>W,e>>>W,d(f))});c.wbg.__wbg_framebufferRenderbuffer_09dddaeb9b013985=((a,b,c,e,f)=>{d(a).framebufferRenderbuffer(b>>>W,c>>>W,e>>>W,d(f))});c.wbg.__wbg_framebufferTexture2D_f8b0567baae853d2=((a,b,c,e,f,g)=>{d(a).framebufferTexture2D(b>>>W,c>>>W,e>>>W,d(f),g)});c.wbg.__wbg_framebufferTexture2D_8d99f62eee2d1757=((a,b,c,e,f,g)=>{d(a).framebufferTexture2D(b>>>W,c>>>W,e>>>W,d(f),g)});c.wbg.__wbg_framebufferTextureLayer_3776751a08a004cd=((a,b,c,e,f,g)=>{d(a).framebufferTextureLayer(b>>>W,c>>>W,d(e),f,g)});c.wbg.__wbg_frontFace_70a1886745b75bc9=((a,b)=>{d(a).frontFace(b>>>W)});c.wbg.__wbg_frontFace_a08d3e57a0667c73=((a,b)=>{d(a).frontFace(b>>>W)});c.wbg.__wbg_getParameter_fedfba9017d5fbcd=function(){return C(((a,b)=>{const c=d(a).getParameter(b>>>W);return l(c)}),arguments)};c.wbg.__wbg_getIndexedParameter_498208e84138d6d0=function(){return C(((a,b,c)=>{const e=d(a).getIndexedParameter(b>>>W,c>>>W);return l(e)}),arguments)};c.wbg.__wbg_getUniformLocation_29cc1018d110f9f0=((a,b,c,e)=>{const f=d(a).getUniformLocation(d(b),k(c,e));return m(f)?W:l(f)});c.wbg.__wbg_getUniformLocation_50b6838495678a49=((a,b,c,e)=>{const f=d(a).getUniformLocation(d(b),k(c,e));return m(f)?W:l(f)});c.wbg.__wbg_getSyncParameter_268f427e8d9f123e=((a,b,c)=>{const e=d(a).getSyncParameter(d(b),c>>>W);return l(e)});c.wbg.__wbg_renderbufferStorage_fcb8aee479a5dd50=((a,b,c,e,f)=>{d(a).renderbufferStorage(b>>>W,c>>>W,e,f)});c.wbg.__wbg_renderbufferStorage_14a5ac06c7f68729=((a,b,c,e,f)=>{d(a).renderbufferStorage(b>>>W,c>>>W,e,f)});c.wbg.__wbg_renderbufferStorageMultisample_77d1555e1b4be5d5=((a,b,c,e,f,g)=>{d(a).renderbufferStorageMultisample(b>>>W,c,e>>>W,f,g)});c.wbg.__wbg_samplerParameterf_726502cef2fc6dff=((a,b,c,e)=>{d(a).samplerParameterf(d(b),c>>>W,e)});c.wbg.__wbg_samplerParameteri_d0f51895de24bcbb=((a,b,c,e)=>{d(a).samplerParameteri(d(b),c>>>W,e)});c.wbg.__wbg_texStorage2D_612a56ff2dc6ac9e=((a,b,c,e,f,g)=>{d(a).texStorage2D(b>>>W,c,e>>>W,f,g)});c.wbg.__wbg_texStorage3D_102ea8c301d9573e=((a,b,c,e,f,g,h)=>{d(a).texStorage3D(b>>>W,c,e>>>W,f,g,h)});c.wbg.__wbg_uniform1i_59bbe75ef84036ac=((a,b,c)=>{d(a).uniform1i(d(b),c)});c.wbg.__wbg_uniform1i_a949331c579124f5=((a,b,c)=>{d(a).uniform1i(d(b),c)});c.wbg.__wbg_uniform2iv_5a9f8821b3d44adb=((a,b,c,e)=>{d(a).uniform2iv(d(b),G(c,e))});c.wbg.__wbg_uniform2iv_c44d289b86e7b9c0=((a,b,c,e)=>{d(a).uniform2iv(d(b),G(c,e))});c.wbg.__wbg_uniform3iv_482ad890ad013578=((a,b,c,e)=>{d(a).uniform3iv(d(b),G(c,e))});c.wbg.__wbg_uniform3iv_d92618b7fac63d5f=((a,b,c,e)=>{d(a).uniform3iv(d(b),G(c,e))});c.wbg.__wbg_uniform4iv_6b5d31657261615b=((a,b,c,e)=>{d(a).uniform4iv(d(b),G(c,e))});c.wbg.__wbg_uniform4iv_7b54b6a063120eb2=((a,b,c,e)=>{d(a).uniform4iv(d(b),G(c,e))});c.wbg.__wbg_uniform1f_97c947ddb8aeacf8=((a,b,c)=>{d(a).uniform1f(d(b),c)});c.wbg.__wbg_uniform1f_0c8a4e0444282098=((a,b,c)=>{d(a).uniform1f(d(b),c)});c.wbg.__wbg_uniform4f_83cd1c05881edfde=((a,b,c,e,f,g)=>{d(a).uniform4f(d(b),c,e,f,g)});c.wbg.__wbg_uniform4f_998813a169b13f40=((a,b,c,e,f,g)=>{d(a).uniform4f(d(b),c,e,f,g)});c.wbg.__wbg_uniform2fv_dee4625f08f7518e=((a,b,c,e)=>{d(a).uniform2fv(d(b),F(c,e))});c.wbg.__wbg_uniform2fv_c9bafe596aaa6f96=((a,b,c,e)=>{d(a).uniform2fv(d(b),F(c,e))});c.wbg.__wbg_uniform3fv_38d48a2561b89815=((a,b,c,e)=>{d(a).uniform3fv(d(b),F(c,e))});c.wbg.__wbg_uniform3fv_7c6cc849b0150aaa=((a,b,c,e)=>{d(a).uniform3fv(d(b),F(c,e))});c.wbg.__wbg_uniform4fv_85d4d7ef22366b93=((a,b,c,e)=>{d(a).uniform4fv(d(b),F(c,e))});c.wbg.__wbg_uniform4fv_4aa6ac4f94369a8f=((a,b,c,e)=>{d(a).uniform4fv(d(b),F(c,e))});c.wbg.__wbg_uniformMatrix2fv_0ec0bb00ca04ae0f=((a,b,c,e,f)=>{d(a).uniformMatrix2fv(d(b),c!==W,F(e,f))});c.wbg.__wbg_uniformMatrix2fv_aaecec3c7496646f=((a,b,c,e,f)=>{d(a).uniformMatrix2fv(d(b),c!==W,F(e,f))});c.wbg.__wbg_uniformMatrix3fv_6c6cf9285fa50932=((a,b,c,e,f)=>{d(a).uniformMatrix3fv(d(b),c!==W,F(e,f))});c.wbg.__wbg_uniformMatrix3fv_8ebebb0a689c27ea=((a,b,c,e,f)=>{d(a).uniformMatrix3fv(d(b),c!==W,F(e,f))});c.wbg.__wbg_uniformMatrix4fv_47822ae94c519f11=((a,b,c,e,f)=>{d(a).uniformMatrix4fv(d(b),c!==W,F(e,f))});c.wbg.__wbg_uniformMatrix4fv_674d03cda2d50ccc=((a,b,c,e,f)=>{d(a).uniformMatrix4fv(d(b),c!==W,F(e,f))});c.wbg.__wbg_cullFace_f7631a823163010d=((a,b)=>{d(a).cullFace(b>>>W)});c.wbg.__wbg_cullFace_d2f78f39007f1d5d=((a,b)=>{d(a).cullFace(b>>>W)});c.wbg.__wbg_colorMask_ee95cb90b5399c1d=((a,b,c,e,f)=>{d(a).colorMask(b!==W,c!==W,e!==W,f!==W)});c.wbg.__wbg_colorMask_048d9f7d86363300=((a,b,c,e,f)=>{d(a).colorMask(b!==W,c!==W,e!==W,f!==W)});c.wbg.__wbg_depthMask_b520fa172dc50fdd=((a,b)=>{d(a).depthMask(b!==W)});c.wbg.__wbg_depthMask_03551bf1079ca4f3=((a,b)=>{d(a).depthMask(b!==W)});c.wbg.__wbg_blendColor_bf0aca4480ec191b=((a,b,c,e,f)=>{d(a).blendColor(b,c,e,f)});c.wbg.__wbg_blendColor_bd7597cf4f926625=((a,b,c,e,f)=>{d(a).blendColor(b,c,e,f)});c.wbg.__wbg_invalidateFramebuffer_233280f8e97054a6=function(){return C(((a,b,c)=>{d(a).invalidateFramebuffer(b>>>W,d(c))}),arguments)};c.wbg.__wbg_polygonOffset_784d0bd354450685=((a,b,c)=>{d(a).polygonOffset(b,c)});c.wbg.__wbg_polygonOffset_f7ac1393deab0d93=((a,b,c)=>{d(a).polygonOffset(b,c)});c.wbg.__wbg_bindTexture_ba764bb08be120f7=((a,b,c)=>{d(a).bindTexture(b>>>W,d(c))});c.wbg.__wbg_bindTexture_df13ba7e7ee5d984=((a,b,c)=>{d(a).bindTexture(b>>>W,d(c))});c.wbg.__wbg_bindSampler_d6c4782741c69639=((a,b,c)=>{d(a).bindSampler(b>>>W,d(c))});c.wbg.__wbg_activeTexture_123afbbc8970fe31=((a,b)=>{d(a).activeTexture(b>>>W)});c.wbg.__wbg_activeTexture_713ce7d3e753740f=((a,b)=>{d(a).activeTexture(b>>>W)});c.wbg.__wbg_fenceSync_88242349a578d268=((a,b,c)=>{const e=d(a).fenceSync(b>>>W,c>>>W);return m(e)?W:l(e)});c.wbg.__wbg_texParameteri_fba016345d388fd9=((a,b,c,e)=>{d(a).texParameteri(b>>>W,c>>>W,e)});c.wbg.__wbg_texParameteri_31d32c2b86548f8e=((a,b,c,e)=>{d(a).texParameteri(b>>>W,c>>>W,e)});c.wbg.__wbg_texSubImage2D_1b4def2ea95bfb31=function(){return C(((a,b,c,e,f,g,h,i,j,k)=>{d(a).texSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j>>>W,d(k))}),arguments)};c.wbg.__wbg_texSubImage2D_be9f61a79f57b819=function(){return C(((a,b,c,e,f,g,h,i,j,k)=>{d(a).texSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j>>>W,d(k))}),arguments)};c.wbg.__wbg_texSubImage2D_8694c2fdf6ffae77=function(){return C(((a,b,c,e,f,g,h,i,j,k)=>{d(a).texSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j>>>W,k)}),arguments)};c.wbg.__wbg_compressedTexSubImage2D_6ab7ed818e5e4070=((a,b,c,e,f,g,h,i,j)=>{d(a).compressedTexSubImage2D(b>>>W,c,e,f,g,h,i>>>W,d(j))});c.wbg.__wbg_compressedTexSubImage2D_b9e80ce57234bf68=((a,b,c,e,f,g,h,i,j)=>{d(a).compressedTexSubImage2D(b>>>W,c,e,f,g,h,i>>>W,d(j))});c.wbg.__wbg_compressedTexSubImage2D_bc2325e36c328ef3=((a,b,c,e,f,g,h,i,j,k)=>{d(a).compressedTexSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j,k)});c.wbg.__wbg_texSubImage3D_c81838d3b14e2574=function(){return C(((a,b,c,e,f,g,h,i,j,k,l,m)=>{d(a).texSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,l>>>W,m)}),arguments)};c.wbg.__wbg_texSubImage3D_4491b14dacde659b=function(){return C(((a,b,c,e,f,g,h,i,j,k,l,m)=>{d(a).texSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,l>>>W,d(m))}),arguments)};c.wbg.__wbg_compressedTexSubImage3D_e237c5dd8b328f82=((a,b,c,e,f,g,h,i,j,k,l,m)=>{d(a).compressedTexSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,l,m)});c.wbg.__wbg_compressedTexSubImage3D_fa81691b7cb3b7e4=((a,b,c,e,f,g,h,i,j,k,l)=>{d(a).compressedTexSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,d(l))});c.wbg.__wbg_depthFunc_4706c33c9966db3b=((a,b)=>{d(a).depthFunc(b>>>W)});c.wbg.__wbg_depthFunc_aa8fdb5bf66ce5dc=((a,b)=>{d(a).depthFunc(b>>>W)});c.wbg.__wbg_depthRange_2d0d6f020c3d5566=((a,b,c)=>{d(a).depthRange(b,c)});c.wbg.__wbg_depthRange_ded9f852ad909448=((a,b,c)=>{d(a).depthRange(b,c)});c.wbg.__wbg_scissor_6691dacd4ecb8e80=((a,b,c,e,f)=>{d(a).scissor(b,c,e,f)});c.wbg.__wbg_scissor_c1bf95c48721deac=((a,b,c,e,f)=>{d(a).scissor(b,c,e,f)});c.wbg.__wbg_vertexAttribDivisorANGLE_c01f8657d1933822=((a,b,c)=>{d(a).vertexAttribDivisorANGLE(b>>>W,c>>>W)});c.wbg.__wbg_vertexAttribDivisor_938fb64827607dbe=((a,b,c)=>{d(a).vertexAttribDivisor(b>>>W,c>>>W)});c.wbg.__wbg_vertexAttribPointer_1241d48b9272fc9d=((a,b,c,e,f,g,h)=>{d(a).vertexAttribPointer(b>>>W,c,e>>>W,f!==W,g,h)});c.wbg.__wbg_vertexAttribPointer_7be57c972fbee1d0=((a,b,c,e,f,g,h)=>{d(a).vertexAttribPointer(b>>>W,c,e>>>W,f!==W,g,h)});c.wbg.__wbg_vertexAttribIPointer_12bfde6cf8b7b821=((a,b,c,e,f,g)=>{d(a).vertexAttribIPointer(b>>>W,c,e>>>W,f,g)});c.wbg.__wbg_viewport_2464c396536924a3=((a,b,c,e,f)=>{d(a).viewport(b,c,e,f)});c.wbg.__wbg_viewport_146f8499414eebc9=((a,b,c,e,f)=>{d(a).viewport(b,c,e,f)});c.wbg.__wbg_blendFunc_3edf09b56fbb3ffd=((a,b,c)=>{d(a).blendFunc(b>>>W,c>>>W)});c.wbg.__wbg_blendFunc_f148dd374b130586=((a,b,c)=>{d(a).blendFunc(b>>>W,c>>>W)});c.wbg.__wbg_blendFuncSeparate_c3c9b0213697920c=((a,b,c,e,f)=>{d(a).blendFuncSeparate(b>>>W,c>>>W,e>>>W,f>>>W)});c.wbg.__wbg_blendFuncSeparate_285a70ec8276ccab=((a,b,c,e,f)=>{d(a).blendFuncSeparate(b>>>W,c>>>W,e>>>W,f>>>W)});c.wbg.__wbg_blendEquation_b53426d0d37db246=((a,b)=>{d(a).blendEquation(b>>>W)});c.wbg.__wbg_blendEquation_e933afa2d360ea3b=((a,b)=>{d(a).blendEquation(b>>>W)});c.wbg.__wbg_blendEquationSeparate_68fd537772dc05eb=((a,b,c)=>{d(a).blendEquationSeparate(b>>>W,c>>>W)});c.wbg.__wbg_blendEquationSeparate_821c15a65234ac9e=((a,b,c)=>{d(a).blendEquationSeparate(b>>>W,c>>>W)});c.wbg.__wbg_stencilFuncSeparate_3b5e111c83147417=((a,b,c,e,f)=>{d(a).stencilFuncSeparate(b>>>W,c>>>W,e,f>>>W)});c.wbg.__wbg_stencilFuncSeparate_639e870ff536309e=((a,b,c,e,f)=>{d(a).stencilFuncSeparate(b>>>W,c>>>W,e,f>>>W)});c.wbg.__wbg_stencilMask_3d9c0a4e72ab96ea=((a,b)=>{d(a).stencilMask(b>>>W)});c.wbg.__wbg_stencilMask_9a8f03321c1dea66=((a,b)=>{d(a).stencilMask(b>>>W)});c.wbg.__wbg_stencilMaskSeparate_ef23e92802d8f995=((a,b,c)=>{d(a).stencilMaskSeparate(b>>>W,c>>>W)});c.wbg.__wbg_stencilMaskSeparate_a5a7c370cd12a043=((a,b,c)=>{d(a).stencilMaskSeparate(b>>>W,c>>>W)});c.wbg.__wbg_stencilOpSeparate_62ee06a95a1f36a4=((a,b,c,e,f)=>{d(a).stencilOpSeparate(b>>>W,c>>>W,e>>>W,f>>>W)});c.wbg.__wbg_stencilOpSeparate_497a2305c23d697a=((a,b,c,e,f)=>{d(a).stencilOpSeparate(b>>>W,c>>>W,e>>>W,f>>>W)});c.wbg.__wbg_getUniformBlockIndex_bdf0666cfd18218e=((a,b,c,e)=>{const f=d(a).getUniformBlockIndex(d(b),k(c,e));return f});c.wbg.__wbg_uniformBlockBinding_efdd3c56716c6289=((a,b,c,e)=>{d(a).uniformBlockBinding(d(b),c>>>W,e>>>W)});c.wbg.__wbg_readBuffer_908a6eccf79eb471=((a,b)=>{d(a).readBuffer(b>>>W)});c.wbg.__wbg_readPixels_d3c0e1ee54deb785=function(){return C(((a,b,c,e,f,g,h,i)=>{d(a).readPixels(b,c,e,f,g>>>W,h>>>W,i)}),arguments)};c.wbg.__wbg_readPixels_070533492e105754=function(){return C(((a,b,c,e,f,g,h,i)=>{d(a).readPixels(b,c,e,f,g>>>W,h>>>W,d(i))}),arguments)};c.wbg.__wbg_readPixels_1324fe35287c6abc=function(){return C(((a,b,c,e,f,g,h,i)=>{d(a).readPixels(b,c,e,f,g>>>W,h>>>W,d(i))}),arguments)};c.wbg.__wbg_beginQuery_91a71d14184dc3b1=((a,b,c)=>{d(a).beginQuery(b>>>W,d(c))});c.wbg.__wbg_endQuery_7f4678342575164a=((a,b)=>{d(a).endQuery(b>>>W)});c.wbg.__wbg_getQueryParameter_55ea7685196c2812=((a,b,c)=>{const e=d(a).getQueryParameter(d(b),c>>>W);return l(e)});c.wbg.__wbg_get_7b48513de5dc5ea4=function(){return C(((a,b)=>{const c=a8.get(d(a),d(b));return l(c)}),arguments)};c.wbg.__wbg_now_b724952e890dc703=(a=>{const b=d(a).now();return b});c.wbg.__wbg_self_f0e34d89f33b99fd=function(){return C((()=>{const a=self.self;return l(a)}),arguments)};c.wbg.__wbg_window_d3b084224f4774d7=function(){return C((()=>{const a=window.window;return l(a)}),arguments)};c.wbg.__wbg_globalThis_9caa27ff917c6860=function(){return C((()=>{const a=globalThis.globalThis;return l(a)}),arguments)};c.wbg.__wbg_global_35dfdd59a4da3e74=function(){return C((()=>{const a=global.global;return l(a)}),arguments)};c.wbg.__wbindgen_is_undefined=(a=>{const b=d(a)===R;return b});c.wbg.__wbg_newnoargs_c62ea9419c21fbac=((a,b)=>{const c=new Function(k(a,b));return l(c)});c.wbg.__wbg_call_90c26b09837aba1c=function(){return C(((a,b)=>{const c=d(a).call(d(b));return l(c)}),arguments)};c.wbg.__wbg_resolve_6e1c6553a82f85b7=(a=>{const b=Promise.resolve(d(a));return l(b)});c.wbg.__wbg_then_3ab08cd4fbb91ae9=((a,b)=>{const c=d(a).then(d(b));return l(c)});c.wbg.__wbg_then_8371cc12cfedc5a2=((a,b,c)=>{const e=d(a).then(d(b),d(c));return l(e)});c.wbg.__wbindgen_memory=(()=>{const a=b.memory;return l(a)});c.wbg.__wbg_buffer_a448f833075b71ba=(a=>{const b=d(a).buffer;return l(b)});c.wbg.__wbg_newwithbyteoffsetandlength_b2f5b737836be06b=((a,b,c)=>{const e=new Int8Array(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_newwithbyteoffsetandlength_c370f7b5f8986669=((a,b,c)=>{const e=new Int16Array(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_newwithbyteoffsetandlength_be0a0b31d480f4b2=((a,b,c)=>{const e=new Z(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_newwithbyteoffsetandlength_d0482f893617af71=((a,b,c)=>{const e=new X(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_set_2357bf09366ee480=((a,b,c)=>{d(a).set(d(b),c>>>W)});c.wbg.__wbg_length_1d25fa9e4ac21ce7=(a=>{const b=d(a).length;return b});c.wbg.__wbg_newwithbyteoffsetandlength_099217381c451830=((a,b,c)=>{const e=new Uint16Array(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_newwithbyteoffsetandlength_7a23ee7b263abe07=((a,b,c)=>{const e=new a6(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_newwithbyteoffsetandlength_fa811509d2a67254=((a,b,c)=>{const e=new a4(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_set_759f75cd92b612d2=function(){return C(((a,b,c)=>{const e=a8.set(d(a),d(b),d(c));return e}),arguments)};c.wbg.__wbg_newwithcontextoptions_b8f7091a3a364b0f=function(){return C((b=>{const c=new a(d(b));return l(c)}),arguments)};c.wbg.__wbg_destination_4d44007f7d08d71b=(a=>{const b=d(a).destination;return l(b)});c.wbg.__wbg_maxChannelCount_652279e4d267be9f=(a=>{const b=d(a).maxChannelCount;return b});c.wbg.__wbg_setchannelCount_12bf2f57feba3188=((a,b)=>{d(a).channelCount=b>>>W});c.wbg.__wbg_createBuffer_444ba95ef8d4d0ff=function(){return C(((a,b,c,e)=>{const f=d(a).createBuffer(b>>>W,c>>>W,e);return l(f)}),arguments)};c.wbg.__wbg_currentTime_d2be936586614ff4=(a=>{const b=d(a).currentTime;return b});c.wbg.__wbg_createBufferSource_2900236a9a0ed333=function(){return C((a=>{const b=d(a).createBufferSource();return l(b)}),arguments)};c.wbg.__wbg_setbuffer_fcb9ea4265b72e7f=((a,b)=>{d(a).buffer=d(b)});c.wbg.__wbg_connect_7374783233c39eda=function(){return C(((a,b)=>{const c=d(a).connect(d(b));return l(c)}),arguments)};c.wbg.__wbg_setonended_7d1552abbde0045d=((a,b)=>{d(a).onended=d(b)});c.wbg.__wbg_start_88b66d1c6c29149b=function(){return C(((a,b)=>{d(a).start(b)}),arguments)};c.wbg.__wbg_copyToChannel_f1e42af1b32c01bb=function(){return C(((a,b,c,e)=>{d(a).copyToChannel(F(b,c),e)}),arguments)};c.wbg.__wbg_measure_aa7a73f17813f708=function(){return C(((a,c,d,e)=>{let f;let g;let h;let i;try{f=a;g=c;h=d;i=e;performance.measure(k(a,c),k(d,e))}finally{b.__wbindgen_free(f,g,Y);b.__wbindgen_free(h,i,Y)}}),arguments)};c.wbg.__wbindgen_debug_string=((a,c)=>{const e=v(d(c));const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbindgen_throw=((a,b)=>{throw new V(k(a,b))});c.wbg.__wbg_instanceof_WebGl2RenderingContext_2a0a9b7be3acc66a=(a=>{let b;try{b=d(a) instanceof WebGL2RenderingContext}catch(a){b=!1}const c=b;return c});c.wbg.__wbg_getProgramInfoLog_5caeb981d27a790c=((a,c,e)=>{const f=d(c).getProgramInfoLog(d(e));var g=m(f)?W:u(f,b.__wbindgen_malloc,b.__wbindgen_realloc);var h=r;q()[a/a5+ Y]=h;q()[a/a5+ W]=g});c.wbg.__wbg_getShaderInfoLog_e78ccbd4507b9d0c=((a,c,e)=>{const f=d(c).getShaderInfoLog(d(e));var g=m(f)?W:u(f,b.__wbindgen_malloc,b.__wbindgen_realloc);var h=r;q()[a/a5+ Y]=h;q()[a/a5+ W]=g});c.wbg.__wbg_instanceof_Window_3e5cd1f48c152d01=(a=>{let b;try{b=d(a) instanceof Window}catch(a){b=!1}const c=b;return c});c.wbg.__wbg_innerWidth_e5d865919c14bdf9=function(){return C((a=>{const b=d(a).innerWidth;return l(b)}),arguments)};c.wbg.__wbg_innerHeight_5e414ce6ae3fd139=function(){return C((a=>{const b=d(a).innerHeight;return l(b)}),arguments)};c.wbg.__wbg_devicePixelRatio_964a528c661f5575=(a=>{const b=d(a).devicePixelRatio;return b});c.wbg.__wbg_open_1526872b77d837c5=function(){return C(((a,b,c,e,f)=>{const g=d(a).open(k(b,c),k(e,f));return m(g)?W:l(g)}),arguments)};c.wbg.__wbg_get_644791d4d61a5f69=((a,b,c)=>{const e=d(a)[k(b,c)];return m(e)?W:l(e)});c.wbg.__wbg_cancelAnimationFrame_cb9c6f65eaa83d76=function(){return C(((a,b)=>{d(a).cancelAnimationFrame(b)}),arguments)};c.wbg.__wbg_clearTimeout_0f534a4b1fb4773d=((a,b)=>{d(a).clearTimeout(b)});c.wbg.__wbg_fullscreenElement_ebc349686c5a66a1=(a=>{const b=d(a).fullscreenElement;return m(b)?W:l(b)});c.wbg.__wbg_createElement_fdd5c113cb84539e=function(){return C(((a,b,c)=>{const e=d(a).createElement(k(b,c));return l(e)}),arguments)};c.wbg.__wbg_exitFullscreen_b5d53ae882b17a5c=(a=>{d(a).exitFullscreen()});c.wbg.__wbg_exitPointerLock_7fdf96663e773b31=(a=>{d(a).exitPointerLock()});c.wbg.__wbg_setAttribute_e7b72a5e7cfcb5a3=function(){return C(((a,b,c,e,f)=>{d(a).setAttribute(k(b,c),k(e,f))}),arguments)};c.wbg.__wbg_getProgramInfoLog_99334d62bea10332=((a,c,e)=>{const f=d(c).getProgramInfoLog(d(e));var g=m(f)?W:u(f,b.__wbindgen_malloc,b.__wbindgen_realloc);var h=r;q()[a/a5+ Y]=h;q()[a/a5+ W]=g});c.wbg.__wbg_getShaderInfoLog_207d91c9201acffa=((a,c,e)=>{const f=d(c).getShaderInfoLog(d(e));var g=m(f)?W:u(f,b.__wbindgen_malloc,b.__wbindgen_realloc);var h=r;q()[a/a5+ Y]=h;q()[a/a5+ W]=g});c.wbg.__wbg_style_97c680a5cbdf49cd=(a=>{const b=d(a).style;return l(b)});c.wbg.__wbg_addListener_265dcc33d68a7574=function(){return C(((a,b)=>{d(a).addListener(d(b))}),arguments)};c.wbg.__wbg_removeListener_03d5c1013266db90=function(){return C(((a,b)=>{d(a).removeListener(d(b))}),arguments)};c.wbg.__wbg_setProperty_ecf331459a4d3891=function(){return C(((a,b,c,e,f)=>{d(a).setProperty(k(b,c),k(e,f))}),arguments)};c.wbg.__wbg_x_dedc0183b8cf9e44=(a=>{const b=d(a).x;return b});c.wbg.__wbg_y_07982b620f686fbd=(a=>{const b=d(a).y;return b});c.wbg.__wbg_width_87fb7beca76ecb6a=(a=>{const b=d(a).width;return b});c.wbg.__wbg_setwidth_a04b04d18cb81715=((a,b)=>{d(a).width=b>>>W});c.wbg.__wbg_height_0fb9764a1a78e3f6=(a=>{const b=d(a).height;return b});c.wbg.__wbg_setheight_ae3c51b7555bd27d=((a,b)=>{d(a).height=b>>>W});c.wbg.__wbg_videoWidth_ca6d86a1026278ad=(a=>{const b=d(a).videoWidth;return b});c.wbg.__wbg_videoHeight_55466ec3a1cae41c=(a=>{const b=d(a).videoHeight;return b});c.wbg.__wbg_width_eb7805903efd7fd3=(a=>{const b=d(a).width;return b});c.wbg.__wbg_height_aac6bd5616201da3=(a=>{const b=d(a).height;return b});c.wbg.__wbg_shiftKey_55894418ec38c771=(a=>{const b=d(a).shiftKey;return b});c.wbg.__wbg_metaKey_16606958d932a374=(a=>{const b=d(a).metaKey;return b});c.wbg.__wbg_code_878e76a4ddb70157=((a,c)=>{const e=d(c).code;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_setwidth_7591ce24118fd14a=((a,b)=>{d(a).width=b>>>W});c.wbg.__wbg_setheight_f7ae862183d88bd5=((a,b)=>{d(a).height=b>>>W});c.wbg.__wbg_getContext_52cc019050c5f7bd=function(){return C(((a,b,c,e)=>{const f=d(a).getContext(k(b,c),d(e));return m(f)?W:l(f)}),arguments)};c.wbg.__wbg_ctrlKey_643b17aaac67db50=(a=>{const b=d(a).ctrlKey;return b});c.wbg.__wbg_shiftKey_8fb7301f56e7e01c=(a=>{const b=d(a).shiftKey;return b});c.wbg.__wbg_altKey_c6c2a7e797d9a669=(a=>{const b=d(a).altKey;return b});c.wbg.__wbg_metaKey_2a8dbd51a3f59e9c=(a=>{const b=d(a).metaKey;return b});c.wbg.__wbg_button_cd87b6dabbde9631=(a=>{const b=d(a).button;return b});c.wbg.__wbg_deltaX_03d8f6dcd2e14b63=(a=>{const b=d(a).deltaX;return b});c.wbg.__wbg_deltaY_7d9a7eb25f83e193=(a=>{const b=d(a).deltaY;return b});c.wbg.__wbg_deltaMode_5f43eb63f3077df7=(a=>{const b=d(a).deltaMode;return b});c.wbg.__wbindgen_closure_wrapper4576=((a,b,c)=>{const d=w(a,b,3607,x);return l(d)});c.wbg.__wbindgen_closure_wrapper68897=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper68899=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper68901=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper68903=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper68905=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper68907=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper68909=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper78221=((a,b,c)=>{const d=w(a,b,53539,z);return l(d)});c.wbg.__wbindgen_closure_wrapper79859=((a,b,c)=>{const d=w(a,b,53852,A);return l(d)});c.wbg.__wbindgen_closure_wrapper83984=((a,b,c)=>{const d=w(a,b,54926,B);return l(d)});return c});var I=(()=>{if(H===T||H.byteLength===W){H=new a6(b.memory.buffer)};return H});var u=((a,b,c)=>{if(c===R){const c=s.encode(a);const d=b(c.length,Y)>>>W;j().subarray(d,d+ c.length).set(c);r=c.length;return d};let d=a.length;let e=b(d,Y)>>>W;const f=j();let g=W;for(;g127)break;f[e+ g]=b};if(g!==d){if(g!==W){a=a.slice(g)};e=c(e,d,d=g+ a.length*3,Y)>>>W;const b=j().subarray(e+ g,e+ d);const f=t(a,b);g+=f.written};r=g;return e});var j=(()=>{if(i===T||i.byteLength===W){i=new X(b.memory.buffer)};return i});var K=(async(a,b)=>{if(typeof Response===_&&a instanceof Response){if(typeof WebAssembly.instantiateStreaming===_){try{return await WebAssembly.instantiateStreaming(a,b)}catch(b){if(a.headers.get(`Content-Type`)!=`application/wasm`){console.warn(`\`WebAssembly.instantiateStreaming\` failed because your server does not serve wasm with \`application/wasm\` MIME type. Falling back to \`WebAssembly.instantiate\` which is slower. Original error:\\n`,b)}else{throw b}}};const c=await a.arrayBuffer();return await WebAssembly.instantiate(c,b)}else{const c=await WebAssembly.instantiate(a,b);if(c instanceof WebAssembly.Instance){return {instance:c,module:a}}else{return c}}});var G=((a,b)=>{a=a>>>W;return q().subarray(a/a5,a/a5+ b)});var J=((a,b)=>{a=a>>>W;return I().subarray(a/a5,a/a5+ b)});var z=((a,c)=>{b.wasm_bindgen__convert__closures__invoke0_mut__ha9571fbe3034bf2b(a,c)});var l=(a=>{if(e===c.length)c.push(c.length+ Y);const b=e;e=c[b];c[b]=a;return b});var g=(a=>{const b=d(a);f(a);return b});var q=(()=>{if(p===T||p.byteLength===W){p=new Z(b.memory.buffer)};return p});var B=((a,c,d)=>{b._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hfc4ca9a76f85a54c(a,c,l(d))});var P=(async(a)=>{if(b!==R)return b;if(typeof a===Q){a=new URL(`egui-gizmo-demo_bg.wasm`,import.meta.url)};const c=L();if(typeof a===a1||typeof Request===_&&a instanceof Request||typeof URL===_&&a instanceof URL){a=fetch(a)};M(c);const {instance:d,module:e}=await K(await a,c);return N(d,e)});var A=((a,c,d)=>{b.wasm_bindgen__convert__closures__invoke1_mut__hbb5e4ed44963543d(a,c,l(d))});var f=(a=>{if(a<132)return;c[a]=e;e=a});var O=(a=>{if(b!==R)return b;const c=L();M(c);if(!(a instanceof WebAssembly.Module)){a=new WebAssembly.Module(a)};const d=new WebAssembly.Instance(a,c);return N(d,a)});var N=((a,c)=>{b=a.exports;P.__wbindgen_wasm_module=c;D=T;n=T;p=T;H=T;i=T;b.__wbindgen_start();return b});var w=((a,c,d,e)=>{const f={a:a,b:c,cnt:Y,dtor:d};const g=(...a)=>{f.cnt++;const c=f.a;f.a=W;try{return e(c,f.b,...a)}finally{if(--f.cnt===W){b.__wbindgen_export_2.get(f.dtor)(c,f.b)}else{f.a=c}}};g.original=f;return g});var k=((a,b)=>{a=a>>>W;return h.decode(j().subarray(a,a+ b))});var x=((a,c)=>{b.wasm_bindgen__convert__closures__invoke0_mut__h3f3eb2c38a8c857b(a,c)});const a=typeof AudioContext!==Q?AudioContext:(typeof webkitAudioContext!==Q?webkitAudioContext:R);let b;const c=new S(128).fill(R);c.push(R,T,!0,!1);let e=c.length;const h=typeof TextDecoder!==Q?new TextDecoder(U,{ignoreBOM:!0,fatal:!0}):{decode:()=>{throw V(`TextDecoder not available`)}};if(typeof TextDecoder!==Q){h.decode()};let i=T;let n=T;let p=T;let r=W;const s=typeof TextEncoder!==Q?new TextEncoder(U):{encode:()=>{throw V(`TextEncoder not available`)}};const t=typeof s.encodeInto===_?((a,b)=>s.encodeInto(a,b)):((a,b)=>{const c=s.encode(a);b.set(c);return {read:a.length,written:c.length}});let D=T;let H=T;export default P;export{O as initSync} \ No newline at end of file +let a5=4,W=0,T=null,Q=`undefined`,a0=`boolean`,_=`function`,a1=`string`,a9=42857,Y=1,a2=`Object`,U=`utf-8`,$=`number`,S=Array,V=Error,a4=Float32Array,Z=Int32Array,a3=JSON.stringify,a7=Object,a8=Reflect,a6=Uint32Array,X=Uint8Array,R=undefined;var F=((a,b)=>{a=a>>>W;return E().subarray(a/a5,a/a5+ b)});var v=(a=>{const b=typeof a;if(b==$||b==a0||a==T){return `${a}`};if(b==a1){return `"${a}"`};if(b==`symbol`){const b=a.description;if(b==T){return `Symbol`}else{return `Symbol(${b})`}};if(b==_){const b=a.name;if(typeof b==a1&&b.length>W){return `Function(${b})`}else{return `Function`}};if(S.isArray(a)){const b=a.length;let c=`[`;if(b>W){c+=v(a[W])};for(let d=Y;dY){d=c[Y]}else{return toString.call(a)};if(d==a2){try{return `Object(`+ a3(a)+ `)`}catch(a){return a2}};if(a instanceof V){return `${a.name}: ${a.message}\n${a.stack}`};return d});var E=(()=>{if(D===T||D.byteLength===W){D=new a4(b.memory.buffer)};return D});var M=((a,b)=>{});var y=((a,c,d)=>{b._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h067ac15b54489931(a,c,l(d))});function C(a,c){try{return a.apply(this,c)}catch(a){b.__wbindgen_exn_store(l(a))}}var m=(a=>a===R||a===T);var d=(a=>c[a]);var o=(()=>{if(n===T||n.byteLength===W){n=new Float64Array(b.memory.buffer)};return n});var L=(()=>{const c={};c.wbg={};c.wbg.__wbg_instanceof_Response_0d25bb8436a9cefe=(a=>{let b;try{b=d(a) instanceof Response}catch(a){b=!1}const c=b;return c});c.wbg.__wbindgen_object_drop_ref=(a=>{g(a)});c.wbg.__wbg_stringify_daa6661e90c04140=function(){return C((a=>{const b=a3(d(a));return l(b)}),arguments)};c.wbg.__wbg_fetch_0117c27c9b3739e0=((a,b,c)=>{const e=d(a).fetch(k(b,c));return l(e)});c.wbg.__wbg_status_351700a30c61ba61=(a=>{const b=d(a).status;return b});c.wbg.__wbg_arrayBuffer_ec4617b29bb0f61c=function(){return C((a=>{const b=d(a).arrayBuffer();return l(b)}),arguments)};c.wbg.__wbg_new_ace717933ad7117f=(a=>{const b=new X(d(a));return l(b)});c.wbg.__wbg_mark_40e050a77cc39fea=((a,b)=>{performance.mark(k(a,b))});c.wbg.__wbg_log_c9486ca5d8e2cbe8=((a,c)=>{let d;let e;try{d=a;e=c;console.log(k(a,c))}finally{b.__wbindgen_free(d,e,Y)}});c.wbg.__wbg_log_aba5996d9bde071f=((a,c,d,e,f,g,h,i)=>{let j;let l;try{j=a;l=c;console.log(k(a,c),k(d,e),k(f,g),k(h,i))}finally{b.__wbindgen_free(j,l,Y)}});c.wbg.__wbg_width_9d9d26b087c6ad54=(a=>{const b=d(a).width;return b});c.wbg.__wbg_height_770da314320603d8=(a=>{const b=d(a).height;return b});c.wbg.__wbg_matchMedia_fed5c8e73cf148cf=function(){return C(((a,b,c)=>{const e=d(a).matchMedia(k(b,c));return m(e)?W:l(e)}),arguments)};c.wbg.__wbg_matches_68b7ad47c1091323=(a=>{const b=d(a).matches;return b});c.wbg.__wbg_removeEventListener_c62be4990a8c9c02=function(){return C(((a,b,c,e,f)=>{d(a).removeEventListener(k(b,c),d(e),d(f))}),arguments)};c.wbg.__wbindgen_string_new=((a,b)=>{const c=k(a,b);return l(c)});c.wbg.__wbg_error_0f3a2d4325dee96a=((a,b)=>{console.error(d(a),d(b))});c.wbg.__wbindgen_object_clone_ref=(a=>{const b=d(a);return l(b)});c.wbg.__wbg_addEventListener_1b158e9e95e0ab00=function(){return C(((a,b,c,e,f)=>{d(a).addEventListener(k(b,c),d(e),d(f))}),arguments)};c.wbg.__wbg_addEventListener_2f891d22985fd3c8=function(){return C(((a,b,c,e)=>{d(a).addEventListener(k(b,c),d(e))}),arguments)};c.wbg.__wbg_new_87d841e70661f6e9=(()=>{const a=new a7();return l(a)});c.wbg.__wbg_document_5257b70811e953c0=(a=>{const b=d(a).document;return m(b)?W:l(b)});c.wbg.__wbg_querySelector_d86f889797c65e88=function(){return C(((a,b,c)=>{const e=d(a).querySelector(k(b,c));return m(e)?W:l(e)}),arguments)};c.wbg.__wbg_parentElement_86a7612dde875ba9=(a=>{const b=d(a).parentElement;return m(b)?W:l(b)});c.wbg.__wbg_getBoundingClientRect_f3f6eb39f24c1bb0=(a=>{const b=d(a).getBoundingClientRect();return l(b)});c.wbg.__wbg_width_164c11c1f72aa632=(a=>{const b=d(a).width;return b});c.wbg.__wbg_height_ac60120008caa50b=(a=>{const b=d(a).height;return b});c.wbg.__wbindgen_cb_drop=(a=>{const b=g(a).original;if(b.cnt--==Y){b.a=W;return !0};const c=!1;return c});c.wbg.__wbg_instanceof_HtmlCanvasElement_a6076360513b6876=(a=>{let b;try{b=d(a) instanceof HTMLCanvasElement}catch(a){b=!1}const c=b;return c});c.wbg.__wbg_stopPropagation_786ab850031995e5=(a=>{d(a).stopPropagation()});c.wbg.__wbg_cancelBubble_191799b8e0ab3254=(a=>{const b=d(a).cancelBubble;return b});c.wbg.__wbg_preventDefault_d2c7416966cb0632=(a=>{d(a).preventDefault()});c.wbg.__wbg_matches_2a7b0d97653c323f=(a=>{const b=d(a).matches;return b});c.wbg.__wbg_target_791826e938c3e308=(a=>{const b=d(a).target;return m(b)?W:l(b)});c.wbg.__wbg_is_a5728dbfb61c82cd=((a,b)=>{const c=a7.is(d(a),d(b));return c});c.wbg.__wbg_offsetX_72778aba0c4b5674=(a=>{const b=d(a).offsetX;return b});c.wbg.__wbg_offsetY_a8d9605d7c28379d=(a=>{const b=d(a).offsetY;return b});c.wbg.__wbg_requestFullscreen_86cc33835b4db656=function(){return C((a=>{d(a).requestFullscreen()}),arguments)};c.wbg.__wbg_movementX_7ed3fefa16dfa971=(a=>{const b=d(a).movementX;return b});c.wbg.__wbg_movementY_a0be141073121d2c=(a=>{const b=d(a).movementY;return b});c.wbg.__wbg_buttons_d516d4a6ffb63df2=(a=>{const b=d(a).buttons;return b});c.wbg.__wbg_pointerType_6421ba54876364b9=((a,c)=>{const e=d(c).pointerType;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_pointerId_288a7753a42433eb=(a=>{const b=d(a).pointerId;return b});c.wbg.__wbg_clientX_4d37584813a1790a=(a=>{const b=d(a).clientX;return b});c.wbg.__wbg_clientY_ea543e0b8dc1490d=(a=>{const b=d(a).clientY;return b});c.wbg.__wbg_pressure_ef807a4027b5b179=(a=>{const b=d(a).pressure;return b});c.wbg.__wbg_key_9a2550983fbad1d0=((a,c)=>{const e=d(c).key;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_ctrlKey_e7fc1575581bc431=(a=>{const b=d(a).ctrlKey;return b});c.wbg.__wbg_altKey_c3c61dc3af936846=(a=>{const b=d(a).altKey;return b});c.wbg.__wbg_getModifierState_3adb04889097105e=((a,b,c)=>{const e=d(a).getModifierState(k(b,c));return e});c.wbg.__wbg_keyCode_6acbcd0e4e062504=(a=>{const b=d(a).keyCode;return b});c.wbg.__wbg_charCode_7bf774ca7e2117ac=(a=>{const b=d(a).charCode;return b});c.wbg.__wbg_setPointerCapture_02adb3c41a2a5367=function(){return C(((a,b)=>{d(a).setPointerCapture(b)}),arguments)};c.wbg.__wbg_requestAnimationFrame_1820a8e6b645ec5a=function(){return C(((a,b)=>{const c=d(a).requestAnimationFrame(d(b));return c}),arguments)};c.wbg.__wbg_setTimeout_bd20251bb242e262=function(){return C(((a,b,c)=>{const e=d(a).setTimeout(d(b),c);return e}),arguments)};c.wbg.__wbg_body_3eb73da919b867a1=(a=>{const b=d(a).body;return m(b)?W:l(b)});c.wbg.__wbg_appendChild_bd383ec5356c0bdb=function(){return C(((a,b)=>{const c=d(a).appendChild(d(b));return l(c)}),arguments)};c.wbg.__wbg_new_abda76e883ba8a5f=(()=>{const a=new V();return l(a)});c.wbg.__wbg_stack_658279fe44541cf6=((a,c)=>{const e=d(c).stack;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_error_f851667af71bcfc6=((a,c)=>{let d;let e;try{d=a;e=c;console.error(k(a,c))}finally{b.__wbindgen_free(d,e,Y)}});c.wbg.__wbg_resume_32fc64eaa464289a=function(){return C((a=>{const b=d(a).resume();return l(b)}),arguments)};c.wbg.__wbg_close_41fb3d66e34246dc=function(){return C((a=>{const b=d(a).close();return l(b)}),arguments)};c.wbg.__wbg_eval_6c93b88a4b3be0eb=function(){return C(((a,b)=>{const c=eval(k(a,b));return l(c)}),arguments)};c.wbg.__wbindgen_boolean_get=(a=>{const b=d(a);const c=typeof b===a0?(b?Y:W):2;return c});c.wbg.__wbg_crypto_d05b68a3572bb8ca=(a=>{const b=d(a).crypto;return l(b)});c.wbg.__wbindgen_is_object=(a=>{const b=d(a);const c=typeof b===`object`&&b!==T;return c});c.wbg.__wbg_process_b02b3570280d0366=(a=>{const b=d(a).process;return l(b)});c.wbg.__wbg_versions_c1cb42213cedf0f5=(a=>{const b=d(a).versions;return l(b)});c.wbg.__wbg_node_43b1089f407e4ec2=(a=>{const b=d(a).node;return l(b)});c.wbg.__wbindgen_is_string=(a=>{const b=typeof d(a)===a1;return b});c.wbg.__wbg_require_9a7e0f667ead4995=function(){return C((()=>{const a=module.require;return l(a)}),arguments)};c.wbg.__wbindgen_is_function=(a=>{const b=typeof d(a)===_;return b});c.wbg.__wbg_call_f6a2bc58c19c53c6=function(){return C(((a,b,c)=>{const e=d(a).call(d(b),d(c));return l(e)}),arguments)};c.wbg.__wbg_msCrypto_10fc94afee92bd76=(a=>{const b=d(a).msCrypto;return l(b)});c.wbg.__wbg_newwithlength_728575f3bba9959b=(a=>{const b=new X(a>>>W);return l(b)});c.wbg.__wbg_randomFillSync_b70ccbdf4926a99d=function(){return C(((a,b)=>{d(a).randomFillSync(g(b))}),arguments)};c.wbg.__wbg_subarray_7f7a652672800851=((a,b,c)=>{const e=d(a).subarray(b>>>W,c>>>W);return l(e)});c.wbg.__wbg_getRandomValues_7e42b4fb8779dc6d=function(){return C(((a,b)=>{d(a).getRandomValues(d(b))}),arguments)};c.wbg.__wbg_connected_e7984632fc5baeca=(a=>{const b=d(a).connected;return b});c.wbg.__wbg_now_86f7ca537c8b86d5=(()=>{const a=Date.now();return a});c.wbg.__wbindgen_number_get=((a,b)=>{const c=d(b);const e=typeof c===$?c:R;o()[a/8+ Y]=m(e)?W:e;q()[a/a5+ W]=!m(e)});c.wbg.__wbg_pressed_6689c2375fac761f=(a=>{const b=d(a).pressed;return b});c.wbg.__wbg_value_df73ea5624c95e17=(a=>{const b=d(a).value;return b});c.wbg.__wbindgen_is_null=(a=>{const b=d(a)===T;return b});c.wbg.__wbg_id_b65a9e5c38af3381=((a,c)=>{const e=d(c).id;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_buttons_42cf81a9dc81d560=(a=>{const b=d(a).buttons;return l(b)});c.wbg.__wbg_length_d99b680fd68bf71b=(a=>{const b=d(a).length;return b});c.wbg.__wbg_axes_29295fc5e2791881=(a=>{const b=d(a).axes;return l(b)});c.wbg.__wbg_mapping_9891f1fe2b08c14b=(a=>{const b=d(a).mapping;return l(b)});c.wbg.__wbg_get_c43534c00f382c8a=((a,b)=>{const c=d(a)[b>>>W];return l(c)});c.wbg.__wbg_isSecureContext_a4963ee69cd2dcf2=(a=>{const b=d(a).isSecureContext;return b});c.wbg.__wbg_navigator_910cca0226b70083=(a=>{const b=d(a).navigator;return l(b)});c.wbg.__wbg_getGamepads_77e0120579fb7c8d=function(){return C((a=>{const b=d(a).getGamepads();return l(b)}),arguments)};c.wbg.__wbg_index_ad8482877f40f04f=(a=>{const b=d(a).index;return b});c.wbg.__wbg_instanceof_DomException_3813d9e5e1312be8=(a=>{let b;try{b=d(a) instanceof DOMException}catch(a){b=!1}const c=b;return c});c.wbg.__wbg_message_9cb2b2d345ff18c6=((a,c)=>{const e=d(c).message;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_getExtension_25430e0ed157fcf8=function(){return C(((a,b,c)=>{const e=d(a).getExtension(k(b,c));return m(e)?W:l(e)}),arguments)};c.wbg.__wbg_getSupportedExtensions_1a007030d26efba5=(a=>{const b=d(a).getSupportedExtensions();return m(b)?W:l(b)});c.wbg.__wbg_getParameter_b282105ca8420119=function(){return C(((a,b)=>{const c=d(a).getParameter(b>>>W);return l(c)}),arguments)};c.wbg.__wbindgen_string_get=((a,c)=>{const e=d(c);const f=typeof e===a1?e:R;var g=m(f)?W:u(f,b.__wbindgen_malloc,b.__wbindgen_realloc);var h=r;q()[a/a5+ Y]=h;q()[a/a5+ W]=g});c.wbg.__wbg_texSubImage2D_4d372d780fc0e4a7=function(){return C(((a,b,c,e,f,g,h,i,j,k)=>{d(a).texSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j>>>W,d(k))}),arguments)};c.wbg.__wbg_texSubImage2D_cbc346dc5a210f5d=function(){return C(((a,b,c,e,f,g,h,i,j,k)=>{d(a).texSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j>>>W,d(k))}),arguments)};c.wbg.__wbg_texSubImage2D_ad0af504139d876c=function(){return C(((a,b,c,e,f,g,h,i,j,k)=>{d(a).texSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j>>>W,d(k))}),arguments)};c.wbg.__wbg_texSubImage3D_e36d3c30ac0d0749=function(){return C(((a,b,c,e,f,g,h,i,j,k,l,m)=>{d(a).texSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,l>>>W,d(m))}),arguments)};c.wbg.__wbg_texSubImage3D_d98b6d6d4c3f3d01=function(){return C(((a,b,c,e,f,g,h,i,j,k,l,m)=>{d(a).texSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,l>>>W,d(m))}),arguments)};c.wbg.__wbg_texSubImage3D_a8f081c484f78039=function(){return C(((a,b,c,e,f,g,h,i,j,k,l,m)=>{d(a).texSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,l>>>W,d(m))}),arguments)};c.wbg.__wbg_framebufferTextureMultiviewOVR_b4f234dba08738d7=((a,b,c,e,f,g,h)=>{d(a).framebufferTextureMultiviewOVR(b>>>W,c>>>W,d(e),f,g,h)});c.wbg.__wbg_bindFramebuffer_28e8c0c3f76447af=((a,b,c)=>{d(a).bindFramebuffer(b>>>W,d(c))});c.wbg.__wbg_bindFramebuffer_0b8b88d70f0b876e=((a,b,c)=>{d(a).bindFramebuffer(b>>>W,d(c))});c.wbg.__wbg_getSupportedProfiles_a3af04122b4f2f30=(a=>{const b=d(a).getSupportedProfiles();return m(b)?W:l(b)});c.wbg.__wbg_new_34c624469fb1d4fd=(()=>{const a=new S();return l(a)});c.wbg.__wbg_includes_b0feae2b4a1ae514=((a,b,c)=>{const e=d(a).includes(d(b),c);return e});c.wbg.__wbg_createFramebuffer_f8c26154f8992bfa=(a=>{const b=d(a).createFramebuffer();return m(b)?W:l(b)});c.wbg.__wbg_createFramebuffer_52e5d7327d5afba3=(a=>{const b=d(a).createFramebuffer();return m(b)?W:l(b)});c.wbg.__wbg_createQuery_dca7163929abd29d=(a=>{const b=d(a).createQuery();return m(b)?W:l(b)});c.wbg.__wbg_createRenderbuffer_e2d77844fbdcc842=(a=>{const b=d(a).createRenderbuffer();return m(b)?W:l(b)});c.wbg.__wbg_createRenderbuffer_881be806709189a9=(a=>{const b=d(a).createRenderbuffer();return m(b)?W:l(b)});c.wbg.__wbg_createSampler_e2bcf2bc717a1cad=(a=>{const b=d(a).createSampler();return m(b)?W:l(b)});c.wbg.__wbg_createShader_896229165c5a11d4=((a,b)=>{const c=d(a).createShader(b>>>W);return m(c)?W:l(c)});c.wbg.__wbg_createShader_119ffcdb1667f405=((a,b)=>{const c=d(a).createShader(b>>>W);return m(c)?W:l(c)});c.wbg.__wbg_createTexture_b77eefdce0bb2c55=(a=>{const b=d(a).createTexture();return m(b)?W:l(b)});c.wbg.__wbg_createTexture_4f0c3c77df4bde11=(a=>{const b=d(a).createTexture();return m(b)?W:l(b)});c.wbg.__wbg_deleteShader_322b059ad560664a=((a,b)=>{d(a).deleteShader(d(b))});c.wbg.__wbg_deleteShader_5ec1e25476df2da0=((a,b)=>{d(a).deleteShader(d(b))});c.wbg.__wbg_shaderSource_04af20ecb1962b3b=((a,b,c,e)=>{d(a).shaderSource(d(b),k(c,e))});c.wbg.__wbg_shaderSource_e12efd3a2bf3413d=((a,b,c,e)=>{d(a).shaderSource(d(b),k(c,e))});c.wbg.__wbg_compileShader_be824cfad43331b8=((a,b)=>{d(a).compileShader(d(b))});c.wbg.__wbg_compileShader_bdfb3d5a3ad59498=((a,b)=>{d(a).compileShader(d(b))});c.wbg.__wbg_getShaderParameter_a9315ba73ab18731=((a,b,c)=>{const e=d(a).getShaderParameter(d(b),c>>>W);return l(e)});c.wbg.__wbg_getShaderParameter_58d3b34afa9db13b=((a,b,c)=>{const e=d(a).getShaderParameter(d(b),c>>>W);return l(e)});c.wbg.__wbg_createProgram_983b87cad6d06768=(a=>{const b=d(a).createProgram();return m(b)?W:l(b)});c.wbg.__wbg_createProgram_0a7670ed33f06d97=(a=>{const b=d(a).createProgram();return m(b)?W:l(b)});c.wbg.__wbg_deleteProgram_8447c337271aa934=((a,b)=>{d(a).deleteProgram(d(b))});c.wbg.__wbg_deleteProgram_d90e44574acb8018=((a,b)=>{d(a).deleteProgram(d(b))});c.wbg.__wbg_attachShader_cfbbdefc08a0422f=((a,b,c)=>{d(a).attachShader(d(b),d(c))});c.wbg.__wbg_attachShader_70c3f88b777a0a54=((a,b,c)=>{d(a).attachShader(d(b),d(c))});c.wbg.__wbg_linkProgram_caeab1eb0c0246be=((a,b)=>{d(a).linkProgram(d(b))});c.wbg.__wbg_linkProgram_e170ffe0b8242136=((a,b)=>{d(a).linkProgram(d(b))});c.wbg.__wbg_getProgramParameter_35800b92324ff726=((a,b,c)=>{const e=d(a).getProgramParameter(d(b),c>>>W);return l(e)});c.wbg.__wbg_getProgramParameter_22b3f1c8d913cd2c=((a,b,c)=>{const e=d(a).getProgramParameter(d(b),c>>>W);return l(e)});c.wbg.__wbg_getActiveUniform_07e2333f5c6a043b=((a,b,c)=>{const e=d(a).getActiveUniform(d(b),c>>>W);return m(e)?W:l(e)});c.wbg.__wbg_size_b9db0a8002af3240=(a=>{const b=d(a).size;return b});c.wbg.__wbg_type_d15cb90f6bbe57c6=(a=>{const b=d(a).type;return b});c.wbg.__wbg_name_4774375796143fca=((a,c)=>{const e=d(c).name;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_getActiveUniform_d5bafdccc7438fbb=((a,b,c)=>{const e=d(a).getActiveUniform(d(b),c>>>W);return m(e)?W:l(e)});c.wbg.__wbg_useProgram_53de6b084c4780ce=((a,b)=>{d(a).useProgram(d(b))});c.wbg.__wbg_useProgram_229c8fa8394b4c26=((a,b)=>{d(a).useProgram(d(b))});c.wbg.__wbg_createBuffer_90bf79c414ad4956=(a=>{const b=d(a).createBuffer();return m(b)?W:l(b)});c.wbg.__wbg_createBuffer_a95c59cc2c1750e7=(a=>{const b=d(a).createBuffer();return m(b)?W:l(b)});c.wbg.__wbg_bindBuffer_ac939bcab5249160=((a,b,c)=>{d(a).bindBuffer(b>>>W,d(c))});c.wbg.__wbg_bindBuffer_3f166cc2f502fc09=((a,b,c)=>{d(a).bindBuffer(b>>>W,d(c))});c.wbg.__wbg_bindBufferRange_bfdd227c2d5515af=((a,b,c,e,f,g)=>{d(a).bindBufferRange(b>>>W,c>>>W,d(e),f,g)});c.wbg.__wbg_bindRenderbuffer_f06f73fc0b43967e=((a,b,c)=>{d(a).bindRenderbuffer(b>>>W,d(c))});c.wbg.__wbg_bindRenderbuffer_2fe89083883b96e7=((a,b,c)=>{d(a).bindRenderbuffer(b>>>W,d(c))});c.wbg.__wbg_blitFramebuffer_8ca764978b2e3b3f=((a,b,c,e,f,g,h,i,j,k,l)=>{d(a).blitFramebuffer(b,c,e,f,g,h,i,j,k>>>W,l>>>W)});c.wbg.__wbg_createVertexArrayOES_96ccfea00081dcf3=(a=>{const b=d(a).createVertexArrayOES();return m(b)?W:l(b)});c.wbg.__wbg_createVertexArray_761ba22fc5da3ad7=(a=>{const b=d(a).createVertexArray();return m(b)?W:l(b)});c.wbg.__wbg_deleteVertexArray_26631f33de66bdfd=((a,b)=>{d(a).deleteVertexArray(d(b))});c.wbg.__wbg_deleteVertexArrayOES_657b2572282b9dff=((a,b)=>{d(a).deleteVertexArrayOES(d(b))});c.wbg.__wbg_bindVertexArray_2a70aed123353597=((a,b)=>{d(a).bindVertexArray(d(b))});c.wbg.__wbg_bindVertexArrayOES_e95cf32f50e47240=((a,b)=>{d(a).bindVertexArrayOES(d(b))});c.wbg.__wbg_pixelStorei_ac98844c2d6d1937=((a,b,c)=>{d(a).pixelStorei(b>>>W,c)});c.wbg.__wbg_pixelStorei_6be3fc7114b690b8=((a,b,c)=>{d(a).pixelStorei(b>>>W,c)});c.wbg.__wbg_bufferData_9566a2faddca5792=((a,b,c,e)=>{d(a).bufferData(b>>>W,c,e>>>W)});c.wbg.__wbg_bufferData_6c5edae24f952d4d=((a,b,c,e)=>{d(a).bufferData(b>>>W,c,e>>>W)});c.wbg.__wbg_bufferData_b2e68fdc1fd1e94b=((a,b,c,e)=>{d(a).bufferData(b>>>W,d(c),e>>>W)});c.wbg.__wbg_bufferData_eab63186e3e72d98=((a,b,c,e)=>{d(a).bufferData(b>>>W,d(c),e>>>W)});c.wbg.__wbg_bufferSubData_7d216abec8307331=((a,b,c,e)=>{d(a).bufferSubData(b>>>W,c,d(e))});c.wbg.__wbg_bufferSubData_3b75566851019327=((a,b,c,e)=>{d(a).bufferSubData(b>>>W,c,d(e))});c.wbg.__wbg_getBufferSubData_42fbdf01d4c31560=((a,b,c,e)=>{d(a).getBufferSubData(b>>>W,c,d(e))});c.wbg.__wbg_clearBufferiv_07046f3c028ef141=((a,b,c,e,f)=>{d(a).clearBufferiv(b>>>W,c,G(e,f))});c.wbg.__wbg_clearBufferuiv_d0ebea28b39eb980=((a,b,c,e,f)=>{d(a).clearBufferuiv(b>>>W,c,J(e,f))});c.wbg.__wbg_clearBufferfv_a415d907abca9e83=((a,b,c,e,f)=>{d(a).clearBufferfv(b>>>W,c,F(e,f))});c.wbg.__wbg_clearBufferfi_04f7c24deffc8e1d=((a,b,c,e,f)=>{d(a).clearBufferfi(b>>>W,c,e,f)});c.wbg.__wbg_clientWaitSync_b3f79a980d4d9498=((a,b,c,e)=>{const f=d(a).clientWaitSync(d(b),c>>>W,e>>>W);return f});c.wbg.__wbg_copyBufferSubData_70becf455ca484cd=((a,b,c,e,f,g)=>{d(a).copyBufferSubData(b>>>W,c>>>W,e,f,g)});c.wbg.__wbg_copyTexSubImage2D_6ce49c4a307e877d=((a,b,c,e,f,g,h,i,j)=>{d(a).copyTexSubImage2D(b>>>W,c,e,f,g,h,i,j)});c.wbg.__wbg_copyTexSubImage2D_6e2fe88bb9fa3ffd=((a,b,c,e,f,g,h,i,j)=>{d(a).copyTexSubImage2D(b>>>W,c,e,f,g,h,i,j)});c.wbg.__wbg_copyTexSubImage3D_f385cc4e05c95e64=((a,b,c,e,f,g,h,i,j,k)=>{d(a).copyTexSubImage3D(b>>>W,c,e,f,g,h,i,j,k)});c.wbg.__wbg_deleteBuffer_d70596808095dac2=((a,b)=>{d(a).deleteBuffer(d(b))});c.wbg.__wbg_deleteBuffer_b8aaa61f9bb13617=((a,b)=>{d(a).deleteBuffer(d(b))});c.wbg.__wbg_deleteFramebuffer_23c9c7c8176aa9b8=((a,b)=>{d(a).deleteFramebuffer(d(b))});c.wbg.__wbg_deleteFramebuffer_d6907809466bdbdb=((a,b)=>{d(a).deleteFramebuffer(d(b))});c.wbg.__wbg_deleteQuery_3524b489c741d48f=((a,b)=>{d(a).deleteQuery(d(b))});c.wbg.__wbg_deleteRenderbuffer_7bb3c4c79eac08ff=((a,b)=>{d(a).deleteRenderbuffer(d(b))});c.wbg.__wbg_deleteRenderbuffer_1c4b186beb91d4a5=((a,b)=>{d(a).deleteRenderbuffer(d(b))});c.wbg.__wbg_deleteSampler_f760c2bdc7a3d881=((a,b)=>{d(a).deleteSampler(d(b))});c.wbg.__wbg_deleteSync_6bff1584a3aae6a1=((a,b)=>{d(a).deleteSync(d(b))});c.wbg.__wbg_deleteTexture_bbda7cb554bc12b9=((a,b)=>{d(a).deleteTexture(d(b))});c.wbg.__wbg_deleteTexture_554c30847d340929=((a,b)=>{d(a).deleteTexture(d(b))});c.wbg.__wbg_disable_57e8624c865bd654=((a,b)=>{d(a).disable(b>>>W)});c.wbg.__wbg_disable_f68719f70ddfb5b8=((a,b)=>{d(a).disable(b>>>W)});c.wbg.__wbg_disableVertexAttribArray_fb822948cb54eec9=((a,b)=>{d(a).disableVertexAttribArray(b>>>W)});c.wbg.__wbg_disableVertexAttribArray_557393d91e187e24=((a,b)=>{d(a).disableVertexAttribArray(b>>>W)});c.wbg.__wbg_drawArrays_d48ee5c0a02be869=((a,b,c,e)=>{d(a).drawArrays(b>>>W,c,e)});c.wbg.__wbg_drawArrays_2f37c32534dffd91=((a,b,c,e)=>{d(a).drawArrays(b>>>W,c,e)});c.wbg.__wbg_drawArraysInstancedANGLE_4ba856b2c59d84b8=((a,b,c,e,f)=>{d(a).drawArraysInstancedANGLE(b>>>W,c,e,f)});c.wbg.__wbg_drawArraysInstanced_b0963fae97f2f14e=((a,b,c,e,f)=>{d(a).drawArraysInstanced(b>>>W,c,e,f)});c.wbg.__wbindgen_number_new=(a=>{const b=a;return l(b)});c.wbg.__wbg_push_906164999551d793=((a,b)=>{const c=d(a).push(d(b));return c});c.wbg.__wbg_of_3d7aa62bb0ab56ee=(a=>{const b=S.of(d(a));return l(b)});c.wbg.__wbg_drawBuffersWEBGL_533ee2b72ddb728a=((a,b)=>{d(a).drawBuffersWEBGL(d(b))});c.wbg.__wbg_drawBuffers_117fa4691357b53d=((a,b)=>{d(a).drawBuffers(d(b))});c.wbg.__wbg_drawElementsInstancedANGLE_fdf5cd2eb03dd141=((a,b,c,e,f,g)=>{d(a).drawElementsInstancedANGLE(b>>>W,c,e>>>W,f,g)});c.wbg.__wbg_drawElementsInstanced_19c02c2c6c7ebdd5=((a,b,c,e,f,g)=>{d(a).drawElementsInstanced(b>>>W,c,e>>>W,f,g)});c.wbg.__wbg_enable_54d01bacc240df3e=((a,b)=>{d(a).enable(b>>>W)});c.wbg.__wbg_enable_6dab9d5278ba15e2=((a,b)=>{d(a).enable(b>>>W)});c.wbg.__wbg_enableVertexAttribArray_c971ef03599058ec=((a,b)=>{d(a).enableVertexAttribArray(b>>>W)});c.wbg.__wbg_enableVertexAttribArray_c2bfb733e87824c8=((a,b)=>{d(a).enableVertexAttribArray(b>>>W)});c.wbg.__wbg_framebufferRenderbuffer_564b54a213de82b7=((a,b,c,e,f)=>{d(a).framebufferRenderbuffer(b>>>W,c>>>W,e>>>W,d(f))});c.wbg.__wbg_framebufferRenderbuffer_27bc520ea685b484=((a,b,c,e,f)=>{d(a).framebufferRenderbuffer(b>>>W,c>>>W,e>>>W,d(f))});c.wbg.__wbg_framebufferTexture2D_e7783c0015d1135a=((a,b,c,e,f,g)=>{d(a).framebufferTexture2D(b>>>W,c>>>W,e>>>W,d(f),g)});c.wbg.__wbg_framebufferTexture2D_c61bc6c888f33a52=((a,b,c,e,f,g)=>{d(a).framebufferTexture2D(b>>>W,c>>>W,e>>>W,d(f),g)});c.wbg.__wbg_framebufferTextureLayer_5fdc631245f13684=((a,b,c,e,f,g)=>{d(a).framebufferTextureLayer(b>>>W,c>>>W,d(e),f,g)});c.wbg.__wbg_frontFace_e13136966c974dd8=((a,b)=>{d(a).frontFace(b>>>W)});c.wbg.__wbg_frontFace_271693c85383f2e8=((a,b)=>{d(a).frontFace(b>>>W)});c.wbg.__wbg_getParameter_798cbb8ff20c7af0=function(){return C(((a,b)=>{const c=d(a).getParameter(b>>>W);return l(c)}),arguments)};c.wbg.__wbg_getIndexedParameter_69fe97ab84f9db9b=function(){return C(((a,b,c)=>{const e=d(a).getIndexedParameter(b>>>W,c>>>W);return l(e)}),arguments)};c.wbg.__wbg_getUniformLocation_f161344f25983444=((a,b,c,e)=>{const f=d(a).getUniformLocation(d(b),k(c,e));return m(f)?W:l(f)});c.wbg.__wbg_getUniformLocation_7b435a76db4f3128=((a,b,c,e)=>{const f=d(a).getUniformLocation(d(b),k(c,e));return m(f)?W:l(f)});c.wbg.__wbg_getSyncParameter_0c83093c52867612=((a,b,c)=>{const e=d(a).getSyncParameter(d(b),c>>>W);return l(e)});c.wbg.__wbg_renderbufferStorage_982fcb5577f764ca=((a,b,c,e,f)=>{d(a).renderbufferStorage(b>>>W,c>>>W,e,f)});c.wbg.__wbg_renderbufferStorage_5a63960c0bb41916=((a,b,c,e,f)=>{d(a).renderbufferStorage(b>>>W,c>>>W,e,f)});c.wbg.__wbg_renderbufferStorageMultisample_c5f884a4faf6330a=((a,b,c,e,f,g)=>{d(a).renderbufferStorageMultisample(b>>>W,c,e>>>W,f,g)});c.wbg.__wbg_samplerParameterf_a15f79d315dcfc5d=((a,b,c,e)=>{d(a).samplerParameterf(d(b),c>>>W,e)});c.wbg.__wbg_samplerParameteri_6f5c08b9c98433e9=((a,b,c,e)=>{d(a).samplerParameteri(d(b),c>>>W,e)});c.wbg.__wbg_texStorage2D_b46c4dcaa6dc9638=((a,b,c,e,f,g)=>{d(a).texStorage2D(b>>>W,c,e>>>W,f,g)});c.wbg.__wbg_texStorage3D_521eded8d8da33a6=((a,b,c,e,f,g,h)=>{d(a).texStorage3D(b>>>W,c,e>>>W,f,g,h)});c.wbg.__wbg_uniform1i_5a5f1f9d5828e6c6=((a,b,c)=>{d(a).uniform1i(d(b),c)});c.wbg.__wbg_uniform1i_1fd90743f7b78faa=((a,b,c)=>{d(a).uniform1i(d(b),c)});c.wbg.__wbg_uniform2iv_5ba0883cf01ae09d=((a,b,c,e)=>{d(a).uniform2iv(d(b),G(c,e))});c.wbg.__wbg_uniform2iv_fcef57681e7795f1=((a,b,c,e)=>{d(a).uniform2iv(d(b),G(c,e))});c.wbg.__wbg_uniform3iv_f297f19f134ad0c2=((a,b,c,e)=>{d(a).uniform3iv(d(b),G(c,e))});c.wbg.__wbg_uniform3iv_da537ca1568e83fe=((a,b,c,e)=>{d(a).uniform3iv(d(b),G(c,e))});c.wbg.__wbg_uniform4iv_2dbb8a34d36a28c3=((a,b,c,e)=>{d(a).uniform4iv(d(b),G(c,e))});c.wbg.__wbg_uniform4iv_eaebe8f50f18f893=((a,b,c,e)=>{d(a).uniform4iv(d(b),G(c,e))});c.wbg.__wbg_uniform1f_5c36f8a2cf1d8cd7=((a,b,c)=>{d(a).uniform1f(d(b),c)});c.wbg.__wbg_uniform1f_b13c736354a10aa7=((a,b,c)=>{d(a).uniform1f(d(b),c)});c.wbg.__wbg_uniform4f_93ef17b7172e8ad2=((a,b,c,e,f,g)=>{d(a).uniform4f(d(b),c,e,f,g)});c.wbg.__wbg_uniform4f_5b57101145ac6da8=((a,b,c,e,f,g)=>{d(a).uniform4f(d(b),c,e,f,g)});c.wbg.__wbg_uniform2fv_d375e6a7b2f1e575=((a,b,c,e)=>{d(a).uniform2fv(d(b),F(c,e))});c.wbg.__wbg_uniform2fv_a079de4d57adc89f=((a,b,c,e)=>{d(a).uniform2fv(d(b),F(c,e))});c.wbg.__wbg_uniform3fv_ce5f4b99b178dd74=((a,b,c,e)=>{d(a).uniform3fv(d(b),F(c,e))});c.wbg.__wbg_uniform3fv_0211c4807ed5b6bb=((a,b,c,e)=>{d(a).uniform3fv(d(b),F(c,e))});c.wbg.__wbg_uniform4fv_f7afb7d09ee03175=((a,b,c,e)=>{d(a).uniform4fv(d(b),F(c,e))});c.wbg.__wbg_uniform4fv_5134ae6d977cd056=((a,b,c,e)=>{d(a).uniform4fv(d(b),F(c,e))});c.wbg.__wbg_uniformMatrix2fv_9e0249ce783ce2be=((a,b,c,e,f)=>{d(a).uniformMatrix2fv(d(b),c!==W,F(e,f))});c.wbg.__wbg_uniformMatrix2fv_1c4f6d47a69eddf2=((a,b,c,e,f)=>{d(a).uniformMatrix2fv(d(b),c!==W,F(e,f))});c.wbg.__wbg_uniformMatrix3fv_2a9524cf34ecbd62=((a,b,c,e,f)=>{d(a).uniformMatrix3fv(d(b),c!==W,F(e,f))});c.wbg.__wbg_uniformMatrix3fv_5b337adcad4a038d=((a,b,c,e,f)=>{d(a).uniformMatrix3fv(d(b),c!==W,F(e,f))});c.wbg.__wbg_uniformMatrix4fv_4c466deaf158ed5b=((a,b,c,e,f)=>{d(a).uniformMatrix4fv(d(b),c!==W,F(e,f))});c.wbg.__wbg_uniformMatrix4fv_10075e61e88aea3b=((a,b,c,e,f)=>{d(a).uniformMatrix4fv(d(b),c!==W,F(e,f))});c.wbg.__wbg_cullFace_a65f5d17b1ff5686=((a,b)=>{d(a).cullFace(b>>>W)});c.wbg.__wbg_cullFace_68b06ff8967b93f3=((a,b)=>{d(a).cullFace(b>>>W)});c.wbg.__wbg_colorMask_57603facaeb6e2e3=((a,b,c,e,f)=>{d(a).colorMask(b!==W,c!==W,e!==W,f!==W)});c.wbg.__wbg_colorMask_743f2bbb6e3fb4e5=((a,b,c,e,f)=>{d(a).colorMask(b!==W,c!==W,e!==W,f!==W)});c.wbg.__wbg_depthMask_d2c08d83ea550563=((a,b)=>{d(a).depthMask(b!==W)});c.wbg.__wbg_depthMask_052a5e3afe45b590=((a,b)=>{d(a).depthMask(b!==W)});c.wbg.__wbg_blendColor_71d54d4dad7a369a=((a,b,c,e,f)=>{d(a).blendColor(b,c,e,f)});c.wbg.__wbg_blendColor_4416443539cdef95=((a,b,c,e,f)=>{d(a).blendColor(b,c,e,f)});c.wbg.__wbg_invalidateFramebuffer_2d3e8a1b99fd845c=function(){return C(((a,b,c)=>{d(a).invalidateFramebuffer(b>>>W,d(c))}),arguments)};c.wbg.__wbg_polygonOffset_442517f9de53e3de=((a,b,c)=>{d(a).polygonOffset(b,c)});c.wbg.__wbg_polygonOffset_0f2730043ba169b2=((a,b,c)=>{d(a).polygonOffset(b,c)});c.wbg.__wbg_bindTexture_e28115f3ea3da6d2=((a,b,c)=>{d(a).bindTexture(b>>>W,d(c))});c.wbg.__wbg_bindTexture_be92cdd3f162b4f9=((a,b,c)=>{d(a).bindTexture(b>>>W,d(c))});c.wbg.__wbg_bindSampler_12a1965a2db071ed=((a,b,c)=>{d(a).bindSampler(b>>>W,d(c))});c.wbg.__wbg_activeTexture_3748123e1becf07d=((a,b)=>{d(a).activeTexture(b>>>W)});c.wbg.__wbg_activeTexture_02d56293bce2f613=((a,b)=>{d(a).activeTexture(b>>>W)});c.wbg.__wbg_fenceSync_452ae6f3789bdc77=((a,b,c)=>{const e=d(a).fenceSync(b>>>W,c>>>W);return m(e)?W:l(e)});c.wbg.__wbg_texParameteri_dd08984388e62491=((a,b,c,e)=>{d(a).texParameteri(b>>>W,c>>>W,e)});c.wbg.__wbg_texParameteri_f5c0d085b77931dd=((a,b,c,e)=>{d(a).texParameteri(b>>>W,c>>>W,e)});c.wbg.__wbg_texSubImage2D_d23a3ec1fa60bdaf=function(){return C(((a,b,c,e,f,g,h,i,j,k)=>{d(a).texSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j>>>W,d(k))}),arguments)};c.wbg.__wbg_texSubImage2D_33018bcf2de70890=function(){return C(((a,b,c,e,f,g,h,i,j,k)=>{d(a).texSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j>>>W,d(k))}),arguments)};c.wbg.__wbg_texSubImage2D_b97aa5ddc0162314=function(){return C(((a,b,c,e,f,g,h,i,j,k)=>{d(a).texSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j>>>W,k)}),arguments)};c.wbg.__wbg_compressedTexSubImage2D_5666e0146e152b7d=((a,b,c,e,f,g,h,i,j)=>{d(a).compressedTexSubImage2D(b>>>W,c,e,f,g,h,i>>>W,d(j))});c.wbg.__wbg_compressedTexSubImage2D_41270fc03b157293=((a,b,c,e,f,g,h,i,j)=>{d(a).compressedTexSubImage2D(b>>>W,c,e,f,g,h,i>>>W,d(j))});c.wbg.__wbg_compressedTexSubImage2D_1194f18adf8859b9=((a,b,c,e,f,g,h,i,j,k)=>{d(a).compressedTexSubImage2D(b>>>W,c,e,f,g,h,i>>>W,j,k)});c.wbg.__wbg_texSubImage3D_5884c8e282839ff9=function(){return C(((a,b,c,e,f,g,h,i,j,k,l,m)=>{d(a).texSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,l>>>W,m)}),arguments)};c.wbg.__wbg_texSubImage3D_2742ec6099cae3fc=function(){return C(((a,b,c,e,f,g,h,i,j,k,l,m)=>{d(a).texSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,l>>>W,d(m))}),arguments)};c.wbg.__wbg_compressedTexSubImage3D_34cd53cffc6add9c=((a,b,c,e,f,g,h,i,j,k,l,m)=>{d(a).compressedTexSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,l,m)});c.wbg.__wbg_compressedTexSubImage3D_f0da020d6e3e3791=((a,b,c,e,f,g,h,i,j,k,l)=>{d(a).compressedTexSubImage3D(b>>>W,c,e,f,g,h,i,j,k>>>W,d(l))});c.wbg.__wbg_depthFunc_b78eec6735fd7a0a=((a,b)=>{d(a).depthFunc(b>>>W)});c.wbg.__wbg_depthFunc_e49f522acf6c6c2d=((a,b)=>{d(a).depthFunc(b>>>W)});c.wbg.__wbg_depthRange_c4d7339e2f6b2e4a=((a,b,c)=>{d(a).depthRange(b,c)});c.wbg.__wbg_depthRange_8309e031492fd023=((a,b,c)=>{d(a).depthRange(b,c)});c.wbg.__wbg_scissor_7206bcd2a5540aa3=((a,b,c,e,f)=>{d(a).scissor(b,c,e,f)});c.wbg.__wbg_scissor_27cb154cc9864444=((a,b,c,e,f)=>{d(a).scissor(b,c,e,f)});c.wbg.__wbg_vertexAttribDivisorANGLE_51dd5c906f4912a2=((a,b,c)=>{d(a).vertexAttribDivisorANGLE(b>>>W,c>>>W)});c.wbg.__wbg_vertexAttribDivisor_aad38a21841ace46=((a,b,c)=>{d(a).vertexAttribDivisor(b>>>W,c>>>W)});c.wbg.__wbg_vertexAttribPointer_e9c4ff85658b9ad2=((a,b,c,e,f,g,h)=>{d(a).vertexAttribPointer(b>>>W,c,e>>>W,f!==W,g,h)});c.wbg.__wbg_vertexAttribPointer_3133080603a92d4c=((a,b,c,e,f,g,h)=>{d(a).vertexAttribPointer(b>>>W,c,e>>>W,f!==W,g,h)});c.wbg.__wbg_vertexAttribIPointer_24c9254053dd8ab4=((a,b,c,e,f,g)=>{d(a).vertexAttribIPointer(b>>>W,c,e>>>W,f,g)});c.wbg.__wbg_viewport_0ca27d1d6ac8424c=((a,b,c,e,f)=>{d(a).viewport(b,c,e,f)});c.wbg.__wbg_viewport_afd5166081d009b2=((a,b,c,e,f)=>{d(a).viewport(b,c,e,f)});c.wbg.__wbg_blendFunc_5adf0a3a9f164e6e=((a,b,c)=>{d(a).blendFunc(b>>>W,c>>>W)});c.wbg.__wbg_blendFunc_ac53b0d3a97b7f7f=((a,b,c)=>{d(a).blendFunc(b>>>W,c>>>W)});c.wbg.__wbg_blendFuncSeparate_52fdb0f1fbf57928=((a,b,c,e,f)=>{d(a).blendFuncSeparate(b>>>W,c>>>W,e>>>W,f>>>W)});c.wbg.__wbg_blendFuncSeparate_b6a96b8e26e75171=((a,b,c,e,f)=>{d(a).blendFuncSeparate(b>>>W,c>>>W,e>>>W,f>>>W)});c.wbg.__wbg_blendEquation_b1df5434f3ad5aac=((a,b)=>{d(a).blendEquation(b>>>W)});c.wbg.__wbg_blendEquation_1c7272d8e9e0ce11=((a,b)=>{d(a).blendEquation(b>>>W)});c.wbg.__wbg_blendEquationSeparate_33f23a57d77e8079=((a,b,c)=>{d(a).blendEquationSeparate(b>>>W,c>>>W)});c.wbg.__wbg_blendEquationSeparate_457e81472270e23c=((a,b,c)=>{d(a).blendEquationSeparate(b>>>W,c>>>W)});c.wbg.__wbg_stencilFuncSeparate_89563ca030dab790=((a,b,c,e,f)=>{d(a).stencilFuncSeparate(b>>>W,c>>>W,e,f>>>W)});c.wbg.__wbg_stencilFuncSeparate_e6b4c784aa470ba1=((a,b,c,e,f)=>{d(a).stencilFuncSeparate(b>>>W,c>>>W,e,f>>>W)});c.wbg.__wbg_stencilMask_76ea69a0c4738423=((a,b)=>{d(a).stencilMask(b>>>W)});c.wbg.__wbg_stencilMask_4093c371489c5e3e=((a,b)=>{d(a).stencilMask(b>>>W)});c.wbg.__wbg_stencilMaskSeparate_1303b1855315b85a=((a,b,c)=>{d(a).stencilMaskSeparate(b>>>W,c>>>W)});c.wbg.__wbg_stencilMaskSeparate_6a90a6801f96c33e=((a,b,c)=>{d(a).stencilMaskSeparate(b>>>W,c>>>W)});c.wbg.__wbg_stencilOpSeparate_fef362ec0f1539d1=((a,b,c,e,f)=>{d(a).stencilOpSeparate(b>>>W,c>>>W,e>>>W,f>>>W)});c.wbg.__wbg_stencilOpSeparate_f98bb31212170061=((a,b,c,e,f)=>{d(a).stencilOpSeparate(b>>>W,c>>>W,e>>>W,f>>>W)});c.wbg.__wbg_getUniformBlockIndex_b9628e75250e866c=((a,b,c,e)=>{const f=d(a).getUniformBlockIndex(d(b),k(c,e));return f});c.wbg.__wbg_uniformBlockBinding_bcbb7fbc2fe88b8d=((a,b,c,e)=>{d(a).uniformBlockBinding(d(b),c>>>W,e>>>W)});c.wbg.__wbg_readBuffer_4c16fe804e5fd30c=((a,b)=>{d(a).readBuffer(b>>>W)});c.wbg.__wbg_readPixels_8260b74d4439418e=function(){return C(((a,b,c,e,f,g,h,i)=>{d(a).readPixels(b,c,e,f,g>>>W,h>>>W,i)}),arguments)};c.wbg.__wbg_readPixels_c1a5f8a1344005bd=function(){return C(((a,b,c,e,f,g,h,i)=>{d(a).readPixels(b,c,e,f,g>>>W,h>>>W,d(i))}),arguments)};c.wbg.__wbg_readPixels_32bab95664f5bcdf=function(){return C(((a,b,c,e,f,g,h,i)=>{d(a).readPixels(b,c,e,f,g>>>W,h>>>W,d(i))}),arguments)};c.wbg.__wbg_beginQuery_ad59d7ffda61cf9e=((a,b,c)=>{d(a).beginQuery(b>>>W,d(c))});c.wbg.__wbg_endQuery_feb28d278e32cfae=((a,b)=>{d(a).endQuery(b>>>W)});c.wbg.__wbg_getQueryParameter_112c9a3c8a8dd0da=((a,b,c)=>{const e=d(a).getQueryParameter(d(b),c>>>W);return l(e)});c.wbg.__wbg_get_5027b32da70f39b1=function(){return C(((a,b)=>{const c=a8.get(d(a),d(b));return l(c)}),arguments)};c.wbg.__wbg_now_65ff8ec2b863300c=(a=>{const b=d(a).now();return b});c.wbg.__wbg_self_086b5302bcafb962=function(){return C((()=>{const a=self.self;return l(a)}),arguments)};c.wbg.__wbg_window_132fa5d7546f1de5=function(){return C((()=>{const a=window.window;return l(a)}),arguments)};c.wbg.__wbg_globalThis_e5f801a37ad7d07b=function(){return C((()=>{const a=globalThis.globalThis;return l(a)}),arguments)};c.wbg.__wbg_global_f9a61fce4af6b7c1=function(){return C((()=>{const a=global.global;return l(a)}),arguments)};c.wbg.__wbindgen_is_undefined=(a=>{const b=d(a)===R;return b});c.wbg.__wbg_newnoargs_5859b6d41c6fe9f7=((a,b)=>{const c=new Function(k(a,b));return l(c)});c.wbg.__wbg_call_a79f1973a4f07d5e=function(){return C(((a,b)=>{const c=d(a).call(d(b));return l(c)}),arguments)};c.wbg.__wbg_resolve_97ecd55ee839391b=(a=>{const b=Promise.resolve(d(a));return l(b)});c.wbg.__wbg_then_7aeb7c5f1536640f=((a,b)=>{const c=d(a).then(d(b));return l(c)});c.wbg.__wbg_then_5842e4e97f7beace=((a,b,c)=>{const e=d(a).then(d(b),d(c));return l(e)});c.wbg.__wbindgen_memory=(()=>{const a=b.memory;return l(a)});c.wbg.__wbg_buffer_5d1b598a01b41a42=(a=>{const b=d(a).buffer;return l(b)});c.wbg.__wbg_newwithbyteoffsetandlength_54c7b98977affdec=((a,b,c)=>{const e=new Int8Array(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_newwithbyteoffsetandlength_16ba6d10861ea013=((a,b,c)=>{const e=new Int16Array(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_newwithbyteoffsetandlength_821c7736f0d22b04=((a,b,c)=>{const e=new Z(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_newwithbyteoffsetandlength_d695c7957788f922=((a,b,c)=>{const e=new X(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_set_74906aa30864df5a=((a,b,c)=>{d(a).set(d(b),c>>>W)});c.wbg.__wbg_length_f0764416ba5bb237=(a=>{const b=d(a).length;return b});c.wbg.__wbg_newwithbyteoffsetandlength_2412e38a0385bbe2=((a,b,c)=>{const e=new Uint16Array(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_newwithbyteoffsetandlength_aeed38cac7555df7=((a,b,c)=>{const e=new a6(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_newwithbyteoffsetandlength_21163b4dfcbc673c=((a,b,c)=>{const e=new a4(d(a),b>>>W,c>>>W);return l(e)});c.wbg.__wbg_set_37a50e901587b477=function(){return C(((a,b,c)=>{const e=a8.set(d(a),d(b),d(c));return e}),arguments)};c.wbg.__wbg_newwithcontextoptions_14f6b0728f2e5974=function(){return C((b=>{const c=new a(d(b));return l(c)}),arguments)};c.wbg.__wbg_destination_62d2e29a54544ec0=(a=>{const b=d(a).destination;return l(b)});c.wbg.__wbg_maxChannelCount_f7897fa7dc85d572=(a=>{const b=d(a).maxChannelCount;return b});c.wbg.__wbg_setchannelCount_ddf571b2ad2e8eef=((a,b)=>{d(a).channelCount=b>>>W});c.wbg.__wbg_createBuffer_a4cdfb0b3c256e3e=function(){return C(((a,b,c,e)=>{const f=d(a).createBuffer(b>>>W,c>>>W,e);return l(f)}),arguments)};c.wbg.__wbg_currentTime_6b9141913a965d2f=(a=>{const b=d(a).currentTime;return b});c.wbg.__wbg_createBufferSource_0d20dc119e4ded11=function(){return C((a=>{const b=d(a).createBufferSource();return l(b)}),arguments)};c.wbg.__wbg_setbuffer_f16a95796c5a7380=((a,b)=>{d(a).buffer=d(b)});c.wbg.__wbg_connect_65474f2479b77506=function(){return C(((a,b)=>{const c=d(a).connect(d(b));return l(c)}),arguments)};c.wbg.__wbg_setonended_d2cab878358a6af4=((a,b)=>{d(a).onended=d(b)});c.wbg.__wbg_start_88dbb78b1c762033=function(){return C(((a,b)=>{d(a).start(b)}),arguments)};c.wbg.__wbg_copyToChannel_47042ca9c7b9618d=function(){return C(((a,b,c,e)=>{d(a).copyToChannel(F(b,c),e)}),arguments)};c.wbg.__wbg_measure_aa7a73f17813f708=function(){return C(((a,c,d,e)=>{let f;let g;let h;let i;try{f=a;g=c;h=d;i=e;performance.measure(k(a,c),k(d,e))}finally{b.__wbindgen_free(f,g,Y);b.__wbindgen_free(h,i,Y)}}),arguments)};c.wbg.__wbindgen_debug_string=((a,c)=>{const e=v(d(c));const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbindgen_throw=((a,b)=>{throw new V(k(a,b))});c.wbg.__wbg_queueMicrotask_118eeb525d584d9a=(a=>{queueMicrotask(d(a))});c.wbg.__wbg_queueMicrotask_26a89c14c53809c0=(a=>{const b=d(a).queueMicrotask;return l(b)});c.wbg.__wbg_instanceof_WebGl2RenderingContext_92adf5bbd2568b71=(a=>{let b;try{b=d(a) instanceof WebGL2RenderingContext}catch(a){b=!1}const c=b;return c});c.wbg.__wbg_getProgramInfoLog_110f43b4125782e9=((a,c,e)=>{const f=d(c).getProgramInfoLog(d(e));var g=m(f)?W:u(f,b.__wbindgen_malloc,b.__wbindgen_realloc);var h=r;q()[a/a5+ Y]=h;q()[a/a5+ W]=g});c.wbg.__wbg_getShaderInfoLog_562b1447e7c24866=((a,c,e)=>{const f=d(c).getShaderInfoLog(d(e));var g=m(f)?W:u(f,b.__wbindgen_malloc,b.__wbindgen_realloc);var h=r;q()[a/a5+ Y]=h;q()[a/a5+ W]=g});c.wbg.__wbg_instanceof_Window_99dc9805eaa2614b=(a=>{let b;try{b=d(a) instanceof Window}catch(a){b=!1}const c=b;return c});c.wbg.__wbg_innerWidth_0bae627f0302b204=function(){return C((a=>{const b=d(a).innerWidth;return l(b)}),arguments)};c.wbg.__wbg_innerHeight_dc4c81e04e8bc294=function(){return C((a=>{const b=d(a).innerHeight;return l(b)}),arguments)};c.wbg.__wbg_devicePixelRatio_93bac98af723c7ba=(a=>{const b=d(a).devicePixelRatio;return b});c.wbg.__wbg_open_0aa18467f0bb625e=function(){return C(((a,b,c,e,f)=>{const g=d(a).open(k(b,c),k(e,f));return m(g)?W:l(g)}),arguments)};c.wbg.__wbg_get_7f8cd08c0360178c=((a,b,c)=>{const e=d(a)[k(b,c)];return m(e)?W:l(e)});c.wbg.__wbg_cancelAnimationFrame_2635bb6bdb94eb3f=function(){return C(((a,b)=>{d(a).cancelAnimationFrame(b)}),arguments)};c.wbg.__wbg_clearTimeout_cf250b4eed087f7b=((a,b)=>{d(a).clearTimeout(b)});c.wbg.__wbg_fullscreenElement_8ebe202aecd8ae3c=(a=>{const b=d(a).fullscreenElement;return m(b)?W:l(b)});c.wbg.__wbg_createElement_1a136faad4101f43=function(){return C(((a,b,c)=>{const e=d(a).createElement(k(b,c));return l(e)}),arguments)};c.wbg.__wbg_exitFullscreen_4207821551a694a7=(a=>{d(a).exitFullscreen()});c.wbg.__wbg_exitPointerLock_5764ae8300935b9e=(a=>{d(a).exitPointerLock()});c.wbg.__wbg_requestPointerLock_7e461e6d3998ca6a=(a=>{d(a).requestPointerLock()});c.wbg.__wbg_setAttribute_0918ea45d5a1c663=function(){return C(((a,b,c,e,f)=>{d(a).setAttribute(k(b,c),k(e,f))}),arguments)};c.wbg.__wbg_getProgramInfoLog_3ff10ea818ab6ce4=((a,c,e)=>{const f=d(c).getProgramInfoLog(d(e));var g=m(f)?W:u(f,b.__wbindgen_malloc,b.__wbindgen_realloc);var h=r;q()[a/a5+ Y]=h;q()[a/a5+ W]=g});c.wbg.__wbg_getShaderInfoLog_3e435d2b50e0ecf0=((a,c,e)=>{const f=d(c).getShaderInfoLog(d(e));var g=m(f)?W:u(f,b.__wbindgen_malloc,b.__wbindgen_realloc);var h=r;q()[a/a5+ Y]=h;q()[a/a5+ W]=g});c.wbg.__wbg_style_b32d5cb9a6bd4720=(a=>{const b=d(a).style;return l(b)});c.wbg.__wbg_ctrlKey_0d75e0e9028bd999=(a=>{const b=d(a).ctrlKey;return b});c.wbg.__wbg_shiftKey_12353f0e19b21d6a=(a=>{const b=d(a).shiftKey;return b});c.wbg.__wbg_altKey_a076f8612103d7e8=(a=>{const b=d(a).altKey;return b});c.wbg.__wbg_metaKey_4e3f6e986f2802b1=(a=>{const b=d(a).metaKey;return b});c.wbg.__wbg_button_8a97c55db17c7314=(a=>{const b=d(a).button;return b});c.wbg.__wbg_setProperty_a763529f4ef8ac76=function(){return C(((a,b,c,e,f)=>{d(a).setProperty(k(b,c),k(e,f))}),arguments)};c.wbg.__wbg_width_05e7fce75535d85f=(a=>{const b=d(a).width;return b});c.wbg.__wbg_height_51b9308e888df865=(a=>{const b=d(a).height;return b});c.wbg.__wbg_width_193b434156effb1d=(a=>{const b=d(a).width;return b});c.wbg.__wbg_setwidth_62ca8c8f2794be77=((a,b)=>{d(a).width=b>>>W});c.wbg.__wbg_height_84d4ae4d422188a3=(a=>{const b=d(a).height;return b});c.wbg.__wbg_setheight_34b71cfdf6095cbd=((a,b)=>{d(a).height=b>>>W});c.wbg.__wbg_addListener_0bbd0358c52d8a0e=function(){return C(((a,b)=>{d(a).addListener(d(b))}),arguments)};c.wbg.__wbg_removeListener_b8fc928c2300e3c6=function(){return C(((a,b)=>{d(a).removeListener(d(b))}),arguments)};c.wbg.__wbg_x_a0dc9ae3ec018f6a=(a=>{const b=d(a).x;return b});c.wbg.__wbg_y_6f1256869a5628ee=(a=>{const b=d(a).y;return b});c.wbg.__wbg_shiftKey_0a061aeba25dbd63=(a=>{const b=d(a).shiftKey;return b});c.wbg.__wbg_metaKey_b879a69fa9f3f7af=(a=>{const b=d(a).metaKey;return b});c.wbg.__wbg_code_3b51bddc7419ef7d=((a,c)=>{const e=d(c).code;const f=u(e,b.__wbindgen_malloc,b.__wbindgen_realloc);const g=r;q()[a/a5+ Y]=g;q()[a/a5+ W]=f});c.wbg.__wbg_deltaX_de18e6f358ab88cf=(a=>{const b=d(a).deltaX;return b});c.wbg.__wbg_deltaY_50a026b7421f883d=(a=>{const b=d(a).deltaY;return b});c.wbg.__wbg_deltaMode_b8290e36698673d0=(a=>{const b=d(a).deltaMode;return b});c.wbg.__wbg_setwidth_05075fb6b4cc720e=((a,b)=>{d(a).width=b>>>W});c.wbg.__wbg_setheight_7e0e88a922100d8c=((a,b)=>{d(a).height=b>>>W});c.wbg.__wbg_getContext_1daf9aba3e114993=function(){return C(((a,b,c,e)=>{const f=d(a).getContext(k(b,c),d(e));return m(f)?W:l(f)}),arguments)};c.wbg.__wbg_videoWidth_024256de61021e4a=(a=>{const b=d(a).videoWidth;return b});c.wbg.__wbg_videoHeight_2c601663d2d0211a=(a=>{const b=d(a).videoHeight;return b});c.wbg.__wbindgen_closure_wrapper3192=((a,b,c)=>{const d=w(a,b,2249,x);return l(d)});c.wbg.__wbindgen_closure_wrapper60448=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper60450=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper60452=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper60454=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper60456=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper60458=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper60460=((a,b,c)=>{const d=w(a,b,a9,y);return l(d)});c.wbg.__wbindgen_closure_wrapper69820=((a,b,c)=>{const d=w(a,b,44968,z);return l(d)});c.wbg.__wbindgen_closure_wrapper71534=((a,b,c)=>{const d=w(a,b,45347,A);return l(d)});c.wbg.__wbindgen_closure_wrapper75644=((a,b,c)=>{const d=w(a,b,46344,B);return l(d)});return c});var I=(()=>{if(H===T||H.byteLength===W){H=new a6(b.memory.buffer)};return H});var u=((a,b,c)=>{if(c===R){const c=s.encode(a);const d=b(c.length,Y)>>>W;j().subarray(d,d+ c.length).set(c);r=c.length;return d};let d=a.length;let e=b(d,Y)>>>W;const f=j();let g=W;for(;g127)break;f[e+ g]=b};if(g!==d){if(g!==W){a=a.slice(g)};e=c(e,d,d=g+ a.length*3,Y)>>>W;const b=j().subarray(e+ g,e+ d);const f=t(a,b);g+=f.written};r=g;return e});var j=(()=>{if(i===T||i.byteLength===W){i=new X(b.memory.buffer)};return i});var K=(async(a,b)=>{if(typeof Response===_&&a instanceof Response){if(typeof WebAssembly.instantiateStreaming===_){try{return await WebAssembly.instantiateStreaming(a,b)}catch(b){if(a.headers.get(`Content-Type`)!=`application/wasm`){console.warn(`\`WebAssembly.instantiateStreaming\` failed because your server does not serve wasm with \`application/wasm\` MIME type. Falling back to \`WebAssembly.instantiate\` which is slower. Original error:\\n`,b)}else{throw b}}};const c=await a.arrayBuffer();return await WebAssembly.instantiate(c,b)}else{const c=await WebAssembly.instantiate(a,b);if(c instanceof WebAssembly.Instance){return {instance:c,module:a}}else{return c}}});var G=((a,b)=>{a=a>>>W;return q().subarray(a/a5,a/a5+ b)});var J=((a,b)=>{a=a>>>W;return I().subarray(a/a5,a/a5+ b)});var z=((a,c)=>{b.wasm_bindgen__convert__closures__invoke0_mut__hc09e9020f5ee71bd(a,c)});var l=(a=>{if(e===c.length)c.push(c.length+ Y);const b=e;e=c[b];c[b]=a;return b});var g=(a=>{const b=d(a);f(a);return b});var q=(()=>{if(p===T||p.byteLength===W){p=new Z(b.memory.buffer)};return p});var B=((a,c,d)=>{b._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h67c6c39025c42490(a,c,l(d))});var P=(async(a)=>{if(b!==R)return b;if(typeof a===Q){a=new URL(`egui-gizmo-demo_bg.wasm`,import.meta.url)};const c=L();if(typeof a===a1||typeof Request===_&&a instanceof Request||typeof URL===_&&a instanceof URL){a=fetch(a)};M(c);const {instance:d,module:e}=await K(await a,c);return N(d,e)});var A=((a,c,d)=>{b._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__had7d730985a1fbbd(a,c,l(d))});var f=(a=>{if(a<132)return;c[a]=e;e=a});var O=(a=>{if(b!==R)return b;const c=L();M(c);if(!(a instanceof WebAssembly.Module)){a=new WebAssembly.Module(a)};const d=new WebAssembly.Instance(a,c);return N(d,a)});var N=((a,c)=>{b=a.exports;P.__wbindgen_wasm_module=c;D=T;n=T;p=T;H=T;i=T;b.__wbindgen_start();return b});var w=((a,c,d,e)=>{const f={a:a,b:c,cnt:Y,dtor:d};const g=(...a)=>{f.cnt++;const c=f.a;f.a=W;try{return e(c,f.b,...a)}finally{if(--f.cnt===W){b.__wbindgen_export_2.get(f.dtor)(c,f.b)}else{f.a=c}}};g.original=f;return g});var k=((a,b)=>{a=a>>>W;return h.decode(j().subarray(a,a+ b))});var x=((a,c)=>{b.wasm_bindgen__convert__closures__invoke0_mut__h56db7e0444ea06f0(a,c)});const a=typeof AudioContext!==Q?AudioContext:(typeof webkitAudioContext!==Q?webkitAudioContext:R);let b;const c=new S(128).fill(R);c.push(R,T,!0,!1);let e=c.length;const h=typeof TextDecoder!==Q?new TextDecoder(U,{ignoreBOM:!0,fatal:!0}):{decode:()=>{throw V(`TextDecoder not available`)}};if(typeof TextDecoder!==Q){h.decode()};let i=T;let n=T;let p=T;let r=W;const s=typeof TextEncoder!==Q?new TextEncoder(U):{encode:()=>{throw V(`TextEncoder not available`)}};const t=typeof s.encodeInto===_?((a,b)=>s.encodeInto(a,b)):((a,b)=>{const c=s.encode(a);b.set(c);return {read:a.length,written:c.length}});let D=T;let H=T;export default P;export{O as initSync} \ No newline at end of file diff --git a/docs/egui-gizmo-demo_bg.wasm b/docs/egui-gizmo-demo_bg.wasm index d28db49..195ceae 100644 Binary files a/docs/egui-gizmo-demo_bg.wasm and b/docs/egui-gizmo-demo_bg.wasm differ diff --git a/docs/index.html b/docs/index.html index d5a3cc1..2ef3754 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1 +1 @@ -egui-gizmo demo \ No newline at end of file +egui-gizmo demo \ No newline at end of file diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 0000000..13a87da --- /dev/null +++ b/rust-toolchain @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.74.0" +components = ["rustfmt", "clippy"] +targets = ["wasm32-unknown-unknown"] \ No newline at end of file diff --git a/scripts/build_demo_web.sh b/scripts/build_demo_web.sh new file mode 100644 index 0000000..cfe46e9 --- /dev/null +++ b/scripts/build_demo_web.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -eu +script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) + +WASM_PATH="docs/egui-gizmo-demo_bg.wasm" + +pushd "$script_path/../demo" +trunk build --config Trunk.toml --release +popd + +wasm-opt "$WASM_PATH" -O2 --fast-math -o "$WASM_PATH" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 2194303..61a831f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,8 +22,6 @@ //! By default, the gizmo will use the ui clip rect as a viewport. //! The gizmo will apply transformations to the given model matrix. -#![warn(clippy::all)] - use std::cmp::Ordering; use std::f32::consts::PI; use std::hash::Hash; @@ -33,14 +31,13 @@ use crate::math::{screen_to_world, world_to_screen}; use egui::{Color32, Context, Id, PointerButton, Rect, Sense, Ui}; use glam::{DMat4, DQuat, DVec3, Mat4, Quat, Vec3, Vec4Swizzles}; -use crate::subgizmo::{SubGizmo, SubGizmoKind}; +use crate::subgizmo::{ + RotationSubGizmo, ScaleSubGizmo, SubGizmo, TransformKind, TranslationSubGizmo, +}; mod math; mod painter; -mod rotation; -mod scale; mod subgizmo; -mod translation; /// The default snapping distance for rotation in radians pub const DEFAULT_SNAP_ANGLE: f32 = PI / 32.0; @@ -49,17 +46,10 @@ pub const DEFAULT_SNAP_DISTANCE: f32 = 0.1; /// The default snapping distance for scale pub const DEFAULT_SNAP_SCALE: f32 = 0.1; -/// Maximum number of subgizmos in a single gizmo. -/// A subgizmo array of this size is allocated from stack, -/// even if the actual number of subgizmos is less. -const MAX_SUBGIZMOS: usize = 6; - -#[derive(Debug)] pub struct Gizmo { id: Id, config: GizmoConfig, - subgizmos: [Option; MAX_SUBGIZMOS], - subgizmo_count: usize, + subgizmos: Vec>, } impl Gizmo { @@ -68,7 +58,6 @@ impl Gizmo { id: Id::new(id_source), config: GizmoConfig::default(), subgizmos: Default::default(), - subgizmo_count: 0, } } @@ -164,24 +153,26 @@ impl Gizmo { // is under the mouse pointer, if any. if state.active_subgizmo_id.is_none() { if let Some(subgizmo) = self.pick_subgizmo(ui, pointer_ray) { - subgizmo.focused = true; + subgizmo.set_focused(true); let interaction = ui.interact(viewport, id, Sense::click_and_drag()); let dragging = interaction.dragged_by(PointerButton::Primary); if interaction.drag_started() && dragging { - state.active_subgizmo_id = Some(subgizmo.id); + state.active_subgizmo_id = Some(subgizmo.id()); } } } - active_subgizmo = state - .active_subgizmo_id - .and_then(|id| self.subgizmos_mut().find(|subgizmo| subgizmo.id == id)); + active_subgizmo = state.active_subgizmo_id.and_then(|id| { + self.subgizmos + .iter_mut() + .find(|subgizmo| subgizmo.id() == id) + }); if let Some(subgizmo) = active_subgizmo.as_mut() { if ui.input(|i| i.pointer.primary_down()) { - subgizmo.active = true; - subgizmo.focused = true; + subgizmo.set_active(true); + subgizmo.set_focused(true); result = subgizmo.update(ui, pointer_ray); } else { state.active_subgizmo_id = None; @@ -189,10 +180,10 @@ impl Gizmo { } } - if let Some((subgizmo, result)) = active_subgizmo.zip(result) { - subgizmo.config.translation = Vec3::from(result.translation).as_dvec3(); - subgizmo.config.rotation = Quat::from(result.rotation).as_f64(); - subgizmo.config.scale = Vec3::from(result.scale).as_dvec3(); + if let Some((_, result)) = active_subgizmo.zip(result) { + self.config.translation = Vec3::from(result.translation).as_dvec3(); + self.config.rotation = Quat::from(result.rotation).as_f64(); + self.config.scale = Vec3::from(result.scale).as_dvec3(); } state.save(ui.ctx(), self.id); @@ -203,154 +194,141 @@ impl Gizmo { } fn draw_subgizmos(&self, ui: &mut Ui, state: &mut GizmoState) { - for subgizmo in self.subgizmos() { - if state.active_subgizmo_id.is_none() || subgizmo.active { + for subgizmo in &self.subgizmos { + if state.active_subgizmo_id.is_none() || subgizmo.is_active() { subgizmo.draw(ui); } } } /// Picks the subgizmo that is closest to the mouse pointer - fn pick_subgizmo(&mut self, ui: &Ui, ray: Ray) -> Option<&mut SubGizmo> { - self.subgizmos_mut() + fn pick_subgizmo(&mut self, ui: &Ui, ray: Ray) -> Option<&mut Box> { + self.subgizmos + .iter_mut() .filter_map(|subgizmo| subgizmo.pick(ui, ray).map(|t| (t, subgizmo))) .min_by(|(first, _), (second, _)| first.partial_cmp(second).unwrap_or(Ordering::Equal)) .map(|(_, subgizmo)| subgizmo) } - /// Iterator to the subgizmos - fn subgizmos(&self) -> impl Iterator { - self.subgizmos.iter().flatten() - } - - /// Mutable iterator to the subgizmos - fn subgizmos_mut(&mut self) -> impl Iterator { - self.subgizmos.iter_mut().flatten() - } - /// Create subgizmos for rotation - fn new_rotation(&self) -> [SubGizmo; 4] { + fn new_rotation(&self) -> [RotationSubGizmo; 4] { [ - SubGizmo::new( + RotationSubGizmo::new( self.id.with("rx"), self.config, GizmoDirection::X, - SubGizmoKind::RotationAxis, + TransformKind::Axis, ), - SubGizmo::new( + RotationSubGizmo::new( self.id.with("ry"), self.config, GizmoDirection::Y, - SubGizmoKind::RotationAxis, + TransformKind::Axis, ), - SubGizmo::new( + RotationSubGizmo::new( self.id.with("rz"), self.config, GizmoDirection::Z, - SubGizmoKind::RotationAxis, + TransformKind::Axis, ), - SubGizmo::new( + RotationSubGizmo::new( self.id.with("rs"), self.config, GizmoDirection::Screen, - SubGizmoKind::RotationAxis, + TransformKind::Axis, ), ] } /// Create subgizmos for translation - fn new_translation(&self) -> [SubGizmo; 6] { + fn new_translation(&self) -> [TranslationSubGizmo; 6] { [ - SubGizmo::new( + TranslationSubGizmo::new( self.id.with("tx"), self.config, GizmoDirection::X, - SubGizmoKind::TranslationVector, + TransformKind::Axis, ), - SubGizmo::new( + TranslationSubGizmo::new( self.id.with("ty"), self.config, GizmoDirection::Y, - SubGizmoKind::TranslationVector, + TransformKind::Axis, ), - SubGizmo::new( + TranslationSubGizmo::new( self.id.with("tz"), self.config, GizmoDirection::Z, - SubGizmoKind::TranslationVector, + TransformKind::Axis, ), - SubGizmo::new( + TranslationSubGizmo::new( self.id.with("tyz"), self.config, GizmoDirection::X, - SubGizmoKind::TranslationPlane, + TransformKind::Plane, ), - SubGizmo::new( + TranslationSubGizmo::new( self.id.with("txz"), self.config, GizmoDirection::Y, - SubGizmoKind::TranslationPlane, + TransformKind::Plane, ), - SubGizmo::new( + TranslationSubGizmo::new( self.id.with("txy"), self.config, GizmoDirection::Z, - SubGizmoKind::TranslationPlane, + TransformKind::Plane, ), ] } /// Create subgizmos for scale - fn new_scale(&self) -> [SubGizmo; 6] { + fn new_scale(&self) -> [ScaleSubGizmo; 6] { [ - SubGizmo::new( + ScaleSubGizmo::new( self.id.with("sx"), self.config, GizmoDirection::X, - SubGizmoKind::ScaleVector, + TransformKind::Axis, ), - SubGizmo::new( + ScaleSubGizmo::new( self.id.with("sy"), self.config, GizmoDirection::Y, - SubGizmoKind::ScaleVector, + TransformKind::Axis, ), - SubGizmo::new( + ScaleSubGizmo::new( self.id.with("sz"), self.config, GizmoDirection::Z, - SubGizmoKind::ScaleVector, + TransformKind::Axis, ), - SubGizmo::new( + ScaleSubGizmo::new( self.id.with("syz"), self.config, GizmoDirection::X, - SubGizmoKind::ScalePlane, + TransformKind::Plane, ), - SubGizmo::new( + ScaleSubGizmo::new( self.id.with("sxz"), self.config, GizmoDirection::Y, - SubGizmoKind::ScalePlane, + TransformKind::Plane, ), - SubGizmo::new( + ScaleSubGizmo::new( self.id.with("sxy"), self.config, GizmoDirection::Z, - SubGizmoKind::ScalePlane, + TransformKind::Plane, ), ] } /// Add given subgizmos to this gizmo - fn add_subgizmos(&mut self, subgizmos: [SubGizmo; N]) { - let mut i = self.subgizmo_count; - for subgizmo in subgizmos.into_iter() { - self.subgizmos[i] = Some(subgizmo); - i += 1; + fn add_subgizmos(&mut self, subgizmos: [T; N]) { + for subgizmo in subgizmos { + self.subgizmos.push(Box::new(subgizmo)); } - - self.subgizmo_count = i; } /// Calculate a world space ray from current mouse position @@ -566,6 +544,11 @@ impl GizmoConfig { self.view_matrix.row(2).xyz() } + /// Up vector of the view camera + pub(crate) fn view_up(&self) -> DVec3 { + self.view_matrix.row(1).xyz() + } + /// Right vector of the view camera pub(crate) fn view_right(&self) -> DVec3 { self.view_matrix.row(0).xyz() @@ -573,7 +556,7 @@ impl GizmoConfig { /// Whether local orientation is used pub(crate) fn local_space(&self) -> bool { - self.orientation == GizmoOrientation::Local + self.orientation == GizmoOrientation::Local || self.mode == GizmoMode::Scale } } diff --git a/src/math.rs b/src/math.rs index a0103cd..3a61989 100644 --- a/src/math.rs +++ b/src/math.rs @@ -3,7 +3,7 @@ use glam::{DMat3, DMat4, DVec3, DVec4, Vec4Swizzles}; /// Creates a matrix that represents rotation between two 3d vectors /// -/// Credit: https://www.iquilezles.org/www/articles/noacos/noacos.htm +/// Credit: pub fn rotation_align(from: DVec3, to: DVec3) -> DMat3 { let v = from.cross(to); let c = from.dot(to); @@ -25,7 +25,7 @@ pub fn rotation_align(from: DVec3, to: DVec3) -> DMat3 { /// Finds points on two rays that are closest to each other. /// This can be used to determine the shortest distance between those two rays. /// -/// Credit: Practical Geometry Algorithms by Daniel Sunday: http://geomalgorithms.com/code.html +/// Credit: Practical Geometry Algorithms by Daniel Sunday: pub fn ray_to_ray(a1: DVec3, adir: DVec3, b1: DVec3, bdir: DVec3) -> (f64, f64) { let b = adir.dot(bdir); let w = a1 - b1; @@ -49,7 +49,7 @@ pub fn ray_to_ray(a1: DVec3, adir: DVec3, b1: DVec3, bdir: DVec3) -> (f64, f64) /// Finds points on two segments that are closest to each other. /// This can be used to determine the shortest distance between those two segments. /// -/// Credit: Practical Geometry Algorithms by Daniel Sunday: http://geomalgorithms.com/code.html +/// Credit: Practical Geometry Algorithms by Daniel Sunday: pub fn segment_to_segment(a1: DVec3, a2: DVec3, b1: DVec3, b2: DVec3) -> (f64, f64) { let da = a2 - a1; let db = b2 - b1; @@ -159,7 +159,7 @@ pub fn round_to_interval(val: f64, interval: f64) -> f64 { pub fn world_to_screen(viewport: Rect, mvp: DMat4, pos: DVec3) -> Option { let mut pos = mvp * DVec4::from((pos, 1.0)); - if pos.w < 0.0 { + if pos.w < 1e-10 { return None; } @@ -188,5 +188,5 @@ pub fn screen_to_world(viewport: Rect, mat: DMat4, pos: Pos2, z: f64) -> DVec3 { world_pos /= world_pos.w; - return world_pos.xyz(); + world_pos.xyz() } diff --git a/src/painter.rs b/src/painter.rs index 580dd4a..d40f2ab 100644 --- a/src/painter.rs +++ b/src/painter.rs @@ -30,12 +30,26 @@ impl Painter3d { end_angle: f64, stroke: impl Into, ) -> ShapeIdx { - let angle = end_angle - start_angle; - let step_count = steps(angle); + let mut closed = false; + let mut angle = end_angle - start_angle; + + if angle <= -TAU { + angle = -TAU; + closed = true; + } else if angle >= TAU { + angle = TAU; + closed = true; + } + + let mut step_count = steps(angle); let mut points = Vec::with_capacity(step_count); let step_size = angle / (step_count - 1) as f64; + if closed { + step_count -= 1; + } + for step in (0..step_count).map(|i| step_size * i as f64) { let x = f64::cos(start_angle + step) * radius; let z = f64::sin(start_angle + step) * radius; @@ -48,7 +62,11 @@ impl Painter3d { .filter_map(|point| self.vec3_to_pos2(point)) .collect::>(); - self.painter.add(Shape::line(points, stroke)) + self.painter.add(if closed { + Shape::closed_line(points, stroke) + } else { + Shape::line(points, stroke) + }) } pub fn circle(&self, radius: f64, stroke: impl Into) -> ShapeIdx { diff --git a/src/rotation.rs b/src/rotation.rs deleted file mode 100644 index 6096c2f..0000000 --- a/src/rotation.rs +++ /dev/null @@ -1,249 +0,0 @@ -use std::f64::consts::{FRAC_PI_2, PI, TAU}; - -use egui::Ui; -use glam::{DMat4, DQuat, DVec2, DVec3}; - -use crate::math::{ray_to_plane_origin, rotation_align, round_to_interval, world_to_screen}; -use crate::painter::Painter3d; -use crate::subgizmo::SubGizmo; -use crate::{GizmoDirection, GizmoMode, GizmoResult, Ray, WidgetData}; - -/// Picks given rotation subgizmo. If the subgizmo is close enough to -/// the mouse pointer, distance from camera to the subgizmo is returned. -pub(crate) fn pick_rotation(subgizmo: &SubGizmo, ui: &Ui, ray: Ray) -> Option { - let radius = arc_radius(subgizmo) as f64; - let config = subgizmo.config; - let origin = config.translation; - let normal = subgizmo.normal(); - let tangent = tangent(subgizmo); - - let (t, dist_from_gizmo_origin) = - ray_to_plane_origin(normal, origin, ray.origin, ray.direction); - let dist_from_gizmo_edge = (dist_from_gizmo_origin - radius).abs(); - - let hit_pos = ray.origin + ray.direction * t; - let dir_to_origin = (origin - hit_pos).normalize(); - let nearest_circle_pos = hit_pos + dir_to_origin * (dist_from_gizmo_origin - radius); - - let offset = (nearest_circle_pos - origin).normalize(); - - let angle = if subgizmo.direction == GizmoDirection::Screen { - f64::atan2(tangent.cross(normal).dot(offset), tangent.dot(offset)) - } else { - let mut forward = config.view_forward(); - if config.left_handed { - forward *= -1.0; - } - f64::atan2(offset.cross(forward).dot(normal), offset.dot(forward)) - }; - - subgizmo.update_state_with(ui, |state: &mut RotationState| { - let rotation_angle = rotation_angle(subgizmo, ui).unwrap_or(0.0); - state.start_axis_angle = angle as f32; - state.start_rotation_angle = rotation_angle as f32; - state.last_rotation_angle = rotation_angle as f32; - state.current_delta = 0.0; - }); - - if dist_from_gizmo_edge <= config.focus_distance as f64 && angle.abs() < arc_angle(subgizmo) { - Some(t) - } else { - None - } -} - -pub(crate) fn draw_rotation(subgizmo: &SubGizmo, ui: &Ui) { - let state = subgizmo.state::(ui); - let config = subgizmo.config; - - let transform = rotation_matrix(subgizmo); - let painter = Painter3d::new( - ui.painter().clone(), - config.view_projection * transform, - config.viewport, - ); - - let color = subgizmo.color(); - let stroke = (config.visuals.stroke_width, color); - - let radius = arc_radius(subgizmo) as f64; - - if !subgizmo.active { - let angle = arc_angle(subgizmo); - painter.arc(radius, FRAC_PI_2 - angle, FRAC_PI_2 + angle, stroke); - } else { - let start_angle = state.start_axis_angle as f64 + FRAC_PI_2; - let end_angle = start_angle + state.current_delta as f64; - - // The polyline does not get rendered correctly if - // the start and end lines are exactly the same - let end_angle = end_angle + 1e-5; - - painter.polyline( - &[ - DVec3::new(start_angle.cos() * radius, 0.0, start_angle.sin() * radius), - DVec3::new(0.0, 0.0, 0.0), - DVec3::new(end_angle.cos() * radius, 0.0, end_angle.sin() * radius), - ], - stroke, - ); - - painter.circle(radius, stroke); - - // Draw snapping ticks - if config.snapping { - let stroke_width = stroke.0 / 2.0; - for i in 0..((TAU / config.snap_angle as f64) as usize + 1) { - let angle = i as f64 * config.snap_angle as f64 + end_angle; - let pos = DVec3::new(angle.cos(), 0.0, angle.sin()); - painter.line_segment( - pos * radius * 1.1, - pos * radius * 1.2, - (stroke_width, stroke.1), - ); - } - } - } -} - -/// Updates given rotation subgizmo. -/// If the subgizmo is active, returns the rotation result. -pub(crate) fn update_rotation(subgizmo: &SubGizmo, ui: &Ui, _ray: Ray) -> Option { - let state = subgizmo.state::(ui); - let config = subgizmo.config; - - let mut rotation_angle = rotation_angle(subgizmo, ui)?; - if config.snapping { - rotation_angle = round_to_interval( - rotation_angle - state.start_rotation_angle as f64, - config.snap_angle as f64, - ) + state.start_rotation_angle as f64; - } - - let mut angle_delta = rotation_angle - state.last_rotation_angle as f64; - - // Always take the smallest angle, e.g. -10° instead of 350° - if angle_delta > PI { - angle_delta -= TAU; - } else if angle_delta < -PI { - angle_delta += TAU; - } - - subgizmo.update_state_with(ui, |state: &mut RotationState| { - state.last_rotation_angle = rotation_angle as f32; - state.current_delta += angle_delta as f32; - }); - - let new_rotation = - DQuat::from_axis_angle(subgizmo.normal(), -angle_delta) * subgizmo.config.rotation; - - Some(GizmoResult { - scale: subgizmo.config.scale.as_vec3().into(), - rotation: new_rotation.as_f32().into(), - translation: subgizmo.config.translation.as_vec3().into(), - mode: GizmoMode::Rotate, - value: (subgizmo.normal().as_vec3() * state.current_delta).to_array(), - }) -} - -/// Calculates angle of the rotation axis arc. -/// The arc is a semicircle, which turns into a full circle when viewed -/// directly from the front. -fn arc_angle(subgizmo: &SubGizmo) -> f64 { - let dot = subgizmo.normal().dot(subgizmo.config.view_forward()).abs(); - let min_dot = 0.990; - let max_dot = 0.995; - - f64::min(1.0, f64::max(0.0, dot - min_dot) / (max_dot - min_dot)) * FRAC_PI_2 + FRAC_PI_2 -} - -/// Calculates a matrix used when rendering the rotation axis. -fn rotation_matrix(subgizmo: &SubGizmo) -> DMat4 { - // First rotate towards the gizmo normal - let local_normal = subgizmo.local_normal(); - let rotation = rotation_align(DVec3::Y, local_normal); - let mut rotation = DQuat::from_mat3(&rotation); - let config = subgizmo.config; - - // TODO optimize this. Use same code for all axes if possible. - - if subgizmo.direction != GizmoDirection::Screen { - if config.local_space() { - rotation = config.rotation * rotation; - } - - let tangent = tangent(subgizmo); - let normal = subgizmo.normal(); - let mut forward = config.view_forward(); - if config.left_handed { - forward *= -1.0; - } - let angle = f64::atan2(tangent.cross(forward).dot(normal), tangent.dot(forward)); - - // Rotate towards the camera, along the rotation axis. - rotation = DQuat::from_axis_angle(normal, angle) * rotation; - } else { - let angle = f64::atan2(local_normal.x, local_normal.z) + FRAC_PI_2; - rotation = DQuat::from_axis_angle(local_normal, angle) * rotation; - } - - DMat4::from_rotation_translation(rotation, config.translation) -} - -fn rotation_angle(subgizmo: &SubGizmo, ui: &Ui) -> Option { - let cursor_pos = ui.input(|i| i.pointer.hover_pos())?; - let viewport = subgizmo.config.viewport; - let gizmo_pos = world_to_screen(viewport, subgizmo.config.mvp, DVec3::new(0.0, 0.0, 0.0))?; - let delta = DVec2::new( - cursor_pos.x as f64 - gizmo_pos.x as f64, - cursor_pos.y as f64 - gizmo_pos.y as f64, - ) - .normalize(); - - if delta.is_nan() { - return None; - } - - let mut angle = f64::atan2(delta.y, delta.x); - if subgizmo.config.view_forward().dot(subgizmo.normal()) < 0.0 { - angle *= -1.0; - } - - Some(angle) -} - -fn tangent(subgizmo: &SubGizmo) -> DVec3 { - let mut tangent = match subgizmo.direction { - GizmoDirection::X => DVec3::Z, - GizmoDirection::Y => DVec3::Z, - GizmoDirection::Z => -DVec3::Y, - GizmoDirection::Screen => -subgizmo.config.view_right(), - }; - - if subgizmo.config.local_space() && subgizmo.direction != GizmoDirection::Screen { - tangent = subgizmo.config.rotation * tangent; - } - - tangent -} - -fn arc_radius(subgizmo: &SubGizmo) -> f32 { - let mut radius = subgizmo.config.visuals.gizmo_size; - - if subgizmo.direction == GizmoDirection::Screen { - // Screen axis should be a little bit larger - radius += subgizmo.config.visuals.stroke_width + 5.0; - } - - subgizmo.config.scale_factor * radius -} - -#[derive(Default, Debug, Copy, Clone)] -struct RotationState { - start_axis_angle: f32, - start_rotation_angle: f32, - last_rotation_angle: f32, - current_delta: f32, -} - -impl WidgetData for RotationState {} diff --git a/src/scale.rs b/src/scale.rs deleted file mode 100644 index 50ce176..0000000 --- a/src/scale.rs +++ /dev/null @@ -1,241 +0,0 @@ -use egui::{Stroke, Ui}; -use glam::{DMat4, DVec3}; -use std::ops::RangeInclusive; - -use crate::math::{ray_to_plane_origin, round_to_interval, segment_to_segment, world_to_screen}; -use crate::painter::Painter3d; -use crate::subgizmo::SubGizmo; -use crate::translation::{ - translation_plane_binormal, translation_plane_local_origin, translation_plane_size, - translation_plane_tangent, -}; -use crate::{GizmoMode, GizmoResult, Ray, WidgetData}; - -const ARROW_FADE: RangeInclusive = (0.95)..=(0.99); -const PLANE_FADE: RangeInclusive = (0.70)..=(0.86); - -/// Picks given scale subgizmo. If the subgizmo is close enough to -/// the mouse pointer, distance from camera to the subgizmo is returned. -pub(crate) fn pick_scale(subgizmo: &SubGizmo, ui: &Ui, ray: Ray) -> Option { - let origin = subgizmo.config.translation; - let dir = subgizmo.config.rotation * subgizmo.local_normal(); - let scale = subgizmo.config.scale_factor * subgizmo.config.visuals.gizmo_size; - let length = scale as f64; - - let ray_length = 1e+14; - - let (ray_t, subgizmo_t) = segment_to_segment( - ray.origin, - ray.origin + ray.direction * ray_length, - origin, - origin + dir * length, - ); - - let ray_point = ray.origin + ray.direction * ray_length * ray_t; - let subgizmo_point = origin + dir * length * subgizmo_t; - let dist = (ray_point - subgizmo_point).length(); - - let start_delta = distance_from_origin_2d(subgizmo, ui)?; - - let dot = subgizmo - .config - .gizmo_view_forward - .dot(subgizmo.normal()) - .abs(); - let visibility = - (1.0 - (dot - *ARROW_FADE.start()) / (*ARROW_FADE.end() - *ARROW_FADE.start())).min(1.0); - - subgizmo.update_state_with(ui, |state: &mut ScaleState| { - state.start_scale = subgizmo.config.scale; - state.start_delta = start_delta; - state.visibility = visibility as _; - }); - - if visibility > 0.0 && dist <= subgizmo.config.focus_distance as f64 { - Some(ray.origin.distance(ray_point)) - } else { - None - } -} - -pub(crate) fn draw_scale(subgizmo: &SubGizmo, ui: &Ui) { - let state = subgizmo.state::(ui); - - if state.visibility <= 0.0001 { - return; - } - - let color = subgizmo.color().gamma_multiply(state.visibility); - - let painter = Painter3d::new( - ui.painter().clone(), - subgizmo.config.view_projection * scale_transform(subgizmo), - subgizmo.config.viewport, - ); - - let direction = subgizmo.local_normal(); - - let width = subgizmo.config.scale_factor * subgizmo.config.visuals.stroke_width; - let length = subgizmo.config.scale_factor * subgizmo.config.visuals.gizmo_size; - let end_stroke_width = subgizmo.config.visuals.stroke_width * 2.5; - let end_length = subgizmo.config.scale_factor * end_stroke_width; - let length = length - end_length; - - let start = direction * width as f64; - let end = direction * length as f64; - - painter.line_segment(start, end, (subgizmo.config.visuals.stroke_width, color)); - painter.line_segment( - end, - end + direction * end_length as f64, - (end_stroke_width, color), - ); -} - -/// Updates given scale subgizmo. -/// If the subgizmo is active, returns the scale result. -pub(crate) fn update_scale(subgizmo: &SubGizmo, ui: &Ui, _ray: Ray) -> Option { - let state = subgizmo.state::(ui); - - let mut delta = distance_from_origin_2d(subgizmo, ui)?; - delta /= state.start_delta; - - if subgizmo.config.snapping { - delta = round_to_interval(delta, subgizmo.config.snap_scale as f64); - } - delta = delta.max(1e-4) - 1.0; - - let offset = DVec3::ONE + (subgizmo.local_normal() * delta); - - let new_scale = state.start_scale * offset; - - Some(GizmoResult { - scale: new_scale.as_vec3().into(), - rotation: subgizmo.config.rotation.as_f32().into(), - translation: subgizmo.config.translation.as_vec3().into(), - mode: GizmoMode::Scale, - value: offset.as_vec3().to_array(), - }) -} - -/// Picks given scale plane subgizmo. If the subgizmo is close enough to -/// the mouse pointer, distance from camera to the subgizmo is returned. -pub(crate) fn pick_scale_plane(subgizmo: &SubGizmo, ui: &Ui, ray: Ray) -> Option { - let origin = scale_plane_global_origin(subgizmo); - - let normal = subgizmo.normal(); - - let (t, dist_from_origin) = ray_to_plane_origin(normal, origin, ray.origin, ray.direction); - - let start_delta = distance_from_origin_2d(subgizmo, ui)?; - - let dot = subgizmo - .config - .gizmo_view_forward - .dot(subgizmo.normal()) - .abs(); - let visibility = (1.0 - - ((1.0 - dot) - *PLANE_FADE.start()) / (*PLANE_FADE.end() - *PLANE_FADE.start())) - .min(1.0); - - subgizmo.update_state_with(ui, |state: &mut ScaleState| { - state.start_scale = subgizmo.config.scale; - state.start_delta = start_delta; - state.visibility = visibility as _; - }); - - if visibility > 0.0 && dist_from_origin <= translation_plane_size(subgizmo) { - Some(t) - } else { - None - } -} - -/// Updates given scale plane subgizmo. -/// If the subgizmo is active, returns the scale result. -pub(crate) fn update_scale_plane(subgizmo: &SubGizmo, ui: &Ui, _ray: Ray) -> Option { - let state = subgizmo.state::(ui); - - let mut delta = distance_from_origin_2d(subgizmo, ui)?; - delta /= state.start_delta; - - if subgizmo.config.snapping { - delta = round_to_interval(delta, subgizmo.config.snap_scale as f64); - } - delta = delta.max(1e-4) - 1.0; - - let binormal = translation_plane_binormal(subgizmo.direction); - let tangent = translation_plane_tangent(subgizmo.direction); - let direction = (binormal + tangent).normalize(); - - let offset = DVec3::ONE + (direction * delta); - - let new_scale = state.start_scale * offset; - - Some(GizmoResult { - scale: new_scale.as_vec3().into(), - rotation: subgizmo.config.rotation.as_f32().into(), - translation: subgizmo.config.translation.as_vec3().into(), - mode: GizmoMode::Scale, - value: offset.as_vec3().to_array(), - }) -} - -pub(crate) fn draw_scale_plane(subgizmo: &SubGizmo, ui: &Ui) { - let state = subgizmo.state::(ui); - - if state.visibility <= 0.0001 { - return; - } - - let color = subgizmo.color().gamma_multiply(state.visibility); - - let painter = Painter3d::new( - ui.painter().clone(), - subgizmo.config.view_projection * scale_transform(subgizmo), - subgizmo.config.viewport, - ); - - let scale = translation_plane_size(subgizmo) * 0.5; - let a = translation_plane_binormal(subgizmo.direction) * scale; - let b = translation_plane_tangent(subgizmo.direction) * scale; - - let origin = translation_plane_local_origin(subgizmo); - - painter.polygon( - &[ - origin - b - a, - origin + b - a, - origin + b + a, - origin - b + a, - ], - color, - Stroke::NONE, - ); -} - -#[derive(Default, Debug, Copy, Clone)] -pub(crate) struct ScaleState { - start_scale: DVec3, - start_delta: f64, - visibility: f32, -} - -impl WidgetData for ScaleState {} - -fn scale_transform(subgizmo: &SubGizmo) -> DMat4 { - DMat4::from_rotation_translation(subgizmo.config.rotation, subgizmo.config.translation) -} - -pub(crate) fn scale_plane_global_origin(subgizmo: &SubGizmo) -> DVec3 { - let origin = translation_plane_local_origin(subgizmo); - subgizmo.config.rotation * origin + subgizmo.config.translation -} - -fn distance_from_origin_2d(subgizmo: &SubGizmo, ui: &Ui) -> Option { - let cursor_pos = ui.input(|i| i.pointer.hover_pos())?; - let viewport = subgizmo.config.viewport; - let gizmo_pos = world_to_screen(viewport, subgizmo.config.mvp, DVec3::new(0.0, 0.0, 0.0))?; - - Some(cursor_pos.distance(gizmo_pos) as f64) -} diff --git a/src/subgizmo.rs b/src/subgizmo.rs index a89f045..d6d6237 100644 --- a/src/subgizmo.rs +++ b/src/subgizmo.rs @@ -1,44 +1,109 @@ use std::hash::Hash; +use std::marker::PhantomData; use egui::{Color32, Id, Ui}; use glam::DVec3; -use crate::rotation::{draw_rotation, pick_rotation, update_rotation}; -use crate::scale::{ - draw_scale, draw_scale_plane, pick_scale, pick_scale_plane, update_scale, update_scale_plane, -}; -use crate::translation::{ - draw_translation, draw_translation_plane, pick_translation, pick_translation_plane, - update_translation, update_translation_plane, -}; use crate::{GizmoConfig, GizmoDirection, GizmoResult, Ray, WidgetData}; -#[derive(Copy, Clone, Debug)] -pub(crate) struct SubGizmo { - pub(crate) id: Id, +pub(crate) use rotation::RotationSubGizmo; +pub(crate) use scale::ScaleSubGizmo; +pub(crate) use translation::TranslationSubGizmo; + +mod common; +mod rotation; +mod scale; +mod translation; + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub(crate) enum TransformKind { + Axis, + Plane, +} + +pub(crate) trait SubGizmoState: Default + Copy + Clone + Send + Sync + 'static {} +impl WidgetData for T where T: SubGizmoState {} + +pub(crate) struct SubGizmoConfig { + id: Id, pub(crate) config: GizmoConfig, pub(crate) direction: GizmoDirection, - pub(crate) kind: SubGizmoKind, + pub(crate) transform_kind: TransformKind, /// Whether this subgizmo is focused this frame pub(crate) focused: bool, /// Whether this subgizmo is active this frame pub(crate) active: bool, + /// Opacity of the subgizmo for this frame. + /// A fully invisible subgizmo cannot be interacted with. + pub(crate) opacity: f32, + + _phantom: PhantomData, +} + +pub(crate) trait SubGizmoBase: 'static { + /// Identifier for this subgizmo. It should be unique across all subgizmos. + fn id(&self) -> Id; + /// Sets whether this subgizmo is currently focused + fn set_focused(&mut self, focused: bool); + /// Sets whether this subgizmo is currently active + fn set_active(&mut self, active: bool); + /// Returns true if this subgizmo is currently focused + fn is_focused(&self) -> bool; + /// Returns true if this subgizmo is currently active + fn is_active(&self) -> bool; +} + +impl SubGizmoBase for SubGizmoConfig { + fn id(&self) -> Id { + self.id + } + + fn set_focused(&mut self, focused: bool) { + self.focused = focused; + } + + fn set_active(&mut self, active: bool) { + self.active = active; + } + + fn is_focused(&self) -> bool { + self.focused + } + + fn is_active(&self) -> bool { + self.active + } +} + +pub(crate) trait SubGizmo: SubGizmoBase { + /// Pick the subgizmo based on pointer ray. If it is close enough to + /// the mouse pointer, distance from camera to the subgizmo is returned. + fn pick(&mut self, ui: &Ui, ray: Ray) -> Option; + /// Update the subgizmo based on pointer ray and interaction. + fn update(&mut self, ui: &Ui, ray: Ray) -> Option; + /// Draw the subgizmo + fn draw(&self, ui: &Ui); } -impl SubGizmo { +impl SubGizmoConfig +where + T: SubGizmoState, +{ pub fn new( id_source: impl Hash, config: GizmoConfig, direction: GizmoDirection, - kind: SubGizmoKind, + transform_kind: TransformKind, ) -> Self { Self { id: Id::new(id_source), config, direction, - kind, + transform_kind, focused: false, active: false, + opacity: 0.0, + _phantom: Default::default(), } } @@ -84,59 +149,13 @@ impl SubGizmo { color.linear_multiply(alpha) } - pub fn state(&self, ui: &Ui) -> T { - T::load(ui.ctx(), self.id) + pub fn state(&self, ui: &Ui) -> T { + <_ as WidgetData>::load(ui.ctx(), self.id) } - pub fn update_state_with(&self, ui: &Ui, fun: impl FnOnce(&mut T)) { - let mut state = self.state::(ui); + pub fn update_state_with(&self, ui: &Ui, fun: impl FnOnce(&mut T)) { + let mut state = self.state(ui); fun(&mut state); state.save(ui.ctx(), self.id); } - - pub fn pick(&self, ui: &Ui, ray: Ray) -> Option { - match self.kind { - SubGizmoKind::RotationAxis => pick_rotation(self, ui, ray), - SubGizmoKind::TranslationVector => pick_translation(self, ui, ray), - SubGizmoKind::TranslationPlane => pick_translation_plane(self, ui, ray), - SubGizmoKind::ScaleVector => pick_scale(self, ui, ray), - SubGizmoKind::ScalePlane => pick_scale_plane(self, ui, ray), - } - } - - /// Update this subgizmo based on pointer ray and interaction. - pub fn update(&self, ui: &Ui, ray: Ray) -> Option { - match self.kind { - SubGizmoKind::RotationAxis => update_rotation(self, ui, ray), - SubGizmoKind::TranslationVector => update_translation(self, ui, ray), - SubGizmoKind::TranslationPlane => update_translation_plane(self, ui, ray), - SubGizmoKind::ScaleVector => update_scale(self, ui, ray), - SubGizmoKind::ScalePlane => update_scale_plane(self, ui, ray), - } - } - - /// Draw this subgizmo - pub fn draw(&self, ui: &Ui) { - match self.kind { - SubGizmoKind::RotationAxis => draw_rotation(self, ui), - SubGizmoKind::TranslationVector => draw_translation(self, ui), - SubGizmoKind::TranslationPlane => draw_translation_plane(self, ui), - SubGizmoKind::ScaleVector => draw_scale(self, ui), - SubGizmoKind::ScalePlane => draw_scale_plane(self, ui), - } - } -} - -#[derive(Copy, Clone, Debug)] -pub(crate) enum SubGizmoKind { - /// Rotation around an axis - RotationAxis, - /// Translation along a vector - TranslationVector, - /// Translation along a plane - TranslationPlane, - /// Scale along a vector - ScaleVector, - /// Scale along a plane - ScalePlane, } diff --git a/src/subgizmo/common.rs b/src/subgizmo/common.rs new file mode 100644 index 0000000..59a3445 --- /dev/null +++ b/src/subgizmo/common.rs @@ -0,0 +1,203 @@ +use crate::math::{ray_to_plane_origin, segment_to_segment}; +use egui::{Stroke, Ui}; +use std::ops::RangeInclusive; + +use crate::painter::Painter3d; +use crate::subgizmo::{SubGizmoConfig, SubGizmoState}; +use crate::{GizmoDirection, GizmoMode, Ray}; +use glam::{DMat4, DVec3}; + +const ARROW_FADE: RangeInclusive = 0.95..=0.99; +const PLANE_FADE: RangeInclusive = 0.70..=0.86; + +#[derive(Debug, Copy, Clone)] +pub(crate) struct PickResult { + pub subgizmo_point: DVec3, + pub visibility: f64, + pub picked: bool, + pub t: f64, +} + +pub(crate) fn pick_arrow(subgizmo: &SubGizmoConfig, ray: Ray) -> PickResult { + let origin = subgizmo.config.translation; + let dir = subgizmo.normal(); + let length = (subgizmo.config.scale_factor * subgizmo.config.visuals.gizmo_size) as f64; + + let ray_length = 1e+14; + + let (ray_t, subgizmo_t) = segment_to_segment( + ray.origin, + ray.origin + ray.direction * ray_length, + origin, + origin + dir * length, + ); + + let ray_point = ray.origin + ray.direction * ray_length * ray_t; + let subgizmo_point = origin + dir * length * subgizmo_t; + let dist = (ray_point - subgizmo_point).length(); + + let dot = subgizmo.config.gizmo_view_forward.dot(dir).abs(); + + let visibility = + (1.0 - (dot - *ARROW_FADE.start()) / (*ARROW_FADE.end() - *ARROW_FADE.start())).min(1.0); + + let picked = visibility > 0.0 && dist <= subgizmo.config.focus_distance as f64; + + PickResult { + subgizmo_point, + visibility, + picked, + t: ray_t, + } +} + +pub(crate) fn pick_plane(subgizmo: &SubGizmoConfig, ray: Ray) -> PickResult { + let origin = plane_global_origin(subgizmo); + + let normal = subgizmo.normal(); + + let (t, dist_from_origin) = ray_to_plane_origin(normal, origin, ray.origin, ray.direction); + + let ray_point = ray.origin + ray.direction * t; + + let dot = subgizmo + .config + .gizmo_view_forward + .dot(subgizmo.normal()) + .abs(); + let visibility = (1.0 + - ((1.0 - dot) - *PLANE_FADE.start()) / (*PLANE_FADE.end() - *PLANE_FADE.start())) + .min(1.0); + + let picked = visibility > 0.0 && dist_from_origin <= plane_size(subgizmo); + + PickResult { + subgizmo_point: ray_point, + visibility, + picked, + t, + } +} + +pub(crate) fn draw_arrow(subgizmo: &SubGizmoConfig, ui: &Ui) { + if subgizmo.opacity <= 0.0001 { + return; + } + + let color = subgizmo.color().gamma_multiply(subgizmo.opacity); + + let transform = if subgizmo.config.local_space() { + DMat4::from_rotation_translation(subgizmo.config.rotation, subgizmo.config.translation) + } else { + DMat4::from_translation(subgizmo.config.translation) + }; + + let painter = Painter3d::new( + ui.painter().clone(), + subgizmo.config.view_projection * transform, + subgizmo.config.viewport, + ); + + let direction = subgizmo.local_normal(); + let width = subgizmo.config.scale_factor * subgizmo.config.visuals.stroke_width; + let length = subgizmo.config.scale_factor * subgizmo.config.visuals.gizmo_size; + + let start = direction * width as f64; + let end = direction * length as f64; + painter.line_segment(start, end, (subgizmo.config.visuals.stroke_width, color)); + + if subgizmo.config.mode == GizmoMode::Scale { + let end_stroke_width = subgizmo.config.visuals.stroke_width * 2.5; + let end_length = subgizmo.config.scale_factor * end_stroke_width; + + painter.line_segment( + end, + end + direction * end_length as f64, + (end_stroke_width, color), + ); + } else { + let arrow_length = width * 2.4; + + painter.arrow( + end, + end + direction * arrow_length as f64, + (subgizmo.config.visuals.stroke_width * 1.2, color), + ); + } +} + +pub(crate) fn draw_plane(subgizmo: &SubGizmoConfig, ui: &Ui) { + if subgizmo.opacity <= 0.0001 { + return; + } + + let color = subgizmo.color().gamma_multiply(subgizmo.opacity); + + let transform = if subgizmo.config.local_space() { + DMat4::from_rotation_translation(subgizmo.config.rotation, subgizmo.config.translation) + } else { + DMat4::from_translation(subgizmo.config.translation) + }; + + let painter = Painter3d::new( + ui.painter().clone(), + subgizmo.config.view_projection * transform, + subgizmo.config.viewport, + ); + + let scale = plane_size(subgizmo) * 0.5; + let a = plane_binormal(subgizmo.direction) * scale; + let b = plane_tangent(subgizmo.direction) * scale; + let origin = plane_local_origin(subgizmo); + + painter.polygon( + &[ + origin - b - a, + origin + b - a, + origin + b + a, + origin - b + a, + ], + color, + Stroke::NONE, + ); +} + +pub(crate) fn plane_binormal(direction: GizmoDirection) -> DVec3 { + match direction { + GizmoDirection::X => DVec3::Y, + GizmoDirection::Y => DVec3::Z, + GizmoDirection::Z => DVec3::X, + GizmoDirection::Screen => DVec3::ZERO, // Unused + } +} + +pub(crate) fn plane_tangent(direction: GizmoDirection) -> DVec3 { + match direction { + GizmoDirection::X => DVec3::Z, + GizmoDirection::Y => DVec3::X, + GizmoDirection::Z => DVec3::Y, + GizmoDirection::Screen => DVec3::ZERO, // Unused + } +} + +pub(crate) fn plane_size(subgizmo: &SubGizmoConfig) -> f64 { + (subgizmo.config.scale_factor + * (subgizmo.config.visuals.gizmo_size * 0.1 + subgizmo.config.visuals.stroke_width * 2.0)) + as f64 +} + +pub(crate) fn plane_local_origin(subgizmo: &SubGizmoConfig) -> DVec3 { + let offset = subgizmo.config.scale_factor * subgizmo.config.visuals.gizmo_size * 0.4; + + let a = plane_binormal(subgizmo.direction); + let b = plane_tangent(subgizmo.direction); + (a + b) * offset as f64 +} + +pub(crate) fn plane_global_origin(subgizmo: &SubGizmoConfig) -> DVec3 { + let mut origin = plane_local_origin(subgizmo); + if subgizmo.config.local_space() { + origin = subgizmo.config.rotation * origin; + } + origin + subgizmo.config.translation +} diff --git a/src/subgizmo/rotation.rs b/src/subgizmo/rotation.rs new file mode 100644 index 0000000..051d5e6 --- /dev/null +++ b/src/subgizmo/rotation.rs @@ -0,0 +1,256 @@ +use std::f64::consts::{FRAC_PI_2, PI, TAU}; + +use egui::Ui; +use glam::{DMat3, DMat4, DQuat, DVec2, DVec3}; + +use crate::math::{ray_to_plane_origin, rotation_align, round_to_interval, world_to_screen}; +use crate::painter::Painter3d; +use crate::subgizmo::{SubGizmo, SubGizmoConfig, SubGizmoState}; +use crate::{GizmoDirection, GizmoMode, GizmoResult, Ray}; + +pub(crate) type RotationSubGizmo = SubGizmoConfig; + +impl SubGizmo for RotationSubGizmo { + fn pick(&mut self, ui: &Ui, ray: Ray) -> Option { + let radius = arc_radius(self) as f64; + let config = self.config; + let origin = config.translation; + let normal = self.normal(); + let tangent = tangent(self); + + let (t, dist_from_gizmo_origin) = + ray_to_plane_origin(normal, origin, ray.origin, ray.direction); + let dist_from_gizmo_edge = (dist_from_gizmo_origin - radius).abs(); + + let hit_pos = ray.origin + ray.direction * t; + let dir_to_origin = (origin - hit_pos).normalize(); + let nearest_circle_pos = hit_pos + dir_to_origin * (dist_from_gizmo_origin - radius); + + let offset = (nearest_circle_pos - origin).normalize(); + + let angle = if self.direction == GizmoDirection::Screen { + f64::atan2(tangent.cross(normal).dot(offset), tangent.dot(offset)) + } else { + let mut forward = config.view_forward(); + if config.left_handed { + forward *= -1.0; + } + f64::atan2(offset.cross(forward).dot(normal), offset.dot(forward)) + }; + + self.update_state_with(ui, |state: &mut RotationState| { + let rotation_angle = rotation_angle(self, ui).unwrap_or(0.0); + state.start_axis_angle = angle as f32; + state.start_rotation_angle = rotation_angle as f32; + state.last_rotation_angle = rotation_angle as f32; + state.current_delta = 0.0; + }); + + if dist_from_gizmo_edge <= config.focus_distance as f64 && angle.abs() < arc_angle(self) { + Some(t) + } else { + None + } + } + + fn update(&mut self, ui: &Ui, _ray: Ray) -> Option { + let state = self.state(ui); + let config = self.config; + + let mut rotation_angle = rotation_angle(self, ui)?; + if config.snapping { + rotation_angle = round_to_interval( + rotation_angle - state.start_rotation_angle as f64, + config.snap_angle as f64, + ) + state.start_rotation_angle as f64; + } + + let mut angle_delta = rotation_angle - state.last_rotation_angle as f64; + + // Always take the smallest angle, e.g. -10° instead of 350° + if angle_delta > PI { + angle_delta -= TAU; + } else if angle_delta < -PI { + angle_delta += TAU; + } + + self.update_state_with(ui, |state: &mut RotationState| { + state.last_rotation_angle = rotation_angle as f32; + state.current_delta += angle_delta as f32; + }); + + let new_rotation = + DQuat::from_axis_angle(self.normal(), -angle_delta) * self.config.rotation; + + Some(GizmoResult { + scale: self.config.scale.as_vec3().into(), + rotation: new_rotation.as_f32().into(), + translation: self.config.translation.as_vec3().into(), + mode: GizmoMode::Rotate, + value: (self.normal().as_vec3() * state.current_delta).to_array(), + }) + } + + fn draw(&self, ui: &Ui) { + let state = self.state(ui); + let config = self.config; + + let transform = rotation_matrix(self); + let painter = Painter3d::new( + ui.painter().clone(), + config.view_projection * transform, + config.viewport, + ); + + let color = self.color(); + let stroke = (config.visuals.stroke_width, color); + + let radius = arc_radius(self) as f64; + + if !self.active { + let angle = arc_angle(self); + painter.arc(radius, FRAC_PI_2 - angle, FRAC_PI_2 + angle, stroke); + } else { + let start_angle = state.start_axis_angle as f64 + FRAC_PI_2; + let end_angle = start_angle + state.current_delta as f64; + + // The polyline does not get rendered correctly if + // the start and end lines are exactly the same + let end_angle = end_angle + 1e-5; + + painter.polyline( + &[ + DVec3::new(start_angle.cos() * radius, 0.0, start_angle.sin() * radius), + DVec3::new(0.0, 0.0, 0.0), + DVec3::new(end_angle.cos() * radius, 0.0, end_angle.sin() * radius), + ], + stroke, + ); + + painter.circle(radius, stroke); + + // Draw snapping ticks + if config.snapping { + let stroke_width = stroke.0 / 2.0; + for i in 0..((TAU / config.snap_angle as f64) as usize + 1) { + let angle = i as f64 * config.snap_angle as f64 + end_angle; + let pos = DVec3::new(angle.cos(), 0.0, angle.sin()); + painter.line_segment( + pos * radius * 1.1, + pos * radius * 1.2, + (stroke_width, stroke.1), + ); + } + } + } + } +} + +/// Calculates angle of the rotation axis arc. +/// The arc is a semicircle, which turns into a full circle when viewed +/// directly from the front. +fn arc_angle(subgizmo: &SubGizmoConfig) -> f64 { + let dot = subgizmo.normal().dot(subgizmo.config.view_forward()).abs(); + let min_dot = 0.990; + let max_dot = 0.995; + + let mut angle = + f64::min(1.0, f64::max(0.0, dot - min_dot) / (max_dot - min_dot)) * FRAC_PI_2 + FRAC_PI_2; + if (angle - PI).abs() < 1e-2 { + angle = PI; + } + angle +} + +/// Calculates a matrix used when rendering the rotation axis. +fn rotation_matrix(subgizmo: &SubGizmoConfig) -> DMat4 { + if subgizmo.direction == GizmoDirection::Screen { + let forward = subgizmo.config.view_forward(); + let right = subgizmo.config.view_right(); + let up = subgizmo.config.view_up(); + + let rotation = DQuat::from_mat3(&DMat3::from_cols(up, -forward, -right)); + + return DMat4::from_rotation_translation(rotation, subgizmo.config.translation); + } + + // First rotate towards the gizmo normal + let local_normal = subgizmo.local_normal(); + let rotation = rotation_align(DVec3::Y, local_normal); + let mut rotation = DQuat::from_mat3(&rotation); + let config = subgizmo.config; + + if config.local_space() { + rotation = config.rotation * rotation; + } + + let tangent = tangent(subgizmo); + let normal = subgizmo.normal(); + let mut forward = config.view_forward(); + if config.left_handed { + forward *= -1.0; + } + let angle = f64::atan2(tangent.cross(forward).dot(normal), tangent.dot(forward)); + + // Rotate towards the camera, along the rotation axis. + rotation = DQuat::from_axis_angle(normal, angle) * rotation; + + DMat4::from_rotation_translation(rotation, config.translation) +} + +fn rotation_angle(subgizmo: &SubGizmoConfig, ui: &Ui) -> Option { + let cursor_pos = ui.input(|i| i.pointer.hover_pos())?; + let viewport = subgizmo.config.viewport; + let gizmo_pos = world_to_screen(viewport, subgizmo.config.mvp, DVec3::new(0.0, 0.0, 0.0))?; + let delta = DVec2::new( + cursor_pos.x as f64 - gizmo_pos.x as f64, + cursor_pos.y as f64 - gizmo_pos.y as f64, + ) + .normalize(); + + if delta.is_nan() { + return None; + } + + let mut angle = f64::atan2(delta.y, delta.x); + if subgizmo.config.view_forward().dot(subgizmo.normal()) < 0.0 { + angle *= -1.0; + } + + Some(angle) +} + +fn tangent(subgizmo: &SubGizmoConfig) -> DVec3 { + let mut tangent = match subgizmo.direction { + GizmoDirection::X | GizmoDirection::Y => DVec3::Z, + GizmoDirection::Z => -DVec3::Y, + GizmoDirection::Screen => -subgizmo.config.view_right(), + }; + + if subgizmo.config.local_space() && subgizmo.direction != GizmoDirection::Screen { + tangent = subgizmo.config.rotation * tangent; + } + + tangent +} + +fn arc_radius(subgizmo: &SubGizmoConfig) -> f32 { + let mut radius = subgizmo.config.visuals.gizmo_size; + + if subgizmo.direction == GizmoDirection::Screen { + // Screen axis should be a little bit larger + radius += subgizmo.config.visuals.stroke_width + 5.0; + } + + subgizmo.config.scale_factor * radius +} + +#[derive(Default, Debug, Copy, Clone)] +pub(crate) struct RotationState { + start_axis_angle: f32, + start_rotation_angle: f32, + last_rotation_angle: f32, + current_delta: f32, +} + +impl SubGizmoState for RotationState {} diff --git a/src/subgizmo/scale.rs b/src/subgizmo/scale.rs new file mode 100644 index 0000000..78fb125 --- /dev/null +++ b/src/subgizmo/scale.rs @@ -0,0 +1,89 @@ +use egui::Ui; +use glam::DVec3; + +use crate::math::{round_to_interval, world_to_screen}; + +use crate::subgizmo::common::{ + draw_arrow, draw_plane, pick_arrow, pick_plane, plane_binormal, plane_tangent, +}; +use crate::subgizmo::{SubGizmo, SubGizmoConfig, SubGizmoState, TransformKind}; +use crate::{GizmoMode, GizmoResult, Ray}; + +pub(crate) type ScaleSubGizmo = SubGizmoConfig; + +impl SubGizmo for ScaleSubGizmo { + fn pick(&mut self, ui: &Ui, ray: Ray) -> Option { + let pick_result = match self.transform_kind { + TransformKind::Axis => pick_arrow(self, ray), + TransformKind::Plane => pick_plane(self, ray), + }; + + let start_delta = distance_from_origin_2d(self, ui)?; + + self.opacity = pick_result.visibility as _; + + self.update_state_with(ui, |state: &mut ScaleState| { + state.start_scale = self.config.scale; + state.start_delta = start_delta; + }); + + if pick_result.picked { + Some(pick_result.t) + } else { + None + } + } + + fn update(&mut self, ui: &Ui, _ray: Ray) -> Option { + let state = self.state(ui); + let mut delta = distance_from_origin_2d(self, ui)?; + delta /= state.start_delta; + + if self.config.snapping { + delta = round_to_interval(delta, self.config.snap_scale as f64); + } + delta = delta.max(1e-4) - 1.0; + + let direction = if self.transform_kind == TransformKind::Plane { + let binormal = plane_binormal(self.direction); + let tangent = plane_tangent(self.direction); + (binormal + tangent).normalize() + } else { + self.local_normal() + }; + + let offset = DVec3::ONE + (direction * delta); + let new_scale = state.start_scale * offset; + + Some(GizmoResult { + scale: new_scale.as_vec3().into(), + rotation: self.config.rotation.as_f32().into(), + translation: self.config.translation.as_vec3().into(), + mode: GizmoMode::Scale, + value: offset.as_vec3().to_array(), + }) + } + + fn draw(&self, ui: &Ui) { + match self.transform_kind { + TransformKind::Axis => draw_arrow(self, ui), + TransformKind::Plane => draw_plane(self, ui), + } + } +} + +#[derive(Default, Debug, Copy, Clone)] +pub(crate) struct ScaleState { + start_scale: DVec3, + start_delta: f64, +} + +impl SubGizmoState for ScaleState {} + +fn distance_from_origin_2d(subgizmo: &SubGizmoConfig, ui: &Ui) -> Option { + let cursor_pos = ui.input(|i| i.pointer.hover_pos())?; + let viewport = subgizmo.config.viewport; + let gizmo_pos = world_to_screen(viewport, subgizmo.config.mvp, DVec3::new(0.0, 0.0, 0.0))?; + + Some(cursor_pos.distance(gizmo_pos) as f64) +} diff --git a/src/subgizmo/translation.rs b/src/subgizmo/translation.rs new file mode 100644 index 0000000..a7d0d1c --- /dev/null +++ b/src/subgizmo/translation.rs @@ -0,0 +1,146 @@ +use egui::Ui; +use glam::DVec3; + +use crate::math::{intersect_plane, ray_to_ray, round_to_interval}; + +use crate::subgizmo::common::{ + draw_arrow, draw_plane, pick_arrow, pick_plane, plane_binormal, plane_global_origin, + plane_tangent, +}; +use crate::subgizmo::{SubGizmo, SubGizmoConfig, SubGizmoState, TransformKind}; +use crate::{GizmoMode, GizmoResult, Ray}; + +pub(crate) type TranslationSubGizmo = SubGizmoConfig; + +impl SubGizmo for TranslationSubGizmo { + fn pick(&mut self, ui: &Ui, ray: Ray) -> Option { + let pick_result = match self.transform_kind { + TransformKind::Axis => pick_arrow(self, ray), + TransformKind::Plane => pick_plane(self, ray), + }; + + self.opacity = pick_result.visibility as _; + + self.update_state_with(ui, |state: &mut TranslationState| { + state.start_point = pick_result.subgizmo_point; + state.last_point = pick_result.subgizmo_point; + state.current_delta = DVec3::ZERO; + }); + + if pick_result.picked { + Some(pick_result.t) + } else { + None + } + } + + fn update(&mut self, ui: &Ui, ray: Ray) -> Option { + let state = self.state(ui); + + let mut new_point = if self.transform_kind == TransformKind::Axis { + point_on_axis(self, ray) + } else { + point_on_plane(self.normal(), plane_global_origin(self), ray)? + }; + + let mut new_delta = new_point - state.start_point; + + if self.config.snapping { + new_delta = if self.transform_kind == TransformKind::Axis { + snap_translation_vector(self, new_delta) + } else { + snap_translation_plane(self, new_delta) + }; + new_point = state.start_point + new_delta; + } + + self.update_state_with(ui, |state: &mut TranslationState| { + state.last_point = new_point; + state.current_delta = new_delta; + }); + + let new_translation = self.config.translation + new_point - state.last_point; + + Some(GizmoResult { + scale: self.config.scale.as_vec3().into(), + rotation: self.config.rotation.as_f32().into(), + translation: new_translation.as_vec3().into(), + mode: GizmoMode::Translate, + value: state.current_delta.as_vec3().to_array(), + }) + } + + fn draw(&self, ui: &Ui) { + match self.transform_kind { + TransformKind::Axis => draw_arrow(self, ui), + TransformKind::Plane => draw_plane(self, ui), + } + } +} + +#[derive(Default, Debug, Copy, Clone)] +pub(crate) struct TranslationState { + start_point: DVec3, + last_point: DVec3, + current_delta: DVec3, +} + +impl SubGizmoState for TranslationState {} + +/// Finds the nearest point on line that points in translation subgizmo direction +fn point_on_axis(subgizmo: &SubGizmoConfig, ray: Ray) -> DVec3 { + let origin = subgizmo.config.translation; + let direction = subgizmo.normal(); + + let (_ray_t, subgizmo_t) = ray_to_ray(ray.origin, ray.direction, origin, direction); + + origin + direction * subgizmo_t +} + +fn point_on_plane(plane_normal: DVec3, plane_origin: DVec3, ray: Ray) -> Option { + let mut t = 0.0; + if !intersect_plane( + plane_normal, + plane_origin, + ray.origin, + ray.direction, + &mut t, + ) { + None + } else { + Some(ray.origin + ray.direction * t) + } +} + +fn snap_translation_vector(subgizmo: &SubGizmoConfig, new_delta: DVec3) -> DVec3 { + let delta_length = new_delta.length(); + if delta_length > 1e-5 { + new_delta / delta_length + * round_to_interval(delta_length, subgizmo.config.snap_distance as f64) + } else { + new_delta + } +} + +fn snap_translation_plane(subgizmo: &SubGizmoConfig, new_delta: DVec3) -> DVec3 { + let mut binormal = plane_binormal(subgizmo.direction); + let mut tangent = plane_tangent(subgizmo.direction); + if subgizmo.config.local_space() { + binormal = subgizmo.config.rotation * binormal; + tangent = subgizmo.config.rotation * tangent; + } + let cb = new_delta.cross(-binormal); + let ct = new_delta.cross(tangent); + let lb = cb.length(); + let lt = ct.length(); + let n = subgizmo.normal(); + + if lb > 1e-5 && lt > 1e-5 { + binormal * round_to_interval(lt, subgizmo.config.snap_distance as f64) * (ct / lt).dot(n) + + tangent + * round_to_interval(lb, subgizmo.config.snap_distance as f64) + * (cb / lb).dot(n) + } else { + new_delta + } +} diff --git a/src/translation.rs b/src/translation.rs deleted file mode 100644 index ebd68a3..0000000 --- a/src/translation.rs +++ /dev/null @@ -1,338 +0,0 @@ -use egui::{Stroke, Ui}; -use glam::{DMat4, DVec3}; -use std::ops::RangeInclusive; - -use crate::math::{ - intersect_plane, ray_to_plane_origin, ray_to_ray, round_to_interval, segment_to_segment, -}; -use crate::painter::Painter3d; -use crate::subgizmo::SubGizmo; -use crate::{GizmoDirection, GizmoMode, GizmoResult, Ray, WidgetData}; - -const ARROW_FADE: RangeInclusive = (0.95)..=(0.99); -const PLANE_FADE: RangeInclusive = (0.70)..=(0.86); - -/// Picks given translation subgizmo. If the subgizmo is close enough to -/// the mouse pointer, distance from camera to the subgizmo is returned. -pub(crate) fn pick_translation(subgizmo: &SubGizmo, ui: &Ui, ray: Ray) -> Option { - let origin = subgizmo.config.translation; - let dir = subgizmo.normal(); - let scale = subgizmo.config.scale_factor * subgizmo.config.visuals.gizmo_size; - let length = scale as f64; - - let ray_length = 1e+14; - - let (ray_t, subgizmo_t) = segment_to_segment( - ray.origin, - ray.origin + ray.direction * ray_length, - origin, - origin + dir * length, - ); - - let ray_point = ray.origin + ray.direction * ray_length * ray_t; - let subgizmo_point = origin + dir * length * subgizmo_t; - let dist = (ray_point - subgizmo_point).length(); - - let dot = subgizmo - .config - .gizmo_view_forward - .dot(subgizmo.normal()) - .abs(); - let visibility = - (1.0 - (dot - *ARROW_FADE.start()) / (*ARROW_FADE.end() - *ARROW_FADE.start())).min(1.0); - - subgizmo.update_state_with(ui, |state: &mut TranslationState| { - state.start_point = subgizmo_point; - state.last_point = subgizmo_point; - state.current_delta = DVec3::ZERO; - state.visibility = visibility as _; - }); - - if visibility > 0.0 && dist <= subgizmo.config.focus_distance as f64 { - Some(ray.origin.distance(ray_point)) - } else { - None - } -} - -pub(crate) fn draw_translation(subgizmo: &SubGizmo, ui: &Ui) { - let state = subgizmo.state::(ui); - - if state.visibility <= 0.0001 { - return; - } - - let color = subgizmo.color().gamma_multiply(state.visibility); - - let painter = Painter3d::new( - ui.painter().clone(), - subgizmo.config.view_projection * translation_transform(subgizmo), - subgizmo.config.viewport, - ); - - let direction = subgizmo.local_normal(); - - let width = subgizmo.config.scale_factor * subgizmo.config.visuals.stroke_width; - let length = subgizmo.config.scale_factor * subgizmo.config.visuals.gizmo_size; - let arrow_length = width * 2.4; - let length = length - arrow_length; - - let start = direction * width as f64; - let end = direction * length as f64; - - painter.line_segment(start, end, (subgizmo.config.visuals.stroke_width, color)); - painter.arrow( - end, - end + direction * arrow_length as f64, - (subgizmo.config.visuals.stroke_width * 1.2, color), - ); -} - -/// Updates given translation subgizmo. -/// If the subgizmo is active, returns the translation result. -pub(crate) fn update_translation(subgizmo: &SubGizmo, ui: &Ui, ray: Ray) -> Option { - let state = subgizmo.state::(ui); - - let mut new_point = point_on_axis(subgizmo, ray); - let mut new_delta = new_point - state.start_point; - - if subgizmo.config.snapping { - new_delta = snap_translation_vector(subgizmo, new_delta); - new_point = state.start_point + new_delta; - } - - subgizmo.update_state_with(ui, |state: &mut TranslationState| { - state.last_point = new_point; - state.current_delta = new_delta; - }); - - let new_translation = subgizmo.config.translation + new_point - state.last_point; - - Some(GizmoResult { - scale: subgizmo.config.scale.as_vec3().into(), - rotation: subgizmo.config.rotation.as_f32().into(), - translation: new_translation.as_vec3().into(), - mode: GizmoMode::Translate, - value: state.current_delta.as_vec3().to_array(), - }) -} - -fn snap_translation_vector(subgizmo: &SubGizmo, new_delta: DVec3) -> DVec3 { - let delta_length = new_delta.length(); - if delta_length > 1e-5 { - new_delta / delta_length - * round_to_interval(delta_length, subgizmo.config.snap_distance as f64) - } else { - new_delta - } -} - -/// Picks given translation plane subgizmo. If the subgizmo is close enough to -/// the mouse pointer, distance from camera to the subgizmo is returned. -pub(crate) fn pick_translation_plane(subgizmo: &SubGizmo, ui: &Ui, ray: Ray) -> Option { - let origin = translation_plane_global_origin(subgizmo); - - let normal = subgizmo.normal(); - - let (t, dist_from_origin) = ray_to_plane_origin(normal, origin, ray.origin, ray.direction); - - let ray_point = ray.origin + ray.direction * t; - - let dot = subgizmo - .config - .gizmo_view_forward - .dot(subgizmo.normal()) - .abs(); - let visibility = (1.0 - - ((1.0 - dot) - *PLANE_FADE.start()) / (*PLANE_FADE.end() - *PLANE_FADE.start())) - .min(1.0); - - subgizmo.update_state_with(ui, |state: &mut TranslationState| { - state.start_point = ray_point; - state.last_point = ray_point; - state.current_delta = DVec3::ZERO; - state.visibility = visibility as _; - }); - - if visibility > 0.0 && dist_from_origin <= translation_plane_size(subgizmo) { - Some(t) - } else { - None - } -} - -pub(crate) fn draw_translation_plane(subgizmo: &SubGizmo, ui: &Ui) { - let state = subgizmo.state::(ui); - - if state.visibility <= 0.0001 { - return; - } - - let color = subgizmo.color().gamma_multiply(state.visibility); - - let painter = Painter3d::new( - ui.painter().clone(), - subgizmo.config.view_projection * translation_transform(subgizmo), - subgizmo.config.viewport, - ); - - let scale = translation_plane_size(subgizmo) * 0.5; - let a = translation_plane_binormal(subgizmo.direction) * scale; - let b = translation_plane_tangent(subgizmo.direction) * scale; - - let origin = translation_plane_local_origin(subgizmo); - - painter.polygon( - &[ - origin - b - a, - origin + b - a, - origin + b + a, - origin - b + a, - ], - color, - Stroke::NONE, - ); -} - -/// Updates given translation subgizmo. -/// If the subgizmo is active, returns the translation result. -pub(crate) fn update_translation_plane( - subgizmo: &SubGizmo, - ui: &Ui, - ray: Ray, -) -> Option { - let state = subgizmo.state::(ui); - - let mut new_point = point_on_plane( - subgizmo.normal(), - translation_plane_global_origin(subgizmo), - ray, - )?; - let mut new_delta = new_point - state.start_point; - - if subgizmo.config.snapping { - new_delta = snap_translation_plane(subgizmo, new_delta); - new_point = state.start_point + new_delta; - } - - subgizmo.update_state_with(ui, |state: &mut TranslationState| { - state.last_point = new_point; - state.current_delta = new_delta; - }); - - let new_translation = subgizmo.config.translation + new_point - state.last_point; - - Some(GizmoResult { - scale: subgizmo.config.scale.as_vec3().into(), - rotation: subgizmo.config.rotation.as_f32().into(), - translation: new_translation.as_vec3().into(), - mode: GizmoMode::Translate, - value: state.current_delta.as_vec3().to_array(), - }) -} - -fn snap_translation_plane(subgizmo: &SubGizmo, new_delta: DVec3) -> DVec3 { - let mut binormal = translation_plane_binormal(subgizmo.direction); - let mut tangent = translation_plane_tangent(subgizmo.direction); - if subgizmo.config.local_space() { - binormal = subgizmo.config.rotation * binormal; - tangent = subgizmo.config.rotation * tangent; - } - let cb = new_delta.cross(-binormal); - let ct = new_delta.cross(tangent); - let lb = cb.length(); - let lt = ct.length(); - let n = subgizmo.normal(); - - if lb > 1e-5 && lt > 1e-5 { - binormal * round_to_interval(lt, subgizmo.config.snap_distance as f64) * (ct / lt).dot(n) - + tangent - * round_to_interval(lb, subgizmo.config.snap_distance as f64) - * (cb / lb).dot(n) - } else { - new_delta - } -} - -#[derive(Default, Debug, Copy, Clone)] -pub(crate) struct TranslationState { - start_point: DVec3, - last_point: DVec3, - current_delta: DVec3, - visibility: f32, -} - -impl WidgetData for TranslationState {} - -fn translation_transform(subgizmo: &SubGizmo) -> DMat4 { - if subgizmo.config.local_space() { - DMat4::from_rotation_translation(subgizmo.config.rotation, subgizmo.config.translation) - } else { - DMat4::from_translation(subgizmo.config.translation) - } -} - -pub(crate) fn translation_plane_binormal(direction: GizmoDirection) -> DVec3 { - match direction { - GizmoDirection::X => DVec3::Y, - GizmoDirection::Y => DVec3::Z, - GizmoDirection::Z => DVec3::X, - GizmoDirection::Screen => DVec3::X, // Unused - } -} - -pub(crate) fn translation_plane_tangent(direction: GizmoDirection) -> DVec3 { - match direction { - GizmoDirection::X => DVec3::Z, - GizmoDirection::Y => DVec3::X, - GizmoDirection::Z => DVec3::Y, - GizmoDirection::Screen => DVec3::X, // Unused - } -} - -pub(crate) fn translation_plane_size(subgizmo: &SubGizmo) -> f64 { - (subgizmo.config.scale_factor - * (subgizmo.config.visuals.gizmo_size * 0.1 + subgizmo.config.visuals.stroke_width * 2.0)) - as f64 -} - -pub(crate) fn translation_plane_local_origin(subgizmo: &SubGizmo) -> DVec3 { - let offset = subgizmo.config.scale_factor * subgizmo.config.visuals.gizmo_size * 0.4; - - let a = translation_plane_binormal(subgizmo.direction); - let b = translation_plane_tangent(subgizmo.direction); - (a + b) * offset as f64 -} - -pub(crate) fn translation_plane_global_origin(subgizmo: &SubGizmo) -> DVec3 { - let mut origin = translation_plane_local_origin(subgizmo); - if subgizmo.config.local_space() { - origin = subgizmo.config.rotation * origin; - } - origin + subgizmo.config.translation -} - -/// Finds the nearest point on line that points in translation subgizmo direction -fn point_on_axis(subgizmo: &SubGizmo, ray: Ray) -> DVec3 { - let origin = subgizmo.config.translation; - let direction = subgizmo.normal(); - - let (_ray_t, subgizmo_t) = ray_to_ray(ray.origin, ray.direction, origin, direction); - - origin + direction * subgizmo_t -} - -fn point_on_plane(plane_normal: DVec3, plane_origin: DVec3, ray: Ray) -> Option { - let mut t = 0.0; - if !intersect_plane( - plane_normal, - plane_origin, - ray.origin, - ray.direction, - &mut t, - ) { - None - } else { - Some(ray.origin + ray.direction * t) - } -}