From f48783f17b95d34368e8f9e152c45ab091f559b0 Mon Sep 17 00:00:00 2001 From: reo Date: Tue, 15 Jul 2025 01:29:08 +0300 Subject: [PATCH] Add physics engine integration with rapier3d --- Cargo.lock | 330 +++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 2 + src/main.rs | 36 +++++- src/physics.rs | 90 ++++++++++++++ 4 files changed, 447 insertions(+), 11 deletions(-) create mode 100644 src/physics.rs diff --git a/Cargo.lock b/Cargo.lock index a227390..0cc983a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,6 +55,12 @@ dependencies = [ "equator", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android-activity" version = "0.6.0" @@ -73,7 +79,7 @@ dependencies = [ "ndk-context", "ndk-sys", "num_enum", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -88,6 +94,15 @@ version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + [[package]] name = "arbitrary" version = "1.4.1" @@ -179,6 +194,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bit_field" version = "0.10.2" @@ -259,7 +280,7 @@ dependencies = [ "polling", "rustix 0.38.44", "slab", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -402,6 +423,28 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -421,6 +464,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -470,6 +522,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" +[[package]] +name = "downcast-rs" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea8a8b81cacc08888170eef4d13b775126db426d0b348bee9d18c2c1eaf123cf" + [[package]] name = "dpi" version = "0.1.2" @@ -482,6 +540,15 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "ena" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +dependencies = [ + "log", +] + [[package]] name = "equator" version = "0.4.2" @@ -558,6 +625,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foreign-types" version = "0.5.0" @@ -599,6 +672,7 @@ dependencies = [ "imgui", "imgui-glium-renderer", "imgui-winit-support", + "rapier3d", "winit", ] @@ -800,6 +874,15 @@ dependencies = [ "crunchy", ] +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -814,6 +897,21 @@ name = "hashbrown" version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] [[package]] name = "heck" @@ -974,7 +1072,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.69", "walkdir", "windows-sys 0.45.0", ] @@ -1055,6 +1153,12 @@ dependencies = [ "windows-targets 0.53.2", ] +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + [[package]] name = "libredox" version = "0.1.3" @@ -1103,6 +1207,16 @@ dependencies = [ "imgref", ] +[[package]] +name = "matrixmultiply" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" +dependencies = [ + "autocfg", + "rawpointer", +] + [[package]] name = "maybe-rayon" version = "0.1.1" @@ -1159,6 +1273,33 @@ version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e53debba6bda7a793e5f99b8dacf19e626084f525f7829104ba9898f367d85ff" +[[package]] +name = "nalgebra" +version = "0.33.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" +dependencies = [ + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational", + "num-traits", + "simba", + "typenum", +] + +[[package]] +name = "nalgebra-macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "ndk" version = "0.9.0" @@ -1171,7 +1312,7 @@ dependencies = [ "ndk-sys", "num_enum", "raw-window-handle", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1221,6 +1362,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + [[package]] name = "num-derive" version = "0.4.2" @@ -1259,6 +1409,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1553,6 +1704,15 @@ dependencies = [ "libredox", ] +[[package]] +name = "ordered-float" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2c1f9f56e534ac6a9b8a4600bdf0f530fb393b5f393e7b4d03489c3cf0c3f01" +dependencies = [ + "num-traits", +] + [[package]] name = "owned_ttf_parser" version = "0.25.0" @@ -1585,6 +1745,31 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "parry3d" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f8d0a3b2f4c0e250d4599b69e490535521c3497e2b88b0b5d2ada251bc83a8" +dependencies = [ + "approx", + "arrayvec", + "bitflags 2.9.1", + "downcast-rs 2.0.1", + "either", + "ena", + "hashbrown 0.15.4", + "log", + "nalgebra", + "num-derive", + "num-traits", + "ordered-float", + "rstar", + "simba", + "slab", + "spade", + "thiserror 2.0.12", +] + [[package]] name = "paste" version = "1.0.15" @@ -1772,6 +1957,30 @@ dependencies = [ "getrandom 0.2.16", ] +[[package]] +name = "rapier3d" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f1015500058823ba9c479c908d7069adcf3f0f51a3e49dca7efc5575df7e574" +dependencies = [ + "approx", + "arrayvec", + "bit-vec", + "bitflags 2.9.1", + "crossbeam", + "downcast-rs 2.0.1", + "log", + "nalgebra", + "num-derive", + "num-traits", + "ordered-float", + "parry3d", + "profiling", + "rustc-hash", + "simba", + "thiserror 2.0.12", +] + [[package]] name = "rav1e" version = "0.7.1" @@ -1802,7 +2011,7 @@ dependencies = [ "rand_chacha", "simd_helpers", "system-deps", - "thiserror", + "thiserror 1.0.69", "v_frame", "wasm-bindgen", ] @@ -1828,6 +2037,12 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" version = "1.10.0" @@ -1872,12 +2087,35 @@ version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" +[[package]] +name = "robust" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e27ee8bb91ca0adcf0ecb116293afa12d393f9c2b9b9cd54d33e8078fe19839" + +[[package]] +name = "rstar" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421400d13ccfd26dfa5858199c30a5d76f9c54e0dba7575273025b43c5175dbb" +dependencies = [ + "heapless", + "num-traits", + "smallvec", +] + [[package]] name = "rustc-demangle" version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "rustix" version = "0.38.44" @@ -1916,6 +2154,15 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "safe_arch" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" +dependencies = [ + "bytemuck", +] + [[package]] name = "same-file" version = "1.0.6" @@ -1997,6 +2244,19 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simba" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", + "wide", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -2038,7 +2298,7 @@ dependencies = [ "log", "memmap2", "rustix 0.38.44", - "thiserror", + "thiserror 1.0.69", "wayland-backend", "wayland-client", "wayland-csd-frame", @@ -2058,12 +2318,30 @@ dependencies = [ "serde", ] +[[package]] +name = "spade" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a14e31a007e9f85c32784b04f89e6e194bb252a4d41b4a8ccd9e77245d901c8c" +dependencies = [ + "hashbrown 0.15.4", + "num-traits", + "robust", + "smallvec", +] + [[package]] name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "strict-num" version = "0.1.1" @@ -2106,7 +2384,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", ] [[package]] @@ -2120,6 +2407,17 @@ dependencies = [ "syn", ] +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tiff" version = "0.9.1" @@ -2212,6 +2510,12 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + [[package]] name = "unicode-ident" version = "1.0.18" @@ -2355,7 +2659,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" dependencies = [ "cc", - "downcast-rs", + "downcast-rs 1.2.1", "rustix 0.38.44", "scoped-tls", "smallvec", @@ -2483,6 +2787,16 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" +[[package]] +name = "wide" +version = "0.7.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" +dependencies = [ + "bytemuck", + "safe_arch", +] + [[package]] name = "winapi-util" version = "0.1.9" diff --git a/Cargo.toml b/Cargo.toml index d26e25b..b580e02 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,3 +19,5 @@ imgui-winit-support = "0.13" imgui-glium-renderer = "0.13" winit = "0.30" + +rapier3d = "0.26.1" diff --git a/src/main.rs b/src/main.rs index 1a92617..6583355 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod gltf_loader; mod render; mod time; mod ui; +mod physics; use anyhow::Result; use camera::Camera; @@ -12,6 +13,8 @@ use ecs::{Transform}; use glam::{Quat, Vec3, EulerRot}; use glium::backend::glutin::SimpleWindowBuilder; use render::GliumRenderer; +use rapier3d::prelude::*; +use rapier3d::na::{UnitQuaternion, Quaternion}; fn main() -> Result<()> { let event_loop = glium::winit::event_loop::EventLoop::builder() @@ -20,7 +23,7 @@ fn main() -> Result<()> { let (window, display) = SimpleWindowBuilder::new() .with_title("fps") - .with_inner_size(1280, 720) + .with_inner_size(1920, 1080) .build(&event_loop); // Create ECS renderer which internally owns both the world and the renderer @@ -30,6 +33,8 @@ fn main() -> Result<()> { ecs::ECSRenderer::new(renderer, world) }; + let mut physics = physics::Physics::new(); + // Dear ImGui integration let mut gui = ui::Gui::new(&display, &window)?; @@ -38,7 +43,7 @@ fn main() -> Result<()> { let object_ent = { let model_3d = gltf_loader::load_gltf("resources/models/tree.gltf", &display)?; ecsr.spawn_mesh(model_3d, Transform { - translation: Vec3::new(0.0, -2.5, -5.0), + translation: Vec3::new(0.0, 2.5, -5.0), rotation: Quat::IDENTITY, scale: Vec3::new(0.01, 0.01, 0.01), }) @@ -49,10 +54,34 @@ fn main() -> Result<()> { ecsr.spawn_mesh(model_3d, Transform { translation: Vec3::new(0.0, -1.5, 0.0), rotation: Quat::IDENTITY, - scale: Vec3::new(1.0, 1.0, 1.0), + scale: Vec3::new(10.0, 10.0, 10.0), }) }; + // Add physics for ground + let ground_tr = *ecsr.world.get::<&Transform>(ground_ent).unwrap(); + let (axis, angle) = ground_tr.rotation.to_axis_angle(); + let rotation = vector![axis.x * angle, axis.y * angle, axis.z * angle]; + let ground_pos = Isometry::new( + vector![ground_tr.translation.x, ground_tr.translation.y, ground_tr.translation.z], + rotation, + ); + let ground_rb = RigidBodyBuilder::fixed().position(ground_pos).build(); + let ground_collider = ColliderBuilder::cuboid(10.0, 0.1, 10.0).build(); + physics.add_rigid_body(ground_ent, ground_rb, ground_collider); + + // Add physics for object + let object_tr = *ecsr.world.get::<&Transform>(object_ent).unwrap(); + let (axis, angle) = object_tr.rotation.to_axis_angle(); + let rotation = vector![axis.x * angle, axis.y * angle, axis.z * angle]; + let object_pos = Isometry::new( + vector![object_tr.translation.x, object_tr.translation.y, object_tr.translation.z], + rotation, + ); + let object_rb = RigidBodyBuilder::dynamic().position(object_pos).build(); + let object_collider = ColliderBuilder::cylinder(2.0, 0.2).build(); + physics.add_rigid_body(object_ent, object_rb, object_collider); + let camera_ent = { let (w, h): (u32, u32) = window.inner_size().into(); @@ -117,6 +146,7 @@ fn main() -> Result<()> { }, Event::AboutToWait => { time.tick(); + physics.step(time.delta_seconds(), &mut ecsr.world); gui.prepare_frame(&window); window.request_redraw(); } diff --git a/src/physics.rs b/src/physics.rs new file mode 100644 index 0000000..0095c9b --- /dev/null +++ b/src/physics.rs @@ -0,0 +1,90 @@ +use std::collections::HashMap; +use rapier3d::prelude::*; +use hecs::World; +use glam::{Vec3, Quat}; +use crate::ecs::Transform; + +pub struct Physics { + rigid_bodies: RigidBodySet, + colliders: ColliderSet, + integration_params: IntegrationParameters, + pipeline: PhysicsPipeline, + island_manager: IslandManager, + broad_phase: BroadPhaseMultiSap, + narrow_phase: NarrowPhase, + impulse_joints: ImpulseJointSet, + multibody_joints: MultibodyJointSet, + ccd_solver: CCDSolver, + query_pipeline: QueryPipeline, + gravity: Vector, + entity_to_rb: HashMap, +} + +impl Physics { + pub fn new() -> Self { + let rigid_bodies = RigidBodySet::new(); + let colliders = ColliderSet::new(); + let integration_params = IntegrationParameters::default(); + let pipeline = PhysicsPipeline::new(); + let island_manager = IslandManager::new(); + let broad_phase = BroadPhaseMultiSap::new(); + let narrow_phase = NarrowPhase::new(); + let impulse_joints = ImpulseJointSet::new(); + let multibody_joints = MultibodyJointSet::new(); + let ccd_solver = CCDSolver::new(); + let query_pipeline = QueryPipeline::new(); + let gravity = vector![0.0, -9.81, 0.0]; + Self { + rigid_bodies, + colliders, + integration_params, + pipeline, + island_manager, + broad_phase, + narrow_phase, + impulse_joints, + multibody_joints, + ccd_solver, + query_pipeline, + gravity, + entity_to_rb: HashMap::new(), + } + } + + pub fn step(&mut self, dt: f32, world: &mut World) { + let physics_hooks = (); + let event_handler = (); + self.integration_params.dt = dt; + self.pipeline.step( + &self.gravity, + &self.integration_params, + &mut self.island_manager, + &mut self.broad_phase, + &mut self.narrow_phase, + &mut self.rigid_bodies, + &mut self.colliders, + &mut self.impulse_joints, + &mut self.multibody_joints, + &mut self.ccd_solver, + Some(&mut self.query_pipeline), + &physics_hooks, + &event_handler, + ); + + for (&ent, &handle) in &self.entity_to_rb { + if let Ok(mut tr) = world.get::<&mut Transform>(ent) { + let rb = self.rigid_bodies.get(handle).unwrap(); + let pos = rb.position(); + tr.translation = Vec3::new(pos.translation.x, pos.translation.y, pos.translation.z); + let q = pos.rotation; + tr.rotation = Quat::from_xyzw(q.i, q.j, q.k, q.w); + } + } + } + + pub fn add_rigid_body(&mut self, ent: hecs::Entity, rb: RigidBody, collider: Collider) { + let rb_handle = self.rigid_bodies.insert(rb); + self.colliders.insert_with_parent(collider, rb_handle, &mut self.rigid_bodies); + self.entity_to_rb.insert(ent, rb_handle); + } +} \ No newline at end of file