Base objects

This commit is contained in:
hodasemi 2023-05-09 16:39:53 +02:00
parent a762f37194
commit 139f7d92cc
4 changed files with 795 additions and 102 deletions

View file

@ -2,16 +2,114 @@ use std::sync::Arc;
use anyhow::Result; use anyhow::Result;
use engine::prelude::{ use engine::prelude::{
cgmath::{vec3, Vector3}, cgmath::{vec2, vec3, Vector2, Vector3},
*, *,
}; };
use crate::{game::MillGame, objects::Objects};
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct BoardSlot {
pub state: BoardSlotState,
pub position: Vector2<f32>,
pub slot_marker: Option<Entity>,
}
impl BoardSlot {
pub const SLOT_MARKER_SIZE: f32 = 1.5;
pub fn new(position: Vector2<f32>, scene: &mut Scene) -> Result<Self> {
let mut marker = scene.engine().assets().empty_entity();
let meshes = vec![Self::create_mesh(&scene.engine(), Color::Black)?];
let draw = Draw::new(meshes);
marker.insert_component(draw);
let mut location = Location::from_entity(&mut marker);
location.set_position(position.extend(MillGame::OFFSET_TO_BOARD));
marker.insert_component(location);
Ok(Self {
state: BoardSlotState::default(),
position,
slot_marker: Some(scene.add_entity(marker)?),
})
}
pub fn invalid() -> Self {
Self {
state: BoardSlotState::Invalid,
position: vec2(0.0, 0.0),
slot_marker: None,
}
}
fn create_mesh(engine: &Arc<Engine>, color: Color) -> Result<AssetMesh> {
let mut mesh = AssetMesh::new(
engine.device(),
engine.settings().graphics_info()?.render_type,
)?;
let vertex_buffer = Buffer::builder()
.set_data(&Objects::create_flat_quad([
vec2(-Self::SLOT_MARKER_SIZE * 0.5, -Self::SLOT_MARKER_SIZE * 0.5),
vec2(Self::SLOT_MARKER_SIZE * 0.5, -Self::SLOT_MARKER_SIZE * 0.5),
vec2(Self::SLOT_MARKER_SIZE * 0.5, Self::SLOT_MARKER_SIZE * 0.5),
vec2(-Self::SLOT_MARKER_SIZE * 0.5, Self::SLOT_MARKER_SIZE * 0.5),
]))
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
.set_memory_usage(MemoryUsage::CpuOnly)
.build(engine.device().clone())?;
let a: [f32; 3] = color.into();
mesh.add_primitive(
vertex_buffer,
None,
None,
PrimitiveMaterial {
color: [a[0], a[1], a[2], 1.0],
metallic_factor: 0.2,
emissive_factor: [0.2, 0.2, 0.2],
roughness_factor: 0.8,
alpha_mode: AlphaMode::Opaque,
alpha_cut_off: 0.5,
},
true,
)?;
Ok(mesh)
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum BoardSlotState {
Invalid,
Empty,
Black(Entity),
White(Entity),
}
impl Default for BoardSlotState {
fn default() -> Self {
Self::Empty
}
}
pub struct Board { pub struct Board {
board: Entity, board: Entity,
center: Vector3<f32>,
connection_lines: Vec<Entity>,
slots: [[[BoardSlot; 3]; 3]; 3],
white_start_slots: [Vector2<f32>; 9],
black_start_slots: [Vector2<f32>; 9],
} }
impl Board { impl Board {
pub fn new(engine: Arc<Engine>, scene: &mut SceneHandle) -> Result<Arc<Self>> { pub fn new(engine: &Arc<Engine>, scene: &mut SceneHandle) -> Result<Arc<Self>> {
let mut board_entity = engine.assets().empty_entity(); let mut board_entity = engine.assets().empty_entity();
let meshes = vec![Self::create_board_base(&engine)?]; let meshes = vec![Self::create_board_base(&engine)?];
@ -23,17 +121,138 @@ impl Board {
board_entity.insert_component(location); board_entity.insert_component(location);
let mut board = None; let mut board = None;
let mut slots = None;
scene.on_scene(|scene| { scene.on_scene(|scene| {
board = Some(scene.add_entity(board_entity)?); board = Some(scene.add_entity(board_entity)?);
slots = Some([
[
[
BoardSlot::new(vec2(-15.0, -15.0), scene)?, // 0 0 0
BoardSlot::new(vec2(-10.0, -10.0), scene)?, // 0 0 1
BoardSlot::new(vec2(-5.0, -5.0), scene)?, // 0 0 2
],
[
BoardSlot::new(vec2(-15.0, 0.0), scene)?, // 0 1 0
BoardSlot::new(vec2(-10.0, 0.0), scene)?, // 0 1 1
BoardSlot::new(vec2(-5.0, 0.0), scene)?, // 0 1 2
],
[
BoardSlot::new(vec2(-15.0, 15.0), scene)?, // 0 2 0
BoardSlot::new(vec2(-10.0, 10.0), scene)?, // 0 2 1
BoardSlot::new(vec2(-5.0, 5.0), scene)?, // 0 2 2
],
],
[
[
BoardSlot::new(vec2(0.0, -15.0), scene)?, // 1 0 0
BoardSlot::new(vec2(0.0, -10.0), scene)?, // 1 0 1
BoardSlot::new(vec2(0.0, -5.0), scene)?, // 1 0 2
],
[
BoardSlot::invalid(), // 1 1 0
BoardSlot::invalid(), // 1 1 1
BoardSlot::invalid(), // 1 1 2
],
[
BoardSlot::new(vec2(0.0, 15.0), scene)?, // 1 2 0
BoardSlot::new(vec2(0.0, 10.0), scene)?, // 1 2 1
BoardSlot::new(vec2(0.0, 5.0), scene)?, // 1 2 2
],
],
[
[
BoardSlot::new(vec2(15.0, -15.0), scene)?, // 2 0 0
BoardSlot::new(vec2(10.0, -10.0), scene)?, // 2 0 1
BoardSlot::new(vec2(5.0, -5.0), scene)?, // 2 0 2
],
[
BoardSlot::new(vec2(15.0, 0.0), scene)?, // 2 1 0
BoardSlot::new(vec2(10.0, 0.0), scene)?, // 2 1 1
BoardSlot::new(vec2(5.0, 0.0), scene)?, // 2 1 2
],
[
BoardSlot::new(vec2(15.0, 15.0), scene)?, // 2 2 0
BoardSlot::new(vec2(10.0, 10.0), scene)?, // 2 2 1
BoardSlot::new(vec2(5.0, 5.0), scene)?, // 2 2 2
],
],
]);
Ok(()) Ok(())
})?; })?;
let distance = 20.0;
let white_start_slots = [
vec2(-16.0, distance),
vec2(-12.0, distance),
vec2(-8.0, distance),
vec2(-4.0, distance),
vec2(0.0, distance),
vec2(4.0, distance),
vec2(8.0, distance),
vec2(12.0, distance),
vec2(16.0, distance),
];
let black_start_slots = [
vec2(-16.0, -distance),
vec2(-12.0, -distance),
vec2(-8.0, -distance),
vec2(-4.0, -distance),
vec2(0.0, -distance),
vec2(4.0, -distance),
vec2(8.0, -distance),
vec2(12.0, -distance),
vec2(16.0, -distance),
];
Ok(Arc::new(Self { Ok(Arc::new(Self {
board: board.unwrap(), board: board.unwrap(),
center: vec3(0.0, 0.0, 0.0),
connection_lines: Self::create_connection_lines(scene, Color::Black)?,
slots: slots.unwrap(),
white_start_slots,
black_start_slots,
})) }))
} }
pub fn center(&self) -> Vector3<f32> {
self.center
}
pub fn white_start_slots(&self) -> &[Vector2<f32>; 9] {
&self.white_start_slots
}
pub fn black_start_slots(&self) -> &[Vector2<f32>; 9] {
&self.black_start_slots
}
pub fn close_to_marker(&self, position: Vector2<f32>) -> bool {
const DISTANCE: f32 = 1.25;
for outer in self.slots.iter() {
for inner in outer.iter() {
for slot in inner.iter() {
if slot.state != BoardSlotState::Invalid {
if (slot.position - position).magnitude() <= DISTANCE {
return true;
}
}
}
}
}
false
}
}
impl Board {
fn create_board_base(engine: &Arc<Engine>) -> Result<AssetMesh> { fn create_board_base(engine: &Arc<Engine>) -> Result<AssetMesh> {
let mut board_base = AssetMesh::new( let mut board_base = AssetMesh::new(
engine.device(), engine.device(),
@ -41,9 +260,9 @@ impl Board {
)?; )?;
let vertex_buffer = Buffer::builder() let vertex_buffer = Buffer::builder()
.set_data(&Self::create_cuboid( .set_data(&Objects::create_cuboid(
vec3(-17.5, -20.0, -2.0), vec3(-22.5, -25.0, -2.0),
vec3(35.0, 40.0, 2.0), vec3(45.0, 50.0, 2.0),
)) ))
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) .set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
.set_memory_usage(MemoryUsage::CpuOnly) .set_memory_usage(MemoryUsage::CpuOnly)
@ -59,7 +278,7 @@ impl Board {
PrimitiveMaterial { PrimitiveMaterial {
color: [a[0], a[1], a[2], 1.0], color: [a[0], a[1], a[2], 1.0],
metallic_factor: 0.2, metallic_factor: 0.2,
emissive_factor: [0.2, 0.2, 0.2], emissive_factor: [0.5, 0.5, 0.5],
roughness_factor: 0.8, roughness_factor: 0.8,
alpha_mode: AlphaMode::Opaque, alpha_mode: AlphaMode::Opaque,
alpha_cut_off: 0.5, alpha_cut_off: 0.5,
@ -70,90 +289,155 @@ impl Board {
Ok(board_base) Ok(board_base)
} }
fn create_cuboid(offset: Vector3<f32>, extent: Vector3<f32>) -> Vec<PositionNormal> { fn create_connection_lines(scene: &mut SceneHandle, color: Color) -> Result<Vec<Entity>> {
vec![ let mut entities = Vec::new();
// near
PositionNormal::new( scene.on_scene(|scene| {
vec3(offset.x, offset.y + extent.y, offset.z + extent.z), let mut lines = scene.engine().assets().empty_entity();
vec3(0.0, -1.0, 0.0),
), let draw = Draw::new(vec![{
PositionNormal::new( let mut mesh = AssetMesh::new(
vec3( scene.engine().device(),
offset.x + extent.x, scene.engine().settings().graphics_info()?.render_type,
offset.y + extent.y, )?;
offset.z + extent.z,
), let vertex_buffer = Buffer::builder()
vec3(0.0, -1.0, 0.0), .set_data(
), &[
PositionNormal::new( Objects::create_flat_quad([
vec3(offset.x, offset.y + extent.y, offset.z), vec2(-15.25, -15.25),
vec3(0.0, -1.0, 0.0), vec2(15.25, -15.25),
), vec2(15.25, -14.75),
PositionNormal::new( vec2(-15.25, -14.75),
vec3(offset.x, offset.y + extent.y, offset.z), ]),
vec3(0.0, -1.0, 0.0), Objects::create_flat_quad([
), vec2(-10.25, -10.25),
PositionNormal::new( vec2(10.25, -10.25),
vec3(offset.x, offset.y + extent.y, offset.z), vec2(10.25, -9.75),
vec3(0.0, -1.0, 0.0), vec2(-10.25, -9.75),
), ]),
PositionNormal::new( Objects::create_flat_quad([
vec3(offset.x, offset.y + extent.y, offset.z + extent.z), vec2(-5.25, -5.25),
vec3(0.0, -1.0, 0.0), vec2(5.25, -5.25),
), vec2(5.25, -4.75),
// right vec2(-5.25, -4.75),
PositionNormal::new( ]),
vec3( Objects::create_flat_quad([
offset.x + extent.x, vec2(-15.25, 14.75),
offset.y + extent.y, vec2(15.25, 14.75),
offset.z + extent.z, vec2(15.25, 15.25),
), vec2(-15.25, 15.25),
vec3(1.0, 0.0, 0.0), ]),
), Objects::create_flat_quad([
PositionNormal::new( vec2(-10.25, 9.75),
vec3(offset.x + extent.x, offset.y, offset.z + extent.z), vec2(10.25, 9.75),
vec3(1.0, 0.0, 0.0), vec2(10.25, 10.25),
), vec2(-10.25, 10.25),
PositionNormal::new( ]),
vec3(offset.x + extent.x, offset.y, offset.z), Objects::create_flat_quad([
vec3(1.0, 0.0, 0.0), vec2(-5.25, 4.75),
), vec2(5.25, 4.75),
PositionNormal::new( vec2(5.25, 5.25),
vec3(offset.x + extent.x, offset.y, offset.z), vec2(-5.25, 5.25),
vec3(1.0, 0.0, 0.0), ]),
), Objects::create_flat_quad([
PositionNormal::new( vec2(-14.75, -15.25),
vec3(offset.x + extent.x, offset.y + extent.y, offset.z), vec2(-14.75, 15.25),
vec3(1.0, 0.0, 0.0), vec2(-15.25, 15.25),
), vec2(-15.25, -15.25),
PositionNormal::new( ]),
vec3( Objects::create_flat_quad([
offset.x + extent.x, vec2(-9.75, -10.25),
offset.y + extent.y, vec2(-9.75, 10.25),
offset.z + extent.z, vec2(-10.25, 10.25),
), vec2(-10.25, -10.25),
vec3(1.0, 0.0, 0.0), ]),
), Objects::create_flat_quad([
// far vec2(-4.75, -5.25),
PositionNormal::new( vec2(-4.75, 5.25),
vec3(offset.x + extent.x, offset.y, offset.z + extent.z), vec2(-5.25, 5.25),
vec3(0.0, 1.0, 0.0), vec2(-5.25, -5.25),
), ]),
PositionNormal::new( Objects::create_flat_quad([
vec3(offset.x, offset.y, offset.z + extent.z), vec2(15.25, -15.25),
vec3(0.0, 1.0, 0.0), vec2(15.25, 15.25),
), vec2(14.75, 15.25),
PositionNormal::new(vec3(offset.x, offset.y, offset.z), vec3(0.0, 1.0, 0.0)), vec2(14.75, -15.25),
PositionNormal::new(vec3(offset.x, offset.y, offset.z), vec3(0.0, 1.0, 0.0)), ]),
PositionNormal::new( Objects::create_flat_quad([
vec3(offset.x + extent.x, offset.y, offset.z), vec2(10.25, -10.25),
vec3(0.0, 1.0, 0.0), vec2(10.25, 10.25),
), vec2(9.75, 10.25),
PositionNormal::new( vec2(9.75, -10.25),
vec3(offset.x + extent.x, offset.y, offset.z + extent.z), ]),
vec3(0.0, 1.0, 0.0), Objects::create_flat_quad([
), vec2(5.25, -5.25),
vec2(5.25, 5.25),
vec2(4.75, 5.25),
vec2(4.75, -5.25),
]),
Objects::create_flat_quad([
vec2(0.25, -15.25),
vec2(0.25, -4.75),
vec2(-0.25, -4.75),
vec2(-0.25, -15.25),
]),
Objects::create_flat_quad([
vec2(-0.25, 15.25),
vec2(-0.25, 4.75),
vec2(0.25, 4.75),
vec2(0.25, 15.25),
]),
Objects::create_flat_quad([
vec2(-15.25, -0.25),
vec2(-4.75, -0.25),
vec2(-4.75, 0.25),
vec2(-15.25, 0.25),
]),
Objects::create_flat_quad([
vec2(15.25, 0.25),
vec2(4.75, 0.25),
vec2(4.75, -0.25),
vec2(15.25, -0.25),
]),
] ]
.concat(),
)
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
.set_memory_usage(MemoryUsage::CpuOnly)
.build(scene.engine().device().clone())?;
let a: [f32; 3] = color.into();
mesh.add_primitive(
vertex_buffer,
None,
None,
PrimitiveMaterial {
color: [a[0], a[1], a[2], 1.0],
metallic_factor: 0.2,
emissive_factor: [0.2, 0.2, 0.2],
roughness_factor: 0.8,
alpha_mode: AlphaMode::Opaque,
alpha_cut_off: 0.5,
},
true,
)?;
mesh
}]);
lines.insert_component(draw);
let mut location = Location::from_entity(&mut lines);
location.set_offset(vec3(0.0, 0.0, MillGame::OFFSET_TO_BOARD));
lines.insert_component(location);
entities.push(scene.add_entity(lines)?);
Ok(())
})?;
Ok(entities)
} }
} }
@ -183,7 +467,7 @@ impl Map for Board {
Ok(vec![]) Ok(vec![])
} }
fn disable(&self, scene: &mut Scene) -> Result<()> { fn disable(&self, _scene: &mut Scene) -> Result<()> {
todo!() unreachable!()
} }
} }

View file

@ -1,26 +1,155 @@
use std::sync::Arc; use std::sync::{
atomic::{AtomicU32, Ordering::SeqCst},
Arc, Mutex,
};
use anyhow::Result; use anyhow::Result;
use engine::prelude::*; use engine::prelude::{cgmath::vec3, *};
use crate::board::Board; use crate::{board::Board, objects::Objects};
pub struct MillGame { pub struct MillGame {
board: Arc<Board>, board: Arc<Board>,
scene: SceneHandle, white_stones: [Entity; 9],
black_stones: [Entity; 9],
scene: Mutex<SceneHandle>,
camera_controls: Mutex<CameraControl>,
mouse_x: AtomicU32,
mouse_y: AtomicU32,
} }
impl MillGame { impl MillGame {
pub const OFFSET_TO_BOARD: f32 = 0.01;
pub fn new(engine: Arc<Engine>) -> Result<Arc<Self>> { pub fn new(engine: Arc<Engine>) -> Result<Arc<Self>> {
let mut scene = SceneHandle::new(&engine)?; let mut scene = SceneHandle::new(&engine)?;
let board = Board::new(&engine, &mut scene)?;
let mut white_stones = None;
let mut black_stones = None;
scene.on_scene(|scene| {
let view = scene.view_mut();
view.camera_mut().set_center(board.center());
view.update_buffer()?;
// add light
let mut sun_light = engine.new_directional_light()?;
sun_light.set_direction(vec3(10.0, -4.0, -20.0))?;
sun_light.set_color(vec3(1.0, 1.0, 1.0))?;
sun_light.set_position(vec3(0.0, 0.0, 100.0))?;
sun_light.set_power(10000000000.0)?;
scene.add_light(sun_light)?;
white_stones = Some(
Self::init_nine_stones(&engine, Color::White)?
.into_iter()
.enumerate()
.map(|(index, mut e)| {
let location = e.get_component_mut::<Location>()?;
location.set_position(board.white_start_slots()[index].extend(0.0));
scene.add_entity(e)
})
.collect::<Result<Vec<Entity>>>()?
.try_into()
.unwrap_or_else(|_: Vec<Entity>| {
unreachable!("create array from vec from an array")
}),
);
black_stones = Some(
Self::init_nine_stones(&engine, Color::Black)?
.into_iter()
.enumerate()
.map(|(index, mut e)| {
let location = e.get_component_mut::<Location>()?;
location.set_position(board.black_start_slots()[index].extend(0.0));
scene.add_entity(e)
})
.collect::<Result<Vec<Entity>>>()?
.try_into()
.unwrap_or_else(|_: Vec<Entity>| {
unreachable!("create array from vec from an array")
}),
);
Ok(())
})?;
let camera_control = CameraControl::new(&mut scene)?;
scene.activate()?; scene.activate()?;
Ok(Arc::new(Self { Ok(Arc::new(Self {
board: Board::new(engine, &mut scene)?, board,
scene, white_stones: white_stones.unwrap(),
black_stones: black_stones.unwrap(),
scene: Mutex::new(scene),
camera_controls: Mutex::new(camera_control),
mouse_x: AtomicU32::new(0),
mouse_y: AtomicU32::new(0),
})) }))
} }
fn init_nine_stones(engine: &Arc<Engine>, color: Color) -> Result<[EntityObject; 9]> {
Ok((0..9)
.map(|_| Self::init_stone(engine, color))
.collect::<Result<Vec<EntityObject>>>()?
.try_into()
.unwrap_or_else(|_: Vec<EntityObject>| {
unreachable!("create array from vec from an array")
}))
}
fn init_stone(engine: &Arc<Engine>, color: Color) -> Result<EntityObject> {
let mut marker = engine.assets().empty_entity();
let draw = Draw::new(vec![{
let mut mesh = AssetMesh::new(
engine.device(),
engine.settings().graphics_info()?.render_type,
)?;
let vertex_buffer = Buffer::builder()
.set_data(&Objects::create_cylinder(1.0, 0.25, 12))
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
.set_memory_usage(MemoryUsage::CpuOnly)
.build(engine.device().clone())?;
let a: [f32; 3] = color.into();
mesh.add_primitive(
vertex_buffer,
None,
None,
PrimitiveMaterial {
color: [a[0], a[1], a[2], 1.0],
metallic_factor: 0.2,
emissive_factor: [0.2, 0.2, 0.2],
roughness_factor: 0.8,
alpha_mode: AlphaMode::Opaque,
alpha_cut_off: 0.5,
},
true,
)?;
mesh
}]);
marker.insert_component(draw);
let location = Location::from_entity(&mut marker);
marker.insert_component(location);
Ok(marker)
}
} }
impl EngineObject for MillGame { impl EngineObject for MillGame {
@ -34,10 +163,51 @@ impl EngineObject for MillGame {
fn event(&self, event: EngineEvent) -> Result<()> { fn event(&self, event: EngineEvent) -> Result<()> {
match event { match event {
EngineEvent::MouseMotion(_, _) => (), EngineEvent::MouseMotion(x, y) => {
EngineEvent::MouseButtonDown(_) => (), self.mouse_x.store(x, SeqCst);
EngineEvent::MouseButtonUp(_) => (), self.mouse_y.store(y, SeqCst);
EngineEvent::MouseWheel(_, _, _) => (),
self.camera_controls.lock().unwrap().mouse_move(
x,
y,
&mut *self.scene.lock().unwrap(),
)?;
}
EngineEvent::MouseButtonDown(button) => match button {
MouseButton::Left => {
self.scene.lock().unwrap().on_scene(|scene| {
if let Some(world_space) = scene.screen_space_to_world(
self.mouse_x.load(SeqCst),
self.mouse_y.load(SeqCst),
)? {
if self.board.close_to_marker(world_space.truncate()) {
println!("close to marker");
} else {
println!("not close to a marker");
}
}
Ok(())
})?;
}
MouseButton::Middle => self.camera_controls.lock().unwrap().hold(),
MouseButton::Right => (),
MouseButton::Forward => (),
MouseButton::Backward => (),
},
EngineEvent::MouseButtonUp(button) => match button {
MouseButton::Left => (),
MouseButton::Middle => self.camera_controls.lock().unwrap().release(),
MouseButton::Right => (),
MouseButton::Forward => (),
MouseButton::Backward => (),
},
EngineEvent::MouseWheel(_x, y, direction) => self
.camera_controls
.lock()
.unwrap()
.scroll_wheel(y, direction, &mut *self.scene.lock().unwrap())?,
EngineEvent::KeyDown(_) => (), EngineEvent::KeyDown(_) => (),
EngineEvent::KeyUp(_) => (), EngineEvent::KeyUp(_) => (),
EngineEvent::ButtonDown(_) => (), EngineEvent::ButtonDown(_) => (),

View file

@ -1,5 +1,6 @@
mod board; mod board;
mod game; mod game;
mod objects;
use anyhow::Result; use anyhow::Result;
use assetpath::AssetPath; use assetpath::AssetPath;
@ -22,6 +23,9 @@ fn main() -> Result<()> {
create_info.window_info.height = 600; create_info.window_info.height = 600;
create_info.window_info.width = 800; create_info.window_info.width = 800;
create_info.enable_keyboard = true;
create_info.enable_mouse = true;
let engine = Engine::new(create_info)?; let engine = Engine::new(create_info)?;
engine.set_game_object(Some(MillGame::new(engine.clone())?))?; engine.set_game_object(Some(MillGame::new(engine.clone())?))?;

235
src/objects.rs Normal file
View file

@ -0,0 +1,235 @@
use cgmath::{vec3, Matrix3, Vector3};
use engine::prelude::{
cgmath::{Deg, Vector2},
*,
};
pub struct Objects;
impl Objects {
pub fn create_cuboid(offset: Vector3<f32>, extent: Vector3<f32>) -> [PositionNormal; 36] {
[
// near
PositionNormal::new(
vec3(offset.x, offset.y + extent.y, offset.z + extent.z),
vec3(0.0, -1.0, 0.0),
),
PositionNormal::new(
vec3(
offset.x + extent.x,
offset.y + extent.y,
offset.z + extent.z,
),
vec3(0.0, -1.0, 0.0),
),
PositionNormal::new(
vec3(offset.x, offset.y + extent.y, offset.z),
vec3(0.0, -1.0, 0.0),
),
PositionNormal::new(
vec3(offset.x, offset.y + extent.y, offset.z),
vec3(0.0, -1.0, 0.0),
),
PositionNormal::new(
vec3(offset.x, offset.y + extent.y, offset.z),
vec3(0.0, -1.0, 0.0),
),
PositionNormal::new(
vec3(offset.x, offset.y + extent.y, offset.z + extent.z),
vec3(0.0, -1.0, 0.0),
),
// right
PositionNormal::new(
vec3(
offset.x + extent.x,
offset.y + extent.y,
offset.z + extent.z,
),
vec3(1.0, 0.0, 0.0),
),
PositionNormal::new(
vec3(offset.x + extent.x, offset.y, offset.z + extent.z),
vec3(1.0, 0.0, 0.0),
),
PositionNormal::new(
vec3(offset.x + extent.x, offset.y, offset.z),
vec3(1.0, 0.0, 0.0),
),
PositionNormal::new(
vec3(offset.x + extent.x, offset.y, offset.z),
vec3(1.0, 0.0, 0.0),
),
PositionNormal::new(
vec3(offset.x + extent.x, offset.y + extent.y, offset.z),
vec3(1.0, 0.0, 0.0),
),
PositionNormal::new(
vec3(
offset.x + extent.x,
offset.y + extent.y,
offset.z + extent.z,
),
vec3(1.0, 0.0, 0.0),
),
// far
PositionNormal::new(
vec3(offset.x + extent.x, offset.y, offset.z + extent.z),
vec3(0.0, 1.0, 0.0),
),
PositionNormal::new(
vec3(offset.x, offset.y, offset.z + extent.z),
vec3(0.0, 1.0, 0.0),
),
PositionNormal::new(vec3(offset.x, offset.y, offset.z), vec3(0.0, 1.0, 0.0)),
PositionNormal::new(vec3(offset.x, offset.y, offset.z), vec3(0.0, 1.0, 0.0)),
PositionNormal::new(
vec3(offset.x + extent.x, offset.y, offset.z),
vec3(0.0, 1.0, 0.0),
),
PositionNormal::new(
vec3(offset.x + extent.x, offset.y, offset.z + extent.z),
vec3(0.0, 1.0, 0.0),
),
// left
PositionNormal::new(
vec3(offset.x, offset.y, offset.z + extent.z),
vec3(-1.0, 0.0, 0.0),
),
PositionNormal::new(
vec3(offset.x, offset.y + extent.y, offset.z + extent.z),
vec3(-1.0, 0.0, 0.0),
),
PositionNormal::new(
vec3(offset.x, offset.y + extent.y, offset.z),
vec3(-1.0, 0.0, 0.0),
),
PositionNormal::new(
vec3(offset.x, offset.y + extent.y, offset.z),
vec3(-1.0, 0.0, 0.0),
),
PositionNormal::new(vec3(offset.x, offset.y, offset.z), vec3(-1.0, 0.0, 0.0)),
PositionNormal::new(
vec3(offset.x, offset.y, offset.z + extent.z),
vec3(-1.0, 0.0, 0.0),
),
// top
PositionNormal::new(
vec3(offset.x, offset.y, offset.z + extent.z),
vec3(0.0, 0.0, 1.0),
),
PositionNormal::new(
vec3(offset.x + extent.x, offset.y, offset.z + extent.z),
vec3(0.0, 0.0, 1.0),
),
PositionNormal::new(
vec3(
offset.x + extent.x,
offset.y + extent.y,
offset.z + extent.z,
),
vec3(0.0, 0.0, 1.0),
),
PositionNormal::new(
vec3(
offset.x + extent.x,
offset.y + extent.y,
offset.z + extent.z,
),
vec3(0.0, 0.0, 1.0),
),
PositionNormal::new(
vec3(offset.x, offset.y + extent.y, offset.z + extent.z),
vec3(0.0, 0.0, 1.0),
),
PositionNormal::new(
vec3(offset.x, offset.y, offset.z + extent.z),
vec3(0.0, 0.0, 1.0),
),
// bottom
PositionNormal::new(
vec3(offset.x + extent.x, offset.y + extent.y, offset.z),
vec3(0.0, 0.0, -1.0),
),
PositionNormal::new(
vec3(offset.x, offset.y + extent.y, offset.z),
vec3(0.0, 0.0, -1.0),
),
PositionNormal::new(vec3(offset.x, offset.y, offset.z), vec3(0.0, 0.0, -1.0)),
PositionNormal::new(vec3(offset.x, offset.y, offset.z), vec3(0.0, 0.0, -1.0)),
PositionNormal::new(
vec3(offset.x + extent.x, offset.y, offset.z),
vec3(0.0, 0.0, -1.0),
),
PositionNormal::new(
vec3(offset.x + extent.x, offset.y + extent.y, offset.z),
vec3(0.0, 0.0, -1.0),
),
]
}
pub fn create_flat_quad(corners: [Vector2<f32>; 4]) -> [PositionNormal; 6] {
let up = vec3(0.0, 0.0, 1.0);
[
PositionNormal::new(corners[0].extend(0.0), up),
PositionNormal::new(corners[1].extend(0.0), up),
PositionNormal::new(corners[2].extend(0.0), up),
PositionNormal::new(corners[2].extend(0.0), up),
PositionNormal::new(corners[3].extend(0.0), up),
PositionNormal::new(corners[0].extend(0.0), up),
]
}
pub fn create_cylinder(radius: f32, height: f32, detail: u8) -> Vec<PositionNormal> {
let center = vec3(0.0, 0.0, 0.0);
let reference_point = vec3(radius, 0.0, 0.0);
let split_degree = Deg(360.0 / detail as f32);
let mut vertices = Vec::with_capacity(detail as usize * 12);
for i in 0..detail {
let first_outer = Matrix3::from_angle_z(split_degree * i as f32) * reference_point;
let second_outer =
Matrix3::from_angle_z(split_degree * (i + 1) as f32) * reference_point;
// bottom triangle
vertices.push(PositionNormal::new(center, vec3(0.0, 0.0, -1.0)));
vertices.push(PositionNormal::new(first_outer, vec3(0.0, 0.0, -1.0)));
vertices.push(PositionNormal::new(second_outer, vec3(0.0, 0.0, -1.0)));
// top triangle
vertices.push(PositionNormal::new(
center + vec3(0.0, 0.0, height),
vec3(0.0, 0.0, 1.0),
));
vertices.push(PositionNormal::new(
first_outer + vec3(0.0, 0.0, height),
vec3(0.0, 0.0, 1.0),
));
vertices.push(PositionNormal::new(
second_outer + vec3(0.0, 0.0, height),
vec3(0.0, 0.0, 1.0),
));
// outside face
vertices.push(PositionNormal::new(
first_outer + vec3(0.0, 0.0, height),
first_outer.normalize(),
));
vertices.push(PositionNormal::new(first_outer, first_outer.normalize()));
vertices.push(PositionNormal::new(second_outer, second_outer.normalize()));
vertices.push(PositionNormal::new(second_outer, second_outer.normalize()));
vertices.push(PositionNormal::new(
second_outer + vec3(0.0, 0.0, height),
second_outer.normalize(),
));
vertices.push(PositionNormal::new(
first_outer + vec3(0.0, 0.0, height),
first_outer.normalize(),
));
}
vertices
}
}