tirbofish/dropbear · commit
5e7c2afbabf5fd8e8c22d9ba3731a72e1d82fea9
refactor: changed from `pub fn Java_*` to `pub extern "system" fn Java_*`
ci: the rfd crate has a dependency (`ashpd`) that caused a bug while compiling. changed rfd version.
chore: updated *most* of the dependencies. wgpu is still at v27 due to egui requiring the dependency.
refactor: due to bincode not being updated and the devs basically nuking the entire project, i have to switch to `postcard`.
refactor + chore: update rapier3d to the latest version (0.32).
refactor: update hecs to the latest version and reflect the new update onto the codebase
refactor: remove the old legacy scripting modules
opt: optimised incremental builds
Signature present but could not be verified.Unverified
@@ -1,2 +1,8 @@ -[target.x86_64-pc-windows-msvc] -rustflags = ["-C", "target-feature=+crt-static", "-C", "prefer-dynamic"] +[target.'cfg(target_os = "windows")'] +rustflags = ["-C", "target-feature=+crt-static", "-C", "prefer-dynamic", "-C", "link-arg=-fuse-ld=lld"] + +[target.'cfg(target_os = "macos")'] +rustflags = ["-C", "link-arg=-fuse-ld=/opt/homebrew/bin/zld"] + +[target.'cfg(target_os = "linux")'] +rustflags = ["-C", "link-arg=-fuse-ld=mold"] @@ -49,15 +49,23 @@ jobs: - name: install assimp-utils (Linux) if: matrix.os == 'ubuntu-latest' run: sudo apt-get install -y assimp-utils + - name: install mold linker (Linux) + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get install -y mold + clang --version || sudo apt-get install -y clang - name: install assimp (macOS) if: matrix.os == 'macos-latest' run: brew install assimp + - name: install zld linker (macOS) + if: matrix.os == 'macos-latest' + run: brew install zld - name: install rust toolchain uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.target }} - name: build eucalyptus packages - # run: cargo build --release --package eucalyptus-core --package eucalyptus-editor --package magna-carta --package redback-runtime --target ${{ matrix.target }} + # run: cargo build --release --package eucalyptus-core --package eucalyptus-editor --package magna-carta --package redback-runtime --target ${{ matrix.target }} run: cargo build --release --package eucalyptus-core --package eucalyptus-editor --package magna-carta --target ${{ matrix.target }} - name: prepare the artifact run: | @@ -77,4 +85,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: executables-${{ matrix.os_name }} - path: dist/ + path: dist/ @@ -22,8 +22,7 @@ members = [ anyhow = { version = "1.0", features = ["backtrace"] } app_dirs2 = "2.5" arboard = "3.6" -bincode = { version = "2.0", features = ["serde"] } -bytemuck = { version = "1.23", features = ["derive"] } +bytemuck = { version = "1.24", features = ["derive"] } chrono = "0.4" clap = { version = "4.5", features = ["derive"] } colored = "3.0" @@ -41,21 +40,21 @@ futures = "0.3" gilrs = "0.11" git2 = { version = "0.20", features = ["vendored-openssl"] } glam = { version = "0.30", features = ["serde", "mint"] } -hecs = { version = "0.10", features = ["serde"] } +hecs = { version = "0.11", features = ["serde"] } log = "0.4" log-once = "0.4" model_to_image = "0.1" once_cell = "1.21" parking_lot = {version = "0.12", features = ["deadlock_detection"] } -rfd = "0.15" -ron = "0.11" +rfd = "0.17" +ron = "0.12" serde = { version = "1.0", features = ["derive"] } spin_sleep = "1.3" transform-gizmo-egui = { version = "0.8" } tokio = { version = "1", features = ["full"] } wgpu = "27" winit = { version = "0.30", features = [] } -zip = "6.0" +zip = "7.0" walkdir = "2.5" rayon = "1.11" backtrace = "0.3" @@ -65,10 +64,10 @@ rustc_version_runtime = "0.3" jni = { version = "0.21", features = ["invocation"] } tree-sitter = "0.22" # must be kept as 0.22 because tree-sitter-kotlin has not been updated tree-sitter-kotlin = "0.3" -libloading = "0.8" +libloading = "0.9" indexmap = "2.11" sha2 = "0.10" -wesl = "0.2" +wesl = "0.3" dashmap = "6.1" open = "5.3" egui_plot = "0.34" @@ -79,8 +78,9 @@ quote = "1.0" egui_ltreeview = { version = "0.6", features = ["doc"] } dyn-hash = "1.0" semver = { version = "1.0", features = ["serde"] } -rapier3d = { version = "0.31", features = [ "simd-stable", "serde-serialize" ] } +rapier3d = { version = "0.32", features = [ "simd-stable", "serde-serialize" ] } cbindgen = { version = "0.29.2" } +postcard = { version = "1.1"} [workspace.dependencies.image] version = "0.25" @@ -88,9 +88,9 @@ default-features = false features = ["png"] [profile.dev] -opt-level = 3 +opt-level = 1 debug = true -codegen-units = 16 +codegen-units = 256 incremental = true lto = false @@ -25,12 +25,24 @@ If you might have not realised, all the crates/projects names are after Australi ## Build -To build, ensure build requirements, clone the repository, then build it. It will build in debug mode, and use a lot of packages, so if your CPU is not fast enough for building you should brew a cup of coffee during the build time or scroll through Instagram Reels (you could get a nice doomscroll in). +<details> +<summary>Windows</summary> -With Unix systems (macOS not tested), you will have to download a couple of dependencies if building locally: +Required dependencies: +- JDK 21 +- assimp is automatically dealt with during build +- the latest rustc +- windows sdk/visual studio of some sort -<!-- If you have a macOS system, please create a PR and add your own implementation. I know you need to use brew, but I don't know what dependencies to install. --> +yeah thats about it +</details> + +<details> + +<summary>Linux</summary> + +With Unix systems (macOS not tested), you will have to download a couple of dependencies if building locally: ```bash # ubuntu @@ -41,6 +53,21 @@ sudo pacman -Syu base-devel systemd pkgconf openssl clang cmake meson assimp jdk ``` +</details> + +<details> + +<summary>macOS</summary> + +If you have a macOS system, please create a PR and add your own implementation. I am unfortunately broke +and do not own any sort of macOS system. + +</details> + +To build, ensure build requirements, clone the repository, then build it. It will build in debug mode, and use a lot +of packages, so if your CPU is not fast enough for building you should brew a cup of coffee during the build time or +scroll through Instagram Reels. (you could get a nice doomscroll in.) + Then run this to build the project ```bash @@ -17,7 +17,6 @@ dropbear-macro = { path = "../dropbear-macro" } anyhow.workspace = true app_dirs2.workspace = true bytemuck.workspace = true -bincode.workspace = true chrono.workspace = true colored.workspace = true egui-wgpu.workspace = true @@ -43,6 +42,7 @@ rustc_version_runtime.workspace = true ron.workspace = true dashmap.workspace = true typetag.workspace = true +postcard.workspace = true [target.'cfg(not(target_os = "android"))'.dependencies] rfd.workspace = true @@ -12,6 +12,7 @@ use dropbear_traits::SerializableComponent; use glam::{DMat4, DQuat, DVec3}; use std::fmt::{Display, Formatter}; use std::sync::Arc; +use hecs::Entity; use wgpu::{BindGroup, BindGroupLayout, Buffer, BufferAddress, CompareFunction, DepthBiasState, RenderPipeline, StencilState, VertexBufferLayout, FilterMode}; pub const MAX_LIGHTS: usize = 8; @@ -678,7 +679,7 @@ impl LightManager { let mut shadow_map_index = 0; - for (_, (light_component, s_trans, e_trans, light)) in world + for (light_component, s_trans, e_trans, light) in world .query::<(&LightComponent, Option<&Transform>, Option<&EntityTransform>, &mut Light)>() .iter() { @@ -86,7 +86,7 @@ pub fn relative_path_from_euca<'a>(uri: &'a str) -> anyhow::Result<&'a str> { /// assert_eq!(resource_ref.as_path().unwrap(), "models/cube.obj"); /// ``` #[derive( - Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, bincode::Decode, bincode::Encode, + Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize )] pub enum ResourceReferenceType { /// The default type; Specifies there being no resource reference type. @@ -116,7 +116,7 @@ pub enum ResourceReferenceType { } #[derive( - Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, bincode::Decode, bincode::Encode, + Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize )] pub enum TextureWrapMode { Repeat, @@ -95,8 +95,7 @@ impl<T: SerializableComponent + hecs::Component + Clone + 'static> ComponentConv world: &World, entity: Entity, ) -> Option<Box<dyn SerializableComponent>> { - if let Ok(mut q) = world.query_one::<&T>(entity) - && let Some(ty) = q.get() + if let Ok(ty) = world.query_one::<&T>(entity).get() { return Some(ty.clone_boxed()); } @@ -327,7 +327,7 @@ impl ComponentRegistry { component_id: u64, ) -> Vec<(Entity, Box<dyn SerializableComponent>)> { let mut matches = Vec::new(); - for (entity, ()) in world.query::<()>().iter() { + for entity in world.query::<Entity>().iter() { if let Some(component) = self.extract_component_by_numeric_id(world, entity, component_id) { @@ -15,7 +15,7 @@ dropbear-macro = { path = "../dropbear-macro" } magna-carta = { path = "../magna-carta" } anyhow.workspace = true -bincode.workspace = true +postcard.workspace = true chrono.workspace = true dropbear-engine.workspace = true egui-toast.workspace = true @@ -33,7 +33,7 @@ pub mod jni { use crate::convert_ptr; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_asset_AssetHandleNative_isModelHandle( + pub extern "system" fn Java_com_dropbear_asset_AssetHandleNative_isModelHandle( _env: JNIEnv, _class: JClass, asset_registry_ptr: jlong, @@ -50,7 +50,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_asset_AssetHandleNative_isTextureHandle( + pub extern "system" fn Java_com_dropbear_asset_AssetHandleNative_isTextureHandle( _env: JNIEnv, _class: JClass, asset_registry_ptr: jlong, @@ -25,7 +25,7 @@ pub mod jni { use crate::scripting::native::DropbearNativeError; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_asset_TextureHandleNative_getTextureName( + pub extern "system" fn Java_com_dropbear_asset_TextureHandleNative_getTextureName( env: JNIEnv, _class: JClass, asset_registry_ptr: jlong, @@ -138,7 +138,7 @@ pub mod jni { use crate::types::Vector3; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_cameraExistsForEntity( + pub extern "system" fn Java_com_dropbear_components_CameraNative_cameraExistsForEntity( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -154,7 +154,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_getCameraEye( + pub extern "system" fn Java_com_dropbear_components_CameraNative_getCameraEye( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -175,7 +175,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_setCameraEye( + pub extern "system" fn Java_com_dropbear_components_CameraNative_setCameraEye( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -200,7 +200,7 @@ pub mod jni { // TARGET #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_getCameraTarget( + pub extern "system" fn Java_com_dropbear_components_CameraNative_getCameraTarget( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -221,7 +221,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_setCameraTarget( + pub extern "system" fn Java_com_dropbear_components_CameraNative_setCameraTarget( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -240,7 +240,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_getCameraUp( + pub extern "system" fn Java_com_dropbear_components_CameraNative_getCameraUp( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -261,7 +261,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_setCameraUp( + pub extern "system" fn Java_com_dropbear_components_CameraNative_setCameraUp( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -280,7 +280,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_getCameraAspect( + pub extern "system" fn Java_com_dropbear_components_CameraNative_getCameraAspect( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -296,7 +296,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_getCameraFovY( + pub extern "system" fn Java_com_dropbear_components_CameraNative_getCameraFovY( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -312,7 +312,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_setCameraFovY( + pub extern "system" fn Java_com_dropbear_components_CameraNative_setCameraFovY( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -327,7 +327,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_getCameraZNear( + pub extern "system" fn Java_com_dropbear_components_CameraNative_getCameraZNear( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -343,7 +343,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_setCameraZNear( + pub extern "system" fn Java_com_dropbear_components_CameraNative_setCameraZNear( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -358,7 +358,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_getCameraZFar( + pub extern "system" fn Java_com_dropbear_components_CameraNative_getCameraZFar( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -374,7 +374,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_setCameraZFar( + pub extern "system" fn Java_com_dropbear_components_CameraNative_setCameraZFar( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -389,7 +389,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_getCameraYaw( + pub extern "system" fn Java_com_dropbear_components_CameraNative_getCameraYaw( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -405,7 +405,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_setCameraYaw( + pub extern "system" fn Java_com_dropbear_components_CameraNative_setCameraYaw( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -420,7 +420,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_getCameraPitch( + pub extern "system" fn Java_com_dropbear_components_CameraNative_getCameraPitch( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -436,7 +436,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_setCameraPitch( + pub extern "system" fn Java_com_dropbear_components_CameraNative_setCameraPitch( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -451,7 +451,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_getCameraSpeed( + pub extern "system" fn Java_com_dropbear_components_CameraNative_getCameraSpeed( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -467,7 +467,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_setCameraSpeed( + pub extern "system" fn Java_com_dropbear_components_CameraNative_setCameraSpeed( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -482,7 +482,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_getCameraSensitivity( + pub extern "system" fn Java_com_dropbear_components_CameraNative_getCameraSensitivity( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -498,7 +498,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CameraNative_setCameraSensitivity( + pub extern "system" fn Java_com_dropbear_components_CameraNative_setCameraSensitivity( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -5,12 +5,12 @@ pub mod shared { use crate::states::Label; use dropbear_engine::asset::AssetRegistry; use dropbear_engine::utils::ResourceReference; - use hecs::World; + use hecs::{Entity, World}; use std::ffi::CStr; use std::os::raw::c_char; pub fn get_entity(world: &World, label: &str) -> DropbearNativeResult<u64> { - for (id, entity_label) in world.query::<&Label>().iter() { + for (id, entity_label) in world.query::<(Entity, &Label)>().iter() { if entity_label.as_str() == label { return Ok(id.to_bits().get()); } @@ -52,7 +52,7 @@ pub mod jni { use crate::return_boxed; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_DropbearEngineNative_getEntity( + pub extern "system" fn Java_com_dropbear_DropbearEngineNative_getEntity( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -74,7 +74,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_DropbearEngineNative_getAsset( + pub extern "system" fn Java_com_dropbear_DropbearEngineNative_getAsset( mut env: JNIEnv, _class: JClass, asset_handle: jlong, @@ -96,7 +96,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_DropbearEngineNative_quit( + pub extern "system" fn Java_com_dropbear_DropbearEngineNative_quit( mut env: JNIEnv, _class: JClass, command_buffer_ptr: jlong, @@ -9,7 +9,7 @@ pub mod jni { use jni::JNIEnv; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_LabelNative_labelExistsForEntity( + pub extern "system" fn Java_com_dropbear_components_LabelNative_labelExistsForEntity( _env: JNIEnv, _: JClass, world_ptr: jlong, @@ -22,7 +22,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_EntityRefNative_getEntityLabel( + pub extern "system" fn Java_com_dropbear_EntityRefNative_getEntityLabel( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -46,7 +46,7 @@ pub mod jni { string.into_raw() } - pub fn Java_com_dropbear_EntityRefNative_getChildren( + pub extern "system" fn Java_com_dropbear_EntityRefNative_getChildren( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -55,8 +55,7 @@ pub mod jni { let world = crate::convert_ptr!(world_ptr => World); let entity = crate::convert_jlong_to_entity!(entity_id); - if let Ok(mut q) = world.query_one::<&Children>(entity) - && let Some(children) = q.get() + if let Ok(children) = world.query_one::<&Children>(entity).get() { let entity_bytes = children.children().iter().map(|c| c.to_bits().get() as i64).collect::<Vec<_>>(); @@ -77,7 +76,7 @@ pub mod jni { } } - pub fn Java_com_dropbear_EntityRefNative_getChildByLabel( + pub extern "system" fn Java_com_dropbear_EntityRefNative_getChildByLabel( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -88,8 +87,7 @@ pub mod jni { let entity = crate::convert_jlong_to_entity!(entity_id); let target = convert_jstring!(env, label); - if let Ok(mut q) = world.query_one::<&Children>(entity) - && let Some(children) = q.get() + if let Ok(children) = world.query_one::<&Children>(entity).get() { for child in children.children() { if let Ok(label) = world.get::<&Label>(entity) { @@ -111,7 +109,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_EntityRefNative_getParent( + pub extern "system" fn Java_com_dropbear_EntityRefNative_getParent( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -119,15 +117,11 @@ pub mod jni { ) -> jobject { let world = convert_ptr!(world_ptr => World); let entity = convert_jlong_to_entity!(entity_id); - - if let Ok(mut q) = world.query_one::<&Parent>(entity) { - if let Some(parent) = q.get() { - crate::return_boxed!(&mut env, Some(JValue::Long(parent.parent().to_bits().get() as jlong)), "(J)Ljava/lang/Long", "java/lang/Long") - } else { - std::ptr::null_mut() - } + + if let Ok(parent) = world.query_one::<&Parent>(entity).get() { + crate::return_boxed!(&mut env, Some(JValue::Long(parent.parent().to_bits().get() as jlong)), "(J)Ljava/lang/Long", "java/lang/Long") } else { - crate::ffi_error_return!("No entity exists") + std::ptr::null_mut() } } } @@ -205,7 +205,7 @@ impl SceneHierarchy { pub fn from_world(world: &hecs::World) -> Self { let mut hierarchy = Self::new(); - for (_entity, (label, parent)) in world.query::<(&Label, &Parent)>().iter() { + for (label, parent) in world.query::<(&Label, &Parent)>().iter() { if let Ok(parent_label) = world.get::<&Label>(parent.parent()) { hierarchy.set_parent(label.clone(), Label::new(parent_label.as_str())); } @@ -201,7 +201,7 @@ pub mod jni { use crate::scripting::jni::utils::ToJObject; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_InputStateNative_printInputState( + pub extern "system" fn Java_com_dropbear_input_InputStateNative_printInputState( _env: JNIEnv, _class: JClass, input_ptr: jlong, @@ -211,7 +211,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_InputStateNative_isKeyPressed( + pub extern "system" fn Java_com_dropbear_input_InputStateNative_isKeyPressed( _env: JNIEnv, _class: JClass, input_ptr: jlong, @@ -222,7 +222,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_InputStateNative_getMousePosition( + pub extern "system" fn Java_com_dropbear_input_InputStateNative_getMousePosition( mut env: JNIEnv, _class: JClass, input_ptr: jlong, @@ -236,7 +236,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_InputStateNative_isMouseButtonPressed( + pub extern "system" fn Java_com_dropbear_input_InputStateNative_isMouseButtonPressed( mut env: JNIEnv, _class: JClass, input_ptr: jlong, @@ -258,7 +258,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_InputStateNative_getMouseDelta( + pub extern "system" fn Java_com_dropbear_input_InputStateNative_getMouseDelta( mut env: JNIEnv, _class: JClass, input_ptr: jlong, @@ -272,7 +272,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_InputStateNative_isCursorLocked( + pub extern "system" fn Java_com_dropbear_input_InputStateNative_isCursorLocked( _env: JNIEnv, _class: JClass, input_ptr: jlong, @@ -282,7 +282,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_InputStateNative_setCursorLocked( + pub extern "system" fn Java_com_dropbear_input_InputStateNative_setCursorLocked( mut env: JNIEnv, _class: JClass, cmd_ptr: jlong, @@ -298,7 +298,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_InputStateNative_getLastMousePos( + pub extern "system" fn Java_com_dropbear_input_InputStateNative_getLastMousePos( mut env: JNIEnv, _class: JClass, input_ptr: jlong, @@ -312,7 +312,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_InputStateNative_isCursorHidden( + pub extern "system" fn Java_com_dropbear_input_InputStateNative_isCursorHidden( _env: JNIEnv, _class: JClass, input_ptr: jlong, @@ -322,7 +322,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_InputStateNative_setCursorHidden( + pub extern "system" fn Java_com_dropbear_input_InputStateNative_setCursorHidden( mut env: JNIEnv, _class: JClass, cmd_ptr: jlong, @@ -338,7 +338,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_InputStateNative_getConnectedGamepads( + pub extern "system" fn Java_com_dropbear_input_InputStateNative_getConnectedGamepads( env: JNIEnv, _class: JClass, input_ptr: jlong, @@ -132,7 +132,7 @@ pub mod jni { use crate::scripting::jni::utils::ToJObject; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_GamepadNative_isGamepadButtonPressed( + pub extern "system" fn Java_com_dropbear_input_GamepadNative_isGamepadButtonPressed( _env: JNIEnv, _class: JClass, input_ptr: jlong, @@ -148,7 +148,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_GamepadNative_getLeftStickPosition( + pub extern "system" fn Java_com_dropbear_input_GamepadNative_getLeftStickPosition( mut env: JNIEnv, _class: JClass, input_ptr: jlong, @@ -164,7 +164,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_input_GamepadNative_getRightStickPosition( + pub extern "system" fn Java_com_dropbear_input_GamepadNative_getRightStickPosition( mut env: JNIEnv, _class: JClass, input_ptr: jlong, @@ -259,7 +259,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_lightExistsForEntity( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_lightExistsForEntity( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -275,7 +275,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_getPosition( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_getPosition( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -296,7 +296,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_setPosition( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_setPosition( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -323,7 +323,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_getDirection( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_getDirection( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -347,7 +347,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_setDirection( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_setDirection( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -383,7 +383,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_getColour( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_getColour( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -405,7 +405,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_setColour( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_setColour( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -435,7 +435,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_getLightType( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_getLightType( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -453,7 +453,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_setLightType( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_setLightType( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -480,7 +480,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_getIntensity( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_getIntensity( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -498,7 +498,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_setIntensity( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_setIntensity( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -517,7 +517,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_getAttenuation( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_getAttenuation( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -544,7 +544,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_setAttenuation( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_setAttenuation( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -577,7 +577,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_getEnabled( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_getEnabled( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -595,7 +595,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_setEnabled( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_setEnabled( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -614,7 +614,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_getCutoffAngle( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_getCutoffAngle( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -632,7 +632,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_setCutoffAngle( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_setCutoffAngle( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -651,7 +651,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_getOuterCutoffAngle( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_getOuterCutoffAngle( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -669,7 +669,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_setOuterCutoffAngle( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_setOuterCutoffAngle( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -688,7 +688,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_getCastsShadows( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_getCastsShadows( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -706,7 +706,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_setCastsShadows( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_setCastsShadows( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -725,7 +725,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_getDepth( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_getDepth( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -751,7 +751,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_lighting_LightNative_setDepth( + pub extern "system" fn Java_com_dropbear_lighting_LightNative_setDepth( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -41,7 +41,7 @@ pub mod jni { use std::sync::Arc; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_MeshRendererNative_meshRendererExistsForEntity( + pub extern "system" fn Java_com_dropbear_components_MeshRendererNative_meshRendererExistsForEntity( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -53,7 +53,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_MeshRendererNative_getModel( + pub extern "system" fn Java_com_dropbear_components_MeshRendererNative_getModel( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -71,7 +71,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_MeshRendererNative_setModel( + pub extern "system" fn Java_com_dropbear_components_MeshRendererNative_setModel( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -96,7 +96,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_MeshRendererNative_getAllTextureIds( + pub extern "system" fn Java_com_dropbear_components_MeshRendererNative_getAllTextureIds( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -130,7 +130,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_MeshRendererNative_getTexture( + pub extern "system" fn Java_com_dropbear_components_MeshRendererNative_getTexture( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -154,7 +154,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_MeshRendererNative_setTextureOverride( + pub extern "system" fn Java_com_dropbear_components_MeshRendererNative_setTextureOverride( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -73,7 +73,7 @@ impl PhysicsState { pub fn step(&mut self, entity_label_map: HashMap<Entity, Label>, pipeline: &mut PhysicsPipeline, physics_hooks: &dyn PhysicsHooks, event_handler: &dyn EventHandler) { self.entity_label_map = entity_label_map; pipeline.step( - &vector![self.gravity[0], self.gravity[1], self.gravity[2]], // a panic is deserved for those who don't specify a 3rd type in a vector array + Vector::new(self.gravity[0], self.gravity[1], self.gravity[2]), // a panic is deserved for those who don't specify a 3rd type in a vector array &self.integration_parameters, &mut self.islands, &mut self.broad_phase, @@ -100,16 +100,16 @@ impl PhysicsState { let rot = transform.rotation.as_quat().to_array(); let body = RigidBodyBuilder::new(mode) - .translation(vector![pos[0], pos[1], pos[2]]) + .translation(Vector::from_array(pos)) .rotation(UnitQuaternion::from_quaternion(Quaternion::new( - rot[3] as f32, rot[0] as f32, rot[1] as f32, rot[2] as f32 - )).scaled_axis()) + rot[3], rot[0], rot[1], rot[2] + )).scaled_axis().into()) .gravity_scale(rigid_body.gravity_scale) .sleeping(rigid_body.sleeping) .can_sleep(rigid_body.can_sleep) .ccd_enabled(rigid_body.ccd_enabled) - .linvel(Vector3::from_column_slice(&rigid_body.linvel)) - .angvel(Vector3::from_column_slice(&rigid_body.angvel)) + .linvel(Vector::from_array(rigid_body.linvel)) + .angvel(Vector::from_array(rigid_body.angvel)) .linear_damping(rigid_body.linear_damping) .angular_damping(rigid_body.angular_damping) .enabled_translations(!rigid_body.lock_translation.x, !rigid_body.lock_translation.y, !rigid_body.lock_translation.z) @@ -161,14 +161,14 @@ impl PhysicsState { } builder = builder.active_events(active_events); - builder = builder.translation(Vector3::from_column_slice(&collider_component.translation)); + builder = builder.translation(Vector::from_array(collider_component.translation)); let rotation = UnitQuaternion::from_euler_angles( collider_component.rotation[0], collider_component.rotation[1], collider_component.rotation[2] ); - builder = builder.rotation(rotation.scaled_axis()); + builder = builder.rotation(rotation.scaled_axis().into()); let handle = if let Some(&rigid_body_handle) = self.bodies_entity_map.get(&collider_component.entity) { self.colliders.insert_with_parent( @@ -293,7 +293,7 @@ pub mod shared { for (_, h1) in handles1 { for (_, h2) in handles2 { if let Some(pair) = physics.narrow_phase.contact_pair(*h1, *h2) { - if pair.has_any_active_contact { + if pair.has_any_active_contact() { return true; } } @@ -320,7 +320,7 @@ pub mod jni { use rapier3d::prelude::{point, vector, Ray}; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_PhysicsNative_getGravity( + pub extern "system" fn Java_com_dropbear_physics_PhysicsNative_getGravity( mut env: JNIEnv, _: JClass, physics_handle: jlong, @@ -338,7 +338,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_PhysicsNative_setGravity( + pub extern "system" fn Java_com_dropbear_physics_PhysicsNative_setGravity( mut env: JNIEnv, _: JClass, physics_handle: jlong, @@ -357,7 +357,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_PhysicsNative_raycast( + pub extern "system" fn Java_com_dropbear_physics_PhysicsNative_raycast( mut env: JNIEnv, _: JClass, physics_handle: jlong, @@ -387,8 +387,8 @@ pub mod jni { }; let ray = Ray::new( - point![origin.x as f32, origin.y as f32, origin.z as f32], - vector![dir.x as f32, dir.y as f32, dir.z as f32], + point![origin.x as f32, origin.y as f32, origin.z as f32].into(), + vector![dir.x as f32, dir.y as f32, dir.z as f32].into(), ); if let Some((hit, distance)) = qp.cast_ray(&ray, time_of_impact as f32, solid != 0) { @@ -452,7 +452,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_PhysicsNative_isOverlapping( + pub extern "system" fn Java_com_dropbear_physics_PhysicsNative_isOverlapping( mut env: JNIEnv, _: JClass, physics_handle: jlong, @@ -480,7 +480,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_PhysicsNative_isTriggering( + pub extern "system" fn Java_com_dropbear_physics_PhysicsNative_isTriggering( mut env: JNIEnv, _: JClass, physics_handle: jlong, @@ -508,7 +508,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_PhysicsNative_isTouching( + pub extern "system" fn Java_com_dropbear_physics_PhysicsNative_isTouching( _env: JNIEnv, _: JClass, physics_handle: jlong, @@ -31,6 +31,7 @@ use rapier3d::na::Vector3; use rapier3d::prelude::ColliderBuilder; use serde::{Deserialize, Serialize}; use std::sync::Arc; +use rapier3d::math::Vector; #[derive(Debug, Default, Serialize, Deserialize, Clone, SerializableComponent)] pub struct ColliderGroup { @@ -425,8 +426,8 @@ impl Collider { .friction(self.friction) .restitution(self.restitution) .sensor(self.is_sensor) - .translation(Vector3::from_column_slice(&self.translation)) - .rotation(Vector3::from_column_slice(&self.rotation)) + .translation(Vector::from_array(self.translation)) + .rotation(Vector::from_array(self.rotation)) .build() } @@ -644,10 +645,10 @@ pub mod jni { use jni::sys::{jboolean, jdouble, jlong, jobject}; use jni::JNIEnv; use rapier3d::na::{UnitQuaternion, Vector3}; - use rapier3d::prelude::{ColliderHandle, SharedShape, TypedShape}; + use rapier3d::prelude::{ColliderHandle, Rotation, SharedShape, TypedShape, Vector}; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_getColliderShape( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_getColliderShape( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -712,7 +713,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_setColliderShape( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_setColliderShape( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -760,7 +761,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_getColliderDensity( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_getColliderDensity( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -777,7 +778,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_setColliderDensity( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_setColliderDensity( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -793,7 +794,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_getColliderFriction( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_getColliderFriction( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -807,7 +808,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_setColliderFriction( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_setColliderFriction( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -823,7 +824,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_getColliderRestitution( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_getColliderRestitution( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -837,7 +838,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_setColliderRestitution( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_setColliderRestitution( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -853,7 +854,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_getColliderMass( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_getColliderMass( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -867,7 +868,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_setColliderMass( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_setColliderMass( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -883,7 +884,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_getColliderIsSensor( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_getColliderIsSensor( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -897,7 +898,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_setColliderIsSensor( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_setColliderIsSensor( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -913,7 +914,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_getColliderTranslation( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_getColliderTranslation( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -926,7 +927,7 @@ pub mod jni { }; if let Some(col) = get_collider(&physics, &ffi) { - let t: &Vector3<f32> = col.translation(); + let t: Vector = col.translation(); let vec = crate::types::Vector3::new(t.x as f64, t.y as f64, t.z as f64); match vec.to_jobject(&mut env) { Ok(o) => o.into_raw(), @@ -938,7 +939,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_setColliderTranslation( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_setColliderTranslation( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -949,7 +950,7 @@ pub mod jni { if let Ok(ffi) = ColliderFFI::from_jobject(&mut env, &collider_obj) { if let Ok(vec) = crate::types::Vector3::from_jobject(&mut env, &vec_obj) { if let Some(col) = get_collider_mut(physics, &ffi) { - let t = Vector3::new(vec.x as f32, vec.y as f32, vec.z as f32); + let t = Vector::new(vec.x as f32, vec.y as f32, vec.z as f32); col.set_translation(t); } } @@ -957,7 +958,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_getColliderRotation( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_getColliderRotation( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -970,8 +971,8 @@ pub mod jni { }; if let Some(col) = get_collider(&physics, &ffi) { - let r: &UnitQuaternion<f32> = col.rotation(); - let q = DQuat::from_xyzw(r.i as f64, r.j as f64, r.k as f64, r.w as f64); + let r: Rotation = col.rotation(); + let q = DQuat::from_xyzw(r.x as f64, r.y as f64, r.z as f64, r.w as f64); let euler = q.to_euler(glam::EulerRot::XYZ); let vec = crate::types::Vector3::new(euler.0, euler.1, euler.2); @@ -985,7 +986,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderNative_setColliderRotation( + pub extern "system" fn Java_com_dropbear_physics_ColliderNative_setColliderRotation( mut env: JNIEnv, _class: JClass, physics_ptr: jlong, @@ -997,9 +998,7 @@ pub mod jni { if let Ok(vec) = crate::types::Vector3::from_jobject(&mut env, &vec_obj) { if let Some(col) = get_collider_mut(physics, &ffi) { let q = DQuat::from_euler(glam::EulerRot::XYZ, vec.x, vec.y, vec.z); - let r = rapier3d::na::UnitQuaternion::new_normalize( - rapier3d::na::Quaternion::new(q.w as f32, q.x as f32, q.y as f32, q.z as f32) - ); + let r = Rotation::from_array([q.w as f32, q.x as f32, q.y as f32, q.z as f32]); col.set_rotation(r); } } @@ -1007,8 +1006,9 @@ pub mod jni { } } -#[dropbear_macro::impl_c_api] +// #[dropbear_macro::impl_c_api] pub mod native { + use crate::physics::Rotation; use crate::convert_ptr; use crate::physics::collider::shared::{get_collider, get_collider_mut}; use crate::physics::PhysicsState; @@ -1019,8 +1019,7 @@ pub mod native { use crate::scripting::result::DropbearNativeResult; use crate::types::{ColliderFFI, ColliderShapeFFI, ColliderShapeType}; use glam::DQuat; - use rapier3d::na::{Quaternion, UnitQuaternion}; - use rapier3d::prelude::{SharedShape, TypedShape}; + use rapier3d::prelude::{SharedShape, TypedShape, Vector}; pub fn dropbear_get_collider_shape( physics_ptr: PhysicsStatePtr, @@ -1242,7 +1241,7 @@ pub mod native { ) -> DropbearNativeResult<()> { let physics = convert_ptr!(mut physics_ptr => PhysicsState); if let Some(col) = get_collider_mut(physics, &ffi) { - let t = rapier3d::na::Vector3::new(translation.x as f32, translation.y as f32, translation.z as f32); + let t = Vector::new(translation.x as f32, translation.y as f32, translation.z as f32); col.set_translation(t); DropbearNativeResult::Ok(()) } else { @@ -1257,7 +1256,7 @@ pub mod native { let physics = convert_ptr!(physics_ptr => PhysicsState); if let Some(col) = get_collider(physics, &ffi) { let r = col.rotation(); - let q = DQuat::from_xyzw(r.i as f64, r.j as f64, r.k as f64, r.w as f64); + let q: DQuat = DQuat::from_xyzw(r.x as f64, r.y as f64, r.z as f64, r.w as f64); let (x, y, z) = q.to_euler(glam::EulerRot::XYZ); DropbearNativeResult::Ok(Vector3 { x, y, z }) } else { @@ -1273,9 +1272,7 @@ pub mod native { let physics = convert_ptr!(mut physics_ptr => PhysicsState); if let Some(col) = get_collider_mut(physics, &ffi) { let q = DQuat::from_euler(glam::EulerRot::XYZ, rotation.x, rotation.y, rotation.z); - let r = UnitQuaternion::new_normalize( - Quaternion::new(q.w as f32, q.x as f32, q.y as f32, q.z as f32) - ); + let r = Rotation::from(q.as_quat()); col.set_rotation(r); DropbearNativeResult::Ok(()) } else { @@ -72,7 +72,7 @@ pub mod jni { use jni::JNIEnv; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderGroupNative_colliderGroupExistsForEntity( + pub extern "system" fn Java_com_dropbear_physics_ColliderGroupNative_colliderGroupExistsForEntity( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -89,7 +89,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_ColliderGroupNative_getColliderGroupColliders( + pub extern "system" fn Java_com_dropbear_physics_ColliderGroupNative_getColliderGroupColliders( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -53,7 +53,7 @@ pub mod jni { use crate::scripting::jni::utils::ToJObject; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_KinematicCharacterControllerNative_existsForEntity( + pub extern "system" fn Java_com_dropbear_physics_KinematicCharacterControllerNative_existsForEntity( _env: JNIEnv, _: JClass, world_handle: jlong, @@ -67,7 +67,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_KinematicCharacterControllerNative_moveCharacter( + pub extern "system" fn Java_com_dropbear_physics_KinematicCharacterControllerNative_moveCharacter( mut env: JNIEnv, _: JClass, world_handle: jlong, @@ -88,8 +88,7 @@ pub mod jni { } }; - if let Ok(mut q) = world.query_one::<(&Label, &KCC)>(entity) - && let Some((label, kcc)) = q.get() + if let Ok((label, kcc)) = world.query_one::<(&Label, &KCC)>(entity).get() { let Some(rigid_body_handle) = physics_state.bodies_entity_map.get(label) else { return; @@ -156,7 +155,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_KinematicCharacterControllerNative_getHitNative( + pub extern "system" fn Java_com_dropbear_physics_KinematicCharacterControllerNative_getHitNative( mut env: JNIEnv, _: JClass, world_handle: jlong, @@ -30,7 +30,7 @@ fn get_collision_from_world(world: &World, entity: Entity, collision_handle: Ind fn collider_ffi_from_handle(world: &World, handle: rapier3d::prelude::ColliderHandle) -> Option<ColliderFFI> { let (idx, generation) = handle.into_raw_parts(); - for (entity, group) in world.query::<&ColliderGroup>().iter() { + for (entity, group) in world.query::<(Entity, &ColliderGroup)>().iter() { if group.colliders.iter().any(|c| c.id == idx) { return Some(ColliderFFI { index: IndexNative { index: idx, generation }, @@ -90,9 +90,9 @@ pub mod shared { let collision = super::get_collision_from_world(world, entity, collision_handle)?; let iso = collision.character_pos; - let t = iso.translation.vector; + let t = iso.translation; let rot = iso.rotation; - let q: Quaternion<f32> = rot.into_inner(); + let q: Quaternion<f32> = Quaternion::from(rot); Ok(DbTransform { position: DVec3::new(t.x as f64, t.y as f64, t.z as f64), @@ -162,7 +162,7 @@ pub mod jni { use jni::objects::JObject; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_CharacterCollisionNative_getCollider( + pub extern "system" fn Java_com_dropbear_physics_CharacterCollisionNative_getCollider( mut env: JNIEnv, _: JClass, world_handle: jlong, @@ -193,7 +193,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_CharacterCollisionNative_getCharacterPosition( + pub extern "system" fn Java_com_dropbear_physics_CharacterCollisionNative_getCharacterPosition( mut env: JNIEnv, _: JClass, world_handle: jlong, @@ -224,7 +224,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_CharacterCollisionNative_getTranslationApplied( + pub extern "system" fn Java_com_dropbear_physics_CharacterCollisionNative_getTranslationApplied( mut env: JNIEnv, _: JClass, world_handle: jlong, @@ -255,7 +255,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_CharacterCollisionNative_getTranslationRemaining( + pub extern "system" fn Java_com_dropbear_physics_CharacterCollisionNative_getTranslationRemaining( mut env: JNIEnv, _: JClass, world_handle: jlong, @@ -286,7 +286,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_CharacterCollisionNative_getTimeOfImpact( + pub extern "system" fn Java_com_dropbear_physics_CharacterCollisionNative_getTimeOfImpact( mut env: JNIEnv, _: JClass, world_handle: jlong, @@ -311,7 +311,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_CharacterCollisionNative_getWitness1( + pub extern "system" fn Java_com_dropbear_physics_CharacterCollisionNative_getWitness1( mut env: JNIEnv, _: JClass, world_handle: jlong, @@ -342,7 +342,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_CharacterCollisionNative_getWitness2( + pub extern "system" fn Java_com_dropbear_physics_CharacterCollisionNative_getWitness2( mut env: JNIEnv, _: JClass, world_handle: jlong, @@ -373,7 +373,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_CharacterCollisionNative_getNormal1( + pub extern "system" fn Java_com_dropbear_physics_CharacterCollisionNative_getNormal1( mut env: JNIEnv, _: JClass, world_handle: jlong, @@ -404,7 +404,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_CharacterCollisionNative_getNormal2( + pub extern "system" fn Java_com_dropbear_physics_CharacterCollisionNative_getNormal2( mut env: JNIEnv, _: JClass, world_handle: jlong, @@ -435,7 +435,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_CharacterCollisionNative_getStatus( + pub extern "system" fn Java_com_dropbear_physics_CharacterCollisionNative_getStatus( mut env: JNIEnv, _: JClass, world_handle: jlong, @@ -206,7 +206,7 @@ pub mod shared { use crate::types::{IndexNative, RigidBodyContext, Vector3}; use hecs::{Entity, World}; use rapier3d::dynamics::{RigidBodyHandle, RigidBodyType}; - use rapier3d::prelude::vector; + use rapier3d::prelude::{vector, Vector}; use rapier3d::prelude::{nalgebra, ColliderHandle, LockedAxes}; pub fn rigid_body_exists_for_entity( @@ -214,8 +214,7 @@ pub mod shared { physics: &PhysicsState, entity: Entity ) -> Option<IndexNative> { - if let Ok(mut q) = world.query_one::<(&Label, &RigidBody)>(entity) - && let Some((label, _)) = q.get() + if let Ok((label, _)) = world.query_one::<(&Label, &RigidBody)>(entity).get() { if let Some(handle) = physics.bodies_entity_map.get(label) { Some(IndexNative::from(handle.0)) @@ -250,7 +249,7 @@ pub mod shared { let entity = Entity::from_bits(rb_context.entity_id).ok_or(DropbearNativeError::InvalidEntity)?; - if let Ok(mut q) = world.query_one::<&mut RigidBody>(entity) && let Some(rb) = q.get() { + if let Ok(rb) = world.query_one::<&mut RigidBody>(entity).get() { let rb_mode = RigidBodyMode::from(mode); rb.mode = rb_mode; } @@ -277,7 +276,7 @@ pub mod shared { let entity = Entity::from_bits(rb_context.entity_id).ok_or(DropbearNativeError::InvalidEntity)?; - if let Ok(mut q) = world.query_one::<&mut RigidBody>(entity) && let Some(rb) = q.get() { + if let Ok(rb) = world.query_one::<&mut RigidBody>(entity).get() { rb.gravity_scale = new_scale as f32; } @@ -303,7 +302,7 @@ pub mod shared { let entity = Entity::from_bits(rb_context.entity_id).ok_or(DropbearNativeError::InvalidEntity)?; - if let Ok(mut q) = world.query_one::<&mut RigidBody>(entity) && let Some(rb) = q.get() { + if let Ok(rb) = world.query_one::<&mut RigidBody>(entity).get() { rb.linear_damping = new as f32; } @@ -329,7 +328,7 @@ pub mod shared { let entity = Entity::from_bits(rb_context.entity_id).ok_or(DropbearNativeError::InvalidEntity)?; - if let Ok(mut q) = world.query_one::<&mut RigidBody>(entity) && let Some(rb) = q.get() { + if let Ok(rb) = world.query_one::<&mut RigidBody>(entity).get() { rb.angular_damping = new as f32; } @@ -359,7 +358,7 @@ pub mod shared { let entity = Entity::from_bits(rb_context.entity_id).ok_or(DropbearNativeError::InvalidEntity)?; - if let Ok(mut q) = world.query_one::<&mut RigidBody>(entity) && let Some(rb) = q.get() { + if let Ok(rb) = world.query_one::<&mut RigidBody>(entity).get() { rb.sleeping = new; } @@ -385,7 +384,7 @@ pub mod shared { let entity = Entity::from_bits(rb_context.entity_id).ok_or(DropbearNativeError::InvalidEntity)?; - if let Ok(mut q) = world.query_one::<&mut RigidBody>(entity) && let Some(rb) = q.get() { + if let Ok(rb) = world.query_one::<&mut RigidBody>(entity).get() { rb.ccd_enabled = new; } @@ -408,11 +407,11 @@ pub mod shared { pub fn set_rigidbody_linvel(physics: &mut PhysicsState, world: &World, rb_context: RigidBodyContext, new: Vector3) -> DropbearNativeResult<()> { let handle = RigidBodyHandle::from_raw_parts(rb_context.index.index, rb_context.index.generation); if let Some(rb) = physics.bodies.get_mut(handle) { - rb.set_linvel(vector![new.x as f32, new.y as f32, new.z as f32], true); + rb.set_linvel(Vector::new(new.x as f32, new.y as f32, new.z as f32), true); let entity = Entity::from_bits(rb_context.entity_id).ok_or(DropbearNativeError::InvalidEntity)?; - if let Ok(mut q) = world.query_one::<&mut RigidBody>(entity) && let Some(rb) = q.get() { + if let Ok(rb) = world.query_one::<&mut RigidBody>(entity).get() { rb.linvel = [new.x as f32, new.y as f32, new.z as f32]; } @@ -435,11 +434,11 @@ pub mod shared { pub fn set_rigidbody_angvel(physics: &mut PhysicsState, world: &World, rb_context: RigidBodyContext, new: Vector3) -> DropbearNativeResult<()> { let handle = RigidBodyHandle::from_raw_parts(rb_context.index.index, rb_context.index.generation); if let Some(rb) = physics.bodies.get_mut(handle) { - rb.set_angvel(vector![new.x as f32, new.y as f32, new.z as f32], true); + rb.set_angvel(Vector::new(new.x as f32, new.y as f32, new.z as f32), true); let entity = Entity::from_bits(rb_context.entity_id).ok_or(DropbearNativeError::InvalidEntity)?; - if let Ok(mut q) = world.query_one::<&mut RigidBody>(entity) && let Some(rb) = q.get() { + if let Ok(rb) = world.query_one::<&mut RigidBody>(entity).get() { rb.angvel = [new.x as f32, new.y as f32, new.z as f32]; } @@ -487,7 +486,7 @@ pub mod shared { let entity = Entity::from_bits(rb_context.entity_id).ok_or(DropbearNativeError::InvalidEntity)?; - if let Ok(mut q) = world.query_one::<&mut RigidBody>(entity) && let Some(rb) = q.get() { + if let Ok(rb) = world.query_one::<&mut RigidBody>(entity).get() { rb.lock_translation = new; } @@ -535,7 +534,7 @@ pub mod shared { let entity = Entity::from_bits(rb_context.entity_id).ok_or(DropbearNativeError::InvalidEntity)?; - if let Ok(mut q) = world.query_one::<&mut RigidBody>(entity) && let Some(rb) = q.get() { + if let Ok(rb) = world.query_one::<&mut RigidBody>(entity).get() { rb.lock_translation = new; } @@ -558,7 +557,7 @@ pub mod shared { pub fn apply_impulse(physics: &mut PhysicsState, _world: &World, rb_context: RigidBodyContext, new: Vector3) -> DropbearNativeResult<()> { let handle = RigidBodyHandle::from_raw_parts(rb_context.index.index, rb_context.index.generation); if let Some(rb) = physics.bodies.get_mut(handle) { - rb.apply_impulse(vector![new.x as f32, new.y as f32, new.z as f32], true); + rb.apply_impulse(Vector::new(new.x as f32, new.y as f32, new.z as f32), true); Ok(()) } else { @@ -569,7 +568,7 @@ pub mod shared { pub fn apply_torque_impulse(physics: &mut PhysicsState, _world: &World, rb_context: RigidBodyContext, new: Vector3) -> DropbearNativeResult<()> { let handle = RigidBodyHandle::from_raw_parts(rb_context.index.index, rb_context.index.generation); if let Some(rb) = physics.bodies.get_mut(handle) { - rb.apply_torque_impulse(vector![new.x as f32, new.y as f32, new.z as f32], true); + rb.apply_torque_impulse(Vector::new(new.x as f32, new.y as f32, new.z as f32), true); Ok(()) } else { @@ -592,7 +591,7 @@ pub mod jni { use rapier3d::dynamics::RigidBodyType; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_rigidBodyExistsForEntity( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_rigidBodyExistsForEntity( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -619,7 +618,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyMode( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyMode( mut env: JNIEnv, _: JClass, _world_ptr: jlong, @@ -650,7 +649,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyMode( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyMode( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -674,7 +673,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyGravityScale( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyGravityScale( mut env: JNIEnv, _: JClass, _world_ptr: jlong, @@ -699,7 +698,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyGravityScale( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyGravityScale( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -723,7 +722,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyLinearDamping( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyLinearDamping( mut env: JNIEnv, _: JClass, _world_ptr: jlong, @@ -748,7 +747,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyLinearDamping( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyLinearDamping( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -772,7 +771,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyAngularDamping( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyAngularDamping( mut env: JNIEnv, _: JClass, _world_ptr: jlong, @@ -797,7 +796,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyAngularDamping( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyAngularDamping( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -821,7 +820,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodySleep( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodySleep( mut env: JNIEnv, _: JClass, _world_ptr: jlong, @@ -846,7 +845,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodySleep( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodySleep( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -870,7 +869,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyCcdEnabled( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyCcdEnabled( mut env: JNIEnv, _: JClass, _world_ptr: jlong, @@ -895,7 +894,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyCcdEnabled( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyCcdEnabled( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -919,7 +918,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyLinearVelocity( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyLinearVelocity( mut env: JNIEnv, _: JClass, _world_ptr: jlong, @@ -953,7 +952,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyLinearVelocity( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyLinearVelocity( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -983,7 +982,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyAngularVelocity( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyAngularVelocity( mut env: JNIEnv, _: JClass, _world_ptr: jlong, @@ -1017,7 +1016,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyAngularVelocity( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyAngularVelocity( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -1047,7 +1046,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyLockTranslation( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyLockTranslation( mut env: JNIEnv, _: JClass, _world_ptr: jlong, @@ -1081,7 +1080,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyLockTranslation( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyLockTranslation( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -1111,7 +1110,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyLockRotation( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyLockRotation( mut env: JNIEnv, _: JClass, _world_ptr: jlong, @@ -1145,7 +1144,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyLockRotation( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_setRigidBodyLockRotation( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -1175,7 +1174,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyChildren( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_getRigidBodyChildren( mut env: JNIEnv, _: JClass, _world_ptr: jlong, @@ -1227,7 +1226,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_applyImpulse( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_applyImpulse( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -1254,7 +1253,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_physics_RigidBodyNative_applyTorqueImpulse( + pub extern "system" fn Java_com_dropbear_physics_RigidBodyNative_applyTorqueImpulse( mut env: JNIEnv, _: JClass, world_ptr: jlong, @@ -221,7 +221,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_customPropertiesExistsForEntity( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_customPropertiesExistsForEntity( _env: JNIEnv, _class: JClass, world_handle: jlong, @@ -238,7 +238,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_getStringProperty( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_getStringProperty( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -258,7 +258,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_getIntProperty( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_getIntProperty( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -279,7 +279,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_getLongProperty( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_getLongProperty( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -300,7 +300,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_getDoubleProperty( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_getDoubleProperty( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -321,7 +321,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_getFloatProperty( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_getFloatProperty( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -342,7 +342,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_getBoolProperty( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_getBoolProperty( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -363,7 +363,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_getVec3Property( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_getVec3Property( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -386,7 +386,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_setStringProperty( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_setStringProperty( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -405,7 +405,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_setIntProperty( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_setIntProperty( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -423,7 +423,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_setLongProperty( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_setLongProperty( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -441,7 +441,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_setFloatProperty( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_setFloatProperty( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -459,7 +459,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_setDoubleProperty( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_setDoubleProperty( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -477,7 +477,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_setBoolProperty( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_setBoolProperty( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -495,7 +495,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_CustomPropertiesNative_setVec3Property( + pub extern "system" fn Java_com_dropbear_components_CustomPropertiesNative_setVec3Property( mut env: JNIEnv, _class: JClass, world_handle: jlong, @@ -10,7 +10,7 @@ use semver::Version; /// This is different to [`SceneSettings`], which contains settings for ONLY /// that specific scene. This is for any configurations of the project during its runtime, /// such as initial scene and stuff like that. -#[derive(bincode::Decode, bincode::Encode, serde::Serialize, serde::Deserialize, Debug, Clone)] +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] pub struct RuntimeSettings { /// The first scene that shows up when redback-runtime is ran. /// @@ -37,7 +37,7 @@ impl Default for RuntimeSettings { } /// A struct that represents the authors and creators of the eucalyptus project. -#[derive(bincode::Decode, bincode::Encode, serde::Serialize, serde::Deserialize, Debug, Clone)] +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] pub struct Authoring { /// The team behind the game pub developer: String, @@ -55,38 +55,31 @@ impl Default for Authoring { /// /// Often stored as a single .eupak file, it contains all the scenes and the references of different /// resources. -#[derive(bincode::Decode, bincode::Encode, serde::Serialize, serde::Deserialize, Clone)] +#[derive(serde::Serialize, serde::Deserialize, Clone)] pub struct RuntimeProjectConfig { /// The name of the project - #[bincode(with_serde)] pub project_name: String, /// The initial/first scene that will show up. /// /// Access to other scenes are done with the game's scripting. - #[bincode(with_serde)] pub initial_scene: String, /// Authors and creators of the game - #[bincode(with_serde)] pub authors: Authoring, /// The version of dropbear engine and eucalyptus-editor. /// /// dropbear and eucalyptus all share the same semver version. - #[bincode(with_serde)] pub editor_version: Version, /// The version of the project. By default, it returns `0.1.0` if none has been specified. - #[bincode(with_serde)] pub project_version: Version, /// Any specific settings to do with the runtime. - #[bincode(with_serde)] pub runtime_settings: RuntimeSettings, /// All scenes that are available in the project. - #[bincode(with_serde)] pub scenes: Vec<SceneConfig>, } @@ -27,6 +27,7 @@ use std::fs; use std::path::{Path, PathBuf}; use std::sync::Arc; use crossbeam_channel::Sender; +use hecs::Entity; use crate::physics::collider::ColliderGroup; use crate::physics::kcc::KCC; use crate::physics::PhysicsState; @@ -51,8 +52,7 @@ impl SceneEntity { entity: hecs::Entity, registry: &ComponentRegistry, ) -> Option<Self> { - let label = if let Ok(mut q) = world.query_one::<&Label>(entity) - && let Some(label) = q.get() + let label = if let Ok(label) = world.query_one::<&Label>(entity).get() { label.clone() } else { @@ -477,34 +477,46 @@ impl SceneConfig { let entity = world.spawn(builder.build()); if has_entity_transform { - if let Ok(mut query) = world.query_one::<( + if let Ok(( + entity_transform, + renderer_opt, + light_opt, + light_comp_opt + )) = world.query_one::<( &EntityTransform, Option<&mut MeshRenderer>, Option<&mut EngineLight>, Option<&mut LightComponent>, - )>(entity) + )>(entity).get() { - if let Some((entity_transform, renderer_opt, light_opt, light_comp_opt)) = - query.get() - { - let transform = entity_transform.sync(); + let transform = entity_transform.sync(); - if let Some(renderer) = renderer_opt { - renderer.update(&transform); - log::debug!("Updated renderer transform for '{}'", label_for_logs); - } + if let Some(renderer) = renderer_opt { + renderer.update(&transform); + log::debug!("Updated renderer transform for '{}'", label_for_logs); + } - if let (Some(light), Some(light_comp)) = (light_opt, light_comp_opt) { - light.update(graphics.as_ref(), light_comp, &transform); - log::debug!("Updated light transform for '{}'", label_for_logs); - } + if let (Some(light), Some(light_comp)) = (light_opt, light_comp_opt) { + light.update(graphics.as_ref(), light_comp, &transform); + log::debug!("Updated light transform for '{}'", label_for_logs); } } } // adding to physics - if let Ok(mut q) = world.query_one::<(&Label, &EntityTransform, Option<&mut RigidBody>, Option<&mut ColliderGroup>, Option<&mut KCC>)>(entity) - && let Some((label, e_trans, rigid, col_group, kcc)) = q.get() { + if let Ok(( + label, + e_trans, + rigid, + col_group, + kcc + )) = world.query_one::<( + &Label, + &EntityTransform, + Option<&mut RigidBody>, + Option<&mut ColliderGroup>, + Option<&mut KCC> + )>(entity).get() { // rigidbody if let Some(body) = rigid { @@ -583,16 +595,12 @@ impl SceneConfig { let mut local_insert_one: Option<hecs::Entity> = None; - match world.query_one::<&mut Children>(parent_entity) { - Ok(mut parent_query) => { - if let Some(child_component) = parent_query.get() { - child_component.clear(); - child_component - .children_mut() - .extend(resolved_children.iter().copied()); - } else { - local_insert_one = Some(parent_entity); - } + match world.query_one::<&mut Children>(parent_entity).get() { + Ok(child_component) => { + child_component.clear(); + child_component + .children_mut() + .extend(resolved_children.iter().copied()); } Err(e) => { log::warn!( @@ -630,7 +638,7 @@ impl SceneConfig { log::info!("No lights in scene, spawning default light"); let legacy_lights: Vec<hecs::Entity> = world - .query::<&Label>() + .query::<(Entity, &Label)>() .iter() .filter_map(|(entity, label)| { if label.as_str() == "Default Light" { @@ -704,9 +712,9 @@ impl SceneConfig { if is_play_mode { log::debug!("Running in play mode"); let starting_camera = world - .query::<(&Camera, &CameraComponent)>() + .query::<(Entity, &Camera, &CameraComponent)>() .iter() - .find_map(|(entity, (_, component))| { + .find_map(|(entity, _, component)| { if component.starting_camera { log::debug!("Found starting camera: {:?}", entity); Some(entity) @@ -724,9 +732,9 @@ impl SceneConfig { } else { let debug_camera = { world - .query::<(&Camera, &CameraComponent)>() + .query::<(Entity, &Camera, &CameraComponent)>() .iter() - .find_map(|(entity, (_, component))| { + .find_map(|(entity, _, component)| { if matches!(component.camera_type, CameraType::Debug) { log::debug!("Found debug camera: {:?}", entity); Some(entity) @@ -744,7 +752,7 @@ impl SceneConfig { log::info!("No debug or starting camera found, creating viewport camera for editor"); let legacy_cameras: Vec<hecs::Entity> = world - .query::<&Label>() + .query::<(Entity, &Label)>() .iter() .filter_map(|(entity, label)| { if label.as_str() == "Viewport Camera" { @@ -146,7 +146,7 @@ pub mod jni { use jni::JNIEnv; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_scene_SceneManagerNative_loadSceneAsyncNative__JJLjava_lang_String_2( + pub extern "system" fn Java_com_dropbear_scene_SceneManagerNative_loadSceneAsyncNative__JJLjava_lang_String_2( mut env: JNIEnv, _: JClass, command_buffer_ptr: jlong, @@ -190,7 +190,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_scene_SceneManagerNative_loadSceneAsyncNative__JJLjava_lang_String_2Ljava_lang_String_2( + pub extern "system" fn Java_com_dropbear_scene_SceneManagerNative_loadSceneAsyncNative__JJLjava_lang_String_2Ljava_lang_String_2( mut env: JNIEnv, _: JClass, command_buffer_ptr: jlong, @@ -236,7 +236,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_scene_SceneManagerNative_switchToSceneImmediateNative( + pub extern "system" fn Java_com_dropbear_scene_SceneManagerNative_switchToSceneImmediateNative( mut env: JNIEnv, _: JClass, command_buffer_ptr: jlong, @@ -254,7 +254,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_scene_SceneLoadHandleNative_getSceneLoadHandleSceneName( + pub extern "system" fn Java_com_dropbear_scene_SceneLoadHandleNative_getSceneLoadHandleSceneName( mut env: JNIEnv, _: JClass, scene_loader_handle: jlong, @@ -284,7 +284,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_scene_SceneLoadHandleNative_switchToSceneAsync( + pub extern "system" fn Java_com_dropbear_scene_SceneLoadHandleNative_switchToSceneAsync( mut env: JNIEnv, _: JClass, command_buffer_ptr: jlong, @@ -308,7 +308,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_scene_SceneLoadHandleNative_getSceneLoadProgress( + pub extern "system" fn Java_com_dropbear_scene_SceneLoadHandleNative_getSceneLoadProgress( mut env: JNIEnv, _: JClass, scene_loader_handle: jlong, @@ -338,7 +338,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_scene_SceneLoadHandleNative_getSceneLoadStatus( + pub extern "system" fn Java_com_dropbear_scene_SceneLoadHandleNative_getSceneLoadStatus( mut env: JNIEnv, _: JClass, scene_loader_handle: jlong, @@ -625,7 +625,7 @@ impl ScriptManager { fn rebuild_entity_tag_database(&mut self, world: &World) -> anyhow::Result<()> { let mut new_map: HashMap<String, Vec<Entity>> = HashMap::new(); - for (entity, script) in world.query::<&Script>().iter() { + for (entity, script) in world.query::<(Entity, &Script)>().iter() { for tag in &script.tags { new_map.entry(tag.clone()).or_default().push(entity); } @@ -1,7 +1,6 @@ #![allow(non_snake_case)] //! Deals with the Java Native Interface (JNI) with the help of the [`jni`] crate -// pub mod exports; pub mod utils; use crate::APP_INFO; @@ -1,6 +0,0 @@ -pub mod components; -pub mod DropbearEngineNative; -pub mod InputStateNative; -pub mod SceneNative; -pub mod JNINative; -mod PhysicsNative; @@ -1,39 +0,0 @@ -#![allow(non_snake_case)] - -use jni::JNIEnv; -use jni::objects::JClass; -use jni::sys::jlong; -use crate::ptr::CommandBufferPtr; -use crate::command::CommandBuffer; - -/** - * Class: `com_dropbear_ffi_DropbearEngineNative` - * - * Method: `quit` - * - * Signature: `(J)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_DropbearEngineNative_quit - * (JNIEnv *, jclass, jlong);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_DropbearEngineNative_quit( - _env: JNIEnv, - _class: JClass, - command_handle: jlong, -) { - let graphics = command_handle as CommandBufferPtr; - - if graphics.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_DropbearEngineNative_quit] [ERROR] Graphics pointer is null" - ); - panic!("NullHandle while quitting GraphicsCommand, better off to shoot with gun than to nicely ask...") - } - - let graphics = unsafe { &*graphics }; - - if let Err(e) = graphics.send(CommandBuffer::Quit) { - panic!("Unable to send window command while quitting GraphicsCommand, better off to shoot with gun than to nicely ask... \n Error: {}", e); - } -} @@ -1,563 +0,0 @@ -#![allow(non_snake_case)] - -use crate::ptr::{CommandBufferPtr, InputStatePtr}; -use crate::scripting::jni::utils::{java_button_to_rust, new_float_array}; -use crate::utils::keycode_from_ordinal; -use crate::command::{CommandBuffer, WindowCommand}; -use crate::scripting::utils::button_from_ordinal; -use jni::objects::JClass; -use jni::objects::{JObject, JValue}; -use jni::sys::{jboolean, jfloatArray, jint, jlong, jobjectArray, JNI_FALSE}; -use jni::JNIEnv; - -/// **Class:** `com_dropbear_ffi_InputStateNative` -/// **Method:** `printInputState` -/// **Signature:** `(J)V` -/// -/// `JNIEXPORT void JNICALL Java_com_dropbear_ffi_InputStateNative_printInputState` -/// `(JNIEnv *, jclass, jlong);` -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_InputStateNative_printInputState( - _env: JNIEnv, - _class: JClass, - input_handle: jlong, -) { - let input = input_handle as InputStatePtr; - - if input.is_null() { - println!( - "[Java_com_dropbear_ffi_InputStateNative_printInputState] [ERROR] Input state pointer is null" - ); - return; - } - - let input = unsafe { &*input }; - println!("{:#?}", input); -} - -/// **Class:** `com_dropbear_ffi_InputStateNative` -/// **Method:** `isKeyPressed` -/// **Signature:** `(JI)Z` -/// -/// `JNIEXPORT jboolean JNICALL Java_com_dropbear_ffi_InputStateNative_isKeyPressed` -/// `(JNIEnv *, jclass, jlong, jint);` -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_InputStateNative_isKeyPressed( - _env: JNIEnv, - _class: JClass, - input_handle: jlong, - key: jint, -) -> jboolean { - let input = input_handle as InputStatePtr; - if input.is_null() { - println!( - "[Java_com_dropbear_ffi_InputStateNative_isKeyPressed] [ERROR] Input state pointer is null" - ); - return false.into(); - } - let input = unsafe { &*input }; - - match keycode_from_ordinal(key) { - Some(k) => input.pressed_keys.contains(&k).into(), - None => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_isKeyPressed] [WARN] Ordinal keycode is invalid" - ); - false.into() - } - } -} - -/// **Class:** `com_dropbear_ffi_InputStateNative` -/// **Method:** `getMousePosition` -/// **Signature:** `(J)[F` -/// -/// `JNIEXPORT jfloatArray JNICALL Java_com_dropbear_ffi_InputStateNative_getMousePosition` -/// `(JNIEnv *, jclass, jlong);` -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_InputStateNative_getMousePosition( - mut env: JNIEnv, - _class: JClass, - input_handle: jlong, -) -> jfloatArray { - let input = input_handle as InputStatePtr; - if input.is_null() { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getMousePosition] [ERROR] Input state pointer is null" - ); - return new_float_array(&mut env, -1.0, -1.0); - } - - let input = unsafe { &*input }; - new_float_array(&mut env, input.mouse_pos.0 as f32, input.mouse_pos.1 as f32) -} - -/// **Class:** `com_dropbear_ffi_InputStateNative` -/// **Method:** `isMouseButtonPressed` -/// **Signature:** `(JI)Z` -/// -/// `JNIEXPORT jboolean JNICALL Java_com_dropbear_ffi_InputStateNative_isMouseButtonPressed` -/// `(JNIEnv *, jclass, jlong, jint);` -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_InputStateNative_isMouseButtonPressed( - _env: JNIEnv, - _class: JClass, - input_handle: jlong, - button: jint, -) -> jboolean { - let input_ptr = input_handle as InputStatePtr; - - if input_ptr.is_null() { - println!( - "[Java_com_dropbear_ffi_InputStateNative_isMouseButtonPressed] [ERROR] Input state pointer is null" - ); - return false as jboolean; - } - - let input = unsafe { &*input_ptr }; - - if let Some(rust_button) = java_button_to_rust(button) { - input.mouse_button.contains(&rust_button) as jboolean - } else { - eprintln!( - "[Java_com_dropbear_ffi_InputStateNative_isMouseButtonPressed] [ERROR] Invalid button code: {}", - button - ); - false as jboolean - } -} - -/// **Class:** `com_dropbear_ffi_InputStateNative` -/// **Method:** `getMouseDelta` -/// **Signature:** `(J)[F` -/// -/// `JNIEXPORT jfloatArray JNICALL Java_com_dropbear_ffi_InputStateNative_getMouseDelta` -/// `(JNIEnv *, jclass, jlong);` -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_InputStateNative_getMouseDelta( - mut env: JNIEnv, - _class: JClass, - input_handle: jlong, -) -> jfloatArray { - let input = input_handle as InputStatePtr; - if input.is_null() { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getMouseDelta] [ERROR] Input state pointer is null" - ); - return new_float_array(&mut env, 0.0, 0.0); - } - - let input = unsafe { &mut *input }; - - if let Some(pos) = input.mouse_delta.take() { - new_float_array(&mut env, pos.0 as f32, pos.1 as f32) - } else { - new_float_array(&mut env, 0.0, 0.0) - } -} - -/// **Class:** `com_dropbear_ffi_InputStateNative` -/// **Method:** `isCursorLocked` -/// **Signature:** `(J)Z` -/// -/// `JNIEXPORT jboolean JNICALL Java_com_dropbear_ffi_InputStateNative_isCursorLocked` -/// `(JNIEnv *, jclass, jlong);` -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_InputStateNative_isCursorLocked( - _env: JNIEnv, - _class: JClass, - input_handle: jlong, -) -> jboolean { - let input = input_handle as InputStatePtr; - if input.is_null() { - println!( - "[Java_com_dropbear_ffi_InputStateNative_isCursorLocked] [ERROR] Input state pointer is null" - ); - return false as jboolean; - } - - let input = unsafe { &*input }; - input.is_cursor_locked as jboolean -} - -/// **Class:** `com_dropbear_ffi_InputStateNative` -/// **Method:** `setCursorLocked` -/// **Signature:** `(JJZ)V` -/// -/// `JNIEXPORT void JNICALL Java_com_dropbear_ffi_InputStateNative_setCursorLocked` -/// `(JNIEnv *, jclass, jlong, jlong, jboolean);` -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_InputStateNative_setCursorLocked( - _env: JNIEnv, - _class: JClass, - input_handle: jlong, - command_handle: jlong, - locked: jboolean, -) { - let input = input_handle as InputStatePtr; - if input.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_InputStateNative_setCursorLocked] [ERROR] Input state pointer is null" - ); - return; - } - - let graphics = command_handle as CommandBufferPtr; - if graphics.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_InputStateNative_setCursorLocked] [ERROR] Graphics pointer is null" - ); - return; - } - - let input = unsafe { &mut *input }; - let graphics = unsafe { &*graphics }; - - let is_locked = locked != 0; - - if let Err(e) = graphics.send(CommandBuffer::WindowCommand(WindowCommand::WindowGrab(is_locked))) { - eprintln!( - "[Java_com_dropbear_ffi_InputStateNative_setCursorLocked] [ERROR] Unable to send window command: {}", - e - ); - return; - } - - input.is_cursor_locked = is_locked; -} - -/// **Class:** `com_dropbear_ffi_InputStateNative` -/// **Method:** `getLastMousePos` -/// **Signature:** `(J)[F` -/// -/// `JNIEXPORT jfloatArray JNICALL Java_com_dropbear_ffi_InputStateNative_getLastMousePos` -/// `(JNIEnv *, jclass, jlong);` -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_InputStateNative_getLastMousePos( - mut env: JNIEnv, - _class: JClass, - input_handle: jlong, -) -> jfloatArray { - let input = input_handle as InputStatePtr; - if input.is_null() { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getLastMousePos] [ERROR] Input state pointer is null" - ); - return new_float_array(&mut env, 0.0, 0.0); - } - - let input = unsafe { &*input }; - if let Some(pos) = input.last_mouse_pos { - new_float_array(&mut env, pos.0 as f32, pos.1 as f32) - } else { - new_float_array(&mut env, 0.0, 0.0) - } -} - -/// **Class:** `com_dropbear_ffi_InputStateNative` -/// **Method:** `isCursorHidden` -/// **Signature:** `(J)Z` -/// -/// `JNIEXPORT jboolean JNICALL Java_com_dropbear_ffi_InputStateNative_isCursorHidden` -/// `(JNIEnv *, jclass, jlong);` -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_InputStateNative_isCursorHidden( - _env: JNIEnv, - _class: JClass, - input_handle: jlong, -) -> jboolean { - let input = input_handle as InputStatePtr; - if input.is_null() { - println!( - "[Java_com_dropbear_ffi_InputStateNative_isCursorHidden] [ERROR] Input state pointer is null" - ); - return false.into(); - } - let input = unsafe { &*input }; - - input.is_cursor_hidden.into() -} - -/// **Class:** `com_dropbear_ffi_InputStateNative` -/// **Method:** `setCursorHidden` -/// **Signature:** `(JJZ)V` -/// -/// `JNIEXPORT void JNICALL Java_com_dropbear_ffi_InputStateNative_setCursorHidden` -/// `(JNIEnv *, jclass, jlong, jlong, jboolean);` -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_InputStateNative_setCursorHidden( - _env: JNIEnv, - _class: JClass, - input_handle: jlong, - command_handle: jlong, - hide: jboolean, -) { - let input = input_handle as InputStatePtr; - if input.is_null() { - println!( - "[Java_com_dropbear_ffi_InputStateNative_setCursorHidden] [ERROR] Input state pointer is null" - ); - return; - } - let input = unsafe { &mut *input }; - - let graphics = command_handle as CommandBufferPtr; - if graphics.is_null() { - println!( - "[Java_com_dropbear_ffi_InputStateNative_setCursorHidden] [ERROR] Graphics pointer is null" - ); - return; - } - let graphics = unsafe { &*graphics }; - - let hide = hide != JNI_FALSE; - - if let Err(e) = graphics.send(CommandBuffer::WindowCommand(WindowCommand::HideCursor(hide))) { - println!( - "[Java_com_dropbear_ffi_InputStateNative_setCursorHidden] [ERROR] Unable to send hide cursor command: {}", - e - ); - } - - input.is_cursor_hidden = hide; -} - -/// **Class:** `com_dropbear_ffi_InputStateNative` -/// **Method:** `getConnectedGamepads` -/// **Signature:** `(J)[Lcom/dropbear/input/Gamepad;` -/// -/// `JNIEXPORT jobjectArray JNICALL Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads -/// (JNIEnv *, jclass, jlong);` -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads( - mut env: JNIEnv, - _class: JClass, - input_handle: jlong, -) -> jobjectArray { - - let input = input_handle as InputStatePtr; - - let empty = match env.new_object_array(0, "com/dropbear/input/Gamepad", JObject::null()) { - Ok(arr) => arr, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Unable to allocate empty Gamepad[]: {}", - e - ); - return std::ptr::null_mut(); - } - }; - - if input.is_null() { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Input state pointer is null" - ); - return empty.into_raw(); - } - - let input = unsafe { &*input }; - - // Create a NativeEngine instance and bind inputHandle so Gamepad.isButtonPressed works. - let engine_obj = match env.new_object("com/dropbear/ffi/NativeEngine", "()V", &[]) { - Ok(o) => o, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Unable to create NativeEngine: {}", - e - ); - return empty.into_raw(); - } - }; - - if let Err(e) = env.set_field(&engine_obj, "inputHandle", "J", JValue::Long(input_handle)) { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Unable to set NativeEngine.inputHandle: {}", - e - ); - return empty.into_raw(); - } - - let count = input.connected_gamepads.len(); - let out = match env.new_object_array(count as i32, "com/dropbear/input/Gamepad", JObject::null()) { - Ok(arr) => arr, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Unable to allocate Gamepad[]: {}", - e - ); - return empty.into_raw(); - } - }; - - for (index, gid) in input.connected_gamepads.iter().enumerate() { - let id: usize = (*gid).into(); - let (lx, ly) = input.get_left_stick(*gid); - let (rx, ry) = input.get_right_stick(*gid); - - let ldx = match env.new_object("java/lang/Double", "(D)V", &[JValue::Double(lx as f64)]) { - Ok(o) => o, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Unable to create Double for left stick x: {}", - e - ); - continue; - } - }; - let ldy = match env.new_object("java/lang/Double", "(D)V", &[JValue::Double(ly as f64)]) { - Ok(o) => o, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Unable to create Double for left stick y: {}", - e - ); - continue; - } - }; - let rdx = match env.new_object("java/lang/Double", "(D)V", &[JValue::Double(rx as f64)]) { - Ok(o) => o, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Unable to create Double for right stick x: {}", - e - ); - continue; - } - }; - let rdy = match env.new_object("java/lang/Double", "(D)V", &[JValue::Double(ry as f64)]) { - Ok(o) => o, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Unable to create Double for right stick y: {}", - e - ); - continue; - } - }; - - let left_vec = match env.new_object( - "com/dropbear/math/Vector2", - "(Ljava/lang/Number;Ljava/lang/Number;)V", - &[JValue::Object(&ldx), JValue::Object(&ldy)], - ) { - Ok(o) => o, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Unable to create left Vector2: {}", - e - ); - continue; - } - }; - - let right_vec = match env.new_object( - "com/dropbear/math/Vector2", - "(Ljava/lang/Number;Ljava/lang/Number;)V", - &[JValue::Object(&rdx), JValue::Object(&rdy)], - ) { - Ok(o) => o, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Unable to create right Vector2: {}", - e - ); - continue; - } - }; - - let gamepad_obj = match env.new_object( - "com/dropbear/input/Gamepad", - "(JLcom/dropbear/math/Vector2;Lcom/dropbear/math/Vector2;Lcom/dropbear/ffi/NativeEngine;)V", - &[ - JValue::Long(id as jlong), - JValue::Object(&left_vec), - JValue::Object(&right_vec), - JValue::Object(&engine_obj), - ], - ) { - Ok(o) => o, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Unable to create Gamepad: {}", - e - ); - continue; - } - }; - - if let Err(e) = env.set_object_array_element(&out, index as i32, gamepad_obj) { - println!( - "[Java_com_dropbear_ffi_InputStateNative_getConnectedGamepads] [ERROR] Unable to set Gamepad[] element {}: {}", - index, e - ); - } - } - - out.into_raw() -} - -/// **Class:** `com_dropbear_ffi_InputStateNative` -/// **Method:** `isGamepadButtonPressed` -/// **Signature:** `(JJI)Z` -/// -/// `JNIEXPORT jboolean JNICALL Java_com_dropbear_ffi_InputStateNative_isGamepadButtonPressed -/// (JNIEnv *, jclass, jlong, jlong, jint);` -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_InputStateNative_isGamepadButtonPressed( - _env: JNIEnv, - _class: JClass, - input_handle: jlong, - gamepad_id: jlong, - button_ordinal: jint, -) -> jboolean { - - let input_ptr = input_handle as InputStatePtr; - if input_ptr.is_null() { - println!( - "[Java_com_dropbear_ffi_InputStateNative_isGamepadButtonPressed] [ERROR] Input state pointer is null" - ); - return false.into(); - } - - if gamepad_id < 0 { - println!( - "[Java_com_dropbear_ffi_InputStateNative_isGamepadButtonPressed] [WARN] Invalid gamepad id (negative): {}", - gamepad_id - ); - return false.into(); - } - - let input = unsafe { &*input_ptr }; - - let button = match button_from_ordinal(button_ordinal) { - Ok(btn) => btn, - Err(_) => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_isGamepadButtonPressed] [WARN] Invalid button ordinal: {}", - button_ordinal - ); - return false.into(); - } - }; - - let target_id = gamepad_id as usize; - let maybe_gid = input - .connected_gamepads - .iter() - .find(|gid| { - let id: usize = (**gid).into(); - id == target_id - }) - .copied(); - - match maybe_gid { - Some(gid) => input.is_button_pressed(gid, button).into(), - None => { - println!( - "[Java_com_dropbear_ffi_InputStateNative_isGamepadButtonPressed] [WARN] Gamepad id {} not connected", - gamepad_id - ); - false.into() - } - } -} @@ -1,120 +0,0 @@ -#![allow(non_snake_case)] - -use hecs::World; -use jni::JNIEnv; -use jni::objects::{JClass, JString}; -use jni::sys::jlong; -use dropbear_engine::utils::ResourceReference; -use crate::ptr::AssetRegistryPtr; -use crate::states::Label; - - -/** - * Class: `com_dropbear_ffi_JNINative` - * - * Method: `getEntity` - * - * Signature: `(JLjava/lang/String;)J` - * - * `JNIEXPORT jlong JNICALL Java_com_dropbear_ffi_JNINative_getEntity - * (JNIEnv *, jclass, jlong, jstring);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_JNINative_getEntity( - mut env: JNIEnv, - _obj: JClass, - world_handle: jlong, - label: JString, -) -> jlong { - let label_jni_result = env.get_string(&label); - let label_str = match label_jni_result { - Ok(java_string) => match java_string.to_str() { - Ok(rust_str) => rust_str.to_string(), - Err(e) => { - println!( - "[Java_com_dropbear_ffi_JNINative_getEntity] [ERROR] Failed to convert Java string to Rust string: {}", - e - ); - return -1; - } - }, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_JNINative_getEntity] [ERROR] Failed to get string from JNI: {}", - e - ); - return -1; - } - }; - - let world = world_handle as *mut World; - - if world.is_null() { - println!("[Java_com_dropbear_ffi_JNINative_getEntity] [ERROR] World pointer is null"); - return -1; - } - - let world = unsafe { &mut *world }; - - for (id, entity_label) in world.query::<&Label>().iter() { - if entity_label.as_str() == label_str { - return id.to_bits().get() as jlong; - } - } - 0 -} - -/** - * Class: `com_dropbear_ffi_JNINative` - * - * Method: `getAsset` - * - * Signature: `(JLjava/lang/String;)J` - * - * `JNIEXPORT jlong JNICALL Java_com_dropbear_ffi_JNINative_getAsset - * (JNIEnv *, jclass, jlong, jstring);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_JNINative_getAsset( - mut env: JNIEnv, - _class: JClass, - asset_handle: jlong, - euca_uri: JString, -) -> jlong { - let asset = asset_handle as AssetRegistryPtr; - if asset.is_null() { - println!( - "[Java_com_dropbear_ffi_JNINative_getAsset] [ERROR] Asset registry pointer is null" - ); - return -1; - } - - let asset = unsafe { &*asset }; - - let jni_result = env.get_string(&euca_uri); - let str = match jni_result { - Ok(java_string) => match java_string.to_str() { - Ok(rust_str) => rust_str.to_string(), - Err(e) => { - println!( - "[Java_com_dropbear_ffi_JNINative_getAsset] [ERROR] Failed to convert Java string to Rust string: {}", - e - ); - return -1; - } - }, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_JNINative_getAsset] [ERROR] Failed to get string from JNI: {}", - e - ); - return -1; - } - }; - if let Ok(res) = ResourceReference::from_euca_uri(str) - && let Some(asset_handle) = asset.get_handle_from_reference(&res) - { - return asset_handle.raw() as jlong; - }; - 0 as jlong -} @@ -1,116 +0,0 @@ -use hecs::World; -use jni::JNIEnv; -use jni::objects::{JClass, JObject}; -use jni::sys::{jboolean, jlong, jobject, jobjectArray}; -use crate::{convert_jlong_to_entity, convert_ptr}; -use crate::physics::PhysicsState; -use crate::physics::rigidbody::RigidBody; - -/** - * Class: `com_dropbear_ffi_PhysicsNative` - * - * Method: `setPhysicsEnabled` - * - * Signature: `(JJJZ)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_PhysicsNative_setPhysicsEnabled - * (JNIEnv *, jclass, jlong, jlong, jlong, jboolean);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_PhysicsNative_setPhysicsEnabled( - mut env: JNIEnv, - _class: JClass, - world_ptr: jlong, - physics_handle: jlong, - entity_id: jlong, - enabled: jboolean, -) { - let world = convert_ptr!(mut world_ptr => World); - let physics = convert_ptr!(mut physics_handle => PhysicsState); - let entity = convert_jlong_to_entity!(entity_id); - - todo!() -} - -/** - * Class: `com_dropbear_ffi_PhysicsNative` - * - * Method: `isPhysicsEnabled` - * - * Signature: `(JJJ)Z` - * - * `JNIEXPORT jboolean JNICALL Java_com_dropbear_ffi_PhysicsNative_isPhysicsEnabled - * (JNIEnv *, jclass, jlong, jlong, jlong);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_PhysicsNative_isPhysicsEnabled( - _env: JNIEnv, - _class: JClass, - world_ptr: jlong, - physics_handle: jlong, - entity_id: jlong, -) -> jboolean { - let world = convert_ptr!(mut world_ptr => World); - let physics = convert_ptr!(mut physics_handle => PhysicsState); - let entity = convert_jlong_to_entity!(entity_id); - - if let Ok(rb) = world.get::<&RigidBody>(entity) { - if rb.disable_physics { - false.into() - } else { - true.into() - } - } else { - false.into() - } -} - -/** - * Class: `com_dropbear_ffi_PhysicsNative` - * - * Method: `getRigidBody` - * - * Signature: `(JJJ)Lcom/dropbear/physics/RigidBody;` - * - * `JNIEXPORT jobject JNICALL Java_com_dropbear_ffi_PhysicsNative_getRigidBody - * (JNIEnv *, jclass, jlong, jlong, jlong);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_PhysicsNative_getRigidBody( - mut env: JNIEnv, - _class: JClass, - world_ptr: jlong, - physics_handle: jlong, - entity_id: jlong, -) -> jobject { - let world = convert_ptr!(mut world_ptr => World); - let physics = convert_ptr!(mut physics_handle => PhysicsState); - let entity = convert_jlong_to_entity!(entity_id); - - todo!() -} - -/** - * Class: `com_dropbear_ffi_PhysicsNative` - * - * Method: `getAllColliders` - * - * Signature: `(JJ)[Lcom/dropbear/physics/Collider;` - * - * `JNIEXPORT jobjectArray JNICALL Java_com_dropbear_ffi_PhysicsNative_getAllColliders - * (JNIEnv *, jclass, jlong, jlong, jlong);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_PhysicsNative_getAllColliders( - mut env: JNIEnv, - _class: JClass, - world_ptr: jlong, - physics_handle: jlong, - entity_id: jlong, -) -> jobjectArray { - let world = convert_ptr!(mut world_ptr => World); - let physics = convert_ptr!(mut physics_handle => PhysicsState); - let entity = convert_jlong_to_entity!(entity_id); - - todo!() -} @@ -1,329 +0,0 @@ -#![allow(non_snake_case, dead_code)] - -use jni::JNIEnv; -use jni::objects::{JClass, JObject, JString, JThrowable, JValue}; -use jni::sys::{jlong, jobject}; -use crate::command::CommandBuffer; -use crate::ptr::{CommandBufferPtr, SceneLoaderPtr}; -use crate::scene::loading::{SceneLoadHandle as CoreSceneLoadHandle}; -use crate::states::WorldLoadingStatus; - -fn throw_premature_scene_switch(env: &mut JNIEnv, message: &str) -> Result<(), jni::errors::Error> { - let ex_class = env.find_class("com/dropbear/exception/PrematureSceneSwitchException")?; - let msg = env.new_string(message)?; - let ex_obj = env.new_object( - ex_class, - "(Ljava/lang/String;Ljava/lang/Throwable;)V", - &[JValue::Object(&JObject::from(msg)), JValue::Object(&JObject::null())], - )?; - let ex_throwable = JThrowable::from(ex_obj); - env.throw(ex_throwable)?; - Ok(()) -} - -/** - * Class: `com_dropbear_ffi_SceneNative` - * - * Method: `loadSceneAsync` - * - * Signature: `(JJLjava/lang/String;Lcom/dropbear/ffi/NativeEngine;)Lcom/dropbear/scene/SceneLoadHandle;` - * - * `JNIEXPORT jobject JNICALL Java_com_dropbear_ffi_SceneNative_loadSceneAsync__JJLjava_lang_String_2Lcom_dropbear_ffi_NativeEngine_2` - * `(JNIEnv *, jclass, jlong, jstring, jobject);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_SceneNative_loadSceneAsync__JJLjava_lang_String_2Lcom_dropbear_ffi_NativeEngine_2( - mut env: JNIEnv, - _class: JClass, - command_buffer_handle: jlong, - scene_loader_ptr: jlong, - scene_name: JString, - native_engine: JObject, -) -> jobject { - let command_buffer_ptr = command_buffer_handle as CommandBufferPtr; - let scene_loader_ptr = scene_loader_ptr as SceneLoaderPtr; - - if command_buffer_ptr.is_null() || scene_loader_ptr.is_null() { - return JObject::null().into_raw(); - } - - let command_buffer = unsafe { &*command_buffer_ptr }; - let scene_loader = unsafe { &*scene_loader_ptr }; - - let scene_name_str: String = match env.get_string(&scene_name) { - Ok(s) => s.into(), - Err(_) => return JObject::null().into_raw(), - }; - - // removes need for double scene loading - let id = { - let loader_guard = scene_loader.lock(); - if let Some(existing_id) = loader_guard.find_pending_id_by_name(&scene_name_str) { - existing_id - } else { - drop(loader_guard); - let mut loader_guard = scene_loader.lock(); - let new_id = loader_guard.register_load(scene_name_str.clone()); - - let core_handle = CoreSceneLoadHandle { - id: new_id, - scene_name: scene_name_str.clone(), - }; - - if command_buffer.try_send(CommandBuffer::LoadSceneAsync(core_handle)).is_err() { - return JObject::null().into_raw(); - } - - new_id - } - }; - - let cls = match env.find_class("com/dropbear/scene/SceneLoadHandle") { - Ok(c) => c, - Err(_) => return JObject::null().into_raw(), - }; - - let obj = match env.new_object(cls, "(JLjava/lang/String;Lcom/dropbear/ffi/NativeEngine;)V", &[ - JValue::Long(id as jlong), - JValue::Object(&scene_name), - JValue::Object(&native_engine), - ]) { - Ok(o) => o, - Err(_) => return JObject::null().into_raw(), - }; - - obj.into_raw() -} - -/** - * Class: `com_dropbear_ffi_SceneNative` - * - * Method: `loadSceneAsync` - * - * Signature: `(JJLjava/lang/String;Ljava/lang/String;Lcom/dropbear/ffi/NativeEngine;)Lcom/dropbear/scene/SceneLoadHandle;` - * - * `JNIEXPORT jobject JNICALL Java_com_dropbear_ffi_SceneNative_loadSceneAsync__JJLjava_lang_String_2Ljava_lang_String_2Lcom_dropbear_ffi_NativeEngine_2` - * `(JNIEnv *, jclass, jlong, jstring, jstring, jobject);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_SceneNative_loadSceneAsync__JJLjava_lang_String_2Ljava_lang_String_2Lcom_dropbear_ffi_NativeEngine_2( - _env: JNIEnv, - _class: JClass, - _command_buffer_handle: jlong, - _scene_loader_ptr: jlong, - _scene_name: JString, - _loading_scene_name: JString, - _native_engine: JObject, -) -> jobject { - todo!("Not implemented yet") -} - -/** - * Class: `com_dropbear_ffi_SceneNative` - * - * Method: `switchToSceneAsync` - * - * Signature: `(JLcom/dropbear/scene/SceneLoadHandle;)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_SceneNative_switchToSceneAsync` - * `(JNIEnv *, jclass, jlong, jobject);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_SceneNative_switchToSceneAsync( - mut env: JNIEnv, - _class: JClass, - command_buffer_ptr: jlong, - handle: JObject, -) { - let command_buffer_ptr = command_buffer_ptr as CommandBufferPtr; - if command_buffer_ptr.is_null() { - return; - } - let command_buffer = unsafe { &*command_buffer_ptr }; - - let id = match env.get_field(&handle, "id", "J") { - Ok(v) => v.j().unwrap(), - Err(_) => return, - }; - - let name_obj = match env.get_field(&handle, "sceneName", "Ljava/lang/String;") { - Ok(v) => v.l().unwrap(), - Err(_) => return, - }; - - let name_str: String = match env.get_string(&JString::from(name_obj)) { - Ok(s) => s.into(), - Err(_) => return, - }; - - let core_handle = CoreSceneLoadHandle { - id: id as u64, - scene_name: name_str, - }; - - let _ = command_buffer.try_send(CommandBuffer::SwitchToAsync(core_handle)); -} - -/** - * Class: `com_dropbear_ffi_SceneNative` - * - * Method: `switchToSceneImmediate` - * - * Signature: `(JLjava/lang/String;)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_SceneNative_switchToSceneImmediate` - * `(JNIEnv *, jclass, jlong, jstring);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_SceneNative_switchToSceneImmediate( - mut env: JNIEnv, - _class: JClass, - command_buffer_ptr: jlong, - scene_name: JString, -) { - let command_buffer_ptr = command_buffer_ptr as CommandBufferPtr; - if command_buffer_ptr.is_null() { - return; - } - let command_buffer = unsafe { &*command_buffer_ptr }; - - let scene_name_str: String = match env.get_string(&scene_name) { - Ok(s) => s.into(), - Err(_) => return, - }; - - let _ = command_buffer.try_send(CommandBuffer::SwitchSceneImmediate(scene_name_str)); -} - -/** - * Class: `com_dropbear_ffi_SceneNative` - * - * Method: `getSceneLoadProgress` - * - * Signature: `(JLcom/dropbear/scene/SceneLoadHandle;)Lcom/dropbear/utils/Progress;` - * - * `JNIEXPORT jobject JNICALL Java_com_dropbear_ffi_SceneNative_getSceneLoadProgress` - * `(JNIEnv *, jclass, jlong, jobject);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_SceneNative_getSceneLoadProgress( - mut env: JNIEnv, - _class: JClass, - scene_loader_ptr: jlong, - handle: JObject, // SceneLoadHandle -) -> jobject { - let scene_loader_ptr = scene_loader_ptr as SceneLoaderPtr; - if scene_loader_ptr.is_null() { - return JObject::null().into_raw(); - } - let scene_loader = unsafe { &*scene_loader_ptr }; - - let id = match env.get_field(&handle, "id", "J") { - Ok(v) => v.j().unwrap(), - Err(_) => return JObject::null().into_raw(), - }; - - let mut loader = scene_loader.lock(); - if let Some(entry) = loader.get_entry_mut(id as u64) { - if let Some(rx) = &entry.status { - while let Ok(status) = rx.try_recv() { - match status { - WorldLoadingStatus::Idle => { - entry.progress.message = "Idle".to_string(); - }, - WorldLoadingStatus::LoadingEntity { index, name, total } => { - entry.progress.current = index; - entry.progress.total = total; - entry.progress.message = format!("Loading entity: {}", name); - }, - WorldLoadingStatus::Completed => { - entry.progress.current = entry.progress.total; - entry.progress.message = "Completed".to_string(); - } - } - } - } - - let p = &entry.progress; - - let cls = match env.find_class("com/dropbear/utils/Progress") { - Ok(c) => c, - Err(_) => return JObject::null().into_raw(), - }; - - let msg = match env.new_string(&p.message) { - Ok(s) => s, - Err(_) => return JObject::null().into_raw(), - }; - - let obj = match env.new_object(cls, "(DDLjava/lang/String;)V", &[ - JValue::Double(p.current as f64), - JValue::Double(p.total as f64), - JValue::Object(&msg), - ]) { - Ok(o) => o, - Err(_) => return JObject::null().into_raw(), - }; - - obj.into_raw() - } else { - JObject::null().into_raw() - } -} - -/** - * Class: `com_dropbear_ffi_SceneNative` - * - * Method: `getSceneLoadStatus` - * - * Signature: `(JLcom/dropbear/scene/SceneLoadHandle;)Lcom/dropbear/scene/SceneLoadStatus;` - * - * `JNIEXPORT jobject JNICALL Java_com_dropbear_ffi_SceneNative_getSceneLoadStatus` - * `(JNIEnv *, jclass, jlong, jobject);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_SceneNative_getSceneLoadStatus( - mut env: JNIEnv, - _class: JClass, - scene_loader_ptr: jlong, - handle: JObject, // SceneLoadHandle -) -> jobject { - let scene_loader_ptr = scene_loader_ptr as SceneLoaderPtr; - if scene_loader_ptr.is_null() { - return JObject::null().into_raw(); - } - let scene_loader = unsafe { &*scene_loader_ptr }; - - let id = match env.get_field(&handle, "id", "J") { - Ok(v) => v.j().unwrap(), - Err(_) => return JObject::null().into_raw(), - }; - - let loader = scene_loader.lock(); - if let Some(entry) = loader.get_entry(id as u64) { - let status_str = match entry.result { - crate::scene::loading::SceneLoadResult::Pending => "PENDING", - crate::scene::loading::SceneLoadResult::Success => "READY", - crate::scene::loading::SceneLoadResult::Error(_) => "FAILED", - }; - - let cls = match env.find_class("com/dropbear/scene/SceneLoadStatus") { - Ok(c) => c, - Err(_) => return JObject::null().into_raw(), - }; - - let field_id = match env.get_static_field_id(&cls, status_str, "Lcom/dropbear/scene/SceneLoadStatus;") { - Ok(f) => f, - Err(_) => return JObject::null().into_raw(), - }; - - let obj = match env.get_static_field_unchecked(&cls, field_id, jni::signature::JavaType::Object("com/dropbear/scene/SceneLoadStatus".to_string())) { - Ok(v) => v.l().unwrap(), - Err(_) => return JObject::null().into_raw(), - }; - - obj.into_raw() - } else { - JObject::null().into_raw() - } -} @@ -1,539 +0,0 @@ -#![allow(non_snake_case)] - -use hecs::World; -use jni::JNIEnv; -use jni::objects::{JClass, JObject, JString, JValue}; -use jni::sys::{jlong, jobject}; -use dropbear_engine::camera::Camera; -use crate::camera::{CameraComponent, CameraType}; -use crate::convert_jlong_to_entity; -use crate::scripting::jni::utils::{create_vector3, extract_vector3}; - -/** - * Class: `com_dropbear_ffi_components_CameraNative` - * - * Method: `getCamera` - * - * Signature: `(JLjava/lang/String;)Lcom/dropbear/Camera;` - * - * `JNIEXPORT jobject JNICALL Java_com_dropbear_ffi_components_CameraNative_getCamera - * (JNIEnv *, jclass, jlong, jstring);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CameraNative_getCamera( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - camera_name: JString, -) -> jobject { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!("[Java_com_dropbear_ffi_components_CameraNative_getCamera] [ERROR] World pointer is null"); - return std::ptr::null_mut(); - } - - let world = unsafe { &*world }; - - let label = env.get_string(&camera_name); - let label: String = if let Ok(str) = label { - str.to_string_lossy().to_string() - } else { - eprintln!("[Java_com_dropbear_ffi_components_CameraNative_getCamera] [ERROR] Failed to get camera name"); - return std::ptr::null_mut(); - }; - - if let Some((id, (cam, comp))) = world - .query::<(&Camera, &CameraComponent)>() - .iter() - .find(|(_, (cam, _))| cam.label == label) - { - if matches!(comp.camera_type, CameraType::Debug) { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getCamera] [WARN] Querying a CameraType::Debug is illegal, returning null" - ); - return std::ptr::null_mut(); - } - - let entity_id = if let Ok(v) = env.find_class("com/dropbear/EntityId") { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getCamera] [ERROR] Unable to find EntityId class" - ); - return std::ptr::null_mut(); - }; - let entity_id = if let Ok(v) = env.new_object( - entity_id, - "(J)V", - &[JValue::Long(id.to_bits().get() as i64)], - ) { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getCamera] [ERROR] Unable to create new entity_id object" - ); - return std::ptr::null_mut(); - }; - - let label = if let Ok(v) = env.new_string(cam.label.as_str()) { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getCamera] [ERROR] Unable to create new string for label" - ); - return std::ptr::null_mut(); - }; - - let eye = if let Ok(v) = create_vector3(&mut env, cam.eye.x, cam.eye.y, cam.eye.z) { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getCamera] [ERROR] Unable to create vector3 for eye" - ); - return std::ptr::null_mut(); - }; - - let target = if let Ok(v) = - create_vector3(&mut env, cam.target.x, cam.target.y, cam.target.z) - { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getCamera] [ERROR] Unable to create vector3 for target" - ); - return std::ptr::null_mut(); - }; - - let up = if let Ok(v) = create_vector3(&mut env, cam.up.x, cam.up.y, cam.up.z) { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getCamera] [ERROR] Unable to create vector3 for up" - ); - return std::ptr::null_mut(); - }; - - let class = if let Ok(v) = env.find_class("com/dropbear/Camera") { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getCamera] [ERROR] Unable to locate camera class" - ); - return std::ptr::null_mut(); - }; - - let camera_obj = if let Ok(v) = env.new_object( - class, - "(Ljava/lang/String;Lcom/dropbear/EntityId;Lcom/dropbear/math/Vector3;Lcom/dropbear/math/Vector3;Lcom/dropbear/math/Vector3;DDDDDDDD)V", - &[ - JValue::Object(&label), - JValue::Object(&entity_id), - JValue::Object(&eye), - JValue::Object(&target), - JValue::Object(&up), - JValue::Double(cam.aspect), - JValue::Double(cam.settings.fov_y), - JValue::Double(cam.znear), - JValue::Double(cam.zfar), - JValue::Double(cam.yaw), - JValue::Double(cam.pitch), - JValue::Double(cam.settings.speed), - JValue::Double(cam.settings.sensitivity), - ], - ) { - v - } else { - eprintln!("[Java_com_dropbear_ffi_components_CameraNative_getCamera] [ERROR] Unable to create the camera object"); - return std::ptr::null_mut(); - }; - - return camera_obj.as_raw(); - } - - std::ptr::null_mut() -} - - - -/** - * Class: `com_dropbear_ffi_components_CameraNative` - * - * Method: `getAttachedCamera` - * - * Signature: `(JJ)Lcom/dropbear/Camera;` - * - * `JNIEXPORT jobject JNICALL Java_com_dropbear_ffi_components_CameraNative_getAttachedCamera - * (JNIEnv *, jclass, jlong, jlong);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CameraNative_getAttachedCamera( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, -) -> jobject { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getAttachedCamera] [ERROR] World pointer is null" - ); - return std::ptr::null_mut(); - } - - let world = unsafe { &*world }; - let entity = convert_jlong_to_entity!(entity_id); - - if let Ok(mut q) = world.query_one::<(&Camera, &CameraComponent)>(entity) - && let Some((cam, comp)) = q.get() - { - if matches!(comp.camera_type, CameraType::Debug) { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getAttachedCamera] [WARN] Querying a CameraType::Debug is illegal, returning null" - ); - return std::ptr::null_mut(); - } - - let entity_id = if let Ok(v) = env.find_class("com/dropbear/EntityId") { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getAttachedCamera] [ERROR] Unable to find EntityId class" - ); - return std::ptr::null_mut(); - }; - let entity_id = if let Ok(v) = env.new_object( - entity_id, - "(J)V", - &[JValue::Long(entity.to_bits().get() as i64)], - ) { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getAttachedCamera] [ERROR] Unable to create new entity_id object" - ); - return std::ptr::null_mut(); - }; - - let label = if let Ok(v) = env.new_string(cam.label.as_str()) { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getAttachedCamera] [ERROR] Unable to create new string for label" - ); - return std::ptr::null_mut(); - }; - - let eye = if let Ok(v) = create_vector3(&mut env, cam.eye.x, cam.eye.y, cam.eye.z) { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getAttachedCamera] [ERROR] Unable to create vector3 for eye" - ); - return std::ptr::null_mut(); - }; - - let target = if let Ok(v) = - create_vector3(&mut env, cam.target.x, cam.target.y, cam.target.z) - { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getAttachedCamera] [ERROR] Unable to create vector3 for target" - ); - return std::ptr::null_mut(); - }; - - let up = if let Ok(v) = create_vector3(&mut env, cam.up.x, cam.up.y, cam.up.z) { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getAttachedCamera] [ERROR] Unable to create vector3 for up" - ); - return std::ptr::null_mut(); - }; - - let class = if let Ok(v) = env.find_class("com/dropbear/Camera") { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_getAttachedCamera] [ERROR] Unable to locate camera class" - ); - return std::ptr::null_mut(); - }; - - let camera_obj = if let Ok(v) = env.new_object( - class, - "(Ljava/lang/String;Lcom/dropbear/EntityId;Lcom/dropbear/math/Vector3;Lcom/dropbear/math/Vector3;Lcom/dropbear/math/Vector3;DDDDDDDD)V", - &[ - JValue::Object(&label), - JValue::Object(&entity_id), - JValue::Object(&eye), - JValue::Object(&target), - JValue::Object(&up), - JValue::Double(cam.aspect), - JValue::Double(cam.settings.fov_y), - JValue::Double(cam.znear), - JValue::Double(cam.zfar), - JValue::Double(cam.yaw), - JValue::Double(cam.pitch), - JValue::Double(cam.settings.speed), - JValue::Double(cam.settings.sensitivity), - ], - ) { - v - } else { - eprintln!("[Java_com_dropbear_ffi_components_CameraNative_getAttachedCamera] [ERROR] Unable to create the camera object"); - return std::ptr::null_mut(); - }; - - return camera_obj.as_raw(); - } - - std::ptr::null_mut() -} - - -/** - * Class: `com_dropbear_ffi_components_CameraNative` - * - * Method: `setCamera` - * - * Signature: `(JLcom/dropbear/Camera;)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_CameraNative_setCamera - * (JNIEnv *, jclass, jlong, jobject);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CameraNative_setCamera( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - camera_obj: JObject, -) { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!("[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] World pointer is null"); - return; - } - - let world = unsafe { &mut *world }; - - let entity_id_obj = if let Ok(v) = - env.call_method(&camera_obj, "getId", "()Lcom/dropbear/EntityId;", &[]) - { - if let Ok(obj) = v.l() { - obj - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to extract EntityId object" - ); - return; - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to get EntityId from camera" - ); - return; - }; - - let entity_id = if let Ok(v) = env.call_method(&entity_id_obj, "getId", "()J", &[]) { - if let Ok(id) = v.j() { - id as u32 - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to extract entity id value" - ); - return; - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to call getId on EntityId" - ); - return; - }; - - let entity = unsafe { world.find_entity_from_id(entity_id) }; - - let eye_obj = if let Ok(v) = - env.call_method(&camera_obj, "getEye", "()Lcom/dropbear/math/Vector3;", &[]) - { - if let Ok(obj) = v.l() { - obj - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to extract eye vector" - ); - return; - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to get eye from camera" - ); - return; - }; - - let eye = if let Some(v) = extract_vector3(&mut env, &eye_obj) { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to extract eye vector values" - ); - return; - }; - - let target_obj = if let Ok(v) = env.call_method( - &camera_obj, - "getTarget", - "()Lcom/dropbear/math/Vector3;", - &[], - ) { - if let Ok(obj) = v.l() { - obj - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to extract target vector" - ); - return; - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to get target from camera" - ); - return; - }; - - let target = if let Some(v) = extract_vector3(&mut env, &target_obj) { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to extract target vector values" - ); - return; - }; - - let up_obj = if let Ok(v) = - env.call_method(&camera_obj, "getUp", "()Lcom/dropbear/math/Vector3;", &[]) - { - if let Ok(obj) = v.l() { - obj - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to extract up vector" - ); - return; - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to get up from camera" - ); - return; - }; - - let up = if let Some(v) = extract_vector3(&mut env, &up_obj) { - v - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to extract up vector values" - ); - return; - }; - - let fov_y = if let Ok(v) = env.call_method(&camera_obj, "getFov_y", "()D", &[]) { - if let Ok(d) = v.d() { - d - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to extract fov_y" - ); - return; - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to get fov_y from camera" - ); - return; - }; - - let znear = if let Ok(v) = env.call_method(&camera_obj, "getZnear", "()D", &[]) { - if let Ok(d) = v.d() { - d - } else { - return; - } - } else { - return; - }; - - let zfar = if let Ok(v) = env.call_method(&camera_obj, "getZfar", "()D", &[]) { - if let Ok(d) = v.d() { - d - } else { - return; - } - } else { - return; - }; - - let yaw = if let Ok(v) = env.call_method(&camera_obj, "getYaw", "()D", &[]) { - if let Ok(d) = v.d() { - d - } else { - return; - } - } else { - return; - }; - - let pitch = if let Ok(v) = env.call_method(&camera_obj, "getPitch", "()D", &[]) { - if let Ok(d) = v.d() { - d - } else { - return; - } - } else { - return; - }; - - let speed = if let Ok(v) = env.call_method(&camera_obj, "getSpeed", "()D", &[]) { - if let Ok(d) = v.d() { - d - } else { - return; - } - } else { - return; - }; - - let sensitivity = if let Ok(v) = env.call_method(&camera_obj, "getSensitivity", "()D", &[]) { - if let Ok(d) = v.d() { - d - } else { - return; - } - } else { - return; - }; - - if let Ok(mut q) = world.query_one::<&mut Camera>(entity) { - if let Some(cam) = q.get() { - cam.eye = eye.as_dvec3(); - cam.target = target.as_dvec3(); - cam.up = up.as_dvec3(); - cam.settings.fov_y = fov_y; - cam.znear = znear; - cam.zfar = zfar; - cam.yaw = yaw; - cam.pitch = pitch; - cam.settings.speed = speed; - cam.settings.sensitivity = sensitivity; - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Entity does not have a Camera component" - ); - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CameraNative_setCamera] [ERROR] Unable to query camera component" - ); - } -} @@ -1,76 +0,0 @@ -use crate::convert_ptr; -use crate::physics::collider::{Collider, ColliderGroup}; -use crate::physics::PhysicsState; -use hecs::World; -use jni::objects::{JClass, JObject}; -use jni::sys::jlong; -use jni::JNIEnv; -use rapier3d::na::{UnitQuaternion, Vector3}; -use rapier3d::prelude::AngVector; - -/** - * Class: `com_dropbear_ffi_components_ColliderNative` - * - * Method: `setCollider` - * - * Signature: `(JLcom/dropbear/physics/Collider;)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_ColliderNative_setCollider - * (JNIEnv *, jclass, jlong, jlong, jobject);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_ColliderNative_setCollider( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - physics_handle: jlong, - collider_obj: JObject, -) { - let world = convert_ptr!(mut world_handle => World); - let physics = convert_ptr!(mut physics_handle => PhysicsState); - - Collider::from_jni_object(&mut env, &collider_obj).and_then(|(handle, collider)| { - if let Some(rapier_collider) = physics.colliders.get_mut(handle) { - rapier_collider.set_friction(collider.friction); - rapier_collider.set_restitution(collider.restitution); - rapier_collider.set_density(collider.density); - rapier_collider.set_sensor(collider.is_sensor); - - let translation = Vector3::from_column_slice(&collider.translation); - let rotation = UnitQuaternion::from_euler_angles( - collider.rotation[0], - collider.rotation[1], - collider.rotation[2] - ); - - rapier_collider.set_translation_wrt_parent(translation); - let rot = rotation.euler_angles(); - rapier_collider.set_rotation_wrt_parent(AngVector::new(rot.0, rot.1, rot.2)); - - let temp_collider = collider.to_rapier(); - rapier_collider.set_shape(temp_collider.shared_shape().clone()); - } - - if let Some(ecs_entity) = collider.entity.locate_entity(&world) { - if let Ok(mut group) = world.get::<&mut ColliderGroup>(ecs_entity) { - let mut success = false; - for c in group.colliders.iter_mut() { - if c.id == collider.id { - *c = collider.clone(); - success = true; - break; - } - } - if success { - Ok(()) - } else { - Err(anyhow::anyhow!("Failed to find Collider [{}] in ColliderGroup", collider.id)) - } - } else { - Err(anyhow::anyhow!("Failed to get ColliderGroup from ECS")) - } - } else { - Err(anyhow::anyhow!("Failed to locate entity in ECS")) - } - }).ok(); -} @@ -1,795 +0,0 @@ -#![allow(non_snake_case)] - -use hecs::World; -use jni::JNIEnv; -use jni::objects::{JClass, JPrimitiveArray, JString}; -use jni::sys::{jboolean, jdouble, jfloatArray, jint, jlong, jstring}; -use dropbear_engine::entity::MeshRenderer; -use crate::convert_jlong_to_entity; -use crate::states::{CustomProperties, Value}; - -/** - * Class: `com_dropbear_ffi_components_CustomPropertiesNative` - * - * Method: `getStringProperty` - * - * Signature: `(JJLjava/lang/String;)Ljava/lang/String;` - * - * `JNIEXPORT jstring JNICALL Java_com_dropbear_ffi_components_CustomPropertiesNative_getStringProperty - * (JNIEnv *, jclass, jlong, jlong, jstring);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CustomPropertiesNative_getStringProperty( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - property_name: JString, -) -> jstring { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getStringProperty] [ERROR] World pointer is null" - ); - return std::ptr::null_mut(); - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - if let Ok(mut q) = world.query_one::<(&MeshRenderer, &CustomProperties)>(entity) - && let Some((_, props)) = q.get() - { - let string = env.get_string(&property_name); - let value: String = if let Ok(str) = string { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getStringProperty] [ERROR] Failed to get property name" - ); - return std::ptr::null_mut(); - }; - let output = props.get_property(&value); - if let Some(output) = output { - match output { - Value::String(val) => match env.new_string(val) { - Ok(string) => string.as_raw(), - Err(e) => { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getStringProperty] [ERROR] Failed to create string: {}", - e - ); - std::ptr::null_mut() - } - }, - _ => { - println!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getStringProperty] [WARN] Property is not a string" - ); - std::ptr::null_mut() - } - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getStringProperty] [WARN] Property not found" - ); - std::ptr::null_mut() - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getStringProperty] [ERROR] Failed to query entity for model properties" - ); - std::ptr::null_mut() - } -} - - -/** - * Fetches a [`jint`]/[`i32`] value from a key value. - * - * If the value does not exist, it will return `650911`, a randomly generated number - * that is extremely specific that no one would be sane enough to use this as a property. - * - * Class: `com_dropbear_ffi_components_CustomPropertiesNative` - * - * Method: `getIntProperty` - * - * Signature: `(JJLjava/lang/String;)I` - * - * `JNIEXPORT jint JNICALL Java_com_dropbear_ffi_components_CustomPropertiesNative_getIntProperty - * (JNIEnv *, jclass, jlong, jlong, jstring);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CustomPropertiesNative_getIntProperty( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - property_name: JString, -) -> jint { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!("[Java_com_dropbear_ffi_components_CustomPropertiesNative_getIntProperty] [ERROR] World pointer is null"); - return 650911; - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - if let Ok(mut q) = world.query_one::<(&MeshRenderer, &CustomProperties)>(entity) - && let Some((_, props)) = q.get() - { - let string = env.get_string(&property_name); - let value: String = if let Ok(str) = string { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getIntProperty] [ERROR] Failed to get property name" - ); - return 650911; - }; - let output = props.get_property(&value); - if let Some(output) = output { - match output { - Value::Int(val) => *val as jint, - _ => { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getIntProperty] [WARN] Property is not an int" - ); - 650911 - } - } - } else { - eprintln!("[Java_com_dropbear_ffi_components_CustomPropertiesNative_getIntProperty] [WARN] Property not found"); - 650911 - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getIntProperty] [ERROR] Failed to query entity for model properties" - ); - 650911 - } -} - - -/** - * Gets a [`jlong`]/[`i64`] property. - * - * If the value doesn't exist, it will return this value: `6509112938`. This is a random number - * from a generator I got, and it is such a specific number that no one would ever have this number - * in one of their properties. - * - * Class: `com_dropbear_ffi_components_CustomPropertiesNative` - * - * Method: `getLongProperty` - * - * Signature: `(JJLjava/lang/String;)J` - * - * `JNIEXPORT jlong JNICALL Java_com_dropbear_ffi_components_CustomPropertiesNative_getLongProperty - * (JNIEnv *, jclass, jlong, jlong, jstring);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CustomPropertiesNative_getLongProperty( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - property_name: JString, -) -> jlong { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getLongProperty] [ERROR] World pointer is null" - ); - return 6509112938; - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - if let Ok(mut q) = world.query_one::<(&MeshRenderer, &CustomProperties)>(entity) - && let Some((_, props)) = q.get() - { - let string = env.get_string(&property_name); - let value: String = if let Ok(str) = string { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getLongProperty] [ERROR] Failed to get property name" - ); - return 0; - }; - let output = props.get_property(&value); - if let Some(output) = output { - match output { - Value::Int(val) => *val as jlong, - _ => { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getLongProperty] [WARN] Property is not a long" - ); - 6509112938 - } - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getLongProperty] [WARN] Property not found" - ); - 6509112938 - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getLongProperty] [ERROR] Failed to query entity for model properties" - ); - 6509112938 - } -} - -/** - * Class: `com_dropbear_ffi_components_CustomPropertiesNative` - * - * Method: `getFloatProperty` - * - * Signature: `(JJLjava/lang/String;)D` - * - * `JNIEXPORT jdouble JNICALL Java_com_dropbear_ffi_components_CustomPropertiesNative_getFloatProperty - * (JNIEnv *, jclass, jlong, jlong, jstring);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CustomPropertiesNative_getFloatProperty( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - property_name: JString, -) -> jdouble { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getFloatProperty] [ERROR] World pointer is null" - ); - return f64::NAN; - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - if let Ok(mut q) = world.query_one::<(&MeshRenderer, &CustomProperties)>(entity) - && let Some((_, props)) = q.get() - { - let string = env.get_string(&property_name); - let value: String = if let Ok(str) = string { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getFloatProperty] [ERROR] Failed to get property name" - ); - return f64::NAN; - }; - let output = props.get_property(&value); - if let Some(output) = output { - match output { - Value::Float(val) => *val as jdouble, - _ => { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getFloatProperty] [WARN] Property is not a float" - ); - f64::NAN - } - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getFloatProperty] [WARN] Property not found" - ); - f64::NAN - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getFloatProperty] [ERROR] Failed to query entity for model properties" - ); - f64::NAN - } -} - - -/** - * Class: `com_dropbear_ffi_components_CustomPropertiesNative` - * - * Method: `getBoolProperty` - * - * Signature: `(JJLjava/lang/String;)Z` - * - * `JNIEXPORT jboolean JNICALL Java_com_dropbear_ffi_components_CustomPropertiesNative_getBoolProperty - * (JNIEnv *, jclass, jlong, jlong, jstring);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CustomPropertiesNative_getBoolProperty( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - property_name: JString, -) -> jboolean { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getBoolProperty] [ERROR] World pointer is null" - ); - return 0; - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - if let Ok(mut q) = world.query_one::<(&MeshRenderer, &CustomProperties)>(entity) - && let Some((_, props)) = q.get() - { - let string = env.get_string(&property_name); - let value: String = if let Ok(str) = string { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getBoolProperty] [ERROR] Failed to get property name" - ); - return 0; - }; - let output = props.get_property(&value); - if let Some(output) = output { - match output { - Value::Bool(val) => { - if *val { - 1 - } else { - 0 - } - } - _ => { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getBoolProperty] [WARN] Property is not a bool" - ); - 0 - } - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getBoolProperty] [WARN] Property not found" - ); - 0 - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getBoolProperty] [ERROR] Failed to query entity for model properties" - ); - 0 - } -} - -/** - * Class: `com_dropbear_ffi_components_CustomPropertiesNative` - * - * Method: `getVec3Property` - * - * Signature: `(JJLjava/lang/String;)[F` - * - * `JNIEXPORT jfloatArray JNICALL Java_com_dropbear_ffi_components_CustomPropertiesNative_getVec3Property - * (JNIEnv *, jclass, jlong, jlong, jstring);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CustomPropertiesNative_getVec3Property( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - property_name: JString, -) -> jfloatArray { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getVec3Property] [ERROR] World pointer is null" - ); - return std::ptr::null_mut(); - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - if let Ok(mut q) = world.query_one::<(&MeshRenderer, &CustomProperties)>(entity) - && let Some((_, props)) = q.get() - { - let string = env.get_string(&property_name); - let value: String = if let Ok(str) = string { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getVec3Property] [ERROR] Failed to get property name" - ); - return std::ptr::null_mut(); - }; - let output = props.get_property(&value); - if let Some(output) = output { - match output { - Value::Vec3([x, y, z]) => { - let arr = env.new_float_array(3); - if let Ok(arr) = arr { - let values = [*x, *y, *z]; - if env.set_float_array_region(&arr, 0, &values).is_ok() { - arr.into_raw() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getVec3Property] [ERROR] Failed to set array region" - ); - std::ptr::null_mut() - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getVec3Property] [ERROR] Failed to create float array" - ); - std::ptr::null_mut() - } - } - _ => { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getVec3Property] [WARN] Property is not a vec3" - ); - std::ptr::null_mut() - } - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getVec3Property] [WARN] Property not found" - ); - std::ptr::null_mut() - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_getVec3Property] [ERROR] Failed to query entity for model properties" - ); - std::ptr::null_mut() - } -} - - -/** - * Class: `com_dropbear_ffi_components_CustomPropertiesNative` - * - * Method: `setStringProperty` - * - * Signature: `(JJLjava/lang/String;Ljava/lang/String;)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_CustomPropertiesNative_setStringProperty - * (JNIEnv *, jclass, jlong, jlong, jstring, jstring);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CustomPropertiesNative_setStringProperty( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - property_name: JString, - value: JString, -) { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setStringProperty] [ERROR] World pointer is null" - ); - return; - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - - let key = env.get_string(&property_name); - let key: String = if let Ok(str) = key { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setStringProperty] [ERROR] Failed to get property name" - ); - return; - }; - - let string = env.get_string(&value); - let value: String = if let Ok(str) = string { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setStringProperty] [ERROR] Failed to get property name" - ); - return; - }; - - if let Ok((_, props)) = world.query_one_mut::<(&MeshRenderer, &mut CustomProperties)>(entity) { - props.set_property(key, Value::String(value)); - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setStringProperty] [ERROR] Failed to query entity for model properties" - ); - } -} - - -/** - * Class: `com_dropbear_ffi_components_CustomPropertiesNative` - * - * Method: `setIntProperty` - * - * Signature: `(JJLjava/lang/String;I)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_CustomPropertiesNative_setIntProperty - * (JNIEnv *, jclass, jlong, jlong, jstring, jint);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CustomPropertiesNative_setIntProperty( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - property_name: JString, - value: jint, -) { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!("[Java_com_dropbear_ffi_components_CustomPropertiesNative_setIntProperty] [ERROR] World pointer is null"); - return; - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - - let key = env.get_string(&property_name); - let key: String = if let Ok(str) = key { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setIntProperty] [ERROR] Failed to get property name" - ); - return; - }; - - if let Ok((_, props)) = world.query_one_mut::<(&MeshRenderer, &mut CustomProperties)>(entity) { - props.set_property(key, Value::Int(value as i64)); - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setIntProperty] [ERROR] Failed to query entity for model properties" - ); - } -} - -/** - * Class: `com_dropbear_ffi_components_CustomPropertiesNative` - * - * Method: `setLongProperty` - * - * Signature: `(JJLjava/lang/String;J)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_CustomPropertiesNative_setLongProperty - * (JNIEnv *, jclass, jlong, jlong, jstring, jlong);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CustomPropertiesNative_setLongProperty( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - property_name: JString, - value: jlong, -) { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setLongProperty] [ERROR] World pointer is null" - ); - return; - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - - let key = env.get_string(&property_name); - let key: String = if let Ok(str) = key { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setLongProperty] [ERROR] Failed to get property name" - ); - return; - }; - - if let Ok((_, props)) = world.query_one_mut::<(&MeshRenderer, &mut CustomProperties)>(entity) { - props.set_property(key, Value::Int(value)); - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setLongProperty] [ERROR] Failed to query entity for model properties" - ); - } -} - -/** - * Class: `com_dropbear_ffi_components_CustomPropertiesNative` - * - * Method: `setFloatProperty` - * - * Signature: `(JJLjava/lang/String;D)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_CustomPropertiesNative_setFloatProperty - * (JNIEnv *, jclass, jlong, jlong, jstring, jdouble);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CustomPropertiesNative_setFloatProperty( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - property_name: JString, - value: jdouble, -) { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setFloatProperty] [ERROR] World pointer is null" - ); - return; - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - - let key = env.get_string(&property_name); - let key: String = if let Ok(str) = key { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setFloatProperty] [ERROR] Failed to get property name" - ); - return; - }; - - if let Ok((_, props)) = world.query_one_mut::<(&MeshRenderer, &mut CustomProperties)>(entity) { - props.set_property(key, Value::Float(value)); - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setFloatProperty] [ERROR] Failed to query entity for model properties" - ); - } -} - -/** - * Class: `com_dropbear_ffi_components_CustomPropertiesNative` - * - * Method: `setBoolProperty` - * - * Signature: `(JJLjava/lang/String;Z)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_CustomPropertiesNative_setBoolProperty - * (JNIEnv *, jclass, jlong, jlong, jstring, jboolean);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CustomPropertiesNative_setBoolProperty( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - property_name: JString, - value: jboolean, -) { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setBoolProperty] [ERROR] World pointer is null" - ); - return; - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - - let key = env.get_string(&property_name); - let key: String = if let Ok(str) = key { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setBoolProperty] [ERROR] Failed to get property name" - ); - return; - }; - - let bool_value = value != 0; - - if let Ok((_, props)) = world.query_one_mut::<(&MeshRenderer, &mut CustomProperties)>(entity) { - props.set_property(key, Value::Bool(bool_value)); - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setBoolProperty] [ERROR] Failed to query entity for model properties" - ); - } -} - - -/** - * Class: `com_dropbear_ffi_components_CustomPropertiesNative` - * - * Method: `setVec3Property` - * - * Signature: `(JJLjava/lang/String;[F)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_CustomPropertiesNative_setVec3Property - * (JNIEnv *, jclass, jlong, jlong, jstring, jfloatArray);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_CustomPropertiesNative_setVec3Property( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - property_name: JString, - value: jfloatArray, -) { - let world = world_handle as *mut World; - if world.is_null() { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setVec3Property] [ERROR] World pointer is null" - ); - return; - } - - if value.is_null() { - eprintln!("[Java_com_dropbear_ffi_components_CustomPropertiesNative_setVec3Property] [ERROR] Value array is null"); - return; - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - #[allow(unused_unsafe)] - let val = unsafe { value }; - let array = unsafe { JPrimitiveArray::from_raw(val) }; - - let key = env.get_string(&property_name); - let key: String = if let Ok(str) = key { - let value = str.to_string_lossy(); - value.to_string() - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setVec3Property] [ERROR] Failed to get property name" - ); - return; - }; - - let length = env.get_array_length(&array); - - if let Ok(length) = length { - if length != 3 { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setVec3Property] [ERROR] Vec3 array must have exactly 3 elements, got {}", - length - ); - return; - } - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setVec3Property] [ERROR] Failed to get array length" - ); - return; - } - - let mut values = [0.0f32; 3]; - if env.get_float_array_region(&array, 0, &mut values).is_err() { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setVec3Property] [ERROR] Failed to get array region" - ); - return; - } - - if let Ok((_, props)) = world.query_one_mut::<(&MeshRenderer, &mut CustomProperties)>(entity) { - props.set_property(key, Value::Vec3(values)); - } else { - eprintln!( - "[Java_com_dropbear_ffi_components_CustomPropertiesNative_setVec3Property] [ERROR] Failed to query entity for model properties" - ); - } -} @@ -1,367 +0,0 @@ -#![allow(non_snake_case)] - -use glam::{DQuat, DVec3}; -use hecs::World; -use jni::JNIEnv; -use jni::objects::{JClass, JObject, JValue}; -use jni::sys::{jclass, jlong, jobject}; -use dropbear_engine::entity::{EntityTransform, Transform}; -use crate::convert_jlong_to_entity; -use crate::hierarchy::EntityTransformExt; - -/** - * Class: `com_dropbear_ffi_components_EntityTransformNative` - * - * Method: `getTransform` - * - * Signature: `(JJ)Lcom/dropbear/EntityTransform;` - * - * `JNIEXPORT jobject JNICALL Java_com_dropbear_ffi_components_EntityTransformNative_getTransform - * (JNIEnv *, jclass, jlong, jlong);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_EntityTransformNative_getTransform( - mut env: JNIEnv, - _class: jclass, - world_handle: jlong, - entity_id: jlong, -) -> JObject { - let world = world_handle as *mut World; - - if world.is_null() { - println!("[Java_com_dropbear_ffi_components_EntityTransformNative_getTransform] [ERROR] World pointer is null"); - return JObject::null(); - } - - let world = unsafe { &mut *world }; - - let entity = convert_jlong_to_entity!(entity_id); - - if let Ok(mut q) = world.query_one::<&EntityTransform>(entity) - && let Some(transform) = q.get() - { - let wt = *transform.world(); - - let transform_class = match env.find_class("com/dropbear/math/Transform") { - Ok(c) => c, - Err(_) => return JObject::null(), - }; - - let world_transform_java = match env.new_object( - &transform_class, - "(DDDDDDDDDD)V", - &[ - wt.position.x.into(), - wt.position.y.into(), - wt.position.z.into(), - wt.rotation.x.into(), - wt.rotation.y.into(), - wt.rotation.z.into(), - wt.rotation.w.into(), - wt.scale.x.into(), - wt.scale.y.into(), - wt.scale.z.into(), - ], - ) { - Ok(java_transform) => java_transform, - Err(_) => { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_getTransform] [ERROR] Failed to create world transform object" - ); - return JObject::null(); - } - }; - - let lt = *transform.local(); - - let local_transform_java = match env.new_object( - &transform_class, - "(DDDDDDDDDD)V", - &[ - lt.position.x.into(), - lt.position.y.into(), - lt.position.z.into(), - lt.rotation.x.into(), - lt.rotation.y.into(), - lt.rotation.z.into(), - lt.rotation.w.into(), - lt.scale.x.into(), - lt.scale.y.into(), - lt.scale.z.into(), - ], - ) { - Ok(java_transform) => java_transform, - Err(_) => { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_getTransform] [ERROR] Failed to create local transform object" - ); - return JObject::null(); - } - }; - - let entity_transform_class = match env.find_class("com/dropbear/EntityTransform") { - Ok(c) => c, - Err(_) => return JObject::null(), - }; - - return match env.new_object( - &entity_transform_class, - "(Lcom/dropbear/math/Transform;Lcom/dropbear/math/Transform;)V", - &[ - JValue::Object(&local_transform_java), - JValue::Object(&world_transform_java), - ], - ) { - Ok(java_transform) => java_transform, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_getTransform] [ERROR] Failed to create Transform object: {}", - e - ); - JObject::null() - } - }; - } - - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_getTransform] [ERROR] Failed to query for transform value for entity: {}", - entity_id - ); - JObject::null() -} - -/** - * Class: com_dropbear_ffi_components_EntityTransformNative - * - * Method: propagateTransform - * - * Signature: (JJ)Lcom/dropbear/math/Transform; - * - * `JNIEXPORT jobject JNICALL Java_com_dropbear_ffi_components_EntityTransformNative_propagateTransform - * (JNIEnv *, jclass, jlong, jlong);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_EntityTransformNative_propagateTransform( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, -) -> jobject { - let world = world_handle as *mut World; - - if world.is_null() { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_propagateTransform] [ERROR] World pointer is null" - ); - return std::ptr::null_mut(); - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - - if let Ok(mut q) = world.query_one::<&mut EntityTransform>(entity) { - if let Some(entity_transform) = q.get() { - let new_world = entity_transform.propagate(world, entity); - - let transform_class = match env.find_class("com/dropbear/math/Transform") { - Ok(c) => c, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_propagateTransform] [ERROR] Failed to find Transform class: {:?}", - e - ); - return std::ptr::null_mut(); - } - }; - - let transform_obj = match env.new_object( - &transform_class, - "(DDDDDDDDDD)V", - &[ - new_world.position.x.into(), - new_world.position.y.into(), - new_world.position.z.into(), - new_world.rotation.x.into(), - new_world.rotation.y.into(), - new_world.rotation.z.into(), - new_world.rotation.w.into(), - new_world.scale.x.into(), - new_world.scale.y.into(), - new_world.scale.z.into(), - ], - ) { - Ok(obj) => obj, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_propagateTransform] [ERROR] Failed to create Transform object: {:?}", - e - ); - return std::ptr::null_mut(); - } - }; - - transform_obj.into_raw() - } else { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_propagateTransform] [ERROR] Failed to get entity transform" - ); - std::ptr::null_mut() - } - } else { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_propagateTransform] [ERROR] Entity does not have EntityTransform component" - ); - std::ptr::null_mut() - } -} - -/** - * Class: `com_dropbear_ffi_components_EntityTransformNative` - * - * Method: `setTransform` - * - * Signature: `(JJLcom/dropbear/EntityTransform;)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_EntityTransformNative_setTransform - * (JNIEnv *, jclass, jlong, jlong, jobject);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_EntityTransformNative_setTransform( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - entity_transform_obj: JObject, -) { - let world = world_handle as *mut World; - - if world.is_null() { - println!("[Java_com_dropbear_ffi_components_EntityTransformNative_setTransform] [ERROR] World pointer is null"); - return; - } - - let world = unsafe { &mut *world }; - let entity = convert_jlong_to_entity!(entity_id); - - let extract_transform = |env: &mut JNIEnv, transform_obj: &JObject| -> Option<Transform> { - let get_number_field = |env: &mut JNIEnv, obj: &JObject, field_name: &str| -> f64 { - match env.get_field(obj, field_name, "Ljava/lang/Number;") { - Ok(v) => match v.l() { - Ok(num_obj) => match env.call_method(&num_obj, "doubleValue", "()D", &[]) { - Ok(result) => result.d().unwrap_or(0.0), - Err(_) => 0.0, - }, - Err(_) => 0.0, - }, - Err(_) => 0.0, - } - }; - - let position_obj: JObject = - match env.get_field(transform_obj, "position", "Lcom/dropbear/math/Vector3;") { - Ok(v) => v.l().ok()?, - Err(_) => return None, - }; - - let rotation_obj: JObject = - match env.get_field(transform_obj, "rotation", "Lcom/dropbear/math/Quaternion;") { - Ok(v) => v.l().ok()?, - Err(_) => return None, - }; - - let scale_obj: JObject = - match env.get_field(transform_obj, "scale", "Lcom/dropbear/math/Vector3;") { - Ok(v) => v.l().ok()?, - Err(_) => return None, - }; - - let px = get_number_field(env, &position_obj, "x"); - let py = get_number_field(env, &position_obj, "y"); - let pz = get_number_field(env, &position_obj, "z"); - - let rx = get_number_field(env, &rotation_obj, "x"); - let ry = get_number_field(env, &rotation_obj, "y"); - let rz = get_number_field(env, &rotation_obj, "z"); - let rw = get_number_field(env, &rotation_obj, "w"); - - let sx = get_number_field(env, &scale_obj, "x"); - let sy = get_number_field(env, &scale_obj, "y"); - let sz = get_number_field(env, &scale_obj, "z"); - - Some(Transform { - position: DVec3::new(px, py, pz), - rotation: DQuat::from_xyzw(rx, ry, rz, rw), - scale: DVec3::new(sx, sy, sz), - }) - }; - - let local_obj: JObject = match env.get_field( - &entity_transform_obj, - "local", - "Lcom/dropbear/math/Transform;", - ) { - Ok(v) => v.l().unwrap_or_else(|_| JObject::null()), - Err(_) => { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_setTransform] [ERROR] Failed to get local transform field" - ); - return; - } - }; - - let world_obj: JObject = match env.get_field( - &entity_transform_obj, - "world", - "Lcom/dropbear/math/Transform;", - ) { - Ok(v) => v.l().unwrap_or_else(|_| JObject::null()), - Err(_) => { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_setTransform] [ERROR] Failed to get world transform field" - ); - return; - } - }; - - if local_obj.is_null() || world_obj.is_null() { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_setTransform] [ERROR] local or world transform is null" - ); - return; - } - - let local_transform = match extract_transform(&mut env, &local_obj) { - Some(t) => t, - None => { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_setTransform] [ERROR] Failed to extract local transform" - ); - return; - } - }; - - let world_transform = match extract_transform(&mut env, &world_obj) { - Some(t) => t, - None => { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_setTransform] [ERROR] Failed to extract world transform" - ); - return; - } - }; - - if let Ok(mut q) = world.query_one::<&mut EntityTransform>(entity) { - if let Some(entity_transform) = q.get() { - *entity_transform.local_mut() = local_transform; - *entity_transform.world_mut() = world_transform; - } else { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_setTransform] [ERROR] Failed to get entity transform" - ); - } - } else { - println!( - "[Java_com_dropbear_ffi_components_EntityTransformNative_setTransform] [ERROR] Entity does not have EntityTransform component" - ); - } -} @@ -1,132 +0,0 @@ -#![allow(non_snake_case)] - -use hecs::World; -use jni::JNIEnv; -use jni::objects::{JClass, JString}; -use jni::sys::{jlong, jlongArray}; -use crate::{convert_jlong_to_entity, convert_jstring, convert_ptr}; -use crate::hierarchy::{Children, Parent}; -use crate::ptr::WorldPtr; -use crate::states::Label; - -/** - * Class: `com_dropbear_ffi_components_HierarchyNative` - * - * Method: `getChildren` - * - * Signature: `(JJ)[J` - * - * `JNIEXPORT jlongArray JNICALL Java_com_dropbear_ffi_components_HierarchyNative_getChildren - * (JNIEnv *, jclass, jlong, jlong);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_HierarchyNative_getChildren( - env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, -) -> jlongArray { - let world = convert_ptr!(world_handle, WorldPtr => World); - let entity = convert_jlong_to_entity!(entity_id); - - let entities = if let Ok(mut q) = world.query_one::<&Children>(entity) - && let Some(children) = q.get() - { - let children = children.children(); - let mut array = vec![]; - for child in children { - array.push(child.to_bits().get() as i64); - } - array - } else { - vec![] - }; - - let array = match env.new_long_array(entities.len() as i32) { - Ok(array) => array, - Err(e) => { - return crate::ffi_error_return!("Unable to create a new long array: {}", e); - } - }; - - if let Err(e) = env.set_long_array_region(&array, 0, &entities) { - return crate::ffi_error_return!("Unable to populate long array: {}", e); - } - - array.into_raw() -} - -/** - * Class: `com_dropbear_ffi_components_HierarchyNative` - * - * Method: `getChildByLabel` - * - * Signature: `(JJLjava/lang/String;)J` - * - * `JNIEXPORT jlong JNICALL Java_com_dropbear_ffi_components_HierarchyNative_getChildByLabel - * (JNIEnv *, jclass, jlong, jlong, jstring);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_HierarchyNative_getChildByLabel( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - label: JString, -) -> jlong { - let world = convert_ptr!(world_handle, WorldPtr => World); - let entity = convert_jlong_to_entity!(entity_id); - let target = convert_jstring!(env, label); - - if let Ok(mut q) = world.query_one::<&Children>(entity) - && let Some(children) = q.get() - { - for child in children.children() { - if let Ok(label) = world.get::<&Label>(entity) { - if label.as_str() == target { - return child.to_bits().get() as jlong; - } - } else { - // skip if error or no entity - continue; - } - } - } else { - // no children exist for the entity - return -2 as jlong; - }; - - // no children exist with that label - -2 as jlong -} - -/** - * Class: com_dropbear_ffi_components_HierarchyNative - * - * Method: getParent - * - * Signature: (JJ)J - * - * `JNIEXPORT jlong JNICALL Java_com_dropbear_ffi_components_HierarchyNative_getParent - * (JNIEnv *, jclass, jlong, jlong);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_HierarchyNative_getParent( - _env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, -) -> jlong { - let world = convert_ptr!(world_handle, WorldPtr => World); - let entity = convert_jlong_to_entity!(entity_id); - - if let Ok(mut q) = world.query_one::<&Parent>(entity) { - if let Some(parent) = q.get() { - parent.parent().to_bits().get() as jlong - } else { - -2 as jlong - } - } else { - crate::ffi_error_return!("No entity exists") - } -} @@ -1,45 +0,0 @@ -#![allow(non_snake_case)] - -use hecs::World; -use jni::JNIEnv; -use jni::sys::{jclass, jlong, jstring}; -use crate::{convert_jlong_to_entity, ffi_error_return}; -use crate::states::Label; - -/** - * Class: `com_dropbear_ffi_components_LabelNative` - * - * Method: `getEntityLabel` - * - * Signature: `(JJ)Ljava/lang/String;` - * - * `JNIEXPORT jstring JNICALL Java_com_dropbear_ffi_components_LabelNative_getEntityLabel - * (JNIEnv *, jclass, jlong, jlong);` -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_LabelNative_getEntityLabel( - env: JNIEnv, - _class: jclass, - world_handle: jlong, - entity_id: jlong, -) -> jstring { - let world = world_handle as *mut World; - - if world.is_null() { - return ffi_error_return!("[Java_com_dropbear_ffi_JNINative_getTransform] [ERROR] World pointer is null"); - } - - let world = unsafe { &mut *world }; - - let entity = convert_jlong_to_entity!(entity_id); - - if let Ok(mut q) = world.query_one::<&Label>(entity) && let Some(label) = q.get() { - let label_str = label.as_str(); - let Ok(str) = env.new_string(label_str) else { - return ffi_error_return!("[Java_com_dropbear_ffi_JNINative_getTransform] [ERROR] Unable to create new string from label"); - }; - return str.into_raw(); - } - - ffi_error_return!("[Java_com_dropbear_ffi_JNINative_getTransform] [ERROR] Unable to locate Label for player, likely engine bug") -} @@ -1,644 +0,0 @@ -#![allow(non_snake_case)] - -use std::collections::{HashMap, HashSet}; -use std::sync::Arc; -use hecs::World; -use jni::JNIEnv; -use jni::objects::{JClass, JObject, JString}; -use jni::sys::{jboolean, jlong, jobjectArray, jstring}; -use parking_lot::Mutex; -use dropbear_engine::asset::{AssetHandle, AssetRegistry, ASSET_REGISTRY}; -use dropbear_engine::asset::PointerKind::Const; -use dropbear_engine::entity::MeshRenderer; -use dropbear_engine::model::Model; -use crate::{convert_jlong_to_entity, convert_jstring, convert_ptr}; -use crate::ptr::{AssetRegistryPtr, WorldPtr}; - -/** - * Class: `com_dropbear_ffi_components_MeshRendererNative` - * - * Method: `getModel` - * - * Signature: `(JJ)J` - * - * JNIEXPORT jlong JNICALL Java_com_dropbear_ffi_components_MeshRendererNative_getModel - * (JNIEnv *, jclass, jlong, jlong); -*/ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_MeshRendererNative_getModel( - _env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, -) -> jlong { - let world = world_handle as WorldPtr; - if world.is_null() { - println!("[Java_com_dropbear_ffi_components_MeshRendererNative_getModel] [ERROR] World pointer is null"); - return -1; - } - - let world = unsafe { &*world }; - let entity = convert_jlong_to_entity!(entity_id); - - if let Ok(mut q) = world.query_one::<&MeshRenderer>(entity) - && let Some(model) = q.get() - { - let handle = model.asset_handle(); - handle.raw() as jlong - } else { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_getModel] [ERROR] Unable to find entity in world" - ); - -1 - } -} - -/** - * Class: `com_dropbear_ffi_components_MeshRendererNative` - * - * Method: `setModel` - * - * Signature: `(JJJJ)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_MeshRendererNative_setModel - * (JNIEnv *, jclass, jlong, jlong, jlong, jlong);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_MeshRendererNative_setModel( - _env: JNIEnv, - _class: JClass, - world_handle: jlong, - asset_handle: jlong, - entity_id: jlong, - model_handle: jlong, -) { - let world = world_handle as WorldPtr; - if world.is_null() { - println!("[Java_com_dropbear_ffi_components_MeshRendererNative_setModel] [ERROR] World pointer is null"); - return; - } - - let asset = asset_handle as AssetRegistryPtr; - if asset.is_null() { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setModel] [ERROR] Asset registry pointer is null" - ); - return; - } - - let world = unsafe { &*world }; - let asset = unsafe { &*asset }; - let entity = convert_jlong_to_entity!(entity_id); - - if let Ok(mut q) = world.query_one::<&mut MeshRenderer>(entity) - && let Some(model) = q.get() - { - let asset_handle = AssetHandle::new(model_handle as u64); - if !asset.contains_handle(asset_handle) { - println!("[Java_com_dropbear_ffi_components_MeshRendererNative_setModel] [ERROR] Invalid model handle"); - return; - } - if let Err(e) = model.set_asset_handle_raw(asset, asset_handle) { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setModel] [ERROR] Unable to set model: {}", - e - ); - } - } -} - -/** - * Class: `com_dropbear_ffi_components_MeshRendererNative` - * - * Method: `isModelHandle` - * - * Signature: `(JJ)Z` - * - * `JNIEXPORT jboolean JNICALL Java_com_dropbear_ffi_components_MeshRendererNative_isModelHandle - * (JNIEnv *, jclass, jlong, jlong);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_MeshRendererNative_isModelHandle( - _env: JNIEnv, - _class: JClass, - asset_handle: jlong, - model_id: jlong, -) -> jboolean { - let asset = convert_ptr!(asset_handle, AssetRegistryPtr => AssetRegistry); - - asset - .contains_handle(AssetHandle::new(model_id as u64)) - .into() -} - -/** - * Class: `com_dropbear_ffi_components_MeshRendererNative` - * - * Method: `isUsingModel` - * - * Signature: `(JJJ)Z` - * `JNIEXPORT jboolean JNICALL Java_com_dropbear_ffi_components_MeshRendererNative_isUsingModel - * (JNIEnv *, jclass, jlong, jlong, jlong);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_MeshRendererNative_isUsingModel( - _env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - model_handle: jlong, -) -> jboolean { - let world = convert_ptr!(world_handle, WorldPtr => World); - let entity = convert_jlong_to_entity!(entity_id); - - let handle = AssetHandle::new(model_handle as u64); - if let Ok(mut q) = world.query_one::<&MeshRenderer>(entity) - && let Some(model) = q.get() - { - if model.asset_handle() == handle { - true.into() - } else { - false.into() - } - } else { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_isUsingModel] [ERROR] Unable to find entity in world" - ); - false.into() - } -} - - -/** - * Class: `com_dropbear_ffi_components_MeshRendererNative` - * - * Method: `getTexture` - * - * Signature: `(JJJLjava/lang/String;)J` - * - * `JNIEXPORT jlong JNICALL Java_com_dropbear_ffi_components_MeshRendererNative_getTexture - * (JNIEnv *, jclass, jlong, jlong, jlong, jstring);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_MeshRendererNative_getTexture( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - asset_handle: jlong, - entity_id: jlong, - name: JString, -) -> jlong { - let world = world_handle as WorldPtr; - if world.is_null() { - println!("[Java_com_dropbear_ffi_components_MeshRendererNative_getTexture] [ERROR] World pointer is null"); - return -1; - } - - let world = unsafe { &*world }; - - let asset = convert_ptr!(asset_handle, AssetRegistryPtr => AssetRegistry); - let entity = convert_jlong_to_entity!(entity_id); - - if let Ok(mut q) = world.query_one::<&MeshRenderer>(entity) - && let Some(mesh) = q.get() - { - let str = convert_jstring!(env, name); - if let Some(handle) = mesh.material_handle_raw(asset, str.as_str()) { - handle.raw() as jlong - } else { - println!("[Java_com_dropbear_ffi_components_MeshRendererNative_getTexture] [ERROR] Invalid texture handle"); - 0 - } - } else { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_getTexture] [ERROR] Unable to find entity in world" - ); - 0 - } -} - -/** - * Class: `com_dropbear_ffi_components_MeshRendererNative` - * - * Method: `getTextureName` - * - * Signature: `(JJ)Ljava/lang/String;` - * - * `JNIEXPORT jstring JNICALL Java_com_dropbear_ffi_components_MeshRendererNative_getTextureName - * (JNIEnv *, jclass, jlong, jlong);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_MeshRendererNative_getTextureName( - env: JNIEnv, - _class: JClass, - asset_handle: jlong, - texture_id: jlong, -) -> jstring { - let asset = convert_ptr!(asset_handle, AssetRegistryPtr => AssetRegistry); - - let texture_id = AssetHandle::new(texture_id as u64); - asset.get_material(texture_id).map_or_else( - || { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_getTextureName] [ERROR] Invalid texture handle" - ); - return std::ptr::null_mut(); - }, - |material| { - let Ok(str) = env.new_string(material.name.as_str()) else { - return std::ptr::null_mut(); - }; - - str.into_raw() - }, - ) -} - -/** - * Class: `com_dropbear_ffi_components_MeshRendererNative` - * - * Method: `setTexture` - * - * Signature: `(JJJLjava/lang/String;J)V` - * - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_MeshRendererNative_setTexture - * (JNIEnv *, jclass, jlong, jlong, jlong, jstring, jlong);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_MeshRendererNative_setTexture( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - asset_handle: jlong, - entity_id: jlong, - old_material_name: JString, - new_texture_handle: jlong, -) { - let world = world_handle as WorldPtr; - if world.is_null() { - println!("[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] World pointer is null"); - return; - } - - let asset = asset_handle as AssetRegistryPtr; - if asset.is_null() { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Asset registry pointer is null" - ); - return; - } - - let asset = unsafe { &*asset }; - - let world = unsafe { &*world }; - let entity = convert_jlong_to_entity!(entity_id); - - match world.query_one::<&mut MeshRenderer>(entity) { - Ok(mut query) => { - let Some(renderer) = query.get() else { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Entity does not have a MeshRenderer component" - ); - return; - }; - - let Some(cache) = asset.get_pointer(Const("model_cache")) else { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Asset registry does not contain model cache" - ); - return; - }; - - let cache = cache as *const Mutex<HashMap<String, Arc<Model>>>; - let cache = unsafe { &*cache }; - - let jni_result = env.get_string(&old_material_name); - let target_identifier = match jni_result { - Ok(java_string) => match java_string.to_str() { - Ok(rust_str) => rust_str.to_string(), - Err(e) => { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Failed to convert Java string to Rust string: {}", - e - ); - return; - } - }, - Err(e) => { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Failed to get string from JNI: {}", - e - ); - return; - } - }; - - let resolved_target_name = renderer - .resolve_texture_identifier(&target_identifier) - .map(|name| name.to_string()) - .or_else(|| { - let model = renderer.model(); - let model_id = renderer.model_id(); - - if model - .materials - .iter() - .any(|material| material.name == target_identifier) - { - return Some(target_identifier.clone()); - } - - model.materials.iter().find_map(|material| { - if material.name == target_identifier { - return Some(material.name.clone()); - } - - let registry_reference = ASSET_REGISTRY - .material_handle(model_id, &material.name) - .and_then(|handle| ASSET_REGISTRY.material_reference_for_handle(handle)) - .and_then(|reference| reference.as_uri().map(|uri| uri.to_string())); - - if registry_reference - .as_ref() - .map(|value| value == &target_identifier) - .unwrap_or(false) - { - return Some(material.name.clone()); - } - - if material - .texture_tag - .as_ref() - .map(|tag| tag == &target_identifier) - .unwrap_or(false) - { - return Some(material.name.clone()); - } - - None - }) - }); - - let Some(target_material) = resolved_target_name else { - let message = format!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Unable to resolve material '{}' on model '{}'", - target_identifier, - renderer.model().label - ); - println!("{}", message); - return; - }; - - let handle = AssetHandle::new(new_texture_handle as u64); - - if !asset.contains_handle(handle) { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Invalid texture handle: {}", - new_texture_handle - ); - return; - } - - if !asset.is_material(handle) { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Handle {} does not refer to a material", - new_texture_handle - ); - return; - } - - let Some(material) = asset.get_material(handle) else { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Invalid texture handle" - ); - return; - }; - - let Some(owner_model_id) = asset.material_owner(handle) else { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Unable to determine owning model for material handle {}", - new_texture_handle - ); - return; - }; - - let Some(owner_model_handle) = asset.model_handle_from_id(owner_model_id) else { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Unable to resolve model handle for owner id {:?}", - owner_model_id - ); - return; - }; - - let Some(source_reference) = asset.model_reference_for_handle(owner_model_handle) - else { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Unable to resolve model reference for handle {}", - owner_model_handle.raw() - ); - return; - }; - - if let Err(e) = renderer.apply_material_override_raw( - asset, - cache, - target_material.as_str(), - source_reference, - material.name.as_str(), - ) { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Failed to apply material override: {}", - e - ); - } - } - Err(err) => { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_setTexture] [ERROR] Unable to query MeshRenderer: {}", - err - ); - } - } -} - -/** - * Class: `com_dropbear_ffi_components_MeshRendererNative` - * - * Method: `isTextureHandle` - * - * Signature: `(JJ)Z` - * - * - * `JNIEXPORT jboolean JNICALL Java_com_dropbear_ffi_components_MeshRendererNative_isTextureHandle - * (JNIEnv *, jclass, jlong, jlong);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_MeshRendererNative_isTextureHandle( - _env: JNIEnv, - _class: JClass, - asset_handle: jlong, - texture_id: jlong, -) -> jboolean { - let asset = convert_ptr!(asset_handle, AssetRegistryPtr => AssetRegistry); - let texture_id = AssetHandle::new(texture_id as u64); - if asset.is_material(texture_id) { - true.into() - } else { - false.into() - } -} - -/** - * Class: `com_dropbear_ffi_components_MeshRendererNative` - * - * Method: `isUsingTexture` - * - * Signature: `(JJJ)Z` - * - * `JNIEXPORT jboolean JNICALL Java_com_dropbear_ffi_components_MeshRendererNative_isUsingTexture - * (JNIEnv *, jclass, jlong, jlong, jlong);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_MeshRendererNative_isUsingTexture( - _env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, - texture_handle: jlong, -) -> jboolean { - let world = convert_ptr!(world_handle, WorldPtr => World); - let entity = convert_jlong_to_entity!(entity_id); - - if let Ok(mut q) = world.query_one::<&MeshRenderer>(entity) - && let Some(mesh) = q.get() - { - mesh.contains_material_handle(AssetHandle::new(texture_handle as u64)) - .into() - } else { - println!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_isUsingTexture] [ERROR] Unable to find entity in world" - ); - false.into() - } -} - -/** - * Class: `com_dropbear_ffi_components_MeshRendererNative` - * - * Method: `getAllTextures` - * - * Signature: `(JJ)[Ljava/lang/String;` - * - * `JNIEXPORT jobjectArray JNICALL Java_com_dropbear_ffi_components_MeshRendererNative_getAllTextures - * (JNIEnv *, jclass, jlong, jlong);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_MeshRendererNative_getAllTextures( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - entity_id: jlong, -) -> jobjectArray { - let world = convert_ptr!(world_handle, WorldPtr => World); - let entity = convert_jlong_to_entity!(entity_id); - - let mut query = match world.query_one::<&mut MeshRenderer>(entity) { - Ok(query) => query, - Err(e) => { - let message = format!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_getAllTextures] [ERROR] Failed to query entity: {}", - e - ); - println!("{}", message); - return std::ptr::null_mut(); - } - }; - - let renderer = match query.get() { - Some(renderer) => renderer, - None => { - let message = "[Java_com_dropbear_ffi_components_MeshRendererNative_getAllTextures] [ERROR] Entity does not have a MeshRenderer component"; - println!("{}", message); - return std::ptr::null_mut(); - } - }; - - renderer.clear_texture_identifier_cache(); - - let model = renderer.model(); - let model_id = renderer.model_id(); - - let mut seen = HashSet::new(); - let mut textures = Vec::new(); - - for material in &model.materials { - renderer.register_texture_identifier(material.name.clone(), material.name.clone()); - if let Some(tag) = &material.texture_tag { - renderer.register_texture_identifier(tag.clone(), material.name.clone()); - } - - let reference = ASSET_REGISTRY - .material_handle(model_id, &material.name) - .and_then(|handle| ASSET_REGISTRY.material_reference_for_handle(handle)) - .and_then(|reference| reference.as_uri().map(|uri| uri.to_string())) - .or_else(|| material.texture_tag.clone()) - .unwrap_or_else(|| material.name.clone()); - - if seen.insert(reference.clone()) { - renderer.register_texture_identifier(reference.clone(), material.name.clone()); - textures.push(reference); - } - } - - let string_class = match env.find_class("java/lang/String") { - Ok(class) => class, - Err(e) => { - let message = format!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_getAllTextures] [ERROR] Failed to locate java/lang/String: {}", - e - ); - println!("{}", message); - return std::ptr::null_mut(); - } - }; - - let array = match env.new_object_array(textures.len() as i32, string_class, JObject::null()) { - Ok(array) => array, - Err(e) => { - let message = format!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_getAllTextures] [ERROR] Failed to allocate string array: {}", - e - ); - println!("{}", message); - return std::ptr::null_mut(); - } - }; - - for (index, value) in textures.iter().enumerate() { - let java_string = match env.new_string(value) { - Ok(string) => string, - Err(e) => { - let message = format!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_getAllTextures] [ERROR] Failed to create Java string: {}", - e - ); - println!("{}", message); - return std::ptr::null_mut(); - } - }; - - if let Err(e) = - env.set_object_array_element(&array, index as i32, JObject::from(java_string)) - { - let message = format!( - "[Java_com_dropbear_ffi_components_MeshRendererNative_getAllTextures] [ERROR] Failed to set array element: {}", - e - ); - println!("{}", message); - return std::ptr::null_mut(); - } - } - - array.into_raw() -} @@ -1,144 +0,0 @@ -use hecs::World; -use jni::JNIEnv; -use jni::objects::{JClass, JObject}; -use jni::sys::{jdouble, jlong, jobjectArray}; -use rapier3d::na::Vector3; -use rapier3d::prelude::RigidBodyType; -use crate::{convert_jlong_to_entity, convert_ptr}; -use crate::physics::PhysicsState; -use crate::physics::rigidbody::{RigidBody, RigidBodyMode}; -use crate::states::Label; - -/** - * Class: `com_dropbear_ffi_components_RigidBodyNative` - * - * Method: `applyImpulse` - * - * Signature: `(JLcom/dropbear/physics/Index;DDD)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_RigidBodyNative_applyImpulse - * (JNIEnv *, jclass, jlong, jobject, jdouble, jdouble, jdouble);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_RigidBodyNative_applyImpulse( - mut env: JNIEnv, - _class: JClass, - physics_handle: jlong, - index_obj: JObject, - x: jdouble, - y: jdouble, - z: jdouble, -) { - // TODO: Implementation -} - -/** - * Class: `com_dropbear_ffi_components_RigidBodyNative` - * - * Method: `applyTorqueImpulse` - * - * Signature: `(JLcom/dropbear/physics/Index;DDD)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_RigidBodyNative_applyTorqueImpulse - * (JNIEnv *, jclass, jlong, jobject, jdouble, jdouble, jdouble);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_RigidBodyNative_applyTorqueImpulse( - mut env: JNIEnv, - _class: JClass, - physics_handle: jlong, - index_obj: JObject, - x: jdouble, - y: jdouble, - z: jdouble, -) { - // TODO: Implementation -} - -/** - * Class: `com_dropbear_ffi_components_RigidBodyNative` - * - * Method: `setRigidBody` - * - * Signature: `(JJLcom/dropbear/physics/RigidBody;)V` - * - * `JNIEXPORT void JNICALL Java_com_dropbear_ffi_components_RigidBodyNative_setRigidBody - * (JNIEnv *, jclass, jlong, jlong, jobject);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_RigidBodyNative_setRigidBody( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - physics_handle: jlong, - rigidbody_obj: JObject, -) { - let world = convert_ptr!(mut world_handle => World); - let physics = convert_ptr!(mut physics_handle => PhysicsState); - - RigidBody::from_jni(&mut env, &rigidbody_obj).map(|(handle, rb_data)| { - if let Some(rapier_body) = physics.bodies.get_mut(handle) { - let rapier_mode = match rb_data.mode { - RigidBodyMode::Dynamic => RigidBodyType::Dynamic, - RigidBodyMode::Fixed => RigidBodyType::Fixed, - RigidBodyMode::KinematicPosition => RigidBodyType::KinematicPositionBased, - RigidBodyMode::KinematicVelocity => RigidBodyType::KinematicVelocityBased, - }; - rapier_body.set_body_type(rapier_mode, true); - - rapier_body.set_gravity_scale(rb_data.gravity_scale, true); - rapier_body.set_linvel(Vector3::from(rb_data.linvel), true); - rapier_body.set_angvel(Vector3::from(rb_data.angvel), true); - rapier_body.set_linear_damping(rb_data.linear_damping); - rapier_body.set_angular_damping(rb_data.angular_damping); - - if !rb_data.can_sleep { - rapier_body.wake_up(true); - } - rapier_body.enable_ccd(rb_data.ccd_enabled); - - rapier_body.set_enabled_translations( - !rb_data.lock_translation.x, - !rb_data.lock_translation.y, - !rb_data.lock_translation.z, - true - ); - rapier_body.set_enabled_rotations( - !rb_data.lock_rotation.x, - !rb_data.lock_rotation.y, - !rb_data.lock_rotation.z, - true - ); - } else { - eprintln!("Attempted to set RigidBody with invalid handle: {:?}", handle); - } - - if let Some(ecs_entity) = rb_data.entity.locate_entity(&world) { - if let Ok(mut component) = world.get::<&mut RigidBody>(ecs_entity) { - *component = rb_data; - } - } - }).ok(); -} - -/** - * Class: `com_dropbear_ffi_components_RigidBodyNative` - * - * Method: `getChildColliders` - * - * Signature: `(JJLcom/dropbear/physics/Index;)[Lcom/dropbear/physics/Collider;` - * - * `JNIEXPORT jobjectArray JNICALL Java_com_dropbear_ffi_components_RigidBodyNative_getChildColliders - * (JNIEnv *, jclass, jlong, jlong, jobject);` - */ -#[unsafe(no_mangle)] -pub fn Java_com_dropbear_ffi_components_RigidBodyNative_getChildColliders( - mut env: JNIEnv, - _class: JClass, - world_handle: jlong, - physics_handle: jlong, - index_obj: JObject, -) -> jobjectArray { - // TODO: Implementation - std::ptr::null_mut() -} @@ -1,8 +0,0 @@ -pub mod CameraNative; -pub mod CustomPropertiesNative; -pub mod EntityTransformNative; -pub mod HierarchyNative; -pub mod LabelNative; -pub mod MeshRendererNative; -mod RigidBodyNative; -mod ColliderNative; @@ -11,7 +11,7 @@ const JAVA_MOUSE_BUTTON_MIDDLE: jint = 2; const JAVA_MOUSE_BUTTON_BACK: jint = 3; const JAVA_MOUSE_BUTTON_FORWARD: jint = 4; -pub fn java_button_to_rust(button_code: jint) -> Option<winit::event::MouseButton> { +pub fn Java_button_to_rust(button_code: jint) -> Option<winit::event::MouseButton> { match button_code { JAVA_MOUSE_BUTTON_LEFT => Some(winit::event::MouseButton::Left), JAVA_MOUSE_BUTTON_RIGHT => Some(winit::event::MouseButton::Right), @@ -381,7 +381,7 @@ fn load_symbol<T>( let mut last_err = None; for (idx, candidate) in candidates.iter().enumerate() { - match unsafe { library.get::<T>(candidate) } { + match unsafe { library.get::<T>(*candidate) } { Ok(symbol) => { if idx > 0 { log::warn!( @@ -538,6 +538,7 @@ pub enum DropbearNativeError { AssetNotFound = -21, /// When a handle has been inputted wrongly. InvalidHandle = -22, + /// When a physics object is not found PhysicsObjectNotFound = -23, /// The entity provided was invalid, likely not from [hecs::Entity::from_bits]. @@ -1,9 +0,0 @@ -#![allow(unsafe_op_in_unsafe_fn)] - -pub mod dropbear_common; -pub mod dropbear_math; -pub mod dropbear_utils; -pub mod components; -pub mod dropbear_engine; -pub mod dropbear_input; -pub mod dropbear_scene; @@ -1,229 +0,0 @@ -use std::ffi::{c_char, CStr, CString}; -use glam::DVec3; -use hecs::World; -use dropbear_engine::camera::Camera; -use crate::camera::{CameraComponent, CameraType}; -use crate::ptr::WorldPtr; -use crate::scripting::native::DropbearNativeError; -use crate::scripting::native::exports::dropbear_common::{DropbearNativeReturn, Handle}; -use crate::scripting::native::exports::dropbear_math::Vector3D; - -/// A camera that represents the [`Camera`] type in Rust in a C struct form. -#[repr(C)] -pub struct NativeCamera { - pub label: *const c_char, - pub entity_id: i64, - pub eye: Vector3D, - pub target: Vector3D, - pub up: Vector3D, - pub aspect: f64, - pub fov_y: f64, - pub znear: f64, - pub zfar: f64, - pub yaw: f64, - pub pitch: f64, - pub speed: f64, - pub sensitivity: f64, -} - -/// Fetches a camera from the world by label. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_camera( - world_ptr: *const World, - label: *const c_char, - out_camera: *mut NativeCamera, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() || out_camera.is_null() { - eprintln!("[dropbear_get_camera] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = unsafe { &*world_ptr }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s, - Err(_) => { - eprintln!("[dropbear_get_camera] [ERROR] Invalid UTF-8 in label"); - return DropbearNativeError::InvalidUTF8 as i32; - } - }; - - if let Some((id, (cam, comp))) = world - .query::<(&Camera, &CameraComponent)>() - .iter() - .find(|(_, (cam, _))| cam.label == label_str) - { - if matches!(comp.camera_type, CameraType::Debug) { - eprintln!("[dropbear_get_camera] [WARN] Querying a CameraType::Debug is illegal"); - return DropbearNativeError::NoSuchEntity as i32; - } - - let label_cstring = CString::new(cam.label.as_str()).unwrap(); - - unsafe { - (*out_camera).label = label_cstring.into_raw(); - (*out_camera).entity_id = id.id() as i64; - - (*out_camera).eye = Vector3D { - x: cam.eye.x, - y: cam.eye.y, - z: cam.eye.z, - }; - - (*out_camera).target = Vector3D { - x: cam.target.x, - y: cam.target.y, - z: cam.target.z, - }; - - (*out_camera).up = Vector3D { - x: cam.up.x, - y: cam.up.y, - z: cam.up.z, - }; - - (*out_camera).aspect = cam.aspect; - (*out_camera).fov_y = cam.settings.fov_y; - (*out_camera).znear = cam.znear; - (*out_camera).zfar = cam.zfar; - (*out_camera).yaw = cam.yaw; - (*out_camera).pitch = cam.pitch; - (*out_camera).speed = cam.settings.speed; - (*out_camera).sensitivity = cam.settings.sensitivity; - } - - return DropbearNativeError::Success as i32; - } - - eprintln!( - "[dropbear_get_camera] [ERROR] Camera with label '{}' not found", - label_str - ); - DropbearNativeError::EntityNotFound as i32 -} - -/// Fetches the camera attached to an entity as a component. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_attached_camera( - world_ptr: *const World, - entity_handle: Handle, - out_camera: *mut NativeCamera, -) -> i32 { - if world_ptr.is_null() || out_camera.is_null() { - eprintln!("[dropbear_get_attached_camera] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = unsafe { &*world_ptr }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - match world.query_one::<(&Camera, &CameraComponent)>(entity) { - Ok(mut q) => { - if let Some((cam, comp)) = q.get() { - if matches!(comp.camera_type, CameraType::Debug) { - eprintln!( - "[dropbear_get_attached_camera] [WARN] Querying a CameraType::Debug is illegal" - ); - return DropbearNativeError::NoSuchEntity as i32; - } - - let label_cstring = CString::new(cam.label.as_str()).unwrap(); - - unsafe { - (*out_camera).label = label_cstring.into_raw(); - (*out_camera).entity_id = entity_handle; - - (*out_camera).eye = Vector3D { - x: cam.eye.x, - y: cam.eye.y, - z: cam.eye.z, - }; - - (*out_camera).target = Vector3D { - x: cam.target.x, - y: cam.target.y, - z: cam.target.z, - }; - - (*out_camera).up = Vector3D { - x: cam.up.x, - y: cam.up.y, - z: cam.up.z, - }; - - (*out_camera).aspect = cam.aspect; - (*out_camera).fov_y = cam.settings.fov_y; - (*out_camera).znear = cam.znear; - (*out_camera).zfar = cam.zfar; - (*out_camera).yaw = cam.yaw; - (*out_camera).pitch = cam.pitch; - (*out_camera).speed = cam.settings.speed; - (*out_camera).sensitivity = cam.settings.sensitivity; - } - - 0 - } else { - eprintln!("[dropbear_get_attached_camera] [ERROR] Entity has no Camera component"); - DropbearNativeError::NoSuchEntity as i32 - } - } - Err(_) => { - eprintln!("[dropbear_get_attached_camera] [ERROR] Failed to query entity"); - DropbearNativeError::EntityNotFound as i32 - } - } -} - -/// Sets the camera attached to an entity as a component. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_set_camera( - world_ptr: WorldPtr, - camera: *const NativeCamera, -) -> i32 { - if world_ptr.is_null() || camera.is_null() { - eprintln!("[dropbear_set_camera] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = unsafe { &mut *(world_ptr) }; - let cam_data = unsafe { &*camera }; - - let entity = unsafe { world.find_entity_from_id(cam_data.entity_id as u32) }; - - match world.query_one_mut::<&mut Camera>(entity) { - Ok(cam) => { - cam.eye = DVec3::new( - cam_data.eye.x, - cam_data.eye.y, - cam_data.eye.z, - ); - - cam.target = DVec3::new( - cam_data.target.x, - cam_data.target.y, - cam_data.target.z, - ); - - cam.up = DVec3::new( - cam_data.up.x, - cam_data.up.y, - cam_data.up.z, - ); - - cam.aspect = cam_data.aspect; - cam.settings.fov_y = cam_data.fov_y; - cam.znear = cam_data.znear; - cam.zfar = cam_data.zfar; - cam.yaw = cam_data.yaw; - cam.pitch = cam_data.pitch; - cam.settings.speed = cam_data.speed; - cam.settings.sensitivity = cam_data.sensitivity; - - DropbearNativeError::Success as i32 - } - Err(_) => { - eprintln!("[dropbear_set_camera] [ERROR] Unable to query camera component"); - DropbearNativeError::EntityNotFound as i32 - } - } -} @@ -1,117 +0,0 @@ -use hecs::World; -use dropbear_engine::entity::EntityTransform; -use crate::hierarchy::EntityTransformExt; -use crate::scripting::native::{utils, DropbearNativeError}; -use crate::scripting::native::exports::dropbear_common::{DropbearNativeReturn, Handle}; -use crate::scripting::native::exports::dropbear_math::{NativeEntityTransform, NativeTransform}; - -/// Fetches the [`EntityTransform`] component of an entity. -/// -/// The [`EntityTransform`] returns a `world` and `local` transform. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_transform( - world_ptr: *const World, - entity_handle: i64, - out_transform: *mut NativeEntityTransform, -) -> DropbearNativeReturn { - if world_ptr.is_null() || out_transform.is_null() { - eprintln!("[dropbear_get_transform] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &*world_ptr; - let entity = world.find_entity_from_id(entity_handle as u32); - - match world.query_one::<&EntityTransform>(entity) { - Ok(mut q) => { - if let Some(transform) = q.get() { - unsafe { - utils::write_native_transform(&mut (*out_transform).local, transform.local()); - utils::write_native_transform(&mut (*out_transform).world, transform.world()); - } - DropbearNativeError::Success as i32 - } else { - eprintln!("[dropbear_get_transform] [ERROR] Entity has no transform component"); - DropbearNativeError::NoSuchComponent as i32 - } - } - Err(_) => { - eprintln!("[dropbear_get_transform] [ERROR] Failed to query entity"); - DropbearNativeError::QueryFailed as i32 - } - } -} - -/// Propagates a transform. -/// -/// To propagate a transform is to collect all the [`EntityTransform`] of the parent and self of the -/// querying entity. It then calculates the positions by summing them up (position, rotation and scale), -/// then returns that resulting [`Transform`] -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_propagate_transform( - world_ptr: *const World, - entity_handle: i64, - out_transform: *mut NativeTransform, -) -> DropbearNativeReturn { - if world_ptr.is_null() || out_transform.is_null() { - eprintln!("[dropbear_propagate_transform] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &mut *(world_ptr as *mut World); - let entity = world.find_entity_from_id(entity_handle as u32); - - match world.query_one::<&mut EntityTransform>(entity) { - Ok(mut q) => { - if let Some(transform) = q.get() { - let propagated = transform.propagate(world, entity); - unsafe { - utils::write_native_transform(&mut *out_transform, &propagated); - } - DropbearNativeError::Success as i32 - } else { - eprintln!( - "[dropbear_propagate_transform] [ERROR] Entity has no transform component" - ); - DropbearNativeError::NoSuchComponent as i32 - } - } - Err(_) => { - eprintln!("[dropbear_propagate_transform] [ERROR] Failed to query entity"); - DropbearNativeError::QueryFailed as i32 - } - } -} - -/// Sets the [`EntityTransform`] component for a specific entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_set_transform( - world_ptr: *const World, - entity_handle: Handle, - transform: NativeEntityTransform, -) -> DropbearNativeReturn { - if world_ptr.is_null() { - eprintln!("[dropbear_set_transform] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &mut *(world_ptr as *mut World); - let entity = world.find_entity_from_id(entity_handle as u32); - - match world.query_one::<&mut EntityTransform>(entity) { - Ok(mut q) => { - if let Some(entity_transform) = q.get() { - *entity_transform.local_mut() = utils::native_transform_to_transform(&transform.local); - *entity_transform.world_mut() = utils::native_transform_to_transform(&transform.world); - DropbearNativeError::Success as i32 - } else { - eprintln!("[dropbear_set_transform] [ERROR] Entity has no transform component"); - DropbearNativeError::NoSuchComponent as i32 - } - } - Err(_) => { - eprintln!("[dropbear_set_transform] [ERROR] Failed to query entity"); - DropbearNativeError::QueryFailed as i32 - } - } -} @@ -1,128 +0,0 @@ -use std::ffi::{c_char, CStr}; -use std::ptr; -use hecs::World; -use crate::hierarchy::{Children, Parent}; -use crate::scripting::native::DropbearNativeError; -use crate::scripting::native::exports::dropbear_common::{DropbearNativeReturn, Handle}; -use crate::states::Label; - -/// Fetches the children of the given entity. -/// -/// Returns an array of [`Handle`], or an [`ptr::null_mut()`] if no children of the entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_children( - world_ptr: *const World, - entity_id: Handle, - out_children: *mut *mut Handle, // array of handles - out_count: *mut usize, -) -> DropbearNativeReturn { - if world_ptr.is_null() || out_children.is_null() || out_count.is_null() { - eprintln!("[dropbear_get_children] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &*world_ptr; - let entity = world.find_entity_from_id(entity_id as u32); - - let children: Vec<i64> = match world.query_one::<&Children>(entity) { - Ok(mut q) => q - .get() - .map(|component| { - component - .children() - .iter() - .map(|child| child.id() as i64) - .collect() - }) - .unwrap_or_default(), - Err(_) => Vec::new(), - }; - - unsafe { - *out_count = children.len(); - } - - if children.is_empty() { - unsafe { *out_children = ptr::null_mut(); } - return DropbearNativeError::Success as i32; - } - - let mut boxed = children.into_boxed_slice(); - unsafe { - *out_children = boxed.as_mut_ptr(); - } - Box::leak(boxed); - DropbearNativeError::Success as i32 -} - -/// Fetches the child of the entity by a String label. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_child_by_label( - world_ptr: *const World, - entity_id: Handle, - label: *const c_char, - out_child: *mut Handle, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() || out_child.is_null() { - eprintln!("[dropbear_get_child_by_label] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &*world_ptr; - let entity = world.find_entity_from_id(entity_id as u32); - let target = match CStr::from_ptr(label).to_str() { - Ok(s) => s, - Err(_) => { - eprintln!("[dropbear_get_child_by_label] [ERROR] Invalid UTF-8 in label"); - return DropbearNativeError::InvalidUTF8 as i32; - } - }; - - match world.query_one::<&Children>(entity) { - Ok(mut q) => { - if let Some(children) = q.get() { - for child in children.children() { - if let Ok(label_comp) = world.get::<&Label>(*child) { - if label_comp.as_str() == target { - unsafe { - *out_child = child.id() as i64; - } - return DropbearNativeError::Success as i32; - } - } - } - } - DropbearNativeError::EntityNotFound as i32 - } - Err(_) => DropbearNativeError::QueryFailed as i32, - } -} - -/// Fetches the parent entity ID of the given entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_parent( - world_ptr: *const World, - entity_id: Handle, - out_parent: *mut Handle, -) -> DropbearNativeReturn { - if world_ptr.is_null() || out_parent.is_null() { - eprintln!("[dropbear_get_parent] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &*world_ptr; - let entity = world.find_entity_from_id(entity_id as u32); - - match world.get::<&Parent>(entity) { - Ok(parent) => { - unsafe { - *out_parent = parent.parent().id() as i64; - } - DropbearNativeError::Success as i32 - } - Err(_) => { - eprintln!("[dropbear_get_parent] [WARN] Parent component not found"); - DropbearNativeError::EntityNotFound as i32 - } - } -} @@ -1,48 +0,0 @@ -use std::ffi::{c_char, CString}; -use hecs::World; -use crate::scripting::native::DropbearNativeError; -use crate::scripting::native::exports::dropbear_common::{DropbearNativeReturn, Handle}; -use crate::states::Label; - -/// Fetches the [`Label`] (or name) component of an entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_entity_name( - world_ptr: *const World, - entity_id: Handle, - out_name: *mut c_char, - max_len: usize, -) -> DropbearNativeReturn { - if world_ptr.is_null() || out_name.is_null() { - eprintln!("[dropbear_get_entity_name] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = unsafe { &*world_ptr }; - let entity = unsafe { world.find_entity_from_id(entity_id as u32) }; - - if let Ok(mut q) = world.query_one::<&Label>(entity) { - if let Some(label) = q.get() { - let label_str = label.as_str(); - let Ok(c_str) = CString::new(label_str) else { - return DropbearNativeError::CStringError as i32; - }; - - let bytes = c_str.as_bytes_with_nul(); - if bytes.len() > max_len { - return DropbearNativeError::BufferTooSmall as i32; - } - - unsafe { - std::ptr::copy_nonoverlapping( - bytes.as_ptr(), - out_name as *mut u8, - bytes.len() - ); - } - - return DropbearNativeError::Success as i32; - } - } - - DropbearNativeError::QueryFailed as i32 -} @@ -1,560 +0,0 @@ -use std::collections::{HashMap, HashSet}; -use std::ffi::{c_char, CStr, CString}; -use std::ptr; -use std::sync::{Arc}; -use hecs::World; -use parking_lot::Mutex; -use dropbear_engine::asset::AssetHandle; -use dropbear_engine::asset::PointerKind::Const; -use dropbear_engine::entity::MeshRenderer; -use dropbear_engine::model::Model; -use crate::ptr::AssetRegistryPtr; -use crate::scripting::native::DropbearNativeError; -use crate::scripting::native::exports::dropbear_common::{Bool, DropbearNativeReturn, Handle}; - -/// Fetches the model that is currently being used by the entity being queried. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_model( - world_ptr: *const World, - asset_ptr: AssetRegistryPtr, - entity_handle: Handle, - out_model_id: *mut Handle, -) -> DropbearNativeReturn { - if world_ptr.is_null() || asset_ptr.is_null() || out_model_id.is_null() { - eprintln!("[dropbear_get_model] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &*world_ptr; - let _asset = &*asset_ptr; - let entity = world.find_entity_from_id(entity_handle as u32); - - match world.query_one::<&MeshRenderer>(entity) { - Ok(mut q) => { - if let Some(renderer) = q.get() { - unsafe { *out_model_id = renderer.asset_handle().raw() as i64; } - DropbearNativeError::Success as i32 - } else { - eprintln!("[dropbear_get_model] [ERROR] Entity missing MeshRenderer component"); - DropbearNativeError::NoSuchComponent as i32 - } - } - Err(_) => { - eprintln!("[dropbear_get_model] [ERROR] Failed to query entity"); - DropbearNativeError::QueryFailed as i32 - } - } -} - -/// Sets the MeshRenderer's model as that of the provided asset in the form of a ModelHandle. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_set_model( - world_ptr: *const World, - asset_ptr: AssetRegistryPtr, - entity_handle: Handle, - model_id: Handle, -) -> DropbearNativeReturn { - if world_ptr.is_null() || asset_ptr.is_null() { - eprintln!("[dropbear_set_model] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &*world_ptr; - let asset = &*asset_ptr; - let entity = world.find_entity_from_id(entity_handle as u32); - - match world.query_one::<&mut MeshRenderer>(entity) { - Ok(mut q) => { - if let Some(renderer) = q.get() { - let handle = AssetHandle::new(model_id as u64); - if let Err(err) = renderer.set_asset_handle_raw(asset, handle) { - eprintln!( - "[dropbear_set_model] [ERROR] Failed to set model handle {}: {}", - model_id, - err - ); - DropbearNativeError::UnknownError as i32 - } else { - DropbearNativeError::Success as i32 - } - } else { - eprintln!("[dropbear_set_model] [ERROR] Entity missing MeshRenderer component"); - DropbearNativeError::NoSuchComponent as i32 - } - } - Err(_) => { - eprintln!("[dropbear_set_model] [ERROR] Failed to query entity"); - DropbearNativeError::QueryFailed as i32 - } - } -} - -/// Checks if a handle provided is that of a Model. Returns false if not or true if is. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_is_model_handle( - asset_ptr: AssetRegistryPtr, - handle: Handle, - out_is_model: *mut Bool, -) -> DropbearNativeReturn { - if asset_ptr.is_null() || out_is_model.is_null() { - eprintln!("[dropbear_is_model_handle] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let asset = &*asset_ptr; - let handle = AssetHandle::new(handle as u64); - unsafe { - *out_is_model = if asset.is_model(handle) { 1 } else { 0 }; - } - DropbearNativeError::Success as i32 -} - -/// Checks if the entity is currently using a specific asset (in the form of a ModelHandle) to render -/// its meshes. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_is_using_model( - world_ptr: *const World, - entity_handle: Handle, - model_handle: Handle, - out_is_using: *mut Bool, -) -> DropbearNativeReturn { - if world_ptr.is_null() || out_is_using.is_null() { - eprintln!("[dropbear_is_using_model] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &*world_ptr; - let entity = world.find_entity_from_id(entity_handle as u32); - let handle = AssetHandle::new(model_handle as u64); - - match world.query_one::<&MeshRenderer>(entity) { - Ok(mut q) => { - if let Some(renderer) = q.get() { - unsafe { - *out_is_using = if renderer.uses_model_handle(handle) { 1 } else { 0 }; - } - DropbearNativeError::Success as i32 - } else { - eprintln!( - "[dropbear_is_using_model] [ERROR] Entity missing MeshRenderer component" - ); - DropbearNativeError::NoSuchComponent as i32 - } - } - Err(_) => { - eprintln!("[dropbear_is_using_model] [ERROR] Failed to query entity"); - DropbearNativeError::QueryFailed as i32 - } - } -} - -/// Fetches the texture (in the form of a TextureHandle) from a specific entity that is currently -/// rendering the model. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_texture( - world_ptr: *const World, - asset_ptr: AssetRegistryPtr, - entity_handle: Handle, - name: *const c_char, - out_texture_id: *mut Handle, -) -> DropbearNativeReturn { - if world_ptr.is_null() || asset_ptr.is_null() || name.is_null() || out_texture_id.is_null() { - eprintln!("[dropbear_get_texture] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &*world_ptr; - let asset = &*asset_ptr; - let entity = world.find_entity_from_id(entity_handle as u32); - let label = match CStr::from_ptr(name).to_str() { - Ok(s) => s.to_string(), - Err(_) => { - eprintln!("[dropbear_get_texture] [ERROR] Invalid UTF-8 in material name"); - return DropbearNativeError::InvalidUTF8 as i32; - } - }; - - match world.query_one::<&MeshRenderer>(entity) { - Ok(mut q) => { - if let Some(renderer) = q.get() { - if let Some(handle) = renderer.material_handle_raw(asset, label.as_str()) { - unsafe { *out_texture_id = handle.raw() as i64; } - DropbearNativeError::Success as i32 - } else { - eprintln!( - "[dropbear_get_texture] [ERROR] Material '{}' not found on entity", - label - ); - DropbearNativeError::EntityNotFound as i32 - } - } else { - eprintln!("[dropbear_get_texture] [ERROR] Entity missing MeshRenderer component"); - DropbearNativeError::NoSuchComponent as i32 - } - } - Err(_) => { - eprintln!("[dropbear_get_texture] [ERROR] Failed to query entity"); - DropbearNativeError::QueryFailed as i32 - } - } -} - -/// Fetches the texture name. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_texture_name( - asset_ptr: AssetRegistryPtr, - texture_handle: Handle, - out_name: *mut *const c_char, -) -> DropbearNativeReturn { - if asset_ptr.is_null() || out_name.is_null() { - eprintln!("[dropbear_get_texture_name] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let asset = &*asset_ptr; - let handle = AssetHandle::new(texture_handle as u64); - - if let Some(material) = asset.get_material(handle) { - match CString::new(material.name.as_str()) { - Ok(c_string) => { - unsafe { - *out_name = c_string.into_raw(); - } - DropbearNativeError::Success as i32 - } - Err(err) => { - eprintln!( - "[dropbear_get_texture_name] [ERROR] Failed to allocate string: {}", - err - ); - DropbearNativeError::UnknownError as i32 - } - } - } else { - eprintln!( - "[dropbear_get_texture_name] [ERROR] Invalid texture handle {}", - texture_handle - ); - DropbearNativeError::EntityNotFound as i32 - } -} - -/// Replaces the texture of a specific texture of the model currently being rendered on an entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_set_texture( - world_ptr: *const World, - asset_ptr: AssetRegistryPtr, - entity_handle: Handle, - old_material_name: *const c_char, - texture_id: Handle, -) -> DropbearNativeReturn { - if world_ptr.is_null() || asset_ptr.is_null() || old_material_name.is_null() { - eprintln!("[dropbear_set_texture] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &*world_ptr; - let asset = &*asset_ptr; - let entity = world.find_entity_from_id(entity_handle as u32); - let target_identifier = match CStr::from_ptr(old_material_name).to_str() { - Ok(s) => s.to_string(), - Err(_) => { - eprintln!("[dropbear_set_texture] [ERROR] Invalid UTF-8 in material identifier"); - return DropbearNativeError::InvalidUTF8 as i32; - } - }; - - match world.query_one::<&mut MeshRenderer>(entity) { - Ok(mut query) => { - let Some(renderer) = query.get() else { - eprintln!( - "[dropbear_set_texture] [ERROR] Entity missing MeshRenderer component" - ); - return DropbearNativeError::NoSuchComponent as i32; - }; - - let cache_ptr = match asset.get_pointer(Const("model_cache")) { - Some(ptr) => ptr as *const Mutex<HashMap<String, Arc<Model>>>, - None => { - eprintln!( - "[dropbear_set_texture] [ERROR] Asset registry missing model cache pointer" - ); - return DropbearNativeError::UnknownError as i32; - } - }; - - let Some(cache) = (unsafe { cache_ptr.as_ref() }) else { - eprintln!("[dropbear_set_texture] [ERROR] Model cache pointer is null"); - return DropbearNativeError::NullPointer as i32; - }; - - let resolved_target_name = renderer - .resolve_texture_identifier(&target_identifier) - .map(|name| name.to_string()) - .or_else(|| { - let model = renderer.model(); - let model_id = renderer.model_id(); - - if model - .materials - .iter() - .any(|material| material.name == target_identifier) - { - return Some(target_identifier.clone()); - } - - model.materials.iter().find_map(|material| { - if material.name == target_identifier { - return Some(material.name.clone()); - } - - let registry_reference = asset - .material_handle(model_id, &material.name) - .and_then(|handle| asset.material_reference_for_handle(handle)) - .and_then(|reference| reference.as_uri().map(|uri| uri.to_string())); - - if registry_reference - .as_ref() - .map(|value| value == &target_identifier) - .unwrap_or(false) - { - return Some(material.name.clone()); - } - - if material - .texture_tag - .as_ref() - .map(|tag| tag == &target_identifier) - .unwrap_or(false) - { - return Some(material.name.clone()); - } - - None - }) - }); - - let Some(target_material) = resolved_target_name else { - eprintln!( - "[dropbear_set_texture] [ERROR] Unable to resolve material '{}' on model '{}'", - target_identifier, - renderer.model().label - ); - return DropbearNativeError::EntityNotFound as i32; - }; - - let handle = AssetHandle::new(texture_id as u64); - - if !asset.contains_handle(handle) || !asset.is_material(handle) { - eprintln!( - "[dropbear_set_texture] [ERROR] Handle {} is not a valid material", - texture_id - ); - return DropbearNativeError::EntityNotFound as i32; - } - - let Some(material) = asset.get_material(handle) else { - eprintln!("[dropbear_set_texture] [ERROR] Material handle not found"); - return DropbearNativeError::EntityNotFound as i32; - }; - - let Some(owner_model_id) = asset.material_owner(handle) else { - eprintln!( - "[dropbear_set_texture] [ERROR] Unable to resolve owner model for material" - ); - return DropbearNativeError::UnknownError as i32; - }; - - let Some(owner_model_handle) = asset.model_handle_from_id(owner_model_id) else { - eprintln!( - "[dropbear_set_texture] [ERROR] Unable to resolve model handle for owner" - ); - return DropbearNativeError::UnknownError as i32; - }; - - let Some(source_reference) = asset.model_reference_for_handle(owner_model_handle) else { - eprintln!( - "[dropbear_set_texture] [ERROR] Unable to resolve model reference for owner" - ); - return DropbearNativeError::UnknownError as i32; - }; - - match renderer.apply_material_override_raw( - asset, - cache, - target_material.as_str(), - source_reference, - material.name.as_str(), - ) { - Ok(()) => DropbearNativeError::Success as i32, - Err(err) => { - eprintln!( - "[dropbear_set_texture] [ERROR] Failed to apply material override: {}", - err - ); - DropbearNativeError::UnknownError as i32 - } - } - } - Err(err) => { - eprintln!( - "[dropbear_set_texture] [ERROR] Unable to query MeshRenderer: {}", - err - ); - DropbearNativeError::QueryFailed as i32 - } - } -} - -/// Checks if a general AssetHandle is linked to a texture, therefore making it a TextureHandle. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_is_texture_handle( - asset_ptr: AssetRegistryPtr, - handle: Handle, - out_is_texture: *mut Bool, -) -> DropbearNativeReturn { - if asset_ptr.is_null() || out_is_texture.is_null() { - eprintln!("[dropbear_is_texture_handle] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let asset = &*asset_ptr; - let handle = AssetHandle::new(handle as u64); - unsafe { - *out_is_texture = if asset.is_material(handle) { 1 } else { 0 }; - } - DropbearNativeError::Success as i32 -} - -/// Checks if an entity is currently using a texture as specified by the TextureId. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_is_using_texture( - world_ptr: *const World, - entity_handle: Handle, - texture_handle: Handle, - out_is_using: *mut Bool, -) -> DropbearNativeReturn { - if world_ptr.is_null() || out_is_using.is_null() { - eprintln!("[dropbear_is_using_texture] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &*world_ptr; - let entity = world.find_entity_from_id(entity_handle as u32); - let handle = AssetHandle::new(texture_handle as u64); - - match world.query_one::<&MeshRenderer>(entity) { - Ok(mut q) => { - if let Some(renderer) = q.get() { - unsafe { - *out_is_using = if renderer.contains_material_handle(handle) { 1 } else { 0 }; - } - DropbearNativeError::Success as i32 - } else { - eprintln!( - "[dropbear_is_using_texture] [ERROR] Entity missing MeshRenderer component" - ); - DropbearNativeError::NoSuchComponent as i32 - } - } - Err(_) => { - eprintln!("[dropbear_is_using_texture] [ERROR] Failed to query entity"); - DropbearNativeError::QueryFailed as i32 - } - } -} - - -// todo: change from returning texture names to return TextureHandle -/// Fetches all the textures currently being rendered by an entity -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_all_textures( - world_ptr: *const World, - asset_registry_ptr: AssetRegistryPtr, - entity_handle: Handle, - out_textures: *mut *mut *const c_char, - out_count: *mut usize, -) -> DropbearNativeReturn { - if world_ptr.is_null() || out_textures.is_null() || out_count.is_null() || asset_registry_ptr.is_null() { - eprintln!("[dropbear_get_all_textures] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = &mut *(world_ptr as *mut World); - let asset = &*asset_registry_ptr; - let entity = world.find_entity_from_id(entity_handle as u32); - - let mut query = match world.query_one::<&mut MeshRenderer>(entity) { - Ok(query) => query, - Err(err) => { - eprintln!( - "[dropbear_get_all_textures] [ERROR] Failed to query entity: {}", - err - ); - return DropbearNativeError::QueryFailed as i32; - } - }; - - let Some(renderer) = query.get() else { - eprintln!( - "[dropbear_get_all_textures] [ERROR] Entity missing MeshRenderer component" - ); - return DropbearNativeError::NoSuchComponent as i32; - }; - - renderer.clear_texture_identifier_cache(); - let model = renderer.model(); - let model_id = renderer.model_id(); - - let mut seen = HashSet::new(); - let mut textures = Vec::new(); - - for material in &model.materials { - renderer.register_texture_identifier(material.name.clone(), material.name.clone()); - if let Some(tag) = &material.texture_tag { - renderer.register_texture_identifier(tag.clone(), material.name.clone()); - } - - let reference = asset - .material_handle(model_id, &material.name) - .and_then(|handle| asset.material_reference_for_handle(handle)) - .and_then(|reference| reference.as_uri().map(|uri| uri.to_string())) - .or_else(|| material.texture_tag.clone()) - .unwrap_or_else(|| material.name.clone()); - - if seen.insert(reference.clone()) { - renderer.register_texture_identifier(reference.clone(), material.name.clone()); - textures.push(reference); - } - } - - unsafe { - *out_count = textures.len(); - } - - if textures.is_empty() { - unsafe { *out_textures = ptr::null_mut(); } - return DropbearNativeError::Success as i32; - } - - let mut c_pointers: Vec<*const c_char> = Vec::with_capacity(textures.len()); - for value in textures { - match CString::new(value) { - Ok(c_string) => c_pointers.push(c_string.into_raw()), - Err(err) => { - eprintln!( - "[dropbear_get_all_textures] [ERROR] Failed to allocate string: {}", - err - ); - return DropbearNativeError::UnknownError as i32; - } - } - } - - let mut boxed = c_pointers.into_boxed_slice(); - unsafe { - *out_textures = boxed.as_mut_ptr(); - } - Box::leak(boxed); - DropbearNativeError::Success as i32 -} @@ -1,441 +0,0 @@ -use std::ffi::{c_char, CStr}; -use hecs::World; -use dropbear_engine::entity::MeshRenderer; -use crate::scripting::native::DropbearNativeError; -use crate::scripting::native::exports::dropbear_common::{Bool, DropbearNativeReturn, Handle}; -use crate::states::{CustomProperties, Value}; - -/// Fetches the string property -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_string_property( - world_ptr: *const World, - entity_handle: Handle, - label: *const c_char, - out_value: *mut c_char, - out_value_max_length: i32, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() || out_value.is_null() { - eprintln!("[dropbear_get_string_property] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let world = unsafe { &*world_ptr }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s, - Err(_) => { - eprintln!("[dropbear_get_string_property] [ERROR] Invalid UTF-8 in label"); - return -108; - } - }; - - match world.query_one::<(&MeshRenderer, &CustomProperties)>(entity) { - Ok(mut q) => { - if let Some((_, props)) = q.get() { - if let Some(Value::String(val)) = props.get_property(label_str) { - let bytes = val.as_bytes(); - let copy_len = std::cmp::min(bytes.len(), (out_value_max_length - 1) as usize); - unsafe { - std::ptr::copy_nonoverlapping( - bytes.as_ptr(), - out_value as *mut u8, - copy_len, - ); - *out_value.add(copy_len) = 0; // null terminator - } - 0 - } else { - eprintln!( - "[dropbear_get_string_property] [WARN] Property not found or wrong type" - ); - -3 - } - } else { - -4 - } - } - Err(_) => { - eprintln!("[dropbear_get_string_property] [ERROR] Failed to query entity"); - -2 - } - } -} - -/// Fetches the integer property of an entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_int_property( - world_ptr: *const World, - entity_handle: Handle, - label: *const c_char, - out_value: *mut i32, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() || out_value.is_null() { - eprintln!("[dropbear_get_int_property] [ERROR] Null pointer received"); - return -1; - } - - let world = unsafe { &*world_ptr }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s, - Err(_) => return -108, - }; - - match world.query_one::<(&MeshRenderer, &CustomProperties)>(entity) { - Ok(mut q) => { - if let Some((_, props)) = q.get() { - if let Some(Value::Int(val)) = props.get_property(label_str) { - unsafe { *out_value = *val as i32 }; - 0 - } else { - -3 - } - } else { - -4 - } - } - Err(_) => -2, - } -} - -/// Fetches the long/[`f64`] property of an entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_long_property( - world_ptr: *const World, - entity_handle: Handle, - label: *const c_char, - out_value: *mut Handle, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() || out_value.is_null() { - return -1; - } - - let world = unsafe { &*world_ptr }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s, - Err(_) => return -108, - }; - - match world.query_one::<(&MeshRenderer, &CustomProperties)>(entity) { - Ok(mut q) => { - if let Some((_, props)) = q.get() { - if let Some(Value::Int(val)) = props.get_property(label_str) { - unsafe { *out_value = *val }; - 0 - } else { - -3 - } - } else { - -4 - } - } - Err(_) => -2, - } -} - -/// Fetches the double/[`f64`] (idk why its called float but cbb to change) value of an entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_float_property( - world_ptr: *const World, - entity_handle: Handle, - label: *const c_char, - out_value: *mut f64, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() || out_value.is_null() { - return -1; - } - - let world = unsafe { &*world_ptr }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s, - Err(_) => return -108, - }; - - match world.query_one::<(&MeshRenderer, &CustomProperties)>(entity) { - Ok(mut q) => { - if let Some((_, props)) = q.get() { - if let Some(Value::Float(val)) = props.get_property(label_str) { - unsafe { *out_value = *val as f64 }; - 0 - } else { - -3 - } - } else { - -4 - } - } - Err(_) => -2, - } -} - -/// Fetches the boolean property of an entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_bool_property( - world_ptr: *const World, - entity_handle: Handle, - label: *const c_char, - out_value: *mut Bool, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() || out_value.is_null() { - return -1; - } - - let world = unsafe { &*world_ptr }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s, - Err(_) => return -108, - }; - - match world.query_one::<(&MeshRenderer, &CustomProperties)>(entity) { - Ok(mut q) => { - if let Some((_, props)) = q.get() { - if let Some(Value::Bool(val)) = props.get_property(label_str) { - unsafe { *out_value = if *val { 1 } else { 0 } }; - 0 - } else { - -3 - } - } else { - -4 - } - } - Err(_) => -2, - } -} - -/// Fetches the Vector3<float> property of an entity -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_vec3_property( - world_ptr: *const World, - entity_handle: Handle, - label: *const c_char, - out_x: *mut f32, - out_y: *mut f32, - out_z: *mut f32, -) -> DropbearNativeReturn { - if world_ptr.is_null() - || label.is_null() - || out_x.is_null() - || out_y.is_null() - || out_z.is_null() - { - return -1; - } - - let world = unsafe { &*world_ptr }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s, - Err(_) => return -108, - }; - - match world.query_one::<(&MeshRenderer, &CustomProperties)>(entity) { - Ok(mut q) => { - if let Some((_, props)) = q.get() { - if let Some(Value::Vec3([x, y, z])) = props.get_property(label_str) { - unsafe { - *out_x = *x; - *out_y = *y; - *out_z = *z; - } - 0 - } else { - -3 - } - } else { - -4 - } - } - Err(_) => -2, - } -} - -/// Sets the string property of an entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_set_string_property( - world_ptr: *const World, - entity_handle: Handle, - label: *const c_char, - value: *const c_char, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() || value.is_null() { - return -1; - } - - let world = unsafe { &mut *(world_ptr as *mut World) }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s.to_string(), - Err(_) => return -108, - }; - - let value_str = match unsafe { CStr::from_ptr(value) }.to_str() { - Ok(s) => s.to_string(), - Err(_) => return -108, - }; - - match world.query_one_mut::<(&MeshRenderer, &mut CustomProperties)>(entity) { - Ok((_, props)) => { - props.set_property(label_str, Value::String(value_str)); - 0 - } - Err(_) => -2, - } -} - -/// Sets the integer property of an entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_set_int_property( - world_ptr: *const World, - entity_handle: Handle, - label: *const c_char, - value: i32, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() { - return -1; - } - - let world = unsafe { &mut *(world_ptr as *mut World) }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s.to_string(), - Err(_) => return -108, - }; - - match world.query_one_mut::<(&MeshRenderer, &mut CustomProperties)>(entity) { - Ok((_, props)) => { - props.set_property(label_str, Value::Int(value as Handle)); - 0 - } - Err(_) => -2, - } -} - -/// Sets the long property of an entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_set_long_property( - world_ptr: *const World, - entity_handle: Handle, - label: *const c_char, - value: Handle, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() { - return -1; - } - - let world = unsafe { &mut *(world_ptr as *mut World) }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s.to_string(), - Err(_) => return -108, - }; - - match world.query_one_mut::<(&MeshRenderer, &mut CustomProperties)>(entity) { - Ok((_, props)) => { - props.set_property(label_str, Value::Int(value)); - 0 - } - Err(_) => -2, - } -} - -/// Sets the float property of an entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_set_float_property( - world_ptr: *const World, - entity_handle: Handle, - label: *const c_char, - value: f32, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() { - return -1; - } - - let world = unsafe { &mut *(world_ptr as *mut World) }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s.to_string(), - Err(_) => return -108, - }; - - match world.query_one_mut::<(&MeshRenderer, &mut CustomProperties)>(entity) { - Ok((_, props)) => { - props.set_property(label_str, Value::Float(value as f64)); - 0 - } - Err(_) => -2, - } -} - -/// Sets the boolean property of an entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_set_bool_property( - world_ptr: *const World, - entity_handle: Handle, - label: *const c_char, - value: Bool, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() { - return -1; - } - - let world = unsafe { &mut *(world_ptr as *mut World) }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s.to_string(), - Err(_) => return -108, - }; - - match world.query_one_mut::<(&MeshRenderer, &mut CustomProperties)>(entity) { - Ok((_, props)) => { - props.set_property(label_str, Value::Bool(value != 0)); - 0 - } - Err(_) => -2, - } -} - -/// Sets the Vector3<float> property of an entity. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_set_vec3_property( - world_ptr: *const World, - entity_handle: Handle, - label: *const c_char, - x: f32, - y: f32, - z: f32, -) -> DropbearNativeReturn { - if world_ptr.is_null() || label.is_null() { - return -1; - } - - let world = unsafe { &mut *(world_ptr as *mut World) }; - let entity = unsafe { world.find_entity_from_id(entity_handle as u32) }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s.to_string(), - Err(_) => return -108, - }; - - match world.query_one_mut::<(&MeshRenderer, &mut CustomProperties)>(entity) { - Ok((_, props)) => { - props.set_property(label_str, Value::Vec3([x, y, z])); - 0 - } - Err(_) => -2, - } -} @@ -1,6 +0,0 @@ -pub mod dropbear_camera; -pub mod dropbear_entitytransform; -pub mod dropbear_hierarchy; -pub mod dropbear_label; -pub mod dropbear_meshrenderer; -pub mod dropbear_properties; @@ -1,14 +0,0 @@ -use crate::ptr::{AssetRegistryPtr, CommandBufferPtr, InputStatePtr, PhysicsStatePtr, SceneLoaderPtr, WorldPtr}; - -/// The return code for a function. -/// -/// Follows the same code as [`DropbearNativeError`] -pub type DropbearNativeReturn = i32; - -/// The handle/id of an object, as a long. -/// -/// Kotlin/Native requires this to be an `int64_t` or a Long. -pub type Handle = i64; - -/// A helper type that defines a value that can either be a 0 or 1. -pub type Bool = i32; @@ -1,119 +0,0 @@ -use std::ffi::{c_char, CStr}; -use hecs::World; -use dropbear_engine::utils::ResourceReference; -use crate::ptr::{AssetRegistryPtr, CommandBufferPtr}; -use crate::scripting::native::DropbearNativeError; -use crate::scripting::native::exports::dropbear_common::{DropbearNativeReturn, Handle}; -use crate::states::Label; -use crate::command::CommandBuffer; - -/// Fetches an entity from the world/current scene by its label. -/// -/// Returns the entity's id. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_entity( - label: *const c_char, - world_ptr: *const World, - out_entity: *mut Handle, -) -> DropbearNativeReturn { - if label.is_null() || world_ptr.is_null() || out_entity.is_null() { - eprintln!("[dropbear_get_entity] [ERROR] received null pointer"); - return DropbearNativeError::NullPointer as i32; - } - - let world = unsafe { &*world_ptr }; - - let label_str = match unsafe { CStr::from_ptr(label) }.to_str() { - Ok(s) => s, - Err(_) => { - eprintln!("[dropbear_get_entity] [ERROR] invalid UTF-8 in label"); - return DropbearNativeError::InvalidUTF8 as i32; - } - }; - - for (id, entity_label) in world.query::<&Label>().iter() { - if entity_label.as_str() == label_str { - unsafe { *out_entity = id.id() as i64 }; - return DropbearNativeError::Success as i32; - } - } - - eprintln!( - "[dropbear_get_entity] [ERROR] Entity with label '{}' not found", - label_str - ); - DropbearNativeError::EntityNotFound as i32 -} - -/// Fetches an asset from the asset registry as by its name. -/// -/// Returns the asset's handle. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_asset( - asset_ptr: AssetRegistryPtr, - uri: *const c_char, - out_asset_id: *mut i64, -) -> DropbearNativeReturn { - if asset_ptr.is_null() || uri.is_null() || out_asset_id.is_null() { - eprintln!("[dropbear_get_asset] [ERROR] Null pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - let asset = &*asset_ptr; - let uri_str = match CStr::from_ptr(uri).to_str() { - Ok(s) => s.to_string(), - Err(_) => { - eprintln!("[dropbear_get_asset] [ERROR] Invalid UTF-8 in URI"); - return DropbearNativeError::InvalidUTF8 as i32; - } - }; - - let reference = match ResourceReference::from_euca_uri(uri_str) { - Ok(reference) => reference, - Err(err) => { - eprintln!( - "[dropbear_get_asset] [ERROR] Failed to parse resource reference: {}", - err - ); - return DropbearNativeError::UnknownError as i32; - } - }; - - if let Some(handle) = asset.get_handle_from_reference(&reference) { - unsafe { - *out_asset_id = handle.raw() as i64; - } - DropbearNativeError::Success as i32 - } else { - eprintln!("[dropbear_get_asset] [ERROR] Asset not found"); - DropbearNativeError::EntityNotFound as i32 - } -} - -/// Quits the currently running app or game. -/// -/// Does not return anything. If any issues occur, it will panic. -/// -/// # Behaviours -/// - eucalyptus-editor - When called, this exits your Play Mode session and brings you back to -/// `EditorState::Editing` -/// - redback-runtime - When called, this will exit your current process and kill the app as is. It will -/// also drop any pointers and do any additional clean-up. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_quit( - command_ptr: CommandBufferPtr, -) { - if command_ptr.is_null() { - panic!("NullPointer (-1) while quitting, better off to shoot with gun than to nicely ask...") - } - - let graphics = unsafe { &*(command_ptr as CommandBufferPtr) }; - - if graphics - .send(CommandBuffer::Quit) - .is_err() - { - panic!("SendError (-7) while sending a quit signal to the CommandBuffer, \ - better off to shoot with gun than to nicely ask...") - } -} @@ -1,392 +0,0 @@ -use crate::ptr::{CommandBufferPtr, InputStatePtr}; -use crate::scripting::native::DropbearNativeError; -use crate::scripting::native::exports::dropbear_common::{Bool, DropbearNativeReturn, Handle}; -use crate::utils::keycode_from_ordinal; -use crate::command::{CommandBuffer, WindowCommand}; -use crate::scripting::native::exports::dropbear_math::Vector2D; -use crate::scripting::utils::button_from_ordinal; - -/// A struct that represents an external input device in the shape of a controller. -#[repr(C)] -#[derive(Clone, Debug)] -pub struct Gamepad { - id: i32, - left_stick_pos: Vector2D, - right_stick_pos: Vector2D, -} - -/// Prints the input state to the console. Does not return anything, failure does not do anything. -/// -/// Can be useful for debugging. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_print_input_state(input_state_ptr: InputStatePtr) { - if input_state_ptr.is_null() { - eprintln!("[dropbear_print_input_state] [ERROR] Input state pointer is null"); - return; - } - - let input_state = unsafe { &*input_state_ptr }; - println!("{:#?}", input_state); -} - -/// Checks if a key is currently pressed. If pressed, returns 1, otherwise 0. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_is_key_pressed( - input_state_ptr: InputStatePtr, - keycode: i32, - out_value: *mut Bool, -) -> DropbearNativeReturn { - if input_state_ptr.is_null() || out_value.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let input = unsafe { &*input_state_ptr }; - - match keycode_from_ordinal(keycode) { - Some(k) => { - let is_pressed = input.pressed_keys.contains(&k); - unsafe { *out_value = if is_pressed { 1 } else { 0 } }; - DropbearNativeError::Success as i32 - } - None => { - eprintln!("[dropbear_is_key_pressed] [WARN] Invalid keycode"); - unsafe { *out_value = 0 }; - DropbearNativeError::Success as i32 - } - } -} - -/// Fetches the current mouse position for that frame. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_mouse_position( - input_state_ptr: InputStatePtr, - out_x: *mut f32, - out_y: *mut f32, -) -> DropbearNativeReturn { - if input_state_ptr.is_null() || out_x.is_null() || out_y.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let input = unsafe { &*input_state_ptr }; - - unsafe { - *out_x = input.mouse_pos.0 as f32; - *out_y = input.mouse_pos.1 as f32; - } - - DropbearNativeError::Success as i32 -} - -/// Checks if a mouse button is currently pressed. If pressed, returns 1, otherwise 0. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_is_mouse_button_pressed( - input_state_ptr: InputStatePtr, - button_code: i32, - out_pressed: *mut Bool, -) -> DropbearNativeReturn { - if input_state_ptr.is_null() || out_pressed.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let input = unsafe { &*input_state_ptr }; - - let button = match button_code { - 0 => Some(winit::event::MouseButton::Left), - 1 => Some(winit::event::MouseButton::Right), - 2 => Some(winit::event::MouseButton::Middle), - 3 => Some(winit::event::MouseButton::Back), - 4 => Some(winit::event::MouseButton::Forward), - _ => None, - }; - - match button { - None => { - eprintln!("[dropbear_is_mouse_button_pressed] [WARN] Invalid button code"); - unsafe { *out_pressed = 0 }; - } - Some(btn) => { - if input.mouse_button.contains(&btn) { - unsafe { *out_pressed = 1 }; - } else { - unsafe { *out_pressed = 0 }; - } - } - } - - DropbearNativeError::Success as i32 -} - -/// Fetches the delta of the mouse position since the last frame. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_mouse_delta( - input_state_ptr: InputStatePtr, - out_delta_x: *mut f32, - out_delta_y: *mut f32, -) -> DropbearNativeReturn { - if input_state_ptr.is_null() || out_delta_x.is_null() || out_delta_y.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let input = unsafe { &mut *(input_state_ptr as InputStatePtr) }; - - if let Some(pos) = input.mouse_delta { - unsafe { - *out_delta_x = pos.0 as f32; - *out_delta_y = pos.1 as f32; - } - } else { - unsafe { - *out_delta_x = 0.0; - *out_delta_y = 0.0; - } - } - - DropbearNativeError::Success as i32 -} - -/// Checks if the cursor is currently locked. If locked, returns 1, otherwise 0. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_is_cursor_locked( - input_state_ptr: InputStatePtr, - out_locked: *mut Bool, -) -> DropbearNativeReturn { - if input_state_ptr.is_null() || out_locked.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let input = unsafe { &*input_state_ptr }; - - unsafe { *out_locked = if input.is_cursor_locked { 1 } else { 0 } }; - - DropbearNativeError::Success as i32 -} - -/// Sets the mouse cursor to be locked or unlocked. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_set_cursor_locked( - input_state_ptr: InputStatePtr, - queue_ptr: CommandBufferPtr, - locked: Bool, -) -> DropbearNativeReturn { - if input_state_ptr.is_null() || queue_ptr.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let input = unsafe { &mut *(input_state_ptr as InputStatePtr) }; - - let graphics = unsafe { &*(queue_ptr as CommandBufferPtr) }; - - input.is_cursor_locked = locked != 0; - - if graphics - .send(CommandBuffer::WindowCommand(WindowCommand::WindowGrab( - input.is_cursor_locked, - ))) - .is_err() - { - DropbearNativeError::SendError as i32 - } else { - DropbearNativeError::Success as i32 - } -} - -/// Fetches the mouse position of the previous frame. -/// -/// Can be used to calculate the delta of the mouse position. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_last_mouse_pos( - input_state_ptr: InputStatePtr, - out_x: *mut f32, - out_y: *mut f32, -) -> DropbearNativeReturn { - if input_state_ptr.is_null() || out_x.is_null() || out_y.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let input = unsafe { &*input_state_ptr }; - - if let Some(pos) = input.last_mouse_pos { - unsafe { - *out_x = pos.0 as f32; - *out_y = pos.1 as f32; - } - } else { - unsafe { - *out_x = 0.0; - *out_y = 0.0; - } - } - - DropbearNativeError::Success as i32 -} - -/// Checks if the cursor is currently hidden. If hidden, returns 1, otherwise 0. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_is_cursor_hidden( - input_state_ptr: InputStatePtr, - out_hidden: *mut Bool, -) -> DropbearNativeReturn { - if input_state_ptr.is_null() || out_hidden.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let input = unsafe { &*input_state_ptr }; - - unsafe { *out_hidden = if input.is_cursor_hidden { 1 } else { 0 } }; - - DropbearNativeError::Success as i32 -} - -/// Sets the cursor to either hidden (invisible) or visible -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_set_cursor_hidden( - input_state_ptr: InputStatePtr, - queue_ptr: CommandBufferPtr, - hidden: Bool, -) -> DropbearNativeReturn { - if input_state_ptr.is_null() || queue_ptr.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let input = unsafe { &mut *(input_state_ptr as InputStatePtr) }; - let graphics = unsafe { &*(queue_ptr as CommandBufferPtr) }; - input.is_cursor_hidden = hidden != 0; - - if graphics - .send(CommandBuffer::WindowCommand(WindowCommand::HideCursor( - input.is_cursor_hidden, - ))) - .is_err() - { - DropbearNativeError::SendError as i32 - } else { - DropbearNativeError::Success as i32 - } -} - -/// Fetches all available connected gamepads in the input state. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_connected_gamepads( - input_state_ptr: InputStatePtr, - out_gamepads: *mut *const Gamepad, - out_count: *mut i32, -) -> DropbearNativeReturn { - if input_state_ptr.is_null() { - eprintln!("[dropbear_get_connected_gamepads] [ERROR] Input state pointer provided was null"); - return DropbearNativeError::NullPointer as i32; - } - - if out_gamepads.is_null() { - eprintln!("[dropbear_get_connected_gamepads] [ERROR] out_gamepads pointer provided was null"); - return DropbearNativeError::NullPointer as i32; - } - - if out_count.is_null() { - eprintln!("[dropbear_get_connected_gamepads] [ERROR] out_count of gamepads pointer provided was null"); - return DropbearNativeError::NullPointer as i32; - } - - let input_state = &mut *input_state_ptr; - - - let mut gamepads = Vec::new(); - for g in &input_state.connected_gamepads { - let id: usize = (*g).into(); - let left_stick = input_state.left_stick_position.get(&g); - let right_stick = input_state.right_stick_position.get(&g); - - if let Some(l) = left_stick && let Some(r) = right_stick { - let l = l.clone(); - let r = r.clone(); - - let gamepad = Gamepad { - id: id as i32, - left_stick_pos: Vector2D { - x: l.0 as f64, - y: l.1 as f64, - }, - right_stick_pos: Vector2D { - x: r.0 as f64, - y: r.1 as f64, - }, - }; - gamepads.push(gamepad); - } - } - - input_state.cached_gamepads = gamepads; - - unsafe { - *out_count = input_state.cached_gamepads.len() as i32; - *out_gamepads = input_state.cached_gamepads.as_ptr(); - } - - DropbearNativeError::Success as i32 -} - -/// Checks if a button has been pressed on a specific gamepad. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_is_gamepad_button_pressed( - input_state_ptr: InputStatePtr, - gamepad_id: Handle, - button_ordinal: i32, - out_pressed: *mut Bool, -) -> DropbearNativeReturn { - if input_state_ptr.is_null() { - eprintln!("[dropbear_is_gamepad_button_pressed] [ERROR] Input state pointer provided was null"); - return DropbearNativeError::NullPointer as i32; - } - - if out_pressed.is_null() { - eprintln!("[dropbear_is_gamepad_button_pressed] [ERROR] out_pressed pointer provided was null"); - return DropbearNativeError::NullPointer as i32; - } - - let input_state = &*input_state_ptr; - - if gamepad_id < 0 { - eprintln!( - "[dropbear_is_gamepad_button_pressed] [ERROR] Invalid gamepad id (negative): {}", - gamepad_id - ); - return DropbearNativeError::InvalidArgument as i32; - } - - let gamepad_id_usize = gamepad_id as usize; - let maybe_gid = input_state - .connected_gamepads - .iter() - .find(|gid| { - let id: usize = (**gid).into(); - id == gamepad_id_usize - }) - .copied(); - - let gid = match maybe_gid { - Some(gid) => gid, - None => { - eprintln!( - "[dropbear_is_gamepad_button_pressed] [ERROR] Gamepad with id {} not found", - gamepad_id - ); - return DropbearNativeError::GamepadNotFound as i32; - } - }; - - let button = match button_from_ordinal(button_ordinal) { - Ok(btn) => btn, - Err(_) => { - eprintln!( - "[dropbear_is_gamepad_button_pressed] [ERROR] Invalid button ordinal: {}", - button_ordinal - ); - return DropbearNativeError::InvalidArgument as i32; - } - }; - - let is_pressed = input_state.is_button_pressed(gid, button); - - *out_pressed = if is_pressed { 1 } else { 0 }; - - DropbearNativeError::Success as i32 -} @@ -1,37 +0,0 @@ -/// Represents a [`Vec2`] in a C struct form. -#[repr(C)] -#[derive(Clone, Debug)] -pub struct Vector2D { - pub x: f64, - pub y: f64, -} - -/// Represents a [`Vec3`] in a C struct form. -#[repr(C)] -pub struct Vector3D { - pub x: f64, - pub y: f64, - pub z: f64, -} - -/// Represents a [`Transform`] in a C struct form. -#[repr(C)] -pub struct NativeTransform { - pub position_x: f64, - pub position_y: f64, - pub position_z: f64, - pub rotation_x: f64, - pub rotation_y: f64, - pub rotation_z: f64, - pub rotation_w: f64, - pub scale_x: f64, - pub scale_y: f64, - pub scale_z: f64, -} - -/// Represents an [`EntityTransform`] in a C struct form. -#[repr(C)] -pub struct NativeEntityTransform { - pub local: NativeTransform, - pub world: NativeTransform, -} @@ -1,238 +0,0 @@ -use std::ffi::{c_char, CStr, CString}; -use crate::command::CommandBuffer; -use crate::ptr::{CommandBufferPtr, SceneLoaderPtr}; -use crate::scripting::native::DropbearNativeError; -use crate::scripting::native::exports::dropbear_common::{DropbearNativeReturn, Handle}; -use crate::scripting::native::exports::dropbear_utils::Progress; -use crate::scene::loading::{SceneLoadHandle as CoreSceneLoadHandle}; - -/// The sister to [`crate::scene::loading::SceneLoadResult`], which provides C-compatible enum values. -#[repr(C)] -#[derive(Default)] -pub enum SceneLoadResult { - Pending = 0, - Success = 1, - #[default] - Error = 2, -} - -impl From<SceneLoadResult> for i32 { - fn from(value: SceneLoadResult) -> Self { - value as i32 - } -} - -impl From<i32> for SceneLoadResult { - fn from(value: i32) -> Self { - match value { - -1 => SceneLoadResult::Error, - 0 => SceneLoadResult::Pending, - 1 => SceneLoadResult::Success, - _ => SceneLoadResult::Error, - } - } -} - -impl From<crate::scene::loading::SceneLoadResult> for SceneLoadResult { - fn from(value: crate::scene::loading::SceneLoadResult) -> Self { - match value { - crate::scene::loading::SceneLoadResult::Pending => SceneLoadResult::Pending, - crate::scene::loading::SceneLoadResult::Success => SceneLoadResult::Success, - crate::scene::loading::SceneLoadResult::Error(_) => SceneLoadResult::Error, - } - } -} - -/// The sister handle to [`crate::scene::loading::SceneLoadHandle`], which provides C-compatible values. -#[repr(C)] -pub struct SceneLoadHandle { - pub id: Handle, - pub name: *mut c_char, -} - -/// Loads a scene asynchronously. -/// -/// Returns a handle (in the form of an integer) -/// to the scene load operation. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_load_scene_async_1( - command_buffer_ptr: CommandBufferPtr, - scene_loader_ptr: SceneLoaderPtr, - scene_name: *const c_char, - out_scene_handle: *mut SceneLoadHandle, -) -> DropbearNativeReturn { - if command_buffer_ptr.is_null() || scene_loader_ptr.is_null() || scene_name.is_null() || out_scene_handle.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let command_buffer = &*command_buffer_ptr; - let scene_loader = &*scene_loader_ptr; - - let Ok(scene_name_str) = CStr::from_ptr(scene_name).to_str() else { - return DropbearNativeError::InvalidUTF8 as i32; - }; - let scene_name_string = scene_name_str.to_string(); - - let mut loader = scene_loader.lock(); - let id = loader.register_load(scene_name_string.clone()); - - let c_string = match CString::new(scene_name_string.clone()) { - Ok(s) => s, - Err(_) => return DropbearNativeError::InvalidUTF8 as i32, - }; - - *out_scene_handle = SceneLoadHandle { - id: id as Handle, - name: c_string.into_raw(), - }; - - let core_handle = CoreSceneLoadHandle { - id, - scene_name: scene_name_string, - }; - - if command_buffer.try_send(CommandBuffer::LoadSceneAsync(core_handle)).is_err() { - return DropbearNativeError::SendError as i32; - } - - DropbearNativeError::Success as i32 -} - -/// Loads a scene asynchronously. Allows you to include a loading_scene_name, -/// which will be displayed while the scene is loading. -/// -/// Returns a handle (in the form of an integer) -/// to the scene load operation. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_load_scene_async_2( - _command_buffer_ptr: CommandBufferPtr, - _scene_loader_ptr: SceneLoaderPtr, - _scene_name: *const c_char, - _loading_scene_name: *const c_char, - _out_scene_handle: *mut SceneLoadHandle, -) -> DropbearNativeReturn { - todo!("Not implemented yet") -} - -/// Switches to a scene asynchronously. -/// -/// This must be run after you initialise the scene loading (using [`dropbear_load_scene_async_1`] -/// or [`dropbear_load_scene_async_2`]). If this function is called before you have checked the progress -/// (with the [`dropbear_get_scene_load_status`] function), it will return -10 or [`DropbearNativeError::PrematureSceneSwitch`]. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_switch_to_scene_async( - command_buffer_ptr: CommandBufferPtr, - scene_handle: SceneLoadHandle, -) -> DropbearNativeReturn { - if command_buffer_ptr.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let command_buffer = &*command_buffer_ptr; - - if scene_handle.name.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let Ok(scene_name) = CStr::from_ptr(scene_handle.name).to_str() else { - return DropbearNativeError::InvalidUTF8 as i32; - }; - - let core_handle = CoreSceneLoadHandle { - id: scene_handle.id as u64, - scene_name: scene_name.to_string(), - }; - - if command_buffer.try_send(CommandBuffer::SwitchToAsync(core_handle)).is_err() { - return DropbearNativeError::SendError as i32; - } - - DropbearNativeError::Success as i32 -} - -/// Switches to a scene immediately. -/// -/// # Warning -/// This will block your main thread and freeze the window. It will be extremely inconvenient for -/// your players, and is recommended to use [`dropbear_load_scene_async_1`] or -/// [`dropbear_load_scene_async_2`]. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_switch_to_scene_immediate( - command_buffer_ptr: CommandBufferPtr, - scene_name: *const c_char, -) -> DropbearNativeReturn { - if command_buffer_ptr.is_null() { - eprintln!("[dropbear_switch_to_scene_immediate] [ERROR] Null command buffer pointer received"); - return DropbearNativeError::NullPointer as i32; - } - - if scene_name.is_null() { - eprintln!("[dropbear_switch_to_scene_immediate] [ERROR] Null scene name received"); - return DropbearNativeError::NullPointer as i32; - } - - let command_buffer = &*command_buffer_ptr; - let Ok(scene_name) = CStr::from_ptr(scene_name).to_str() else { - return DropbearNativeError::InvalidUTF8 as i32; - }; - - if command_buffer.try_send(CommandBuffer::SwitchSceneImmediate(scene_name.to_string())).is_err() { - return DropbearNativeError::SendError as i32; - } - - DropbearNativeError::Success as i32 -} - -/// Gets the progress of a scene load operation. -/// -/// Returns a [`Progress`] and a [`DropbearNativeReturn`] -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_scene_load_progress( - scene_loader_ptr: SceneLoaderPtr, - scene_handle: SceneLoadHandle, - out_progress: *mut Progress, -) -> DropbearNativeReturn { - if scene_loader_ptr.is_null() || out_progress.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let scene_loader = &*scene_loader_ptr; - let loader = scene_loader.lock(); - - if let Some(entry) = loader.get_entry(scene_handle.id as u64) { - let p = &entry.progress; - let c_message = CString::new(p.message.clone()).unwrap_or_default(); - *out_progress = Progress { - current: p.current as f64, - total: p.total as f64, - message: c_message.into_raw(), - }; - DropbearNativeError::Success as i32 - } else { - DropbearNativeError::GenericError as i32 - } -} - -/// Gets the status of a scene load operation -/// -/// Returns a [`SceneLoadResult`] and a [`DropbearNativeReturn`] -#[unsafe(no_mangle)] -pub unsafe extern "C" fn dropbear_get_scene_load_status( - scene_loader_ptr: SceneLoaderPtr, - scene_handle: SceneLoadHandle, - out_status: *mut SceneLoadResult, -) -> DropbearNativeReturn { - if scene_loader_ptr.is_null() || out_status.is_null() { - return DropbearNativeError::NullPointer as i32; - } - - let scene_loader = &*scene_loader_ptr; - let loader = scene_loader.lock(); - - if let Some(entry) = loader.get_entry(scene_handle.id as u64) { - *out_status = entry.result.clone().into(); - DropbearNativeError::Success as i32 - } else { - DropbearNativeError::GenericError as i32 - } -} @@ -1,12 +0,0 @@ -use std::ffi::{c_char}; - -/// A double-precision floating point number. Convenient! -pub type Double = f64; - -/// The sister to [`crate::utils::Progress`], which provides C-compatible values. -#[repr(C)] -pub struct Progress { - pub current: Double, - pub total: Double, - pub message: *mut c_char, -} @@ -20,7 +20,7 @@ use std::fmt; use std::fmt::{Display, Formatter}; use std::ops::{Deref, DerefMut}; use std::path::PathBuf; -use hecs::World; +use hecs::{Entity, World}; use crate::properties::Value; /// A global "singleton" that contains the configuration of a project. @@ -279,15 +279,11 @@ pub enum WorldLoadingStatus { Completed, } -#[derive(Clone, Serialize, Deserialize, bincode::Encode, bincode::Decode)] +#[derive(Clone, Serialize, Deserialize)] pub struct RuntimeData { - #[bincode(with_serde)] pub project_config: ProjectConfig, - #[bincode(with_serde)] pub source_config: SourceConfig, - #[bincode(with_serde)] pub scene_data: Vec<SceneConfig>, - #[bincode(with_serde)] pub scripts: HashMap<String, String>, } @@ -332,7 +328,7 @@ impl Label { } pub fn locate_entity(&self, world: &World) -> Option<hecs::Entity> { - world.query::<&Label>().iter().find_map(|(e, l)| if l == self { Some(e.clone()) } else { None }) + world.query::<(Entity, &Label)>().iter().find_map(|(e, l)| if l == self { Some(e.clone()) } else { None }) } } @@ -152,7 +152,7 @@ pub mod jni { use jni::JNIEnv; #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_EntityTransformNative_entityTransformExistsForEntity( + pub extern "system" fn Java_com_dropbear_components_EntityTransformNative_entityTransformExistsForEntity( _env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -165,7 +165,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_EntityTransformNative_getLocalTransform( + pub extern "system" fn Java_com_dropbear_components_EntityTransformNative_getLocalTransform( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -186,7 +186,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_EntityTransformNative_setLocalTransform( + pub extern "system" fn Java_com_dropbear_components_EntityTransformNative_setLocalTransform( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -212,7 +212,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_EntityTransformNative_getWorldTransform( + pub extern "system" fn Java_com_dropbear_components_EntityTransformNative_getWorldTransform( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -233,7 +233,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_EntityTransformNative_setWorldTransform( + pub extern "system" fn Java_com_dropbear_components_EntityTransformNative_setWorldTransform( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -256,7 +256,7 @@ pub mod jni { } #[unsafe(no_mangle)] - pub fn Java_com_dropbear_components_EntityTransformNative_propagateTransform( + pub extern "system" fn Java_com_dropbear_components_EntityTransformNative_propagateTransform( mut env: JNIEnv, _class: JClass, world_ptr: jlong, @@ -13,7 +13,7 @@ magna-carta = { path = "../magna-carta" } anyhow.workspace = true app_dirs2.workspace = true -bincode.workspace = true +postcard.workspace = true bytemuck.workspace = true dropbear-engine.workspace = true egui-toast.workspace = true @@ -76,7 +76,8 @@ pub fn build(project_config: PathBuf) -> anyhow::Result<PathBuf> { // export to .eupak let eupak_path = build_dir.join("data.eupak"); - let config_bytes = bincode::encode_to_vec(&runtime_config, bincode::config::standard())?; + const SIZE_OF_RUNTIME_PROJECT_CONFIG: usize = size_of::<RuntimeProjectConfig>(); + let config_bytes = postcard::to_vec::<RuntimeProjectConfig, SIZE_OF_RUNTIME_PROJECT_CONFIG>(&runtime_config)?; fs::write(&eupak_path, config_bytes)?; log::debug!("Exported scene config to {:?}", eupak_path); @@ -113,7 +114,7 @@ fn copy_dir_recursive(src: &Path, dst: &Path) -> anyhow::Result<()> { pub fn read(eupak: PathBuf) -> anyhow::Result<RuntimeProjectConfig> { let bytes = std::fs::read(&eupak)?; let (content, _): (RuntimeProjectConfig, usize) = - bincode::decode_from_slice(&bytes, bincode::config::standard())?; + postcard::from_bytes(&bytes)?; let str = ron::ser::to_string_pretty(&content, PrettyConfig::default())?; @@ -273,19 +273,13 @@ impl<'a> TabViewer for EditorTabViewer<'a> { let active_cam = self.active_camera.lock(); if let Some(active_camera) = *active_cam { let camera_data = { - if let Ok(mut q) = self + if let Ok((cam, comp)) = self .world - .query_one::<(&Camera, &CameraComponent)>(active_camera) + .query_one::<(&Camera, &CameraComponent)>(active_camera).get() { - let val = q.get(); - if let Some(val) = val { - Some(val.0.clone()) - } else { - log::warn!("Queried camera but unable to get value"); - - None - } + Some(cam.clone()) } else { + log::warn!("Queried camera but found no value"); None } }; @@ -308,8 +302,7 @@ impl<'a> TabViewer for EditorTabViewer<'a> { { let mut handled = false; - if let Ok(mut q) = self.world.query_one::<&mut EntityTransform>(*entity_id) - && let Some(entity_transform) = q.get() + if let Ok(entity_transform) = self.world.query_one::<&mut EntityTransform>(*entity_id).get() { let was_focused = cfg.is_focused; cfg.is_focused = self.gizmo.is_focused(); @@ -394,8 +387,7 @@ impl<'a> TabViewer for EditorTabViewer<'a> { } if !handled { - if let Ok(mut q) = self.world.query_one::<&mut Transform>(*entity_id) - && let Some(transform) = q.get() + if let Ok(transform) = self.world.query_one::<&mut Transform>(*entity_id).get() { let was_focused = cfg.is_focused; cfg.is_focused = self.gizmo.is_focused(); @@ -470,8 +462,7 @@ impl<'a> TabViewer for EditorTabViewer<'a> { signal: &mut Signal, ) -> anyhow::Result<()> { let entity_id = entity.to_bits().get(); - let label = if let Ok(mut q) = world.query_one::<&Label>(entity) - && let Some(label) = q.get() + let label = if let Ok(label) = world.query_one::<&Label>(entity).get() { label.clone() } else { @@ -620,10 +611,10 @@ impl<'a> TabViewer for EditorTabViewer<'a> { let root_entities: Vec<Entity> = self .world - .query::<()>() + .query::<Entity>() .without::<&Parent>() .iter() - .map(|(e, _)| e) + .map(|e| e) .collect(); for entity in root_entities { @@ -681,254 +672,245 @@ impl<'a> TabViewer for EditorTabViewer<'a> { let world = &self.world; if !cfg.root_node_selected { - if let Ok(mut q) = world.query_one::<(&mut Label,)>(inspect_entity) { - if let Some((label, )) = q.get() { - label.inspect( - &mut inspect_entity, - &mut cfg, - ui, - self.undo_stack, - self.signal, - &mut String::new(), - ); + if let Ok((label, )) = world.query_one::<(&mut Label,)>(inspect_entity).get() { + label.inspect( + &mut inspect_entity, + &mut cfg, + ui, + self.undo_stack, + self.signal, + &mut String::new(), + ); - ui.label(format!("Entity ID: {}", inspect_entity.id())); + ui.label(format!("Entity ID: {}", inspect_entity.id())); - ui.separator(); + ui.separator(); - // mesh renderer - if let Ok(mut q) = world.query_one::<&mut MeshRenderer>(inspect_entity) - && let Some(e) = q.get() - { - CollapsingHeader::new("MeshRenderer").default_open(true).show(ui, |ui| { - e.inspect( - &mut inspect_entity, - &mut cfg, - ui, - self.undo_stack, - self.signal, - &mut String::new(), - ); - }); - } + // mesh renderer + if let Ok(e) = world.query_one::<&mut MeshRenderer>(inspect_entity).get() + { + CollapsingHeader::new("MeshRenderer").default_open(true).show(ui, |ui| { + e.inspect( + &mut inspect_entity, + &mut cfg, + ui, + self.undo_stack, + self.signal, + &mut String::new(), + ); + }); + } - // entity transform - if let Ok(mut q) = world.query_one::<&mut EntityTransform>(inspect_entity) - && let Some(t) = q.get() - { - CollapsingHeader::new("Transform").default_open(true).show(ui, |ui| { - t.inspect( - &mut inspect_entity, - &mut cfg, - ui, - self.undo_stack, - self.signal, - &mut String::new(), - ); - }); - ui.separator(); - } + // entity transform + if let Ok(t) = world.query_one::<&mut EntityTransform>(inspect_entity).get() + { + CollapsingHeader::new("Transform").default_open(true).show(ui, |ui| { + t.inspect( + &mut inspect_entity, + &mut cfg, + ui, + self.undo_stack, + self.signal, + &mut String::new(), + ); + }); + ui.separator(); + } - // custom properties - if let Ok(mut q) = world.query_one::<&mut CustomProperties>(inspect_entity) - && let Some(props) = q.get() - { - CollapsingHeader::new("Custom Properties").default_open(true).show(ui, |ui| { - props.inspect( - &mut inspect_entity, - &mut cfg, - ui, - self.undo_stack, - self.signal, - label.as_mut_string(), - ); - }); - ui.separator(); - } + // custom properties + if let Ok(props) = world.query_one::<&mut CustomProperties>(inspect_entity).get() + { + CollapsingHeader::new("Custom Properties").default_open(true).show(ui, |ui| { + props.inspect( + &mut inspect_entity, + &mut cfg, + ui, + self.undo_stack, + self.signal, + label.as_mut_string(), + ); + }); + ui.separator(); + } - // camera - if let Ok(mut q) = world - .query_one::<(&mut Camera, &mut CameraComponent)>(inspect_entity) - && let Some((camera, camera_component)) = q.get() - { - CollapsingHeader::new("Camera").default_open(true).show(ui, |ui| { - camera.inspect( - &mut inspect_entity, - &mut cfg, - ui, - self.undo_stack, - self.signal, - &mut String::new(), - ); + // camera + if let Ok((camera, camera_component)) = world + .query_one::<(&mut Camera, &mut CameraComponent)>(inspect_entity).get() + { + CollapsingHeader::new("Camera").default_open(true).show(ui, |ui| { + camera.inspect( + &mut inspect_entity, + &mut cfg, + ui, + self.undo_stack, + self.signal, + &mut String::new(), + ); - ui.separator(); + ui.separator(); - camera_component.inspect( - &mut inspect_entity, - &mut cfg, - ui, - self.undo_stack, - self.signal, - &mut camera.label.clone(), - ); + camera_component.inspect( + &mut inspect_entity, + &mut cfg, + ui, + self.undo_stack, + self.signal, + &mut camera.label.clone(), + ); - ui.separator(); + ui.separator(); - // camera controller - let mut active_camera = self.active_camera.lock(); + // camera controller + let mut active_camera = self.active_camera.lock(); - if active_camera.equivalent(&Some(*entity)) { - ui.label("Status: Currently viewing through camera"); - } else { - ui.label("Status: Not viewing through this camera"); - } + if active_camera.equivalent(&Some(*entity)) { + ui.label("Status: Currently viewing through camera"); + } else { + ui.label("Status: Not viewing through this camera"); + } - if ui.button("Set as active camera").clicked() { - *active_camera = Some(*entity); - log::info!( + if ui.button("Set as active camera").clicked() { + *active_camera = Some(*entity); + log::info!( "Currently viewing from camera angle '{}'", camera.label ); - } + } - if camera_component.starting_camera { - if ui.button("Stop making camera initial").clicked() { - log::debug!("'Stop making camera initial' button clicked"); - camera_component.starting_camera = false; - success!("Removed {} from starting camera", camera.label); - } - } else if ui.button("Set as initial camera").clicked() { - log::debug!("'Set as initial camera' button clicked"); - if matches!(camera_component.camera_type, CameraType::Debug) { - warn!( + if camera_component.starting_camera { + if ui.button("Stop making camera initial").clicked() { + log::debug!("'Stop making camera initial' button clicked"); + camera_component.starting_camera = false; + success!("Removed {} from starting camera", camera.label); + } + } else if ui.button("Set as initial camera").clicked() { + log::debug!("'Set as initial camera' button clicked"); + if matches!(camera_component.camera_type, CameraType::Debug) { + warn!( "Cannot set any cameras of type 'Debug' to initial camera" ); - } else { - local_set_initial_camera = true - } + } else { + local_set_initial_camera = true } - }); - ui.separator(); - } + } + }); + ui.separator(); + } - // light - if let Ok(mut q) = world.query_one::<(&mut Light, &mut LightComponent, &mut Transform)>(inspect_entity) - && let Some((light, comp, transform)) = q.get() - { - light.transform = *transform; - light.light_component = comp.clone(); + // light + if let Ok((light, comp, transform)) = world.query_one::<(&mut Light, &mut LightComponent, &mut Transform)>(inspect_entity).get() + { + light.transform = *transform; + light.light_component = comp.clone(); + + light.inspect( + entity, + &mut cfg, + ui, + self.undo_stack, + self.signal, + &mut String::new(), + ); - light.inspect( + *transform = light.transform; + *comp = light.light_component.clone(); + ui.separator(); + } + + // script + if let Ok(script) = world.query_one::<&mut Script>(*entity).get() + { + CollapsingHeader::new("Script").default_open(true).show(ui, |ui| { + script.inspect( entity, &mut cfg, ui, self.undo_stack, self.signal, - &mut String::new(), + label.as_mut_string(), ); + }); + ui.separator(); + } - *transform = light.transform; - *comp = light.light_component.clone(); - ui.separator(); - } - - // script - if let Ok(mut q) = world.query_one::<&mut Script>(*entity) - && let Some(script) = q.get() - { - CollapsingHeader::new("Script").default_open(true).show(ui, |ui| { - script.inspect( - entity, - &mut cfg, - ui, - self.undo_stack, - self.signal, - label.as_mut_string(), - ); - }); - ui.separator(); - } - - // physics - if let Ok(mut q) = world.query_one::<(Option<&mut RigidBody>, Option<&mut ColliderGroup>, Option<&mut KCC>)>(*entity) - && let Some((rigid, colliders, kcc)) = q.get() - { - if rigid.is_some() || colliders.is_some() || kcc.is_some() { - CollapsingHeader::new("Physics").default_open(true).show(ui, |ui| { + // physics + if let Ok((rigid, colliders, kcc)) = world.query_one::<(Option<&mut RigidBody>, Option<&mut ColliderGroup>, Option<&mut KCC>)>(*entity).get() + { + if rigid.is_some() || colliders.is_some() || kcc.is_some() { + CollapsingHeader::new("Physics").default_open(true).show(ui, |ui| { + + if let Some(kcc) = kcc { + CollapsingHeader::new("Kinematic Character Controller").default_open(true).show(ui, |ui| { + kcc.inspect( + entity, + &mut cfg, + ui, + self.undo_stack, + self.signal, + label.as_mut_string(), + ); + }); + ui.separator(); + } - if let Some(kcc) = kcc { - CollapsingHeader::new("Kinematic Character Controller").default_open(true).show(ui, |ui| { - kcc.inspect( - entity, - &mut cfg, - ui, - self.undo_stack, - self.signal, - label.as_mut_string(), - ); - }); - ui.separator(); - } + if let Some(rigid) = rigid { + CollapsingHeader::new("RigidBody").default_open(true).show(ui, |ui| { + rigid.inspect( + entity, + &mut cfg, + ui, + self.undo_stack, + self.signal, + label.as_mut_string(), + ); + }); + ui.separator(); + } - if let Some(rigid) = rigid { - CollapsingHeader::new("RigidBody").default_open(true).show(ui, |ui| { - rigid.inspect( - entity, - &mut cfg, - ui, - self.undo_stack, - self.signal, - label.as_mut_string(), - ); - }); - ui.separator(); - } + if let Some(col) = colliders { + CollapsingHeader::new("Colliders").default_open(true).show(ui, |ui| { + let mut to_remove: Option<usize> = None; + + for (index, c) in col.colliders.iter_mut().enumerate() { + ui.horizontal(|ui| { + let header = CollapsingHeader::new(format!("Collider {}", index + 1)) + .default_open(true); + + header.show(ui, |ui| { + c.inspect( + entity, + &mut cfg, + ui, + self.undo_stack, + self.signal, + label.as_mut_string(), + ); + }); - if let Some(col) = colliders { - CollapsingHeader::new("Colliders").default_open(true).show(ui, |ui| { - let mut to_remove: Option<usize> = None; - - for (index, c) in col.colliders.iter_mut().enumerate() { - ui.horizontal(|ui| { - let header = CollapsingHeader::new(format!("Collider {}", index + 1)) - .default_open(true); - - header.show(ui, |ui| { - c.inspect( - entity, - &mut cfg, - ui, - self.undo_stack, - self.signal, - label.as_mut_string(), - ); - }); - - ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { - if ui.button("🗑").on_hover_text("Remove collider").clicked() { - to_remove = Some(index); - } - }); + ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { + if ui.button("🗑").on_hover_text("Remove collider").clicked() { + to_remove = Some(index); + } }); + }); - ui.separator(); - } + ui.separator(); + } - if let Some(index) = to_remove { - col.colliders.remove(index); - } + if let Some(index) = to_remove { + col.colliders.remove(index); + } - if ui.button("➕ Add new collider").clicked() { - local_add_collider = Some(*entity); - } - }); - } + if ui.button("➕ Add new collider").clicked() { + local_add_collider = Some(*entity); + } + }); + } - ui.separator(); - }); - } - ui.separator(); + ui.separator(); + }); } + ui.separator(); } } else { log_once::debug_once!("Unable to query entity inside resource inspector"); @@ -936,7 +918,7 @@ impl<'a> TabViewer for EditorTabViewer<'a> { } if local_set_initial_camera { - for (id, comp) in self.world.query::<&mut CameraComponent>().iter() { + for (id, comp) in self.world.query::<(Entity, &mut CameraComponent)>().iter() { comp.starting_camera = false; self.undo_stack .push(UndoableAction::RemoveStartingCamera(id)) @@ -959,8 +941,7 @@ impl<'a> TabViewer for EditorTabViewer<'a> { if let Some(e) = local_add_collider { let mut manual_edit = false; - if let Ok(mut q) = self.world.query_one::<Option<&mut ColliderGroup>>(e) - && let Some(col) = q.get() + if let Ok(col) = self.world.query_one::<Option<&mut ColliderGroup>>(e).get() { if let Some(col) = col { let mut collider = Collider::new(); @@ -190,35 +190,29 @@ impl Keyboard for Editor { && matches!(tab, EditorTab::ModelEntityList) { if let Some(entity) = &self.selected_entity { - let query = self.world.query_one::<( + let mut query = self.world.query_one::<( &Label, &MeshRenderer, &EntityTransform, &CustomProperties, )>(*entity); - if let Ok(mut q) = query { - if let Some((label, renderer, t, props)) = q.get() { - let s_entity = SceneEntity { - label: label.clone(), - components: vec![ - Box::new(props.clone()), - Box::new(SerializedMeshRenderer::from_renderer( - &renderer, - )), - Box::new(t.clone()), - ], - entity_id: None, - }; - self.signal = Signal::Copy(s_entity); + if let Ok((label, renderer, t, props)) = query.get() { + let s_entity = SceneEntity { + label: label.clone(), + components: vec![ + Box::new(props.clone()), + Box::new(SerializedMeshRenderer::from_renderer( + &renderer, + )), + Box::new(t.clone()), + ], + entity_id: None, + }; + self.signal = Signal::Copy(s_entity); - info!("Copied!"); + info!("Copied!"); - log::debug!("Copied selected entity"); - } else { - warn!( - "Unable to copy entity: Unable to fetch world entity properties" - ); - } + log::debug!("Copied selected entity"); } else { warn!("Unable to copy entity: Unable to obtain lock"); } @@ -355,10 +349,9 @@ impl Mouse for Editor { } if let Some(active_camera) = *self.active_camera.lock() - && let Ok(mut q) = self + && let Ok((camera, _)) = self .world - .query_one::<(&mut Camera, &CameraComponent)>(active_camera) - && let Some((camera, _)) = q.get() + .query_one::<(&mut Camera, &CameraComponent)>(active_camera).get() { if let Some((dx, dy)) = delta { camera.track_mouse_delta(dx, dy); @@ -294,7 +294,7 @@ impl Editor { let labels = self .world - .query::<&Label>() + .query::<(Entity, &Label)>() .iter() .map(|(e, l)| (e, l.clone())) .collect::<Vec<_>>(); @@ -522,9 +522,9 @@ impl Editor { } else { let existing_debug_camera = { world - .query::<(&Camera, &CameraComponent)>() + .query::<(Entity, &Camera, &CameraComponent)>() .iter() - .find_map(|(entity, (_, component))| { + .find_map(|(entity, _, component)| { if matches!(component.camera_type, CameraType::Debug) { Some(entity) } else { @@ -888,34 +888,30 @@ impl Editor { ui.menu_button("Edit", |ui| { if ui.button("Copy").clicked() { if let Some(entity) = &self.selected_entity { - let query = self.world.query_one::<( + let mut query = self.world.query_one::<( &Label, &MeshRenderer, &EntityTransform, &CustomProperties, )>(*entity); - if let Ok(mut q) = query { - if let Some((entity_label, renderer, transform, props)) = q.get() { - let mut components: Vec<Box<dyn SerializableComponent>> = Vec::new(); + if let Ok((entity_label, renderer, transform, props)) = query.get() { + let mut components: Vec<Box<dyn SerializableComponent>> = Vec::new(); - components.push(Box::new(*transform)); + components.push(Box::new(*transform)); - let serialized_renderer = SerializedMeshRenderer::from_renderer(renderer); - components.push(Box::new(serialized_renderer)); + let serialized_renderer = SerializedMeshRenderer::from_renderer(renderer); + components.push(Box::new(serialized_renderer)); - components.push(Box::new(props.clone())); + components.push(Box::new(props.clone())); - let s_entity = SceneEntity { - label: entity_label.clone(), - components, - entity_id: None, - }; - self.signal = Signal::Copy(s_entity); + let s_entity = SceneEntity { + label: entity_label.clone(), + components, + entity_id: None, + }; + self.signal = Signal::Copy(s_entity); - info!("Copied selected entity!"); - } else { - warn!("Unable to copy entity: Unable to fetch world entity properties"); - } + info!("Copied selected entity!"); } else { warn!("Unable to copy entity: Unable to obtain lock"); } @@ -1185,16 +1181,17 @@ impl Editor { pub fn create_backup(&mut self) -> anyhow::Result<()> { let mut entities = Vec::new(); - for (entity_id, (mesh_renderer, transform, properties)) in self + for (entity_id, mesh_renderer, transform, properties) in self .world - .query::<(&MeshRenderer, &EntityTransform, &CustomProperties)>() + .query::<(Entity, &MeshRenderer, &EntityTransform, &CustomProperties)>() .iter() { let script = self .world .query_one::<&Script>(entity_id) + .get() .ok() - .and_then(|mut s| s.get().cloned()); + .cloned(); entities.push(( entity_id, mesh_renderer.clone(), @@ -1206,8 +1203,8 @@ impl Editor { let mut camera_data = Vec::new(); - for (entity_id, (camera, component)) in - self.world.query::<(&Camera, &CameraComponent)>().iter() + for (entity_id, camera, component) in + self.world.query::<(Entity, &Camera, &CameraComponent)>().iter() { camera_data.push((entity_id, camera.clone(), component.clone())); } @@ -1232,9 +1229,9 @@ impl Editor { pub fn switch_to_debug_camera(&mut self) { let debug_camera = self .world - .query::<(&Camera, &CameraComponent)>() + .query::<(Entity, &Camera, &CameraComponent)>() .iter() - .find_map(|(e, (_cam, comp))| { + .find_map(|(e, _, comp)| { if matches!(comp.camera_type, CameraType::Debug) { Some(e) } else { @@ -1254,10 +1251,10 @@ impl Editor { pub fn switch_to_player_camera(&mut self) { let player_camera = self .world - .query::<(&Camera, &CameraComponent)>() + .query::<(Entity, &Camera, &CameraComponent)>() .iter() .find_map( - |(e, (_cam, comp))| { + |(e, _, comp)| { if comp.starting_camera { Some(e) } else { None } }, ); @@ -1274,10 +1271,9 @@ impl Editor { pub fn is_using_debug_camera(&self) -> bool { let active_camera = self.active_camera.lock(); if let Some(active_camera_entity) = *active_camera - && let Ok(mut query) = self + && let Ok(component) = self .world - .query_one::<&CameraComponent>(active_camera_entity) - && let Some(component) = query.get() + .query_one::<&CameraComponent>(active_camera_entity).get() { return matches!(component.camera_type, CameraType::Debug); } @@ -1299,55 +1295,49 @@ impl Editor { .create_light_array_resources(graphics.shared.clone()); if let Some(active_camera) = *self.active_camera.lock() { - if let Ok(mut q) = self + if let Ok((camera, _)) = self .world .query_one::<(&Camera, &CameraComponent)>(active_camera) + .get() { - if let Some((camera, _component)) = q.get() { - let pipeline = graphics.create_render_pipline( - &shader, - vec![ - &graphics.shared.texture_bind_layout.clone(), - camera.layout(), - self.light_manager.layout(), - &graphics.shared.material_tint_bind_layout.clone(), - ], - None, - ); - self.render_pipeline = Some(pipeline); - - // log::debug!("Contents of light shader: \n{:#?}", dropbear_engine::shader::shader_wesl::LIGHT_SHADER); - self.light_manager.create_render_pipeline( - graphics.shared.clone(), - dropbear_engine::shader::shader_wesl::LIGHT_SHADER, - camera, - Some("Light Pipeline"), - ); - - self.light_manager.create_shadow_pipeline( - graphics.shared.clone(), - dropbear_engine::shader::shader_wesl::SHADOW_SHADER, - Some("Shadow Pipeline"), - ); - - // log::debug!("Contents of outline shader: \n{:#?}", dropbear_engine::shader::shader_wesl::OUTLINE_SHADER); - let outline_shader = - OutlineShader::init(graphics.shared.clone(), camera.layout()); - self.outline_pipeline = Some(outline_shader); - - let collider_pipeline = ColliderWireframePipeline::new(graphics.shared.clone(), camera.layout()); - self.collider_wireframe_pipeline = Some(collider_pipeline); - - self.mipmap_generator = Some(MipMapGenerator::new(graphics.shared.clone())) - } else { - log_once::warn_once!( - "Unable to fetch the query result of camera: {:?}", - active_camera - ) - } + let pipeline = graphics.create_render_pipline( + &shader, + vec![ + &graphics.shared.texture_bind_layout.clone(), + camera.layout(), + self.light_manager.layout(), + &graphics.shared.material_tint_bind_layout.clone(), + ], + None, + ); + self.render_pipeline = Some(pipeline); + + // log::debug!("Contents of light shader: \n{:#?}", dropbear_engine::shader::shader_wesl::LIGHT_SHADER); + self.light_manager.create_render_pipeline( + graphics.shared.clone(), + dropbear_engine::shader::shader_wesl::LIGHT_SHADER, + camera, + Some("Light Pipeline"), + ); + + self.light_manager.create_shadow_pipeline( + graphics.shared.clone(), + dropbear_engine::shader::shader_wesl::SHADOW_SHADER, + Some("Shadow Pipeline"), + ); + + // log::debug!("Contents of outline shader: \n{:#?}", dropbear_engine::shader::shader_wesl::OUTLINE_SHADER); + let outline_shader = + OutlineShader::init(graphics.shared.clone(), camera.layout()); + self.outline_pipeline = Some(outline_shader); + + let collider_pipeline = ColliderWireframePipeline::new(graphics.shared.clone(), camera.layout()); + self.collider_wireframe_pipeline = Some(collider_pipeline); + + self.mipmap_generator = Some(MipMapGenerator::new(graphics.shared.clone())) } else { log_once::warn_once!( - "Unable to query camera, component and option<camerafollowtarget> for active camera: {:?}", + "Unable to query Camera and CameraComponent for active camera: {:?}", active_camera ); } @@ -1453,27 +1443,19 @@ impl UndoableAction { pub fn undo(&self, world: &mut World) -> anyhow::Result<()> { match self { UndoableAction::Transform(entity, transform) => { - if let Ok(mut q) = world.query_one::<&mut Transform>(*entity) { - if let Some(e_t) = q.get() { - *e_t = *transform; - log::debug!("Reverted transform"); - Ok(()) - } else { - Err(anyhow::anyhow!("Unable to query the entity")) - } + if let Ok(e_t) = world.query_one::<&mut Transform>(*entity).get() { + *e_t = *transform; + log::debug!("Reverted transform"); + Ok(()) } else { Err(anyhow::anyhow!("Could not find an entity to query")) } } UndoableAction::EntityTransform(entity, transform) => { - if let Ok(mut q) = world.query_one::<&mut EntityTransform>(*entity) { - if let Some(e_t) = q.get() { - *e_t = *transform; - log::debug!("Reverted entity transform"); - Ok(()) - } else { - Err(anyhow::anyhow!("Unable to query the entity")) - } + if let Ok(e_t) = world.query_one::<&mut EntityTransform>(*entity).get() { + *e_t = *transform; + log::debug!("Reverted entity transform"); + Ok(()) } else { Err(anyhow::anyhow!("Could not find an entity to query")) } @@ -1495,7 +1477,7 @@ impl UndoableAction { } } UndoableAction::RemoveStartingCamera(old) => { - for (_i, comp) in &mut world.query::<&mut CameraComponent>() { + for comp in &mut world.query::<&mut CameraComponent>() { comp.starting_camera = false; } if let Ok((cam, comp)) = @@ -219,10 +219,9 @@ impl Scene for Editor { { let active_cam = self.active_camera.lock(); if let Some(active_camera) = *active_cam - && let Ok(mut query) = self + && let Ok((camera, _)) = self .world - .query_one::<(&mut Camera, &CameraComponent)>(active_camera) - && let Some((camera, _)) = query.get() + .query_one::<(&mut Camera, &CameraComponent)>(active_camera).get() { for key in &self.input_state.pressed_keys { match key { @@ -242,15 +241,13 @@ impl Scene for Editor { if let Some(e) = self.previously_selected_entity - && let Ok(mut q) = self.world.query_one::<&mut MeshRenderer>(e) - && let Some(entity) = q.get() + && let Ok(entity) = self.world.query_one::<&mut MeshRenderer>(e).get() { entity.is_selected = false } if let Some(e) = self.selected_entity - && let Ok(mut q) = self.world.query_one::<&mut MeshRenderer>(e) - && let Some(entity) = q.get() + && let Ok(entity) = self.world.query_one::<&mut MeshRenderer>(e).get() { entity.is_selected = true } @@ -265,8 +262,7 @@ impl Scene for Editor { let world = self.world.as_mut(); if let Some(active_camera) = active_camera - && let Ok(mut query) = world.query_one::<&mut Camera>(active_camera) - && let Some(camera) = query.get() + && let Ok(camera) = world.query_one::<&mut Camera>(active_camera).get() { camera.aspect = new_aspect; } @@ -275,8 +271,8 @@ impl Scene for Editor { { let sim_world = self.world.as_mut(); - for (_entity_id, (camera, component)) in sim_world - .query::<(&mut Camera, &mut CameraComponent)>() + for (_entity_id, camera, component) in sim_world + .query::<(Entity, &mut Camera, &mut CameraComponent)>() .iter() { component.update(camera); @@ -289,14 +285,14 @@ impl Scene for Editor { { let query = sim_world.query_mut::<(&mut MeshRenderer, &Transform)>(); - for (_, (renderer, transform)) in query { + for (renderer, transform) in query { renderer.update(transform); } } { let mut updates = Vec::new(); - for (entity, transform) in sim_world.query::<&EntityTransform>().iter() { + for (entity, transform) in sim_world.query::<(Entity, &EntityTransform)>().iter() { let final_transform = transform.propagate(sim_world, entity); updates.push((entity, final_transform)); } @@ -316,7 +312,7 @@ impl Scene for Editor { &mut Light, )>(); - for (_, (light_component, transform_opt, entity_transform_opt, light)) in light_query { + for (light_component, transform_opt, entity_transform_opt, light) in light_query { let transform = if let Some(entity_transform) = entity_transform_opt { entity_transform.sync() } else if let Some(transform) = transform_opt { @@ -369,18 +365,14 @@ impl Scene for Editor { if let Some(active_camera) = active_camera { let cam = { - if let Ok(mut query) = world.query_one::<&Camera>(active_camera) { - query.get().cloned() - } else { - None - } + world.query_one::<&Camera>(active_camera).get().ok().cloned() }; if let Some(camera) = cam { let lights = { let mut lights = Vec::new(); let mut light_query = world.query::<(&Light, &LightComponent)>(); - for (_, (light, comp)) in light_query.iter() { + for (light, comp) in light_query.iter() { lights.push((light.clone(), comp.clone())); } lights @@ -389,7 +381,7 @@ impl Scene for Editor { let entities = { let mut entities = Vec::new(); let mut entity_query = world.query::<&MeshRenderer>(); - for (_, renderer) in entity_query.iter() { + for renderer in entity_query.iter() { entities.push(renderer.clone()); } entities @@ -551,7 +543,7 @@ impl Scene for Editor { HashMap::new(); let mut q = self.world.query::<(&EntityTransform, &ColliderGroup)>(); - for (_entity, (entity_transform, group)) in q.iter() { + for (entity_transform, group) in q.iter() { for collider in &group.colliders { let world_tf = entity_transform.sync(); @@ -50,7 +50,7 @@ impl InspectableComponent for KCC { ui.vertical(|ui| { ui.label("Up Vector:"); - let up = *self.controller.up; + let up = self.controller.up; let mut up_v = Vector3::new(up.x, up.y, up.z); ui.horizontal(|ui| { @@ -63,7 +63,7 @@ impl InspectableComponent for KCC { }); if up_v.norm_squared() > 0.0 { - self.controller.up = UnitVector3::new_normalize(up_v); + self.controller.up = UnitVector3::new_normalize(up_v).into(); } ui.add_space(8.0); @@ -176,59 +176,54 @@ impl PlayMode { self.light_manager .create_light_array_resources(graphics.shared.clone()); - if let Some(active_camera) = self.active_camera { - if let Ok(mut q) = self - .world - .query_one::<(&Camera, &CameraComponent)>(active_camera) - { - if let Some((camera, _component)) = q.get() { - let pipeline = graphics.create_render_pipline( - &shader, - vec![ - &graphics.shared.texture_bind_layout.clone(), - camera.layout(), - self.light_manager.layout(), - &graphics.shared.material_tint_bind_layout.clone(), - ], - None, - ); - self.render_pipeline = Some(pipeline); - - self.light_manager.create_render_pipeline( - graphics.shared.clone(), - dropbear_engine::shader::shader_wesl::LIGHT_SHADER, - camera, - Some("Light Pipeline"), - ); - - self.light_manager.create_shadow_pipeline( - graphics.shared.clone(), - dropbear_engine::shader::shader_wesl::SHADOW_SHADER, - Some("Shadow Pipeline"), - ); - - let collider_pipeline = ColliderWireframePipeline::new(graphics.shared.clone(), camera.layout()); - self.collider_wireframe_pipeline = Some(collider_pipeline); - } else { - log_once::warn_once!( - "Unable to fetch the query result of camera: {:?}", - active_camera - ) - } - } else { - log_once::warn_once!( + let Some(active_camera) = self.active_camera else { + log_once::warn_once!("No active camera found"); + return; + }; + + if let Ok((camera, _component)) = self + .world + .query_one::<(&Camera, &CameraComponent)>(active_camera) + .get() + { + let pipeline = graphics.create_render_pipline( + &shader, + vec![ + &graphics.shared.texture_bind_layout.clone(), + camera.layout(), + self.light_manager.layout(), + &graphics.shared.material_tint_bind_layout.clone(), + ], + None, + ); + self.render_pipeline = Some(pipeline); + + self.light_manager.create_render_pipeline( + graphics.shared.clone(), + dropbear_engine::shader::shader_wesl::LIGHT_SHADER, + camera, + Some("Light Pipeline"), + ); + + self.light_manager.create_shadow_pipeline( + graphics.shared.clone(), + dropbear_engine::shader::shader_wesl::SHADOW_SHADER, + Some("Shadow Pipeline"), + ); + + let collider_pipeline = ColliderWireframePipeline::new(graphics.shared.clone(), camera.layout()); + self.collider_wireframe_pipeline = Some(collider_pipeline); + } else { + log_once::warn_once!( "Unable to query camera, component for active camera: {:?}", active_camera ); - } - } else { - log_once::warn_once!("No active camera found"); } } fn reload_scripts_for_current_world(&mut self) { let mut entity_tag_map: HashMap<String, Vec<Entity>> = HashMap::new(); - for (entity_id, script) in self.world.query::<&Script>().iter() { + for (entity_id, script) in self.world.query::<(Entity, &Script)>().iter() { for tag in &script.tags { entity_tag_map.entry(tag.clone()).or_default().push(entity_id); } @@ -3,8 +3,8 @@ use egui::{CentralPanel, MenuBar, TopBottomPanel}; use eucalyptus_core::physics::collider::ColliderGroup; use eucalyptus_core::physics::collider::ColliderShapeKey; use eucalyptus_core::physics::collider::shader::ColliderInstanceRaw; -use glam::{DMat4, DQuat, DVec3}; -use hecs::Entity; +use glam::{DMat4, DQuat, DVec3, Quat}; +use hecs::{Entity, QueryOneError}; use wgpu::Color; use wgpu::util::DeviceExt; use winit::event_loop::ActiveEventLoop; @@ -50,11 +50,11 @@ impl Scene for PlayMode { let _ = self.script_manager.physics_update_script(self.world.as_mut(), dt as f64); } - for (_, kcc) in self.world.query::<&mut KCC>().iter() { + for kcc in self.world.query::<&mut KCC>().iter() { kcc.collisions.clear(); } - for (e, (l, _)) in self.world.query::<(&Label, &KCC)>().iter() { + for (e, l, _) in self.world.query::<(Entity, &Label, &KCC)>().iter() { log_once::debug_once!("This entity [{:?}, label = {}] has the KCC (KinematicCharacterController) component attached", e, l); } @@ -78,12 +78,14 @@ impl Scene for PlayMode { kcc.collisions = collisions.clone(); } - let (label, kcc_controller) = match self.world.query_one::<(&Label, &KCC)>(entity) { - Ok(mut q) => match q.get() { - Some((label, kcc)) => (label.clone(), kcc.controller.clone()), - None => continue, - }, - Err(_) => continue, + let (label, kcc_controller) = match self.world.query_one::<(&Label, &KCC)>(entity).get() { + Ok(v) => { + (v.0.clone(), v.1.clone()) + } + Err(e) => { + log_once::warn_once!("Unable to query {:?}: {}", entity, e); + continue; + } }; let Some(rigid_body_handle) = self.physics_state.bodies_entity_map.get(&label).copied() else { @@ -124,7 +126,7 @@ impl Scene for PlayMode { filter, ); - kcc_controller.solve_character_collision_impulses( + kcc_controller.controller.solve_character_collision_impulses( dt, &mut query_pipeline_mut, character_shape.as_ref(), @@ -135,7 +137,7 @@ impl Scene for PlayMode { } let mut entity_label_map = HashMap::new(); - for (entity, label) in self.world.query::<&Label>().iter() { + for (entity, label) in self.world.query::<(Entity, &Label)>().iter() { entity_label_map.insert(entity, label.clone()); } @@ -166,7 +168,7 @@ impl Scene for PlayMode { let mut sync_updates = Vec::new(); - for (entity, (label, _)) in self.world.query::<(&Label, &EntityTransform)>().iter() { + for (entity, label, _) in self.world.query::<(Entity, &Label, &EntityTransform)>().iter() { if let Some(handle) = self.physics_state.bodies_entity_map.get(label) { if let Some(body) = self.physics_state.bodies.get(*handle) { let p = body.translation(); @@ -175,7 +177,7 @@ impl Scene for PlayMode { sync_updates.push(( entity, DVec3::new(p.x as f64, p.y as f64, p.z as f64), - DQuat::from_xyzw(r.i as f64, r.j as f64, r.k as f64, r.w as f64) + Quat::from(r.clone()).as_dquat() )); } } @@ -301,14 +303,14 @@ impl Scene for PlayMode { { let mut query = self.world.query::<(&mut MeshRenderer, &Transform)>(); - for (_entity, (renderer, transform)) in query.iter() { + for (renderer, transform) in query.iter() { renderer.update(transform); } } { let mut updates = Vec::new(); - for (entity, transform) in self.world.query::<&EntityTransform>().iter() { + for (entity, transform) in self.world.query::<(Entity, &EntityTransform)>().iter() { let final_transform = transform.propagate(&self.world, entity); updates.push((entity, final_transform)); } @@ -325,7 +327,7 @@ impl Scene for PlayMode { .world .query::<(&mut LightComponent, Option<&Transform>, Option<&EntityTransform>, &mut Light)>(); - for (_, (light_comp, transform_opt, entity_transform_opt, light)) in light_query.iter() { + for (light_comp, transform_opt, entity_transform_opt, light) in light_query.iter() { let transform = if let Some(entity_transform) = entity_transform_opt { entity_transform.sync() } else if let Some(transform) = transform_opt { @@ -339,7 +341,7 @@ impl Scene for PlayMode { } { - for (_entity_id, (camera, component)) in self + for (camera, component) in self .world .query::<(&mut Camera, &mut CameraComponent)>() .iter() @@ -477,11 +479,7 @@ impl Scene for PlayMode { }; log_once::debug_once!("Active camera found: {:?}", active_camera); - let q = if let Ok(mut query) = self.world.query_one::<&Camera>(active_camera) { - query.get().cloned() - } else { - None - }; + let q = self.world.query_one::<&Camera>(active_camera).get().ok().cloned(); let Some(camera) = q else { return; @@ -505,7 +503,7 @@ impl Scene for PlayMode { let lights = { let mut lights = Vec::new(); let mut query = self.world.query::<(&Light, &LightComponent)>(); - for (_, (light, comp)) in query.iter() { + for (light, comp) in query.iter() { lights.push((light.clone(), comp.clone())); } lights @@ -514,7 +512,7 @@ impl Scene for PlayMode { let renderers = { let mut renderers = Vec::new(); let mut query = self.world.query::<&MeshRenderer>(); - for (_, renderer) in query.iter() { + for renderer in query.iter() { renderers.push(renderer.clone()); } renderers @@ -559,7 +557,7 @@ impl Scene for PlayMode { &mut Light, )>(); - for (_, (light_component, transform_opt, entity_transform_opt, light)) in query.iter() { + for (light_component, transform_opt, entity_transform_opt, light) in query.iter() { let transform = if let Some(entity_transform) = entity_transform_opt { entity_transform.sync() } else if let Some(transform) = transform_opt { @@ -658,7 +656,7 @@ impl Scene for PlayMode { HashMap::new(); let mut q = self.world.query::<(&EntityTransform, &ColliderGroup)>(); - for (_entity, (entity_transform, group)) in q.iter() { + for (entity_transform, group) in q.iter() { for collider in &group.colliders { let world_tf = entity_transform.sync(); @@ -63,12 +63,8 @@ impl SignalController for Editor { Signal::Delete => { if let Some(sel_e) = &self.selected_entity { let is_viewport_cam = - if let Ok(mut q) = self.world.query_one::<&CameraComponent>(*sel_e) { - if let Some(c) = q.get() { - matches!(c.camera_type, CameraType::Debug) - } else { - false - } + if let Ok(c) = self.world.query_one::<&CameraComponent>(*sel_e).get() { + matches!(c.camera_type, CameraType::Debug) } else { false }; @@ -18,7 +18,7 @@ chrono.workspace = true env_logger.workspace = true colored.workspace = true parking_lot.workspace = true -bincode.workspace = true +postcard.workspace = true ron.workspace = true hecs.workspace = true bytemuck.workspace = true