diff --git a/src/main.rs b/src/main.rs index 315c953..9e7b52a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ mod time; mod uniforms; mod vertex; mod world; +mod npc; use std::time::{Duration, Instant}; use wgpu::SwapChainError; diff --git a/src/npc.rs b/src/npc.rs index 7a476b5..c09d1ea 100644 --- a/src/npc.rs +++ b/src/npc.rs @@ -1,5 +1,67 @@ -pub struct Npc { - Vector3 position; - Vector3 scale; - Vector3 rotation; +extern crate gltf; +extern crate wgpu; + +use cgmath::{Vector3}; + +use crate::{ + vertex::Vertex, }; + +pub struct Npc { + pub position: Vector3, + pub scale: Vector3, + pub rotation: Vector3, + pub vertices: Vec, + pub indices: Vec, + pub vertex_buffer: Option, + pub index_buffer: Option, +} + + +impl Npc { + pub fn load() -> Self { + let position: Vector3 = Vector3::new(0.0, 0.0, 0.0); + let scale: Vector3 = Vector3::new(0.0, 0.0, 0.0); + let rotation: Vector3 = Vector3::new(0.0, 0.0, 0.0); + + let (model, buffers, _) = gltf::import("assets/models/minecrab.glb").unwrap(); + + let mut indices: Vec = Vec::new(); + let mut vertices: Vec = Vec::new(); + + for mesh in model.meshes() { + for primitive in mesh.primitives() { + let reader = primitive.reader(|buffer| Some(&buffers[buffer.index()])); + indices = reader.read_indices().unwrap().into_u32().collect(); + // loop over all primitives and get the normals, position and color + + let pos_iter = reader.read_positions().unwrap(); + let norm_iter = reader.read_normals().unwrap(); + let tex_iter = reader.read_tex_coords(0).unwrap().into_f32(); + + for it in pos_iter.zip(norm_iter).zip(tex_iter) { + let ((position, normal), [tex_x, tex_y]) = it; + + let current_vert: Vertex = Vertex { + position, + texture_coordinates: [tex_x, tex_y, 0.0], + normal, + highlighted: 0 + }; + + vertices.push(current_vert); + } + } + } + + return Self { + position, + scale, + rotation, + indices, + vertices, + vertex_buffer: None, + index_buffer: None + }; + } +} diff --git a/src/state/world_state.rs b/src/state/world_state.rs index f4a9cb8..a15c433 100644 --- a/src/state/world_state.rs +++ b/src/state/world_state.rs @@ -258,6 +258,27 @@ impl WorldState { println!("World update took {:?}", elapsed); } + pub fn load_npc_geometry( + &mut self, + render_context: &RenderContext, + ) { + self.world.npc.vertex_buffer = Some(render_context + .device + .create_buffer_init(&BufferInitDescriptor { + label: None, + contents: &bytemuck::cast_slice(&self.world.npc.vertices), + usage: wgpu::BufferUsage::VERTEX, + })); + + self.world.npc.index_buffer = Some(render_context + .device + .create_buffer_init(&BufferInitDescriptor { + label: None, + contents: &bytemuck::cast_slice(&self.world.npc.indices), + usage: wgpu::BufferUsage::INDEX, + })); + } + pub fn update_chunk_geometry( &mut self, render_context: &RenderContext, @@ -370,6 +391,7 @@ impl WorldState { }; world_state.update_world_geometry(render_context); + world_state.load_npc_geometry(render_context); world_state } @@ -425,6 +447,15 @@ impl WorldState { triangle_count += index_count / 3; } + { + let vertex_buffer = self.world.npc.vertex_buffer.unwrap(); + let index_buffer = self.world.npc.index_buffer.unwrap(); + + render_pass.set_vertex_buffer(0, vertex_buffer.slice(..)); + render_pass.set_index_buffer(index_buffer.slice(..), wgpu::IndexFormat::Uint32); + render_pass.draw_indexed(0..self.world.npc.indices.len() as u32 , 0, 0..1); + } + triangle_count } diff --git a/src/world.rs b/src/world.rs index 27aff76..d12b4ae 100644 --- a/src/world.rs +++ b/src/world.rs @@ -1,12 +1,14 @@ use crate::{ chunk::{Block, Chunk, CHUNK_SIZE}, vertex::Vertex, + npc::Npc, }; use cgmath::{InnerSpace, Vector3}; use rayon::prelude::*; pub struct World { pub chunks: Vec>>, + pub npc: Npc } const WORLD_SIZE: Vector3 = Vector3::new( @@ -19,6 +21,8 @@ impl World { pub fn generate() -> Self { let mut chunks = Vec::new(); + let npc = Npc::load(); + (0..WORLD_SIZE.y) .into_par_iter() .map(|y| { @@ -35,7 +39,7 @@ impl World { }) .collect_into_vec(&mut chunks); - Self { chunks } + Self { chunks, npc } } pub fn highlighted_for_chunk(