proof of concept UI hooks

This commit is contained in:
Lillian Vixe 2024-04-09 05:58:37 -07:00
parent fcb6b4b2b1
commit 849469c2c1
11 changed files with 596 additions and 550 deletions

View file

@ -4,6 +4,7 @@
"./Cargo.toml",
"./Cargo.toml",
"./Cargo.toml",
"./Cargo.toml",
"./Cargo.toml"
],
}

459
Cargo.lock generated
View file

@ -179,6 +179,25 @@ dependencies = [
"num-traits",
]
[[package]]
name = "arboard"
version = "3.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2041f1943049c7978768d84e6d0fd95de98b76d6c4727b09e78ec253d29fa58"
dependencies = [
"clipboard-win",
"core-graphics",
"image",
"log",
"objc",
"objc-foundation",
"objc_id",
"parking_lot",
"thiserror",
"windows-sys 0.48.0",
"x11rb",
]
[[package]]
name = "arrayref"
version = "0.3.7"
@ -503,6 +522,27 @@ dependencies = [
"syn 2.0.50",
]
[[package]]
name = "bevy_egui"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44197ead4c9e40303fa5056be44de593f17151bd08d1d9dbe7b127700e1b9d01"
dependencies = [
"arboard",
"bevy",
"console_log",
"crossbeam-channel",
"egui",
"js-sys",
"log",
"thread_local",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"webbrowser",
"winit",
]
[[package]]
name = "bevy_encase_derive"
version = "0.13.1"
@ -1213,6 +1253,18 @@ dependencies = [
"thiserror",
]
[[package]]
name = "calloop-wayland-source"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02"
dependencies = [
"calloop",
"rustix",
"wayland-backend",
"wayland-client",
]
[[package]]
name = "cc"
version = "1.0.86"
@ -1260,6 +1312,15 @@ dependencies = [
"libloading 0.8.1",
]
[[package]]
name = "clipboard-win"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d517d4b86184dbb111d3556a10f1c8a04da7428d2987bf1081602bf11c3aa9ee"
dependencies = [
"error-code",
]
[[package]]
name = "codespan-reporting"
version = "0.11.1"
@ -1336,6 +1397,16 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "console_log"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f"
dependencies = [
"log",
"web-sys",
]
[[package]]
name = "const-fnv1a-hash"
version = "1.1.0"
@ -1539,12 +1610,41 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]]
name = "ecolor"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03cfe80b1890e1a8cdbffc6044d6872e814aaf6011835a2a5e2db0e5c5c4ef4e"
dependencies = [
"bytemuck",
]
[[package]]
name = "egui"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180f595432a5b615fc6b74afef3955249b86cfea72607b40740a4cd60d5297d0"
dependencies = [
"ahash",
"epaint",
"nohash-hasher",
]
[[package]]
name = "either"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
[[package]]
name = "emath"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6916301ecf80448f786cdf3eb51d9dbdd831538732229d49119e2d4312eaaf09"
dependencies = [
"bytemuck",
]
[[package]]
name = "encase"
version = "0.7.0"
@ -1577,6 +1677,21 @@ dependencies = [
"syn 2.0.50",
]
[[package]]
name = "epaint"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77b9fdf617dd7f58b0c8e6e9e4a1281f730cde0831d40547da446b2bb76a47af"
dependencies = [
"ab_glyph",
"ahash",
"bytemuck",
"ecolor",
"emath",
"nohash-hasher",
"parking_lot",
]
[[package]]
name = "equivalent"
version = "1.0.1"
@ -1602,6 +1717,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "error-code"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b"
[[package]]
name = "euclid"
version = "0.22.9"
@ -1723,6 +1844,15 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
[[package]]
name = "form_urlencoded"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [
"percent-encoding",
]
[[package]]
name = "futures-core"
version = "0.3.30"
@ -2010,6 +2140,15 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
[[package]]
name = "home"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "icrate"
version = "0.0.4"
@ -2021,6 +2160,16 @@ dependencies = [
"objc2 0.4.1",
]
[[package]]
name = "idna"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "image"
version = "0.24.8"
@ -2032,6 +2181,7 @@ dependencies = [
"color_quant",
"num-traits",
"png",
"tiff",
]
[[package]]
@ -2145,6 +2295,12 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "jpeg-decoder"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
[[package]]
name = "js-sys"
version = "0.3.68"
@ -2305,6 +2461,15 @@ version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "memmap2"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
dependencies = [
"libc",
]
[[package]]
name = "metal"
version = "0.27.0"
@ -2452,6 +2617,12 @@ dependencies = [
"libc",
]
[[package]]
name = "nohash-hasher"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
[[package]]
name = "nom"
version = "7.1.3"
@ -2559,6 +2730,17 @@ dependencies = [
"objc_exception",
]
[[package]]
name = "objc-foundation"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
dependencies = [
"block",
"objc",
"objc_id",
]
[[package]]
name = "objc-sys"
version = "0.2.0-beta.2"
@ -2616,6 +2798,15 @@ dependencies = [
"cc",
]
[[package]]
name = "objc_id"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
dependencies = [
"objc",
]
[[package]]
name = "oboe"
version = "0.5.0"
@ -2825,6 +3016,15 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58"
[[package]]
name = "quick-xml"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
dependencies = [
"memchr",
]
[[package]]
name = "quote"
version = "1.0.35"
@ -3029,12 +3229,31 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sctk-adwaita"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82b2eaf3a5b264a521b988b2e73042e742df700c4f962cde845d1541adb46550"
dependencies = [
"ab_glyph",
"log",
"memmap2",
"smithay-client-toolkit",
"tiny-skia",
]
[[package]]
name = "serde"
version = "1.0.197"
@ -3114,6 +3333,31 @@ dependencies = [
"serde",
]
[[package]]
name = "smithay-client-toolkit"
version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a"
dependencies = [
"bitflags 2.4.2",
"calloop",
"calloop-wayland-source",
"cursor-icon",
"libc",
"log",
"memmap2",
"rustix",
"thiserror",
"wayland-backend",
"wayland-client",
"wayland-csd-frame",
"wayland-cursor",
"wayland-protocols",
"wayland-protocols-wlr",
"wayland-scanner",
"xkeysym",
]
[[package]]
name = "smol_str"
version = "0.2.1"
@ -3138,6 +3382,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strict-num"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
[[package]]
name = "svg_fmt"
version = "0.4.1"
@ -3231,6 +3481,42 @@ dependencies = [
"once_cell",
]
[[package]]
name = "tiff"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e"
dependencies = [
"flate2",
"jpeg-decoder",
"weezl",
]
[[package]]
name = "tiny-skia"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab"
dependencies = [
"arrayref",
"arrayvec",
"bytemuck",
"cfg-if",
"log",
"tiny-skia-path",
]
[[package]]
name = "tiny-skia-path"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93"
dependencies = [
"arrayref",
"bytemuck",
"strict-num",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
@ -3373,12 +3659,27 @@ dependencies = [
"static_assertions",
]
[[package]]
name = "unicode-bidi"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-normalization"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.11.0"
@ -3397,6 +3698,17 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "url"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]]
name = "uuid"
version = "1.7.0"
@ -3430,6 +3742,7 @@ name = "vvu"
version = "0.1.0"
dependencies = [
"bevy",
"bevy_egui",
"rand",
]
@ -3515,6 +3828,115 @@ version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838"
[[package]]
name = "wayland-backend"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d50fa61ce90d76474c87f5fc002828d81b32677340112b4ef08079a9d459a40"
dependencies = [
"cc",
"downcast-rs",
"rustix",
"scoped-tls",
"smallvec",
"wayland-sys",
]
[[package]]
name = "wayland-client"
version = "0.31.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82fb96ee935c2cea6668ccb470fb7771f6215d1691746c2d896b447a00ad3f1f"
dependencies = [
"bitflags 2.4.2",
"rustix",
"wayland-backend",
"wayland-scanner",
]
[[package]]
name = "wayland-csd-frame"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e"
dependencies = [
"bitflags 2.4.2",
"cursor-icon",
"wayland-backend",
]
[[package]]
name = "wayland-cursor"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71ce5fa868dd13d11a0d04c5e2e65726d0897be8de247c0c5a65886e283231ba"
dependencies = [
"rustix",
"wayland-client",
"xcursor",
]
[[package]]
name = "wayland-protocols"
version = "0.31.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4"
dependencies = [
"bitflags 2.4.2",
"wayland-backend",
"wayland-client",
"wayland-scanner",
]
[[package]]
name = "wayland-protocols-plasma"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479"
dependencies = [
"bitflags 2.4.2",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"wayland-scanner",
]
[[package]]
name = "wayland-protocols-wlr"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6"
dependencies = [
"bitflags 2.4.2",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"wayland-scanner",
]
[[package]]
name = "wayland-scanner"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63b3a62929287001986fb58c789dce9b67604a397c15c611ad9f747300b6c283"
dependencies = [
"proc-macro2",
"quick-xml",
"quote",
]
[[package]]
name = "wayland-sys"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15a0c8eaff5216d07f226cb7a549159267f3467b289d9a2e52fd3ef5aae2b7af"
dependencies = [
"dlib",
"log",
"once_cell",
"pkg-config",
]
[[package]]
name = "web-sys"
version = "0.3.68"
@ -3535,6 +3957,29 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webbrowser"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd595fb70f33583ac61644820ebc144a26c96028b625b96cafcd861f4743fbc8"
dependencies = [
"core-foundation",
"home",
"jni 0.21.1",
"log",
"ndk-context",
"objc",
"raw-window-handle 0.5.2",
"url",
"web-sys",
]
[[package]]
name = "weezl"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
[[package]]
name = "wgpu"
version = "0.19.3"
@ -3944,6 +4389,7 @@ version = "0.29.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca"
dependencies = [
"ahash",
"android-activity",
"atomic-waker",
"bitflags 2.4.2",
@ -3957,6 +4403,7 @@ dependencies = [
"js-sys",
"libc",
"log",
"memmap2",
"ndk 0.8.0",
"ndk-sys 0.5.0+25.2.9519653",
"objc2 0.4.1",
@ -3966,10 +4413,16 @@ dependencies = [
"raw-window-handle 0.6.0",
"redox_syscall 0.3.5",
"rustix",
"sctk-adwaita",
"smithay-client-toolkit",
"smol_str",
"unicode-segmentation",
"wasm-bindgen",
"wasm-bindgen-futures",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"wayland-protocols-plasma",
"web-sys",
"web-time",
"windows-sys 0.48.0",
@ -4019,6 +4472,12 @@ version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34"
[[package]]
name = "xcursor"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911"
[[package]]
name = "xi-unicode"
version = "0.3.0"

View file

@ -8,3 +8,4 @@ edition = "2021"
[dependencies]
bevy = "0.13"
rand = "0.8.5"
bevy_egui = "0.26"

View file

@ -1,9 +1,17 @@
use bevy::app::*;
use vvlib::setup;
mod orbit_camera;
mod vvedit;
mod vvlib;
mod vvum;
use vvedit::editor_ui;
fn main() {
setup::setup(&mut App::new()).run();
editor_ui::register_edit_ui(
// ^ constructs editor UI
vvlib::setup::setup(
// ^ setup the window itself
&mut App::new(),
),
)
.run();
}

View file

@ -1,2 +1,3 @@
#![allow(dead_code)]
pub mod editor_events;
pub mod editor_ui;

View file

@ -1,4 +1,6 @@
#![allow(dead_code)]
use bevy::math::Vec2;
pub enum InputEvent {
DragMouse(Vec2),
}

52
src/vvedit/editor_ui.rs Normal file
View file

@ -0,0 +1,52 @@
use bevy::{
app::{Startup, Update},
asset::Assets,
ecs::system::{Commands, ResMut, Resource},
math::Vec3,
render::color::Color,
};
use bevy_egui::{egui, EguiContexts, EguiPlugin};
use crate::{
orbit_camera::orbit_camera::{pan_orbit_camera, spawn_camera},
vvlib::oct_asset::{MeshingOctTreePairs, OctTreeAsset},
};
pub fn register_edit_ui(app: &mut bevy::prelude::App) -> &mut bevy::prelude::App {
app.add_plugins(EguiPlugin);
app.add_systems(Startup, startup_system_edit_ui);
app.add_systems(Update, edit_window_ui);
app.insert_resource(EditWindowUIState {});
app.add_systems(Update, pan_orbit_camera);
app
}
pub fn startup_system_edit_ui(commands: Commands) {
spawn_camera(commands);
}
#[derive(Default, Resource)]
pub struct EditWindowUIState {}
pub fn edit_window_ui(
mut _shared_ui_state: ResMut<EditWindowUIState>,
mut contexts: EguiContexts,
mut oct_assets: ResMut<Assets<OctTreeAsset>>,
mut pairs: ResMut<MeshingOctTreePairs>,
) {
egui::Window::new("VVEdit").show(contexts.ctx_mut(), |ui| {
if ui.button("add voxels").clicked() {
//
for pair in &mut pairs.handles {
let id = pair.oct_handle.clone();
let tree = oct_assets.get_mut(id);
if tree.is_some() {
//
let tree = tree.unwrap();
tree.model
.set_voxel_at_location(Vec3::splat(-2.), Color::BLUE);
}
}
}
});
}

View file

@ -1,33 +1,5 @@
#![allow(dead_code)]
use bevy::app::App;
use bevy::app::Plugin;
use bevy::app::Update;
use bevy::asset::Assets;
use bevy::asset::Handle;
use bevy::ecs::component::Component;
use bevy::ecs::system::CommandQueue;
use bevy::ecs::system::Commands;
use bevy::ecs::system::Query;
use bevy::ecs::system::Res;
use bevy::ecs::system::ResMut;
use bevy::ecs::world::World;
use bevy::math::Vec3;
use bevy::render::color::Color;
use bevy::render::mesh::Indices;
use bevy::render::mesh::Mesh;
use bevy::render::mesh::PrimitiveTopology;
use bevy::render::render_asset::RenderAssetUsages;
use bevy::tasks::block_on;
use bevy::tasks::futures_lite::future;
use bevy::tasks::AsyncComputeTaskPool;
use bevy::tasks::Task;
use bevy::time::Time;
use bevy::utils::hashbrown::HashMap;
use rand::Rng;
use self::octtree::Path;
pub mod fps_display;
pub mod inputs;
pub mod intersections;
@ -137,445 +109,3 @@ pub mod constants {
pub const ORDERED: [Vec3; 6] = [PX, NX, PY, NY, PZ, NZ];
}
}
pub struct OctTreePlugin {}
impl Plugin for OctTreePlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, oct_tree_edit_updater);
}
}
#[derive(Component)]
pub struct OctTreeModelComponent {
pub model: octtree::OctTree<Color>,
pub handle: Option<Handle<Mesh>>,
pub task: Option<Task<CommandQueue>>,
}
/// schedules re-meshing updates of the models used to represent oct-tree data. collisions are instantly updated (as any update to the oct-tree itself updates the data used for collisioning, so we can be lazy about when the visuals kick in (to an extent, of course). as such, we want to kick them into an async updater for the meshes used)
pub fn oct_tree_edit_updater(
mut query: Query<&mut OctTreeModelComponent>,
mesh_assets: ResMut<Assets<Mesh>>,
) {
for mut model in &mut query {
if model.model.needs_update && model.task.is_none() {
if model.handle.is_none() {
model.handle = Some(mesh_assets.reserve_handle());
}
let thread_pool = AsyncComputeTaskPool::get();
let handle = model.handle.clone().unwrap();
let pre_collect = model.model.collect_voxels();
let task = thread_pool.spawn(async move {
let meshed = OctTreeModelComponent::deferred_render(pre_collect);
let mut command_queue = CommandQueue::default();
command_queue.push(move |world: &mut World| {
let mut mesh_assets = world.resource_mut::<Assets<Mesh>>();
mesh_assets.insert(handle, meshed);
});
return command_queue;
});
model.task = Some(task);
model.model.needs_update = false;
}
}
}
pub fn oct_tree_edit_task_catcher(
mut query: Query<&mut OctTreeModelComponent>,
mut commands: Commands,
) {
for mut model in &mut query {
if model.task.is_some() {
if let Some(mut commands_queue) =
block_on(future::poll_once(&mut model.task.as_mut().unwrap()))
{
commands.append(&mut commands_queue);
model.task = None;
}
}
}
}
//TODO: event that takes finished remeshing events and emits an event to be caught with the relevant mesh to update the meshdata
impl OctTreeModelComponent {
pub fn new(
model: octtree::OctTree<Color>,
mesh_assets: Option<ResMut<Assets<Mesh>>>,
) -> OctTreeModelComponent {
if mesh_assets.is_some() {
return OctTreeModelComponent {
model: model,
handle: Some(mesh_assets.unwrap().reserve_handle()),
task: None,
};
} else {
return OctTreeModelComponent {
model: model,
handle: None,
task: None,
};
}
}
pub fn deferred_render(elements: Vec<(Path, Vec3, Color)>) -> Mesh {
let mut vertices = Vec::new();
let mut normals = Vec::new();
let mut indices = Vec::new();
let mut colors = Vec::new();
let mut lookup = HashMap::new();
{
for (_, loc, col) in elements {
lookup.insert(as_ia(loc), col);
}
}
for (loc, col) in &lookup {
emit_cube_at(
as_v(*loc),
&mut vertices,
&mut indices,
&mut normals,
&mut colors,
*col,
lookup.get(&as_ia(as_v(*loc) + Vec3::X)).is_none(),
lookup.get(&as_ia(as_v(*loc) + Vec3::NEG_X)).is_none(),
lookup.get(&as_ia(as_v(*loc) + Vec3::Y)).is_none(),
lookup.get(&as_ia(as_v(*loc) + Vec3::NEG_Y)).is_none(),
lookup.get(&as_ia(as_v(*loc) + Vec3::Z)).is_none(),
lookup.get(&as_ia(as_v(*loc) + Vec3::NEG_Z)).is_none(),
None, // will let me do custom per-vox normals later. that requires extra calculation im not doing yet
);
}
return as_mesh(vertices, indices, normals, colors);
}
pub fn render_as_mesh(&self) -> Mesh {
let mut vertices = Vec::new();
let mut normals = Vec::new();
let mut indices = Vec::new();
let mut colors = Vec::new();
let mut lookup = HashMap::new();
{
let elements: Vec<(Path, Vec3, Color)> = self.model.collect_voxels();
for (_, loc, col) in elements {
lookup.insert(as_ia(loc), col);
}
}
for (loc, col) in &lookup {
emit_cube_at(
as_v(*loc),
&mut vertices,
&mut indices,
&mut normals,
&mut colors,
*col,
lookup.get(&as_ia(as_v(*loc) + Vec3::X)).is_none(),
lookup.get(&as_ia(as_v(*loc) + Vec3::NEG_X)).is_none(),
lookup.get(&as_ia(as_v(*loc) + Vec3::Y)).is_none(),
lookup.get(&as_ia(as_v(*loc) + Vec3::NEG_Y)).is_none(),
lookup.get(&as_ia(as_v(*loc) + Vec3::Z)).is_none(),
lookup.get(&as_ia(as_v(*loc) + Vec3::NEG_Z)).is_none(),
None, // will let me do custom per-vox normals later. that requires extra calculation im not doing yet
);
}
return as_mesh(vertices, indices, normals, colors);
}
}
fn as_ia(input: Vec3) -> [i64; 3] {
[
input.x.round() as i64,
input.y.round() as i64,
input.z.round() as i64,
]
}
fn as_v(input: [i64; 3]) -> Vec3 {
Vec3::new(input[0] as f32, input[1] as f32, input[2] as f32)
}
fn as_mesh(
vertices: Vec<[f32; 3]>,
indices: Vec<u32>,
normals: Vec<[f32; 3]>,
colors: Vec<[f32; 4]>,
) -> Mesh {
Mesh::new(
PrimitiveTopology::TriangleList,
RenderAssetUsages::RENDER_WORLD,
)
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vertices)
.with_inserted_attribute(Mesh::ATTRIBUTE_COLOR, colors)
.with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
.with_inserted_indices(Indices::U32(indices))
}
fn emit_cube_at(
pos: Vec3,
vertices: &mut Vec<[f32; 3]>,
indices: &mut Vec<u32>,
normals: &mut Vec<[f32; 3]>,
colors: &mut Vec<[f32; 4]>,
color: Color,
render_px: bool,
render_nx: bool,
render_py: bool,
render_ny: bool,
render_pz: bool,
render_nz: bool,
normal: Option<Vec3>,
) {
if render_px {
let len = vertices.len() as u32;
vertices.extend([
[pos.x + 0.5, pos.y - 0.5, pos.z - 0.5],
[pos.x + 0.5, pos.y - 0.5, pos.z + 0.5],
[pos.x + 0.5, pos.y + 0.5, pos.z + 0.5],
[pos.x + 0.5, pos.y + 0.5, pos.z - 0.5],
]);
if normal.is_some() {
let normal = normal.clone().unwrap();
normals.extend([
normal.to_array(),
normal.to_array(),
normal.to_array(),
normal.to_array(),
]);
} else {
normals.extend([
[1.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
]);
}
colors.extend([
color.as_rgba_f32(),
color.as_rgba_f32(),
color.as_rgba_f32(),
color.as_rgba_f32(),
]);
indices.extend([len, len + 3, len + 1, len + 1, len + 3, len + 2]);
}
if render_nx {
let len = vertices.len() as u32;
vertices.extend([
[pos.x - 0.5, pos.y - 0.5, pos.z - 0.5],
[pos.x - 0.5, pos.y - 0.5, pos.z + 0.5],
[pos.x - 0.5, pos.y + 0.5, pos.z + 0.5],
[pos.x - 0.5, pos.y + 0.5, pos.z - 0.5],
]);
if normal.is_some() {
let normal = normal.clone().unwrap();
normals.extend([
normal.to_array(),
normal.to_array(),
normal.to_array(),
normal.to_array(),
]);
} else {
normals.extend([
[-1.0, 0.0, 0.0],
[-1.0, 0.0, 0.0],
[-1.0, 0.0, 0.0],
[-1.0, 0.0, 0.0],
]);
}
colors.extend([
color.as_rgba_f32(),
color.as_rgba_f32(),
color.as_rgba_f32(),
color.as_rgba_f32(),
]);
indices.extend([len + 2, len + 3, len + 1, len + 1, len + 3, len]);
}
if render_py {
let len = vertices.len() as u32;
vertices.extend([
[pos.x - 0.5, pos.y + 0.5, pos.z - 0.5],
[pos.x + 0.5, pos.y + 0.5, pos.z - 0.5],
[pos.x + 0.5, pos.y + 0.5, pos.z + 0.5],
[pos.x - 0.5, pos.y + 0.5, pos.z + 0.5],
]);
if normal.is_some() {
let normal = normal.clone().unwrap();
normals.extend([
normal.to_array(),
normal.to_array(),
normal.to_array(),
normal.to_array(),
]);
} else {
normals.extend([
[0.0, 1.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 1.0, 0.0],
]);
}
colors.extend([
color.as_rgba_f32(),
color.as_rgba_f32(),
color.as_rgba_f32(),
color.as_rgba_f32(),
]);
indices.extend([len, len + 3, len + 1, len + 1, len + 3, len + 2]);
}
if render_ny {
let len = vertices.len() as u32;
vertices.extend([
[pos.x - 0.5, pos.y - 0.5, pos.z - 0.5],
[pos.x + 0.5, pos.y - 0.5, pos.z - 0.5],
[pos.x + 0.5, pos.y - 0.5, pos.z + 0.5],
[pos.x - 0.5, pos.y - 0.5, pos.z + 0.5],
]);
if normal.is_some() {
let normal = normal.clone().unwrap();
normals.extend([
normal.to_array(),
normal.to_array(),
normal.to_array(),
normal.to_array(),
]);
} else {
normals.extend([
[0.0, -1.0, 0.0],
[0.0, -1.0, 0.0],
[0.0, -1.0, 0.0],
[0.0, -1.0, 0.0],
]);
}
colors.extend([
color.as_rgba_f32(),
color.as_rgba_f32(),
color.as_rgba_f32(),
color.as_rgba_f32(),
]);
indices.extend([len + 2, len + 3, len + 1, len + 1, len + 3, len]);
}
if render_pz {
let len = vertices.len() as u32;
vertices.extend([
[pos.x - 0.5, pos.y - 0.5, pos.z + 0.5],
[pos.x - 0.5, pos.y + 0.5, pos.z + 0.5],
[pos.x + 0.5, pos.y + 0.5, pos.z + 0.5],
[pos.x + 0.5, pos.y - 0.5, pos.z + 0.5],
]);
if normal.is_some() {
let normal = normal.clone().unwrap();
normals.extend([
normal.to_array(),
normal.to_array(),
normal.to_array(),
normal.to_array(),
]);
} else {
normals.extend([
[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0],
]);
}
colors.extend([
color.as_rgba_f32(),
color.as_rgba_f32(),
color.as_rgba_f32(),
color.as_rgba_f32(),
]);
indices.extend([len, len + 3, len + 1, len + 1, len + 3, len + 2]);
}
if render_nz {
let len = vertices.len() as u32;
vertices.extend([
[pos.x - 0.5, pos.y - 0.5, pos.z - 0.5],
[pos.x - 0.5, pos.y + 0.5, pos.z - 0.5],
[pos.x + 0.5, pos.y + 0.5, pos.z - 0.5],
[pos.x + 0.5, pos.y - 0.5, pos.z - 0.5],
]);
if normal.is_some() {
let normal = normal.clone().unwrap();
normals.extend([
normal.to_array(),
normal.to_array(),
normal.to_array(),
normal.to_array(),
]);
} else {
normals.extend([
[0.0, 0.0, -1.0],
[0.0, 0.0, -1.0],
[0.0, 0.0, -1.0],
[0.0, 0.0, -1.0],
]);
}
colors.extend([
color.as_rgba_f32(),
color.as_rgba_f32(),
color.as_rgba_f32(),
color.as_rgba_f32(),
]);
indices.extend([len + 2, len + 3, len + 1, len + 1, len + 3, len]);
}
}
#[derive(Component)]
pub struct VoxelIterativeBuildTest {
pub count: usize,
}
pub fn iterate_voxels(
mut query: Query<(&mut OctTreeModelComponent, &mut VoxelIterativeBuildTest)>,
) {
for (mut model, mut counter) in &mut query {
let mut rng = rand::thread_rng();
while counter.count > 0 {
let x: f32 = rng.gen_range(-RANDOM_SPACE..RANDOM_SPACE);
let y: f32 = rng.gen_range(-RANDOM_SPACE..RANDOM_SPACE);
let z: f32 = rng.gen_range(-RANDOM_SPACE..RANDOM_SPACE);
let vec = Vec3::new(x.round(), y.round(), z.round());
let r: f32 = rng.gen_range(0.0..1.0);
let g: f32 = rng.gen_range(0.0..1.0);
let b: f32 = rng.gen_range(0.0..1.0);
model.model.set_voxel_at_location(vec, Color::rgb(r, g, b));
counter.count -= 1;
}
}
}
#[derive(Component)]
pub struct ChangeOnTimerRandomized {
pub timer: f32,
}
pub fn occasional_change(
time: Res<Time>,
mut query: Query<(&mut OctTreeModelComponent, &mut ChangeOnTimerRandomized)>,
) {
for (mut model, mut timer) in &mut query {
timer.timer += time.delta_seconds();
if timer.timer > INTERVAL {
let mut rng = rand::thread_rng();
for _ in 0..(TOTAL_TO_EDIT / ADDITION_THROTTLE) {
let x: f32 = rng.gen_range(-RANDOM_SPACE..RANDOM_SPACE);
let y: f32 = rng.gen_range(-RANDOM_SPACE..RANDOM_SPACE);
let z: f32 = rng.gen_range(-RANDOM_SPACE..RANDOM_SPACE);
let vec = Vec3::new(x.round(), y.round(), z.round());
let r: f32 = rng.gen_range(0.0..1.0);
let g: f32 = rng.gen_range(0.0..1.0);
let b: f32 = rng.gen_range(0.0..1.0);
model.model.set_voxel_at_location(vec, Color::rgb(r, g, b));
}
for _ in 0..TOTAL_TO_EDIT {
let x: f32 = rng.gen_range(-RANDOM_SPACE..RANDOM_SPACE);
let y: f32 = rng.gen_range(-RANDOM_SPACE..RANDOM_SPACE);
let z: f32 = rng.gen_range(-RANDOM_SPACE..RANDOM_SPACE);
let vec = Vec3::new(x.round(), y.round(), z.round());
model.model.remove_voxel(vec);
}
timer.timer -= INTERVAL;
}
}
}

View file

@ -7,6 +7,7 @@ use bevy::{
Handle,
},
ecs::{
component::Component,
event::EventReader,
system::{CommandQueue, Commands, Res, ResMut, Resource},
world::World,
@ -177,10 +178,10 @@ impl AssetLoader for OctLoader {
#[derive(Resource)]
pub struct MeshingOctTreePairs {
handles: Vec<HandlePair>,
pub handles: Vec<HandlePair>,
}
impl MeshingOctTreePairs {
pub fn contains(&self, id: Handle<OctTreeAsset>) -> bool {
pub fn contains_oct(&self, id: Handle<OctTreeAsset>) -> bool {
//
for handle in &self.handles {
if handle.oct_handle == id {
@ -189,6 +190,15 @@ impl MeshingOctTreePairs {
}
false
}
pub fn contains_mesh(&self, id: Handle<Mesh>) -> bool {
//
for handle in &self.handles {
if handle.mesh_handle == id {
return true;
}
}
false
}
pub fn mesh_handle_for(
&mut self,
id: Handle<OctTreeAsset>,
@ -206,10 +216,27 @@ impl MeshingOctTreePairs {
});
result
}
pub fn oct_handle_for(
&mut self,
id: Handle<Mesh>,
octtrees: &mut ResMut<Assets<OctTreeAsset>>,
) -> Handle<OctTreeAsset> {
for handle in &self.handles {
if handle.mesh_handle == id {
return handle.oct_handle.clone();
}
}
let result = octtrees.reserve_handle();
self.handles.push(HandlePair {
mesh_handle: id,
oct_handle: result.clone(),
});
result
}
}
pub struct HandlePair {
mesh_handle: Handle<Mesh>,
oct_handle: Handle<OctTreeAsset>,
pub mesh_handle: Handle<Mesh>,
pub oct_handle: Handle<OctTreeAsset>,
}
pub fn attach_mesh_handle(
@ -245,7 +272,7 @@ impl Plugin for OctAssetPlugin {
impl OctTreeAsset {
pub fn load(
mut pairs: ResMut<MeshingOctTreePairs>,
pairs: &mut ResMut<MeshingOctTreePairs>,
asset_server: Res<AssetServer>,
mut mesh_assets: ResMut<Assets<Mesh>>,
path: AssetPath,
@ -255,6 +282,11 @@ impl OctTreeAsset {
}
}
#[derive(Component)]
pub struct OctAssetMarker {
pub oct_handle: Handle<OctTreeAsset>,
}
pub fn oct_asset_to_mesh(
mut pairs: ResMut<MeshingOctTreePairs>,
mut oct_assets: ResMut<Assets<OctTreeAsset>>,

View file

@ -6,9 +6,7 @@ use bevy::{
DefaultPlugins,
};
use crate::vvum::mesh_plugin;
use super::oct_asset::{self, OctTreeAsset};
use super::oct_asset::{self, OctAssetMarker, OctTreeAsset};
pub fn setup(app: &mut App) -> &mut App {
app.add_plugins(DefaultPlugins.set(WindowPlugin {
@ -19,8 +17,6 @@ pub fn setup(app: &mut App) -> &mut App {
}),
..default()
}))
.add_plugins(mesh_plugin::PluginInitializer)
//.add_plugins(OctTreePlugin {})
.add_systems(Startup, crate::vvlib::fps_display::setup_fps_counter)
.add_systems(
Update,
@ -36,14 +32,41 @@ pub fn setup(app: &mut App) -> &mut App {
}
pub fn startup(
pairs: ResMut<oct_asset::MeshingOctTreePairs>,
mut pairs: ResMut<oct_asset::MeshingOctTreePairs>,
asset_server: Res<AssetServer>,
mesh_assets: ResMut<Assets<Mesh>>,
mut oct_assets: ResMut<Assets<OctTreeAsset>>,
mut commands: Commands,
) {
let x = OctTreeAsset::load(pairs, asset_server, mesh_assets, "test.vvg".into());
commands.spawn((PbrBundle {
mesh: x,
let id = OctTreeAsset::load(&mut pairs, asset_server, mesh_assets, "test.vvg".into());
let parent = commands
.spawn(TransformBundle {
local: Transform::from_scale(Vec3::splat(0.25)),
..Default::default()
})
.id();
let child = commands
.spawn((
PbrBundle {
mesh: id.clone(),
..default()
},
OctAssetMarker {
oct_handle: pairs.oct_handle_for(id, &mut oct_assets),
},
))
.id();
commands.entity(parent).add_child(child);
let camera_and_light_transform =
Transform::from_xyz(1.8, 1.8, 1.8).looking_at(Vec3::ZERO, Vec3::Y);
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1000.0,
range: 100.0,
..default()
},
transform: camera_and_light_transform,
..default()
},));
});
}

View file

@ -1,64 +1 @@
pub mod mesh_plugin {
use crate::vvlib::SCALE_OF_FIELD;
use bevy::prelude::*;
use crate::{
orbit_camera::orbit_camera::*,
vvlib::{
iterate_voxels, occasional_change, oct_tree_edit_task_catcher, octtree::OctTree,
ChangeOnTimerRandomized, OctTreeModelComponent, VoxelIterativeBuildTest, TOTAL_TO_EDIT,
},
};
pub struct PluginInitializer;
impl Plugin for PluginInitializer {
fn build(&self, app: &mut App) {
app.add_systems(Startup, setup);
app.add_systems(Update, pan_orbit_camera);
app.add_systems(Update, iterate_voxels);
app.add_systems(Update, occasional_change);
app.add_systems(PostUpdate, oct_tree_edit_task_catcher);
}
}
fn setup(mesh_assets: ResMut<Assets<Mesh>>, mut commands: Commands) {
let oct = OctTree::new(Vec3::ZERO, Color::RED);
let model_oct = OctTreeModelComponent::new(oct, Some(mesh_assets));
let parent = commands
.spawn(TransformBundle {
local: Transform::from_scale(Vec3::splat(SCALE_OF_FIELD)),
..Default::default()
})
.id();
let child = commands
.spawn((
PbrBundle {
mesh: model_oct.handle.clone().unwrap(),
..default()
},
model_oct,
VoxelIterativeBuildTest {
count: TOTAL_TO_EDIT,
},
ChangeOnTimerRandomized { timer: 0. },
))
.id();
commands.entity(parent).add_child(child);
let camera_and_light_transform =
Transform::from_xyz(1.8, 1.8, 1.8).looking_at(Vec3::ZERO, Vec3::Y);
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1000.0,
range: 100.0,
..default()
},
transform: camera_and_light_transform,
..default()
});
spawn_camera(commands);
}
}