forked from karx/catbox
karx pls review, i believe I am doing the vec3 right
This commit is contained in:
parent
08aac51b0a
commit
e7470c2d8f
4
build.rs
4
build.rs
|
@ -76,7 +76,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut new_file_path = manifest_dir.clone();
|
let mut new_file_path = manifest_dir.clone();
|
||||||
if let Some(file_name) = file_name_result {
|
if let Some(file_name) = file_name_result {
|
||||||
let file_name = file_name.to_str().unwrap();
|
let file_name = file_name.to_str().unwrap();
|
||||||
if Path::new(file_name)
|
if Path::new(file_name)
|
||||||
.extension()
|
.extension()
|
||||||
.map_or(false, |ext| ext.eq_ignore_ascii_case("dll"))
|
.map_or(false, |ext| ext.eq_ignore_ascii_case("dll"))
|
||||||
{
|
{
|
||||||
|
@ -98,7 +98,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
/// A: unable to get `TlsConnector`
|
/// A: unable to get `TlsConnector`
|
||||||
/// B: A File is unable to be create
|
/// B: A File is unable to be create
|
||||||
/// C: or if the reader is unable to be copied into the writer
|
/// C: or if the reader is unable to be copied into the writer
|
||||||
pub fn download_files(path: &Path,url: &str) -> Result<File, Box<dyn std::error::Error>> {
|
pub fn download_files(path: &Path, url: &str) -> Result<File, Box<dyn std::error::Error>> {
|
||||||
let agent = AgentBuilder::new()
|
let agent = AgentBuilder::new()
|
||||||
.tls_connector(Arc::new(native_tls::TlsConnector::new()?))
|
.tls_connector(Arc::new(native_tls::TlsConnector::new()?))
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -22,6 +22,11 @@ fn main() {
|
||||||
#[cfg(feature = "audio")]
|
#[cfg(feature = "audio")]
|
||||||
cat_box::play("output.mp3", 120);
|
cat_box::play("output.mp3", 120);
|
||||||
game.run(|ctx| {
|
game.run(|ctx| {
|
||||||
|
let (_, _, _) = ctx.inner();
|
||||||
|
|
||||||
|
//let win = b.window_mut();
|
||||||
|
/* let instance_schtuff = win.vulkan_instance_extensions().unwrap(); */
|
||||||
|
|
||||||
if game.step() >= 1 {
|
if game.step() >= 1 {
|
||||||
i = (i + 1) % 255;
|
i = (i + 1) % 255;
|
||||||
ctx.set_background_colour(i, 64, 255);
|
ctx.set_background_colour(i, 64, 255);
|
||||||
|
|
13
src/lib.rs
13
src/lib.rs
|
@ -92,8 +92,9 @@
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
|
|
||||||
|
pub mod math;
|
||||||
pub mod physics;
|
pub mod physics;
|
||||||
pub mod vec2;
|
pub mod space;
|
||||||
|
|
||||||
#[cfg(feature = "audio")]
|
#[cfg(feature = "audio")]
|
||||||
use rodio::{self, source::Source, Decoder, OutputStream};
|
use rodio::{self, source::Source, Decoder, OutputStream};
|
||||||
|
@ -115,8 +116,8 @@ use std::{
|
||||||
slice::IterMut,
|
slice::IterMut,
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
use vec2::Vec2Int;
|
|
||||||
|
|
||||||
|
use math::vec2::Vec2Int;
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use sdl2::{self, event::Event, keyboard::Scancode, pixels::Color};
|
pub use sdl2::{self, event::Event, keyboard::Scancode, pixels::Color};
|
||||||
|
|
||||||
|
@ -748,7 +749,6 @@ impl Game {
|
||||||
///```
|
///```
|
||||||
pub fn step(&self) -> u128 {
|
pub fn step(&self) -> u128 {
|
||||||
self.time.get().elapsed().as_millis()
|
self.time.get().elapsed().as_millis()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///Resets in-game timer
|
///Resets in-game timer
|
||||||
|
@ -769,11 +769,10 @@ impl Game {
|
||||||
let sdl_context = sdl2::init()?;
|
let sdl_context = sdl2::init()?;
|
||||||
let video_subsystem = sdl_context.video()?;
|
let video_subsystem = sdl_context.video()?;
|
||||||
|
|
||||||
let mut window_build = video_subsystem
|
let mut window_build = video_subsystem.window(&self.title, self.width, self.height);
|
||||||
.window(&self.title, self.width, self.height);
|
|
||||||
|
|
||||||
//init window
|
//init window
|
||||||
let window = if cfg!(feature = "opengl"){
|
let window = if cfg!(feature = "opengl") {
|
||||||
window_build.opengl().build()?
|
window_build.opengl().build()?
|
||||||
} else if cfg!(feature = "vulkan") {
|
} else if cfg!(feature = "vulkan") {
|
||||||
window_build.vulkan().build()?
|
window_build.vulkan().build()?
|
||||||
|
@ -817,7 +816,7 @@ impl Game {
|
||||||
/// Plays an audio file given the path of file and plays it for y seconds
|
/// Plays an audio file given the path of file and plays it for y seconds
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// # use cat_box::play;
|
/// # use cat_box::play;
|
||||||
/// play("/path/to/song.mp3", 15);
|
/// play("/path/to/song.mp71", 15);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn play<P: AsRef<Path> + Send + 'static>(
|
pub fn play<P: AsRef<Path> + Send + 'static>(
|
||||||
path: P,
|
path: P,
|
||||||
|
|
2
src/math/mod.rs
Normal file
2
src/math/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod vec2;
|
||||||
|
pub mod vec3;
|
385
src/math/vec3.rs
Normal file
385
src/math/vec3.rs
Normal file
|
@ -0,0 +1,385 @@
|
||||||
|
use std::{
|
||||||
|
fmt::Debug,
|
||||||
|
ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vec3
|
||||||
|
/// A set of 3 [`f32`]s representing a location or direction in the 3d plane.
|
||||||
|
#[derive(Clone, Copy, Default, PartialEq)]
|
||||||
|
pub struct Vec3 {
|
||||||
|
/// The x component of the vector.
|
||||||
|
pub x: f32,
|
||||||
|
/// The y component of the vector.
|
||||||
|
pub y: f32,
|
||||||
|
/// The z component of the vector
|
||||||
|
pub z: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for Vec3 {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_tuple("Vec3")
|
||||||
|
.field(&self.x)
|
||||||
|
.field(&self.y)
|
||||||
|
.field(&self.z)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vec3 {
|
||||||
|
/// Creates a new `Vec3` with the given x- and y-values.
|
||||||
|
///
|
||||||
|
/// It is often simpler, and preferred, to just write `(x, y).into()`.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(x: f32, y: f32, z: f32) -> Vec3 {
|
||||||
|
Self { x, y, z }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the squared magnitude of the vector.
|
||||||
|
///
|
||||||
|
/// Useful for comparisons as it is faster to calculate than `magnitude`.
|
||||||
|
#[must_use]
|
||||||
|
pub fn sq_magnitude(self) -> f32 {
|
||||||
|
self.x * self.x + self.y * self.y + self.z * self.z
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the magnitude of the vector.
|
||||||
|
#[must_use]
|
||||||
|
pub fn magnitude(self) -> f32 {
|
||||||
|
self.sq_magnitude().sqrt()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the squared distance from this vector to `rhs`.
|
||||||
|
///
|
||||||
|
/// Useful for comparisons as it is faster to calculate than `dist`.
|
||||||
|
#[must_use]
|
||||||
|
pub fn sq_dist(self, rhs: Self) -> f32 {
|
||||||
|
(self - rhs).sq_magnitude()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the distance from this vector to `rhs`.
|
||||||
|
#[must_use]
|
||||||
|
pub fn dist(self, rhs: Self) -> f32 {
|
||||||
|
(self - rhs).magnitude()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Normalizes the vector, making its magnitude `1`.
|
||||||
|
#[must_use]
|
||||||
|
pub fn normalized(self) -> Self {
|
||||||
|
self / self.magnitude()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Rounds the vector to a [`Vec3Int`].
|
||||||
|
///
|
||||||
|
/// This uses `as i32` under the hood, and as such comes with all the same unfortunate edge cases. Beware.
|
||||||
|
#[must_use]
|
||||||
|
pub fn rounded(self) -> Vec3Int {
|
||||||
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
|
Vec3Int {
|
||||||
|
x: self.x as i32,
|
||||||
|
y: self.y as i32,
|
||||||
|
z: self.z as i32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(i32, i32, i32)> for Vec3 {
|
||||||
|
fn from(v: (i32, i32, i32)) -> Self {
|
||||||
|
Vec3Int::from(v).to_f32()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(f32, f32, f32)> for Vec3 {
|
||||||
|
fn from(v: (f32, f32, f32)) -> Self {
|
||||||
|
Self {
|
||||||
|
x: v.0,
|
||||||
|
y: v.1,
|
||||||
|
z: v.2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec3> for (f32, f32, f32) {
|
||||||
|
fn from(v: Vec3) -> Self {
|
||||||
|
(v.x, v.y, v.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq<(i32, i32, i32)> for Vec3 {
|
||||||
|
fn eq(&self, other: &(i32, i32, i32)) -> bool {
|
||||||
|
self == &Self::from(*other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq<(f32, f32, f32)> for Vec3 {
|
||||||
|
fn eq(&self, other: &(f32, f32, f32)) -> bool {
|
||||||
|
self == &Self::from(*other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...and related op impls
|
||||||
|
impl Neg for Vec3 {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn neg(self) -> Self::Output {
|
||||||
|
self * -1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add for Vec3 {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
|
Self {
|
||||||
|
x: self.x + rhs.x,
|
||||||
|
y: self.y + rhs.y,
|
||||||
|
z: self.z + rhs.z,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> AddAssign<T> for Vec3
|
||||||
|
where
|
||||||
|
Vec3: Add<T, Output = Self>,
|
||||||
|
{
|
||||||
|
fn add_assign(&mut self, rhs: T) {
|
||||||
|
*self = *self + rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Sub<T> for Vec3
|
||||||
|
where
|
||||||
|
Vec3: Add<T, Output = Self>,
|
||||||
|
{
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn sub(self, rhs: T) -> Self::Output {
|
||||||
|
-(-self + rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> SubAssign<T> for Vec3
|
||||||
|
where
|
||||||
|
Vec3: Sub<T, Output = Self>,
|
||||||
|
{
|
||||||
|
fn sub_assign(&mut self, rhs: T) {
|
||||||
|
*self = *self - rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<f32> for Vec3 {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn mul(self, rhs: f32) -> Self::Output {
|
||||||
|
Self {
|
||||||
|
x: self.x * rhs,
|
||||||
|
y: self.y * rhs,
|
||||||
|
z: self.z * rhs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Div<f32> for Vec3 {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn div(self, rhs: f32) -> Self::Output {
|
||||||
|
Self {
|
||||||
|
x: self.x / rhs,
|
||||||
|
y: self.y / rhs,
|
||||||
|
z: self.z / rhs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MulAssign<f32> for Vec3 {
|
||||||
|
fn mul_assign(&mut self, rhs: f32) {
|
||||||
|
*self = *self * rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DivAssign<f32> for Vec3 {
|
||||||
|
fn div_assign(&mut self, rhs: f32) {
|
||||||
|
*self = *self / rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vec3Int
|
||||||
|
/// A set of 2 [`i32`]s representing a location or direction in the 2d plane.
|
||||||
|
#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
|
||||||
|
pub struct Vec3Int {
|
||||||
|
/// The x component of the vector.
|
||||||
|
pub x: i32,
|
||||||
|
/// The y component of the vector.
|
||||||
|
pub y: i32,
|
||||||
|
|
||||||
|
pub z: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for Vec3Int {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_tuple("Vec3Int")
|
||||||
|
.field(&self.x)
|
||||||
|
.field(&self.y)
|
||||||
|
.field(&self.z)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vec3Int {
|
||||||
|
/// Creates a new `Vec3` with the given x- and y-values.
|
||||||
|
///
|
||||||
|
/// It is often simpler, and preferred, to just write `(x, y).into()`.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(x: i32, y: i32, z: i32) -> Vec3Int {
|
||||||
|
Self { x, y, z }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the squared magnitude of the vector.
|
||||||
|
///
|
||||||
|
/// Useful for comparisons as it is faster to calculate than `magnitude`.
|
||||||
|
#[must_use]
|
||||||
|
pub fn sq_magnitude(self) -> i32 {
|
||||||
|
self.x * self.x + self.y * self.y + self.z * self.z
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the magnitude of the vector.
|
||||||
|
#[must_use]
|
||||||
|
pub fn magnitude(self) -> f32 {
|
||||||
|
#[allow(clippy::cast_precision_loss)]
|
||||||
|
(self.sq_magnitude() as f32).sqrt()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the squared distance from this vector to `rhs`.
|
||||||
|
///
|
||||||
|
/// Useful for comparisons as it is faster to calculate than `dist`.
|
||||||
|
#[must_use]
|
||||||
|
pub fn sq_dist(self, rhs: Self) -> i32 {
|
||||||
|
(self - rhs).sq_magnitude()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the distance from this vector to `rhs`.
|
||||||
|
#[must_use]
|
||||||
|
pub fn dist(self, rhs: Self) -> f32 {
|
||||||
|
(self - rhs).magnitude()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Casts this vector to a [`Vec3`].
|
||||||
|
///
|
||||||
|
/// This uses `as f32` under the hood, and as such comes with all the same unfortunate edge cases. Beware.
|
||||||
|
#[must_use]
|
||||||
|
pub fn to_f32(self) -> Vec3 {
|
||||||
|
#[allow(clippy::cast_precision_loss)]
|
||||||
|
Vec3 {
|
||||||
|
x: self.x as f32,
|
||||||
|
y: self.y as f32,
|
||||||
|
z: self.z as f32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(i32, i32, i32)> for Vec3Int {
|
||||||
|
fn from(v: (i32, i32, i32)) -> Self {
|
||||||
|
Self {
|
||||||
|
x: v.0,
|
||||||
|
y: v.1,
|
||||||
|
z: v.2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec3Int> for (i32, i32, i32) {
|
||||||
|
fn from(v: Vec3Int) -> Self {
|
||||||
|
(v.x, v.y, v.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq<(i32, i32, i32)> for Vec3Int {
|
||||||
|
fn eq(&self, other: &(i32, i32, i32)) -> bool {
|
||||||
|
self == &Self::from(*other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...and related op impls
|
||||||
|
impl Neg for Vec3Int {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn neg(self) -> Self::Output {
|
||||||
|
self * -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add for Vec3Int {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
|
Self {
|
||||||
|
x: self.x + rhs.x,
|
||||||
|
y: self.y + rhs.y,
|
||||||
|
z: self.z + rhs.z,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> AddAssign<T> for Vec3Int
|
||||||
|
where
|
||||||
|
Vec3Int: Add<T, Output = Self>,
|
||||||
|
{
|
||||||
|
fn add_assign(&mut self, rhs: T) {
|
||||||
|
*self = *self + rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Sub<T> for Vec3Int
|
||||||
|
where
|
||||||
|
Vec3Int: Add<T, Output = Self>,
|
||||||
|
{
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn sub(self, rhs: T) -> Self::Output {
|
||||||
|
-(-self + rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> SubAssign<T> for Vec3Int
|
||||||
|
where
|
||||||
|
Vec3Int: Sub<T, Output = Self>,
|
||||||
|
{
|
||||||
|
fn sub_assign(&mut self, rhs: T) {
|
||||||
|
*self = *self - rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<i32> for Vec3Int {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn mul(self, rhs: i32) -> Self::Output {
|
||||||
|
Self {
|
||||||
|
x: self.x * rhs,
|
||||||
|
y: self.y * rhs,
|
||||||
|
z: self.z * rhs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Div<i32> for Vec3Int {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn div(self, rhs: i32) -> Self::Output {
|
||||||
|
Self {
|
||||||
|
x: self.x / rhs,
|
||||||
|
y: self.y / rhs,
|
||||||
|
z: self.z / rhs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MulAssign<i32> for Vec3Int {
|
||||||
|
fn mul_assign(&mut self, rhs: i32) {
|
||||||
|
*self = *self * rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DivAssign<i32> for Vec3Int {
|
||||||
|
fn div_assign(&mut self, rhs: i32) {
|
||||||
|
*self = *self / rhs;
|
||||||
|
}
|
||||||
|
}
|
37
src/space/mesh.rs
Normal file
37
src/space/mesh.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
use crate::math::{vec3::Vec3, vec2::Vec2};
|
||||||
|
|
||||||
|
//credit to Djuk1c, abstracting your code into a game engine bcuz i can
|
||||||
|
#[derive(Default, Clone, Copy, Debug)]
|
||||||
|
pub struct Vertex {
|
||||||
|
pub pos: Vec3,
|
||||||
|
pub normal: Vec3,
|
||||||
|
pub texture: Vec2,
|
||||||
|
pub color: u32,
|
||||||
|
pub lit: f32,
|
||||||
|
}
|
||||||
|
impl Vertex {
|
||||||
|
pub fn new(pos: Vec3, normal: Vec3, texture: Vec2, color: u32, lit: f32) -> Self {
|
||||||
|
Self { pos, normal, texture, color, lit }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Triangle {
|
||||||
|
pub v: [Vertex; 3],
|
||||||
|
}
|
||||||
|
impl Triangle {
|
||||||
|
pub fn new(
|
||||||
|
p1: Vertex,
|
||||||
|
p2: Vertex,
|
||||||
|
p3: Vertex,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
v: [p1, p2, p3]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Mesh {
|
||||||
|
pub triangles: Vec<Triangle>,
|
||||||
|
}
|
||||||
|
|
1
src/space/mod.rs
Normal file
1
src/space/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod mesh;
|
Loading…
Reference in a new issue