diff --git a/shaders/triangle.frag b/shaders/triangle.frag index eba1bc5..cc264b4 100644 --- a/shaders/triangle.frag +++ b/shaders/triangle.frag @@ -1,6 +1,11 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable +layout(push_constant) uniform PushConstants { + mat4 model; + bool is_selected; +} push; + layout(binding = 0) uniform ObjectUniformData { mat4 view; mat4 projection; @@ -42,4 +47,7 @@ void main() { vec3 specular_color = specular_value * specular_strength * light_color; out_color = vec4(ambient_color + diffuse_color + specular_color, 1.0) * texture(diffuse_tex, tex_coords); + if (push.is_selected) { + out_color = mix(out_color, vec4(0.5, 0.5, 0.0, 1.0), 0.1); + } } \ No newline at end of file diff --git a/shaders/triangle.frag.spv b/shaders/triangle.frag.spv index e6711a2..779b42d 100644 Binary files a/shaders/triangle.frag.spv and b/shaders/triangle.frag.spv differ diff --git a/shaders/triangle.vert b/shaders/triangle.vert index afd9fb8..90cdd93 100644 --- a/shaders/triangle.vert +++ b/shaders/triangle.vert @@ -3,6 +3,7 @@ layout(push_constant) uniform PushConstants { mat4 model; + bool is_selected; } push; layout(binding = 0) uniform ObjectUniformData { diff --git a/shaders/triangle.vert.spv b/shaders/triangle.vert.spv index ef450b9..083bb83 100644 Binary files a/shaders/triangle.vert.spv and b/shaders/triangle.vert.spv differ diff --git a/src/game/player.rs b/src/game/player.rs index 27a47a7..a23b7a5 100644 --- a/src/game/player.rs +++ b/src/game/player.rs @@ -1,4 +1,5 @@ use cgmath::{Deg, InnerSpace, Matrix4, One, Quaternion, Rad, Rotation, Rotation3, SquareMatrix, Vector3, vec3, vec4}; +use mgf::Intersection; use crate::game::player::PlayerMovementMode::{FirstPerson, Flying}; @@ -117,11 +118,26 @@ impl Updatable for Player { let ray_direction = self.camera.viewport_pos_to_ray(input.mouse_position, renderer.game_data.dimensions).unwrap(); let ray_origin: [f32; 3] = self.camera.position.into(); let ray = mgf::Ray::new(ray_origin.into(), ray_direction); - println!("Ray: {:?}", ray); - let collision_mesh = &renderer.game_data.meshes[renderer.game_data.game_objects[0].mesh_index].collision_mesh; - collision_mesh.bvh.raytrace(&ray, |v, is| { - println!("v: {:?}, is: {:?}", v, is); - }); + + let mut shortest_hit: Option<(usize, Intersection)> = None; + let mut shortest_hit_distance: f32 = f32::MAX; + + for i in 0..renderer.game_data.game_objects.len() { + let obj = &renderer.game_data.game_objects[i]; + let collision_mesh = &renderer.game_data.meshes[obj.mesh_index].collision_mesh; + collision_mesh.bvh.raytrace(&ray, |_, is| { + if is.t < shortest_hit_distance { + shortest_hit = Some((i, is)); + shortest_hit_distance = is.t; + } + }); + } + + if let Some((obj_index, intersection)) = shortest_hit { + let obj = &mut renderer.game_data.game_objects[obj_index]; + obj.is_selected = !obj.is_selected; + println!("Hit: {:?}, {:?}", obj.mesh_index, intersection); + } } // Rotation diff --git a/src/vulkan/gameobject.rs b/src/vulkan/gameobject.rs index 8f89481..2a1e914 100644 --- a/src/vulkan/gameobject.rs +++ b/src/vulkan/gameobject.rs @@ -6,6 +6,8 @@ use crate::input::InputState; use crate::vulkan::{RendererDescriptorSets, TextureHandle}; use crate::vulkan::{MeshHandle, VulkanRenderer}; +use super::pipelines::vs; + #[derive(Clone)] pub struct GameObject { pub mesh_index: usize, @@ -15,14 +17,15 @@ pub struct GameObject { pub rotation: Quaternion, pub scale: Vector3, pub children: Vec, - pub descriptor_sets: Vec> + pub descriptor_sets: Vec>, + pub is_selected: bool } impl GameObject { pub fn new(mesh: MeshHandle) -> GameObject { GameObject { mesh_index: mesh.index, texture_index: mesh.diffuse_handle, normal_map_index: mesh.normal_handle, position: Vector3::new(0.0, 0.0, 0.0), rotation: Quaternion::new(1.0, 0.0, 0.0, 0.0), scale: Vector3::new(1.0, 1.0, 1.0), children: vec![], - descriptor_sets: vec![] } + descriptor_sets: vec![], is_selected: false } } pub fn _set_position(&mut self, x: f32, y: f32, z: f32) { @@ -51,6 +54,13 @@ impl GameObject { self.rotation = self.rotation * Quaternion::from(Euler::new(Deg(x), Deg(y), Deg(z))); } + pub fn get_push_constants(&self) -> vs::ty::PushConstants { + vs::ty::PushConstants { + model: self.get_model_matrix().into(), + is_selected: if self.is_selected { 0 } else { 1 }, + } + } + pub fn get_model_matrix(&self) -> Matrix4 { let translation = Matrix4::from_translation(self.position); let rotation: Matrix4 = self.rotation.into(); diff --git a/src/vulkan/mod.rs b/src/vulkan/mod.rs index 3e2f87c..060cbbb 100644 --- a/src/vulkan/mod.rs +++ b/src/vulkan/mod.rs @@ -27,7 +27,6 @@ use pipelines::{Drawcall, LineShader}; use pipelines::line_vs::ty::LinePushConstants; use pipelines::DefaultShader; use pipelines::vs; -use pipelines::vs::ty::PushConstants; use crate::config::RenderConfig; use crate::vulkan::gameobject::{GameObject, GameObjectHandle}; @@ -91,7 +90,6 @@ pub struct Texture { pub struct GameData { pub start_time: SystemTime, pub line_vertices: Vec, - pub push_constants: PushConstants, pub line_push_constants: LinePushConstants, pub recreate_pipeline: bool, pub dimensions: [u32; 2], @@ -126,9 +124,6 @@ impl VulkanRenderer { pub fn init(line_vertices: Vec, enable_validation_layers: bool, render_config: RenderConfig) -> (VulkanRenderer, EventLoop<()>) { // Create empty game data struct to be filled let mut data = GameData { - push_constants: PushConstants { - model: Matrix4::identity().into(), - }, line_push_constants: LinePushConstants { model: Matrix4::identity().into(), view: Matrix4::identity().into(), diff --git a/src/vulkan/pipelines.rs b/src/vulkan/pipelines.rs index 23f04a9..c9628ab 100644 --- a/src/vulkan/pipelines.rs +++ b/src/vulkan/pipelines.rs @@ -140,8 +140,7 @@ impl Drawcall for DefaultShader { for i in 0..game_data.game_objects.len() { let game_object = &game_data.game_objects[i]; let mesh = &game_data.meshes[game_object.mesh_index]; - let mut push_constants = game_data.push_constants.clone(); - push_constants.model = game_object.get_model_matrix().into(); + let push_constants = game_object.get_push_constants(); builder.draw_indexed( self.pipeline.clone(),