kitgit

tirbofish/dropbear · diff

d57f407 · Thribhu K

fix: implemented rotation for KCC Unverified

diff --git a/Cargo.toml b/Cargo.toml
index 41fa125..ff19719 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -35,7 +35,7 @@ glam = { version = "0.30", features = ["serde", "mint"] }
 hecs = { version = "0.11", features = ["serde"] }
 log = "0.4"
 log-once = "0.4"
-model_to_image = "0.1"
+#model_to_image = "0.1"
 once_cell = "1.21"
 parking_lot = {version = "0.12", features = ["deadlock_detection"] }
 rfd = "0.17"
diff --git a/crates/eucalyptus-core/src/physics/kcc.rs b/crates/eucalyptus-core/src/physics/kcc.rs
index a6bae53..6500a5a 100644
--- a/crates/eucalyptus-core/src/physics/kcc.rs
+++ b/crates/eucalyptus-core/src/physics/kcc.rs
@@ -40,6 +40,7 @@ pub mod jni {
     use jni::objects::{JClass, JObject};
     use jni::sys::{jboolean, jdouble, jlong};
     use rapier3d::dynamics::RigidBodyType;
+    use rapier3d::math::Rotation;
     use rapier3d::prelude::QueryFilter;
     use crate::{convert_jlong_to_entity, convert_ptr};
     use crate::physics::kcc::KCC;
@@ -155,6 +156,72 @@ pub mod jni {
     }
 
     #[unsafe(no_mangle)]
+    pub extern "system" fn Java_com_dropbear_physics_KinematicCharacterControllerNative_setRotation(
+        mut env: JNIEnv,
+        _: JClass,
+        world_handle: jlong,
+        physics_handle: jlong,
+        entity: jlong,
+        rotation: JObject,
+    ) {
+        let world = convert_ptr!(world_handle => World);
+        let physics_state = convert_ptr!(mut physics_handle => PhysicsState);
+        let entity = convert_jlong_to_entity!(entity);
+
+        let class = match env.find_class("com/dropbear/math/Quaterniond") {
+            Ok(cls) => cls,
+            Err(_) => {
+                let _ = env.throw_new("java/lang/RuntimeException", "Unable to find Quaterniond class");
+                return;
+            }
+        };
+
+        if let Ok(false) = env.is_instance_of(&rotation, &class) {
+            let _ = env.throw_new("java/lang/IllegalArgumentException", "rotation must be Quaterniond");
+            return;
+        }
+
+        let mut get_double = |field: &str| -> Option<f64> {
+            env.get_field(&rotation, field, "D").ok()?.d().ok()
+        };
+
+        let Some(rx) = get_double("x") else { return; };
+        let Some(ry) = get_double("y") else { return; };
+        let Some(rz) = get_double("z") else { return; };
+        let Some(rw) = get_double("w") else { return; };
+
+        let len = (rx * rx + ry * ry + rz * rz + rw * rw).sqrt();
+        let (x, y, z, w) = if len > 0.0 {
+            (rx / len, ry / len, rz / len, rw / len)
+        } else {
+            (0.0, 0.0, 0.0, 1.0)
+        };
+
+        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;
+            };
+
+            let body_type = {
+                let Some(body) = physics_state.bodies.get(*rigid_body_handle) else {
+                    return;
+                };
+                body.body_type()
+            };
+
+            match body_type {
+                RigidBodyType::KinematicPositionBased => {}
+                _ => return,
+            }
+
+            if let Some(body) = physics_state.bodies.get_mut(*rigid_body_handle) {
+                let rot = Rotation::from_xyzw(x as f32, y as f32, z as f32, w as f32);
+                body.set_next_kinematic_rotation(rot);
+            }
+        }
+    }
+
+    #[unsafe(no_mangle)]
     pub extern "system" fn Java_com_dropbear_physics_KinematicCharacterControllerNative_getHitNative(
         mut env: JNIEnv,
         _: JClass,
diff --git a/crates/eucalyptus-editor/Cargo.toml b/crates/eucalyptus-editor/Cargo.toml
index 7d8ea76..6c2eafb 100644
--- a/crates/eucalyptus-editor/Cargo.toml
+++ b/crates/eucalyptus-editor/Cargo.toml
@@ -28,7 +28,7 @@ glam.workspace = true
 hecs.workspace = true
 log.workspace = true
 log-once.workspace = true
-model_to_image.workspace = true
+#model_to_image.workspace = true
 parking_lot.workspace = true
 transform-gizmo-egui.workspace = true
 wgpu.workspace = true
diff --git a/scripting/commonMain/kotlin/com/dropbear/physics/KinematicCharacterController.kt b/scripting/commonMain/kotlin/com/dropbear/physics/KinematicCharacterController.kt
index 07fe528..bfc14f1 100644
--- a/scripting/commonMain/kotlin/com/dropbear/physics/KinematicCharacterController.kt
+++ b/scripting/commonMain/kotlin/com/dropbear/physics/KinematicCharacterController.kt
@@ -3,6 +3,7 @@ package com.dropbear.physics
 import com.dropbear.EntityId
 import com.dropbear.ecs.Component
 import com.dropbear.ecs.ComponentType
+import com.dropbear.math.Quaterniond
 import com.dropbear.math.Vector3d
 import com.dropbear.math.degreesToRadians
 import kotlin.math.cos
@@ -28,6 +29,16 @@ class KinematicCharacterController(
     }
 
     /**
+     * Sets the kinematic rotation for this tick.
+     *
+     * This is useful for facing the character toward the camera direction while still
+     * using KCC movement.
+     */
+    fun setRotation(rotation: Quaterniond) {
+        setRotationNative(rotation)
+    }
+
+    /**
      * This function fetches the hits that are cached in the `KCC` struct.
      *
      * # Note
@@ -62,4 +73,5 @@ class KinematicCharacterController(
 internal expect fun kccExistsForEntity(entityId: EntityId): Boolean
 
 internal expect fun KinematicCharacterController.moveCharacter(dt: Double, translation: Vector3d)
+internal expect fun KinematicCharacterController.setRotationNative(rotation: Quaterniond)
 internal expect fun KinematicCharacterController.getHitsNative(): List<CharacterCollision>
\ No newline at end of file
diff --git a/scripting/jvmMain/java/com/dropbear/physics/KinematicCharacterControllerNative.java b/scripting/jvmMain/java/com/dropbear/physics/KinematicCharacterControllerNative.java
index fbf3e1a..cccdaa1 100644
--- a/scripting/jvmMain/java/com/dropbear/physics/KinematicCharacterControllerNative.java
+++ b/scripting/jvmMain/java/com/dropbear/physics/KinematicCharacterControllerNative.java
@@ -2,6 +2,7 @@ package com.dropbear.physics;
 
 import com.dropbear.EucalyptusCoreLoader;
 import com.dropbear.math.Vector3d;
+import com.dropbear.math.Quaterniond;
 
 // fuck, this got a long ass name
 public class KinematicCharacterControllerNative {
@@ -12,5 +13,6 @@ public class KinematicCharacterControllerNative {
     public static native boolean existsForEntity(long worldHandle, long entityHandle);
 
     public static native void moveCharacter(long worldHandle, long physicsHandle, long entityHandle, Vector3d translation, double deltaTime);
+    public static native void setRotation(long worldHandle, long physicsHandle, long entityHandle, Quaterniond rotation);
     public static native CharacterCollision[] getHitNative(long worldHandle, long entity);
 }
diff --git a/scripting/jvmMain/kotlin/com/dropbear/physics/KinematicCharacterController.jvm.kt b/scripting/jvmMain/kotlin/com/dropbear/physics/KinematicCharacterController.jvm.kt
index dc306ce..a549ce0 100644
--- a/scripting/jvmMain/kotlin/com/dropbear/physics/KinematicCharacterController.jvm.kt
+++ b/scripting/jvmMain/kotlin/com/dropbear/physics/KinematicCharacterController.jvm.kt
@@ -18,6 +18,15 @@ internal actual fun KinematicCharacterController.moveCharacter(dt: Double, trans
     )
 }
 
+internal actual fun KinematicCharacterController.setRotationNative(rotation: com.dropbear.math.Quaterniond) {
+    return KinematicCharacterControllerNative.setRotation(
+        DropbearEngine.native.worldHandle,
+        DropbearEngine.native.physicsEngineHandle,
+        entity.raw,
+        rotation
+    )
+}
+
 internal actual fun KinematicCharacterController.getHitsNative(): List<CharacterCollision> {
     return KinematicCharacterControllerNative.getHitNative(
         DropbearEngine.native.worldHandle,
diff --git a/scripting/nativeMain/kotlin/com/dropbear/physics/KinematicCharacterController.native.kt b/scripting/nativeMain/kotlin/com/dropbear/physics/KinematicCharacterController.native.kt
index eec669a..ed0e696 100644
--- a/scripting/nativeMain/kotlin/com/dropbear/physics/KinematicCharacterController.native.kt
+++ b/scripting/nativeMain/kotlin/com/dropbear/physics/KinematicCharacterController.native.kt
@@ -1,11 +1,16 @@
 package com.dropbear.physics
 
 import com.dropbear.EntityId
+import com.dropbear.math.Quaterniond
 import com.dropbear.math.Vector3d
 
 internal actual fun KinematicCharacterController.moveCharacter(dt: Double, translation: Vector3d) {
 }
 
+internal actual fun KinematicCharacterController.setRotationNative(rotation: Quaterniond) {
+    TODO("Not yet implemented")
+}
+
 internal actual fun kccExistsForEntity(entityId: EntityId): Boolean {
     TODO("Not yet implemented")
 }