pub mod asset;
pub mod character;
pub mod context;
pub mod interaction;
pub mod item;
pub mod project;
pub mod region;
pub mod rusterix_utils;
pub mod screen;
pub mod tilemap;
pub mod prelude {
pub use ::serde::{Deserialize, Serialize};
pub use crate::asset::*;
pub use crate::character::Character;
pub use crate::context::*;
pub use crate::interaction::*;
pub use crate::item::Item;
pub use crate::project::Project;
pub use crate::region::Region;
pub use crate::screen::*;
pub use crate::tilemap::{Tile, Tilemap};
pub use indexmap::IndexMap;
pub use rusterix::{
Avatar, AvatarAnimation, AvatarAnimationFrame, AvatarDirection, AvatarPerspective,
AvatarPerspectiveCount,
};
}
use theframework::prelude::*;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub enum ServerMessage {
PlayerJoined(Uuid, Uuid, Uuid),
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
pub struct Ray {
pub o: Vec3<f32>,
pub d: Vec3<f32>,
}
impl Ray {
pub fn new(o: Vec3<f32>, d: Vec3<f32>) -> Self {
Self { o, d }
}
pub fn at(&self, d: f32) -> Vec3<f32> {
self.o + self.d * d
}
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub enum HitMode {
Albedo,
Bump,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub enum HitFace {
XFace,
YFace,
ZFace,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub enum MaterialType {
Off,
PBR,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct Material {
pub base_color: Vec3<f32>,
pub roughness: f32,
pub metallic: f32,
pub ior: f32,
pub mat_type: MaterialType,
}
impl Default for Material {
fn default() -> Self {
Self::new()
}
}
impl Material {
pub fn new() -> Self {
Self {
base_color: Vec3::new(0.5, 0.5, 0.5),
roughness: 0.5,
metallic: 0.0,
ior: 1.45,
mat_type: MaterialType::Off,
}
}
pub fn mix(&mut self, mat1: &Material, mat2: &Material, t: f32) {
self.base_color = mat1
.base_color
.map2(mat2.base_color, |a, b| a + t * (b - a));
self.metallic = f32::lerp(mat1.metallic, mat2.metallic, t);
self.roughness = f32::lerp(mat1.roughness, mat2.roughness, t);
self.ior = f32::lerp(mat1.ior, mat2.ior, t);
}
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct Hit {
pub is_valid: bool,
pub mode: HitMode,
pub node: usize,
pub eps: f32,
pub key: Vec3<f32>,
pub hash: f32,
pub bump: f32,
pub distance: f32,
pub interior_distance: f32,
pub hit_point: Vec3<f32>,
pub normal: Vec3<f32>,
pub uv: Vec2<f32>,
pub global_uv: Vec2<f32>,
pub face: HitFace,
pub pattern_pos: Vec2<f32>,
pub color: Vec4<f32>,
pub mat: Material,
pub noise: Option<f32>,
pub noise_scale: f32,
pub value: f32,
pub two_d: bool,
}
impl Default for Hit {
fn default() -> Self {
Self::new()
}
}
impl Hit {
pub fn new() -> Self {
Self {
is_valid: true,
mode: HitMode::Albedo,
node: 0,
eps: 0.001,
key: Vec3::zero(),
hash: 0.0,
bump: 0.0,
distance: f32::MAX,
interior_distance: f32::MAX,
hit_point: Vec3::zero(),
normal: Vec3::zero(),
uv: Vec2::zero(),
global_uv: Vec2::zero(),
face: HitFace::XFace,
pattern_pos: Vec2::zero(),
color: Vec4::zero(),
mat: Material::default(),
noise: None,
noise_scale: 1.0,
value: 1.0,
two_d: false,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct AABB2D {
min: Vec2<f32>,
max: Vec2<f32>,
}
impl Default for AABB2D {
fn default() -> Self {
Self::zero()
}
}
impl AABB2D {
pub fn new(min: Vec2<f32>, max: Vec2<f32>) -> Self {
AABB2D { min, max }
}
pub fn zero() -> Self {
AABB2D {
min: Vec2::new(f32::MAX, f32::MAX),
max: Vec2::new(f32::MIN, f32::MIN),
}
}
pub fn is_empty(&self) -> bool {
self.min.x > self.max.x || self.min.y > self.max.y
}
pub fn grow(&mut self, other: AABB2D) {
self.min.x = self.min.x.min(other.min.x);
self.min.y = self.min.y.min(other.min.y);
self.max.x = self.max.x.max(other.max.x);
self.max.y = self.max.y.max(other.max.y);
}
pub fn to_int(&self) -> (Vec2<i32>, Vec2<i32>) {
let min_int = Vec2::new(self.min.x.floor() as i32, self.min.y.floor() as i32);
let max_int = Vec2::new(self.max.x.ceil() as i32, self.max.y.ceil() as i32);
(min_int, max_int)
}
pub fn to_tiles(&self) -> Vec<Vec2<i32>> {
let (min_int, max_int) = self.to_int();
let mut tiles = Vec::new();
for x in min_int.x..=max_int.x {
for y in min_int.y..=max_int.y {
tiles.push(Vec2::new(x, y));
}
}
tiles
}
}
pub fn do_intersect(p1: (i32, i32), q1: (i32, i32), p2: (i32, i32), q2: (i32, i32)) -> bool {
fn on_segment(p: (i32, i32), q: (i32, i32), r: (i32, i32)) -> bool {
q.0 <= std::cmp::max(p.0, r.0)
&& q.0 >= std::cmp::min(p.0, r.0)
&& q.1 <= std::cmp::max(p.1, r.1)
&& q.1 >= std::cmp::min(p.1, r.1)
}
fn orientation(p: (i32, i32), q: (i32, i32), r: (i32, i32)) -> i32 {
let val = (q.1 - p.1) * (r.0 - q.0) - (q.0 - p.0) * (r.1 - q.1);
if val == 0 {
return 0;
} if val > 0 { 1 } else { 2 } }
let o1 = orientation(p1, q1, p2);
let o2 = orientation(p1, q1, q2);
let o3 = orientation(p2, q2, p1);
let o4 = orientation(p2, q2, q1);
if o1 != o2 && o3 != o4 {
return true;
}
if o1 == 0 && on_segment(p1, p2, q1) {
return true;
}
if o2 == 0 && on_segment(p1, q2, q1) {
return true;
}
if o3 == 0 && on_segment(p2, p1, q2) {
return true;
}
if o4 == 0 && on_segment(p2, q1, q2) {
return true;
}
false
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct RenderTile {
pub x: usize,
pub y: usize,
pub width: usize,
pub height: usize,
}
impl RenderTile {
pub fn new(x: usize, y: usize, width: usize, height: usize) -> Self {
Self {
x,
y,
width,
height,
}
}
pub fn create_tiles(
image_width: usize,
image_height: usize,
tile_width: usize,
tile_height: usize,
) -> Vec<Self> {
let mut tiles = Vec::new();
let mut x = 0;
let mut y = 0;
while x < image_width && y < image_height {
let tile = Self {
x,
y,
width: tile_width,
height: tile_height,
};
tiles.push(tile);
x += tile_width;
if x >= image_width {
x = 0;
y += tile_height;
}
}
tiles
}
}