//! an Object Module for defining Objects const SCR_WIDTH: u32 = 1600; const SCR_HEIGHT: u32 = 900; use cgmath::{Vector3, Quaternion, Rotation3, Deg, perspective, Matrix4}; use cgmath::prelude::*; use crate::model::Model; use crate::camera::Camera; use glow::HasContext; pub struct Input { pub Accel: bool, pub Decel: bool, pub Left: bool, pub Right: bool } impl Default for Input { fn default() -> Input { Input { Accel: false, Decel: false, Left: false, Right: false } } } pub struct Transform { pub Position: Vector3, pub Rotation: Quaternion, pub Velocity: Vector3, pub Scale: f32, } impl Default for Transform { fn default() -> Transform { Transform { Position: Vector3::::new(0.0, 0.0, 0.0), Rotation: Quaternion::from_angle_y(cgmath::Deg(0.0)), Velocity: Vector3::::new(0.0, 0.0, 0.0), Scale: 0.2, } } } impl Transform { pub fn setPos(&mut self, input: Vector3) { self.Position = input; } } pub struct Player { pub Transform: Transform, pub Model: Model } impl Player { pub fn new(gl: std::sync::Arc) -> Self { Player { Transform: Transform::default(), Model: Model::new("resources/models/TestCarModel/CarW4.obj", gl), } } pub fn update(&mut self, input: &Input) { if input.Accel { self.forward(0.01); } if input.Decel { self.forward(-0.01) } if input.Left { self.turn(1.5) } if input.Right { self.turn(-1.5) } self.Transform.Position += self.Transform.Velocity; self.Transform.Rotation = self.Transform.Rotation.normalize(); } pub fn forward(&mut self, amount: f32) { let forward = self.Transform.Rotation.rotate_vector(cgmath::Vector3::unit_z()); let distance = forward * amount; self.Transform.Position += distance; } pub fn turn(&mut self, amount: f32) { let up = Vector3::::unit_y(); let delta_rotation = Quaternion::from_axis_angle(up, cgmath::Deg(amount)); self.Transform.Rotation = self.Transform.Rotation * delta_rotation; } pub fn Draw(&self, shader: &crate::shader::shader, camera: &Camera) { shader.Use(); let translation = cgmath::Matrix4::from_translation(self.Transform.Position); let rotation = cgmath::Matrix4::from(self.Transform.Rotation); let scale = cgmath::Matrix4::from_scale(self.Transform.Scale); let model = translation * rotation * scale; let projection = cgmath::perspective(cgmath::Deg(camera.Zoom), SCR_WIDTH as f32 /SCR_HEIGHT as f32, 0.1, 100.0 ); let view = camera.GetViewMatrix(); shader.setMat4("projection", &projection); shader.setMat4("view", &view); shader.setMat4("model", &model); self.Model.Draw(shader); } } pub struct plane { pub texture: glow::NativeTexture, pub VAO: glow::VertexArray, VBO: glow::Buffer, EBO: glow::Buffer, } impl plane { pub fn new(gl: std::sync::Arc) -> plane { let vertices: [f32; 20] = [ 10.5, 10.5, 0.0, 1.0, 1.0, 10.5, -10.5, 0.0, 1.0, 0.0, -10.5, -10.5, 0.0, 0.0, 0.0, -10.5, 10.5, 0.0, 0.0, 1.0 ]; let indices: [u32; 6] = [ 0, 1, 3, 1, 2, 3 ]; unsafe { let VAO = gl.create_vertex_array().unwrap(); let VBO = gl.create_buffer().unwrap(); let EBO = gl.create_buffer().unwrap(); gl.bind_vertex_array(Some(VAO)); gl.bind_buffer(glow::ARRAY_BUFFER, Some(VBO)); let data = core::slice::from_raw_parts( vertices.as_ptr() as *const u8, vertices.len() * core::mem::size_of::(), ); gl.named_buffer_data_u8_slice(VBO, data, glow::STATIC_DRAW); gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(EBO)); let data = core::slice::from_raw_parts( indices.as_ptr() as *const u8, indices.len() * core::mem::size_of::(), ); gl.named_buffer_data_u8_slice(EBO, data, glow::STATIC_DRAW); let stride = 5 * core::mem::size_of::() as i32; gl.enable_vertex_attrib_array(0); gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, stride, 0); gl.enable_vertex_attrib_array(1); gl.vertex_attrib_pointer_f32(1, 2, glow::FLOAT, false, stride, (3 * core::mem::size_of::()) as i32 ); gl.bind_vertex_array(None); plane { texture: crate::model::TextureFromFile("texture.jpg", "resources", gl.clone()), VAO, VBO, EBO } } } pub fn draw(&self, shader: &crate::shader::shader, camera: &Camera) { unsafe { shader.Use(); let model = cgmath::Matrix4::from_angle_x(cgmath::Deg(-90.0)); let projection = cgmath::perspective(cgmath::Deg(camera.Zoom), SCR_WIDTH as f32 /SCR_HEIGHT as f32, 0.1, 100.0); let view = camera.GetViewMatrix(); shader.setMat4("model", &model); shader.setMat4("view", &view); shader.setMat4("projection", &projection); shader.setFloat("tile_size", 0.5); shader.setFloat("scroll_speed", 10.0); let camera_direction = (camera.Position - cgmath::Point3::new(0.0, 0.0, 0.0)); shader.setVector3("camera_position", camera_direction); shader.gl.bind_texture(glow::TEXTURE_2D, Some(self.texture)); shader.gl.bind_vertex_array(Some(self.VAO)); shader.gl.draw_elements(glow::TRIANGLES, 6, glow::UNSIGNED_INT, 0); shader.gl.bind_vertex_array(None); shader.gl.active_texture(glow::TEXTURE0); } } }