From 6e04ec99df0cddec7a2aa43be1098ee2ac83195b Mon Sep 17 00:00:00 2001 From: Nova Date: Mon, 26 Feb 2024 04:56:48 -0500 Subject: [PATCH] refactor(input): use idl --- .lapce/run.toml | 29 ++ Cargo.lock | 330 +++++++++++----------- Cargo.toml | 2 +- codegen/src/lib.rs | 30 +- src/nodes/fields/mod.rs | 66 ----- src/nodes/input/hand.rs | 96 ++++--- src/nodes/input/handler.rs | 83 ++++++ src/nodes/input/method.rs | 211 ++++++++++++++ src/nodes/input/mod.rs | 426 ++++++----------------------- src/nodes/input/pointer.rs | 102 +++---- src/nodes/input/tip.rs | 86 ++---- src/objects/input/eye_pointer.rs | 25 +- src/objects/input/mouse_pointer.rs | 11 +- src/objects/input/sk_controller.rs | 12 +- src/objects/input/sk_hand.rs | 65 ++--- 15 files changed, 770 insertions(+), 804 deletions(-) create mode 100644 .lapce/run.toml create mode 100644 src/nodes/input/handler.rs create mode 100644 src/nodes/input/method.rs diff --git a/.lapce/run.toml b/.lapce/run.toml new file mode 100644 index 00000000..2f04861e --- /dev/null +++ b/.lapce/run.toml @@ -0,0 +1,29 @@ +# The run config is used for both run mode and debug mode + +[[configs]] +# the name of this task +name = "task" + +# the type of the debugger. If not set, it can't be debugged but can still be run +# type = "lldb" + +# the program to run +program = "cargo" + +# the program arguments, e.g. args = ["arg1", "arg2"], optional +args = ["lrun", "--", "-f"] + +# current working directory, optional +# cwd = "${workspace}" + +# enviroment variables, optional +# [configs.env] +# VAR1 = "VAL1" +# VAR2 = "VAL2" + +# task to run before the run/debug session is started, optional +# [configs.prelaunch] +# program = "cargo" +# args = [ +# "build", +# ] diff --git a/Cargo.lock b/Cargo.lock index 25fbfb68..fbc33c2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,12 +26,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "aliasable" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" - [[package]] name = "angle" version = "0.5.0" @@ -88,7 +82,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -98,7 +92,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -139,7 +133,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -282,7 +276,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -335,6 +329,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "cgmath" version = "0.18.0" @@ -387,7 +387,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -454,7 +454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f76990911f2267d837d9d0ad060aa63aaad170af40904b29461734c339030d4d" dependencies = [ "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -546,7 +546,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf" dependencies = [ "nix 0.27.1", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -582,7 +582,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -591,7 +591,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.8.0", + "libloading 0.7.4", ] [[package]] @@ -667,7 +667,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -824,7 +824,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" dependencies = [ "libc", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -867,9 +867,9 @@ dependencies = [ [[package]] name = "glam" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" +checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" dependencies = [ "mint", ] @@ -967,7 +967,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1102,15 +1102,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.9" @@ -1148,9 +1139,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libloading" @@ -1169,7 +1160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" dependencies = [ "cfg-if", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1222,7 +1213,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -1257,9 +1248,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] @@ -1284,7 +1275,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -1319,13 +1310,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1345,25 +1336,25 @@ checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" [[package]] name = "nix" -version = "0.26.4" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cfg-if", "libc", "memoffset", - "pin-utils", ] [[package]] name = "nix" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ "bitflags 2.4.0", "cfg-if", + "cfg_aliases", "libc", ] @@ -1445,7 +1436,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -1469,31 +1460,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "ouroboros" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c86de06555b970aec45229b27291b53154f21a5743a163419f4e4c0b065dcde" -dependencies = [ - "aliasable", - "ouroboros_macro", - "static_assertions", -] - -[[package]] -name = "ouroboros_macro" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cad0c4b129e9696e37cb712b243777b90ef489a0bfaa0ac34e7d9b860e4f134" -dependencies = [ - "heck", - "itertools 0.11.0", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.37", -] - [[package]] name = "overload" version = "0.1.1" @@ -1551,7 +1517,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -1583,7 +1549,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -1615,7 +1581,7 @@ dependencies = [ "pin-project-lite", "rustix", "tracing", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1651,30 +1617,6 @@ dependencies = [ "toml_edit 0.19.15", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.78" @@ -1700,7 +1642,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb156a45b6b9fe8027497422179fb65afc84d36707a7ca98297bf06bccb8d43f" dependencies = [ "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -1720,7 +1662,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools", "proc-macro2", "quote", "syn 1.0.109", @@ -1746,9 +1688,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1887,7 +1829,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.11", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1934,22 +1876,22 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -1965,13 +1907,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.16" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -2073,12 +2015,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -2089,15 +2031,15 @@ checksum = "2f2b15926089e5526bb2dd738a2eb0e59034356e06eb71e1cd912358c0e62c4d" [[package]] name = "stardust-xr" -version = "0.14.1" -source = "git+https://github.com/StardustXR/core.git#ddb2953f6acac01ee9c4ccfae2d4b7eb959a07a2" +version = "0.44.0" +source = "git+https://github.com/StardustXR/core.git#c587446076b92d8a945f4d0e2a872c09f80cc575" dependencies = [ "cluFlock", "color-rs", "dirs", "global_counter", "mint", - "nix 0.26.4", + "nix 0.27.1", "parking_lot 0.12.1", "rustc-hash", "serde", @@ -2110,15 +2052,14 @@ dependencies = [ [[package]] name = "stardust-xr-schemas" version = "1.5.3" -source = "git+https://github.com/StardustXR/core.git#ddb2953f6acac01ee9c4ccfae2d4b7eb959a07a2" +source = "git+https://github.com/StardustXR/core.git#c587446076b92d8a945f4d0e2a872c09f80cc575" dependencies = [ "flatbuffers", "flexbuffers", - "glam 0.24.2", + "glam 0.25.0", "kdl", "manifest-dir-macros", "mint", - "ouroboros", "serde", "serde_repr", "thiserror", @@ -2143,7 +2084,7 @@ dependencies = [ "libc", "mint", "nanoid", - "nix 0.27.1", + "nix 0.28.0", "once_cell", "parking_lot 0.12.1", "portable-atomic", @@ -2179,12 +2120,6 @@ dependencies = [ "stardust-xr-schemas", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "stereokit" version = "0.16.9" @@ -2232,9 +2167,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.37" +version = "2.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" dependencies = [ "proc-macro2", "quote", @@ -2257,27 +2192,27 @@ dependencies = [ "fastrand", "redox_syscall 0.3.5", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -2292,9 +2227,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.32.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -2304,10 +2239,10 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.4", + "socket2 0.5.6", "tokio-macros", "tracing", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2322,13 +2257,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] @@ -2463,11 +2398,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -2475,20 +2409,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.50", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -2590,12 +2524,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "want" version = "0.3.1" @@ -2676,14 +2604,14 @@ dependencies = [ [[package]] name = "wayland-server" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f3f0c52a445936ca1184c98f1a69cf4ad9c9130788884531ef04428468cb1ce" +checksum = "00e6e4d5c285bc24ba4ed2d5a4bd4febd5fd904451f465973225c8e99772fdb7" dependencies = [ "bitflags 2.4.0", "downcast-rs", "io-lifetimes", - "nix 0.26.4", + "rustix", "wayland-backend", "wayland-scanner", ] @@ -2739,7 +2667,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -2748,7 +2676,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.3", ] [[package]] @@ -2757,13 +2694,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +dependencies = [ + "windows_aarch64_gnullvm 0.52.3", + "windows_aarch64_msvc 0.52.3", + "windows_i686_gnu 0.52.3", + "windows_i686_msvc 0.52.3", + "windows_x86_64_gnu 0.52.3", + "windows_x86_64_gnullvm 0.52.3", + "windows_x86_64_msvc 0.52.3", ] [[package]] @@ -2772,42 +2724,84 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" + [[package]] name = "winnow" version = "0.5.15" diff --git a/Cargo.toml b/Cargo.toml index 5a9816cf..87e27ce3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,7 +67,7 @@ xkbcommon = { version = "0.7.0", default-features = false, optional = true } ctrlc = "3.4.1" libc = "0.2.148" input-event-codes = "5.16.8" -nix = "0.27.1" +nix = "0.28.0" wayland-scanner = "0.31.1" wayland-backend = "0.3.3" cluFlock = "1.2.7" diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 19b2a3ef..0e9bf87e 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -36,10 +36,10 @@ pub fn codegen_audio_protocol(_input: proc_macro::TokenStream) -> proc_macro::To pub fn codegen_drawable_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { codegen_protocol(DRAWABLE_PROTOCOL) } -// #[proc_macro] -// pub fn codegen_input_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { -// codegen_protocol(INPUT_PROTOCOL) -// } +#[proc_macro] +pub fn codegen_input_protocol(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { + codegen_protocol(INPUT_PROTOCOL) +} fn codegen_protocol(protocol: &'static str) -> proc_macro::TokenStream { let protocol = Protocol::parse(protocol).unwrap(); @@ -213,8 +213,10 @@ fn generate_aspect(aspect: &Aspect) -> TokenStream { .map(generate_member) .reduce(fold_tokens) .map(|t| { + // TODO: properly import all dependencies quote! { pub mod #client_mod_name { + use super::*; #t } } @@ -388,6 +390,12 @@ fn generate_argument_name(argument: &Argument) -> TokenStream { fn convert_deserializeable_argument_type(argument_type: &ArgumentType) -> ArgumentType { match argument_type { ArgumentType::Node { .. } => ArgumentType::String, + ArgumentType::Vec(v) => { + ArgumentType::Vec(Box::new(convert_deserializeable_argument_type(v.as_ref()))) + } + ArgumentType::Map(v) => { + ArgumentType::Map(Box::new(convert_deserializeable_argument_type(v.as_ref()))) + } f => f.clone(), } } @@ -397,12 +405,18 @@ fn generate_argument_deserialize( optional: bool, ) -> TokenStream { let name = Ident::new(&argument_name.to_case(Case::Snake), Span::call_site()); - - match argument_type { - ArgumentType::Node { .. } => match optional { + if let ArgumentType::Node { .. } = argument_type { + return match optional { true => quote!(#name.map(|n| _calling_client.get_node(#argument_name, &n)?)), false => quote!(_calling_client.get_node(#argument_name, &#name)?), - }, + }; + } + if optional { + let mapping = generate_argument_deserialize("o", argument_type, false); + return quote!(#name.map(|o| Ok::<_, color_eyre::eyre::Report>(#mapping)).transpose()?); + } + + match argument_type { ArgumentType::Color => quote!(color::rgba_linear!(#name[0], #name[1], #name[2], #name[3])), ArgumentType::Vec(v) => { let mapping = generate_argument_deserialize("a", v, false); diff --git a/src/nodes/fields/mod.rs b/src/nodes/fields/mod.rs index e2cf301c..8e9ef283 100644 --- a/src/nodes/fields/mod.rs +++ b/src/nodes/fields/mod.rs @@ -199,72 +199,6 @@ impl Deref for Field { } } } -// impl FieldTrait for Field { -// fn spatial_ref(&self) -> &Spatial { -// match self { -// Field::Box(field) => field.spatial_ref(), -// Field::Cylinder(field) => field.spatial_ref(), -// Field::Sphere(field) => field.spatial_ref(), -// Field::Torus(field) => field.spatial_ref(), -// } -// } -// fn local_distance(&self, p: Vec3A) -> f32 { -// match self { -// Field::Box(field) => field.local_distance(p), -// Field::Cylinder(field) => field.local_distance(p), -// Field::Sphere(field) => field.local_distance(p), -// Field::Torus(field) => field.local_distance(p), -// } -// } -// fn local_normal(&self, p: Vec3A, r: f32) -> Vec3A { -// match self { -// Field::Box(field) => field.local_normal(p, r), -// Field::Cylinder(field) => field.local_normal(p, r), -// Field::Sphere(field) => field.local_normal(p, r), -// Field::Torus(field) => field.local_normal(p, r), -// } -// } -// fn local_closest_point(&self, p: Vec3A, r: f32) -> Vec3A { -// match self { -// Field::Box(field) => field.local_closest_point(p, r), -// Field::Cylinder(field) => field.local_closest_point(p, r), -// Field::Sphere(field) => field.local_closest_point(p, r), -// Field::Torus(field) => field.local_closest_point(p, r), -// } -// } -// fn distance(&self, reference_space: &Spatial, p: Vec3A) -> f32 { -// match self { -// Field::Box(field) => field.distance(reference_space, p), -// Field::Cylinder(field) => field.distance(reference_space, p), -// Field::Sphere(field) => field.distance(reference_space, p), -// Field::Torus(field) => field.distance(reference_space, p), -// } -// } -// fn normal(&self, reference_space: &Spatial, p: Vec3A, r: f32) -> Vec3A { -// match self { -// Field::Box(field) => field.normal(reference_space, p, r), -// Field::Cylinder(field) => field.normal(reference_space, p, r), -// Field::Sphere(field) => field.normal(reference_space, p, r), -// Field::Torus(field) => field.normal(reference_space, p, r), -// } -// } -// fn closest_point(&self, reference_space: &Spatial, p: Vec3A, r: f32) -> Vec3A { -// match self { -// Field::Box(field) => field.closest_point(reference_space, p, r), -// Field::Cylinder(field) => field.closest_point(reference_space, p, r), -// Field::Sphere(field) => field.closest_point(reference_space, p, r), -// Field::Torus(field) => field.closest_point(reference_space, p, r), -// } -// } -// fn ray_march(&self, ray: Ray) -> RayMarchResult { -// match self { -// Field::Box(field) => field.ray_march(ray), -// Field::Cylinder(field) => field.ray_march(ray), -// Field::Sphere(field) => field.ray_march(ray), -// Field::Torus(field) => field.ray_march(ray), -// } -// } -// } create_interface!(FieldInterface, FieldInterfaceAspect, "/field"); pub struct FieldInterface; diff --git a/src/nodes/input/hand.rs b/src/nodes/input/hand.rs index 893bf9df..0c8f9dc2 100644 --- a/src/nodes/input/hand.rs +++ b/src/nodes/input/hand.rs @@ -1,16 +1,57 @@ +use super::{DistanceLink, Finger, Hand, InputDataTrait, Joint, Thumb}; use crate::nodes::fields::Field; use crate::nodes::spatial::Spatial; -use glam::{vec3a, Mat4}; -use stardust_xr::schemas::flat::{Hand as FlatHand, InputDataType, Joint}; +use glam::{vec3a, Mat4, Quat}; use std::sync::Arc; -use super::{DistanceLink, InputSpecialization}; - -#[derive(Debug, Default)] -pub struct Hand { - pub base: FlatHand, +impl Default for Joint { + fn default() -> Self { + Joint { + position: [0.0; 3].into(), + rotation: Quat::IDENTITY.into(), + radius: 0.0, + distance: 0.0, + } + } +} +impl Default for Finger { + fn default() -> Self { + Finger { + tip: Default::default(), + distal: Default::default(), + intermediate: Default::default(), + proximal: Default::default(), + metacarpal: Default::default(), + } + } +} +impl Default for Thumb { + fn default() -> Self { + Thumb { + tip: Default::default(), + distal: Default::default(), + proximal: Default::default(), + metacarpal: Default::default(), + } + } } -impl InputSpecialization for Hand { +impl Default for Hand { + fn default() -> Self { + Hand { + right: Default::default(), + thumb: Default::default(), + index: Default::default(), + middle: Default::default(), + ring: Default::default(), + little: Default::default(), + palm: Default::default(), + wrist: Default::default(), + elbow: Default::default(), + } + } +} + +impl InputDataTrait for Hand { fn compare_distance(&self, space: &Arc, field: &Field) -> f32 { self.true_distance(space, field).abs() } @@ -18,34 +59,29 @@ impl InputSpecialization for Hand { let mut min_distance = f32::MAX; for tip in [ - &self.base.thumb.tip.position, - &self.base.index.tip.position, - &self.base.middle.tip.position, - &self.base.ring.tip.position, - &self.base.little.tip.position, + &self.thumb.tip.position, + &self.index.tip.position, + &self.middle.tip.position, + &self.ring.tip.position, + &self.little.tip.position, ] { min_distance = min_distance.min(field.distance(space, vec3a(tip.x, tip.y, tip.z))); } min_distance } - fn serialize( - &self, - distance_link: &DistanceLink, - local_to_handler_matrix: Mat4, - ) -> InputDataType { - let mut hand = self.base; + fn update_to(&mut self, distance_link: &DistanceLink, local_to_handler_matrix: Mat4) { let mut joints: Vec<&mut Joint> = Vec::new(); - joints.extend([&mut hand.palm, &mut hand.wrist]); - if let Some(elbow) = &mut hand.elbow { + joints.extend([&mut self.palm, &mut self.wrist]); + if let Some(elbow) = &mut self.elbow { joints.push(elbow); } for finger in [ - &mut hand.index, - &mut hand.middle, - &mut hand.ring, - &mut hand.little, + &mut self.index, + &mut self.middle, + &mut self.ring, + &mut self.little, ] { joints.extend([ &mut finger.tip, @@ -56,10 +92,10 @@ impl InputSpecialization for Hand { ]); } joints.extend([ - &mut hand.thumb.tip, - &mut hand.thumb.distal, - &mut hand.thumb.proximal, - &mut hand.thumb.metacarpal, + &mut self.thumb.tip, + &mut self.thumb.distal, + &mut self.thumb.proximal, + &mut self.thumb.metacarpal, ]); for joint in joints { @@ -73,7 +109,5 @@ impl InputSpecialization for Hand { .field .distance(&distance_link.handler.spatial, position.into()); } - - InputDataType::Hand(Box::new(hand)) } } diff --git a/src/nodes/input/handler.rs b/src/nodes/input/handler.rs new file mode 100644 index 00000000..2ca0f973 --- /dev/null +++ b/src/nodes/input/handler.rs @@ -0,0 +1,83 @@ +use super::{ + input_handler_client, DistanceLink, InputHandlerAspect, INPUT_HANDLER_REGISTRY, + INPUT_METHOD_REGISTRY, +}; +use crate::{ + core::node_collections::LifeLinkedNodeMap, + nodes::{fields::Field, spatial::Spatial, Aspect, Node}, +}; +use color_eyre::eyre::Result; +use portable_atomic::AtomicBool; +use stardust_xr::values::Datamap; +use std::sync::{Arc, Weak}; +use tracing::instrument; + +pub struct InputHandler { + pub enabled: Arc, + pub uid: String, + pub node: Weak, + pub spatial: Arc, + pub field: Arc, + pub(super) method_aliases: LifeLinkedNodeMap, +} +impl InputHandler { + pub fn add_to(node: &Arc, field: &Arc) -> Result<()> { + let handler = InputHandler { + enabled: node.enabled.clone(), + uid: node.uid.clone(), + node: Arc::downgrade(node), + spatial: node.get_aspect::().unwrap().clone(), + field: field.clone(), + method_aliases: LifeLinkedNodeMap::default(), + }; + for method in INPUT_METHOD_REGISTRY.get_valid_contents() { + method.make_alias(&handler); + method.handle_new_handler(&handler); + } + let handler = INPUT_HANDLER_REGISTRY.add(handler); + node.add_aspect_raw(handler); + Ok(()) + } + + #[instrument(level = "debug", skip(self, distance_link))] + pub(super) fn send_input( + &self, + order: u32, + captured: bool, + distance_link: &DistanceLink, + datamap: Datamap, + ) { + let Some(node) = self.node.upgrade() else { + return; + }; + let Some(method_alias) = distance_link + .handler + .method_aliases + .get(&(Arc::as_ptr(&distance_link.method) as usize)) + else { + return; + }; + let _ = input_handler_client::input( + &node, + &method_alias, + &distance_link.serialize(order, captured, datamap), + ); + } +} +impl Aspect for InputHandler { + const NAME: &'static str = "InputHandler"; +} +impl InputHandlerAspect for InputHandler {} +impl PartialEq for InputHandler { + fn eq(&self, other: &Self) -> bool { + self.spatial == other.spatial + } +} +impl Drop for InputHandler { + fn drop(&mut self) { + INPUT_HANDLER_REGISTRY.remove(self); + for method in INPUT_METHOD_REGISTRY.get_valid_contents() { + method.handle_drop_handler(self); + } + } +} diff --git a/src/nodes/input/method.rs b/src/nodes/input/method.rs new file mode 100644 index 00000000..0d716c12 --- /dev/null +++ b/src/nodes/input/method.rs @@ -0,0 +1,211 @@ +use super::{ + input_method_client, InputDataTrait, InputDataType, InputHandler, InputMethodAspect, + INPUT_HANDLER_REGISTRY, INPUT_METHOD_REGISTRY, +}; +use crate::{ + core::{client::Client, node_collections::LifeLinkedNodeMap, registry::Registry}, + nodes::{ + alias::{Alias, AliasInfo}, + fields::{Field, FIELD_ALIAS_INFO}, + spatial::Spatial, + Aspect, Node, + }, +}; +use color_eyre::eyre::Result; +use parking_lot::Mutex; +use portable_atomic::Ordering; +use stardust_xr::values::Datamap; +use std::sync::{Arc, Weak}; + +pub struct InputMethod { + pub node: Weak, + pub uid: String, + pub enabled: Mutex, + pub spatial: Arc, + pub data: Mutex, + pub datamap: Mutex, + + pub(super) captures: Registry, + pub(super) handler_aliases: LifeLinkedNodeMap, + pub(super) handler_order: Mutex>>>, +} +impl InputMethod { + pub fn add_to( + node: &Arc, + data: InputDataType, + datamap: Datamap, + ) -> Result> { + let method = InputMethod { + node: Arc::downgrade(node), + uid: node.uid.clone(), + enabled: Mutex::new(true), + spatial: node.get_aspect::().unwrap().clone(), + data: Mutex::new(data), + captures: Registry::new(), + datamap: Mutex::new(datamap), + handler_aliases: LifeLinkedNodeMap::default(), + handler_order: Mutex::new(None), + }; + for handler in INPUT_HANDLER_REGISTRY.get_valid_contents() { + method.handle_new_handler(&handler); + method.make_alias(&handler); + } + let method = INPUT_METHOD_REGISTRY.add(method); + ::add_node_members(node); + node.add_aspect_raw(method.clone()); + Ok(method) + } + + pub(super) fn make_alias(&self, handler: &InputHandler) { + let Some(method_node) = self.node.upgrade() else { + return; + }; + let Some(handler_node) = handler.node.upgrade() else { + return; + }; + let Some(client) = handler_node.get_client() else { + return; + }; + let Ok(method_alias) = Alias::create( + &client, + handler_node.get_path(), + &self.uid, + &method_node, + AliasInfo { + server_signals: vec!["capture"], + ..Default::default() + }, + ) else { + return; + }; + method_alias.enabled.store(false, Ordering::Relaxed); + handler + .method_aliases + .add(self as *const InputMethod as usize, &method_alias); + } + + pub fn compare_distance(&self, to: &InputHandler) -> f32 { + let distance = self.data.lock().compare_distance(&self.spatial, &to.field); + if self.captures.contains(to) { + distance * 0.5 + } else { + distance + } + } + pub fn true_distance(&self, to: &Field) -> f32 { + self.data.lock().true_distance(&self.spatial, to) + } + + pub(super) fn handle_new_handler(&self, handler: &InputHandler) { + let Some(method_node) = self.node.upgrade() else { + return; + }; + let Some(method_client) = method_node.get_client() else { + return; + }; + let Some(handler_node) = handler.node.upgrade() else { + return; + }; + // Receiver itself + let Ok(handler_alias) = Alias::create( + &method_client, + method_node.get_path(), + handler.uid.as_str(), + &handler_node, + AliasInfo { + server_methods: vec!["get_transform"], + ..Default::default() + }, + ) else { + return; + }; + self.handler_aliases + .add(handler.uid.clone(), &handler_alias); + + if let Some(handler_field_node) = handler.field.spatial_ref().node.upgrade() { + // Handler's field + let Ok(rx_field_alias) = Alias::create( + &method_client, + handler_alias.get_path(), + "field", + &handler_field_node, + FIELD_ALIAS_INFO.clone(), + ) else { + return; + }; + self.handler_aliases + .add(handler.uid.clone() + "-field", &rx_field_alias); + } + + let _ = input_method_client::new_handler(&method_node, &handler.uid, &handler_node); + } + pub(super) fn handle_drop_handler(&self, handler: &InputHandler) { + let uid = handler.uid.as_str(); + self.handler_aliases.remove(uid); + self.handler_aliases.remove(&(uid.to_string() + "-field")); + let Some(tx_node) = self.node.upgrade() else { + return; + }; + + let _ = input_method_client::drop_handler(&tx_node, &uid); + } +} +impl Aspect for InputMethod { + const NAME: &'static str = "InputMethod"; +} +impl InputMethodAspect for InputMethod { + #[doc = "Set the spatial input component of this input method. You must keep the same input data type throughout the entire thing."] + fn set_input( + node: Arc, + _calling_client: Arc, + input: InputDataType, + ) -> Result<()> { + let input_method = node.get_aspect::()?; + *input_method.data.lock() = input; + Ok(()) + } + + #[doc = "Set the datmap of this input method"] + fn set_datamap(node: Arc, _calling_client: Arc, datamap: Datamap) -> Result<()> { + let input_method = node.get_aspect::()?; + *input_method.datamap.lock() = datamap; + Ok(()) + } + + #[doc = "Manually set the order of handlers to propagate input to, or else let the server decide."] + fn set_handler_order( + node: Arc, + _calling_client: Arc, + handlers: Option>>, + ) -> Result<()> { + let input_method = node.get_aspect::()?; + let Some(handlers) = handlers else { + *input_method.handler_order.lock() = None; + return Ok(()); + }; + let handlers = handlers + .into_iter() + .filter_map(|p| p.get_aspect::().ok()) + .map(|i| Arc::downgrade(&i)) + .collect::>(); + + *input_method.handler_order.lock() = Some(handlers); + Ok(()) + } + + #[doc = "Have the input handler that this method reference came from capture the method for the next frame."] + fn capture(node: Arc, _calling_client: Arc, handler: Arc) -> Result<()> { + let input_method = node.get_aspect::()?; + let input_handler = handler.get_aspect::()?; + + input_method.captures.add_raw(&input_handler); + // input_method_client:: + // node.send_remote_signal("capture", message) + Ok(()) + } +} +impl Drop for InputMethod { + fn drop(&mut self) { + INPUT_METHOD_REGISTRY.remove(self); + } +} diff --git a/src/nodes/input/mod.rs b/src/nodes/input/mod.rs index 7e4af87b..c72c3f43 100644 --- a/src/nodes/input/mod.rs +++ b/src/nodes/input/mod.rs @@ -1,255 +1,29 @@ -pub mod hand; -pub mod pointer; -pub mod tip; - -use self::hand::Hand; -use self::pointer::Pointer; -use self::tip::Tip; - -use super::{ - alias::{Alias, AliasInfo}, - fields::{find_field, Field, FIELD_ALIAS_INFO}, - spatial::{parse_transform, Spatial}, - Aspect, Message, Node, -}; -use crate::core::{client::Client, node_collections::LifeLinkedNodeMap}; +mod hand; +mod handler; +mod method; +mod pointer; +mod tip; + +pub use handler::*; +pub use method::*; + +use super::fields::Field; +use super::spatial::Spatial; +use crate::create_interface; +use crate::nodes::alias::Alias; +use crate::{core::client::Client, nodes::Node}; use crate::{core::registry::Registry, nodes::spatial::Transform}; use color_eyre::eyre::Result; use glam::Mat4; -use once_cell::sync::OnceCell; -use parking_lot::Mutex; -use portable_atomic::AtomicBool; -use serde::Deserialize; -use stardust_xr::schemas::{flat::InputDataType, flex::serialize}; -use stardust_xr::{ - schemas::{flat::InputData, flex::deserialize}, - values::Datamap, -}; -use std::ops::Deref; -use std::sync::atomic::Ordering; +use portable_atomic::Ordering; +use stardust_xr::values::Datamap; use std::sync::{Arc, Weak}; use tracing::{debug_span, instrument}; static INPUT_METHOD_REGISTRY: Registry = Registry::new(); static INPUT_HANDLER_REGISTRY: Registry = Registry::new(); -pub trait InputSpecialization: Send + Sync { - fn compare_distance(&self, space: &Arc, field: &Field) -> f32; - fn true_distance(&self, space: &Arc, field: &Field) -> f32; - fn serialize( - &self, - distance_link: &DistanceLink, - local_to_handler_matrix: Mat4, - ) -> InputDataType; -} -pub enum InputType { - Pointer(Pointer), - Hand(Box), - Tip(Tip), -} -impl Deref for InputType { - type Target = dyn InputSpecialization; - fn deref(&self) -> &Self::Target { - match self { - InputType::Pointer(p) => p, - InputType::Hand(h) => h.as_ref(), - InputType::Tip(t) => t, - } - } -} - -pub struct InputMethod { - node: Weak, - uid: String, - pub enabled: Mutex, - pub spatial: Arc, - pub specialization: Mutex, - captures: Registry, - pub datamap: Mutex>, - handler_aliases: LifeLinkedNodeMap, - handler_order: OnceCell>>>, -} -impl InputMethod { - #[allow(dead_code)] - pub fn add_to( - node: &Arc, - specialization: InputType, - datamap: Option, - ) -> Result> { - node.add_local_signal("capture", InputMethod::capture_flex); - node.add_local_signal("set_datamap", InputMethod::set_datamap_flex); - node.add_local_signal("set_handlers", InputMethod::set_handlers_flex); - - let method = InputMethod { - node: Arc::downgrade(node), - uid: node.uid.clone(), - enabled: Mutex::new(true), - spatial: node.get_aspect::().unwrap().clone(), - specialization: Mutex::new(specialization), - captures: Registry::new(), - datamap: Mutex::new(datamap), - handler_aliases: LifeLinkedNodeMap::default(), - handler_order: OnceCell::new(), - }; - for handler in INPUT_HANDLER_REGISTRY.get_valid_contents() { - method.handle_new_handler(&handler); - method.make_alias(&handler); - } - let method = INPUT_METHOD_REGISTRY.add(method); - node.add_aspect_raw(method.clone()); - Ok(method) - } - fn get(node: &Node) -> Result> { - node.get_aspect::() - } - - fn capture_flex(node: Arc, calling_client: Arc, message: Message) -> Result<()> { - let method = InputMethod::get(&node)?; - let handler = InputHandler::find(&calling_client, deserialize(message.as_ref())?)?; - - method.captures.add_raw(&handler); - node.send_remote_signal("capture", message) - } - fn set_datamap_flex( - node: Arc, - _calling_client: Arc, - message: Message, - ) -> Result<()> { - let method = InputMethod::get(&node)?; - method - .datamap - .lock() - .replace(Datamap::from_raw(message.data)?); - Ok(()) - } - fn set_handlers_flex( - node: Arc, - calling_client: Arc, - message: Message, - ) -> Result<()> { - let method = InputMethod::get(&node)?; - let handler_paths: Vec<&str> = deserialize(message.as_ref())?; - let handlers: Vec> = handler_paths - .into_iter() - .filter_map(|p| InputHandler::find(&calling_client, p).ok()) - .map(|h| Arc::downgrade(&h)) - .collect(); - - *method - .handler_order - .get_or_init(|| Mutex::new(Vec::new())) - .lock() = handlers; - Ok(()) - } - - fn make_alias(&self, handler: &InputHandler) { - let Some(method_node) = self.node.upgrade() else { - return; - }; - let Some(handler_node) = handler.node.upgrade() else { - return; - }; - let Some(client) = handler_node.get_client() else { - return; - }; - let Ok(method_alias) = Alias::create( - &client, - handler_node.get_path(), - &self.uid, - &method_node, - AliasInfo { - server_signals: vec!["capture"], - ..Default::default() - }, - ) else { - return; - }; - method_alias.enabled.store(false, Ordering::Relaxed); - handler - .method_aliases - .add(self as *const InputMethod as usize, &method_alias); - } - - fn compare_distance(&self, to: &InputHandler) -> f32 { - let distance = self - .specialization - .lock() - .compare_distance(&self.spatial, &to.field); - if self.captures.contains(to) { - distance * 0.5 - } else { - distance - } - } - fn true_distance(&self, to: &Field) -> f32 { - self.specialization.lock().true_distance(&self.spatial, to) - } - - fn handle_new_handler(&self, handler: &InputHandler) { - let Some(method_node) = self.node.upgrade() else { - return; - }; - let Some(method_client) = method_node.get_client() else { - return; - }; - let Some(handler_node) = handler.node.upgrade() else { - return; - }; - // Receiver itself - let Ok(handler_alias) = Alias::create( - &method_client, - method_node.get_path(), - handler.uid.as_str(), - &handler_node, - AliasInfo { - server_methods: vec!["get_transform"], - ..Default::default() - }, - ) else { - return; - }; - self.handler_aliases - .add(handler.uid.clone(), &handler_alias); - - if let Some(handler_field_node) = handler.field.spatial_ref().node.upgrade() { - // Handler's field - let Ok(rx_field_alias) = Alias::create( - &method_client, - handler_alias.get_path(), - "field", - &handler_field_node, - FIELD_ALIAS_INFO.clone(), - ) else { - return; - }; - self.handler_aliases - .add(handler.uid.clone() + "-field", &rx_field_alias); - } - - let Ok(data) = serialize(&handler.uid) else { - return; - }; - let _ = method_node.send_remote_signal("handler_created", data); - } - fn handle_drop_handler(&self, handler: &InputHandler) { - let uid = handler.uid.as_str(); - self.handler_aliases.remove(uid); - self.handler_aliases.remove(&(uid.to_string() + "-field")); - let Some(tx_node) = self.node.upgrade() else { - return; - }; - let Ok(data) = serialize(&uid) else { return }; - let _ = tx_node.send_remote_signal("handler_destroyed", data); - } -} -impl Aspect for InputMethod { - const NAME: &'static str = "InputMethod"; -} -impl Drop for InputMethod { - fn drop(&mut self) { - INPUT_METHOD_REGISTRY.remove(self); - } -} +stardust_xr_server_codegen::codegen_input_protocol!(); pub struct DistanceLink { distance: f32, @@ -269,118 +43,98 @@ impl DistanceLink { self.handler.send_input(order, captured, self, datamap); } #[instrument(level = "debug", skip(self))] - fn serialize(&self, order: u32, captured: bool, datamap: Datamap) -> Vec { - let input = self.method.specialization.lock().serialize( + fn serialize(&self, order: u32, captured: bool, datamap: Datamap) -> InputData { + let mut input = self.method.data.lock().clone(); + input.update_to( self, Spatial::space_to_space_matrix(Some(&self.method.spatial), Some(&self.handler.spatial)), ); - let root = InputData { + InputData { uid: self.method.uid.clone(), input, distance: self.method.true_distance(&self.handler.field), datamap, order, captured, - }; - root.serialize() + } } } - -pub struct InputHandler { - enabled: Arc, - uid: String, - node: Weak, - spatial: Arc, - field: Arc, - method_aliases: LifeLinkedNodeMap, +pub trait InputDataTrait { + fn compare_distance(&self, space: &Arc, field: &Field) -> f32; + fn true_distance(&self, space: &Arc, field: &Field) -> f32; + fn update_to(&mut self, distance_link: &DistanceLink, local_to_handler_matrix: Mat4); } -impl InputHandler { - pub fn add_to(node: &Arc, field: &Arc) -> Result<()> { - let handler = InputHandler { - enabled: node.enabled.clone(), - uid: node.uid.clone(), - node: Arc::downgrade(node), - spatial: node.get_aspect::().unwrap().clone(), - field: field.clone(), - method_aliases: LifeLinkedNodeMap::default(), - }; - for method in INPUT_METHOD_REGISTRY.get_valid_contents() { - method.make_alias(&handler); - method.handle_new_handler(&handler); +impl InputDataTrait for InputDataType { + fn compare_distance(&self, space: &Arc, field: &Field) -> f32 { + match self { + InputDataType::Pointer(i) => i.compare_distance(space, field), + InputDataType::Hand(i) => i.compare_distance(space, field), + InputDataType::Tip(i) => i.compare_distance(space, field), } - let handler = INPUT_HANDLER_REGISTRY.add(handler); - node.add_aspect_raw(handler); - Ok(()) - } - fn find(client: &Client, path: &str) -> Result> { - client.get_node("Input Handler", path)?.get_aspect::() } - #[instrument(level = "debug", skip(self, distance_link))] - fn send_input( - &self, - order: u32, - captured: bool, - distance_link: &DistanceLink, - datamap: Datamap, - ) { - let Some(node) = self.node.upgrade() else { - return; - }; - let _ = node.send_remote_signal("input", distance_link.serialize(order, captured, datamap)); - } -} -impl Aspect for InputHandler { - const NAME: &'static str = "InputHandler"; -} -impl PartialEq for InputHandler { - fn eq(&self, other: &Self) -> bool { - self.spatial == other.spatial - } -} -impl Drop for InputHandler { - fn drop(&mut self) { - INPUT_HANDLER_REGISTRY.remove(self); - for method in INPUT_METHOD_REGISTRY.get_valid_contents() { - method.handle_drop_handler(self); + fn true_distance(&self, space: &Arc, field: &Field) -> f32 { + match self { + InputDataType::Pointer(i) => i.true_distance(space, field), + InputDataType::Hand(i) => i.true_distance(space, field), + InputDataType::Tip(i) => i.true_distance(space, field), } } -} -pub fn create_interface(client: &Arc) -> Result<()> { - let node = Node::create_path(client, "/input", false); - node.add_local_signal("create_input_handler", create_input_handler_flex); - node.add_local_signal("create_input_method_pointer", pointer::create_pointer_flex); - node.add_local_signal("create_input_method_tip", tip::create_tip_flex); - node.add_to_scenegraph().map(|_| ()) + fn update_to(&mut self, distance_link: &DistanceLink, local_to_handler_matrix: Mat4) { + match self { + InputDataType::Pointer(i) => i.update_to(distance_link, local_to_handler_matrix), + InputDataType::Hand(i) => i.update_to(distance_link, local_to_handler_matrix), + InputDataType::Tip(i) => i.update_to(distance_link, local_to_handler_matrix), + } + } } -pub fn create_input_handler_flex( - _node: Arc, - calling_client: Arc, - message: Message, -) -> Result<()> { - #[derive(Deserialize)] - struct CreateInputHandlerInfo<'a> { - name: &'a str, - parent_path: &'a str, +create_interface!(InputInterface, InputInterfaceAspect, "/input"); +pub struct InputInterface; +impl InputInterfaceAspect for InputInterface { + #[doc = "Create an input method node"] + fn create_input_method( + _node: Arc, + calling_client: Arc, + name: String, + parent: Arc, transform: Transform, - field_path: &'a str, + initial_data: InputDataType, + datamap: Datamap, + ) -> Result<()> { + let parent = parent.get_aspect::()?; + let transform = transform.to_mat4(true, true, true); + + let node = Node::create_parent_name(&calling_client, "/input/method", &name, true) + .add_to_scenegraph()?; + Spatial::add_to(&node, Some(parent.clone()), transform, false); + InputMethod::add_to(&node, initial_data, datamap)?; + Ok(()) } - let info: CreateInputHandlerInfo = deserialize(message.as_ref())?; - let parent = calling_client - .get_node("Spatial parent", info.parent_path)? - .get_aspect::()?; - let transform = parse_transform(info.transform, true, true, true); - let field = find_field(&calling_client, info.field_path)?; - let node = Node::create_parent_name(&calling_client, "/input/handler", info.name, true) - .add_to_scenegraph()?; - Spatial::add_to(&node, Some(parent.clone()), transform, false); - InputHandler::add_to(&node, &field)?; - Ok(()) + #[doc = "Create an input handler node"] + fn create_input_handler( + _node: Arc, + calling_client: Arc, + name: String, + parent: Arc, + transform: Transform, + field: Arc, + ) -> Result<()> { + let parent = parent.get_aspect::()?; + let transform = transform.to_mat4(true, true, true); + let field = field.get_aspect::()?; + + let node = Node::create_parent_name(&calling_client, "/input/handler", &name, true) + .add_to_scenegraph()?; + Spatial::add_to(&node, Some(parent.clone()), transform, false); + InputHandler::add_to(&node, &field)?; + Ok(()) + } } + #[tracing::instrument(level = "debug")] pub fn process_input() { // Iterate over all valid input methods @@ -389,7 +143,6 @@ pub fn process_input() { .get_valid_contents() .into_iter() .filter(|method| *method.enabled.lock()) - .filter(|method| method.datamap.lock().is_some()) }); let handlers = INPUT_HANDLER_REGISTRY.get_valid_contents(); const LIMIT: usize = 50; @@ -402,11 +155,10 @@ pub fn process_input() { // Get all valid input handlers and convert them to DistanceLink objects let distance_links: Vec = debug_span!("Generate distance links") .in_scope(|| { - if let Some(handler_order) = method.handler_order.get() { - let handler_order = handler_order.lock(); + if let Some(handler_order) = &*method.handler_order.lock() { handler_order .iter() - .filter_map(|h| h.upgrade()) + .filter_map(Weak::upgrade) .filter(|handler| handler.enabled.load(Ordering::Relaxed)) .map(|handler| DistanceLink::from(method.clone(), handler)) .collect() @@ -445,11 +197,7 @@ pub fn process_input() { method_alias.enabled.store(true, Ordering::Release); } let captured = captures.contains(&distance_link.handler); - distance_link.send_input( - i as u32, - captured, - method.datamap.lock().clone().unwrap(), - ); + distance_link.send_input(i as u32, captured, method.datamap.lock().clone()); // If the current distance link is in the list of captured input handlers, // break out of the loop to avoid sending input to the remaining distance links diff --git a/src/nodes/input/pointer.rs b/src/nodes/input/pointer.rs index 2effe147..1c7f7d7f 100644 --- a/src/nodes/input/pointer.rs +++ b/src/nodes/input/pointer.rs @@ -1,38 +1,34 @@ -use super::{DistanceLink, InputSpecialization}; -use crate::core::client::Client; -use crate::nodes::fields::{Field, Ray, RayMarchResult}; -use crate::nodes::input::{InputMethod, InputType}; -use crate::nodes::spatial::{parse_transform, Spatial, Transform}; -use crate::nodes::{Message, Node}; -use glam::{vec3, Mat4}; -use serde::Deserialize; -use stardust_xr::schemas::flat::{InputDataType, Pointer as FlatPointer}; -use stardust_xr::schemas::flex::deserialize; -use stardust_xr::values::Datamap; +use super::{DistanceLink, InputDataTrait, Pointer}; +use crate::nodes::{ + fields::{Field, Ray, RayMarchResult}, + spatial::Spatial, +}; +use glam::{vec3, Mat4, Quat}; +use std::sync::{Arc, Weak}; -use std::sync::Arc; - -#[derive(Default)] -pub struct Pointer; -// impl Default for Pointer { -// fn default() -> Self { -// Pointer { -// grab: Default::default(), -// select: Default::default(), -// } -// } -// } +impl Default for Pointer { + fn default() -> Self { + Pointer { + origin: [0.0; 3].into(), + orientation: Quat::IDENTITY.into(), + deepest_point: [0.0; 3].into(), + } + } +} impl Pointer { - fn ray_march(&self, space: &Arc, field: &Field) -> RayMarchResult { + fn ray_march(&self, method_space: &Arc, field: &Field) -> RayMarchResult { field.ray_march(Ray { origin: vec3(0.0, 0.0, 0.0), direction: vec3(0.0, 0.0, -1.0), - space: space.clone(), + space: Spatial::new( + Weak::new(), + Some(method_space.clone()), + Mat4::from_rotation_translation(self.orientation.into(), self.origin.into()), + ), }) } } - -impl InputSpecialization for Pointer { +impl InputDataTrait for Pointer { fn compare_distance(&self, space: &Arc, field: &Field) -> f32 { let ray_info = self.ray_march(space, field); if ray_info.min_distance > 0.0 { @@ -47,50 +43,20 @@ impl InputSpecialization for Pointer { let ray_info = self.ray_march(space, field); ray_info.min_distance } - fn serialize( - &self, - distance_link: &DistanceLink, - local_to_handler_matrix: Mat4, - ) -> InputDataType { + fn update_to(&mut self, distance_link: &DistanceLink, mut local_to_handler_matrix: Mat4) { + local_to_handler_matrix = + Mat4::from_rotation_translation(self.orientation.into(), self.origin.into()) + * local_to_handler_matrix; let (_, orientation, origin) = local_to_handler_matrix.to_scale_rotation_translation(); - let direction = local_to_handler_matrix.transform_vector3(vec3(0.0, 0.0, -1.0)); + let ray_march = self.ray_march(&distance_link.method.spatial, &distance_link.handler.field); + let direction = local_to_handler_matrix + .transform_vector3(vec3(0.0, 0.0, -1.0)) + .normalize(); let deepest_point = (direction * ray_march.deepest_point_distance) + origin; - InputDataType::Pointer(FlatPointer { - origin: origin.into(), - orientation: orientation.into(), - deepest_point: deepest_point.into(), - }) + self.origin = origin.into(); + self.orientation = orientation.into(); + self.deepest_point = deepest_point.into(); } } - -pub fn create_pointer_flex( - _node: Arc, - calling_client: Arc, - message: Message, -) -> color_eyre::eyre::Result<()> { - #[derive(Deserialize)] - struct CreatePointerInfo<'a> { - name: &'a str, - parent_path: &'a str, - transform: Transform, - datamap: Option>, - } - let info: CreatePointerInfo = deserialize(message.as_ref())?; - let node = Node::create_parent_name(&calling_client, "/input/method/pointer", info.name, true); - let parent = calling_client - .get_node("Spatial parent", info.parent_path)? - .get_aspect::()?; - let transform = parse_transform(info.transform, true, true, false); - - let node = node.add_to_scenegraph()?; - Spatial::add_to(&node, Some(parent.clone()), transform, false); - InputMethod::add_to( - &node, - InputType::Pointer(Pointer), - info.datamap - .and_then(|datamap| Datamap::from_raw(datamap).ok()), - )?; - Ok(()) -} diff --git a/src/nodes/input/tip.rs b/src/nodes/input/tip.rs index 55453743..edb102ba 100644 --- a/src/nodes/input/tip.rs +++ b/src/nodes/input/tip.rs @@ -1,82 +1,28 @@ -use super::{DistanceLink, InputSpecialization}; -use crate::core::client::Client; -use crate::nodes::fields::Field; -use crate::nodes::input::{InputMethod, InputType}; -use crate::nodes::spatial::{parse_transform, Spatial, Transform}; -use crate::nodes::{Message, Node}; -use color_eyre::eyre::Result; -use glam::{vec3a, Mat4}; -use serde::Deserialize; -use stardust_xr::schemas::flat::{InputDataType, Tip as FlatTip}; -use stardust_xr::schemas::flex::deserialize; -use stardust_xr::values::Datamap; - +use super::{DistanceLink, InputDataTrait, Tip}; +use crate::nodes::{fields::Field, spatial::Spatial}; +use glam::{Mat4, Quat}; use std::sync::Arc; -#[derive(Default)] -pub struct Tip { - pub radius: f32, -} -impl Tip { - fn set_radius(node: Arc, _calling_client: Arc, message: Message) -> Result<()> { - let input_method = node.get_aspect::()?; - if let InputType::Tip(tip) = &mut *input_method.specialization.lock() { - tip.radius = deserialize(message.as_ref())?; +impl Default for Tip { + fn default() -> Self { + Tip { + origin: [0.0; 3].into(), + orientation: Quat::IDENTITY.into(), } - Ok(()) } } -impl InputSpecialization for Tip { +impl InputDataTrait for Tip { fn compare_distance(&self, space: &Arc, field: &Field) -> f32 { - field.distance(space, vec3a(0.0, 0.0, 0.0)).abs() + field.distance(space, self.origin.into()).abs() } fn true_distance(&self, space: &Arc, field: &Field) -> f32 { - field.distance(space, vec3a(0.0, 0.0, 0.0)) + field.distance(space, self.origin.into()) } - fn serialize( - &self, - _distance_link: &DistanceLink, - local_to_handler_matrix: Mat4, - ) -> InputDataType { + fn update_to(&mut self, _distance_link: &DistanceLink, mut local_to_handler_matrix: Mat4) { + local_to_handler_matrix *= + Mat4::from_rotation_translation(self.orientation.into(), self.origin.into()); let (_, orientation, origin) = local_to_handler_matrix.to_scale_rotation_translation(); - InputDataType::Tip(FlatTip { - origin: origin.into(), - orientation: orientation.into(), - radius: self.radius, - }) - } -} - -pub fn create_tip_flex( - _node: Arc, - calling_client: Arc, - message: Message, -) -> Result<()> { - #[derive(Deserialize)] - struct CreateTipInfo<'a> { - name: &'a str, - parent_path: &'a str, - transform: Transform, - radius: f32, - datamap: Option>, + self.origin = origin.into(); + self.orientation = orientation.into(); } - let info: CreateTipInfo = deserialize(message.as_ref())?; - let node = Node::create_parent_name(&calling_client, "/input/method/tip", info.name, true); - let parent = calling_client - .get_node("Spatial parent", info.parent_path)? - .get_aspect::()?; - let transform = parse_transform(info.transform, true, true, false); - - let node = node.add_to_scenegraph()?; - Spatial::add_to(&node, Some(parent.clone()), transform, false); - InputMethod::add_to( - &node, - InputType::Tip(Tip { - radius: info.radius, - }), - info.datamap - .and_then(|datamap| Datamap::from_raw(datamap).ok()), - )?; - node.add_local_signal("set_radius", Tip::set_radius); - Ok(()) } diff --git a/src/objects/input/eye_pointer.rs b/src/objects/input/eye_pointer.rs index 81d9cf9c..2382e1ce 100644 --- a/src/objects/input/eye_pointer.rs +++ b/src/objects/input/eye_pointer.rs @@ -1,7 +1,7 @@ use crate::{ core::client::INTERNAL_CLIENT, nodes::{ - input::{pointer::Pointer, InputMethod, InputType}, + input::{InputDataType, InputMethod, Pointer}, spatial::Spatial, Node, }, @@ -9,11 +9,16 @@ use crate::{ use color_eyre::eyre::Result; use glam::Mat4; use nanoid::nanoid; -use serde::Serialize; -use stardust_xr::{schemas::flex::flexbuffers, values::Datamap}; +use serde::{Deserialize, Serialize}; +use stardust_xr::values::Datamap; use std::sync::Arc; use stereokit::StereoKitMultiThread; +#[derive(Default, Deserialize, Serialize)] +pub struct EyeDatamap { + eye: u32, +} + #[derive(Debug, Clone, Serialize)] pub struct KeyboardEvent { pub keyboard: String, @@ -31,8 +36,12 @@ impl EyePointer { let node = Node::create_parent_name(&INTERNAL_CLIENT, "", &nanoid!(), false) .add_to_scenegraph()?; let spatial = Spatial::add_to(&node, None, Mat4::IDENTITY, false); - let pointer = - InputMethod::add_to(&node, InputType::Pointer(Pointer::default()), None).unwrap(); + let pointer = InputMethod::add_to( + &node, + InputDataType::Pointer(Pointer::default()), + Datamap::from_typed(EyeDatamap::default())?, + ) + .unwrap(); Ok(EyePointer { spatial, pointer }) } @@ -45,11 +54,7 @@ impl EyePointer { )); { // Set pointer input datamap - let mut fbb = flexbuffers::Builder::default(); - let mut map = fbb.start_map(); - map.push("eye", 2); - map.end_map(); - *self.pointer.datamap.lock() = Datamap::from_raw(fbb.take_buffer()).ok(); + *self.pointer.datamap.lock() = Datamap::from_typed(EyeDatamap { eye: 2 }).unwrap(); } } } diff --git a/src/objects/input/mouse_pointer.rs b/src/objects/input/mouse_pointer.rs index a8b7ea1c..1f0a5c7d 100644 --- a/src/objects/input/mouse_pointer.rs +++ b/src/objects/input/mouse_pointer.rs @@ -5,7 +5,7 @@ use crate::{ mask_matches, pulse_receiver_client, PulseSender, KEYMAPS, PULSE_RECEIVER_REGISTRY, }, fields::{Field, Ray}, - input::{pointer::Pointer, InputMethod, InputType}, + input::{InputDataType, InputMethod, Pointer}, spatial::Spatial, Node, }, @@ -61,8 +61,11 @@ impl MousePointer { let node = Node::create_parent_name(&INTERNAL_CLIENT, "", &nanoid!(), false) .add_to_scenegraph()?; let spatial = Spatial::add_to(&node, None, Mat4::IDENTITY, false); - let pointer = - InputMethod::add_to(&node, InputType::Pointer(Pointer::default()), None).unwrap(); + let pointer = InputMethod::add_to( + &node, + InputDataType::Pointer(Pointer::default()), + Datamap::from_typed(MouseEvent::default())?, + )?; KEYMAPS.lock().insert( "flatscreen".to_string(), @@ -129,7 +132,7 @@ impl MousePointer { }; self.mouse_datamap.scroll_continuous = vec2(0.0, mouse.scroll_change / 120.0); self.mouse_datamap.scroll_discrete = vec2(0.0, mouse.scroll_change / 120.0); - *self.pointer.datamap.lock() = Datamap::from_typed(&self.mouse_datamap).ok(); + *self.pointer.datamap.lock() = Datamap::from_typed(&self.mouse_datamap).unwrap(); } self.send_keyboard_input(sk); } diff --git a/src/objects/input/sk_controller.rs b/src/objects/input/sk_controller.rs index fb70b626..42592846 100644 --- a/src/objects/input/sk_controller.rs +++ b/src/objects/input/sk_controller.rs @@ -1,7 +1,7 @@ use crate::{ core::client::INTERNAL_CLIENT, nodes::{ - input::{tip::Tip, InputMethod, InputType}, + input::{InputDataType, InputMethod, Tip}, spatial::Spatial, Node, }, @@ -45,8 +45,12 @@ impl SkController { .add_to_scenegraph()?; Spatial::add_to(&_node, None, Mat4::IDENTITY, false); let model = sk.model_create_mem("cursor.glb", include_bytes!("cursor.glb"), None)?; - let tip = InputType::Tip(Tip::default()); - let input = InputMethod::add_to(&_node, tip, None)?; + let tip = InputDataType::Tip(Tip::default()); + let input = InputMethod::add_to( + &_node, + tip, + Datamap::from_typed(ControllerDatamap::default())?, + )?; Ok(SkController { _node, input, @@ -74,6 +78,6 @@ impl SkController { self.datamap.select = controller.trigger; self.datamap.grab = controller.grip; self.datamap.scroll = controller.stick; - *self.input.datamap.lock() = Datamap::from_typed(&self.datamap).ok(); + *self.input.datamap.lock() = Datamap::from_typed(&self.datamap).unwrap(); } } diff --git a/src/objects/input/sk_hand.rs b/src/objects/input/sk_hand.rs index 627704df..00493447 100644 --- a/src/objects/input/sk_hand.rs +++ b/src/objects/input/sk_hand.rs @@ -1,19 +1,15 @@ -use crate::{ - core::client::INTERNAL_CLIENT, - nodes::{ - input::{hand::Hand, InputMethod, InputType}, - spatial::Spatial, - Node, - }, +use crate::core::client::INTERNAL_CLIENT; +use crate::nodes::input::InputDataType; +use crate::nodes::{ + input::{Hand, InputMethod, Joint}, + spatial::Spatial, + Node, }; use color_eyre::eyre::Result; use glam::Mat4; use nanoid::nanoid; use serde::{Deserialize, Serialize}; -use stardust_xr::{ - schemas::flat::{Hand as FlatHand, Joint}, - values::Datamap, -}; +use stardust_xr::values::Datamap; use std::sync::Arc; use stereokit::{ButtonState, HandJoint, Handed, StereoKitMultiThread}; @@ -43,13 +39,12 @@ impl SkHand { let _node = Node::create_parent_name(&INTERNAL_CLIENT, "", &nanoid!(), false) .add_to_scenegraph()?; Spatial::add_to(&_node, None, Mat4::IDENTITY, false); - let hand = InputType::Hand(Box::new(Hand { - base: FlatHand { - right: handed == Handed::Right, - ..Default::default() - }, - })); - let input = InputMethod::add_to(&_node, hand, None)?; + let hand = InputDataType::Hand(Hand { + right: handed == Handed::Right, + ..Default::default() + }); + let datamap = Datamap::from_typed(HandDatamap::default())?; + let input = InputMethod::add_to(&_node, hand, datamap)?; Ok(SkHand { _node, input, @@ -59,7 +54,7 @@ impl SkHand { } pub fn update(&mut self, controller_enabled: bool, sk: &impl StereoKitMultiThread) { let sk_hand = sk.input_hand(self.handed); - if let InputType::Hand(hand) = &mut *self.input.specialization.lock() { + if let InputDataType::Hand(hand) = &mut *self.input.data.lock() { let controller_active = controller_enabled && sk .input_controller(self.handed) @@ -69,16 +64,16 @@ impl SkHand { !controller_active && sk_hand.tracked_state.contains(ButtonState::ACTIVE); sk.input_hand_visible(self.handed, *self.input.enabled.lock()); if *self.input.enabled.lock() { - hand.base.thumb.tip = convert_joint(sk_hand.fingers[0][4]); - hand.base.thumb.distal = convert_joint(sk_hand.fingers[0][3]); - hand.base.thumb.proximal = convert_joint(sk_hand.fingers[0][2]); - hand.base.thumb.metacarpal = convert_joint(sk_hand.fingers[0][1]); + hand.thumb.tip = convert_joint(sk_hand.fingers[0][4]); + hand.thumb.distal = convert_joint(sk_hand.fingers[0][3]); + hand.thumb.proximal = convert_joint(sk_hand.fingers[0][2]); + hand.thumb.metacarpal = convert_joint(sk_hand.fingers[0][1]); for (finger, sk_finger) in [ - (&mut hand.base.index, sk_hand.fingers[1]), - (&mut hand.base.middle, sk_hand.fingers[2]), - (&mut hand.base.ring, sk_hand.fingers[3]), - (&mut hand.base.little, sk_hand.fingers[4]), + (&mut hand.index, sk_hand.fingers[1]), + (&mut hand.middle, sk_hand.fingers[2]), + (&mut hand.ring, sk_hand.fingers[3]), + (&mut hand.little, sk_hand.fingers[4]), ] { finger.tip = convert_joint(sk_finger[4]); finger.distal = convert_joint(sk_finger[3]); @@ -87,21 +82,21 @@ impl SkHand { finger.metacarpal = convert_joint(sk_finger[0]); } - hand.base.palm.position = sk_hand.palm.position.into(); - hand.base.palm.rotation = sk_hand.palm.orientation.into(); - hand.base.palm.radius = + hand.palm.position = sk_hand.palm.position.into(); + hand.palm.rotation = sk_hand.palm.orientation.into(); + hand.palm.radius = (sk_hand.fingers[2][0].radius + sk_hand.fingers[2][1].radius) * 0.5; - hand.base.wrist.position = sk_hand.wrist.position.into(); - hand.base.wrist.rotation = sk_hand.wrist.orientation.into(); - hand.base.wrist.radius = + hand.wrist.position = sk_hand.wrist.position.into(); + hand.wrist.rotation = sk_hand.wrist.orientation.into(); + hand.wrist.radius = (sk_hand.fingers[0][0].radius + sk_hand.fingers[4][0].radius) * 0.5; - hand.base.elbow = None; + hand.elbow = None; } } self.datamap.pinch_strength = sk_hand.pinch_activation; self.datamap.grab_strength = sk_hand.grip_activation; - *self.input.datamap.lock() = Datamap::from_typed(&self.datamap).ok(); + *self.input.datamap.lock() = Datamap::from_typed(&self.datamap).unwrap(); } }