going to make entity spawning a little easier

master
mitchellhansen 4 years ago
parent 722bf45a7a
commit e3c1ce7789

@ -25,6 +25,7 @@ tobj = "2.0.3"
gilrs = "0.8.0"
gfx-backend-vulkan = { version = "0.6", features = ["x11"] }
lazy_static = "1.4.0"
crossbeam = "0.8.0"
cgmath = "0.18.0"
rapier3d = { version = "0.5.0", features = ["simd-nightly", "parallel"] }

@ -28,29 +28,12 @@ pub struct Position {
pub rot: cgmath::Euler<Deg<f32>>,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Color {
pub r: f32,
pub g: f32,
pub b: f32,
pub a: f32,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Velocity {
pub dx: f32,
pub dy: f32,
pub rs: f32,
}
#[derive(Clone, Default, PartialEq, Eq, Hash, Copy, Debug)]
pub struct RangeCopy<Idx> {
pub start: Idx,
pub end: Idx,
}
#[derive(Clone, Debug)]
pub struct Mesh {
pub index_buffer: Arc<Buffer>,
@ -59,6 +42,7 @@ pub struct Mesh {
pub vertex_buffer: Arc<Buffer>,
pub uniform_buffer: Arc<Buffer>,
pub bind_group: Arc<BindGroup>,
pub color: wgpu::Color,
}
#[derive(Clone, Debug)]

@ -1,24 +1,32 @@
use bytemuck::{Pod, Zeroable};
use nalgebra::Vector4;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Vertex {
_pos: [f32; 4],
_normal: [f32; 4],
pos: [f32; 4],
normal: [f32; 4],
}
unsafe impl Pod for Vertex {}
unsafe impl Zeroable for Vertex {}
pub fn vertex(pos: [f32; 3], nor: [f32; 3]) -> Vertex {
impl Vertex {
pub fn position(&self) -> Vector4<f32> {
Vector4::new(self.pos[0], self.pos[1], self.pos[2], self.pos[3])
}
pub fn from(pos: [f32; 3], nor: [f32; 3]) -> Vertex {
Vertex {
_pos: [pos[0], pos[1], pos[2], 1.0],
_normal: [nor[0], nor[1], nor[2], 0.0],
pos: [pos[0], pos[1], pos[2], 1.0],
normal: [nor[0], nor[1], nor[2], 0.0],
}
}
}
unsafe impl Pod for Vertex {}
unsafe impl Zeroable for Vertex {}
pub fn import_mesh(mesh_path: &str) -> (Vec<Vertex>, Vec<u32>) {
pub fn load_obj(mesh_path: &str) -> (Vec<Vertex>, Vec<u32>) {
let (models, materials) = tobj::load_obj(mesh_path, false).expect("Failed to load file");
@ -46,7 +54,7 @@ pub fn import_mesh(mesh_path: &str) -> (Vec<Vertex>, Vec<u32>) {
for v in 0..mesh.positions.len() / 3 {
vertex_data.push(
vertex([
Vertex::from([
mesh.positions[3 * v],
mesh.positions[3 * v + 1],
mesh.positions[3 * v + 2]

@ -1,18 +1,15 @@
extern crate imgui;
extern crate imgui_wgpu;
extern crate tobj;
extern crate winit_24;
#[macro_use]
extern crate lazy_static;
extern crate tobj;
extern crate winit_24;
use std::borrow::Borrow;
use std::f32::consts::PI;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
#[cfg(not(target_arch = "wasm32"))]
use std::time::{Duration, Instant};
use bytemuck::__core::ops::Range;
use cgmath::{
Decomposed, Deg, Euler, InnerSpace, Point3, Quaternion, Rad, Rotation3, SquareMatrix,
};
@ -32,6 +29,7 @@ use rapier3d::dynamics::{
};
use rapier3d::geometry::{BroadPhase, ColliderBuilder, ColliderHandle, ColliderSet, NarrowPhase};
use rapier3d::math;
use rapier3d::math::Point;
use rapier3d::na::{Isometry, Isometry3, Vector, Vector3};
use rapier3d::pipeline::PhysicsPipeline;
use wgpu::{BindGroup, Buffer, TextureView};
@ -45,7 +43,8 @@ use winit_24::{
};
use crate::camera::{Camera, CameraController};
use crate::components::{Collider, Color, ImguiWindow, LoopState, Physics, Position};
use crate::components::{Collider, ImguiWindow, LoopState, Physics, Position};
use crate::geometry::load_obj;
use crate::imgui_supp::extended_winit_imgui_support;
use crate::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform};
use crate::owned_event::{OwnedEvent, OwnedEventExtension};
@ -91,8 +90,9 @@ ECS
// ImGUI works on more or less a global state. which is MegaLame
static mut CURRENT_UI: Option<imgui::Ui<'static>> = None;
pub unsafe fn current_ui<'a>() -> Option<&'a imgui::Ui<'a>> { CURRENT_UI.as_ref() }
pub unsafe fn current_ui<'a>() -> Option<&'a imgui::Ui<'a>> {
CURRENT_UI.as_ref()
}
fn main() {
let mut world = World::default();
@ -190,18 +190,18 @@ fn main() {
if gamepad_.name() == "PS4" {
gamepad = Some(gamepad_);
}
println!(
"{} is {:?} {:?}",
gamepad_.name(),
gamepad_.power_info(),
gamepad_.id()
);
// println!(
// "{} is {:?} {:?}",
// gamepad_.name(),
// gamepad_.power_info(),
// gamepad_.id()
// );
}
let mut active_gamepad = None;
loop {
while let Some(GilEvent { id, event, time }) = gilrs.next_event() {
println!("{:?} New event from {}: {:?}", time, id, event);
//println!("{:?} New event from {}: {:?}", time, id, event);
active_gamepad = Some(id);
event_loop_proxy
.send_event(OwnedEventExtension::GamepadEvent {
@ -235,9 +235,7 @@ fn main() {
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {
event::Event::NewEvents(cause) => {
}
event::Event::NewEvents(cause) => {}
// This is the big boy section of the event loop
// We : dispatch events and clear the queue, query the loops
@ -266,7 +264,7 @@ fn main() {
}
accumulator_time += delta_time;
while ((accumulator_time - step_size) >= step_size) {
while accumulator_time - step_size >= step_size {
accumulator_time -= step_size;
// ==== DELTA TIME LOCKED ====
update_schedule.execute(&mut world, &mut resources);
@ -280,7 +278,6 @@ fn main() {
event: WindowEvent::Resized(size),
..
} => {
log::info!("Resizing to {:?}", size);
let width = size.width;
let height = size.height;
@ -308,10 +305,67 @@ fn main() {
});
}
pub fn entity_loading(world: &mut World, renderer: &mut render::state::RenderState) {
pub fn load_colliding_mesh_entity(world: &mut World, renderer: &mut render::state::RenderState, mesh_path: &str) {
let mut static_floor_body = RigidBodyBuilder::new_static()
.position(Isometry3::new(Vector3::new(0.0, -8.0, 0.0), Vector::y()))
.build();
//let pair = import_mesh("./resources/terrain.obj");
let pair = load_obj(mesh_path);
let floor_collider = ColliderBuilder::trimesh(
pair.0
.iter()
.map(|v| {
let position = v.position();
Point::<f32>::new(position.x, position.y, position.z)
})
.collect(),
pair.1
.chunks(3)
.map(|v| [v[0], v[1], v[2]])
.collect(),
)
.build();
let plane_mesh = renderer.load_mesh_to_buffer(
"./resources/terrain.obj",
Some(wgpu::Color {
r: 1.0,
g: 0.7,
b: 0.3,
a: 1.0,
}),
);
let plane_entity: Entity = world.push((
Position {
x: 0.0,
y: -8.0,
z: 0.0,
rot: Euler {
x: Deg(0.0),
y: Deg(0.0),
z: Deg(0.0),
},
},
plane_mesh,
Physics {
rigid_body: static_floor_body,
rigid_body_handle: None,
},
Collider {
collider: floor_collider,
collider_handle: None,
},
));
let monkey_mesh = renderer.load_mesh_to_buffer("./resources/monkey.obj");
}
pub fn entity_loading(world: &mut World, renderer: &mut render::state::RenderState) {
let monkey_mesh =
renderer.load_mesh_to_buffer("./resources/monkey.obj", Some(wgpu::Color::GREEN));
let camera_ent: Entity = world.push((
Camera {
@ -323,16 +377,11 @@ pub fn entity_loading(world: &mut World, renderer: &mut render::state::RenderSta
yaw: Rad(-PI),
pitch: Rad(PI / 2.0),
},
Color {
r: 1.0,
g: 1.0,
b: 0.5,
a: 1.0,
},
CameraController::new(3.0, 1.0),
));
let light_mesh = renderer.load_mesh_to_buffer("./resources/light.obj");
let light_mesh =
renderer.load_mesh_to_buffer("./resources/light.obj", Some(wgpu::Color::BLACK));
let light_entity: Entity = world.push((
Position {
@ -345,12 +394,6 @@ pub fn entity_loading(world: &mut World, renderer: &mut render::state::RenderSta
z: Deg(0.0),
},
},
Color {
r: 1.0,
g: 0.0,
b: 1.0,
a: 1.0,
},
light_mesh.clone(),
renderer.create_light(),
));
@ -384,61 +427,42 @@ pub fn entity_loading(world: &mut World, renderer: &mut render::state::RenderSta
}, //mx: cgmath::Matrix4::from(transform),
},
monkey_mesh,
Color {
r: 0.0,
g: 1.0,
b: 0.0,
a: 1.0,
},
));
let mut dynamic_ball_body = RigidBodyBuilder::new_dynamic()
.position(Isometry3::new(Vector3::new(0.0, 0.0, 0.0), Vector::y()))
.can_sleep(false)
.mass(1.0)
//.position(Isometry3::new(Vector3::new(0.0, 10.0, 0.0), Vector::y()))
.translation(0.0, 35.0, 0.0)
.build();
let mut static_floor_body = RigidBodyBuilder::new_static()
.position(Isometry3::new(Vector3::new(0.0, -8.0, 0.0), Vector::y()))
.build();
let ball_collider = ColliderBuilder::ball(1.5).build();
let floor_collider = ColliderBuilder::cuboid(10.0, 0.2, 10.0).build();
let pair = load_obj("./resources/ball.obj");
let plane_mesh = renderer.load_mesh_to_buffer("./resources/plane.obj");
let ball_collider = ColliderBuilder::trimesh(
pair.0
.iter()
.map(|v| {
let position = v.position();
Point::<f32>::new(position.x, position.y, position.z)
})
.collect(),
pair.1
//.iter()
.chunks(3)
.map(|v| [v[0], v[1], v[2]])
.collect(),
)
.build();
let plane_entity: Entity = world.push((
Position {
x: 0.0,
y: -8.0,
z: 0.0,
rot: Euler {
x: Deg(0.0),
y: Deg(0.0),
z: Deg(0.0),
},
},
plane_mesh,
Color {
r: 1.0,
g: 0.5,
b: 0.5,
a: 1.0,
},
Physics {
rigid_body: static_floor_body,
rigid_body_handle: None,
},
Collider {
collider: floor_collider,
collider_handle: None,
},
));
let ball_mesh = renderer.load_mesh_to_buffer("./resources/ball.obj");
let ball_mesh = renderer.load_mesh_to_buffer("./resources/ball.obj", Some(wgpu::Color::BLUE));
let ball_mesh: Entity = world.push((
Position {
x: 0.0,
y: 0.0,
y: 20.0,
z: 0.0,
rot: Euler {
x: Deg(25.0),
@ -447,12 +471,6 @@ pub fn entity_loading(world: &mut World, renderer: &mut render::state::RenderSta
},
},
ball_mesh,
Color {
r: 1.0,
g: 0.5,
b: 0.5,
a: 1.0,
},
Physics {
rigid_body: dynamic_ball_body,
rigid_body_handle: None,

@ -280,7 +280,7 @@ pub fn event_dispatch(
match keyboard_input.virtual_keycode.unwrap() {
VirtualKeyCode::A => {
if keyboard_input.state == ElementState::Pressed {
println!("cursorijf");
winit_window.set_cursor_position(
LogicalPosition{ x: 100.0, y: 100.0 }
);

@ -7,7 +7,7 @@ use legion::*;
use nalgebra::Quaternion as naQuaternion;
use rapier3d::dynamics::{IntegrationParameters, JointSet, RigidBodySet};
use rapier3d::geometry::{BroadPhase, ColliderSet, NarrowPhase};
use rapier3d::pipeline::PhysicsPipeline;
use rapier3d::pipeline::{PhysicsPipeline, ChannelEventCollector};
use crate::camera::{Camera, CameraController};
use crate::components::{Collider, LoopState, Mesh, Physics, Position};
@ -45,8 +45,12 @@ pub fn run_physics(
}
}
let (contact_send, contact_recv) = crossbeam::channel::unbounded();
let (intersection_send, intersection_recv) = crossbeam::channel::unbounded();
let event_handler = ChannelEventCollector::new(intersection_send, contact_send);
// run the physics step
let event_handler = ();
physics_pipeline.step(
&physics_state.gravity,
&physics_state.integration_parameters,
@ -59,6 +63,14 @@ pub fn run_physics(
None,
&event_handler,
);
while let Ok(intersection_event) = intersection_recv.try_recv() {
println!("{:?}", intersection_event)
}
while let Ok(contact_event) = contact_recv.try_recv() {
println!("{:?}", contact_event)
}
}

@ -24,9 +24,9 @@ use winit_24::platform::unix::x11::ffi::Time;
use winit_24::window::Window;
use crate::camera::{Camera, CameraController};
use crate::components::{Color, Mesh, Position, RangeCopy};
use crate::components::{Mesh, Position, RangeCopy};
use crate::current_ui;
use crate::geometry::{import_mesh, vertex, Vertex};
use crate::geometry::{load_obj, Vertex};
use crate::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform};
use crate::light::{DirectionalLight, LightRaw};
use crate::render::{EntityUniforms, ShadowUniforms, ForwardUniforms};
@ -134,45 +134,10 @@ impl RenderState {
(vertex_buf, index_buf)
}
/// When creating a light we have to give it a target view to render to
/// This is major danger scary since we have a 10 light limit, and only
/// 2 views created at this moment, need to smarten this up
pub fn create_light(&mut self) -> DirectionalLight {
let target = self
.shadow_target_views
.get(self.views_given as usize)
.take()
.unwrap();
self.views_given = self.views_given + 1;
DirectionalLight {
color: wgpu::Color {
r: 1.0,
g: 0.5,
b: 0.5,
a: 1.0,
},
fov: 45.0,
depth: RangeCopy {
start: 1.0,
end: 20.0,
},
target_view: target.clone(),
pos: Position {
x: 0.0,
y: 0.0,
z: 0.0,
rot: Euler {
x: Deg(0.0),
y: Deg(-25.0),
z: Deg(0.0),
},
},
}
}
pub fn load_mesh_to_buffer(&self, filepath: &str) -> Mesh {
let (vertices, indices) = import_mesh(filepath);
pub fn load_mesh_to_buffer(&self, filepath: &str, color: Option<wgpu::Color>) -> Mesh {
let (vertices, indices) = load_obj(filepath);
let index_count = indices.len();
let (vertex_buf, index_buf) = RenderState::create_buffer(&self.device, indices, vertices);
let uniform_size = mem::size_of::<EntityUniforms>() as wgpu::BufferAddress;
@ -205,6 +170,43 @@ impl RenderState {
vertex_buffer: vertex_buf,
uniform_buffer: uniform_buf,
bind_group: bind_group,
color: color.unwrap_or(wgpu::Color::RED),
}
}
/// When creating a light we have to give it a target view to render to
/// This is major danger scary since we have a 10 light limit, and only
/// 2 views created at this moment, need to smarten this up
pub fn create_light(&mut self) -> DirectionalLight {
let target = self
.shadow_target_views
.get(self.views_given as usize)
.take()
.unwrap();
self.views_given = self.views_given + 1;
DirectionalLight {
color: wgpu::Color {
r: 1.0,
g: 0.5,
b: 0.5,
a: 1.0,
},
fov: 45.0,
depth: RangeCopy {
start: 1.0,
end: 20.0,
},
target_view: target.clone(),
pos: Position {
x: 0.0,
y: 0.0,
z: 0.0,
rot: Euler {
x: Deg(0.0),
y: Deg(-25.0),
z: Deg(0.0),
},
},
}
}
@ -437,7 +439,7 @@ impl RenderState {
cgmath::Deg(75f32), // FOV, might wanna hook this up somewhere
sc_desc.width as f32 / sc_desc.height as f32,
1.0,
20.0,
50.0,
);
let forward_pass = {

@ -24,9 +24,9 @@ use winit_24::platform::unix::x11::ffi::Time;
use winit_24::window::Window;
use crate::camera::{Camera, CameraController};
use crate::components::{Color, Mesh, Position, RangeCopy};
use crate::components::{Mesh, Position, RangeCopy};
use crate::current_ui;
use crate::geometry::{import_mesh, vertex, Vertex};
use crate::geometry::{load_obj, Vertex};
use crate::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform};
use crate::light::{DirectionalLight, LightRaw};
use crate::render::state::{RenderState};
@ -52,12 +52,12 @@ pub fn imgui_prepare(
// get the frame and build a ui window
unsafe { crate::CURRENT_UI = Some(std::mem::transmute(imgui_context.frame())) }
}
#[system]
#[write_component(Camera)]
#[write_component(Position)]
#[write_component(Point3<f32>)]
#[write_component(Mesh)]
#[write_component(Color)]
#[write_component(DirectionalLight)]
pub fn render_test(
world: &mut SubWorld,
@ -88,11 +88,11 @@ pub fn render_test(
);
}
let mut query = <(&mut Position, &mut Mesh, &mut Color)>::query();
let mut query = <(&mut Position, &mut Mesh)>::query();
let mut mesh_stack = Vec::new();
// Update the entity uniforms
for (pos, mesh, color) in query.iter_mut(world) {
for (pos, mesh) in query.iter_mut(world) {
let d = Decomposed {
scale: 1.0,
rot: Quaternion::from(pos.rot),
@ -102,10 +102,10 @@ pub fn render_test(
let data = EntityUniforms {
model: m.into(),
color: [
color.r as f32,
color.g as f32,
color.b as f32,
color.a as f32,
mesh.color.r as f32,
mesh.color.g as f32,
mesh.color.b as f32,
mesh.color.a as f32,
],
};
renderer
@ -204,9 +204,9 @@ pub fn render_test(
pass.set_pipeline(&renderer.forward_pass.pipeline);
pass.set_bind_group(0, &renderer.forward_pass.bind_group, &[]);
let mut query = <(&mut Position, &mut Mesh, &mut Color)>::query();
let mut query = <(&mut Position, &mut Mesh)>::query();
for (pos, mesh, color) in query.iter_mut(world) {
for (pos, mesh) in query.iter_mut(world) {
pass.set_bind_group(1, &mesh.bind_group, &[]);
// TODO: Pipe this in through the mesh
pass.set_index_buffer(mesh.index_buffer.slice(..), mesh.index_format);

Loading…
Cancel
Save