Base objects
This commit is contained in:
parent
a762f37194
commit
139f7d92cc
4 changed files with 795 additions and 102 deletions
466
src/board.rs
466
src/board.rs
|
@ -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!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
190
src/game.rs
190
src/game.rs
|
@ -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(_) => (),
|
||||||
|
|
|
@ -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
235
src/objects.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue