Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use crate::{collision::*, renderable::Renderable};
- use nalgebra::{Matrix4, Vector3};
- use std::{ffi::c_void, ptr};
- #[derive(Debug, Copy, Clone)]
- pub struct Cube {
- pub vao: u32,
- pub position: Vector3<f32>,
- pub rotation: Vector3<f32>,
- pub scale: Vector3<f32>,
- pub color: Vector3<f32>,
- pub texture_id: Option<u32>,
- pub normal_map: Option<u32>,
- pub roughness_map: Option<u32>,
- }
- impl Cube {
- pub fn new(
- pos_x: f32, pos_y: f32, pos_z: f32,
- rot_x: f32, rot_y: f32, rot_z: f32,
- scale_x: f32, scale_y: f32, scale_z: f32,
- color_r: f32, color_g: f32, color_b: f32,
- tile: f32
- ) -> Cube {
- // let vertices: [f32; 288] = [
- // // back face
- // -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 0.0,
- // 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, tile, 0.0,
- // 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, tile, tile,
- // 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, tile, tile,
- // -0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 0.0, tile,
- // -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 0.0,
- // // front face
- // -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0,
- // 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, tile, 0.0,
- // 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, tile, tile,
- // 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, tile, tile,
- // -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 0.0, tile,
- // -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0,
- // // left face
- // -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, tile, 0.0,
- // -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, tile, tile,
- // -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 0.0, tile,
- // -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 0.0, tile,
- // -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 0.0, 0.0,
- // -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, tile, 0.0,
- // // right face
- // 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, tile, 0.0,
- // 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, tile, tile,
- // 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 0.0, tile,
- // 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 0.0, tile,
- // 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0,
- // 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, tile, 0.0,
- // // bottom face
- // -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 0.0, tile,
- // 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, tile, tile,
- // 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, tile, 0.0,
- // 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, tile, 0.0,
- // -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 0.0, 0.0,
- // -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 0.0, tile,
- // // top face
- // -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, tile,
- // 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, tile, tile,
- // 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, tile, 0.0,
- // 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, tile, 0.0,
- // -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 0.0,
- // -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, tile,
- // ];
- // how many times to repeat the texture along each local axis:
- let repeat_x = scale_x * tile;
- let repeat_y = scale_y * tile;
- let repeat_z = scale_z * tile;
- // build a Vec<f32> with 36 vertices × (pos3 + norm3 + uv2) = 288 floats
- let mut v: Vec<f32> = Vec::with_capacity(36 * 8);
- macro_rules! push {
- ($px:expr, $py:expr, $pz:expr,
- $nx:expr, $ny:expr, $nz:expr,
- $u:expr, $w:expr) => {
- v.extend_from_slice(&[$px, $py, $pz, $nx, $ny, $nz, $u, $w]);
- };
- }
- // BACK (–Z): spans X×Y
- push!(-0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 0.0 );
- push!( 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, repeat_x, 0.0 );
- push!( 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, repeat_x, repeat_y );
- push!( 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, repeat_x, repeat_y );
- push!(-0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 0.0, repeat_y );
- push!(-0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 0.0 );
- // FRONT (+Z): spans X×Y
- push!(-0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0 );
- push!( 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, repeat_x, 0.0 );
- push!( 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, repeat_x, repeat_y );
- push!( 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, repeat_x, repeat_y );
- push!(-0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 0.0, repeat_y );
- push!(-0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0 );
- // LEFT (–X): spans Z×Y
- push!(-0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 0.0, 0.0 );
- push!(-0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 0.0, repeat_y );
- push!(-0.5, 0.5, -0.5, -1.0, 0.0, 0.0, repeat_z, repeat_y );
- push!(-0.5, 0.5, -0.5, -1.0, 0.0, 0.0, repeat_z, repeat_y );
- push!(-0.5, -0.5, -0.5, -1.0, 0.0, 0.0, repeat_z, 0.0 );
- push!(-0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 0.0, 0.0 );
- // RIGHT (+X): spans Z×Y
- push!( 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0 );
- push!( 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 0.0, repeat_y );
- push!( 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, repeat_z, repeat_y );
- push!( 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, repeat_z, repeat_y );
- push!( 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, repeat_z, 0.0 );
- push!( 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0 );
- // BOTTOM (–Y): spans X×Z
- push!(-0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 0.0, repeat_z );
- push!( 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, repeat_x, repeat_z );
- push!( 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, repeat_x, 0.0 );
- push!( 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, repeat_x, 0.0 );
- push!(-0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 0.0, 0.0 );
- push!(-0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 0.0, repeat_z );
- // TOP (+Y): spans X×Z
- push!(-0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, repeat_z );
- push!( 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, repeat_x, repeat_z );
- push!( 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, repeat_x, 0.0 );
- push!( 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, repeat_x, 0.0 );
- push!(-0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 0.0 );
- push!(-0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, repeat_z );
- // ── Upload to GPU ────────────────────────────────────────────────────────
- let (mut vao, mut vbo) = (0, 0);
- unsafe {
- gl::GenVertexArrays(1, &mut vao);
- gl::GenBuffers(1, &mut vbo);
- gl::BindVertexArray(vao);
- gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
- gl::BufferData(
- gl::ARRAY_BUFFER,
- (v.len() * std::mem::size_of::<f32>()) as isize,
- v.as_ptr() as *const c_void,
- gl::STATIC_DRAW,
- );
- // pos (loc=0)
- gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, 8 * 4, ptr::null());
- gl::EnableVertexAttribArray(0);
- // normal (loc=1)
- gl::VertexAttribPointer(1, 3, gl::FLOAT, gl::FALSE, 8 * 4, (3 * 4) as *const _);
- gl::EnableVertexAttribArray(1);
- // texcoord (loc=2)
- gl::VertexAttribPointer(2, 2, gl::FLOAT, gl::FALSE, 8 * 4, (6 * 4) as *const _);
- gl::EnableVertexAttribArray(2);
- }
- Cube {
- vao,
- position: Vector3::new(pos_x, pos_y, pos_z),
- rotation: Vector3::new(rot_x, rot_y, rot_z),
- scale: Vector3::new(scale_x, scale_y, scale_z),
- color: Vector3::new(color_r, color_g, color_b),
- texture_id: None,
- normal_map: None,
- roughness_map: None,
- }
- }
- pub fn normal_map(&self) -> Option<u32> {
- self.normal_map
- }
- pub fn roughness_map(&self) -> Option<u32> {
- self.roughness_map
- }
- }
- impl Renderable for Cube {
- fn vao(&self) -> u32 { self.vao }
- fn model_matrix(&self) -> Matrix4<f32> {
- let t = Matrix4::new_translation(&self.position);
- let rx = Matrix4::from_euler_angles(self.rotation.x, 0.0, 0.0);
- let ry = Matrix4::from_euler_angles(0.0, self.rotation.y, 0.0);
- let rz = Matrix4::from_euler_angles(0.0, 0.0, self.rotation.z);
- let s = Matrix4::new_nonuniform_scaling(&self.scale);
- t * rz * ry * rx * s
- }
- fn vertex_count(&self) -> i32 { 36 }
- fn color(&self) -> Vector3<f32> { self.color }
- fn texture(&self) -> Option<u32> { self.texture_id }
- }
- impl Collidable for Cube {
- fn collider(&self) -> Collider {
- let half = self.scale / 2.0;
- Collider { min: self.position - half, max: self.position + half }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement