aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/render-bsp/Cargo.toml2
-rw-r--r--examples/render-bsp/src/main.rs30
-rw-r--r--stockton-levels/src/features.rs21
-rw-r--r--stockton-levels/src/helpers.rs8
-rw-r--r--stockton-levels/src/lib.rs5
-rw-r--r--stockton-levels/src/prelude.rs18
-rw-r--r--stockton-levels/src/q3/brushes.rs8
-rw-r--r--stockton-levels/src/q3/effects.rs8
-rw-r--r--stockton-levels/src/q3/entities.rs6
-rw-r--r--stockton-levels/src/q3/faces.rs63
-rw-r--r--stockton-levels/src/q3/light_maps.rs8
-rw-r--r--stockton-levels/src/q3/light_vols.rs8
-rw-r--r--stockton-levels/src/q3/models.rs8
-rw-r--r--stockton-levels/src/q3/planes.rs10
-rw-r--r--stockton-levels/src/q3/textures.rs6
-rw-r--r--stockton-levels/src/q3/tree.rs4
-rw-r--r--stockton-levels/src/q3/vertices.rs20
-rw-r--r--stockton-levels/src/traits/brushes.rs10
-rw-r--r--stockton-levels/src/traits/effects.rs10
-rw-r--r--stockton-levels/src/traits/entities.rs6
-rw-r--r--stockton-levels/src/traits/faces.rs28
-rw-r--r--stockton-levels/src/traits/light_maps.rs8
-rw-r--r--stockton-levels/src/traits/light_vols.rs10
-rw-r--r--stockton-levels/src/traits/models.rs10
-rw-r--r--stockton-levels/src/traits/planes.rs7
-rw-r--r--stockton-levels/src/traits/textures.rs6
-rw-r--r--stockton-levels/src/traits/tree.rs5
-rw-r--r--stockton-levels/src/traits/vertices.rs21
-rw-r--r--stockton-levels/src/traits/visdata.rs2
-rw-r--r--stockton-render/Cargo.toml2
-rw-r--r--stockton-render/src/culling.rs41
-rw-r--r--stockton-render/src/draw/context.rs16
-rw-r--r--stockton-render/src/lib.rs11
-rw-r--r--stockton-types/src/lib.rs2
-rw-r--r--stockton-types/src/world.rs19
35 files changed, 258 insertions, 189 deletions
diff --git a/examples/render-bsp/Cargo.toml b/examples/render-bsp/Cargo.toml
index a68223f..666f035 100644
--- a/examples/render-bsp/Cargo.toml
+++ b/examples/render-bsp/Cargo.toml
@@ -6,7 +6,7 @@ authors = ["Oscar <oscar.shrimpton.personal@gmail.com>"]
[dependencies]
stockton-render = { path = "../../stockton-render", features = ["vulkan"] }
stockton-types = { path = "../../stockton-types" }
-stockton-bsp = { git = "https://github.com/tcmal/rust-bsp.git" }
+stockton-levels = { path = "../../stockton-levels" }
winit = "^0.21"
simple_logger = "1.0"
image = "0.23.2"
diff --git a/examples/render-bsp/src/main.rs b/examples/render-bsp/src/main.rs
index 7477567..f2310e6 100644
--- a/examples/render-bsp/src/main.rs
+++ b/examples/render-bsp/src/main.rs
@@ -16,7 +16,7 @@
//! Renders ./example.bsp
extern crate stockton_types;
-extern crate stockton_bsp;
+extern crate stockton_levels;
extern crate stockton_render;
extern crate winit;
extern crate simple_logger;
@@ -25,7 +25,7 @@ extern crate image;
use image::load_from_memory;
use std::time::SystemTime;
-use stockton_bsp::BSPFile;
+use stockton_levels::q3::Q3BSPFile;
use stockton_types::{World, Vector3};
use stockton_render::Renderer;
@@ -35,7 +35,7 @@ use winit::{
window::WindowBuilder
};
-const SPEED: f32 = 25.0;
+const SPEED: f32 = 100.0;
#[derive(Debug)]
struct KeyState {
@@ -91,21 +91,22 @@ fn main() {
let event_loop = EventLoop::new();
let window = WindowBuilder::new().build(&event_loop).unwrap();
let data = include_bytes!("../data/test.bsp").to_vec().into_boxed_slice();
- let bsp = BSPFile::from_buffer(data).unwrap();
+ let bsp = Q3BSPFile::new(&data).unwrap();
- let world = World::new(bsp).unwrap();
+ let world = World::new(bsp);
let mut renderer = Renderer::new(world, &window).unwrap();
+ {
+ renderer.context.add_texture(
+ load_from_memory(include_bytes!("../../render-quad/data/test1.png"))
+ .expect("Couldn't load test texture 1")
+ .into_rgba()).unwrap();
- renderer.context.add_texture(
- load_from_memory(include_bytes!("../../render-quad/data/test1.png"))
- .expect("Couldn't load test texture 1")
- .into_rgba()).unwrap();
-
- renderer.context.add_texture(
- load_from_memory(include_bytes!("../../render-quad/data/test2.png"))
- .expect("Couldn't load test texture 2")
- .into_rgba()).unwrap();
+ renderer.context.add_texture(
+ load_from_memory(include_bytes!("../../render-quad/data/test2.png"))
+ .expect("Couldn't load test texture 2")
+ .into_rgba()).unwrap();
+ }
let mut last_update = SystemTime::now();
let mut key_state = KeyState::new();
@@ -113,7 +114,6 @@ fn main() {
// Keep rendering the world
event_loop.run(move |event, _, flow| {
*flow = ControlFlow::Poll;
-
match event {
Event::WindowEvent {
event,
diff --git a/stockton-levels/src/features.rs b/stockton-levels/src/features.rs
new file mode 100644
index 0000000..3f53308
--- /dev/null
+++ b/stockton-levels/src/features.rs
@@ -0,0 +1,21 @@
+// Copyright (C) Oscar Shrimpton 2019
+
+// This program is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation, either version 3 of the License, or (at your option)
+// any later version.
+
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>.
+//! Marker traits for different feature sets
+
+use crate::traits::*;
+
+pub trait MinBSPFeatures: HasBSPTree {}
+impl<T> MinBSPFeatures for T
+ where T: HasBSPTree {} \ No newline at end of file
diff --git a/stockton-levels/src/helpers.rs b/stockton-levels/src/helpers.rs
index b81fb6a..c3e6c80 100644
--- a/stockton-levels/src/helpers.rs
+++ b/stockton-levels/src/helpers.rs
@@ -63,9 +63,9 @@ pub fn slice_to_vec3i(slice: &[u8]) -> Vector3<i32> {
)
}
-/// Turn a slice of i32s into a 2D vector
+/// Turn a slice of u32s into a 2D vector
/// # Panics
/// If slice isn't 8 bytes long.
-pub fn slice_to_vec2i(slice: &[u8]) -> Vector2<i32> {
- Vector2::new(slice_to_i32(&slice[0..4]), slice_to_i32(&slice[4..8]))
-}
+pub fn slice_to_vec2ui(slice: &[u8]) -> Vector2<u32> {
+ Vector2::new(slice_to_u32(&slice[0..4]), slice_to_u32(&slice[4..8]))
+} \ No newline at end of file
diff --git a/stockton-levels/src/lib.rs b/stockton-levels/src/lib.rs
index 37d1050..aef802e 100644
--- a/stockton-levels/src/lib.rs
+++ b/stockton-levels/src/lib.rs
@@ -13,6 +13,7 @@
// You should have received a copy of the GNU General Public License along
// with this program. If not, see <http://www.gnu.org/licenses/>.
//! Parses common features from many BSP file formats.
+#![feature(generic_associated_types)]
#[macro_use]
extern crate bitflags;
@@ -22,4 +23,6 @@ extern crate nalgebra as na;
mod helpers;
pub mod q3;
pub mod types;
-pub mod traits; \ No newline at end of file
+pub mod traits;
+pub mod prelude;
+pub mod features; \ No newline at end of file
diff --git a/stockton-levels/src/prelude.rs b/stockton-levels/src/prelude.rs
new file mode 100644
index 0000000..8834f03
--- /dev/null
+++ b/stockton-levels/src/prelude.rs
@@ -0,0 +1,18 @@
+// Copyright (C) Oscar Shrimpton 2019
+
+// This program is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation, either version 3 of the License, or (at your option)
+// any later version.
+
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>.
+//! Common traits, etc.
+
+pub use crate::traits::*;
+pub use crate::features::*; \ No newline at end of file
diff --git a/stockton-levels/src/q3/brushes.rs b/stockton-levels/src/q3/brushes.rs
index 48462a2..f8a979d 100644
--- a/stockton-levels/src/q3/brushes.rs
+++ b/stockton-levels/src/q3/brushes.rs
@@ -104,14 +104,14 @@ fn get_sides(
}
-impl<'a> HasBrushes<'a> for Q3BSPFile {
- type BrushesIter = std::slice::Iter<'a, Brush>;
+impl HasBrushes for Q3BSPFile {
+ type BrushesIter<'a> = std::slice::Iter<'a, Brush>;
- fn brushes_iter(&'a self) -> Self::BrushesIter {
+ fn brushes_iter<'a>(&'a self) -> Self::BrushesIter<'a> {
self.brushes.iter()
}
- fn get_brush(&'a self, index: u32) -> &'a Brush {
+ fn get_brush<'a>(&'a self, index: u32) -> &'a Brush {
&self.brushes[index as usize]
}
}
diff --git a/stockton-levels/src/q3/effects.rs b/stockton-levels/src/q3/effects.rs
index 2a76da9..0fddfb7 100644
--- a/stockton-levels/src/q3/effects.rs
+++ b/stockton-levels/src/q3/effects.rs
@@ -50,14 +50,14 @@ pub fn from_data(data: &[u8], n_brushes: u32) -> Result<Box<[Effect]>> {
}
-impl<'a> HasEffects<'a> for Q3BSPFile {
- type EffectsIter = std::slice::Iter<'a, Effect>;
+impl HasEffects for Q3BSPFile {
+ type EffectsIter<'a> = std::slice::Iter<'a, Effect>;
- fn effects_iter(&'a self) -> Self::EffectsIter {
+ fn effects_iter<'a>(&'a self) -> Self::EffectsIter<'a> {
self.effects.iter()
}
- fn get_effect(&'a self, index: u32) -> &'a Effect {
+ fn get_effect<'a>(&'a self, index: u32) -> &'a Effect {
&self.effects[index as usize]
}
}
diff --git a/stockton-levels/src/q3/entities.rs b/stockton-levels/src/q3/entities.rs
index 1614f26..9284fe4 100644
--- a/stockton-levels/src/q3/entities.rs
+++ b/stockton-levels/src/q3/entities.rs
@@ -99,10 +99,10 @@ pub fn from_data(data: &[u8]) -> Result<Box<[Entity]>> {
Ok(entities.into_boxed_slice())
}
-impl<'a> HasEntities<'a> for Q3BSPFile {
- type EntitiesIter = std::slice::Iter<'a, Entity>;
+impl HasEntities for Q3BSPFile {
+ type EntitiesIter<'a> = std::slice::Iter<'a, Entity>;
- fn entities_iter(&'a self) -> Self::EntitiesIter {
+ fn entities_iter<'a>(&'a self) -> Self::EntitiesIter<'a> {
self.entities.iter()
}
}
diff --git a/stockton-levels/src/q3/faces.rs b/stockton-levels/src/q3/faces.rs
index 835dbe8..933f0d6 100644
--- a/stockton-levels/src/q3/faces.rs
+++ b/stockton-levels/src/q3/faces.rs
@@ -15,7 +15,7 @@
// You should have received a copy of the GNU General Public License
// along with stockton-bsp. If not, see <http://www.gnu.org/licenses/>.
-use crate::helpers::{slice_to_i32, slice_to_vec2i, slice_to_vec3};
+use crate::helpers::{slice_to_i32, slice_to_u32, slice_to_vec2ui, slice_to_vec3};
use crate::types::{Result, ParseError};
use na::Vector3;
use crate::traits::faces::*;
@@ -41,11 +41,11 @@ pub fn from_data(
for n in 0..length {
faces.push(face_from_slice(
&data[n * FACE_SIZE..(n + 1) * FACE_SIZE],
- n_textures as usize,
- n_effects as usize,
- n_vertices as usize,
- n_meshverts as usize,
- n_lightmaps as usize,
+ n_textures,
+ n_effects,
+ n_vertices,
+ n_meshverts,
+ n_lightmaps,
)?);
}
@@ -55,24 +55,24 @@ pub fn from_data(
fn face_from_slice(
data: &[u8],
- n_textures: usize,
- n_effects: usize,
- n_vertices: usize,
- n_meshverts: usize,
- n_lightmaps: usize,
+ n_textures: u32,
+ n_effects: u32,
+ n_vertices: u32,
+ n_meshverts: u32,
+ n_lightmaps: u32,
) -> Result<Face> {
if data.len() != FACE_SIZE {
panic!("tried to call face.from_slice with invalid slice size");
}
// texture
- let texture_idx = slice_to_i32(&data[0..4]) as usize;
+ let texture_idx = slice_to_u32(&data[0..4]);
if texture_idx >= n_textures {
return Err(ParseError::Invalid);
}
// effects
- let effect_idx = slice_to_i32(&data[4..8]) as usize;
+ let effect_idx = slice_to_u32(&data[4..8]);
let effect_idx = if effect_idx < 0xffffffff {
if effect_idx >= n_effects {
return Err(ParseError::Invalid);
@@ -85,11 +85,11 @@ fn face_from_slice(
// face type
// TODO
- let face_type: FaceType = unsafe { ::std::mem::transmute(slice_to_i32(&data[8..12])) };
+ let face_type: FaceType = unsafe { ::std::mem::transmute(slice_to_u32(&data[8..12])) };
// vertices
- let vertex_offset = slice_to_i32(&data[12..16]) as usize;
- let vertex_n = slice_to_i32(&data[16..20]) as usize;
+ let vertex_offset = slice_to_u32(&data[12..16]);
+ let vertex_n = slice_to_u32(&data[16..20]);
if (vertex_offset + vertex_n) > n_vertices {
return Err(ParseError::Invalid);
}
@@ -97,8 +97,8 @@ fn face_from_slice(
let vertices_idx = vertex_offset..vertex_offset + vertex_n;
// meshverts
- let meshverts_offset = slice_to_i32(&data[20..24]) as usize;
- let meshverts_n = slice_to_i32(&data[24..28]) as usize;
+ let meshverts_offset = slice_to_u32(&data[20..24]);
+ let meshverts_n = slice_to_u32(&data[24..28]);
if (meshverts_offset + meshverts_n) > n_meshverts {
return Err(ParseError::Invalid);
}
@@ -106,20 +106,20 @@ fn face_from_slice(
let meshverts_idx = meshverts_offset..meshverts_offset + meshverts_n;
// lightmap
- let lightmap_idx = slice_to_i32(&data[28..32]) as usize;
- let lightmap_idx = if lightmap_idx < 0xffffffff {
- if lightmap_idx >= n_lightmaps {
+ let lightmap_idx = slice_to_i32(&data[28..32]);
+ let lightmap_idx = if lightmap_idx > 0 {
+ if lightmap_idx as u32 >= n_lightmaps {
return Err(ParseError::Invalid);
}
- Some(lightmap_idx)
+ Some(lightmap_idx as u32)
} else {
None
};
// map properties
- let map_start = slice_to_vec2i(&data[32..40]);
- let map_size = slice_to_vec2i(&data[40..48]);
+ let map_start = slice_to_vec2ui(&data[32..40]);
+ let map_size = slice_to_vec2ui(&data[40..48]);
let map_origin = slice_to_vec3(&data[48..60]);
// map_vecs
@@ -131,7 +131,7 @@ fn face_from_slice(
// normal & size
let normal = slice_to_vec3(&data[84..96]);
- let size = slice_to_vec2i(&data[96..104]);
+ let size = slice_to_vec2ui(&data[96..104]);
Ok(Face {
face_type,
@@ -150,14 +150,19 @@ fn face_from_slice(
}
-impl<'a> HasFaces<'a> for Q3BSPFile {
- type FacesIter = std::slice::Iter<'a, Face>;
+impl HasFaces for Q3BSPFile {
+ type FacesIter<'a> = std::slice::Iter<'a, Face>;
- fn faces_iter(&'a self) -> Self::FacesIter {
+ fn faces_iter<'a>(&'a self) -> Self::FacesIter<'a> {
self.faces.iter()
}
- fn get_face(&'a self, index: u32) -> &'a Face {
+ fn faces_len(&self) -> u32 {
+ self.faces.len() as u32
+ }
+
+ fn get_face<'a>(&'a self, index: u32) -> &'a Face {
&self.faces[index as usize]
}
+
}
diff --git a/stockton-levels/src/q3/light_maps.rs b/stockton-levels/src/q3/light_maps.rs
index 6743aa4..a03f164 100644
--- a/stockton-levels/src/q3/light_maps.rs
+++ b/stockton-levels/src/q3/light_maps.rs
@@ -46,14 +46,14 @@ pub fn from_data(data: &[u8]) -> Result<Box<[LightMap]>> {
Ok(maps.into_boxed_slice())
}
-impl<'a> HasLightMaps<'a> for Q3BSPFile {
- type LightMapsIter = std::slice::Iter<'a, LightMap>;
+impl HasLightMaps for Q3BSPFile {
+ type LightMapsIter<'a> = std::slice::Iter<'a, LightMap>;
- fn lightmaps_iter(&'a self) -> Self::LightMapsIter {
+ fn lightmaps_iter<'a>(&'a self) -> Self::LightMapsIter<'a> {
self.light_maps.iter()
}
- fn get_lightmap(&'a self, index: u32) -> &'a LightMap {
+ fn get_lightmap<'a>(&'a self, index: u32) -> &'a LightMap {
&self.light_maps[index as usize]
}
} \ No newline at end of file
diff --git a/stockton-levels/src/q3/light_vols.rs b/stockton-levels/src/q3/light_vols.rs
index 02c4cb4..202c375 100644
--- a/stockton-levels/src/q3/light_vols.rs
+++ b/stockton-levels/src/q3/light_vols.rs
@@ -43,14 +43,14 @@ pub fn from_data(data: &[u8]) -> Result<Box<[LightVol]>> {
}
-impl<'a> HasLightVols<'a> for Q3BSPFile {
- type LightVolsIter = std::slice::Iter<'a, LightVol>;
+impl HasLightVols for Q3BSPFile {
+ type LightVolsIter<'a> = std::slice::Iter<'a, LightVol>;
- fn lightvols_iter(&'a self) -> Self::LightVolsIter {
+ fn lightvols_iter<'a>(&'a self) -> Self::LightVolsIter<'a> {
self.light_vols.iter()
}
- fn get_lightvol(&'a self, index: u32) -> &'a LightVol {
+ fn get_lightvol<'a>(&'a self, index: u32) -> &'a LightVol {
&self.light_vols[index as usize]
}
}
diff --git a/stockton-levels/src/q3/models.rs b/stockton-levels/src/q3/models.rs
index e2307d6..cd901bc 100644
--- a/stockton-levels/src/q3/models.rs
+++ b/stockton-levels/src/q3/models.rs
@@ -73,14 +73,14 @@ pub fn from_data(
}
-impl<'a> HasModels<'a> for Q3BSPFile {
- type ModelsIter = std::slice::Iter<'a, Model>;
+impl HasModels for Q3BSPFile {
+ type ModelsIter<'a> = std::slice::Iter<'a, Model>;
- fn models_iter(&'a self) -> Self::ModelsIter {
+ fn models_iter<'a>(&'a self) -> Self::ModelsIter<'a> {
self.models.iter()
}
- fn get_model(&'a self, index: u32) -> &'a Model {
+ fn get_model<'a>(&'a self, index: u32) -> &'a Model {
&self.models[index as usize]
}
}
diff --git a/stockton-levels/src/q3/planes.rs b/stockton-levels/src/q3/planes.rs
index 970ddde..dd4f3aa 100644
--- a/stockton-levels/src/q3/planes.rs
+++ b/stockton-levels/src/q3/planes.rs
@@ -45,10 +45,14 @@ pub fn from_data(data: &[u8]) -> Result<Box<[Plane]>> {
Ok(planes.into_boxed_slice())
}
-impl<'a> HasPlanes<'a> for Q3BSPFile {
- type PlanesIter = std::slice::Iter<'a, Plane>;
+impl HasPlanes for Q3BSPFile {
+ type PlanesIter<'a> = std::slice::Iter<'a, Plane>;
- fn planes_iter(&'a self) -> Self::PlanesIter {
+ fn planes_iter<'a>(&'a self) -> Self::PlanesIter<'a> {
self.planes.iter()
}
+
+ fn get_plane<'a>(&'a self, idx: u32) -> &'a Plane {
+ &self.planes[idx as usize]
+ }
} \ No newline at end of file
diff --git a/stockton-levels/src/q3/textures.rs b/stockton-levels/src/q3/textures.rs
index 264389e..78c3135 100644
--- a/stockton-levels/src/q3/textures.rs
+++ b/stockton-levels/src/q3/textures.rs
@@ -50,10 +50,10 @@ pub fn from_data(lump: &[u8]) -> Result<Box<[Texture]>> {
Ok(textures.into_boxed_slice())
}
-impl<'a> HasTextures<'a> for Q3BSPFile {
- type TexturesIter = std::slice::Iter<'a, Texture>;
+impl HasTextures for Q3BSPFile {
+ type TexturesIter<'a> = std::slice::Iter<'a, Texture>;
- fn textures_iter(&'a self) -> Self::TexturesIter {
+ fn textures_iter<'a>(&'a self) -> Self::TexturesIter<'a> {
self.textures.iter()
}
}
diff --git a/stockton-levels/src/q3/tree.rs b/stockton-levels/src/q3/tree.rs
index 4ef5470..e157d97 100644
--- a/stockton-levels/src/q3/tree.rs
+++ b/stockton-levels/src/q3/tree.rs
@@ -161,8 +161,8 @@ fn compile_node(
}
}
-impl<'a> HasBSPTree<'a> for Q3BSPFile {
- fn get_bsp_root(&'a self) -> &'a BSPNode {
+impl HasBSPTree for Q3BSPFile {
+ fn get_bsp_root<'a>(&'a self) -> &'a BSPNode {
&self.tree_root
}
} \ No newline at end of file
diff --git a/stockton-levels/src/q3/vertices.rs b/stockton-levels/src/q3/vertices.rs
index 4583aef..51a3590 100644
--- a/stockton-levels/src/q3/vertices.rs
+++ b/stockton-levels/src/q3/vertices.rs
@@ -18,7 +18,7 @@
use std::convert::TryInto;
use super::Q3BSPFile;
-use crate::helpers::{slice_to_i32, slice_to_vec3};
+use crate::helpers::{slice_to_u32, slice_to_vec3};
use crate::types::{Result, ParseError, RGBA};
use crate::traits::vertices::*;
@@ -58,32 +58,32 @@ pub fn meshverts_from_data(data: &[u8]) -> Result<Box<[MeshVert]>> {
let mut meshverts = Vec::with_capacity(length as usize);
for n in 0..length {
- meshverts.push(slice_to_i32(&data[n * 4..(n + 1) * 4]))
+ meshverts.push(slice_to_u32(&data[n * 4..(n + 1) * 4]))
}
Ok(meshverts.into_boxed_slice())
}
-impl<'a> HasVertices<'a> for Q3BSPFile {
- type VerticesIter = std::slice::Iter<'a, Vertex>;
+impl HasVertices for Q3BSPFile {
+ type VerticesIter<'a> = std::slice::Iter<'a, Vertex>;
- fn vertices_iter(&'a self) -> Self::VerticesIter {
+ fn vertices_iter<'a>(&'a self) -> Self::VerticesIter<'a> {
self.vertices.iter()
}
- fn get_vertex(&'a self, index: u32) -> &'a Vertex {
+ fn get_vertex<'a>(&'a self, index: u32) -> &'a Vertex {
&self.vertices[index as usize]
}
}
-impl<'a> HasMeshVerts<'a> for Q3BSPFile {
- type MeshVertsIter = std::slice::Iter<'a, MeshVert>;
+impl HasMeshVerts for Q3BSPFile {
+ type MeshVertsIter<'a> = std::slice::Iter<'a, MeshVert>;
- fn meshverts_iter(&'a self) -> Self::MeshVertsIter {
+ fn meshverts_iter<'a>(&'a self) -> Self::MeshVertsIter<'a> {
self.meshverts.iter()
}
- fn get_meshvert(&self, index: u32) -> MeshVert {
+ fn get_meshvert<'a>(&self, index: u32) -> MeshVert {
self.meshverts[index as usize]
}
} \ No newline at end of file
diff --git a/stockton-levels/src/traits/brushes.rs b/stockton-levels/src/traits/brushes.rs
index 0b07653..6131824 100644
--- a/stockton-levels/src/traits/brushes.rs
+++ b/stockton-levels/src/traits/brushes.rs
@@ -17,6 +17,8 @@
//! Parses the brushes & brushsides lumps from a bsp file
+use super::HasPlanes;
+
/// One brush record. Used for collision detection.
/// "Each brush describes a convex volume as defined by its surrounding surfaces."
#[derive(Debug, Clone, PartialEq)]
@@ -33,9 +35,9 @@ pub struct BrushSide {
pub is_opposing: bool,
}
-pub trait HasBrushes<'a> {
- type BrushesIter: Iterator<Item = &'a Brush>;
+pub trait HasBrushes: HasPlanes {
+ type BrushesIter<'a>: Iterator<Item = &'a Brush>;
- fn brushes_iter(&'a self) -> Self::BrushesIter;
- fn get_brush(&'a self, index: u32) -> &'a Brush;
+ fn brushes_iter<'a>(&'a self) -> Self::BrushesIter<'a>;
+ fn get_brush<'a>(&'a self, index: u32) -> &'a Brush;
}
diff --git a/stockton-levels/src/traits/effects.rs b/stockton-levels/src/traits/effects.rs
index c889ea7..d969dd1 100644
--- a/stockton-levels/src/traits/effects.rs
+++ b/stockton-levels/src/traits/effects.rs
@@ -15,6 +15,8 @@
// You should have received a copy of the GNU General Public License
// along with stockton-bsp. If not, see <http://www.gnu.org/licenses/>.
+use super::HasBrushes;
+
/// One effect definition
#[derive(Debug, Clone, PartialEq)]
pub struct Effect {
@@ -27,9 +29,9 @@ pub struct Effect {
// todo: unknown: i32
}
-pub trait HasEffects<'a> {
- type EffectsIter: Iterator<Item = &'a Effect>;
+pub trait HasEffects: HasBrushes {
+ type EffectsIter<'a>: Iterator<Item = &'a Effect>;
- fn effects_iter(&'a self) -> Self::EffectsIter;
- fn get_effect(&'a self, index: u32) -> &'a Effect;
+ fn effects_iter<'a>(&'a self) -> Self::EffectsIter<'a>;
+ fn get_effect<'a>(&'a self, index: u32) -> &'a Effect;
}
diff --git a/stockton-levels/src/traits/entities.rs b/stockton-levels/src/traits/entities.rs
index 6a762e0..706f25a 100644
--- a/stockton-levels/src/traits/entities.rs
+++ b/stockton-levels/src/traits/entities.rs
@@ -22,8 +22,8 @@ pub struct Entity {
pub attributes: HashMap<String, String>,
}
-pub trait HasEntities<'a> {
- type EntitiesIter: Iterator<Item = &'a Entity>;
+pub trait HasEntities {
+ type EntitiesIter<'a>: Iterator<Item = &'a Entity>;
- fn entities_iter(&'a self) -> Self::EntitiesIter;
+ fn entities_iter<'a>(&'a self) -> Self::EntitiesIter<'a>;
} \ No newline at end of file
diff --git a/stockton-levels/src/traits/faces.rs b/stockton-levels/src/traits/faces.rs
index ff73c73..cb97877 100644
--- a/stockton-levels/src/traits/faces.rs
+++ b/stockton-levels/src/traits/faces.rs
@@ -15,9 +15,10 @@
// You should have received a copy of the GNU General Public License
// along with stockton-bsp. If not, see <http://www.gnu.org/licenses/>.
+use std::ops::Range;
use na::{Vector2, Vector3};
-use std::ops::Range;
+use super::{HasEffects, HasTextures, HasLightMaps, HasMeshVerts};
#[derive(Debug, Clone, Copy, PartialEq)]
#[repr(i32)]
@@ -31,24 +32,25 @@ pub enum FaceType {
#[derive(Debug, Clone, PartialEq)]
pub struct Face {
pub face_type: FaceType,
- pub texture_idx: usize,
- pub effect_idx: Option<usize>,
- pub lightmap_idx: Option<usize>,
- pub vertices_idx: Range<usize>,
- pub meshverts_idx: Range<usize>,
+ pub texture_idx: u32,
+ pub effect_idx: Option<u32>,
+ pub lightmap_idx: Option<u32>,
+ pub vertices_idx: Range<u32>,
+ pub meshverts_idx: Range<u32>,
- pub map_start: Vector2<i32>,
- pub map_size: Vector2<i32>,
+ pub map_start: Vector2<u32>,
+ pub map_size: Vector2<u32>,
pub map_origin: Vector3<f32>,
pub map_vecs: [Vector3<f32>; 2],
pub normal: Vector3<f32>,
- pub size: Vector2<i32>,
+ pub size: Vector2<u32>,
}
-pub trait HasFaces<'a> {
- type FacesIter: Iterator<Item = &'a Face>;
+pub trait HasFaces: HasTextures + HasEffects + HasLightMaps + HasMeshVerts {
+ type FacesIter<'a>: Iterator<Item = &'a Face>;
- fn faces_iter(&'a self) -> Self::FacesIter;
- fn get_face(&'a self, index: u32) -> &'a Face;
+ fn faces_iter<'a>(&'a self) -> Self::FacesIter<'a>;
+ fn faces_len(&self) -> u32;
+ fn get_face<'a>(&'a self, index: u32) -> &'a Face;
}
diff --git a/stockton-levels/src/traits/light_maps.rs b/stockton-levels/src/traits/light_maps.rs
index 406746d..9b30d91 100644
--- a/stockton-levels/src/traits/light_maps.rs
+++ b/stockton-levels/src/traits/light_maps.rs
@@ -54,9 +54,9 @@ impl fmt::Debug for LightMap {
}
}
-pub trait HasLightMaps<'a> {
- type LightMapsIter: Iterator<Item = &'a LightMap>;
+pub trait HasLightMaps {
+ type LightMapsIter<'a>: Iterator<Item = &'a LightMap>;
- fn lightmaps_iter(&'a self) -> Self::LightMapsIter;
- fn get_lightmap(&'a self, index: u32) -> &'a LightMap;
+ fn lightmaps_iter<'a>(&'a self) -> Self::LightMapsIter<'a>;
+ fn get_lightmap<'a>(&'a self, index: u32) -> &'a LightMap;
} \ No newline at end of file
diff --git a/stockton-levels/src/traits/light_vols.rs b/stockton-levels/src/traits/light_vols.rs
index 027709a..8e75401 100644
--- a/stockton-levels/src/traits/light_vols.rs
+++ b/stockton-levels/src/traits/light_vols.rs
@@ -15,8 +15,6 @@
// You should have received a copy of the GNU General Public License
// along with stockton-bsp. If not, see <http://www.gnu.org/licenses/>.
-use std::convert::TryInto;
-
use crate::types::RGB;
#[derive(Debug, Clone, Copy)]
@@ -26,9 +24,9 @@ pub struct LightVol {
pub dir: [u8; 2],
}
-pub trait HasLightVols<'a> {
- type LightVolsIter: Iterator<Item = &'a LightVol>;
+pub trait HasLightVols {
+ type LightVolsIter<'a>: Iterator<Item = &'a LightVol>;
- fn lightvols_iter(&'a self) -> Self::LightVolsIter;
- fn get_lightvol(&'a self, index: u32) -> &'a LightVol;
+ fn lightvols_iter<'a>(&'a self) -> Self::LightVolsIter<'a>;
+ fn get_lightvol<'a>(&'a self, index: u32) -> &'a LightVol;
}
diff --git a/stockton-levels/src/traits/models.rs b/stockton-levels/src/traits/models.rs
index ede7f78..7d1b896 100644
--- a/stockton-levels/src/traits/models.rs
+++ b/stockton-levels/src/traits/models.rs
@@ -18,6 +18,8 @@
use na::Vector3;
use std::ops::Range;
+use super::{HasFaces, HasBrushes};
+
#[derive(Debug, Clone)]
pub struct Model {
pub mins: Vector3<f32>,
@@ -26,9 +28,9 @@ pub struct Model {
pub brushes_idx: Range<u32>,
}
-pub trait HasModels<'a> {
- type ModelsIter: Iterator<Item = &'a Model>;
+pub trait HasModels: HasFaces + HasBrushes {
+ type ModelsIter<'a>: Iterator<Item = &'a Model>;
- fn models_iter(&'a self) -> Self::ModelsIter;
- fn get_model(&'a self, index: u32) -> &'a Model;
+ fn models_iter<'a>(&'a self) -> Self::ModelsIter<'a>;
+ fn get_model<'a>(&'a self, index: u32) -> &'a Model;
}
diff --git a/stockton-levels/src/traits/planes.rs b/stockton-levels/src/traits/planes.rs
index 6962c71..6a4e95a 100644
--- a/stockton-levels/src/traits/planes.rs
+++ b/stockton-levels/src/traits/planes.rs
@@ -35,8 +35,9 @@ pub struct Plane {
pub dist: f32,
}
-pub trait HasPlanes<'a> {
- type PlanesIter: Iterator<Item = &'a Plane>;
+pub trait HasPlanes {
+ type PlanesIter<'a>: Iterator<Item = &'a Plane>;
- fn planes_iter(&'a self) -> Self::PlanesIter;
+ fn planes_iter<'a>(&'a self) -> Self::PlanesIter<'a>;
+ fn get_plane<'a>(&'a self, idx: u32) -> &'a Plane;
} \ No newline at end of file
diff --git a/stockton-levels/src/traits/textures.rs b/stockton-levels/src/traits/textures.rs
index d1a2a83..ffd2a2f 100644
--- a/stockton-levels/src/traits/textures.rs
+++ b/stockton-levels/src/traits/textures.rs
@@ -142,8 +142,8 @@ bitflags!(
}
);
-pub trait HasTextures<'a> {
- type TexturesIter: Iterator<Item = &'a Texture>;
+pub trait HasTextures {
+ type TexturesIter<'a>: Iterator<Item = &'a Texture>;
- fn textures_iter(&'a self) -> Self::TexturesIter;
+ fn textures_iter<'a>(&'a self) -> Self::TexturesIter<'a>;
}
diff --git a/stockton-levels/src/traits/tree.rs b/stockton-levels/src/traits/tree.rs
index 06cfd80..bdbe705 100644
--- a/stockton-levels/src/traits/tree.rs
+++ b/stockton-levels/src/traits/tree.rs
@@ -18,6 +18,7 @@
//! Parses the BSP tree into a usable format
use na::Vector3;
+use super::{HasFaces, HasBrushes, HasVisData};
/// A node in a BSP tree.
/// Either has two children *or* a leaf entry.
@@ -45,6 +46,6 @@ pub struct BSPLeaf {
pub brushes_idx: Box<[u32]>,
}
-pub trait HasBSPTree<'a> {
- fn get_bsp_root(&'a self) -> &'a BSPNode;
+pub trait HasBSPTree: HasFaces + HasBrushes + HasVisData {
+ fn get_bsp_root<'a>(&'a self) -> &'a BSPNode;
} \ No newline at end of file
diff --git a/stockton-levels/src/traits/vertices.rs b/stockton-levels/src/traits/vertices.rs
index cb06b3a..2afa802 100644
--- a/stockton-levels/src/traits/vertices.rs
+++ b/stockton-levels/src/traits/vertices.rs
@@ -18,7 +18,6 @@
use crate::helpers::{slice_to_f32};
use crate::types::RGBA;
use na::Vector3;
-use std::convert::TryInto;
/// A vertex, used to describe a face.
@@ -49,22 +48,22 @@ impl TexCoord {
}
/// A vertex offset, used to describe generalised triangle meshes
-pub type MeshVert = i32;
+pub type MeshVert = u32;
-pub trait HasVertices<'a> {
- type VerticesIter: Iterator<Item = &'a Vertex>;
+pub trait HasVertices {
+ type VerticesIter<'a>: Iterator<Item = &'a Vertex>;
- fn vertices_iter(&'a self) -> Self::VerticesIter;
- fn get_vertex(&'a self, index: u32) -> &'a Vertex;
+ fn vertices_iter<'a>(&'a self) -> Self::VerticesIter<'a>;
+ fn get_vertex<'a>(&'a self, index: u32) -> &'a Vertex;
}
-pub trait HasMeshVerts<'a>: HasVertices<'a> {
- type MeshVertsIter: Iterator<Item = &'a MeshVert>;
+pub trait HasMeshVerts: HasVertices {
+ type MeshVertsIter<'a>: Iterator<Item = &'a MeshVert>;
- fn meshverts_iter(&'a self) -> Self::MeshVertsIter;
+ fn meshverts_iter<'a>(&'a self) -> Self::MeshVertsIter<'a>;
fn get_meshvert(&self, index: u32) -> MeshVert;
- fn resolve_meshvert(&'a self, index: u32) -> &'a Vertex {
- self.get_vertex(self.get_meshvert(index).try_into().unwrap())
+ fn resolve_meshvert<'a>(&'a self, index: u32, base: u32) -> &'a Vertex {
+ self.get_vertex(self.get_meshvert(index) + base)
}
} \ No newline at end of file
diff --git a/stockton-levels/src/traits/visdata.rs b/stockton-levels/src/traits/visdata.rs
index 27849d3..92ba9b8 100644
--- a/stockton-levels/src/traits/visdata.rs
+++ b/stockton-levels/src/traits/visdata.rs
@@ -22,7 +22,7 @@ pub trait HasVisData {
type VisibleIterator: Iterator<Item = ClusterId>;
/// Returns an iterator of all clusters visible from the given Cluster ID
- fn all_visible_from<'a>(&'a self, from: ClusterId) -> Self::VisibleIterator;
+ fn all_visible_from(&self, from: ClusterId) -> Self::VisibleIterator;
/// Returns true if `dest` is visible from `from`.
fn cluster_visible_from(&self, from: ClusterId, dest: ClusterId) -> bool;
diff --git a/stockton-render/Cargo.toml b/stockton-render/Cargo.toml
index 4d2cd47..852d174 100644
--- a/stockton-render/Cargo.toml
+++ b/stockton-render/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.1.0"
authors = ["Oscar <oscar.shrimpton.personal@gmail.com>"]
[dependencies]
-stockton-bsp = { git = "https://github.com/tcmal/rust-bsp.git" }
+stockton-levels = { path = "../stockton-levels" }
stockton-types = { path = "../stockton-types" }
winit = "^0.21"
gfx-hal = "^0.5"
diff --git a/stockton-render/src/culling.rs b/stockton-render/src/culling.rs
index a9b8753..2fa33b6 100644
--- a/stockton-render/src/culling.rs
+++ b/stockton-render/src/culling.rs
@@ -14,34 +14,45 @@
// with this program. If not, see <http://www.gnu.org/licenses/>.
//! Functions for figuring out what to render
+#![allow(dead_code)]
-use stockton_bsp::BSPFile;
+use stockton_levels::prelude::*;
+use stockton_levels::traits::tree::BSPNodeValue;
use stockton_types::Vector3;
+
/// Get the visible faces according to visdata and frustum culling
// TODO: Write this. For now, just render all faces
-pub fn get_visible_faces<'a>(pos: Vector3, file: &BSPFile) -> Vec<usize> {
- let mut visible = Vec::with_capacity(file.faces.faces.len());
- for x in 0..file.faces.faces.len() {
- visible.push(x);
+pub fn get_visible_faces<T: MinBSPFeatures>(_pos: Vector3, file: &T) -> Vec<u32> {
+ let mut visible = Vec::with_capacity(file.faces_len() as usize);
+ for x in 0..file.faces_len() {
+ visible.push(x as u32);
}
return visible;
}
/// Get the viscluster pos lies in
-fn get_cluster_id(pos: Vector3, file: &BSPFile) -> usize {
- let mut node = &file.tree.root;
- while node.leaf.is_none() {
- let plane = file.planes.planes[node.plane_idx as usize];
- let dist = plane.normal.dot(&pos) - plane.dist;
-
- if dist >= 0.0 {
- node = &node.children.as_ref().unwrap()[0]
+fn get_cluster_id<T: MinBSPFeatures>(pos: Vector3, file: &T) -> u32 {
+ let mut node = file.get_bsp_root();
+ loop {
+ if let BSPNodeValue::Children(front, back) = &node.value{
+ let plane = file.get_plane(node.plane_idx);
+ let dist = plane.normal.dot(&pos) - plane.dist;
+
+ if dist >= 0.0 {
+ node = front;
+ } else {
+ node = back;
+ }
} else {
- node = &node.children.as_ref().unwrap()[1]
+ break;
}
}
- node.leaf.as_ref().unwrap().cluster_id as usize
+ if let BSPNodeValue::Leaf(leaf) = &node.value {
+ leaf.cluster_id
+ } else {
+ panic!("should have had a leaf but didn't");
+ }
} \ No newline at end of file
diff --git a/stockton-render/src/draw/context.rs b/stockton-render/src/draw/context.rs
index 12f24ad..533cf08 100644
--- a/stockton-render/src/draw/context.rs
+++ b/stockton-render/src/draw/context.rs
@@ -33,10 +33,8 @@ use hal::{
window::SwapchainConfig
};
use stockton_types::{Vector2, Vector3};
-use stockton_bsp::{
- BSPFile,
- lumps::faces::FaceType
-};
+use stockton_levels::prelude::*;
+use stockton_levels::traits::faces::FaceType;
use crate::{
types::*,
@@ -853,19 +851,19 @@ impl<'a> RenderingContext<'a> {
/// Load all active faces into the vertex buffers for drawing
// TODO: This is just a POC, we need to restructure things a lot for actually texturing, etc
- pub fn set_active_faces(&mut self, faces: Vec<usize>, file: &BSPFile) {
+ pub fn set_active_faces<M: MinBSPFeatures>(&mut self, faces: Vec<u32>, file: &M) -> () {
let mut curr_vert_idx: usize = 0;
let mut curr_idx_idx: usize = 0;
- for face in faces.into_iter().map(|idx| &file.faces.faces[idx]) {
+ for face in faces.into_iter().map(|idx| file.get_face(idx)) {
if face.face_type == FaceType::Polygon || face.face_type == FaceType::Mesh {
- let base = face.vertices_idx.start as i32;
+ let base = face.vertices_idx.start;
for idx in face.meshverts_idx.clone().step_by(3) {
let start_idx: u16 = curr_vert_idx.try_into().unwrap();
- for mv in &file.meshverts.meshverts[idx..idx+3] {
- let vert = &file.vertices.vertices[(base + mv.offset) as usize];
+ for idx2 in idx..idx+3 {
+ let vert = &file.resolve_meshvert(idx2 as u32, base);
let uv = Vector2::new(vert.tex.u[0], vert.tex.v[0]);
let uvp = UVPoint (vert.position, uv, 0);
diff --git a/stockton-render/src/lib.rs b/stockton-render/src/lib.rs
index 3f157a1..1abc408 100644
--- a/stockton-render/src/lib.rs
+++ b/stockton-render/src/lib.rs
@@ -26,7 +26,7 @@ extern crate image;
extern crate log;
extern crate stockton_types;
-extern crate stockton_bsp;
+extern crate stockton_levels;
extern crate arrayvec;
@@ -36,22 +36,23 @@ mod types;
mod culling;
use stockton_types::World;
+use stockton_levels::prelude::*;
use error::{CreationError, FrameError};
use draw::RenderingContext;
use culling::get_visible_faces;
/// Renders a world to a window when you tell it to.
-pub struct Renderer<'a> {
- world: World,
+pub struct Renderer<'a, T: MinBSPFeatures> {
+ world: World<T>,
pub context: RenderingContext<'a>
}
-impl<'a> Renderer<'a> {
+impl<'a, T: MinBSPFeatures> Renderer<'a, T> {
/// Create a new Renderer.
/// This initialises all the vulkan context, etc needed.
- pub fn new(world: World, window: &winit::window::Window) -> Result<Self, CreationError> {
+ pub fn new(world: World<T>, window: &winit::window::Window) -> Result<Self, CreationError> {
let context = RenderingContext::new(window)?;
Ok(Renderer {
diff --git a/stockton-types/src/lib.rs b/stockton-types/src/lib.rs
index 5a409d8..bf690f1 100644
--- a/stockton-types/src/lib.rs
+++ b/stockton-types/src/lib.rs
@@ -14,7 +14,7 @@
// with this program. If not, see <http://www.gnu.org/licenses/>.
//! Common types for all stockton crates.
-extern crate stockton_bsp;
+extern crate stockton_levels;
extern crate nalgebra_glm as na;
pub mod world;
diff --git a/stockton-types/src/world.rs b/stockton-types/src/world.rs
index 2c677b7..8294523 100644
--- a/stockton-types/src/world.rs
+++ b/stockton-types/src/world.rs
@@ -15,18 +15,19 @@
//! The thing you play on and all the associated state.
-use stockton_bsp::BSPFile;
+use stockton_levels::prelude::*;
/// A loaded world.
-pub struct World {
- pub map: BSPFile
+pub struct World<T: MinBSPFeatures> {
+ pub map: T,
}
-impl World {
- /// Create a new world from a BSPFile.
- pub fn new(bsp: BSPFile) -> Option<World> {
- Some(World {
- map: bsp
- })
+impl<T: MinBSPFeatures> World<T> {
+ /// Create a new world from a level.
+ /// The level can be any format, as long as it has the required features of a bsp.
+ pub fn new(map: T) -> World<T> {
+ World {
+ map
+ }
}
} \ No newline at end of file