Merge branch 'physics'
This commit is contained in:
commit
d1a8c536eb
280
Cargo.lock
generated
280
Cargo.lock
generated
|
@ -1020,6 +1020,34 @@ dependencies = [
|
||||||
"winit",
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bevy_xpbd_3d"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0425ea7361b9b27c2a382e0663deb42f41147eee60fb2b3d5fa7e42d363ea848"
|
||||||
|
dependencies = [
|
||||||
|
"bevy",
|
||||||
|
"bevy_math",
|
||||||
|
"bevy_xpbd_derive",
|
||||||
|
"derive_more",
|
||||||
|
"fxhash",
|
||||||
|
"indexmap",
|
||||||
|
"itertools",
|
||||||
|
"nalgebra",
|
||||||
|
"parry3d",
|
||||||
|
"parry3d-f64",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bevy_xpbd_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3e1ef1d5e328abe1b76df974245f78e17fd17867583883d5e77444c6a8223a64"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.52",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bindgen"
|
name = "bindgen"
|
||||||
version = "0.69.4"
|
version = "0.69.4"
|
||||||
|
@ -1358,6 +1386,12 @@ dependencies = [
|
||||||
"const_soft_float",
|
"const_soft_float",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "convert_case"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
|
@ -1459,6 +1493,25 @@ dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.19"
|
version = "0.8.19"
|
||||||
|
@ -1500,8 +1553,10 @@ version = "0.99.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"convert_case",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
"rustc_version",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1729,6 +1784,15 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fxhash"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gethostname"
|
name = "gethostname"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
@ -2134,6 +2198,12 @@ dependencies = [
|
||||||
"windows-targets 0.52.4",
|
"windows-targets 0.52.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libm"
|
||||||
|
version = "0.2.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libredox"
|
name = "libredox"
|
||||||
version = "0.0.2"
|
version = "0.0.2"
|
||||||
|
@ -2194,6 +2264,16 @@ dependencies = [
|
||||||
"regex-automata 0.1.10",
|
"regex-automata 0.1.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matrixmultiply"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"rawpointer",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.1"
|
version = "2.7.1"
|
||||||
|
@ -2272,6 +2352,34 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nalgebra"
|
||||||
|
version = "0.32.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ea4908d4f23254adda3daa60ffef0f1ac7b8c3e9a864cf3cc154b251908a2ef"
|
||||||
|
dependencies = [
|
||||||
|
"approx",
|
||||||
|
"glam",
|
||||||
|
"matrixmultiply",
|
||||||
|
"nalgebra-macros",
|
||||||
|
"num-complex",
|
||||||
|
"num-rational",
|
||||||
|
"num-traits",
|
||||||
|
"simba",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nalgebra-macros"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ndk"
|
name = "ndk"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
@ -2337,6 +2445,15 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-complex"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-derive"
|
name = "num-derive"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
@ -2348,6 +2465,26 @@ dependencies = [
|
||||||
"syn 2.0.52",
|
"syn 2.0.52",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.46"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-rational"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.18"
|
version = "0.2.18"
|
||||||
|
@ -2355,6 +2492,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
|
"libm",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2498,6 +2636,7 @@ version = "0.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy",
|
"bevy",
|
||||||
"bevy_embedded_assets",
|
"bevy_embedded_assets",
|
||||||
|
"bevy_xpbd_3d",
|
||||||
"regex",
|
"regex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2545,6 +2684,50 @@ dependencies = [
|
||||||
"windows-targets 0.48.5",
|
"windows-targets 0.48.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parry3d"
|
||||||
|
version = "0.13.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ccba18a65dba56c08dadfa936e0c9efbc883b3a26dc77d2685f78be10f7667c"
|
||||||
|
dependencies = [
|
||||||
|
"approx",
|
||||||
|
"arrayvec",
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"downcast-rs",
|
||||||
|
"either",
|
||||||
|
"nalgebra",
|
||||||
|
"num-derive",
|
||||||
|
"num-traits",
|
||||||
|
"rayon",
|
||||||
|
"rustc-hash",
|
||||||
|
"simba",
|
||||||
|
"slab",
|
||||||
|
"smallvec",
|
||||||
|
"spade",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parry3d-f64"
|
||||||
|
version = "0.13.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d259245abcc09379798e4d373d9019e0df4dc6f7f128ecd68700a5927dc32034"
|
||||||
|
dependencies = [
|
||||||
|
"approx",
|
||||||
|
"arrayvec",
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"downcast-rs",
|
||||||
|
"either",
|
||||||
|
"nalgebra",
|
||||||
|
"num-derive",
|
||||||
|
"num-traits",
|
||||||
|
"rayon",
|
||||||
|
"rustc-hash",
|
||||||
|
"simba",
|
||||||
|
"slab",
|
||||||
|
"smallvec",
|
||||||
|
"spade",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
|
@ -2683,6 +2866,32 @@ version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544"
|
checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rawpointer"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rectangle-pack"
|
name = "rectangle-pack"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
@ -2757,6 +2966,12 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
|
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "robust"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cbf4a6aa5f6d6888f39e980649f3ad6b666acdce1d78e95b8a2cb076e687ae30"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rodio"
|
name = "rodio"
|
||||||
version = "0.17.3"
|
version = "0.17.3"
|
||||||
|
@ -2785,6 +3000,15 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.31"
|
version = "0.38.31"
|
||||||
|
@ -2815,6 +3039,15 @@ version = "1.0.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "safe_arch"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "same-file"
|
name = "same-file"
|
||||||
version = "1.0.6"
|
version = "1.0.6"
|
||||||
|
@ -2830,6 +3063,12 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.197"
|
version = "1.0.197"
|
||||||
|
@ -2876,6 +3115,19 @@ version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simba"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae"
|
||||||
|
dependencies = [
|
||||||
|
"approx",
|
||||||
|
"num-complex",
|
||||||
|
"num-traits",
|
||||||
|
"paste",
|
||||||
|
"wide",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simd-adler32"
|
name = "simd-adler32"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
|
@ -2918,6 +3170,18 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spade"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "61addf9117b11d1f5b4bf6fe94242ba25f59d2d4b2080544b771bd647024fd00"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown",
|
||||||
|
"num-traits",
|
||||||
|
"robust",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spirv"
|
name = "spirv"
|
||||||
version = "0.3.0+sdk-1.3.268.0"
|
version = "0.3.0+sdk-1.3.268.0"
|
||||||
|
@ -3157,6 +3421,12 @@ dependencies = [
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
|
@ -3412,6 +3682,16 @@ dependencies = [
|
||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wide"
|
||||||
|
version = "0.7.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "89beec544f246e679fc25490e3f8e08003bc4bf612068f325120dad4cea02c1c"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
"safe_arch",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "widestring"
|
name = "widestring"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
|
|
@ -11,8 +11,9 @@ rust-version = "1.76.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
regex = "1"
|
regex = "1"
|
||||||
bevy_embedded_assets = "0.10.2"
|
|
||||||
bevy = { version = "0.13.0", default-features = false, features = ["jpeg", "bevy_asset", "bevy_audio", "bevy_scene", "bevy_winit", "bevy_core_pipeline", "bevy_pbr", "bevy_gltf", "bevy_render", "bevy_text", "bevy_ui", "multi-threaded", "png", "vorbis", "x11", "tonemapping_luts"]}
|
bevy = { version = "0.13.0", default-features = false, features = ["jpeg", "bevy_asset", "bevy_audio", "bevy_scene", "bevy_winit", "bevy_core_pipeline", "bevy_pbr", "bevy_gltf", "bevy_render", "bevy_text", "bevy_ui", "multi-threaded", "png", "vorbis", "x11", "tonemapping_luts"]}
|
||||||
|
bevy_xpbd_3d = { version = "0.4", default-features = false, features = ["3d", "f32", "parry-f32", "parallel"] }
|
||||||
|
bevy_embedded_assets = "0.10.2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
dev = ["bevy/dynamic_linking"]
|
dev = ["bevy/dynamic_linking"]
|
||||||
|
|
|
@ -24,6 +24,7 @@ Key features:
|
||||||
- t: toggle music (NOTE: currently no music is included in the git repo)
|
- t: toggle music (NOTE: currently no music is included in the git repo)
|
||||||
- m: mute sound effects
|
- m: mute sound effects
|
||||||
- q: enter/exit vehicle
|
- q: enter/exit vehicle
|
||||||
|
- f: toggle 3rd person view
|
||||||
- TAB: toggle augmented reality overlay (HUD, low-light amplifier)
|
- TAB: toggle augmented reality overlay (HUD, low-light amplifier)
|
||||||
|
|
||||||
# System Requirements
|
# System Requirements
|
||||||
|
@ -113,6 +114,7 @@ cargo run --release
|
||||||
- https://pixabay.com/sound-effects/electricity-6353
|
- https://pixabay.com/sound-effects/electricity-6353
|
||||||
- https://pixabay.com/sound-effects/ducati-696-monster-33217
|
- https://pixabay.com/sound-effects/ducati-696-monster-33217
|
||||||
- https://pixabay.com/sound-effects/high-energy-humming-195612
|
- https://pixabay.com/sound-effects/high-energy-humming-195612
|
||||||
|
- https://pixabay.com/sound-effects/box-crash-106687
|
||||||
- Music: [Dead Space Style Ambient Music](https://pixabay.com/music/ambient-dead-space-style-ambient-music-184793) by [Sharvarian](https://www.fiverr.com/sharvarian)
|
- Music: [Dead Space Style Ambient Music](https://pixabay.com/music/ambient-dead-space-style-ambient-music-184793) by [Sharvarian](https://www.fiverr.com/sharvarian)
|
||||||
- Star chart based on the [HYG Stellar database](https://github.com/astronexus/HYG-Database)
|
- Star chart based on the [HYG Stellar database](https://github.com/astronexus/HYG-Database)
|
||||||
- Custom font Yupiter is based on:
|
- Custom font Yupiter is based on:
|
||||||
|
|
Binary file not shown.
BIN
assets/sounds/crash.ogg
Normal file
BIN
assets/sounds/crash.ogg
Normal file
Binary file not shown.
83
src/actor.rs
83
src/actor.rs
|
@ -1,4 +1,6 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
use bevy::transform::TransformSystem;
|
||||||
|
use bevy_xpbd_3d::prelude::*;
|
||||||
use crate::{nature, settings, actor, audio, hud};
|
use crate::{nature, settings, actor, audio, hud};
|
||||||
|
|
||||||
pub const ENGINE_SPEED_FACTOR: f32 = 30.0;
|
pub const ENGINE_SPEED_FACTOR: f32 = 30.0;
|
||||||
|
@ -11,7 +13,6 @@ impl Plugin for ActorPlugin {
|
||||||
app.register_type::<ChatBranch>();
|
app.register_type::<ChatBranch>();
|
||||||
app.add_systems(FixedUpdate, (
|
app.add_systems(FixedUpdate, (
|
||||||
update_physics_lifeforms,
|
update_physics_lifeforms,
|
||||||
update_physics_actors,
|
|
||||||
));
|
));
|
||||||
app.add_systems(Update, (
|
app.add_systems(Update, (
|
||||||
handle_new_conversations,
|
handle_new_conversations,
|
||||||
|
@ -19,7 +20,8 @@ impl Plugin for ActorPlugin {
|
||||||
handle_conversations,
|
handle_conversations,
|
||||||
handle_input,
|
handle_input,
|
||||||
handle_chat_scripts,
|
handle_chat_scripts,
|
||||||
handle_vehicle_enter_exit,
|
handle_vehicle_enter_exit.after(PhysicsSet::Sync).before(TransformSystem::TransformPropagate),
|
||||||
|
handle_collisions,
|
||||||
));
|
));
|
||||||
app.add_event::<StartConversationEvent>();
|
app.add_event::<StartConversationEvent>();
|
||||||
app.add_event::<SendMessageEvent>();
|
app.add_event::<SendMessageEvent>();
|
||||||
|
@ -63,6 +65,7 @@ pub struct Actor {
|
||||||
pub v: Vec3, // velocity
|
pub v: Vec3, // velocity
|
||||||
pub angular_momentum: Quat,
|
pub angular_momentum: Quat,
|
||||||
pub inside_entity: u32,
|
pub inside_entity: u32,
|
||||||
|
pub camdistance: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Actor {
|
impl Default for Actor {
|
||||||
|
@ -74,12 +77,14 @@ impl Default for Actor {
|
||||||
v: Vec3::ZERO,
|
v: Vec3::ZERO,
|
||||||
inside_entity: NO_RIDE,
|
inside_entity: NO_RIDE,
|
||||||
angular_momentum: Quat::from_euler(EulerRot::XYZ, 0.001, 0.01, 0.003),
|
angular_momentum: Quat::from_euler(EulerRot::XYZ, 0.001, 0.01, 0.003),
|
||||||
|
camdistance: 15.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)] pub struct Player;
|
#[derive(Component)] pub struct Player; // Attached to the suit of the player
|
||||||
#[derive(Component)] pub struct PlayerDrivesThis;
|
#[derive(Component)] pub struct PlayerDrivesThis; // Attached to the entered vehicle
|
||||||
|
#[derive(Component)] pub struct PlayerCamera; // Attached to the actor to use as point of view
|
||||||
#[derive(Component)] pub struct PlayerInConversation;
|
#[derive(Component)] pub struct PlayerInConversation;
|
||||||
#[derive(Component)] pub struct InConversationWithPlayer;
|
#[derive(Component)] pub struct InConversationWithPlayer;
|
||||||
#[derive(Component)] pub struct ActorEnteringVehicle;
|
#[derive(Component)] pub struct ActorEnteringVehicle;
|
||||||
|
@ -187,19 +192,6 @@ const SUIT_SIMPLE: Suit = Suit {
|
||||||
integrity: 1e5,
|
integrity: 1e5,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn update_physics_actors(
|
|
||||||
time: Res<Time>,
|
|
||||||
mut q_actors: Query<(&mut Actor, &mut Transform)>,
|
|
||||||
) {
|
|
||||||
let d = time.delta_seconds();
|
|
||||||
for (actor, mut transform) in q_actors.iter_mut() {
|
|
||||||
transform.rotate(actor.angular_momentum);
|
|
||||||
// TODO: animate only a step based on time between update:
|
|
||||||
//transform.rotate(actor.angular_momentum.slerp(Quat::IDENTITY, d)); // not working
|
|
||||||
transform.translation += d * actor.v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_physics_lifeforms(
|
pub fn update_physics_lifeforms(
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
mut query: Query<(&mut LifeForm, &mut Suit, &Actor)>,
|
mut query: Query<(&mut LifeForm, &mut Suit, &Actor)>,
|
||||||
|
@ -294,6 +286,7 @@ pub fn handle_input(
|
||||||
is_entering: false,
|
is_entering: false,
|
||||||
is_player: true,
|
is_player: true,
|
||||||
});
|
});
|
||||||
|
commands.entity(player_entity).insert(RigidBody::Dynamic);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,41 +297,43 @@ pub fn handle_input(
|
||||||
pub fn handle_vehicle_enter_exit(
|
pub fn handle_vehicle_enter_exit(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut er_vehicle: EventReader<VehicleEnterExitEvent>,
|
mut er_vehicle: EventReader<VehicleEnterExitEvent>,
|
||||||
mut q_drivers: Query<(Entity, &mut Actor, &mut Visibility, &mut Transform), (Without<ActorVehicleBeingEntered>, With<ActorEnteringVehicle>)>,
|
mut q_drivers: Query<(Entity, &mut Visibility, &mut Transform, &mut LinearVelocity, &mut AngularVelocity), (Without<ActorVehicleBeingEntered>, With<ActorEnteringVehicle>)>,
|
||||||
mut q_vehicles: Query<(Entity, &mut Actor, &mut Visibility, &mut Transform), (With<ActorVehicleBeingEntered>, Without<ActorEnteringVehicle>)>,
|
mut q_vehicles: Query<(Entity, &mut Visibility, &mut Transform, &LinearVelocity, &AngularVelocity), (With<ActorVehicleBeingEntered>, Without<ActorEnteringVehicle>)>,
|
||||||
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||||
) {
|
) {
|
||||||
for event in er_vehicle.read() {
|
for event in er_vehicle.read() {
|
||||||
for (driver, mut driver_actor, mut driver_vis, mut driver_trans) in q_drivers.iter_mut() {
|
for (driver, mut driver_vis, mut driver_trans, mut driver_linv, mut driver_angv) in q_drivers.iter_mut() {
|
||||||
if driver == event.driver {
|
if driver == event.driver {
|
||||||
for (vehicle, mut vehicle_actor, mut vehicle_vis, mut vehicle_trans) in q_vehicles.iter_mut() {
|
for (vehicle, mut vehicle_vis, vehicle_trans, vehicle_linv, vehicle_angv) in q_vehicles.iter_mut() {
|
||||||
if vehicle == event.vehicle {
|
if vehicle == event.vehicle {
|
||||||
if event.is_entering {
|
if event.is_entering {
|
||||||
// Entering Vehicle
|
// Entering Vehicle
|
||||||
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::EnterVehicle));
|
commands.entity(driver).remove::<RigidBody>();
|
||||||
*driver_vis = Visibility::Hidden;
|
*driver_vis = Visibility::Hidden; //seems to have no effect...
|
||||||
*driver_trans = vehicle_trans.clone();
|
|
||||||
if event.is_player {
|
if event.is_player {
|
||||||
//player_actor.inside_entity = entity.index();
|
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::EnterVehicle));
|
||||||
*vehicle_vis = Visibility::Hidden;
|
commands.entity(driver).remove::<PlayerCamera>();
|
||||||
driver_actor.v = vehicle_actor.v;
|
commands.entity(vehicle).insert(PlayerCamera);
|
||||||
commands.entity(vehicle).insert(PlayerDrivesThis);
|
commands.entity(vehicle).insert(PlayerDrivesThis);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Exiting Vehicle
|
// Exiting Vehicle
|
||||||
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Switch));
|
*driver_linv = vehicle_linv.clone();
|
||||||
*driver_vis = Visibility::Inherited;
|
*driver_angv = vehicle_angv.clone();
|
||||||
|
driver_trans.translation = vehicle_trans.translation + Vec3::new(0.0, 0.0, 10.0);
|
||||||
|
driver_trans.rotation = vehicle_trans.rotation;
|
||||||
|
// NOTE: I would rather have the following line here,
|
||||||
|
// but then, for some reason, changing driver translation
|
||||||
|
// does not work. For now, you must manually insert the RigidBody
|
||||||
|
// component from the place that adds this event.
|
||||||
|
//commands.entity(driver).insert(RigidBody::Dynamic);
|
||||||
if event.is_player {
|
if event.is_player {
|
||||||
*vehicle_vis = Visibility::Inherited;
|
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Switch));
|
||||||
vehicle_actor.v = driver_actor.v;
|
commands.entity(vehicle).remove::<PlayerCamera>();
|
||||||
vehicle_actor.angular_momentum = driver_actor.angular_momentum;
|
commands.entity(driver).insert(PlayerCamera);
|
||||||
*vehicle_trans = driver_trans.clone();
|
|
||||||
commands.entity(vehicle).remove::<PlayerDrivesThis>();
|
commands.entity(vehicle).remove::<PlayerDrivesThis>();
|
||||||
}
|
*vehicle_vis = Visibility::Inherited;
|
||||||
else {
|
|
||||||
*driver_trans = vehicle_trans.clone();
|
|
||||||
*driver_trans = vehicle_trans.clone();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -566,3 +561,17 @@ pub fn handle_chat_scripts(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_collisions(
|
||||||
|
mut collision_event_reader: EventReader<Collision>,
|
||||||
|
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||||
|
q_player: Query<Entity, With<PlayerCamera>>,
|
||||||
|
) {
|
||||||
|
if let Ok(player) = q_player.get_single() {
|
||||||
|
for Collision(contacts) in collision_event_reader.read() {
|
||||||
|
if contacts.entity1 == player || contacts.entity2 == player {
|
||||||
|
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Crash));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ const ASSET_ROCKET: &str = "sounds/rocket.ogg";
|
||||||
const ASSET_ION: &str = "sounds/ion.ogg";
|
const ASSET_ION: &str = "sounds/ion.ogg";
|
||||||
//const ASSET_WAKEUP: &str = "sounds/wakeup.ogg";
|
//const ASSET_WAKEUP: &str = "sounds/wakeup.ogg";
|
||||||
const ASSET_BIKESTART: &str = "sounds/bikestart.ogg";
|
const ASSET_BIKESTART: &str = "sounds/bikestart.ogg";
|
||||||
|
const ASSET_CRASH: &str = "sounds/crash.ogg";
|
||||||
|
|
||||||
pub struct AudioPlugin;
|
pub struct AudioPlugin;
|
||||||
impl Plugin for AudioPlugin {
|
impl Plugin for AudioPlugin {
|
||||||
|
@ -33,6 +34,7 @@ pub enum Sfx {
|
||||||
Ping,
|
Ping,
|
||||||
Connect,
|
Connect,
|
||||||
EnterVehicle,
|
EnterVehicle,
|
||||||
|
Crash,
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +51,7 @@ pub enum Sfx {
|
||||||
#[derive(Resource)] pub struct SoundPing(Handle<AudioSource>);
|
#[derive(Resource)] pub struct SoundPing(Handle<AudioSource>);
|
||||||
#[derive(Resource)] pub struct SoundConnect(Handle<AudioSource>);
|
#[derive(Resource)] pub struct SoundConnect(Handle<AudioSource>);
|
||||||
#[derive(Resource)] pub struct SoundBikeStart(Handle<AudioSource>);
|
#[derive(Resource)] pub struct SoundBikeStart(Handle<AudioSource>);
|
||||||
|
#[derive(Resource)] pub struct SoundCrash(Handle<AudioSource>);
|
||||||
|
|
||||||
pub fn setup(
|
pub fn setup(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
|
@ -113,6 +116,7 @@ pub fn setup(
|
||||||
commands.insert_resource(SoundPing(asset_server.load(ASSET_PING)));
|
commands.insert_resource(SoundPing(asset_server.load(ASSET_PING)));
|
||||||
commands.insert_resource(SoundConnect(asset_server.load(ASSET_CONNECT)));
|
commands.insert_resource(SoundConnect(asset_server.load(ASSET_CONNECT)));
|
||||||
commands.insert_resource(SoundBikeStart(asset_server.load(ASSET_BIKESTART)));
|
commands.insert_resource(SoundBikeStart(asset_server.load(ASSET_BIKESTART)));
|
||||||
|
commands.insert_resource(SoundCrash(asset_server.load(ASSET_CRASH)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_bgm(
|
pub fn toggle_bgm(
|
||||||
|
@ -143,6 +147,7 @@ pub fn play_sfx(
|
||||||
sound_ping: Res<SoundPing>,
|
sound_ping: Res<SoundPing>,
|
||||||
sound_connect: Res<SoundConnect>,
|
sound_connect: Res<SoundConnect>,
|
||||||
sound_bikestart: Res<SoundBikeStart>,
|
sound_bikestart: Res<SoundBikeStart>,
|
||||||
|
sound_crash: Res<SoundCrash>,
|
||||||
) {
|
) {
|
||||||
if settings.mute_sfx && !events_sfx.is_empty() {
|
if settings.mute_sfx && !events_sfx.is_empty() {
|
||||||
events_sfx.clear();
|
events_sfx.clear();
|
||||||
|
@ -160,6 +165,7 @@ pub fn play_sfx(
|
||||||
Sfx::Ping => sound_ping.0.clone(),
|
Sfx::Ping => sound_ping.0.clone(),
|
||||||
Sfx::Connect => sound_connect.0.clone(),
|
Sfx::Connect => sound_connect.0.clone(),
|
||||||
Sfx::EnterVehicle => sound_bikestart.0.clone(),
|
Sfx::EnterVehicle => sound_bikestart.0.clone(),
|
||||||
|
Sfx::Crash => sound_crash.0.clone(),
|
||||||
Sfx::None => sound_ping.0.clone(),
|
Sfx::None => sound_ping.0.clone(),
|
||||||
},
|
},
|
||||||
settings: PlaybackSettings::DESPAWN,
|
settings: PlaybackSettings::DESPAWN,
|
||||||
|
@ -175,6 +181,7 @@ pub fn str2sfx(sfx_label: &str) -> Sfx {
|
||||||
"ping" => Sfx::Ping,
|
"ping" => Sfx::Ping,
|
||||||
"connect" => Sfx::Connect,
|
"connect" => Sfx::Connect,
|
||||||
"entervehicle" => Sfx::EnterVehicle,
|
"entervehicle" => Sfx::EnterVehicle,
|
||||||
|
"crash" => Sfx::Crash,
|
||||||
_ => Sfx::None,
|
_ => Sfx::None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
177
src/camera.rs
177
src/camera.rs
|
@ -1,6 +1,10 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::input::mouse::MouseMotion;
|
use bevy::input::mouse::MouseMotion;
|
||||||
use bevy::window::PrimaryWindow;
|
use bevy::window::PrimaryWindow;
|
||||||
|
use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings};
|
||||||
|
use bevy::core_pipeline::tonemapping::Tonemapping;
|
||||||
|
use bevy::transform::TransformSystem;
|
||||||
|
use bevy_xpbd_3d::prelude::*;
|
||||||
use std::f32::consts::*;
|
use std::f32::consts::*;
|
||||||
use crate::{settings, audio, actor};
|
use crate::{settings, audio, actor};
|
||||||
|
|
||||||
|
@ -8,7 +12,14 @@ pub struct CameraControllerPlugin;
|
||||||
|
|
||||||
impl Plugin for CameraControllerPlugin {
|
impl Plugin for CameraControllerPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_systems(Update, run_camera_controller);
|
app.add_systems(Startup, setup_camera);
|
||||||
|
app.add_systems(Update, handle_input);
|
||||||
|
app.add_systems(Update, manage_player_actor.after(handle_input));
|
||||||
|
app.add_systems(PostUpdate, sync_camera_to_player
|
||||||
|
.after(PhysicsSet::Sync)
|
||||||
|
.before(TransformSystem::TransformPropagate));
|
||||||
|
app.add_systems(Update, update_fov);
|
||||||
|
app.add_systems(Update, apply_input_to_player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,29 +28,90 @@ impl Plugin for CameraControllerPlugin {
|
||||||
// it because it felt nice.
|
// it because it felt nice.
|
||||||
pub const RADIANS_PER_DOT: f32 = 1.0 / 180.0;
|
pub const RADIANS_PER_DOT: f32 = 1.0 / 180.0;
|
||||||
|
|
||||||
#[derive(Component)]
|
fn setup_camera(
|
||||||
pub struct CameraController {
|
mut commands: Commands,
|
||||||
pub enabled: bool,
|
) {
|
||||||
pub initialized: bool,
|
// Add player
|
||||||
pub sensitivity: f32,
|
commands.spawn((
|
||||||
pub pitch: f32,
|
Camera3dBundle {
|
||||||
pub yaw: f32,
|
camera: Camera {
|
||||||
|
hdr: true, // HDR is required for bloom
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
tonemapping: Tonemapping::TonyMcMapface,
|
||||||
|
transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
BloomSettings {
|
||||||
|
composite_mode: BloomCompositeMode::EnergyConserving,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CameraController {
|
pub fn sync_camera_to_player(
|
||||||
fn default() -> Self {
|
settings: Res<settings::Settings>,
|
||||||
Self {
|
mut q_camera: Query<&mut Transform, With<Camera>>,
|
||||||
enabled: true,
|
q_playercam: Query<(&actor::Actor, &Transform), (With<actor::PlayerCamera>, Without<Camera>)>,
|
||||||
initialized: false,
|
) {
|
||||||
sensitivity: 0.5,
|
if q_camera.is_empty() || q_playercam.is_empty() {
|
||||||
pitch: 1.0, // pitch=0/yaw=0 -> face sun
|
return;
|
||||||
yaw: 0.3,
|
|
||||||
}
|
}
|
||||||
|
let mut camera_transform = q_camera.get_single_mut().unwrap();
|
||||||
|
let (actor, player_transform) = q_playercam.get_single().unwrap();
|
||||||
|
|
||||||
|
// Rotation
|
||||||
|
camera_transform.rotation = player_transform.rotation * Quat::from_array([0.0, -1.0, 0.0, 0.0]);
|
||||||
|
|
||||||
|
// Translation
|
||||||
|
if settings.third_person {
|
||||||
|
camera_transform.translation = player_transform.translation + camera_transform.rotation * (actor.camdistance * Vec3::new(0.0, 0.2, 1.0));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
camera_transform.translation = player_transform.translation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_fov(
|
||||||
|
q_player: Query<&actor::LifeForm, With<actor::Player>>,
|
||||||
|
mut q_camera: Query<&mut Projection, With<Camera>>,
|
||||||
|
) {
|
||||||
|
if let (Ok(lifeform), Ok(mut projection)) = (q_player.get_single(), q_camera.get_single_mut())
|
||||||
|
{
|
||||||
|
let fov = (lifeform.adrenaline.powf(3.0) * 45.0 + 45.0).to_radians();
|
||||||
|
*projection = Projection::Perspective(PerspectiveProjection { fov: fov, ..default() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_input(
|
||||||
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||||
|
mut settings: ResMut<settings::Settings>,
|
||||||
|
) {
|
||||||
|
if keyboard_input.just_pressed(settings.key_camera) {
|
||||||
|
settings.third_person ^= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn manage_player_actor(
|
||||||
|
settings: Res<settings::Settings>,
|
||||||
|
mut q_playercam: Query<&mut Visibility, With<actor::PlayerCamera>>,
|
||||||
|
mut q_hiddenplayer: Query<&mut Visibility, (With<actor::Player>, Without<actor::PlayerCamera>)>,
|
||||||
|
) {
|
||||||
|
for mut vis in &mut q_playercam {
|
||||||
|
if settings.third_person {
|
||||||
|
*vis = Visibility::Inherited;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*vis = Visibility::Hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for mut vis in &mut q_hiddenplayer {
|
||||||
|
*vis = Visibility::Hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn run_camera_controller(
|
fn apply_input_to_player(
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
settings: Res<settings::Settings>,
|
settings: Res<settings::Settings>,
|
||||||
mut windows: Query<&mut Window, With<PrimaryWindow>>,
|
mut windows: Query<&mut Window, With<PrimaryWindow>>,
|
||||||
|
@ -48,15 +120,12 @@ fn run_camera_controller(
|
||||||
thruster_sound_controller: Query<&AudioSink, With<audio::ComponentThrusterSound>>,
|
thruster_sound_controller: Query<&AudioSink, With<audio::ComponentThrusterSound>>,
|
||||||
rocket_sound_controller: Query<&AudioSink, With<audio::ComponentRocketSound>>,
|
rocket_sound_controller: Query<&AudioSink, With<audio::ComponentRocketSound>>,
|
||||||
ion_sound_controller: Query<&AudioSink, With<audio::ComponentIonSound>>,
|
ion_sound_controller: Query<&AudioSink, With<audio::ComponentIonSound>>,
|
||||||
mut q_engine: Query<&mut actor::Engine, With<actor::PlayerDrivesThis>>,
|
mut q_playercam: Query<(
|
||||||
mut query: Query<(
|
|
||||||
&mut Transform,
|
&mut Transform,
|
||||||
&mut CameraController,
|
&mut actor::Engine,
|
||||||
&mut Projection,
|
&mut AngularVelocity,
|
||||||
&mut actor::Actor,
|
&mut LinearVelocity,
|
||||||
&actor::LifeForm,
|
), (With<actor::PlayerCamera>, Without<Camera>)>,
|
||||||
&mut actor::Engine
|
|
||||||
), (With<Camera>, Without<actor::PlayerDrivesThis>)>,
|
|
||||||
) {
|
) {
|
||||||
let dt = time.delta_seconds();
|
let dt = time.delta_seconds();
|
||||||
let mut play_thruster_sound = false;
|
let mut play_thruster_sound = false;
|
||||||
|
@ -67,31 +136,31 @@ fn run_camera_controller(
|
||||||
focused = window_result.unwrap().focused;
|
focused = window_result.unwrap().focused;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok((mut transform, mut controller, mut projection, mut actor, lifeform, player_engine)) = query.get_single_mut() {
|
if let Ok((mut player_transform, mut engine, mut angularvelocity, mut v)) = q_playercam.get_single_mut() {
|
||||||
if !controller.initialized {
|
|
||||||
controller.initialized = true;
|
if angularvelocity.length_squared() > 0.0001 {
|
||||||
transform.rotation =
|
angularvelocity.x *= 0.98;
|
||||||
Quat::from_euler(EulerRot::ZYX, 0.0, controller.yaw, controller.pitch);
|
angularvelocity.y *= 0.98;
|
||||||
|
angularvelocity.z *= 0.98;
|
||||||
}
|
}
|
||||||
if !controller.enabled {
|
else {
|
||||||
mouse_events.clear();
|
angularvelocity.0 = Vec3::splat(0.0);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle key input
|
// Handle key input
|
||||||
let mut axis_input = Vec3::ZERO;
|
let mut axis_input = Vec3::ZERO;
|
||||||
if focused {
|
if focused {
|
||||||
if key_input.pressed(settings.key_forward) {
|
if key_input.pressed(settings.key_forward) {
|
||||||
axis_input.z -= 1.2;
|
|
||||||
}
|
|
||||||
if key_input.pressed(settings.key_back) {
|
|
||||||
axis_input.z += 1.2;
|
axis_input.z += 1.2;
|
||||||
}
|
}
|
||||||
|
if key_input.pressed(settings.key_back) {
|
||||||
|
axis_input.z -= 1.2;
|
||||||
|
}
|
||||||
if key_input.pressed(settings.key_right) {
|
if key_input.pressed(settings.key_right) {
|
||||||
axis_input.x += 1.2;
|
axis_input.x -= 1.2;
|
||||||
}
|
}
|
||||||
if key_input.pressed(settings.key_left) {
|
if key_input.pressed(settings.key_left) {
|
||||||
axis_input.x -= 1.2;
|
axis_input.x += 1.2;
|
||||||
}
|
}
|
||||||
if key_input.pressed(settings.key_up) {
|
if key_input.pressed(settings.key_up) {
|
||||||
axis_input.y += 1.2;
|
axis_input.y += 1.2;
|
||||||
|
@ -100,9 +169,9 @@ fn run_camera_controller(
|
||||||
axis_input.y -= 1.2;
|
axis_input.y -= 1.2;
|
||||||
}
|
}
|
||||||
if key_input.pressed(settings.key_stop) {
|
if key_input.pressed(settings.key_stop) {
|
||||||
let stop_direction = -actor.v.normalize();
|
let stop_direction = -v.normalize();
|
||||||
if stop_direction.length_squared() > 0.3 {
|
if stop_direction.length_squared() > 0.3 {
|
||||||
axis_input += 1.0 * (transform.rotation.inverse() * stop_direction);
|
axis_input += 1.0 * (player_transform.rotation.inverse() * stop_direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,10 +182,8 @@ fn run_camera_controller(
|
||||||
// total diagonal acceleration is faster than the forward acceleration alone.
|
// total diagonal acceleration is faster than the forward acceleration alone.
|
||||||
axis_input = axis_input.clamp(Vec3::splat(-1.0), Vec3::splat(1.0));
|
axis_input = axis_input.clamp(Vec3::splat(-1.0), Vec3::splat(1.0));
|
||||||
|
|
||||||
let mut engine = if let Ok(engine) = q_engine.get_single_mut() { engine } else { player_engine };
|
|
||||||
|
|
||||||
// Apply movement update
|
// Apply movement update
|
||||||
let forward_factor = engine.current_warmup * (if axis_input.z < 0.0 {
|
let forward_factor = engine.current_warmup * (if axis_input.z > 0.0 {
|
||||||
engine.thrust_forward
|
engine.thrust_forward
|
||||||
} else {
|
} else {
|
||||||
engine.thrust_back
|
engine.thrust_back
|
||||||
|
@ -126,22 +193,22 @@ fn run_camera_controller(
|
||||||
let factor = Vec3::new(right_factor, up_factor, forward_factor);
|
let factor = Vec3::new(right_factor, up_factor, forward_factor);
|
||||||
|
|
||||||
if axis_input.length_squared() > 0.003 {
|
if axis_input.length_squared() > 0.003 {
|
||||||
let acceleration_global = transform.rotation * (axis_input * factor);
|
let acceleration_global = player_transform.rotation * (axis_input * factor);
|
||||||
let mut acceleration_total = actor::ENGINE_SPEED_FACTOR * dt * acceleration_global;
|
let mut acceleration_total = actor::ENGINE_SPEED_FACTOR * dt * acceleration_global;
|
||||||
let threshold = 1e-5;
|
let threshold = 1e-5;
|
||||||
if key_input.pressed(settings.key_stop) {
|
if key_input.pressed(settings.key_stop) {
|
||||||
for i in 0..3 {
|
for i in 0..3 {
|
||||||
if actor.v[i].abs() < threshold {
|
if v[i].abs() < threshold {
|
||||||
actor.v[i] = 0.0;
|
v[i] = 0.0;
|
||||||
}
|
}
|
||||||
else if actor.v[i].signum() != (actor.v[i] + acceleration_total[i]).signum() {
|
else if v[i].signum() != (v[i] + acceleration_total[i]).signum() {
|
||||||
// Overshoot
|
// Overshoot
|
||||||
actor.v[i] = 0.0;
|
v[i] = 0.0;
|
||||||
acceleration_total[i] = 0.0;
|
acceleration_total[i] = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
actor.v += acceleration_total;
|
v.0 += acceleration_total;
|
||||||
engine.current_warmup = (engine.current_warmup + dt / engine.warmup_seconds).clamp(0.0, 1.0);
|
engine.current_warmup = (engine.current_warmup + dt / engine.warmup_seconds).clamp(0.0, 1.0);
|
||||||
play_thruster_sound = !settings.mute_sfx;
|
play_thruster_sound = !settings.mute_sfx;
|
||||||
}
|
}
|
||||||
|
@ -157,17 +224,11 @@ fn run_camera_controller(
|
||||||
|
|
||||||
if mouse_delta != Vec2::ZERO {
|
if mouse_delta != Vec2::ZERO {
|
||||||
// Apply look update
|
// Apply look update
|
||||||
controller.pitch = (controller.pitch
|
let pitch = (mouse_delta.y * RADIANS_PER_DOT * settings.mouse_sensitivity).clamp(-PI / 2., PI / 2.);
|
||||||
- mouse_delta.y * RADIANS_PER_DOT * controller.sensitivity)
|
let yaw = mouse_delta.x * RADIANS_PER_DOT * settings.mouse_sensitivity;
|
||||||
.clamp(-PI / 2., PI / 2.);
|
player_transform.rotation *= Quat::from_euler(EulerRot::ZYX, 0.0, -yaw, pitch).normalize();
|
||||||
controller.yaw -= mouse_delta.x * RADIANS_PER_DOT * controller.sensitivity;
|
|
||||||
transform.rotation =
|
|
||||||
Quat::from_euler(EulerRot::ZYX, 0.0, controller.yaw, controller.pitch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let fov = (lifeform.adrenaline * lifeform.adrenaline * lifeform.adrenaline * 45.0 + 45.0).to_radians();
|
|
||||||
*projection = Projection::Perspective(PerspectiveProjection { fov: fov, ..default() });
|
|
||||||
|
|
||||||
if let Ok(sink) = thruster_sound_controller.get_single() {
|
if let Ok(sink) = thruster_sound_controller.get_single() {
|
||||||
if play_thruster_sound && engine.engine_type == actor::EngineType::Monopropellant {
|
if play_thruster_sound && engine.engine_type == actor::EngineType::Monopropellant {
|
||||||
sink.play()
|
sink.play()
|
||||||
|
|
18
src/defs.txt
18
src/defs.txt
|
@ -1,3 +1,13 @@
|
||||||
|
actor 0 0 0 suit
|
||||||
|
player yes
|
||||||
|
mass 200.0
|
||||||
|
scale 1
|
||||||
|
oxygen 0.008
|
||||||
|
health 0.3
|
||||||
|
collider capsule 2 1
|
||||||
|
thrust 1.2 1 1 1 1.5
|
||||||
|
engine monopropellant
|
||||||
|
|
||||||
actor 300000 0 500000 jupiter
|
actor 300000 0 500000 jupiter
|
||||||
scale 200000
|
scale 200000
|
||||||
rotationy -1.40
|
rotationy -1.40
|
||||||
|
@ -12,6 +22,11 @@ actor 1000 20 300 monolith
|
||||||
rotationx 0.5
|
rotationx 0.5
|
||||||
angularmomentum 0.0 0.0 0.01
|
angularmomentum 0.0 0.0 0.01
|
||||||
|
|
||||||
|
actor 10 20 30 monolith
|
||||||
|
scale 2
|
||||||
|
rotationx 0.5
|
||||||
|
angularmomentum 0.0 0.0 0.01
|
||||||
|
|
||||||
actor 10000 2000 -3500 monolith
|
actor 10000 2000 -3500 monolith
|
||||||
scale 2
|
scale 2
|
||||||
rotationx 0.5
|
rotationx 0.5
|
||||||
|
@ -97,6 +112,9 @@ actor 10 -30 20 MeteorAceGT
|
||||||
vehicle yes
|
vehicle yes
|
||||||
thrust 70 13.7 9.4 0.5 20
|
thrust 70 13.7 9.4 0.5 20
|
||||||
engine ion
|
engine ion
|
||||||
|
collider sphere 1.5
|
||||||
|
camdistance 50
|
||||||
|
mass 500
|
||||||
|
|
||||||
actor 10 0 70 suit
|
actor 10 0 70 suit
|
||||||
name Icarus
|
name Icarus
|
||||||
|
|
12
src/hud.rs
12
src/hud.rs
|
@ -1,6 +1,7 @@
|
||||||
use crate::{settings, actor, audio, nature};
|
use crate::{settings, actor, audio, nature};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin};
|
use bevy::diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin};
|
||||||
|
use bevy_xpbd_3d::prelude::*;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
@ -370,7 +371,8 @@ fn update(
|
||||||
diagnostics: Res<DiagnosticsStore>,
|
diagnostics: Res<DiagnosticsStore>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
mut log: ResMut<Log>,
|
mut log: ResMut<Log>,
|
||||||
player: Query<(&actor::Suit, &actor::LifeForm, &actor::Actor), With<actor::Player>>,
|
player: Query<(&actor::Suit, &actor::LifeForm), With<actor::Player>>,
|
||||||
|
q_camera: Query<&LinearVelocity, With<actor::PlayerCamera>>,
|
||||||
mut timer: ResMut<FPSUpdateTimer>,
|
mut timer: ResMut<FPSUpdateTimer>,
|
||||||
mut query: Query<&mut Text, With<GaugesText>>,
|
mut query: Query<&mut Text, With<GaugesText>>,
|
||||||
q_choices: Query<&ChoiceAvailable>,
|
q_choices: Query<&ChoiceAvailable>,
|
||||||
|
@ -380,9 +382,11 @@ fn update(
|
||||||
) {
|
) {
|
||||||
// TODO only when hud is actually on
|
// TODO only when hud is actually on
|
||||||
if timer.0.tick(time.delta()).just_finished() || log.needs_rerendering {
|
if timer.0.tick(time.delta()).just_finished() || log.needs_rerendering {
|
||||||
|
let q_camera_result = q_camera.get_single();
|
||||||
let player = player.get_single();
|
let player = player.get_single();
|
||||||
if player.is_ok() {
|
if player.is_ok() && q_camera_result.is_ok() {
|
||||||
let (suit, lifeform, actor) = player.unwrap();
|
let (suit, lifeform) = player.unwrap();
|
||||||
|
let cam_v = q_camera_result.unwrap();
|
||||||
for mut text in &mut query {
|
for mut text in &mut query {
|
||||||
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) {
|
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) {
|
||||||
if let Some(value) = fps.smoothed() {
|
if let Some(value) = fps.smoothed() {
|
||||||
|
@ -409,7 +413,7 @@ fn update(
|
||||||
text.sections[10].value = format!("{all_actors:.0}");
|
text.sections[10].value = format!("{all_actors:.0}");
|
||||||
let integrity = suit.integrity * 100.0;
|
let integrity = suit.integrity * 100.0;
|
||||||
text.sections[12].value = format!("{integrity:.0}%");
|
text.sections[12].value = format!("{integrity:.0}%");
|
||||||
let speed = actor.v.length();
|
let speed = cam_v.length();
|
||||||
let kmh = speed * 60.0 * 60.0 / 1000.0;
|
let kmh = speed * 60.0 * 60.0 / 1000.0;
|
||||||
text.sections[14].value = format!("{speed:.0}m/s | {kmh:.0}km/h");
|
text.sections[14].value = format!("{speed:.0}m/s | {kmh:.0}km/h");
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,9 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
App::new().add_plugins((
|
App::new().add_plugins(OutFlyPlugin).run();
|
||||||
OutFlyPlugin,
|
|
||||||
)).run();
|
|
||||||
} else {
|
} else {
|
||||||
|
// In release builds, embed assets into the binary
|
||||||
App::new().add_plugins((
|
App::new().add_plugins((
|
||||||
EmbeddedAssetPlugin { mode: PluginMode::ReplaceDefault },
|
EmbeddedAssetPlugin { mode: PluginMode::ReplaceDefault },
|
||||||
OutFlyPlugin,
|
OutFlyPlugin,
|
||||||
|
|
|
@ -7,9 +7,11 @@ pub struct Settings {
|
||||||
pub mute_music: bool,
|
pub mute_music: bool,
|
||||||
pub volume_sfx: u8,
|
pub volume_sfx: u8,
|
||||||
pub volume_music: u8,
|
pub volume_music: u8,
|
||||||
|
pub mouse_sensitivity: f32,
|
||||||
pub font_size_hud: f32,
|
pub font_size_hud: f32,
|
||||||
pub font_size_conversations: f32,
|
pub font_size_conversations: f32,
|
||||||
pub hud_active: bool,
|
pub hud_active: bool,
|
||||||
|
pub third_person: bool,
|
||||||
pub key_togglehud: KeyCode,
|
pub key_togglehud: KeyCode,
|
||||||
pub key_exit: KeyCode,
|
pub key_exit: KeyCode,
|
||||||
pub key_restart: KeyCode,
|
pub key_restart: KeyCode,
|
||||||
|
@ -24,6 +26,7 @@ pub struct Settings {
|
||||||
pub key_stop: KeyCode,
|
pub key_stop: KeyCode,
|
||||||
pub key_interact: KeyCode,
|
pub key_interact: KeyCode,
|
||||||
pub key_vehicle: KeyCode,
|
pub key_vehicle: KeyCode,
|
||||||
|
pub key_camera: KeyCode,
|
||||||
pub key_reply1: KeyCode,
|
pub key_reply1: KeyCode,
|
||||||
pub key_reply2: KeyCode,
|
pub key_reply2: KeyCode,
|
||||||
pub key_reply3: KeyCode,
|
pub key_reply3: KeyCode,
|
||||||
|
@ -53,9 +56,11 @@ impl Default for Settings {
|
||||||
mute_music: default_mute_music,
|
mute_music: default_mute_music,
|
||||||
volume_sfx: 100,
|
volume_sfx: 100,
|
||||||
volume_music: 100,
|
volume_music: 100,
|
||||||
|
mouse_sensitivity: 0.5,
|
||||||
font_size_hud: 32.0,
|
font_size_hud: 32.0,
|
||||||
font_size_conversations: 32.0,
|
font_size_conversations: 32.0,
|
||||||
hud_active: false,
|
hud_active: false,
|
||||||
|
third_person: false,
|
||||||
key_togglehud: KeyCode::Tab,
|
key_togglehud: KeyCode::Tab,
|
||||||
key_exit: KeyCode::Escape,
|
key_exit: KeyCode::Escape,
|
||||||
key_restart: KeyCode::F12,
|
key_restart: KeyCode::F12,
|
||||||
|
@ -70,6 +75,7 @@ impl Default for Settings {
|
||||||
key_stop: KeyCode::Space,
|
key_stop: KeyCode::Space,
|
||||||
key_interact: KeyCode::KeyE,
|
key_interact: KeyCode::KeyE,
|
||||||
key_vehicle: KeyCode::KeyQ,
|
key_vehicle: KeyCode::KeyQ,
|
||||||
|
key_camera: KeyCode::KeyF,
|
||||||
key_reply1: KeyCode::Digit1,
|
key_reply1: KeyCode::Digit1,
|
||||||
key_reply2: KeyCode::Digit2,
|
key_reply2: KeyCode::Digit2,
|
||||||
key_reply3: KeyCode::Digit3,
|
key_reply3: KeyCode::Digit3,
|
||||||
|
|
199
src/world.rs
199
src/world.rs
|
@ -1,12 +1,12 @@
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
use crate::{actor, camera, nature};
|
use crate::{actor, nature};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
//use bevy::core_pipeline::Skybox;
|
//use bevy::core_pipeline::Skybox;
|
||||||
//use bevy::asset::LoadState;
|
//use bevy::asset::LoadState;
|
||||||
//use bevy::render::render_resource::{TextureViewDescriptor, TextureViewDimension};
|
//use bevy::render::render_resource::{TextureViewDescriptor, TextureViewDimension};
|
||||||
use bevy::pbr::CascadeShadowConfigBuilder;
|
use bevy::pbr::CascadeShadowConfigBuilder;
|
||||||
use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings};
|
use bevy_xpbd_3d::prelude::*;
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
|
|
||||||
const ASTEROID_SIZE: f32 = 100.0;
|
const ASTEROID_SIZE: f32 = 100.0;
|
||||||
|
@ -40,7 +40,10 @@ impl Plugin for WorldPlugin {
|
||||||
app.add_systems(Startup, (setup, load_defs));
|
app.add_systems(Startup, (setup, load_defs));
|
||||||
//app.add_systems(Update, asset_loaded.after(load_cubemap_asset));
|
//app.add_systems(Update, asset_loaded.after(load_cubemap_asset));
|
||||||
//app.add_systems(Update, swap_world_on_ar_toggle);
|
//app.add_systems(Update, swap_world_on_ar_toggle);
|
||||||
|
app.add_plugins(PhysicsPlugins::default());
|
||||||
|
//app.add_plugins(PhysicsDebugPlugin::default());
|
||||||
app.insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)));
|
app.insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)));
|
||||||
|
app.insert_resource(Gravity(Vec3::splat(0.0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,43 +81,6 @@ pub fn setup(
|
||||||
// cubemap_ar_handle: asset_server.load(ASSET_CUBEMAP_AR),
|
// cubemap_ar_handle: asset_server.load(ASSET_CUBEMAP_AR),
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// Add player
|
|
||||||
commands.spawn((
|
|
||||||
actor::Player,
|
|
||||||
actor::Actor {
|
|
||||||
angular_momentum: Quat::IDENTITY,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
actor::LifeForm::default(),
|
|
||||||
actor::Suit {
|
|
||||||
oxygen: nature::OXY_H,
|
|
||||||
integrity: 0.3,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
actor::Engine {
|
|
||||||
thrust_forward: 1.2,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
Visibility::Visible,
|
|
||||||
Camera3dBundle {
|
|
||||||
camera: Camera {
|
|
||||||
hdr: true, // HDR is required for bloom
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
camera::CameraController::default(),
|
|
||||||
// Skybox {
|
|
||||||
// image: cubemap_handle,
|
|
||||||
// brightness: SKYBOX_BRIGHTNESS,
|
|
||||||
// },
|
|
||||||
BloomSettings {
|
|
||||||
composite_mode: BloomCompositeMode::EnergyConserving,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
));
|
|
||||||
|
|
||||||
// Generate a bunch of asteriods
|
// Generate a bunch of asteriods
|
||||||
let maxdist = 10;
|
let maxdist = 10;
|
||||||
for i in -maxdist..maxdist {
|
for i in -maxdist..maxdist {
|
||||||
|
@ -238,6 +204,7 @@ struct ParserState {
|
||||||
rotation: Quat,
|
rotation: Quat,
|
||||||
angular_momentum: Quat,
|
angular_momentum: Quat,
|
||||||
pronoun: String,
|
pronoun: String,
|
||||||
|
is_player: bool,
|
||||||
is_lifeform: bool,
|
is_lifeform: bool,
|
||||||
is_alive: bool,
|
is_alive: bool,
|
||||||
is_suited: bool,
|
is_suited: bool,
|
||||||
|
@ -249,6 +216,9 @@ struct ParserState {
|
||||||
warmup_seconds: f32,
|
warmup_seconds: f32,
|
||||||
engine_type: actor::EngineType,
|
engine_type: actor::EngineType,
|
||||||
oxygen: f32,
|
oxygen: f32,
|
||||||
|
mass: f32,
|
||||||
|
collider: Collider,
|
||||||
|
camdistance: f32,
|
||||||
|
|
||||||
// Chat fields
|
// Chat fields
|
||||||
delay: f64,
|
delay: f64,
|
||||||
|
@ -278,6 +248,7 @@ impl Default for ParserState {
|
||||||
rotation: Quat::IDENTITY,
|
rotation: Quat::IDENTITY,
|
||||||
angular_momentum: default_actor.angular_momentum,
|
angular_momentum: default_actor.angular_momentum,
|
||||||
pronoun: "they/them".to_string(),
|
pronoun: "they/them".to_string(),
|
||||||
|
is_player: false,
|
||||||
is_lifeform: false,
|
is_lifeform: false,
|
||||||
is_alive: false,
|
is_alive: false,
|
||||||
is_suited: false,
|
is_suited: false,
|
||||||
|
@ -289,6 +260,9 @@ impl Default for ParserState {
|
||||||
warmup_seconds: default_engine.warmup_seconds,
|
warmup_seconds: default_engine.warmup_seconds,
|
||||||
engine_type: default_engine.engine_type,
|
engine_type: default_engine.engine_type,
|
||||||
oxygen: nature::OXY_D,
|
oxygen: nature::OXY_D,
|
||||||
|
mass: 1.0,
|
||||||
|
collider: Collider::sphere(1.0),
|
||||||
|
camdistance: default_actor.camdistance,
|
||||||
|
|
||||||
delay: 0.0,
|
delay: 0.0,
|
||||||
text: "".to_string(),
|
text: "".to_string(),
|
||||||
|
@ -345,32 +319,14 @@ impl ParserState {
|
||||||
self.reset_message();
|
self.reset_message();
|
||||||
}
|
}
|
||||||
fn spawn_actor(&mut self, commands: &mut Commands, asset_server: &Res<AssetServer>) {
|
fn spawn_actor(&mut self, commands: &mut Commands, asset_server: &Res<AssetServer>) {
|
||||||
let component_actor = actor::Actor {
|
let mut actor = commands.spawn_empty();
|
||||||
|
actor.insert(actor::Actor {
|
||||||
angular_momentum: self.angular_momentum,
|
angular_momentum: self.angular_momentum,
|
||||||
id: self.id.clone(),
|
id: self.id.clone(),
|
||||||
|
camdistance: self.camdistance,
|
||||||
..default()
|
..default()
|
||||||
};
|
});
|
||||||
let component_lifeform = actor::LifeForm::default();
|
actor.insert(SceneBundle {
|
||||||
let component_talker = actor::Talker {
|
|
||||||
conv_id: self.chat.clone(),
|
|
||||||
..default()
|
|
||||||
};
|
|
||||||
let component_vehicle = actor::Vehicle;
|
|
||||||
let component_engine = actor::Engine {
|
|
||||||
thrust_forward: self.thrust_forward,
|
|
||||||
thrust_back: self.thrust_back,
|
|
||||||
thrust_sideways: self.thrust_sideways,
|
|
||||||
reaction_wheels: self.reaction_wheels,
|
|
||||||
warmup_seconds: self.warmup_seconds,
|
|
||||||
engine_type: self.engine_type,
|
|
||||||
..default()
|
|
||||||
};
|
|
||||||
let component_suit = actor::Suit {
|
|
||||||
oxygen: self.oxygen,
|
|
||||||
oxygen_max: nature::OXY_D,
|
|
||||||
..default()
|
|
||||||
};
|
|
||||||
let component_model = SceneBundle {
|
|
||||||
transform: Transform {
|
transform: Transform {
|
||||||
translation: self.pos,
|
translation: self.pos,
|
||||||
scale: Vec3::splat(self.model_scale),
|
scale: Vec3::splat(self.model_scale),
|
||||||
|
@ -378,55 +334,50 @@ impl ParserState {
|
||||||
},
|
},
|
||||||
scene: asset_server.load(asset_name_to_path(self.model.as_str())),
|
scene: asset_server.load(asset_name_to_path(self.model.as_str())),
|
||||||
..default()
|
..default()
|
||||||
};
|
});
|
||||||
|
|
||||||
// TODO: is there a more dynamic way to construct this...?
|
// Physics Parameters
|
||||||
info!("Spawning actor {} with model {} at {}/{}/{}",
|
let fix_scale = 1.0 / self.model_scale.powf(3.0);
|
||||||
self.name, self.model, self.pos.x, self.pos.y, self.pos.z);
|
actor.insert(RigidBody::Dynamic);
|
||||||
|
actor.insert(self.collider.clone());
|
||||||
|
actor.insert(ColliderDensity(self.mass * fix_scale));
|
||||||
|
|
||||||
|
// Optional Components
|
||||||
|
if self.is_player {
|
||||||
|
actor.insert(actor::Player);
|
||||||
|
actor.insert(actor::PlayerCamera);
|
||||||
|
}
|
||||||
if self.is_lifeform {
|
if self.is_lifeform {
|
||||||
|
actor.insert(actor::LifeForm::default());
|
||||||
|
actor.insert(actor::Suit {
|
||||||
|
oxygen: self.oxygen,
|
||||||
|
oxygen_max: nature::OXY_D,
|
||||||
|
..default()
|
||||||
|
});
|
||||||
|
}
|
||||||
if !self.chat.is_empty() {
|
if !self.chat.is_empty() {
|
||||||
commands.spawn((
|
actor.insert(actor::Talker {
|
||||||
component_actor,
|
conv_id: self.chat.clone(),
|
||||||
component_lifeform,
|
..default()
|
||||||
component_suit,
|
});
|
||||||
component_talker,
|
|
||||||
component_model,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
commands.spawn((
|
|
||||||
component_actor,
|
|
||||||
component_lifeform,
|
|
||||||
component_suit,
|
|
||||||
component_model,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if !self.chat.is_empty() {
|
|
||||||
commands.spawn((
|
|
||||||
component_actor,
|
|
||||||
component_talker,
|
|
||||||
component_model,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if self.is_vehicle {
|
if self.is_vehicle {
|
||||||
commands.spawn((
|
actor.insert(actor::Vehicle);
|
||||||
component_actor,
|
|
||||||
component_model,
|
|
||||||
component_vehicle,
|
|
||||||
component_engine,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
commands.spawn((
|
|
||||||
component_actor,
|
|
||||||
component_model,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if self.is_vehicle || self.is_suited {
|
||||||
|
actor.insert(actor::Engine {
|
||||||
|
thrust_forward: self.thrust_forward,
|
||||||
|
thrust_back: self.thrust_back,
|
||||||
|
thrust_sideways: self.thrust_sideways,
|
||||||
|
reaction_wheels: self.reaction_wheels,
|
||||||
|
warmup_seconds: self.warmup_seconds,
|
||||||
|
engine_type: self.engine_type,
|
||||||
|
..default()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//info!("Spawning actor {} with model {} at {}/{}/{}",
|
||||||
|
// self.name, self.model, self.pos.x, self.pos.y, self.pos.z);
|
||||||
self.reset();
|
self.reset();
|
||||||
}
|
}
|
||||||
fn spawn_entities(&mut self, commands: &mut Commands, asset_server: &Res<AssetServer>) {
|
fn spawn_entities(&mut self, commands: &mut Commands, asset_server: &Res<AssetServer>) {
|
||||||
|
@ -580,6 +531,46 @@ pub fn load_defs(
|
||||||
["engine", "ion"] => {
|
["engine", "ion"] => {
|
||||||
state.engine_type = actor::EngineType::Ion;
|
state.engine_type = actor::EngineType::Ion;
|
||||||
}
|
}
|
||||||
|
["mass", value] => {
|
||||||
|
if let Ok(value_float) = value.parse::<f32>() {
|
||||||
|
state.mass = value_float;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error!("Can't parse float: {line}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
["collider", "sphere", radius] => {
|
||||||
|
if let Ok(radius_float) = radius.parse::<f32>() {
|
||||||
|
state.collider = Collider::sphere(radius_float);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error!("Can't parse float: {line}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
["collider", "capsule", height, radius] => {
|
||||||
|
if let (Ok(height_float), Ok(radius_float)) = (height.parse::<f32>(), radius.parse::<f32>()) {
|
||||||
|
state.collider = Collider::capsule(height_float, radius_float);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error!("Can't parse float: {line}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
["player", "yes"] => {
|
||||||
|
state.is_player = true;
|
||||||
|
state.is_alive = true;
|
||||||
|
}
|
||||||
|
["camdistance", value] => {
|
||||||
|
if let Ok(value_float) = value.parse::<f32>() {
|
||||||
|
state.camdistance = value_float;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error!("Can't parse float: {line}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Parsing chats
|
// Parsing chats
|
||||||
["chat", chat_name] => {
|
["chat", chat_name] => {
|
||||||
|
|
Loading…
Reference in a new issue