Compare commits
21 Commits
master
...
data-struc
Author | SHA1 | Date | |
---|---|---|---|
05e609521a | |||
b5ab8f377d | |||
5c9a79390a | |||
5baff7a6e7 | |||
c3fef4dc35 | |||
ea48c40938 | |||
66269f326d | |||
77fb784c7e | |||
cb80773db4 | |||
da9fa7c51c | |||
7a6b494358 | |||
864f9dc551 | |||
5fc2dda3a1 | |||
777ee3439c | |||
69f08061ed | |||
1ad6104c14 | |||
20cc3ef96f | |||
ffb20c6dc9 | |||
451808f9af | |||
2cc7d76a48 | |||
56859d4e0c |
@ -1,2 +0,0 @@
|
||||
[registries.strafesnet]
|
||||
index = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
507
Cargo.lock
generated
507
Cargo.lock
generated
@ -4,36 +4,30 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "array-init"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.9"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
|
||||
checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.6"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
@ -41,47 +35,17 @@ version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "binrw"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f36b7cb3ab9ff6a2858650d8dc360e783a5d14dc29594db48c56a3c233cc265"
|
||||
dependencies = [
|
||||
"array-init",
|
||||
"binrw_derive",
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "binrw_derive"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20ea7a8c5c8eeffffac6d54d172444e15beffac6f817fac714460a9a9aa88da3"
|
||||
dependencies = [
|
||||
"either",
|
||||
"owo-colors",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "blake3"
|
||||
version = "1.5.4"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7"
|
||||
checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
@ -90,28 +54,6 @@ dependencies = [
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bnum"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50202def95bf36cb7d1d7a7962cea1c36a3f8ad42425e5d2b71d7acb8041b5b8"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
@ -120,11 +62,11 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.24"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -135,33 +77,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.3.1"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "fixed_wide"
|
||||
version = "0.1.1"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "d9c2cf115b3785ede870fada07e8b1aeba3378345b4ca86fe3c772ecabc05c0f"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bnum",
|
||||
"paste",
|
||||
"ratio_ops",
|
||||
]
|
||||
checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
@ -170,26 +94,25 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.29.0"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c28091a37a5d09b555cb6628fd954da299b536433834f5b8e59eba78e0cbbf8a"
|
||||
checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3"
|
||||
|
||||
[[package]]
|
||||
name = "id"
|
||||
version = "0.1.0"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "2337e7a6c273082b672e377e159d7a168fb51438461b7c4033c79a515dd7a25a"
|
||||
source = "git+https://git.itzana.me/Quaternions/id?rev=1f710976cc786c8853dab73d6e1cee53158deeb0#1f710976cc786c8853dab73d6e1cee53158deeb0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.79",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy-regex"
|
||||
version = "3.3.0"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d8e41c97e6bc7ecb552016274b99fbb5d035e8de288c582d9b933af6677bfda"
|
||||
checksum = "5d12be4595afdf58bd19e4a9f4e24187da2a66700786ff660a418e9059937a4c"
|
||||
dependencies = [
|
||||
"lazy-regex-proc_macros",
|
||||
"once_cell",
|
||||
@ -198,78 +121,49 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lazy-regex-proc_macros"
|
||||
version = "3.3.0"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76e1d8b05d672c53cb9c7b920bbba8783845ae4f0b076e02a3db1d02c81b4163"
|
||||
checksum = "44bcd58e6c97a7fcbaffcdc95728b393b8d98933bfadad49ed4097845b57ef0b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn 2.0.79",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.159"
|
||||
version = "0.2.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linear_ops"
|
||||
version = "0.1.0"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "b2e6977ac24f47086d8a7a2d4ae1c720e86dfdc8407cf5e34c18bfa01053c456"
|
||||
dependencies = [
|
||||
"fixed_wide",
|
||||
"paste",
|
||||
"ratio_ops",
|
||||
]
|
||||
checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "luau0-src"
|
||||
version = "0.10.3+luau640"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f39d12b514a676c943990cfbe6200fedcb9c293c8c9219d29be512a6969be92"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "lz4"
|
||||
version = "1.28.0"
|
||||
version = "1.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d1febb2b4a79ddd1980eede06a8f7902197960aa0383ffcfdd62fe723036725"
|
||||
checksum = "7e9e2dd86df36ce760a60f6ff6ad526f7ba1f14ba0356f8254fb6905e6494df1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"lz4-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lz4-sys"
|
||||
version = "1.11.1+lz4-1.10.0"
|
||||
version = "1.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6"
|
||||
checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@ -277,120 +171,70 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "mlua"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d111deb18a9c9bd33e1541309f4742523bfab01d276bfa9a27519f6de9c11dc7"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"libloading",
|
||||
"mlua-sys",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"rustc-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mlua-sys"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebe026d6bd1583a9cf9080e189030ddaea7e6f5f0deb366a8e26f8a26c4135b8"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"luau0-src",
|
||||
"pkg-config",
|
||||
]
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.20.1"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1"
|
||||
dependencies = [
|
||||
"portable-atomic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.20"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "profiling"
|
||||
version = "1.0.15"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58"
|
||||
checksum = "0f0f7f43585c34e4fdd7497d746bc32e14458cf11c69341cc0587b1d825dde42"
|
||||
dependencies = [
|
||||
"profiling-procmacros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "profiling-procmacros"
|
||||
version = "1.0.15"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd"
|
||||
checksum = "ce97fecd27bc49296e5e20518b5a1bb54a14f7d5fe6228bc9686ee2a74915cc8"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.79",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -425,17 +269,11 @@ dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratio_ops"
|
||||
version = "0.1.0"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "01239195d6afe0509e7e3511b716c0540251dfe7ece0a9a5a27116afb766c42c"
|
||||
|
||||
[[package]]
|
||||
name = "rbx_binary"
|
||||
version = "0.7.4"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "18b401155b93f7151217bf51e36bdfa7bddcaf5f0d26b563c9ac3b08a3701c27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6314dd6bf5c21d0598cdb53cf5d241aa643ba41da8b8abf7402b4a35096f03f6"
|
||||
dependencies = [
|
||||
"log",
|
||||
"lz4",
|
||||
@ -448,29 +286,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rbx_dom_weak"
|
||||
version = "2.9.0"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "2a6b916687c98aaea36f9c03e80906bfafab057bebee248628c8c04def807f43"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b67b56bac99849c2e3c57547b036927f71c57cf7f4d900d04e3e4ee774ec316"
|
||||
dependencies = [
|
||||
"rbx_types",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rbx_mesh"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "864ead0e98afce28c960f653d6203483834890d07f87b60e2f01415530a2fe9d"
|
||||
dependencies = [
|
||||
"binrw",
|
||||
"lazy-regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rbx_reflection"
|
||||
version = "4.7.0"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "c1b43fe592a4ce6fe54eb215fb82735efbb516d2cc045a94e3dc0234ff293620"
|
||||
version = "4.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d41509c991b53a7276a746a795eae2b9204f398164920f61976995b47fe1722"
|
||||
dependencies = [
|
||||
"rbx_types",
|
||||
"serde",
|
||||
@ -479,9 +307,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rbx_reflection_database"
|
||||
version = "0.2.12+roblox-638"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "2e772bb9e1bc0ebe65d338f876d1bb1ea22e15a8f9a82e8245028010c2fea3c9"
|
||||
version = "0.2.10+roblox-607"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12e20c06fa41f7aadc79005c8354f592b2c2f4d0c61e1080ed5718dafc30aea0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"rbx_reflection",
|
||||
@ -491,12 +319,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rbx_types"
|
||||
version = "1.10.0"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "d7a390c44034fa448c53bd0983dfc2d70d8d6b2f65be4f164d4bec8b6a2a2d09"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ca23bfd469d067d81ef14f65fe09aeddc25abcf576a889d1a7664fe021cf18c"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"blake3",
|
||||
"lazy_static",
|
||||
"rand",
|
||||
@ -507,8 +335,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rbx_xml"
|
||||
version = "0.13.3"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "d6d1a15f58a1e4b4f578abe6eb5e1461cb16eea82fb4a147d5995c9b79f08d1f"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8c03f95500961c32340791d1fabd4587f6873bdbff077ecca6ae32db7960dea"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"log",
|
||||
@ -520,9 +348,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.0"
|
||||
version = "1.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
|
||||
checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@ -532,9 +360,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.8"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
|
||||
checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@ -543,15 +371,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.5"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "rmp"
|
||||
version = "0.8.14"
|
||||
version = "0.8.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4"
|
||||
checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"num-traits",
|
||||
@ -560,108 +388,62 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rmp-serde"
|
||||
version = "1.3.0"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db"
|
||||
checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"rmp",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roblox_emulator"
|
||||
version = "0.4.0"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "df647d25a9bc8871a838a830ae90776cd31c44d1a74268bd783d1cadcd8fcd93"
|
||||
dependencies = [
|
||||
"glam",
|
||||
"mlua",
|
||||
"rbx_dom_weak",
|
||||
"rbx_reflection",
|
||||
"rbx_reflection_database",
|
||||
"rbx_types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.210"
|
||||
version = "1.0.196"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
|
||||
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.210"
|
||||
version = "1.0.196"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
|
||||
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.79",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "strafesnet_common"
|
||||
version = "0.5.2"
|
||||
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
|
||||
checksum = "91cc1f3699bd8248da18bf5d11273264396a257b5d47b8558acb2cb4e1761219"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.itzana.me/StrafesNET/common?rev=fccb13bc6080ea6db94ef9175affd4aef1d9249d#fccb13bc6080ea6db94ef9175affd4aef1d9249d"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags 2.6.0",
|
||||
"fixed_wide",
|
||||
"glam",
|
||||
"id",
|
||||
"linear_ops",
|
||||
"ratio_ops",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strafesnet_rbx_loader"
|
||||
version = "0.5.2"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"glam",
|
||||
"lazy-regex",
|
||||
"rbx_binary",
|
||||
"rbx_dom_weak",
|
||||
"rbx_mesh",
|
||||
"rbx_reflection_database",
|
||||
"rbx_xml",
|
||||
"roblox_emulator",
|
||||
"strafesnet_common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
version = "2.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
|
||||
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -670,29 +452,29 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.64"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
|
||||
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.64"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
|
||||
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.79",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.13"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
@ -700,93 +482,8 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.8.22"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a"
|
||||
|
21
Cargo.toml
21
Cargo.toml
@ -1,22 +1,15 @@
|
||||
[package]
|
||||
name = "strafesnet_rbx_loader"
|
||||
version = "0.5.2"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
repository = "https://git.itzana.me/StrafesNET/rbx_loader"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Convert Roblox place and model files to StrafesNET data structures."
|
||||
authors = ["Rhys Lloyd <krakow20@gmail.com>"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bytemuck = "1.14.3"
|
||||
glam = "0.29.0"
|
||||
glam = "0.25.0"
|
||||
lazy-regex = "3.1.0"
|
||||
rbx_binary = { version = "0.7.4", registry = "strafesnet" }
|
||||
rbx_dom_weak = { version = "2.7.0", registry = "strafesnet" }
|
||||
rbx_mesh = "0.1.2"
|
||||
rbx_reflection_database = { version = "0.2.10", registry = "strafesnet" }
|
||||
rbx_xml = { version = "0.13.3", registry = "strafesnet" }
|
||||
roblox_emulator = { version = "0.4.0", registry = "strafesnet" }
|
||||
strafesnet_common = { version = "0.5.1", registry = "strafesnet" }
|
||||
rbx_binary = "0.7.4"
|
||||
rbx_dom_weak = "2.7.0"
|
||||
rbx_reflection_database = "0.2.10"
|
||||
rbx_xml = "0.13.3"
|
||||
strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "fccb13bc6080ea6db94ef9175affd4aef1d9249d" }
|
||||
|
97
src/lib.rs
97
src/lib.rs
@ -1,107 +1,26 @@
|
||||
use std::io::Read;
|
||||
use rbx_dom_weak::WeakDom;
|
||||
|
||||
mod rbx;
|
||||
mod mesh;
|
||||
mod primitives;
|
||||
|
||||
pub mod data{
|
||||
pub struct RobloxMeshBytes(Vec<u8>);
|
||||
impl RobloxMeshBytes{
|
||||
pub fn new(bytes:Vec<u8>)->Self{
|
||||
Self(bytes)
|
||||
}
|
||||
pub(crate) fn cursor(self)->std::io::Cursor<Vec<u8>>{
|
||||
std::io::Cursor::new(self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Model{
|
||||
dom:WeakDom,
|
||||
}
|
||||
impl Model{
|
||||
fn new(dom:WeakDom)->Self{
|
||||
Self{dom}
|
||||
}
|
||||
pub fn into_place(self)->Place{
|
||||
let Self{mut dom}=self;
|
||||
let context=roblox_emulator::context::Context::from_mut(&mut dom);
|
||||
let services=context.convert_into_place();
|
||||
Place{dom,services}
|
||||
}
|
||||
}
|
||||
impl AsRef<WeakDom> for Model{
|
||||
fn as_ref(&self)->&WeakDom{
|
||||
&self.dom
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Place{
|
||||
dom:WeakDom,
|
||||
services:roblox_emulator::context::Services,
|
||||
}
|
||||
impl Place{
|
||||
fn new(dom:WeakDom)->Option<Self>{
|
||||
let context=roblox_emulator::context::Context::from_ref(&dom);
|
||||
Some(Self{
|
||||
services:context.find_services()?,
|
||||
dom,
|
||||
})
|
||||
}
|
||||
pub fn run_scripts(&mut self){
|
||||
let Place{dom,services}=self;
|
||||
let runner=roblox_emulator::runner::Runner::new().unwrap();
|
||||
let context=roblox_emulator::context::Context::from_mut(dom);
|
||||
let scripts=context.scripts();
|
||||
let runnable=runner.runnable_context_with_services(context,services).unwrap();
|
||||
for script in scripts{
|
||||
if let Err(e)=runnable.run_script(script){
|
||||
println!("runner error: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl AsRef<WeakDom> for Place{
|
||||
fn as_ref(&self)->&WeakDom{
|
||||
&self.dom
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ReadError{
|
||||
pub enum Error{
|
||||
RbxBinary(rbx_binary::DecodeError),
|
||||
RbxXml(rbx_xml::DecodeError),
|
||||
Io(std::io::Error),
|
||||
UnknownFileFormat,
|
||||
}
|
||||
impl std::fmt::Display for ReadError{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
write!(f,"{self:?}")
|
||||
}
|
||||
}
|
||||
impl std::error::Error for ReadError{}
|
||||
|
||||
pub fn read<R:Read>(input:R)->Result<Model,ReadError>{
|
||||
fn load_dom<R:Read>(input:R)->Result<rbx_dom_weak::WeakDom,Error>{
|
||||
let mut buf=std::io::BufReader::new(input);
|
||||
let peek=std::io::BufRead::fill_buf(&mut buf).map_err(ReadError::Io)?;
|
||||
let peek=std::io::BufRead::fill_buf(&mut buf).map_err(Error::Io)?;
|
||||
match &peek[0..8]{
|
||||
b"<roblox!"=>rbx_binary::from_reader(buf).map(Model::new).map_err(ReadError::RbxBinary),
|
||||
b"<roblox "=>rbx_xml::from_reader_default(buf).map(Model::new).map_err(ReadError::RbxXml),
|
||||
_=>Err(ReadError::UnknownFileFormat),
|
||||
b"<roblox!"=>return rbx_binary::from_reader(buf).map_err(Error::RbxBinary),
|
||||
b"<roblox "=>return rbx_xml::from_reader_default(buf).map_err(Error::RbxXml),
|
||||
_=>Err(Error::UnknownFileFormat),
|
||||
}
|
||||
}
|
||||
|
||||
//ConvertError
|
||||
|
||||
pub fn convert<AcquireRenderConfigId,AcquireMeshId>(
|
||||
dom:impl AsRef<WeakDom>,
|
||||
acquire_render_config_id:AcquireRenderConfigId,
|
||||
acquire_mesh_id:AcquireMeshId
|
||||
)->rbx::PartialMap1
|
||||
where
|
||||
AcquireRenderConfigId:FnMut(Option<&str>)->strafesnet_common::model::RenderConfigId,
|
||||
AcquireMeshId:FnMut(&str)->strafesnet_common::model::MeshId,
|
||||
{
|
||||
rbx::convert(&dom.as_ref(),acquire_render_config_id,acquire_mesh_id)
|
||||
pub fn read<R:Read,F:FnMut(&str)->Option<strafesnet_common::model::TextureId>>(input:R,acquire_id:F)->Result<strafesnet_common::map::CompleteMap,Error>{
|
||||
Ok(rbx::convert(load_dom(input)?,acquire_id))
|
||||
}
|
210
src/mesh.rs
210
src/mesh.rs
@ -1,210 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use rbx_mesh::mesh::{Vertex2, Vertex2Truncated};
|
||||
use strafesnet_common::{integer::vec3,model::{self, ColorId, IndexedVertex, NormalId, PolygonGroup, PolygonList, PositionId, TextureCoordinateId, VertexId}};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error{
|
||||
Planar64Vec3(strafesnet_common::integer::Planar64TryFromFloatError),
|
||||
RbxMesh(rbx_mesh::mesh::Error)
|
||||
}
|
||||
impl std::fmt::Display for Error{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
write!(f,"{self:?}")
|
||||
}
|
||||
}
|
||||
impl std::error::Error for Error{}
|
||||
|
||||
fn ingest_vertices2<
|
||||
AcquirePosId,
|
||||
AcquireTexId,
|
||||
AcquireNormalId,
|
||||
AcquireColorId,
|
||||
AcquireVertexId,
|
||||
>(
|
||||
vertices:Vec<Vertex2>,
|
||||
acquire_pos_id:&mut AcquirePosId,
|
||||
acquire_tex_id:&mut AcquireTexId,
|
||||
acquire_normal_id:&mut AcquireNormalId,
|
||||
acquire_color_id:&mut AcquireColorId,
|
||||
acquire_vertex_id:&mut AcquireVertexId,
|
||||
)->Result<HashMap<rbx_mesh::mesh::VertexId2,VertexId>,Error>
|
||||
where
|
||||
AcquirePosId:FnMut([f32;3])->Result<PositionId,Error>,
|
||||
AcquireTexId:FnMut([f32;2])->TextureCoordinateId,
|
||||
AcquireNormalId:FnMut([f32;3])->Result<NormalId,Error>,
|
||||
AcquireColorId:FnMut([f32;4])->ColorId,
|
||||
AcquireVertexId:FnMut(IndexedVertex)->VertexId,
|
||||
{
|
||||
//this monster is collecting a map of old_vertices_index -> unique_vertices_index
|
||||
//while also doing the inserting unique entries into lists simultaneously
|
||||
Ok(vertices.into_iter().enumerate().map(|(vertex_id,vertex)|Ok((
|
||||
rbx_mesh::mesh::VertexId2(vertex_id as u32),
|
||||
acquire_vertex_id(IndexedVertex{
|
||||
pos:acquire_pos_id(vertex.pos)?,
|
||||
tex:acquire_tex_id(vertex.tex),
|
||||
normal:acquire_normal_id(vertex.norm)?,
|
||||
color:acquire_color_id(vertex.color.map(|f|f as f32/255.0f32))
|
||||
}),
|
||||
))).collect::<Result<_,_>>()?)
|
||||
}
|
||||
fn ingest_vertices_truncated2<
|
||||
AcquirePosId,
|
||||
AcquireTexId,
|
||||
AcquireNormalId,
|
||||
AcquireVertexId,
|
||||
>(
|
||||
vertices:Vec<Vertex2Truncated>,
|
||||
acquire_pos_id:&mut AcquirePosId,
|
||||
acquire_tex_id:&mut AcquireTexId,
|
||||
acquire_normal_id:&mut AcquireNormalId,
|
||||
static_color_id:ColorId,//pick one color and fill everything with it
|
||||
acquire_vertex_id:&mut AcquireVertexId,
|
||||
)->Result<HashMap<rbx_mesh::mesh::VertexId2,VertexId>,Error>
|
||||
where
|
||||
AcquirePosId:FnMut([f32;3])->Result<PositionId,Error>,
|
||||
AcquireTexId:FnMut([f32;2])->TextureCoordinateId,
|
||||
AcquireNormalId:FnMut([f32;3])->Result<NormalId,Error>,
|
||||
AcquireVertexId:FnMut(IndexedVertex)->VertexId,
|
||||
{
|
||||
//this monster is collecting a map of old_vertices_index -> unique_vertices_index
|
||||
//while also doing the inserting unique entries into lists simultaneously
|
||||
Ok(vertices.into_iter().enumerate().map(|(vertex_id,vertex)|Ok((
|
||||
rbx_mesh::mesh::VertexId2(vertex_id as u32),
|
||||
acquire_vertex_id(IndexedVertex{
|
||||
pos:acquire_pos_id(vertex.pos)?,
|
||||
tex:acquire_tex_id(vertex.tex),
|
||||
normal:acquire_normal_id(vertex.norm)?,
|
||||
color:static_color_id
|
||||
}),
|
||||
))).collect::<Result<_,_>>()?)
|
||||
}
|
||||
|
||||
fn ingest_faces2_lods3(
|
||||
polygon_groups:&mut Vec<PolygonGroup>,
|
||||
vertex_id_map:&HashMap<rbx_mesh::mesh::VertexId2,VertexId>,
|
||||
faces:&Vec<rbx_mesh::mesh::Face2>,
|
||||
lods:&Vec<rbx_mesh::mesh::Lod3>
|
||||
){
|
||||
//faces have to be split into polygon groups based on lod
|
||||
polygon_groups.extend(lods.windows(2).map(|lod_pair|
|
||||
PolygonGroup::PolygonList(PolygonList::new(faces[lod_pair[0].0 as usize..lod_pair[1].0 as usize].iter().map(|face|
|
||||
vec![vertex_id_map[&face.0],vertex_id_map[&face.1],vertex_id_map[&face.2]]
|
||||
).collect()))
|
||||
))
|
||||
}
|
||||
|
||||
pub fn convert(roblox_mesh_bytes:crate::data::RobloxMeshBytes)->Result<model::Mesh,Error>{
|
||||
//generate that mesh boi
|
||||
let mut unique_pos=Vec::new();
|
||||
let mut pos_id_from=HashMap::new();
|
||||
let mut unique_tex=Vec::new();
|
||||
let mut tex_id_from=HashMap::new();
|
||||
let mut unique_normal=Vec::new();
|
||||
let mut normal_id_from=HashMap::new();
|
||||
let mut unique_color=Vec::new();
|
||||
let mut color_id_from=HashMap::new();
|
||||
let mut unique_vertices=Vec::new();
|
||||
let mut vertex_id_from=HashMap::new();
|
||||
let mut polygon_groups=Vec::new();
|
||||
let mut acquire_pos_id=|pos|{
|
||||
let p=vec3::try_from_f32_array(pos).map_err(Error::Planar64Vec3)?;
|
||||
Ok(PositionId::new(*pos_id_from.entry(p).or_insert_with(||{
|
||||
let pos_id=unique_pos.len();
|
||||
unique_pos.push(p);
|
||||
pos_id
|
||||
}) as u32))
|
||||
};
|
||||
let mut acquire_tex_id=|tex|{
|
||||
let h=bytemuck::cast::<[f32;2],[u32;2]>(tex);
|
||||
TextureCoordinateId::new(*tex_id_from.entry(h).or_insert_with(||{
|
||||
let tex_id=unique_tex.len();
|
||||
unique_tex.push(glam::Vec2::from_array(tex));
|
||||
tex_id
|
||||
}) as u32)
|
||||
};
|
||||
let mut acquire_normal_id=|normal|{
|
||||
let n=vec3::try_from_f32_array(normal).map_err(Error::Planar64Vec3)?;
|
||||
Ok(NormalId::new(*normal_id_from.entry(n).or_insert_with(||{
|
||||
let normal_id=unique_normal.len();
|
||||
unique_normal.push(n);
|
||||
normal_id
|
||||
}) as u32))
|
||||
};
|
||||
let mut acquire_color_id=|color|{
|
||||
let h=bytemuck::cast::<[f32;4],[u32;4]>(color);
|
||||
ColorId::new(*color_id_from.entry(h).or_insert_with(||{
|
||||
let color_id=unique_color.len();
|
||||
unique_color.push(glam::Vec4::from_array(color));
|
||||
color_id
|
||||
}) as u32)
|
||||
};
|
||||
let mut acquire_vertex_id=|vertex:IndexedVertex|{
|
||||
VertexId::new(*vertex_id_from.entry(vertex.clone()).or_insert_with(||{
|
||||
let vertex_id=unique_vertices.len();
|
||||
unique_vertices.push(vertex);
|
||||
vertex_id
|
||||
}) as u32)
|
||||
};
|
||||
match rbx_mesh::read_versioned(roblox_mesh_bytes.cursor()).map_err(Error::RbxMesh)?{
|
||||
rbx_mesh::mesh::VersionedMesh::Version1(mesh)=>{
|
||||
let color_id=acquire_color_id([1.0f32;4]);
|
||||
polygon_groups.push(PolygonGroup::PolygonList(PolygonList::new(mesh.vertices.chunks_exact(3).map(|trip|{
|
||||
let mut ingest_vertex1=|vertex:&rbx_mesh::mesh::Vertex1|Ok(acquire_vertex_id(IndexedVertex{
|
||||
pos:acquire_pos_id(vertex.pos)?,
|
||||
tex:acquire_tex_id([vertex.tex[0],vertex.tex[1]]),
|
||||
normal:acquire_normal_id(vertex.norm)?,
|
||||
color:color_id,
|
||||
}));
|
||||
Ok(vec![ingest_vertex1(&trip[0])?,ingest_vertex1(&trip[1])?,ingest_vertex1(&trip[2])?])
|
||||
}).collect::<Result<_,_>>()?)));
|
||||
},
|
||||
rbx_mesh::mesh::VersionedMesh::Version2(mesh)=>{
|
||||
let vertex_id_map=match mesh.header.sizeof_vertex{
|
||||
rbx_mesh::mesh::SizeOfVertex2::Truncated=>{
|
||||
//pick white and make all the vertices white
|
||||
let color_id=acquire_color_id([1.0f32;4]);
|
||||
ingest_vertices_truncated2(mesh.vertices_truncated,&mut acquire_pos_id,&mut acquire_tex_id,&mut acquire_normal_id,color_id,&mut acquire_vertex_id)
|
||||
},
|
||||
rbx_mesh::mesh::SizeOfVertex2::Full=>ingest_vertices2(mesh.vertices,&mut acquire_pos_id,&mut acquire_tex_id,&mut acquire_normal_id,&mut acquire_color_id,&mut acquire_vertex_id),
|
||||
}?;
|
||||
//one big happy group for all the faces
|
||||
polygon_groups.push(PolygonGroup::PolygonList(PolygonList::new(mesh.faces.into_iter().map(|face|
|
||||
vec![vertex_id_map[&face.0],vertex_id_map[&face.1],vertex_id_map[&face.2]]
|
||||
).collect())));
|
||||
},
|
||||
rbx_mesh::mesh::VersionedMesh::Version3(mesh)=>{
|
||||
let vertex_id_map=match mesh.header.sizeof_vertex{
|
||||
rbx_mesh::mesh::SizeOfVertex2::Truncated=>{
|
||||
let color_id=acquire_color_id([1.0f32;4]);
|
||||
ingest_vertices_truncated2(mesh.vertices_truncated,&mut acquire_pos_id,&mut acquire_tex_id,&mut acquire_normal_id,color_id,&mut acquire_vertex_id)
|
||||
},
|
||||
rbx_mesh::mesh::SizeOfVertex2::Full=>ingest_vertices2(mesh.vertices,&mut acquire_pos_id,&mut acquire_tex_id,&mut acquire_normal_id,&mut acquire_color_id,&mut acquire_vertex_id),
|
||||
}?;
|
||||
ingest_faces2_lods3(&mut polygon_groups,&vertex_id_map,&mesh.faces,&mesh.lods);
|
||||
},
|
||||
rbx_mesh::mesh::VersionedMesh::Version4(mesh)=>{
|
||||
let vertex_id_map=ingest_vertices2(
|
||||
mesh.vertices,&mut acquire_pos_id,&mut acquire_tex_id,&mut acquire_normal_id,&mut acquire_color_id,&mut acquire_vertex_id
|
||||
)?;
|
||||
ingest_faces2_lods3(&mut polygon_groups,&vertex_id_map,&mesh.faces,&mesh.lods);
|
||||
},
|
||||
rbx_mesh::mesh::VersionedMesh::Version5(mesh)=>{
|
||||
let vertex_id_map=ingest_vertices2(
|
||||
mesh.vertices,&mut acquire_pos_id,&mut acquire_tex_id,&mut acquire_normal_id,&mut acquire_color_id,&mut acquire_vertex_id
|
||||
)?;
|
||||
ingest_faces2_lods3(&mut polygon_groups,&vertex_id_map,&mesh.faces,&mesh.lods);
|
||||
},
|
||||
}
|
||||
Ok(model::Mesh{
|
||||
unique_pos,
|
||||
unique_normal,
|
||||
unique_tex,
|
||||
unique_color,
|
||||
unique_vertices,
|
||||
polygon_groups,
|
||||
//these should probably be moved to the model...
|
||||
graphics_groups:Vec::new(),
|
||||
physics_groups:Vec::new(),
|
||||
})
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
use strafesnet_common::model::{Color4,TextureCoordinate,Mesh,IndexedGraphicsGroup,IndexedPhysicsGroup,IndexedVertex,PolygonGroupId,PolygonGroup,PolygonList,IndexedVertexList,PositionId,TextureCoordinateId,NormalId,ColorId,VertexId,RenderConfigId};
|
||||
use strafesnet_common::integer::{vec3,Planar64Vec3};
|
||||
use strafesnet_common::integer::Planar64Vec3;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Primitives{
|
||||
@ -25,22 +25,22 @@ const CUBE_DEFAULT_TEXTURE_COORDS:[TextureCoordinate;4]=[
|
||||
TextureCoordinate::new(0.0,1.0),
|
||||
];
|
||||
const CUBE_DEFAULT_VERTICES:[Planar64Vec3;8]=[
|
||||
vec3::int(-1,-1, 1),//0 left bottom back
|
||||
vec3::int( 1,-1, 1),//1 right bottom back
|
||||
vec3::int( 1, 1, 1),//2 right top back
|
||||
vec3::int(-1, 1, 1),//3 left top back
|
||||
vec3::int(-1, 1,-1),//4 left top front
|
||||
vec3::int( 1, 1,-1),//5 right top front
|
||||
vec3::int( 1,-1,-1),//6 right bottom front
|
||||
vec3::int(-1,-1,-1),//7 left bottom front
|
||||
Planar64Vec3::int(-1,-1, 1),//0 left bottom back
|
||||
Planar64Vec3::int( 1,-1, 1),//1 right bottom back
|
||||
Planar64Vec3::int( 1, 1, 1),//2 right top back
|
||||
Planar64Vec3::int(-1, 1, 1),//3 left top back
|
||||
Planar64Vec3::int(-1, 1,-1),//4 left top front
|
||||
Planar64Vec3::int( 1, 1,-1),//5 right top front
|
||||
Planar64Vec3::int( 1,-1,-1),//6 right bottom front
|
||||
Planar64Vec3::int(-1,-1,-1),//7 left bottom front
|
||||
];
|
||||
const CUBE_DEFAULT_NORMALS:[Planar64Vec3;6]=[
|
||||
vec3::int( 1, 0, 0),//CubeFace::Right
|
||||
vec3::int( 0, 1, 0),//CubeFace::Top
|
||||
vec3::int( 0, 0, 1),//CubeFace::Back
|
||||
vec3::int(-1, 0, 0),//CubeFace::Left
|
||||
vec3::int( 0,-1, 0),//CubeFace::Bottom
|
||||
vec3::int( 0, 0,-1),//CubeFace::Front
|
||||
Planar64Vec3::int( 1, 0, 0),//CubeFace::Right
|
||||
Planar64Vec3::int( 0, 1, 0),//CubeFace::Top
|
||||
Planar64Vec3::int( 0, 0, 1),//CubeFace::Back
|
||||
Planar64Vec3::int(-1, 0, 0),//CubeFace::Left
|
||||
Planar64Vec3::int( 0,-1, 0),//CubeFace::Bottom
|
||||
Planar64Vec3::int( 0, 0,-1),//CubeFace::Front
|
||||
];
|
||||
const CUBE_DEFAULT_POLYS:[[[u32;3];4];6]=[
|
||||
// right (1, 0, 0)
|
||||
@ -96,11 +96,11 @@ pub enum WedgeFace{
|
||||
Bottom,
|
||||
}
|
||||
const WEDGE_DEFAULT_NORMALS:[Planar64Vec3;5]=[
|
||||
vec3::int( 1, 0, 0),//Wedge::Right
|
||||
vec3::int( 0, 1,-1),//Wedge::TopFront
|
||||
vec3::int( 0, 0, 1),//Wedge::Back
|
||||
vec3::int(-1, 0, 0),//Wedge::Left
|
||||
vec3::int( 0,-1, 0),//Wedge::Bottom
|
||||
Planar64Vec3::int( 1, 0, 0),//Wedge::Right
|
||||
Planar64Vec3::int( 0, 1,-1),//Wedge::TopFront
|
||||
Planar64Vec3::int( 0, 0, 1),//Wedge::Back
|
||||
Planar64Vec3::int(-1, 0, 0),//Wedge::Left
|
||||
Planar64Vec3::int( 0,-1, 0),//Wedge::Bottom
|
||||
];
|
||||
/*
|
||||
local cornerWedgeVerticies = {
|
||||
@ -120,11 +120,11 @@ pub enum CornerWedgeFace{
|
||||
Front,
|
||||
}
|
||||
const CORNERWEDGE_DEFAULT_NORMALS:[Planar64Vec3;5]=[
|
||||
vec3::int( 1, 0, 0),//CornerWedge::Right
|
||||
vec3::int( 0, 1, 1),//CornerWedge::BackTop
|
||||
vec3::int(-1, 1, 0),//CornerWedge::LeftTop
|
||||
vec3::int( 0,-1, 0),//CornerWedge::Bottom
|
||||
vec3::int( 0, 0,-1),//CornerWedge::Front
|
||||
Planar64Vec3::int( 1, 0, 0),//CornerWedge::Right
|
||||
Planar64Vec3::int( 0, 1, 1),//CornerWedge::BackTop
|
||||
Planar64Vec3::int(-1, 1, 0),//CornerWedge::LeftTop
|
||||
Planar64Vec3::int( 0,-1, 0),//CornerWedge::Bottom
|
||||
Planar64Vec3::int( 0, 0,-1),//CornerWedge::Front
|
||||
];
|
||||
pub fn unit_sphere(render:RenderConfigId)->Mesh{
|
||||
unit_cube(render)
|
||||
@ -207,6 +207,8 @@ impl FaceDescription{
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO: it's probably better to use a shared vertex buffer between all primitives and use indexed rendering instead of generating a unique vertex buffer for each primitive.
|
||||
//implementation: put all roblox primitives into one model.groups <- this won't work but I forget why
|
||||
pub fn generate_partial_unit_cube(face_descriptions:CubeFaceDescription)->Mesh{
|
||||
let mut generated_pos=Vec::new();
|
||||
let mut generated_tex=Vec::new();
|
||||
@ -215,7 +217,7 @@ pub fn generate_partial_unit_cube(face_descriptions:CubeFaceDescription)->Mesh{
|
||||
let mut generated_vertices=Vec::new();
|
||||
let mut polygon_groups=Vec::new();
|
||||
let mut graphics_groups=Vec::new();
|
||||
let mut physics_group=IndexedPhysicsGroup::default();
|
||||
let mut physics_groups=vec![IndexedPhysicsGroup::default()];
|
||||
let mut transforms=Vec::new();
|
||||
//note that on a cube every vertex is guaranteed to be unique, so there's no need to hash them against existing vertices.
|
||||
for (face_id,face_description) in face_descriptions.pairs(){
|
||||
@ -226,9 +228,9 @@ pub fn generate_partial_unit_cube(face_descriptions:CubeFaceDescription)->Mesh{
|
||||
//create new transform_index
|
||||
let transform_index=transforms.len();
|
||||
transforms.push(face_description.transform);
|
||||
generated_tex.extend(CUBE_DEFAULT_TEXTURE_COORDS.map(|tex|
|
||||
face_description.transform.transform_point2(tex)
|
||||
));
|
||||
for tex in CUBE_DEFAULT_TEXTURE_COORDS{
|
||||
generated_tex.push(face_description.transform.transform_point2(tex));
|
||||
}
|
||||
transform_index
|
||||
} as u32;
|
||||
let color_index=if let Some(color_index)=generated_color.iter().position(|&color|color==face_description.color){
|
||||
@ -271,7 +273,7 @@ pub fn generate_partial_unit_cube(face_descriptions:CubeFaceDescription)->Mesh{
|
||||
render:face_description.render,
|
||||
groups:vec![group_id],
|
||||
});
|
||||
physics_group.groups.push(group_id);
|
||||
physics_groups[0].groups.push(group_id);
|
||||
}
|
||||
Mesh{
|
||||
unique_pos:generated_pos,
|
||||
@ -281,7 +283,7 @@ pub fn generate_partial_unit_cube(face_descriptions:CubeFaceDescription)->Mesh{
|
||||
unique_vertices:generated_vertices,
|
||||
polygon_groups,
|
||||
graphics_groups,
|
||||
physics_groups:vec![physics_group],
|
||||
physics_groups,
|
||||
}
|
||||
}
|
||||
//don't think too hard about the copy paste because this is all going into the map tool eventually...
|
||||
@ -328,7 +330,7 @@ pub fn generate_partial_unit_wedge(face_descriptions:WedgeFaceDescription)->Mesh
|
||||
let mut generated_vertices=Vec::new();
|
||||
let mut polygon_groups=Vec::new();
|
||||
let mut graphics_groups=Vec::new();
|
||||
let mut physics_group=IndexedPhysicsGroup::default();
|
||||
let mut physics_groups=vec![IndexedPhysicsGroup::default()];
|
||||
let mut transforms=Vec::new();
|
||||
//note that on a cube every vertex is guaranteed to be unique, so there's no need to hash them against existing vertices.
|
||||
for (face_id,face_description) in face_descriptions.pairs(){
|
||||
@ -339,9 +341,9 @@ pub fn generate_partial_unit_wedge(face_descriptions:WedgeFaceDescription)->Mesh
|
||||
//create new transform_index
|
||||
let transform_index=transforms.len();
|
||||
transforms.push(face_description.transform);
|
||||
generated_tex.extend(CUBE_DEFAULT_TEXTURE_COORDS.map(|tex|
|
||||
face_description.transform.transform_point2(tex)
|
||||
));
|
||||
for tex in CUBE_DEFAULT_TEXTURE_COORDS{
|
||||
generated_tex.push(face_description.transform.transform_point2(tex));
|
||||
}
|
||||
transform_index
|
||||
} as u32;
|
||||
let color_index=if let Some(color_index)=generated_color.iter().position(|&color|color==face_description.color){
|
||||
@ -384,7 +386,7 @@ pub fn generate_partial_unit_wedge(face_descriptions:WedgeFaceDescription)->Mesh
|
||||
render:face_description.render,
|
||||
groups:vec![group_id],
|
||||
});
|
||||
physics_group.groups.push(group_id);
|
||||
physics_groups[0].groups.push(group_id);
|
||||
}
|
||||
Mesh{
|
||||
unique_pos:generated_pos,
|
||||
@ -394,7 +396,7 @@ pub fn generate_partial_unit_wedge(face_descriptions:WedgeFaceDescription)->Mesh
|
||||
unique_vertices:generated_vertices,
|
||||
polygon_groups,
|
||||
graphics_groups,
|
||||
physics_groups:vec![physics_group],
|
||||
physics_groups,
|
||||
}
|
||||
}
|
||||
|
||||
@ -439,7 +441,7 @@ pub fn generate_partial_unit_cornerwedge(face_descriptions:CornerWedgeFaceDescri
|
||||
let mut generated_vertices=Vec::new();
|
||||
let mut polygon_groups=Vec::new();
|
||||
let mut graphics_groups=Vec::new();
|
||||
let mut physics_group=IndexedPhysicsGroup::default();
|
||||
let mut physics_groups=vec![IndexedPhysicsGroup::default()];
|
||||
let mut transforms=Vec::new();
|
||||
//note that on a cube every vertex is guaranteed to be unique, so there's no need to hash them against existing vertices.
|
||||
for (face_id,face_description) in face_descriptions.pairs(){
|
||||
@ -450,9 +452,9 @@ pub fn generate_partial_unit_cornerwedge(face_descriptions:CornerWedgeFaceDescri
|
||||
//create new transform_index
|
||||
let transform_index=transforms.len();
|
||||
transforms.push(face_description.transform);
|
||||
generated_tex.extend(CUBE_DEFAULT_TEXTURE_COORDS.map(|tex|
|
||||
face_description.transform.transform_point2(tex)
|
||||
));
|
||||
for tex in CUBE_DEFAULT_TEXTURE_COORDS{
|
||||
generated_tex.push(face_description.transform.transform_point2(tex));
|
||||
}
|
||||
transform_index
|
||||
} as u32;
|
||||
let color_index=if let Some(color_index)=generated_color.iter().position(|&color|color==face_description.color){
|
||||
@ -495,7 +497,7 @@ pub fn generate_partial_unit_cornerwedge(face_descriptions:CornerWedgeFaceDescri
|
||||
render:face_description.render,
|
||||
groups:vec![group_id],
|
||||
});
|
||||
physics_group.groups.push(group_id);
|
||||
physics_groups[0].groups.push(group_id);
|
||||
}
|
||||
Mesh{
|
||||
unique_pos:generated_pos,
|
||||
@ -505,6 +507,6 @@ pub fn generate_partial_unit_cornerwedge(face_descriptions:CornerWedgeFaceDescri
|
||||
unique_vertices:generated_vertices,
|
||||
polygon_groups,
|
||||
graphics_groups,
|
||||
physics_groups:vec![physics_group],
|
||||
physics_groups,
|
||||
}
|
||||
}
|
||||
|
386
src/rbx.rs
386
src/rbx.rs
@ -5,7 +5,8 @@ use strafesnet_common::model;
|
||||
use strafesnet_common::gameplay_modes;
|
||||
use strafesnet_common::gameplay_style;
|
||||
use strafesnet_common::gameplay_attributes as attr;
|
||||
use strafesnet_common::integer::{self,vec3,Planar64,Planar64Vec3,Planar64Mat3,Planar64Affine3};
|
||||
use strafesnet_common::integer::{Planar64,Planar64Vec3,Planar64Mat3,Planar64Affine3};
|
||||
use strafesnet_common::model::RenderConfig;
|
||||
use strafesnet_common::model::RenderConfigId;
|
||||
use strafesnet_common::updatable::Updatable;
|
||||
|
||||
@ -19,7 +20,7 @@ fn class_is_a(class: &str, superclass: &str) -> bool {
|
||||
return class_is_a(&class_super, superclass)
|
||||
}
|
||||
}
|
||||
false
|
||||
return false
|
||||
}
|
||||
fn recursive_collect_superclass(objects: &mut std::vec::Vec<rbx_dom_weak::types::Ref>,dom: &rbx_dom_weak::WeakDom, instance: &rbx_dom_weak::Instance, superclass: &str){
|
||||
let mut stack=vec![instance];
|
||||
@ -36,15 +37,15 @@ fn recursive_collect_superclass(objects: &mut std::vec::Vec<rbx_dom_weak::types:
|
||||
}
|
||||
fn planar64_affine3_from_roblox(cf:&rbx_dom_weak::types::CFrame,size:&rbx_dom_weak::types::Vector3)->Planar64Affine3{
|
||||
Planar64Affine3::new(
|
||||
Planar64Mat3::from_cols([
|
||||
vec3::try_from_f32_array([cf.orientation.x.x,cf.orientation.y.x,cf.orientation.z.x]).unwrap()
|
||||
*integer::try_from_f32(size.x/2.0).unwrap(),
|
||||
vec3::try_from_f32_array([cf.orientation.x.y,cf.orientation.y.y,cf.orientation.z.y]).unwrap()
|
||||
*integer::try_from_f32(size.y/2.0).unwrap(),
|
||||
vec3::try_from_f32_array([cf.orientation.x.z,cf.orientation.y.z,cf.orientation.z.z]).unwrap()
|
||||
*integer::try_from_f32(size.z/2.0).unwrap(),
|
||||
].map(|t|t.fix_1())),
|
||||
vec3::try_from_f32_array([cf.position.x,cf.position.y,cf.position.z]).unwrap()
|
||||
Planar64Mat3::from_cols(
|
||||
Planar64Vec3::try_from([cf.orientation.x.x,cf.orientation.y.x,cf.orientation.z.x]).unwrap()
|
||||
*Planar64::try_from(size.x/2.0).unwrap(),
|
||||
Planar64Vec3::try_from([cf.orientation.x.y,cf.orientation.y.y,cf.orientation.z.y]).unwrap()
|
||||
*Planar64::try_from(size.y/2.0).unwrap(),
|
||||
Planar64Vec3::try_from([cf.orientation.x.z,cf.orientation.y.z,cf.orientation.z.z]).unwrap()
|
||||
*Planar64::try_from(size.z/2.0).unwrap(),
|
||||
),
|
||||
Planar64Vec3::try_from([cf.position.x,cf.position.y,cf.position.z]).unwrap()
|
||||
)
|
||||
}
|
||||
struct ModeBuilder{
|
||||
@ -63,7 +64,7 @@ impl ModesBuilder{
|
||||
//collect modes and stages into contiguous arrays
|
||||
let mut unique_modes:Vec<(gameplay_modes::ModeId,gameplay_modes::Mode)>
|
||||
=self.modes.into_iter().collect();
|
||||
unique_modes.sort_by_key(|&(mode_id,_)|mode_id);
|
||||
unique_modes.sort_by(|a,b|a.0.cmp(&b.0));
|
||||
let (mut modes,final_mode_id_from_builder_mode_id):(Vec<ModeBuilder>,HashMap<gameplay_modes::ModeId,gameplay_modes::ModeId>)
|
||||
=unique_modes.into_iter().enumerate()
|
||||
.map(|(final_mode_id,(builder_mode_id,mut mode))|{
|
||||
@ -134,7 +135,8 @@ impl ModesBuilder{
|
||||
self.stage_updates.push((mode_id,stage_id,stage_update));
|
||||
}
|
||||
}
|
||||
fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,model_id:model::ModelId,modes_builder:&mut ModesBuilder,wormhole_in_model_to_id:&mut HashMap<model::ModelId,u32>,wormhole_id_to_out_model:&mut HashMap<u32,model::ModelId>)->attr::CollisionAttributes{
|
||||
fn get_attributes(object:&rbx_dom_weak::Instance,can_collide:bool,velocity:Planar64Vec3,model_id:model::ModelId,modes_builder:&mut ModesBuilder,wormhole_in_model_to_id:&mut HashMap<model::ModelId,u32>,wormhole_id_to_out_model:&mut HashMap<u32,model::ModelId>)->attr::CollisionAttributes{
|
||||
let name=object.name.as_str();
|
||||
let mut general=attr::GeneralAttributes::default();
|
||||
let mut intersecting=attr::IntersectingAttributes::default();
|
||||
let mut contacting=attr::ContactingAttributes::default();
|
||||
@ -163,7 +165,7 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,model_id:mode
|
||||
force_intersecting=true;
|
||||
modes_builder.insert_mode(
|
||||
gameplay_modes::ModeId::MAIN,
|
||||
gameplay_modes::Mode::empty(
|
||||
gameplay_modes::Mode::new(
|
||||
gameplay_style::StyleModifiers::roblox_bhop(),
|
||||
model_id
|
||||
)
|
||||
@ -196,7 +198,7 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,model_id:mode
|
||||
gameplay_modes::ModeId::MAIN,
|
||||
gameplay_modes::ModeUpdate::element(
|
||||
model_id,
|
||||
gameplay_modes::StageElement::new(gameplay_modes::StageId::FIRST,false,gameplay_modes::StageElementBehaviour::Platform,None),//roblox does not know which stage the platform belongs to
|
||||
gameplay_modes::StageElement::new(gameplay_modes::StageId::FIRST,false,gameplay_modes::StageElementBehaviour::Platform),//roblox does not know which stage the platform belongs to
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -209,7 +211,7 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,model_id:mode
|
||||
force_intersecting=true;
|
||||
modes_builder.insert_mode(
|
||||
gameplay_modes::ModeId::new(captures[2].parse::<u32>().unwrap()),
|
||||
gameplay_modes::Mode::empty(
|
||||
gameplay_modes::Mode::new(
|
||||
gameplay_style::StyleModifiers::roblox_bhop(),
|
||||
model_id
|
||||
)
|
||||
@ -241,7 +243,7 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,model_id:mode
|
||||
modes_builder.insert_stage(
|
||||
gameplay_modes::ModeId::MAIN,
|
||||
stage_id,
|
||||
gameplay_modes::Stage::empty(model_id),
|
||||
gameplay_modes::Stage::new(model_id),
|
||||
);
|
||||
//TODO: let denormalize handle this
|
||||
gameplay_modes::StageElementBehaviour::SpawnAt
|
||||
@ -254,7 +256,6 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,model_id:mode
|
||||
"Platform"=>gameplay_modes::StageElementBehaviour::Platform,
|
||||
_=>panic!("regex1[2] messed up bad"),
|
||||
},
|
||||
None
|
||||
);
|
||||
modes_builder.push_mode_update(
|
||||
gameplay_modes::ModeId::MAIN,
|
||||
@ -268,15 +269,10 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,model_id:mode
|
||||
match &captures[1]{
|
||||
"Jump"=>modes_builder.push_mode_update(
|
||||
gameplay_modes::ModeId::MAIN,
|
||||
gameplay_modes::ModeUpdate::element(
|
||||
gameplay_modes::ModeUpdate::jump_limit(
|
||||
model_id,
|
||||
//jump_limit:
|
||||
gameplay_modes::StageElement::new(
|
||||
gameplay_modes::StageId::FIRST,
|
||||
false,
|
||||
gameplay_modes::StageElementBehaviour::Check,
|
||||
Some(captures[2].parse::<u8>().unwrap())
|
||||
)
|
||||
captures[2].parse::<u32>().unwrap()
|
||||
),
|
||||
),
|
||||
"WormholeIn"=>{
|
||||
@ -317,7 +313,7 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,model_id:mode
|
||||
}
|
||||
}
|
||||
//need some way to skip this
|
||||
if velocity!=vec3::ZERO{
|
||||
if velocity!=Planar64Vec3::ZERO{
|
||||
general.booster=Some(attr::Booster::Velocity(velocity));
|
||||
}
|
||||
match force_can_collide{
|
||||
@ -328,13 +324,13 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,model_id:mode
|
||||
"Ladder"=>contacting.contact_behaviour=Some(attr::ContactingBehaviour::Ladder(attr::ContactingLadder{sticky:true})),
|
||||
_=>(),
|
||||
}
|
||||
attr::CollisionAttributes::Contact(attr::ContactAttributes{contacting,general})
|
||||
attr::CollisionAttributes::Contact{contacting,general}
|
||||
},
|
||||
false=>if force_intersecting
|
||||
||general.any()
|
||||
||intersecting.any()
|
||||
{
|
||||
attr::CollisionAttributes::Intersect(attr::IntersectAttributes{intersecting,general})
|
||||
attr::CollisionAttributes::Intersect{intersecting,general}
|
||||
}else{
|
||||
attr::CollisionAttributes::Decoration
|
||||
},
|
||||
@ -403,52 +399,29 @@ enum RobloxBasePartDescription{
|
||||
Wedge(RobloxWedgeDescription),
|
||||
CornerWedge(RobloxCornerWedgeDescription),
|
||||
}
|
||||
enum Shape{
|
||||
Primitive(primitives::Primitives),
|
||||
MeshPart,
|
||||
}
|
||||
enum MeshAvailability{
|
||||
Immediate,
|
||||
Deferred(RenderConfigId),
|
||||
}
|
||||
struct DeferredModelDeferredAttributes{
|
||||
render:RenderConfigId,
|
||||
model:ModelDeferredAttributes,
|
||||
}
|
||||
struct ModelDeferredAttributes{
|
||||
mesh:model::MeshId,
|
||||
deferred_attributes:GetAttributesArgs,
|
||||
color:model::Color4,//transparency is in here
|
||||
transform:Planar64Affine3,
|
||||
}
|
||||
struct ModelOwnedAttributes{
|
||||
mesh:model::MeshId,
|
||||
attributes:attr::CollisionAttributes,
|
||||
color:model::Color4,//transparency is in here
|
||||
transform:Planar64Affine3,
|
||||
}
|
||||
struct GetAttributesArgs{
|
||||
name:Box<str>,
|
||||
can_collide:bool,
|
||||
velocity:Planar64Vec3,
|
||||
}
|
||||
pub fn convert<AcquireRenderConfigId,AcquireMeshId>(
|
||||
dom:&rbx_dom_weak::WeakDom,
|
||||
mut acquire_render_config_id:AcquireRenderConfigId,
|
||||
mut acquire_mesh_id:AcquireMeshId,
|
||||
)->PartialMap1
|
||||
where
|
||||
AcquireRenderConfigId:FnMut(Option<&str>)->model::RenderConfigId,
|
||||
AcquireMeshId:FnMut(&str)->model::MeshId,
|
||||
{
|
||||
pub fn convert<F:FnMut(&str)->Option<model::TextureId>>(dom:rbx_dom_weak::WeakDom,mut acquire_id:F)->map::CompleteMap{
|
||||
let mut modes_builder=ModesBuilder::default();
|
||||
|
||||
let mut deferred_models_deferred_attributes=Vec::new();
|
||||
let mut primitive_models_deferred_attributes=Vec::new();
|
||||
let mut primitive_meshes=Vec::new();
|
||||
let mut mesh_id_from_description=HashMap::new();
|
||||
let mut models1=Vec::new();
|
||||
let mut meshes=Vec::new();
|
||||
let mut indexed_model_id_from_description=HashMap::new();
|
||||
|
||||
//just going to leave it like this for now instead of reworking the data structures for this whole thing
|
||||
let textureless_render_group=acquire_render_config_id(None);
|
||||
let mut unique_attributes=Vec::new();
|
||||
let mut attributes_id_from_attributes=HashMap::new();
|
||||
|
||||
let mut wormhole_in_model_to_id=HashMap::new();
|
||||
let mut wormhole_id_to_out_model=HashMap::new();
|
||||
|
||||
//TODO: some sort of thing like RobloxResources that describes where to get each resource
|
||||
//this would be another dependency built for downloading resources to keep this one clean
|
||||
let mut unique_render_groups=vec![RenderConfig::default()];
|
||||
let textureless_render_group=RenderConfigId::new(0);
|
||||
|
||||
let mut object_refs=Vec::new();
|
||||
let mut temp_objects=Vec::new();
|
||||
@ -473,7 +446,7 @@ where
|
||||
{
|
||||
let model_transform=planar64_affine3_from_roblox(cf,size);
|
||||
|
||||
if model_transform.matrix3.det().is_zero(){
|
||||
if model_transform.matrix3.determinant()==Planar64::ZERO{
|
||||
let mut parent_ref=object.parent();
|
||||
let mut full_path=object.name.clone();
|
||||
while let Some(parent)=dom.get_by_ref(parent_ref){
|
||||
@ -486,35 +459,33 @@ where
|
||||
}
|
||||
|
||||
//at this point a new model is going to be generated for sure.
|
||||
let model_id=model::ModelId::new(primitive_models_deferred_attributes.len() as u32);
|
||||
let model_id=model::ModelId::new(models1.len() as u32);
|
||||
|
||||
//TODO: also detect "CylinderMesh" etc here
|
||||
let shape=match object.class.as_str(){
|
||||
"Part"=>if let Some(rbx_dom_weak::types::Variant::Enum(shape))=object.properties.get("Shape"){
|
||||
Shape::Primitive(match shape.to_u32(){
|
||||
let shape=match &object.class[..]{
|
||||
"Part"=>{
|
||||
if let Some(rbx_dom_weak::types::Variant::Enum(shape))=object.properties.get("Shape"){
|
||||
match shape.to_u32(){
|
||||
0=>primitives::Primitives::Sphere,
|
||||
1=>primitives::Primitives::Cube,
|
||||
2=>primitives::Primitives::Cylinder,
|
||||
3=>primitives::Primitives::Wedge,
|
||||
4=>primitives::Primitives::CornerWedge,
|
||||
other=>panic!("Funky roblox PartType={};",other),
|
||||
})
|
||||
_=>panic!("Funky roblox PartType={};",shape.to_u32()),
|
||||
}
|
||||
}else{
|
||||
panic!("Part has no Shape!");
|
||||
}
|
||||
},
|
||||
"TrussPart"=>Shape::Primitive(primitives::Primitives::Cube),
|
||||
"WedgePart"=>Shape::Primitive(primitives::Primitives::Wedge),
|
||||
"CornerWedgePart"=>Shape::Primitive(primitives::Primitives::CornerWedge),
|
||||
"MeshPart"=>Shape::MeshPart,
|
||||
"TrussPart"=>primitives::Primitives::Cube,
|
||||
"WedgePart"=>primitives::Primitives::Wedge,
|
||||
"CornerWedgePart"=>primitives::Primitives::CornerWedge,
|
||||
_=>{
|
||||
println!("Unsupported BasePart ClassName={}; defaulting to cube",object.class);
|
||||
Shape::Primitive(primitives::Primitives::Cube)
|
||||
primitives::Primitives::Cube
|
||||
}
|
||||
};
|
||||
|
||||
let (availability,mesh_id)=match shape{
|
||||
Shape::Primitive(primitive_shape)=>{
|
||||
//TODO: TAB TAB
|
||||
//use the biggest one and cut it down later...
|
||||
let mut part_texture_description:RobloxPartDescription=[None,None,None,None,None,None];
|
||||
temp_objects.clear();
|
||||
@ -532,7 +503,14 @@ where
|
||||
decal.properties.get("Color3"),
|
||||
decal.properties.get("Transparency"),
|
||||
) {
|
||||
let render_id=acquire_render_config_id(Some(content.as_ref()));
|
||||
if let Some(texture_id)=acquire_id(content.as_ref()){
|
||||
//this is equivalent to a get_or_create pattern because there is a singular no-texture RenderId
|
||||
//so RenderId==TextureId+1
|
||||
//not the most failsafe code but this is just for the map tool lmao
|
||||
if unique_render_groups.len()==texture_id.get() as usize+1{
|
||||
unique_render_groups.push(RenderConfig::texture(texture_id));
|
||||
};
|
||||
let render_id=RenderConfigId::new(texture_id.get()+1);
|
||||
let normal_id=normalid.to_u32();
|
||||
if normal_id<6{
|
||||
let (roblox_texture_color,roblox_texture_transform)=if decal.class=="Texture"{
|
||||
@ -556,7 +534,7 @@ where
|
||||
3=>(size.z,size.y),//left
|
||||
4=>(size.x,size.z),//bottom
|
||||
5=>(size.x,size.y),//front
|
||||
_=>unreachable!(),
|
||||
_=>panic!("unreachable"),
|
||||
};
|
||||
(
|
||||
glam::vec4(decal_color3.r,decal_color3.g,decal_color3.b,1.0-*decal_transparency),
|
||||
@ -577,7 +555,8 @@ where
|
||||
transform:roblox_texture_transform,
|
||||
});
|
||||
}else{
|
||||
println!("NormalId={} unsupported for shape={:?}",normal_id,primitive_shape);
|
||||
println!("NormalId={} unsupported for shape={:?}",normal_id,shape);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -591,7 +570,7 @@ where
|
||||
f4,//Cube::Bottom
|
||||
f5,//Cube::Front
|
||||
]=part_texture_description;
|
||||
let basepart_description=match primitive_shape{
|
||||
let basepart_texture_description=match shape{
|
||||
primitives::Primitives::Sphere=>RobloxBasePartDescription::Sphere([f0,f1,f2,f3,f4,f5]),
|
||||
primitives::Primitives::Cube=>RobloxBasePartDescription::Part([f0,f1,f2,f3,f4,f5]),
|
||||
primitives::Primitives::Cylinder=>RobloxBasePartDescription::Cylinder([f0,f1,f2,f3,f4,f5]),
|
||||
@ -613,13 +592,13 @@ where
|
||||
]),
|
||||
};
|
||||
//make new model if unit cube has not been created before
|
||||
let mesh_id=if let Some(&mesh_id)=mesh_id_from_description.get(&basepart_description){
|
||||
let indexed_model_id=if let Some(&indexed_model_id)=indexed_model_id_from_description.get(&basepart_texture_description){
|
||||
//push to existing texture model
|
||||
mesh_id
|
||||
indexed_model_id
|
||||
}else{
|
||||
let mesh_id=model::MeshId::new(primitive_meshes.len() as u32);
|
||||
mesh_id_from_description.insert(basepart_description.clone(),mesh_id);//borrow checker going crazy
|
||||
let mesh=match basepart_description{
|
||||
let indexed_model_id=model::MeshId::new(meshes.len() as u32);
|
||||
indexed_model_id_from_description.insert(basepart_texture_description.clone(),indexed_model_id);//borrow checker going crazy
|
||||
meshes.push(match basepart_texture_description{
|
||||
RobloxBasePartDescription::Sphere(part_texture_description)
|
||||
|RobloxBasePartDescription::Cylinder(part_texture_description)
|
||||
|RobloxBasePartDescription::Part(part_texture_description)=>{
|
||||
@ -633,7 +612,7 @@ where
|
||||
3=>primitives::CubeFace::Left,
|
||||
4=>primitives::CubeFace::Bottom,
|
||||
5=>primitives::CubeFace::Front,
|
||||
_=>unreachable!(),
|
||||
_=>panic!("unreachable"),
|
||||
},
|
||||
match roblox_face_description{
|
||||
Some(roblox_texture_transform)=>roblox_texture_transform.to_face_description(),
|
||||
@ -652,7 +631,7 @@ where
|
||||
2=>primitives::WedgeFace::Back,
|
||||
3=>primitives::WedgeFace::Left,
|
||||
4=>primitives::WedgeFace::Bottom,
|
||||
_=>unreachable!(),
|
||||
_=>panic!("unreachable"),
|
||||
},
|
||||
match roblox_face_description{
|
||||
Some(roblox_texture_transform)=>roblox_texture_transform.to_face_description(),
|
||||
@ -671,7 +650,7 @@ where
|
||||
2=>primitives::CornerWedgeFace::TopLeft,
|
||||
3=>primitives::CornerWedgeFace::Bottom,
|
||||
4=>primitives::CornerWedgeFace::Front,
|
||||
_=>unreachable!(),
|
||||
_=>panic!("unreachable"),
|
||||
},
|
||||
match roblox_face_description{
|
||||
Some(roblox_texture_transform)=>roblox_texture_transform.to_face_description(),
|
||||
@ -680,168 +659,36 @@ where
|
||||
}
|
||||
primitives::generate_partial_unit_cornerwedge(cornerwedge_face_description)
|
||||
},
|
||||
};
|
||||
primitive_meshes.push(mesh);
|
||||
mesh_id
|
||||
};
|
||||
(MeshAvailability::Immediate,mesh_id)
|
||||
},
|
||||
Shape::MeshPart=>if let (
|
||||
Some(rbx_dom_weak::types::Variant::Content(mesh_asset_id)),
|
||||
Some(rbx_dom_weak::types::Variant::Content(texture_asset_id)),
|
||||
)=(
|
||||
object.properties.get("MeshId"),
|
||||
object.properties.get("TextureID"),
|
||||
){
|
||||
(
|
||||
MeshAvailability::Deferred(acquire_render_config_id(Some(texture_asset_id.as_ref()))),
|
||||
acquire_mesh_id(mesh_asset_id.as_ref()),
|
||||
)
|
||||
}else{
|
||||
panic!("Mesh has no Mesh or Texture");
|
||||
},
|
||||
};
|
||||
let model_deferred_attributes=ModelDeferredAttributes{
|
||||
mesh:mesh_id,
|
||||
transform:model_transform,
|
||||
color:glam::vec4(color3.r as f32/255f32, color3.g as f32/255f32, color3.b as f32/255f32, 1.0-*transparency),
|
||||
deferred_attributes:GetAttributesArgs{
|
||||
name:object.name.as_str().into(),
|
||||
can_collide:*can_collide,
|
||||
velocity:vec3::try_from_f32_array([velocity.x,velocity.y,velocity.z]).unwrap(),
|
||||
},
|
||||
};
|
||||
match availability{
|
||||
MeshAvailability::Immediate=>primitive_models_deferred_attributes.push(model_deferred_attributes),
|
||||
MeshAvailability::Deferred(render)=>deferred_models_deferred_attributes.push(DeferredModelDeferredAttributes{
|
||||
render,
|
||||
model:model_deferred_attributes
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PartialMap1{
|
||||
primitive_meshes,
|
||||
primitive_models_deferred_attributes,
|
||||
deferred_models_deferred_attributes,
|
||||
}
|
||||
}
|
||||
struct MeshWithAabb{
|
||||
mesh:model::Mesh,
|
||||
aabb:strafesnet_common::aabb::Aabb,
|
||||
}
|
||||
pub struct PartialMap1{
|
||||
primitive_meshes:Vec<model::Mesh>,
|
||||
primitive_models_deferred_attributes:Vec<ModelDeferredAttributes>,
|
||||
deferred_models_deferred_attributes:Vec<DeferredModelDeferredAttributes>,
|
||||
}
|
||||
impl PartialMap1{
|
||||
pub fn add_meshpart_meshes_and_calculate_attributes(
|
||||
mut self,
|
||||
meshpart_meshes:impl IntoIterator<Item=(model::MeshId,crate::data::RobloxMeshBytes)>,
|
||||
)->PartialMap2{
|
||||
//calculate attributes
|
||||
let mut modes_builder=ModesBuilder::default();
|
||||
let mut unique_attributes=Vec::new();
|
||||
let mut attributes_id_from_attributes=HashMap::new();
|
||||
|
||||
let mut wormhole_in_model_to_id=HashMap::new();
|
||||
let mut wormhole_id_to_out_model=HashMap::new();
|
||||
|
||||
//decode roblox meshes
|
||||
//generate mesh_id_map based on meshes that failed to load
|
||||
let loaded_meshes:HashMap<model::MeshId,MeshWithAabb>=
|
||||
meshpart_meshes.into_iter().flat_map(|(old_mesh_id,roblox_mesh_bytes)|
|
||||
match crate::mesh::convert(roblox_mesh_bytes){
|
||||
Ok(mesh)=>{
|
||||
let mut aabb=strafesnet_common::aabb::Aabb::default();
|
||||
for &pos in &mesh.unique_pos{
|
||||
aabb.grow(pos);
|
||||
}
|
||||
Some((old_mesh_id,MeshWithAabb{
|
||||
mesh,
|
||||
aabb,
|
||||
}))
|
||||
},
|
||||
Err(e)=>{
|
||||
println!("Error converting mesh: {e:?}");
|
||||
None
|
||||
},
|
||||
}
|
||||
).collect();
|
||||
|
||||
let mut mesh_id_from_render_config_id=HashMap::new();
|
||||
//ignore meshes that fail to load completely for now
|
||||
let mut acquire_mesh_id_from_render_config_id=|old_mesh_id,render|{
|
||||
loaded_meshes.get(&old_mesh_id).map(|mesh_with_aabb|(
|
||||
*mesh_id_from_render_config_id.entry(old_mesh_id).or_insert_with(||HashMap::new())
|
||||
.entry(render).or_insert_with(||{
|
||||
let mesh_id=model::MeshId::new(self.primitive_meshes.len() as u32);
|
||||
let mut mesh_clone=mesh_with_aabb.mesh.clone();
|
||||
//add a render group lool
|
||||
mesh_clone.graphics_groups.push(model::IndexedGraphicsGroup{
|
||||
render,
|
||||
//the lowest lod is highest quality
|
||||
groups:vec![model::PolygonGroupId::new(0)]
|
||||
});
|
||||
self.primitive_meshes.push(mesh_clone);
|
||||
mesh_id
|
||||
}),
|
||||
&mesh_with_aabb.aabb,
|
||||
))
|
||||
indexed_model_id
|
||||
};
|
||||
//now that the meshes are loaded, these models can be generated
|
||||
let models_owned_attributes:Vec<ModelOwnedAttributes>=
|
||||
self.deferred_models_deferred_attributes.into_iter().flat_map(|deferred_model_deferred_attributes|{
|
||||
//meshes need to be cloned from loaded_meshes with a new id when they are used with a new render_id
|
||||
//insert into primitive_meshes
|
||||
let (mesh,aabb)=acquire_mesh_id_from_render_config_id(
|
||||
deferred_model_deferred_attributes.model.mesh,
|
||||
deferred_model_deferred_attributes.render
|
||||
)?;
|
||||
let size=aabb.size();
|
||||
Some(ModelDeferredAttributes{
|
||||
mesh,
|
||||
deferred_attributes:deferred_model_deferred_attributes.model.deferred_attributes,
|
||||
color:deferred_model_deferred_attributes.model.color,
|
||||
transform:Planar64Affine3::new(
|
||||
Planar64Mat3::from_cols([
|
||||
(deferred_model_deferred_attributes.model.transform.matrix3.x_axis*2/size.x).divide().fix_1(),
|
||||
(deferred_model_deferred_attributes.model.transform.matrix3.y_axis*2/size.y).divide().fix_1(),
|
||||
(deferred_model_deferred_attributes.model.transform.matrix3.z_axis*2/size.z).divide().fix_1()
|
||||
]),
|
||||
deferred_model_deferred_attributes.model.transform.translation
|
||||
),
|
||||
})
|
||||
}).chain(self.primitive_models_deferred_attributes.into_iter())
|
||||
.enumerate().map(|(model_id,model_deferred_attributes)|{
|
||||
let model_id=model::ModelId::new(model_id as u32);
|
||||
ModelOwnedAttributes{
|
||||
mesh:model_deferred_attributes.mesh,
|
||||
attributes:get_attributes(
|
||||
&model_deferred_attributes.deferred_attributes.name,
|
||||
model_deferred_attributes.deferred_attributes.can_collide,
|
||||
model_deferred_attributes.deferred_attributes.velocity,
|
||||
let attributes=get_attributes(
|
||||
&object,
|
||||
*can_collide,
|
||||
Planar64Vec3::try_from([velocity.x,velocity.y,velocity.z]).unwrap(),
|
||||
model_id,
|
||||
&mut modes_builder,
|
||||
&mut wormhole_in_model_to_id,
|
||||
&mut wormhole_id_to_out_model,
|
||||
),
|
||||
color:model_deferred_attributes.color,
|
||||
transform:model_deferred_attributes.transform,
|
||||
);
|
||||
models1.push(ModelOwnedAttributes{
|
||||
mesh:indexed_model_id,
|
||||
transform:model_transform,
|
||||
color:glam::vec4(color3.r as f32/255f32, color3.g as f32/255f32, color3.b as f32/255f32, 1.0-*transparency),
|
||||
attributes,
|
||||
});
|
||||
}
|
||||
}).collect();
|
||||
let models=models_owned_attributes.into_iter().enumerate().map(|(model_id,mut model_owned_attributes)|{
|
||||
//TODO: TAB
|
||||
}
|
||||
}
|
||||
let models=models1.into_iter().enumerate().map(|(model_id,mut model1)|{
|
||||
let model_id=model::ModelId::new(model_id as u32);
|
||||
//update attributes with wormhole id
|
||||
//TODO: errors/prints
|
||||
if let Some(wormhole_id)=wormhole_in_model_to_id.get(&model_id){
|
||||
if let Some(&wormhole_out_model_id)=wormhole_id_to_out_model.get(wormhole_id){
|
||||
match &mut model_owned_attributes.attributes{
|
||||
attr::CollisionAttributes::Contact(attr::ContactAttributes{contacting:_,general})
|
||||
|attr::CollisionAttributes::Intersect(attr::IntersectAttributes{intersecting:_,general})
|
||||
match &mut model1.attributes{
|
||||
attr::CollisionAttributes::Contact{contacting:_,general}
|
||||
|attr::CollisionAttributes::Intersect{intersecting:_,general}
|
||||
=>general.wormhole=Some(attr::Wormhole{destination_model:wormhole_out_model_id}),
|
||||
attr::CollisionAttributes::Decoration=>println!("Not a wormhole"),
|
||||
}
|
||||
@ -849,61 +696,26 @@ impl PartialMap1{
|
||||
}
|
||||
|
||||
//index the attributes
|
||||
let attributes_id=if let Some(&attributes_id)=attributes_id_from_attributes.get(&model_owned_attributes.attributes){
|
||||
let attributes_id=if let Some(&attributes_id)=attributes_id_from_attributes.get(&model1.attributes){
|
||||
attributes_id
|
||||
}else{
|
||||
let attributes_id=attr::CollisionAttributesId::new(unique_attributes.len() as u32);
|
||||
attributes_id_from_attributes.insert(model_owned_attributes.attributes.clone(),attributes_id);
|
||||
unique_attributes.push(model_owned_attributes.attributes);
|
||||
attributes_id_from_attributes.insert(model1.attributes.clone(),attributes_id);
|
||||
unique_attributes.push(model1.attributes);
|
||||
attributes_id
|
||||
};
|
||||
model::Model{
|
||||
mesh:model_owned_attributes.mesh,
|
||||
transform:model_owned_attributes.transform,
|
||||
color:model_owned_attributes.color,
|
||||
mesh:model1.mesh,
|
||||
transform:model1.transform,
|
||||
color:model1.color,
|
||||
attributes:attributes_id,
|
||||
}
|
||||
}).collect();
|
||||
PartialMap2{
|
||||
meshes:self.primitive_meshes,
|
||||
map::CompleteMap{
|
||||
render_configs:unique_render_groups,//asset_id_from_texture_id.iter().map(|t|t.to_string()).collect(),
|
||||
meshes,
|
||||
models,
|
||||
modes:modes_builder.build(),
|
||||
attributes:unique_attributes,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PartialMap2{
|
||||
meshes:Vec<model::Mesh>,
|
||||
models:Vec<model::Model>,
|
||||
modes:gameplay_modes::Modes,
|
||||
attributes:Vec<strafesnet_common::gameplay_attributes::CollisionAttributes>,
|
||||
}
|
||||
impl PartialMap2{
|
||||
pub fn add_render_configs_and_textures(
|
||||
self,
|
||||
render_configs:impl IntoIterator<Item=(model::RenderConfigId,model::RenderConfig)>,
|
||||
textures:impl IntoIterator<Item=(model::TextureId,Vec<u8>)>,
|
||||
)->map::CompleteMap{
|
||||
let (textures,texture_id_map):(Vec<Vec<u8>>,HashMap<model::TextureId,model::TextureId>)
|
||||
=textures.into_iter().enumerate().map(|(new_texture_id,(old_texture_id,texture))|{
|
||||
(texture,(old_texture_id,model::TextureId::new(new_texture_id as u32)))
|
||||
}).unzip();
|
||||
let render_configs=render_configs.into_iter().map(|(render_config_id,mut render_config)|{
|
||||
//this may generate duplicate no-texture render configs but idc
|
||||
render_config.texture=render_config.texture.and_then(|texture_id|
|
||||
texture_id_map.get(&texture_id).copied()
|
||||
);
|
||||
render_config
|
||||
}).collect();
|
||||
map::CompleteMap{
|
||||
modes:self.modes,
|
||||
attributes:self.attributes,
|
||||
meshes:self.meshes,
|
||||
models:self.models,
|
||||
//the roblox legacy texture thing always works
|
||||
textures,
|
||||
render_configs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user