From 76a21ec73bbaf4d784be884de31dc439953758c6 Mon Sep 17 00:00:00 2001 From: mitchellhansen Date: Thu, 4 Feb 2021 23:55:38 -0800 Subject: [PATCH] adding physics and collision --- Cargo.toml | 4 +- src/main.rs | 113 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 80 insertions(+), 37 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3ff16fd..6cf16d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,5 +28,5 @@ ddsfile = "0.4" wgpu-subscriber = "0.1.0" tobj = "2.0.3" legion = "0.3.1" -nalgebra = "0.20" -ncollide3d = "0.22" +nalgebra = "0.24.1" +nphysics3d = "0.19.0" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index c436e84..5b07314 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,36 @@ +extern crate nphysics3d; extern crate tobj; extern crate winit; -extern crate ncollide3d; +use std::f32::consts::PI; use std::rc::Rc; use std::sync::Arc; #[cfg(not(target_arch = "wasm32"))] use std::time::{Duration, Instant}; use bytemuck::__core::ops::Range; -use cgmath::{Matrix4, Point3, Decomposed, Quaternion, Rotation3, Deg, InnerSpace, SquareMatrix}; +use cgmath::{Decomposed, Deg, InnerSpace, Quaternion, Rotation3, SquareMatrix}; use futures::task::LocalSpawn; use legion::*; +use nphysics3d::math::Inertia; +use nphysics3d::math::Velocity as VelocityN; +use nphysics3d::nalgebra::{Isometry3, Matrix3, Matrix4, Point3, Point4, Vector3, Vector4}; +use nphysics3d::ncollide3d::pipeline::CollisionGroups; +use nphysics3d::ncollide3d::shape::{Ball, ShapeHandle}; +use nphysics3d::object::{BodyStatus, ColliderDesc, RigidBodyDesc, DefaultBodySet, DefaultColliderSet, BodyPartHandle}; use wgpu::{BindGroup, Buffer, TextureView}; use wgpu_subscriber; -use winit::platform::unix::x11::ffi::Time; use winit::{ event::{self, WindowEvent}, event_loop::{ControlFlow, EventLoop}, }; +use winit::event::DeviceEvent::MouseMotion; +use winit::platform::unix::x11::ffi::Time; use crate::render::Renderer; -use winit::event::DeviceEvent::MouseMotion; +use nphysics3d::world::{DefaultMechanicalWorld, DefaultGeometricalWorld}; +use nphysics3d::joint::DefaultJointConstraintSet; +use nphysics3d::force_generator::DefaultForceGeneratorSet; mod framework; mod geometry; @@ -30,7 +40,7 @@ mod render; /* Collision detection -https://crates.io/crates/mgf +https://nphysics.org/rigid_body_simulations_with_contacts/ Obj file format http://paulbourke.net/dataformats/obj/ @@ -65,27 +75,13 @@ pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4 = cgmath::Matrix4::new( 0.0, 0.0, 0.5, 1.0, ); -#[allow(dead_code)] -pub fn cast_slice(data: &[T]) -> &[u8] { - use std::{mem::size_of, slice::from_raw_parts}; - - unsafe { from_raw_parts(data.as_ptr() as *const u8, data.len() * size_of::()) } -} - -#[allow(dead_code)] -pub enum ShaderStage { - Vertex, - Fragment, - Compute, -} - // a component is any type that is 'static, sized, send and sync #[derive(Clone, Copy, Debug, PartialEq)] pub struct Position { x: f32, y: f32, z: f32, - mx: Matrix4, + mx: cgmath::Matrix4, } #[derive(Clone, Copy, Debug, PartialEq)] @@ -129,7 +125,6 @@ pub struct Mesh { //log::info!(""); fn main() { - let mut world = World::default(); let (mut pool, spawner) = { @@ -170,9 +165,7 @@ fn main() { let mut resources = Resources::default(); resources.insert(renderer); - event_loop.run(move |event, _, control_flow| { - // Artificially slows the loop rate to 10 millis // This is called after redraw events cleared *control_flow = ControlFlow::WaitUntil(Instant::now() + Duration::from_millis(10)); @@ -187,17 +180,16 @@ fn main() { pool.run_until_stalled(); } event::Event::DeviceEvent { - event: MouseMotion{ delta }, + event: MouseMotion { delta }, .. } => { - resources .get_mut::() .unwrap() .cam_look_delta((delta.0, delta.1)); //swap_chain = device.create_swap_chain(&surface, &sc_desc); - }, + } // Resizing will queue a request_redraw event::Event::WindowEvent { event: WindowEvent::Resized(size), @@ -213,7 +205,7 @@ fn main() { .resize(width, height); //swap_chain = device.create_swap_chain(&surface, &sc_desc); - }, + } event::Event::WindowEvent { event, .. } => match event { WindowEvent::KeyboardInput { input: @@ -240,11 +232,64 @@ fn main() { }); } +pub fn physics() { + + let mut mechanical_world = DefaultMechanicalWorld::new(Vector3::new(0.0, -9.81, 0.0)); + let mut geometrical_world = DefaultGeometricalWorld::new(); + + let mut bodies = DefaultBodySet::new(); + let mut colliders = DefaultColliderSet::new(); + let mut joint_constraints = DefaultJointConstraintSet::new(); + let mut force_generators = DefaultForceGeneratorSet::new(); + + // Run the simulation. + mechanical_world.step( + &mut geometrical_world, + &mut bodies, + &mut colliders, + &mut joint_constraints, + &mut force_generators + ); + + let rigid_body = + RigidBodyDesc::new() + // The rigid body position. Will override `.translation(...)` and `.rotation(...)`. + .position(Isometry3::new( + Vector3::new(1.0, 2.0, 3.0), + Vector3::y() * PI, + )) + .gravity_enabled(true) + .status(BodyStatus::Dynamic) + .velocity(VelocityN::linear(1.0, 2.0, 3.0)) + .linear_damping(10.0) + .angular_damping(5.0) + .max_linear_velocity(10.0) + .max_angular_velocity(1.7) + .mass(1.2) + // Arbitrary user-defined data associated to the rigid body to be built. + .user_data(10) + .build(); + + + // let parent_rigid_body = RigidBodyDesc::new() + // .build(); + let parent_handle = bodies.insert(rigid_body); + + let shape = ShapeHandle::new(Ball::new(1.5)); + let collider = ColliderDesc::new(shape) + .density(1.0) + .translation(Vector3::y() * 5.0) + .build(BodyPartHandle(parent_handle, 0)); + let collider_handle = colliders.insert(collider); + + // let ball = ShapeHandle::new(Ball::new(1.5)); + // + // let collider = ColliderDesc::new(rigid_body) + // .build(); +} pub fn entity_loading(world: &mut World, renderer: &mut Renderer) { - - let untitled_mesh = - renderer.load_mesh_to_buffer("./resources/monkey.obj"); + let untitled_mesh = renderer.load_mesh_to_buffer("./resources/monkey.obj"); // This could be used for relationships between entities...??? let light_entity: Entity = world.push(( @@ -288,15 +333,14 @@ pub fn entity_loading(world: &mut World, renderer: &mut Renderer) { }, )); - let plane_mesh = - renderer.create_plane(7.0); + let plane_mesh = renderer.create_plane(7.0); let plane_entity: Entity = world.push(( Position { x: 0.0, y: 0.0, z: 0.0, - mx: cgmath::Matrix4::identity(), + mx: cgmath::Matrix4::identity(), }, plane_mesh, Color { @@ -306,5 +350,4 @@ pub fn entity_loading(world: &mut World, renderer: &mut Renderer) { a: 1.0, }, )); - -} \ No newline at end of file +}