fix PID params for lean; fix camera wobble; add torque arrow gizmo
This commit is contained in:
parent
040bf10f41
commit
d66a26d63c
6 changed files with 863 additions and 166 deletions
530
Cargo.lock
generated
530
Cargo.lock
generated
|
@ -180,6 +180,24 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arboard"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb4009533e8ff8f1450a5bcbc30f4242a1d34442221f72314bea1f5dc9c7f89"
|
||||
dependencies = [
|
||||
"clipboard-win",
|
||||
"core-graphics",
|
||||
"image 0.25.2",
|
||||
"log",
|
||||
"objc2",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation",
|
||||
"parking_lot",
|
||||
"windows-sys 0.48.0",
|
||||
"x11rb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.8"
|
||||
|
@ -333,6 +351,50 @@ dependencies = [
|
|||
"bevy_internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bevy-inspector-egui"
|
||||
version = "0.25.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8d77dbe53c8840aa74b66ea19dac6675d0a1752c989610cbded909d03967bec"
|
||||
dependencies = [
|
||||
"bevy-inspector-egui-derive",
|
||||
"bevy_app",
|
||||
"bevy_asset",
|
||||
"bevy_color",
|
||||
"bevy_core",
|
||||
"bevy_core_pipeline",
|
||||
"bevy_ecs",
|
||||
"bevy_egui",
|
||||
"bevy_hierarchy",
|
||||
"bevy_log",
|
||||
"bevy_math",
|
||||
"bevy_pbr",
|
||||
"bevy_reflect",
|
||||
"bevy_render",
|
||||
"bevy_state",
|
||||
"bevy_time",
|
||||
"bevy_utils",
|
||||
"bevy_window",
|
||||
"bytemuck",
|
||||
"egui",
|
||||
"fuzzy-matcher",
|
||||
"image 0.24.9",
|
||||
"once_cell",
|
||||
"pretty-type-name",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bevy-inspector-egui-derive"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "161d93f4b3a9246a87485e30ccf4cc927f204a14f26df42da977e383f0a0ec5d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bevy_a11y"
|
||||
version = "0.14.0"
|
||||
|
@ -598,6 +660,28 @@ dependencies = [
|
|||
"syn 2.0.71",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bevy_egui"
|
||||
version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e4a90f30f2849a07d91e393b10c0cc05df09b5773c010ddde57dd8b583be230"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"bevy",
|
||||
"bytemuck",
|
||||
"console_log",
|
||||
"crossbeam-channel",
|
||||
"egui",
|
||||
"js-sys",
|
||||
"log",
|
||||
"thread_local",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"webbrowser",
|
||||
"winit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bevy_encase_derive"
|
||||
version = "0.14.0"
|
||||
|
@ -907,7 +991,7 @@ dependencies = [
|
|||
"encase",
|
||||
"futures-lite",
|
||||
"hexasphere",
|
||||
"image",
|
||||
"image 0.25.2",
|
||||
"js-sys",
|
||||
"ktx2",
|
||||
"naga",
|
||||
|
@ -1320,6 +1404,18 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "calloop-wayland-source"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20"
|
||||
dependencies = [
|
||||
"calloop",
|
||||
"rustix",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.6"
|
||||
|
@ -1374,6 +1470,15 @@ dependencies = [
|
|||
"libloading 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
version = "5.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892"
|
||||
dependencies = [
|
||||
"error-code",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.11.1"
|
||||
|
@ -1384,6 +1489,12 @@ dependencies = [
|
|||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "com"
|
||||
version = "0.6.0"
|
||||
|
@ -1444,6 +1555,16 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console_log"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f"
|
||||
dependencies = [
|
||||
"log",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-fnv1a-hash"
|
||||
version = "1.1.0"
|
||||
|
@ -1687,12 +1808,43 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53"
|
||||
|
||||
[[package]]
|
||||
name = "ecolor"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e6b451ff1143f6de0f33fc7f1b68fecfd2c7de06e104de96c4514de3f5396f8"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"emath",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "egui"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20c97e70a2768de630f161bb5392cbd3874fcf72868f14df0e002e82e06cb798"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"emath",
|
||||
"epaint",
|
||||
"nohash-hasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "emath"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6a21708405ea88f63d8309650b4d77431f4bc28fb9d8e6f77d3963b51249e6"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encase"
|
||||
version = "0.8.0"
|
||||
|
@ -1725,6 +1877,21 @@ dependencies = [
|
|||
"syn 2.0.71",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "epaint"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f0dcc0a0771e7500e94cd1cb797bd13c9f23b9409bdc3c824e2cbc562b7fa01"
|
||||
dependencies = [
|
||||
"ab_glyph",
|
||||
"ahash",
|
||||
"bytemuck",
|
||||
"ecolor",
|
||||
"emath",
|
||||
"nohash-hasher",
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
|
@ -1751,6 +1918,12 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "error-code"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b"
|
||||
|
||||
[[package]]
|
||||
name = "euclid"
|
||||
version = "0.22.10"
|
||||
|
@ -1857,6 +2030,15 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.30"
|
||||
|
@ -1882,6 +2064,15 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuzzy-matcher"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
|
||||
dependencies = [
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fxhash"
|
||||
version = "0.2.1"
|
||||
|
@ -2160,6 +2351,37 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.24.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.25.2"
|
||||
|
@ -2170,6 +2392,7 @@ dependencies = [
|
|||
"byteorder-lite",
|
||||
"num-traits",
|
||||
"png",
|
||||
"tiff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2282,6 +2505,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jpeg-decoder"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.69"
|
||||
|
@ -2464,6 +2693,15 @@ version = "2.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "metal"
|
||||
version = "0.28.0"
|
||||
|
@ -2630,6 +2868,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nohash-hasher"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
|
@ -3114,6 +3358,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"avian3d",
|
||||
"bevy",
|
||||
"bevy-inspector-egui",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3202,6 +3447,12 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
|
||||
|
||||
[[package]]
|
||||
name = "pretty-type-name"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0f73cdaf19b52e6143685c3606206e114a4dfa969d6b14ec3894c88eb38bd4b"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "3.1.0"
|
||||
|
@ -3226,6 +3477,15 @@ version = "1.0.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58"
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
|
@ -3459,12 +3719,31 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "sctk-adwaita"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec"
|
||||
dependencies = [
|
||||
"ab_glyph",
|
||||
"log",
|
||||
"memmap2",
|
||||
"smithay-client-toolkit",
|
||||
"tiny-skia",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.23"
|
||||
|
@ -3566,6 +3845,31 @@ version = "1.13.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "smithay-client-toolkit"
|
||||
version = "0.19.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"calloop",
|
||||
"calloop-wayland-source",
|
||||
"cursor-icon",
|
||||
"libc",
|
||||
"log",
|
||||
"memmap2",
|
||||
"rustix",
|
||||
"thiserror",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-csd-frame",
|
||||
"wayland-cursor",
|
||||
"wayland-protocols",
|
||||
"wayland-protocols-wlr",
|
||||
"wayland-scanner",
|
||||
"xkeysym",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smol_str"
|
||||
version = "0.2.2"
|
||||
|
@ -3602,6 +3906,12 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "strict-num"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
||||
|
||||
[[package]]
|
||||
name = "svg_fmt"
|
||||
version = "0.4.3"
|
||||
|
@ -3696,6 +4006,42 @@ dependencies = [
|
|||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiff"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"jpeg-decoder",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-skia"
|
||||
version = "0.11.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"bytemuck",
|
||||
"cfg-if",
|
||||
"log",
|
||||
"tiny-skia-path",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-skia-path"
|
||||
version = "0.11.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bytemuck",
|
||||
"strict-num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.8.0"
|
||||
|
@ -3839,12 +4185,27 @@ version = "1.17.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.11.0"
|
||||
|
@ -3863,6 +4224,17 @@ version = "0.2.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.10.0"
|
||||
|
@ -3973,6 +4345,115 @@ version = "0.2.92"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||
|
||||
[[package]]
|
||||
name = "wayland-backend"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"downcast-rs",
|
||||
"rustix",
|
||||
"scoped-tls",
|
||||
"smallvec",
|
||||
"wayland-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-client"
|
||||
version = "0.31.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"rustix",
|
||||
"wayland-backend",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-csd-frame"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"cursor-icon",
|
||||
"wayland-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-cursor"
|
||||
version = "0.31.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ef9489a8df197ebf3a8ce8a7a7f0a2320035c3743f3c1bd0bdbccf07ce64f95"
|
||||
dependencies = [
|
||||
"rustix",
|
||||
"wayland-client",
|
||||
"xcursor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-protocols"
|
||||
version = "0.32.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-protocols-plasma"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f79f2d57c7fcc6ab4d602adba364bf59a5c24de57bd194486bf9b8360e06bfc4"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-protocols",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-protocols-wlr"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-protocols",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-scanner"
|
||||
version = "0.31.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quick-xml",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-sys"
|
||||
version = "0.31.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148"
|
||||
dependencies = [
|
||||
"dlib",
|
||||
"log",
|
||||
"once_cell",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.69"
|
||||
|
@ -3993,6 +4474,30 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webbrowser"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "425ba64c1e13b1c6e8c5d2541c8fac10022ca584f33da781db01b5756aef1f4e"
|
||||
dependencies = [
|
||||
"block2",
|
||||
"core-foundation",
|
||||
"home",
|
||||
"jni",
|
||||
"log",
|
||||
"ndk-context",
|
||||
"objc2",
|
||||
"objc2-foundation",
|
||||
"url",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
|
||||
|
||||
[[package]]
|
||||
name = "wgpu"
|
||||
version = "0.20.1"
|
||||
|
@ -4294,6 +4799,15 @@ dependencies = [
|
|||
"windows-targets 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
|
@ -4487,6 +5001,7 @@ version = "0.30.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4225ddd8ab67b8b59a2fee4b34889ebf13c0460c1c3fa297c58e21eb87801b33"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"android-activity",
|
||||
"atomic-waker",
|
||||
"bitflags 2.6.0",
|
||||
|
@ -4501,6 +5016,7 @@ dependencies = [
|
|||
"dpi",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"memmap2",
|
||||
"ndk 0.9.0",
|
||||
"objc2",
|
||||
"objc2-app-kit",
|
||||
|
@ -4512,11 +5028,17 @@ dependencies = [
|
|||
"raw-window-handle",
|
||||
"redox_syscall 0.4.1",
|
||||
"rustix",
|
||||
"sctk-adwaita",
|
||||
"smithay-client-toolkit",
|
||||
"smol_str",
|
||||
"tracing",
|
||||
"unicode-segmentation",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-protocols",
|
||||
"wayland-protocols-plasma",
|
||||
"web-sys",
|
||||
"web-time",
|
||||
"windows-sys 0.52.0",
|
||||
|
@ -4575,6 +5097,12 @@ version = "0.13.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d"
|
||||
|
||||
[[package]]
|
||||
name = "xcursor"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d491ee231a51ae64a5b762114c3ac2104b967aadba1de45c86ca42cf051513b7"
|
||||
|
||||
[[package]]
|
||||
name = "xi-unicode"
|
||||
version = "0.3.0"
|
||||
|
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
|||
[dependencies]
|
||||
avian3d = "0.1.1"
|
||||
bevy = { version = "0.14.0", features = ["bevy_dev_tools"] }
|
||||
bevy-inspector-egui = "0.25.1"
|
||||
|
||||
[features]
|
||||
no-mesh = []
|
||||
|
|
58
src/bike.rs
Normal file
58
src/bike.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use std::f32::consts::FRAC_PI_2;
|
||||
|
||||
use avian3d::prelude::*;
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::physics::CatControllerState;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct CyberBikeBody;
|
||||
|
||||
fn spawn_bike(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
let xform = Transform::from_xyz(0.0, 4.0, 0.0);
|
||||
let body_collider =
|
||||
Collider::capsule_endpoints(0.5, Vec3::new(0.0, 0.0, -0.65), Vec3::new(0.0, 0.0, 0.8));
|
||||
|
||||
let _bike = commands
|
||||
.spawn(SpatialBundle::from_transform(xform))
|
||||
.insert((
|
||||
RigidBody::Dynamic,
|
||||
body_collider,
|
||||
CollisionLayers::from_bits(1, 1),
|
||||
SleepingDisabled,
|
||||
CyberBikeBody,
|
||||
CatControllerState::default(),
|
||||
ColliderDensity(0.12),
|
||||
LinearDamping(0.1),
|
||||
AngularDamping(2.0),
|
||||
LinearVelocity::ZERO,
|
||||
AngularVelocity::ZERO,
|
||||
ExternalForce::ZERO.with_persistence(false),
|
||||
ExternalTorque::ZERO.with_persistence(false),
|
||||
))
|
||||
.with_children(|builder| {
|
||||
let color = Color::srgb(0.7, 0.05, 0.7);
|
||||
let mut rotation = Transform::default(); // Transform::from_rotation(Quat::from_rotation_y(FRAC_PI_2));
|
||||
rotation.rotate_x(FRAC_PI_2);
|
||||
let pbr_bundle = PbrBundle {
|
||||
mesh: meshes.add(Capsule3d::new(0.5, 1.45)),
|
||||
transform: rotation,
|
||||
material: materials.add(color),
|
||||
..Default::default()
|
||||
};
|
||||
builder.spawn(pbr_bundle);
|
||||
})
|
||||
.id();
|
||||
}
|
||||
|
||||
pub struct CyberBikePlugin;
|
||||
|
||||
impl Plugin for CyberBikePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, spawn_bike);
|
||||
}
|
||||
}
|
98
src/camera.rs
Normal file
98
src/camera.rs
Normal file
|
@ -0,0 +1,98 @@
|
|||
use bevy::{prelude::*, utils::HashSet};
|
||||
|
||||
use crate::bike::CyberBikeBody;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct CyberCameras;
|
||||
|
||||
#[derive(Debug, Resource)]
|
||||
pub struct DebugCamOffset {
|
||||
pub rot: f32,
|
||||
pub dist: f32,
|
||||
pub alt: f32,
|
||||
}
|
||||
|
||||
impl Default for DebugCamOffset {
|
||||
fn default() -> Self {
|
||||
DebugCamOffset {
|
||||
rot: 60.0,
|
||||
dist: 10.0,
|
||||
alt: 4.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_camera(mut commands: Commands) {
|
||||
commands
|
||||
.spawn(Camera3dBundle::default())
|
||||
.insert(CyberCameras);
|
||||
}
|
||||
|
||||
fn update_camera_pos(mut offset: ResMut<DebugCamOffset>, mut keys: ResMut<ButtonInput<KeyCode>>) {
|
||||
let keyset: HashSet<_> = keys.get_pressed().collect();
|
||||
let shifted = keyset.contains(&KeyCode::ShiftLeft) || keyset.contains(&KeyCode::ShiftRight);
|
||||
|
||||
for key in keyset {
|
||||
match key {
|
||||
KeyCode::ArrowLeft => offset.rot -= 5.0,
|
||||
KeyCode::ArrowRight => offset.rot += 5.0,
|
||||
KeyCode::ArrowUp => {
|
||||
if shifted {
|
||||
bevy::log::info!("up, shifted");
|
||||
offset.alt += 0.5;
|
||||
} else {
|
||||
bevy::log::info!("up");
|
||||
offset.dist -= 0.5;
|
||||
}
|
||||
}
|
||||
KeyCode::ArrowDown => {
|
||||
if shifted {
|
||||
bevy::log::info!("down, shifted");
|
||||
offset.alt -= 0.5;
|
||||
} else {
|
||||
bevy::log::info!("down");
|
||||
offset.dist += 0.5;
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
|
||||
let just_released: HashSet<_> = keys.get_just_released().cloned().collect();
|
||||
if !just_released.is_empty() {
|
||||
let released_shift = just_released.contains(&KeyCode::ShiftLeft)
|
||||
|| just_released.contains(&KeyCode::ShiftRight);
|
||||
keys.reset_all();
|
||||
if !released_shift && shifted {
|
||||
keys.press(KeyCode::ShiftLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn follow_bike(
|
||||
mut camera: Query<&mut Transform, (With<CyberCameras>, Without<CyberBikeBody>)>,
|
||||
bike: Query<&Transform, (With<CyberBikeBody>, Without<CyberCameras>)>,
|
||||
offset: Res<DebugCamOffset>,
|
||||
) {
|
||||
let bike_xform = *bike.single();
|
||||
let up = Vec3::Y;
|
||||
|
||||
let mut ncx = Transform::from_translation(bike_xform.translation);
|
||||
ncx.rotate(Quat::from_axis_angle(up, offset.rot.to_radians()));
|
||||
ncx.translation += ncx.forward() * offset.dist;
|
||||
ncx.translation += ncx.up() * offset.alt;
|
||||
ncx.look_at(bike_xform.translation, up);
|
||||
|
||||
let mut cam_xform = camera.single_mut();
|
||||
*cam_xform = ncx;
|
||||
}
|
||||
|
||||
pub struct CamPlug;
|
||||
|
||||
impl Plugin for CamPlug {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.insert_resource(DebugCamOffset::default())
|
||||
.add_systems(Startup, spawn_camera)
|
||||
.add_systems(Update, (follow_bike, update_camera_pos));
|
||||
}
|
||||
}
|
176
src/main.rs
176
src/main.rs
|
@ -1,16 +1,23 @@
|
|||
use avian3d::prelude::*;
|
||||
use bevy::{self, color::palettes::css::SILVER, prelude::*};
|
||||
use bevy_inspector_egui::quick::WorldInspectorPlugin;
|
||||
|
||||
mod bike;
|
||||
mod camera;
|
||||
mod physics;
|
||||
|
||||
use bike::CyberBikePlugin;
|
||||
use camera::CamPlug;
|
||||
use physics::CyberPhysicsPlugin;
|
||||
|
||||
fn main() {
|
||||
let mut app = App::new();
|
||||
app.add_plugins((
|
||||
DefaultPlugins,
|
||||
PhysicsPlugins::default(),
|
||||
PhysicsDebugPlugin::default(),
|
||||
CamPlug,
|
||||
CyberBikePlugin,
|
||||
CyberPhysicsPlugin,
|
||||
WorldInspectorPlugin::new(),
|
||||
))
|
||||
.insert_gizmo_config(
|
||||
PhysicsGizmos {
|
||||
|
@ -19,7 +26,7 @@ fn main() {
|
|||
joint_separation_color: Some(Srgba::RED.into()),
|
||||
#[cfg(feature = "no-mesh")]
|
||||
hide_meshes: true,
|
||||
//axis_lengths: Some(Vec3::ZERO),
|
||||
axis_lengths: Some(Vec3::new(2.0, 2.0, 4.0)),
|
||||
..Default::default()
|
||||
},
|
||||
GizmoConfig::default(),
|
||||
|
@ -40,7 +47,7 @@ fn ground_and_light(
|
|||
PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)),
|
||||
material: materials.add(Color::from(SILVER)),
|
||||
transform: Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
transform: Transform::from_xyz(0.0, -3., 0.0),
|
||||
..default()
|
||||
},
|
||||
));
|
||||
|
@ -72,164 +79,3 @@ fn close_on_esc(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod bike {
|
||||
use std::f32::consts::FRAC_PI_2;
|
||||
|
||||
use avian3d::prelude::*;
|
||||
use bevy::prelude::*;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct CyberBikeBody;
|
||||
|
||||
fn spawn_bike(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
let xform = Transform::from_xyz(0.0, 4.0, 0.0);
|
||||
let body_collider =
|
||||
Collider::capsule_endpoints(0.5, Vec3::new(0.0, 0.0, -0.65), Vec3::new(0.0, 0.0, 0.8));
|
||||
|
||||
let _bike = commands
|
||||
.spawn(SpatialBundle::from_transform(xform))
|
||||
.insert((
|
||||
RigidBody::Dynamic,
|
||||
body_collider,
|
||||
SleepingDisabled,
|
||||
CyberBikeBody,
|
||||
//CatControllerState::default(),
|
||||
ColliderDensity(0.06),
|
||||
LinearDamping(0.1),
|
||||
AngularDamping(2.0),
|
||||
LinearVelocity::ZERO,
|
||||
AngularVelocity::ZERO,
|
||||
ExternalForce::ZERO.with_persistence(false),
|
||||
ExternalTorque::ZERO.with_persistence(false),
|
||||
))
|
||||
.with_children(|builder| {
|
||||
let color = Color::srgb(0.7, 0.05, 0.7);
|
||||
let mut rotation = Transform::from_rotation(Quat::from_rotation_y(FRAC_PI_2));
|
||||
rotation.rotate_x(FRAC_PI_2);
|
||||
let pbr_bundle = PbrBundle {
|
||||
mesh: meshes.add(Capsule3d::new(0.5, 1.45)),
|
||||
transform: rotation,
|
||||
material: materials.add(color),
|
||||
..Default::default()
|
||||
};
|
||||
builder.spawn(pbr_bundle);
|
||||
});
|
||||
}
|
||||
|
||||
pub struct CyberBikePlugin;
|
||||
|
||||
impl Plugin for CyberBikePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, spawn_bike);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod camera {
|
||||
use bevy::{prelude::*, utils::HashSet};
|
||||
|
||||
use crate::bike::CyberBikeBody;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct CyberCameras;
|
||||
|
||||
#[derive(Debug, Resource)]
|
||||
pub struct DebugCamOffset {
|
||||
pub rot: f32,
|
||||
pub dist: f32,
|
||||
pub alt: f32,
|
||||
}
|
||||
|
||||
impl Default for DebugCamOffset {
|
||||
fn default() -> Self {
|
||||
DebugCamOffset {
|
||||
rot: 60.0,
|
||||
dist: 10.0,
|
||||
alt: 4.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_camera(mut commands: Commands) {
|
||||
commands
|
||||
.spawn(Camera3dBundle::default())
|
||||
.insert(CyberCameras);
|
||||
}
|
||||
|
||||
fn update_camera_pos(
|
||||
mut offset: ResMut<DebugCamOffset>,
|
||||
mut keys: ResMut<ButtonInput<KeyCode>>,
|
||||
) {
|
||||
let keyset: HashSet<_> = keys.get_pressed().collect();
|
||||
let shifted = keyset.contains(&KeyCode::ShiftLeft) || keyset.contains(&KeyCode::ShiftRight);
|
||||
|
||||
for key in keyset {
|
||||
match key {
|
||||
KeyCode::ArrowLeft => offset.rot -= 5.0,
|
||||
KeyCode::ArrowRight => offset.rot += 5.0,
|
||||
KeyCode::ArrowUp => {
|
||||
if shifted {
|
||||
bevy::log::info!("up, shifted");
|
||||
offset.alt += 0.5;
|
||||
} else {
|
||||
bevy::log::info!("up");
|
||||
offset.dist -= 0.5;
|
||||
}
|
||||
}
|
||||
KeyCode::ArrowDown => {
|
||||
if shifted {
|
||||
bevy::log::info!("down, shifted");
|
||||
offset.alt -= 0.5;
|
||||
} else {
|
||||
bevy::log::info!("down");
|
||||
offset.dist += 0.5;
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
|
||||
let just_released: HashSet<_> = keys.get_just_released().cloned().collect();
|
||||
if !just_released.is_empty() {
|
||||
let released_shift = just_released.contains(&KeyCode::ShiftLeft)
|
||||
|| just_released.contains(&KeyCode::ShiftRight);
|
||||
keys.reset_all();
|
||||
if !released_shift && shifted {
|
||||
keys.press(KeyCode::ShiftLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn follow_bike(
|
||||
mut camera: Query<&mut Transform, (With<CyberCameras>, Without<CyberBikeBody>)>,
|
||||
bike: Query<&Transform, (With<CyberBikeBody>, Without<CyberCameras>)>,
|
||||
offset: Res<DebugCamOffset>,
|
||||
) {
|
||||
let bike_xform = *bike.single();
|
||||
let up = Vec3::Y;
|
||||
|
||||
let mut ncx = bike_xform;
|
||||
ncx.rotate(Quat::from_axis_angle(up, offset.rot.to_radians()));
|
||||
ncx.translation += ncx.forward() * offset.dist;
|
||||
ncx.translation += ncx.up() * offset.alt;
|
||||
ncx.look_at(bike_xform.translation, up);
|
||||
|
||||
let mut cam_xform = camera.single_mut();
|
||||
*cam_xform = ncx;
|
||||
}
|
||||
|
||||
pub struct CamPlug;
|
||||
|
||||
impl Plugin for CamPlug {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.insert_resource(DebugCamOffset::default())
|
||||
.add_systems(Startup, spawn_camera)
|
||||
.add_systems(Update, (follow_bike, update_camera_pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
166
src/physics.rs
Normal file
166
src/physics.rs
Normal file
|
@ -0,0 +1,166 @@
|
|||
use avian3d::prelude::*;
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::CyberBikePlugin;
|
||||
|
||||
#[derive(Resource, Default, Debug, Reflect)]
|
||||
#[reflect(Resource)]
|
||||
struct CyberLean {
|
||||
pub lean: f32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Resource, Reflect)]
|
||||
#[reflect(Resource)]
|
||||
pub struct CatControllerSettings {
|
||||
pub kp: f32,
|
||||
pub kd: f32,
|
||||
pub ki: f32,
|
||||
}
|
||||
|
||||
impl Default for CatControllerSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
kp: 10.0,
|
||||
kd: 1.0,
|
||||
ki: 0.1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Clone, Copy)]
|
||||
pub struct CatControllerState {
|
||||
pub roll_integral: f32,
|
||||
pub roll_prev: f32,
|
||||
decay_factor: f32,
|
||||
roll_limit: f32,
|
||||
}
|
||||
|
||||
impl Default for CatControllerState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
roll_integral: Default::default(),
|
||||
roll_prev: Default::default(),
|
||||
decay_factor: 0.99,
|
||||
roll_limit: 1.5,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CatControllerState {
|
||||
pub fn decay(&mut self) {
|
||||
if self.roll_integral.abs() > 0.001 {
|
||||
self.roll_integral *= self.decay_factor;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_roll(&mut self, error: f32, dt: f32) -> (f32, f32) {
|
||||
let lim = self.roll_limit;
|
||||
self.roll_integral = (self.roll_integral + (error * dt)).min(lim).max(-lim);
|
||||
let derivative = (error - self.roll_prev) / dt;
|
||||
self.roll_prev = error;
|
||||
(derivative, self.roll_integral)
|
||||
}
|
||||
|
||||
pub fn set_integral_limits(&mut self, roll: f32) {
|
||||
self.roll_limit = roll;
|
||||
}
|
||||
}
|
||||
|
||||
mod systems {
|
||||
use std::f32::consts::{FRAC_PI_3, FRAC_PI_4};
|
||||
|
||||
use avian3d::prelude::*;
|
||||
use bevy::prelude::*;
|
||||
|
||||
use super::{CatControllerSettings, CatControllerState, CyberLean};
|
||||
use crate::bike::CyberBikeBody;
|
||||
|
||||
fn _yaw_to_angle(yaw: f32) -> f32 {
|
||||
let v = yaw.powi(5) * FRAC_PI_4;
|
||||
if v.is_normal() {
|
||||
v
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
fn rotate_point(pt: &Vec3, rot: &Quat) -> Vec3 {
|
||||
// thanks to https://danceswithcode.net/engineeringnotes/quaternions/quaternions.html
|
||||
let [x, y, z] = pt.normalize().to_array();
|
||||
let qpt = Quat::from_xyzw(x, y, z, 0.0);
|
||||
// p' = rot^-1 * qpt * rot
|
||||
let rot_qpt = rot.inverse() * qpt * *rot;
|
||||
|
||||
// why does this need to be inverted???
|
||||
-Vec3::from_array([rot_qpt.x, rot_qpt.y, rot_qpt.z])
|
||||
}
|
||||
|
||||
pub(super) fn calculate_lean(
|
||||
bike_state: Query<(&LinearVelocity, &Transform), With<CyberBikeBody>>,
|
||||
mut lean: ResMut<CyberLean>,
|
||||
) {
|
||||
let (velocity, xform) = bike_state.single();
|
||||
let vel = velocity.dot(*xform.forward());
|
||||
let v_squared = vel.powi(2);
|
||||
let wheel_base = 1.145f32;
|
||||
let radius = wheel_base;
|
||||
let gravity = -9.8f32;
|
||||
let v2_r = v_squared / radius;
|
||||
let tan_theta = (v2_r / gravity).clamp(-FRAC_PI_3, FRAC_PI_3);
|
||||
|
||||
if tan_theta.is_finite() && !tan_theta.is_subnormal() {
|
||||
lean.lean = tan_theta.atan().clamp(-FRAC_PI_3, FRAC_PI_3);
|
||||
} else {
|
||||
lean.lean = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn apply_lean(
|
||||
mut bike_query: Query<(&Transform, &mut ExternalTorque, &mut CatControllerState)>,
|
||||
time: Res<Time>,
|
||||
settings: Res<CatControllerSettings>,
|
||||
lean: Res<CyberLean>,
|
||||
mut gizmos: Gizmos,
|
||||
) {
|
||||
let (xform, mut torque, mut control_vars) = bike_query.single_mut();
|
||||
let world_up = xform.translation.normalize();
|
||||
let rot = Quat::from_axis_angle(*xform.back(), lean.lean);
|
||||
let target_up = rotate_point(&world_up, &rot).normalize();
|
||||
|
||||
let bike_right = xform.right();
|
||||
|
||||
let roll_error = bike_right.dot(target_up);
|
||||
let pitch_error = world_up.dot(*xform.back());
|
||||
|
||||
// only try to correct roll if we're not totally vertical
|
||||
if pitch_error.abs() < 0.95 {
|
||||
let (derivative, integral) = control_vars.update_roll(roll_error, time.delta_seconds());
|
||||
let mag =
|
||||
(settings.kp * roll_error) + (settings.ki * integral) + (settings.kd * derivative);
|
||||
if mag.is_finite() {
|
||||
let tork = mag * *xform.back();
|
||||
torque.apply_torque(tork);
|
||||
gizmos.arrow(
|
||||
xform.translation + Vec3::Y,
|
||||
xform.translation + tork + Vec3::Y,
|
||||
Color::WHITE,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use systems::{apply_lean, calculate_lean};
|
||||
|
||||
pub struct CyberPhysicsPlugin;
|
||||
|
||||
impl Plugin for CyberPhysicsPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<CatControllerSettings>()
|
||||
.register_type::<CatControllerSettings>()
|
||||
.init_resource::<CyberLean>()
|
||||
.register_type::<CyberLean>()
|
||||
.add_plugins((PhysicsPlugins::default(), PhysicsDebugPlugin::default()))
|
||||
.add_systems(Update, (apply_lean, calculate_lean));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue