Compare commits
3 commits
f78fc95c50
...
d2fa6e007c
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d2fa6e007c | ||
![]() |
8cc79b24a7 | ||
![]() |
3a87be73f9 |
5 changed files with 739 additions and 107 deletions
328
Cargo.lock
generated
328
Cargo.lock
generated
|
@ -58,7 +58,7 @@ dependencies = [
|
|||
"accesskit",
|
||||
"accesskit_consumer",
|
||||
"hashbrown 0.15.3",
|
||||
"paste",
|
||||
"paste 1.0.15",
|
||||
"static_assertions",
|
||||
"windows 0.58.0",
|
||||
"windows-core 0.58.0",
|
||||
|
@ -448,7 +448,7 @@ dependencies = [
|
|||
"bevy_transform",
|
||||
"bevy_utils",
|
||||
"blake3",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"downcast-rs",
|
||||
"either",
|
||||
"petgraph 0.6.5",
|
||||
|
@ -472,7 +472,7 @@ dependencies = [
|
|||
"bevy_utils",
|
||||
"console_error_panic_hook",
|
||||
"ctrlc",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"downcast-rs",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
|
@ -498,7 +498,7 @@ dependencies = [
|
|||
"bitflags 2.9.1",
|
||||
"blake3",
|
||||
"crossbeam-channel",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"disqualified",
|
||||
"downcast-rs",
|
||||
"either",
|
||||
|
@ -555,7 +555,7 @@ dependencies = [
|
|||
"bevy_math",
|
||||
"bevy_reflect",
|
||||
"bytemuck",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"encase",
|
||||
"serde",
|
||||
"wgpu-types 23.0.0",
|
||||
|
@ -595,7 +595,7 @@ dependencies = [
|
|||
"bevy_utils",
|
||||
"bevy_window",
|
||||
"bitflags 2.9.1",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"nonmax",
|
||||
"radsort",
|
||||
"serde",
|
||||
|
@ -643,7 +643,7 @@ dependencies = [
|
|||
"bevy_utils",
|
||||
"bitflags 2.9.1",
|
||||
"concurrent-queue",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"disqualified",
|
||||
"fixedbitset 0.5.7",
|
||||
"nonmax",
|
||||
|
@ -685,7 +685,7 @@ dependencies = [
|
|||
"bevy_input",
|
||||
"bevy_time",
|
||||
"bevy_utils",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"gilrs",
|
||||
]
|
||||
|
||||
|
@ -749,7 +749,7 @@ dependencies = [
|
|||
"bevy_tasks",
|
||||
"bevy_transform",
|
||||
"bevy_utils",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"gltf",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
|
@ -785,7 +785,7 @@ dependencies = [
|
|||
"bevy_utils",
|
||||
"bitflags 2.9.1",
|
||||
"bytemuck",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"futures-lite",
|
||||
"image 0.25.6",
|
||||
"ktx2",
|
||||
|
@ -806,7 +806,7 @@ dependencies = [
|
|||
"bevy_math",
|
||||
"bevy_reflect",
|
||||
"bevy_utils",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"smol_str",
|
||||
]
|
||||
|
||||
|
@ -888,9 +888,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1c2650169161b64f9a93e41f13253701fdf971dc95265ed667d17bea6d2a334f"
|
||||
dependencies = [
|
||||
"bevy_reflect",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"glam 0.29.3",
|
||||
"itertools",
|
||||
"itertools 0.13.0",
|
||||
"rand 0.8.5",
|
||||
"rand_distr",
|
||||
"serde",
|
||||
|
@ -914,7 +914,7 @@ dependencies = [
|
|||
"bevy_utils",
|
||||
"bitflags 2.9.1",
|
||||
"bytemuck",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"hexasphere",
|
||||
"serde",
|
||||
"wgpu 23.0.1",
|
||||
|
@ -983,7 +983,7 @@ dependencies = [
|
|||
"bevy_window",
|
||||
"bitflags 2.9.1",
|
||||
"bytemuck",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"fixedbitset 0.5.7",
|
||||
"nonmax",
|
||||
"radsort",
|
||||
|
@ -1031,7 +1031,7 @@ dependencies = [
|
|||
"bevy_ptr",
|
||||
"bevy_reflect_derive",
|
||||
"bevy_utils",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"disqualified",
|
||||
"downcast-rs",
|
||||
"erased-serde",
|
||||
|
@ -1084,7 +1084,7 @@ dependencies = [
|
|||
"bevy_window",
|
||||
"bytemuck",
|
||||
"codespan-reporting",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"downcast-rs",
|
||||
"encase",
|
||||
"futures-lite",
|
||||
|
@ -1130,7 +1130,7 @@ dependencies = [
|
|||
"bevy_render",
|
||||
"bevy_transform",
|
||||
"bevy_utils",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"serde",
|
||||
"uuid",
|
||||
]
|
||||
|
@ -1157,7 +1157,7 @@ dependencies = [
|
|||
"bevy_window",
|
||||
"bitflags 2.9.1",
|
||||
"bytemuck",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"fixedbitset 0.5.7",
|
||||
"guillotiere",
|
||||
"nonmax",
|
||||
|
@ -1227,7 +1227,7 @@ dependencies = [
|
|||
"bevy_utils",
|
||||
"bevy_window",
|
||||
"cosmic-text",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"sys-locale",
|
||||
|
@ -1258,7 +1258,7 @@ dependencies = [
|
|||
"bevy_hierarchy",
|
||||
"bevy_math",
|
||||
"bevy_reflect",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1288,7 +1288,7 @@ dependencies = [
|
|||
"bevy_utils",
|
||||
"bevy_window",
|
||||
"bytemuck",
|
||||
"derive_more",
|
||||
"derive_more 1.0.0",
|
||||
"nonmax",
|
||||
"smallvec",
|
||||
"taffy",
|
||||
|
@ -1380,7 +1380,7 @@ dependencies = [
|
|||
"bitflags 2.9.1",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools",
|
||||
"itertools 0.13.0",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
|
@ -1767,6 +1767,12 @@ dependencies = [
|
|||
"const_soft_float",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
|
@ -2020,6 +2026,18 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991"
|
||||
|
||||
[[package]]
|
||||
name = "cv-core"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6615281229e05151670257a1dc2bcc46720fe53a533093d9c4f7e534b82a9c88"
|
||||
dependencies = [
|
||||
"derive_more 0.99.20",
|
||||
"nalgebra 0.21.1",
|
||||
"num-traits",
|
||||
"sample-consensus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "d3d12"
|
||||
version = "0.7.0"
|
||||
|
@ -2053,6 +2071,19 @@ dependencies = [
|
|||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "1.0.0"
|
||||
|
@ -2295,6 +2326,16 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
version = "0.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
|
||||
dependencies = [
|
||||
"indenter",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.3.0"
|
||||
|
@ -2547,6 +2588,15 @@ dependencies = [
|
|||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gethostname"
|
||||
version = "0.4.3"
|
||||
|
@ -2937,6 +2987,19 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
||||
|
||||
[[package]]
|
||||
name = "homography"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/azazdeaz/homography#e4ae85c569b584b5d978e8855bddaffe2e7dbd82"
|
||||
dependencies = [
|
||||
"cv-core",
|
||||
"derive_more 0.99.20",
|
||||
"eyre",
|
||||
"itertools 0.10.5",
|
||||
"nalgebra 0.30.1",
|
||||
"sample-consensus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.63"
|
||||
|
@ -2973,7 +3036,7 @@ dependencies = [
|
|||
"gif",
|
||||
"jpeg-decoder",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-rational 0.3.2",
|
||||
"num-traits",
|
||||
"png 0.16.8",
|
||||
"scoped_threadpool",
|
||||
|
@ -3003,6 +3066,12 @@ dependencies = [
|
|||
"arrayvec 0.7.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indenter"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
|
@ -3071,6 +3140,15 @@ dependencies = [
|
|||
"mach2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
|
@ -3449,6 +3527,16 @@ dependencies = [
|
|||
"regex-automata 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matrixmultiply"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"rawpointer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maybe-uninit"
|
||||
version = "2.0.0"
|
||||
|
@ -3509,7 +3597,7 @@ dependencies = [
|
|||
"foreign-types 0.5.0",
|
||||
"log",
|
||||
"objc",
|
||||
"paste",
|
||||
"paste 1.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3524,7 +3612,7 @@ dependencies = [
|
|||
"foreign-types 0.5.0",
|
||||
"log",
|
||||
"objc",
|
||||
"paste",
|
||||
"paste 1.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3647,6 +3735,49 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nalgebra"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6b6147c3d50b4f3cdabfe2ecc94a0191fd3d6ad58aefd9664cf396285883486"
|
||||
dependencies = [
|
||||
"approx 0.3.2",
|
||||
"generic-array",
|
||||
"num-complex 0.2.4",
|
||||
"num-rational 0.2.4",
|
||||
"num-traits",
|
||||
"rand 0.7.3",
|
||||
"simba 0.1.5",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nalgebra"
|
||||
version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb2d0de08694bed883320212c18ee3008576bfe8c306f4c3c4a58b4876998be"
|
||||
dependencies = [
|
||||
"approx 0.5.1",
|
||||
"matrixmultiply",
|
||||
"nalgebra-macros",
|
||||
"num-complex 0.4.6",
|
||||
"num-rational 0.4.2",
|
||||
"num-traits",
|
||||
"simba 0.7.3",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nalgebra-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nannou"
|
||||
version = "0.19.0"
|
||||
|
@ -3929,6 +4060,25 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.4.2"
|
||||
|
@ -3960,6 +4110,17 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.3.2"
|
||||
|
@ -3971,6 +4132,16 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
|
@ -4444,12 +4615,31 @@ dependencies = [
|
|||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
|
||||
dependencies = [
|
||||
"paste-impl",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "paste-impl"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pennereq"
|
||||
version = "0.3.1"
|
||||
|
@ -4644,6 +4834,12 @@ dependencies = [
|
|||
"toml_edit 0.22.26",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.20+deprecated"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
|
@ -4803,6 +4999,12 @@ version = "0.6.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
|
||||
|
||||
[[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"
|
||||
|
@ -4967,6 +5169,15 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.44"
|
||||
|
@ -5034,6 +5245,15 @@ version = "1.0.20"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
|
||||
[[package]]
|
||||
name = "safe_arch"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
|
@ -5043,6 +5263,12 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sample-consensus"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3404fd9b14a035bdff14fc4097e5d7a16435fc4661e80f19ae5204f8bee3c718"
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
|
@ -5093,6 +5319,12 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
||||
|
||||
[[package]]
|
||||
name = "send_wrapper"
|
||||
version = "0.6.0"
|
||||
|
@ -5184,6 +5416,31 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simba"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb931b1367faadea6b1ab1c306a860ec17aaa5fa39f367d0c744e69d971a1fb2"
|
||||
dependencies = [
|
||||
"approx 0.3.2",
|
||||
"num-complex 0.2.4",
|
||||
"num-traits",
|
||||
"paste 0.1.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simba"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f3fd720c48c53cace224ae62bef1bbff363a70c68c4802a78b5cc6159618176"
|
||||
dependencies = [
|
||||
"approx 0.5.1",
|
||||
"num-complex 0.4.6",
|
||||
"num-traits",
|
||||
"paste 1.0.15",
|
||||
"wide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
|
@ -5726,7 +5983,10 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"bevy",
|
||||
"bevy_nannou",
|
||||
"cv-core",
|
||||
"homography",
|
||||
"iyes_perf_ui",
|
||||
"nalgebra 0.30.1",
|
||||
"nannou",
|
||||
"nannou_egui",
|
||||
"nannou_laser",
|
||||
|
@ -5779,6 +6039,12 @@ version = "1.0.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.18"
|
||||
|
@ -6392,6 +6658,16 @@ dependencies = [
|
|||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wide"
|
||||
version = "0.7.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"safe_arch",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "widestring"
|
||||
version = "1.2.0"
|
||||
|
|
|
@ -19,6 +19,11 @@ nannou_egui = { version = "0.19.0", features = ["wayland"] }
|
|||
serde_repr = "0.1.20"
|
||||
|
||||
|
||||
# homography and its dependents:
|
||||
homography = { git = "https://github.com/azazdeaz/homography" }
|
||||
nalgebra = "0.30.0"
|
||||
cv-core = "0.15.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
|
||||
|
|
|
@ -6,13 +6,14 @@
|
|||
// use nannou::lyon::geom::euclid::Transform2D;
|
||||
use nannou::{geom::Rect, math::map_range as nannou_map_range};
|
||||
use nannou::prelude::*;
|
||||
use bevy::prelude::Mat3; // for glam::f32::Mat3, which is distinct from nannou::prelude::Mat3
|
||||
// use nannou_egui::egui::emath::inverse_lerp;
|
||||
use nannou_egui::{self, egui, Egui};
|
||||
use nannou_laser::DacId;
|
||||
use nannou_laser::{self as laser};
|
||||
use serde_json::Result;
|
||||
use trap_rust::trap::filters::PointFilters;
|
||||
use trap_rust::trap::laser::{LaserPoints, StreamSource, STREAM_SOURCES, TMP_DESK_CLUBMAX};
|
||||
use trap_rust::trap::laser::{shape_rect, LaserPoints, LaserSpace, StreamSource, STREAM_SOURCES, TMP_DESK_CLUBMAX};
|
||||
use trap_rust::trap::tracks::CoordinateSpace;
|
||||
use trap_rust::trap::{laser::{python_cv_h_into_mat3, LaserModel, TMP_PYTHON_LASER_H, DacConfig}, tracks::{RenderableLines}};
|
||||
use zmq::Socket;
|
||||
|
@ -21,6 +22,14 @@ use std::time::{Instant, Duration};
|
|||
use std::collections::HashMap;
|
||||
use serde::{Serialize,Deserialize};
|
||||
|
||||
use nannou::winit::dpi::PhysicalPosition;
|
||||
|
||||
use homography::find_homography;
|
||||
use cv_core::FeatureMatch;
|
||||
// use opencv::prelude::Mat;
|
||||
// use opencv::imgproc;
|
||||
|
||||
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
|
@ -41,6 +50,29 @@ pub struct StreamConfig{
|
|||
type StreamConfigMap = HashMap<DacId, StreamConfig>;
|
||||
type StreamMap = HashMap<DacId, laser::FrameStream<LaserModel>>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Corner{
|
||||
TopLeft,
|
||||
TopRight,
|
||||
BottomLeft,
|
||||
BottomRight,
|
||||
}
|
||||
|
||||
impl Corner {
|
||||
pub fn in_laser_space() -> Vec<[f32; 2]>{
|
||||
vec!([-1.,1.], [1.,1.], [-1.,-1.], [1., -1.])
|
||||
}
|
||||
|
||||
fn index(&self) -> usize {
|
||||
match self {
|
||||
Self::TopLeft => 0,
|
||||
Self::TopRight => 1,
|
||||
Self::BottomLeft => 2,
|
||||
Self::BottomRight => 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct GuiModel {
|
||||
// A handle to the laser API used for spawning streams and detecting DACs.
|
||||
laser_api: Arc<laser::Api>,
|
||||
|
@ -63,6 +95,9 @@ struct GuiModel {
|
|||
lost_alpha: f32,
|
||||
connected: bool,
|
||||
selected_stream: Option<DacId>,
|
||||
canvas_scale: f32,
|
||||
canvas_translate: Vec2,
|
||||
canvas_dragging_corner: Option<Corner>,
|
||||
// canvas_transform: Translation2D<f32, ScreenSpace, ScreenSpace>,
|
||||
// dragging: bool,
|
||||
}
|
||||
|
@ -280,7 +315,10 @@ fn model(app: &App) -> GuiModel {
|
|||
.new_window()
|
||||
.size(1024, 768)
|
||||
// .key_pressed(key_pressed)
|
||||
// .mouse_wheel(canvas_zoom)
|
||||
.mouse_wheel(map_wheel_zoom)
|
||||
.mouse_pressed(map_mouse_pressed)
|
||||
.mouse_released(map_mouse_released)
|
||||
.mouse_moved(map_mouse_moved)
|
||||
.view(view_line_canvas)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
@ -372,6 +410,9 @@ fn model(app: &App) -> GuiModel {
|
|||
connected: true,
|
||||
per_laser_config: get_dac_configs(),
|
||||
selected_stream: None,
|
||||
canvas_scale: 25.,
|
||||
canvas_translate: Vec2::new(-300.,100.),
|
||||
canvas_dragging_corner: None,
|
||||
// canvas_transform: Transform2D
|
||||
// dimming_factor: 1.,
|
||||
}
|
||||
|
@ -704,7 +745,7 @@ fn update(_app: &App, model: &mut GuiModel, update: Update) {
|
|||
}
|
||||
|
||||
if ui
|
||||
.add(egui::Slider::new(&mut selected_config.filters.scale.factor, 0.0..=2.).text("Scale"))
|
||||
.add(egui::Slider::new(&mut selected_config.filters.scale.factor, 0.001..=2.).text("Scale"))
|
||||
.changed()
|
||||
{
|
||||
let factor = selected_config.filters.scale.factor;
|
||||
|
@ -796,8 +837,9 @@ fn view_line_canvas(app: &App, model: &GuiModel, frame: Frame) {
|
|||
// get canvas to draw on
|
||||
let draw = app.draw();
|
||||
|
||||
// set background to blue
|
||||
|
||||
// LaserPoints supports a mode that sends points directly into the laser
|
||||
// if this mode is enabled by the sender, set background to blue
|
||||
// Red if nothing is sending / not for too long.
|
||||
let bgcolor = match model.current_lines.space {
|
||||
CoordinateSpace::Laser => MEDIUMSLATEBLUE,
|
||||
_ => match model.connected{
|
||||
|
@ -809,20 +851,29 @@ fn view_line_canvas(app: &App, model: &GuiModel, frame: Frame) {
|
|||
|
||||
let win = app.window_rect();
|
||||
|
||||
let scale = 25.;
|
||||
let translate_x = -300.;
|
||||
let translate_y = 100.;
|
||||
|
||||
|
||||
let scale = model.canvas_scale;
|
||||
let translate_x = model.canvas_translate.x;
|
||||
let translate_y = model.canvas_translate.y;
|
||||
|
||||
// background grid
|
||||
draw_grid(&draw, &win, scale, 1.);
|
||||
// let t = app.time;
|
||||
|
||||
// let n_points = 10;
|
||||
let thickness = 2.0;
|
||||
// let hz = ((app.mouse.x + win.right()) / win.w()).powi(4) * 1000.0;
|
||||
|
||||
// TODO refactor to using euclid::point2D for scale
|
||||
// draw origin indicator
|
||||
draw.ellipse()
|
||||
.x_y(0. + translate_x, 0. + translate_y)
|
||||
.radius(3.)
|
||||
.color(BLUE);
|
||||
draw.line()
|
||||
.weight(thickness)
|
||||
.caps_round()
|
||||
.color(RED)
|
||||
.points([0. * scale + translate_x, 0. * -scale + translate_y].into(), [1. * scale + translate_x, 0. * -scale + translate_y].into());
|
||||
|
||||
|
||||
|
||||
// draw current laser lines
|
||||
for line in &model.current_lines.lines{
|
||||
let vertices = line.points.iter().map(|p| {
|
||||
let color = srgba(p.color.red, p.color.green, p.color.blue, p.color.alpha);
|
||||
|
@ -836,6 +887,33 @@ fn view_line_canvas(app: &App, model: &GuiModel, frame: Frame) {
|
|||
.join_round()
|
||||
.points_colored(vertices);
|
||||
}
|
||||
|
||||
// show each configured laser in the canvas. Highlight the selected.
|
||||
for (dac_id, config) in model.per_laser_config.iter() {
|
||||
let rect = shape_rect(LaserSpace::READY);
|
||||
let points = config.filters.reverse(&rect);
|
||||
|
||||
|
||||
|
||||
let vertices = points.points.iter().map(|p| {
|
||||
let color = if model.selected_stream == Some(dac_id.clone()) {
|
||||
// Srgba::hex("e52d9f");
|
||||
// ORCHID. to_srgba()
|
||||
srgba(229./255.,45./255.,159./255.,0.8)
|
||||
} else {
|
||||
// ORCHID;
|
||||
srgba(1.,1.,1., 0.2)
|
||||
};
|
||||
|
||||
let pos = [p.position[0] * scale + translate_x, p.position[1] * -scale + translate_y];
|
||||
(pos, color)
|
||||
});
|
||||
|
||||
draw.polyline()
|
||||
.weight(thickness)
|
||||
.join_round()
|
||||
.points_colored(vertices);
|
||||
}
|
||||
|
||||
|
||||
// put everything on the frame
|
||||
|
@ -982,12 +1060,137 @@ fn style() -> egui::Style {
|
|||
fn mouse_moved(_app: &App, _model: &mut GuiModel, _pos: Point2) {
|
||||
}
|
||||
|
||||
fn mouse_pressed(_app: &App, _model: &mut GuiModel, _button: MouseButton) {
|
||||
// _model.dragging
|
||||
fn laser_corners_to_world(filters: &PointFilters) -> Vec<[f32;2]> {
|
||||
let corners_raw: Vec<[f32; 2]> = Corner::in_laser_space();
|
||||
let corners_laser: LaserPoints = corners_raw.into();
|
||||
|
||||
let world_points = filters.reverse(&corners_laser);
|
||||
let world_corners: Vec<[f32;2]> = world_points.points.iter().map(|p| {
|
||||
p.position
|
||||
}).collect();
|
||||
world_corners
|
||||
}
|
||||
|
||||
fn mouse_released(_app: &App, _model: &mut GuiModel, _button: MouseButton) {}
|
||||
fn map_mouse_moved(_app: &App, model: &mut GuiModel, pos: Point2) {
|
||||
|
||||
let corner = match &model.canvas_dragging_corner {
|
||||
None => return,
|
||||
Some(c) => c,
|
||||
};
|
||||
let dac_id = match &model.selected_stream {
|
||||
None => return,
|
||||
Some(d) => d,
|
||||
};
|
||||
|
||||
let config = model.per_laser_config.get_mut(&dac_id).expect("Dac config unavailable");
|
||||
|
||||
// 1. For the dragging point, reverse the canvas space to world space:
|
||||
let world_point = [
|
||||
(pos[0] - model.canvas_translate.x) / model.canvas_scale,
|
||||
(pos[1] - model.canvas_translate.y) / -model.canvas_scale,
|
||||
];
|
||||
|
||||
// 2. find existing corners in world space, replacing the
|
||||
// dragging corner
|
||||
let mut world_corners = laser_corners_to_world(&config.filters);
|
||||
world_corners[corner.index()] = world_point;
|
||||
|
||||
// 3. find the corners of the laser, correct them for all
|
||||
// geometric filters, except the homography itself.
|
||||
let laser_corners: LaserPoints = Corner::in_laser_space().into();
|
||||
let distorted_laser_corners: Vec<[f32;2]> = config.filters.reverse_without_homography(&laser_corners).into();
|
||||
|
||||
|
||||
// 4. find new homography on pairs of points, and convert to compatible matrix type
|
||||
let matches: Vec<FeatureMatch<nalgebra::Point2<f64>>> = world_corners.iter().zip(distorted_laser_corners).map(|(world, laser)| {
|
||||
FeatureMatch(
|
||||
nalgebra::Point2::new(world[0] as f64, world[1] as f64),
|
||||
nalgebra::Point2::new(laser[0] as f64, laser[1] as f64),
|
||||
)
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
let m = find_homography(matches).unwrap();
|
||||
let mat: Mat3 = Mat3::from_cols_array(&[m[0] as f32, m[1] as f32, m[2] as f32, m[3] as f32, m[4] as f32, m[5] as f32, m[6] as f32, m[7] as f32, m[8] as f32]);
|
||||
|
||||
// 5. update config in Gui and laser stream threat
|
||||
config.filters.homography.homography_matrix = mat.clone();
|
||||
|
||||
let selected_laser_stream = model.laser_streams.get(&dac_id);
|
||||
if let Some(stream) = selected_laser_stream {
|
||||
stream.send(move |laser_model: &mut LaserModel| {
|
||||
laser_model.config.filters.homography.homography_matrix = mat;
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
fn mouse_wheel(_app: &App, _model: &mut GuiModel, _dt: MouseScrollDelta, _phase: TouchPhase) {
|
||||
// canvas zoom
|
||||
}
|
||||
|
||||
fn map_mouse_pressed(app: &App, model: &mut GuiModel, button: MouseButton) {
|
||||
if button != MouseButton::Left {
|
||||
// ignore
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(dac_id) = &model.selected_stream {
|
||||
const MATCH_DISTANCE: f32 = 30.; // screen pixels
|
||||
|
||||
let config = model.per_laser_config.get(&dac_id).expect("Dac config unavailable");
|
||||
|
||||
// find close corner to drag
|
||||
let corners = laser_corners_to_world(&config.filters);
|
||||
let canvas_corners: Vec<[f32;2]> = corners.iter().map(|p| {
|
||||
[
|
||||
p[0] * model.canvas_scale + model.canvas_translate.x,
|
||||
p[1] * -model.canvas_scale + model.canvas_translate.y
|
||||
]
|
||||
}).collect();
|
||||
|
||||
dbg!("{:?}", &canvas_corners);
|
||||
dbg!("{:?}, {:?}", &app.mouse.x, &app.mouse.y);
|
||||
|
||||
let mut selected: Option<Corner> = None;
|
||||
for (i, c) in canvas_corners.iter().enumerate(){
|
||||
if (app.mouse.x - c[0]).abs() < MATCH_DISTANCE && (app.mouse.y - c[1]).abs() < MATCH_DISTANCE {
|
||||
dbg!("close to corner! {:?}", &c);
|
||||
match i {
|
||||
0 => selected = Some(Corner::TopLeft),
|
||||
1 => selected = Some(Corner::TopRight),
|
||||
2 => selected = Some(Corner::BottomLeft),
|
||||
3 => selected = Some(Corner::BottomRight),
|
||||
_ => selected = None,
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
dbg!("selected! {:?}", &selected);
|
||||
model.canvas_dragging_corner = selected;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
let half_w = (1024 / 2) as f32;
|
||||
let half_h = (1024 / 2) as f32;
|
||||
|
||||
let x = app.mouse.x / half_w;
|
||||
let y = app.mouse.y / half_h;
|
||||
|
||||
if x > 1. || x < -1. || y > 1. || y < -1. {
|
||||
println!("Click outside of canvas: {} {}", x, y);
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
fn map_mouse_released(_app: &App, model: &mut GuiModel, _button: MouseButton) {
|
||||
model.canvas_dragging_corner = None;
|
||||
}
|
||||
|
||||
fn map_wheel_zoom(_app: &App, model: &mut GuiModel, dt: MouseScrollDelta, _phase: TouchPhase) {
|
||||
let (x,y) = match dt {
|
||||
MouseScrollDelta::PixelDelta(PhysicalPosition::<f64>{ x, y }) => (x as f32, y as f32),
|
||||
MouseScrollDelta::LineDelta(x, y) => (x,y),
|
||||
};
|
||||
|
||||
model.canvas_scale += y;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ pub trait Filter {
|
|||
// fn set_config(&self)
|
||||
// fn set_config(&self)
|
||||
fn apply(&self, points: &LaserPoints) -> LaserPoints;
|
||||
fn reverse(&self, points: &LaserPoints) -> LaserPoints;
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
|
@ -84,6 +85,34 @@ impl PointFilters {
|
|||
p
|
||||
}
|
||||
|
||||
// laser space to world space
|
||||
pub fn reverse(&self, points: &LaserPoints) -> LaserPoints{
|
||||
let mut p = self.dim.reverse(points);
|
||||
// dbg!("in {:?}", &p.points[0]);
|
||||
p = self.pincushion.reverse(&p);
|
||||
// dbg!("undistort {:?}", &p.points[0]);
|
||||
p = self.scale.reverse(&p);
|
||||
// dbg!("unscale {:?}", &p.points[0]);
|
||||
p = self.homography.reverse(&p);
|
||||
// dbg!("unperspective {:?}", &p.points[0]);
|
||||
// p = self.crop.reverse(&p);
|
||||
p
|
||||
}
|
||||
|
||||
// same as reverse() but ignores homography. Required when gathering points for calculating homography.
|
||||
pub fn reverse_without_homography(&self, points: &LaserPoints) -> LaserPoints{
|
||||
let mut p = self.dim.reverse(points);
|
||||
// dbg!("in {:?}", &p.points[0]);
|
||||
p = self.pincushion.reverse(&p);
|
||||
// dbg!("undistort {:?}", &p.points[0]);
|
||||
p = self.scale.reverse(&p);
|
||||
// dbg!("unscale {:?}", &p.points[0]);
|
||||
// p = self.homography.reverse(&p);
|
||||
// dbg!("unperspective {:?}", &p.points[0]);
|
||||
// p = self.crop.reverse(&p);
|
||||
p
|
||||
}
|
||||
|
||||
pub fn with_homography(mut self, h: Mat3) -> Self{
|
||||
self.homography.homography_matrix = h;
|
||||
self
|
||||
|
@ -116,12 +145,11 @@ impl Filter for HomographyFilter {
|
|||
_ => panic!("Invalid coordinate space"),
|
||||
|
||||
};
|
||||
// let new_position = apply_homography_matrix(LASER_H, &p);
|
||||
// let s = 1.; // when using TMP_PYTHON_LASER_H_FOR_NANNOU -- doesn't work?
|
||||
let s = 0xFFF as f32 / 2.; // when using TMP_PYTHON_LASER_H
|
||||
// also converts from world space to laser space (origin in center)
|
||||
let s = 0xFFF as f32 / 2.;
|
||||
let normalised_pos: [f32;2] = [new_position[0]/s - 1., new_position[1]/s - 1.];
|
||||
laser::Point {
|
||||
position: normalised_pos,
|
||||
position: new_position,
|
||||
.. point.clone()
|
||||
}
|
||||
|
||||
|
@ -131,6 +159,32 @@ impl Filter for HomographyFilter {
|
|||
space: CoordinateSpace::Laser
|
||||
}
|
||||
}
|
||||
|
||||
fn reverse(&self, points: &LaserPoints) -> LaserPoints{
|
||||
let space = points.space;
|
||||
let inv_matrix = self.homography_matrix.inverse();
|
||||
|
||||
let projected_positions: Vec<laser::Point> = points.points.iter().map(|point| {
|
||||
let p = point.position;
|
||||
// let s = 0xFFF as f32 / 2.;
|
||||
// let de_normalised_position: [f32;2] = [(p[0] + 1.)*s, (p[1]+1.)*s];
|
||||
let new_position = match space {
|
||||
CoordinateSpace::World => p,
|
||||
CoordinateSpace::Laser => apply_homography_matrix(inv_matrix, &p),
|
||||
_ => panic!("Invalid coordinate space"),
|
||||
|
||||
};
|
||||
// also converts from world space to laser space (origin in center)
|
||||
laser::Point {
|
||||
position: new_position,
|
||||
.. point.clone()
|
||||
}
|
||||
}).collect();
|
||||
LaserPoints{
|
||||
points: projected_positions,
|
||||
space: CoordinateSpace::World
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HomographyFilter{
|
||||
|
@ -266,40 +320,64 @@ impl Filter for CropFilter {
|
|||
space
|
||||
}
|
||||
}
|
||||
|
||||
fn reverse(&self, points: &LaserPoints) -> LaserPoints{
|
||||
// we cannot really add points, can we
|
||||
return LaserPoints{
|
||||
points: points.points.clone(),
|
||||
space: points.space,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn change_brightness(points: &LaserPoints, intensity: f32) -> LaserPoints{
|
||||
let new_points = points.points.iter().map(|point| {
|
||||
let mut color = point.color.clone();
|
||||
if intensity != 1.0 {
|
||||
color[0] *= intensity;
|
||||
color[1] *= intensity;
|
||||
color[2] *= intensity;
|
||||
}
|
||||
Point::new(point.position, color)
|
||||
}).collect();
|
||||
LaserPoints {
|
||||
points: new_points,
|
||||
space: points.space
|
||||
}
|
||||
}
|
||||
|
||||
impl Filter for DimFilter {
|
||||
fn apply(&self, points: &LaserPoints) -> LaserPoints {
|
||||
let new_points = points.points.iter().map(|point| {
|
||||
let mut color = point.color.clone();
|
||||
if self.intensity != 1.0 {
|
||||
color[0] *= self.intensity;
|
||||
color[1] *= self.intensity;
|
||||
color[2] *= self.intensity;
|
||||
}
|
||||
Point::new(point.position, color)
|
||||
}).collect();
|
||||
LaserPoints {
|
||||
points: new_points,
|
||||
space: points.space
|
||||
change_brightness(points, self.intensity)
|
||||
}
|
||||
|
||||
fn reverse(&self, points: &LaserPoints) -> LaserPoints{
|
||||
change_brightness(points, 1./self.intensity)
|
||||
}
|
||||
}
|
||||
|
||||
fn scale(points: &LaserPoints, factor: f32) -> LaserPoints{
|
||||
let new_points = points.points.iter().map(|point| {
|
||||
let mut position = point.position.clone();
|
||||
if factor != 1.0 {
|
||||
position[0] *= factor;
|
||||
position[1] *= factor;
|
||||
}
|
||||
Point::new(position, point.color)
|
||||
}).collect();
|
||||
LaserPoints {
|
||||
points: new_points,
|
||||
space: points.space
|
||||
}
|
||||
}
|
||||
|
||||
impl Filter for ScaleFilter {
|
||||
fn apply(&self, points: &LaserPoints) -> LaserPoints {
|
||||
let new_points = points.points.iter().map(|point| {
|
||||
let mut position = point.position.clone();
|
||||
if self.factor != 1.0 {
|
||||
position[0] *= self.factor;
|
||||
position[1] *= self.factor;
|
||||
}
|
||||
Point::new(position, point.color)
|
||||
}).collect();
|
||||
LaserPoints {
|
||||
points: new_points,
|
||||
space: points.space
|
||||
}
|
||||
scale(points, self.factor)
|
||||
}
|
||||
|
||||
fn reverse(&self, points: &LaserPoints) -> LaserPoints{
|
||||
scale(points, 1./self.factor)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,8 +388,6 @@ impl Filter for PincushionFilter {
|
|||
// becomes trivial
|
||||
fn apply(&self, points: &LaserPoints) -> LaserPoints{
|
||||
let space = points.space;
|
||||
// dbg!(&space);
|
||||
// assert!(!matches!(space, CoordinateSpace::Laser));
|
||||
|
||||
let projected_positions: Vec<laser::Point> = points.points.iter().map(|point| {
|
||||
let p = point.position;
|
||||
|
@ -340,4 +416,33 @@ impl Filter for PincushionFilter {
|
|||
space
|
||||
}
|
||||
}
|
||||
|
||||
// should be a reversal of what apply() does. TODO: check if the below actually
|
||||
// checks out. It might need to be slightly different, in particular, radius calculation
|
||||
// as an approximate, it might do
|
||||
fn reverse(&self, points: &LaserPoints) -> LaserPoints{
|
||||
let space = points.space;
|
||||
|
||||
let projected_positions: Vec<laser::Point> = points.points.iter().map(|point| {
|
||||
let p = point.position;
|
||||
|
||||
let radius = (p[0].powi(2) + p[1].powi(2)).sqrt();
|
||||
|
||||
let new_position = [
|
||||
p[0] / (1. + self.k_x * radius.powi(2)+ self.k_x2 * radius.powi(4)),
|
||||
p[1] / (1. + self.k_y * radius.powi(2)+ self.k_y2 * radius.powi(4))
|
||||
];
|
||||
|
||||
laser::Point {
|
||||
position: new_position,
|
||||
.. point.clone()
|
||||
}
|
||||
|
||||
}).collect();
|
||||
|
||||
LaserPoints{
|
||||
points: projected_positions,
|
||||
space
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,39 @@ use crate::trap::{filters::{PointFilters}, tracks::CoordinateSpace};
|
|||
use super::tracks::{RenderableLines};
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LaserPoints{
|
||||
pub points: Vec<laser::Point>,
|
||||
pub space: CoordinateSpace
|
||||
}
|
||||
|
||||
impl From<Vec<[f32;2]>> for LaserPoints{
|
||||
|
||||
// assumes input is in CoordinateSpace::Laser
|
||||
fn from(input: Vec<[f32;2]>) -> LaserPoints {
|
||||
// let points = Vec::new();
|
||||
let points = input.iter().map(|p| {
|
||||
laser::Point {
|
||||
position: p.clone(),
|
||||
color: [1.,1.,1.],
|
||||
weight: 0,
|
||||
}
|
||||
}).collect();
|
||||
LaserPoints{
|
||||
points,
|
||||
space: CoordinateSpace::Laser
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Into<Vec<[f32;2]>> for LaserPoints{
|
||||
fn into(self) -> Vec<[f32;2]> {
|
||||
// let points = Vec::new();
|
||||
self.points.iter().map(|p| {
|
||||
p.position
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// homography for laserworld in studio
|
||||
pub const TMP_PYTHON_LASER_H: [[f32;3];3] = [[ 2.47442963e+02, -7.01714050e+01, -9.71749119e+01],
|
||||
|
@ -132,44 +160,59 @@ impl Default for LaserPoints {
|
|||
}
|
||||
}
|
||||
|
||||
// because code is a mess, old homography assumed conversion to 0xFFF (10bit range) as
|
||||
// accepted by Python helios code. Nannuo uses the relative -1..1 coordinate system
|
||||
// coordinates are converted behind the scenes.
|
||||
// to derpecate this, the homography filter needs to be adapted
|
||||
pub enum LaserSpace {
|
||||
OLD,
|
||||
READY,
|
||||
}
|
||||
|
||||
pub fn shape_rect(space: LaserSpace) -> LaserPoints {
|
||||
let offset: f32 = match space { LaserSpace::OLD => 0., _ => 1. };
|
||||
let factor: f32 = match space { LaserSpace::OLD => 1., _ => 2./0xFFF as f32 };
|
||||
let mut points = Vec::new();
|
||||
let steps: usize = 10;
|
||||
for i in (0..=steps).rev() {
|
||||
points.push(laser::Point{
|
||||
position:[0xFFF as f32 * factor - offset, (0xFFF * i / steps) as f32 * factor - offset],
|
||||
color: [1.,1.,1.],
|
||||
weight: 0,
|
||||
});
|
||||
}
|
||||
for i in (0..=steps).rev() {
|
||||
points.push(laser::Point{
|
||||
position:[(0xFFF * i / steps) as f32 * factor - offset, 0.0 * factor - offset],
|
||||
color: [1.,1.,1.],
|
||||
weight: 0,
|
||||
});
|
||||
}
|
||||
for i in 0..=steps {
|
||||
points.push(laser::Point{
|
||||
position:[0.0 * factor - offset, (0xFFF * i / steps) as f32 * factor - offset],
|
||||
color: [1.,1.,1.],
|
||||
weight: 0,
|
||||
});
|
||||
}
|
||||
for i in 0..=steps {
|
||||
points.push(laser::Point{
|
||||
position:[(0xFFF * i / steps) as f32 * factor - offset , 0xFFF as f32 * factor - offset],
|
||||
color: [1.,1.,1.],
|
||||
weight: 0,
|
||||
});
|
||||
}
|
||||
// dbg!("{:?}", &points);
|
||||
LaserPoints { points, space: CoordinateSpace::Laser }
|
||||
}
|
||||
|
||||
// the different shapes that override the provided lines if needed
|
||||
impl StreamSource{
|
||||
pub fn get_shape(&self, current_lines: LaserPoints) -> LaserPoints {
|
||||
match self {
|
||||
Self::CurrentLines => current_lines,
|
||||
Self::Rectangle => {
|
||||
let mut points = Vec::new();
|
||||
let steps: usize = 10;
|
||||
for i in (0..=steps).rev() {
|
||||
points.push(laser::Point{
|
||||
position:[0xFFF as f32, (0xFFF * i / steps) as f32],
|
||||
color: [1.,1.,1.],
|
||||
weight: 0,
|
||||
});
|
||||
}
|
||||
for i in (0..=steps).rev() {
|
||||
points.push(laser::Point{
|
||||
position:[(0xFFF * i / steps) as f32, 0.0],
|
||||
color: [1.,1.,1.],
|
||||
weight: 0,
|
||||
});
|
||||
}
|
||||
for i in 0..=steps {
|
||||
points.push(laser::Point{
|
||||
position:[0.0 , (0xFFF * i / steps) as f32],
|
||||
color: [1.,1.,1.],
|
||||
weight: 0,
|
||||
});
|
||||
}
|
||||
for i in 0..=steps {
|
||||
points.push(laser::Point{
|
||||
position:[(0xFFF * i / steps) as f32 , 0xFFF as f32],
|
||||
color: [1.,1.,1.],
|
||||
weight: 0,
|
||||
});
|
||||
}
|
||||
// dbg!("{:?}", &points);
|
||||
LaserPoints { points, space: CoordinateSpace::Laser }
|
||||
shape_rect(LaserSpace::OLD)
|
||||
},
|
||||
Self::Grid => {
|
||||
let lines: usize = 5;
|
||||
|
|
Loading…
Reference in a new issue