1pub mod asset;
2pub mod character;
3pub mod context;
4pub mod interaction;
5pub mod item;
6pub mod project;
7pub mod region;
8pub mod rusterix_utils;
9pub mod screen;
10pub mod tilemap;
11
12pub mod prelude {
13 pub use ::serde::{Deserialize, Serialize};
14
15 pub use crate::asset::*;
16 pub use crate::character::Character;
17 pub use crate::context::*;
18 pub use crate::interaction::*;
19 pub use crate::item::Item;
20 pub use crate::project::Project;
21 pub use crate::region::Region;
22 pub use crate::screen::*;
23 pub use crate::tilemap::{Tile, Tilemap};
24 pub use indexmap::IndexMap;
25 pub use rusterix::{
26 Avatar, AvatarAnimation, AvatarAnimationFrame, AvatarDirection, AvatarPerspective,
27 AvatarPerspectiveCount,
28 };
29}
30
31use theframework::prelude::*;
32
33#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
35pub enum ServerMessage {
36 PlayerJoined(Uuid, Uuid, Uuid),
39}
40
41#[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
43pub struct Ray {
44 pub o: Vec3<f32>,
45 pub d: Vec3<f32>,
46}
47
48impl Ray {
49 pub fn new(o: Vec3<f32>, d: Vec3<f32>) -> Self {
50 Self { o, d }
51 }
52
53 pub fn at(&self, d: f32) -> Vec3<f32> {
55 self.o + self.d * d
56 }
57}
58
59#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
60pub enum HitMode {
61 Albedo,
62 Bump,
63}
64
65#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
66pub enum HitFace {
67 XFace,
68 YFace,
69 ZFace,
70}
71
72#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
73pub enum MaterialType {
74 Off,
75 PBR,
76}
77
78#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
79pub struct Material {
80 pub base_color: Vec3<f32>,
81
82 pub roughness: f32,
83 pub metallic: f32,
84 pub ior: f32,
85
86 pub mat_type: MaterialType,
87}
88
89impl Default for Material {
90 fn default() -> Self {
91 Self::new()
92 }
93}
94
95impl Material {
96 pub fn new() -> Self {
97 Self {
98 base_color: Vec3::new(0.5, 0.5, 0.5),
99 roughness: 0.5,
100 metallic: 0.0,
101 ior: 1.45,
102
103 mat_type: MaterialType::Off,
104 }
105 }
106
107 pub fn mix(&mut self, mat1: &Material, mat2: &Material, t: f32) {
109 self.base_color = mat1
110 .base_color
111 .map2(mat2.base_color, |a, b| a + t * (b - a));
112
113 self.metallic = f32::lerp(mat1.metallic, mat2.metallic, t);
114 self.roughness = f32::lerp(mat1.roughness, mat2.roughness, t);
115 self.ior = f32::lerp(mat1.ior, mat2.ior, t);
116 }
117}
118
119#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
120pub struct Hit {
121 pub is_valid: bool,
122
123 pub mode: HitMode,
124
125 pub node: usize,
126
127 pub eps: f32,
128
129 pub key: Vec3<f32>,
130 pub hash: f32,
131
132 pub bump: f32,
133
134 pub distance: f32,
135 pub interior_distance: f32,
136
137 pub hit_point: Vec3<f32>,
138 pub normal: Vec3<f32>,
139 pub uv: Vec2<f32>,
140 pub global_uv: Vec2<f32>,
141 pub face: HitFace,
142
143 pub pattern_pos: Vec2<f32>,
144
145 pub color: Vec4<f32>,
146
147 pub mat: Material,
148 pub noise: Option<f32>,
149 pub noise_scale: f32,
150
151 pub value: f32,
152
153 pub two_d: bool,
154}
155
156impl Default for Hit {
157 fn default() -> Self {
158 Self::new()
159 }
160}
161
162impl Hit {
163 pub fn new() -> Self {
164 Self {
165 is_valid: true,
166
167 mode: HitMode::Albedo,
168
169 node: 0,
170
171 eps: 0.001, key: Vec3::zero(),
174 hash: 0.0,
175
176 bump: 0.0,
177
178 distance: f32::MAX,
179 interior_distance: f32::MAX,
180
181 hit_point: Vec3::zero(),
182 normal: Vec3::zero(),
183 uv: Vec2::zero(),
184 global_uv: Vec2::zero(),
185 face: HitFace::XFace,
186
187 pattern_pos: Vec2::zero(),
188
189 color: Vec4::zero(),
190
191 mat: Material::default(),
192 noise: None,
193 noise_scale: 1.0,
194
195 value: 1.0,
196
197 two_d: false,
198 }
199 }
200}
201
202#[derive(Debug, Clone, Copy)]
203pub struct AABB2D {
204 min: Vec2<f32>,
205 max: Vec2<f32>,
206}
207
208impl Default for AABB2D {
209 fn default() -> Self {
210 Self::zero()
211 }
212}
213
214impl AABB2D {
215 pub fn new(min: Vec2<f32>, max: Vec2<f32>) -> Self {
216 AABB2D { min, max }
217 }
218
219 pub fn zero() -> Self {
220 AABB2D {
221 min: Vec2::new(f32::MAX, f32::MAX),
222 max: Vec2::new(f32::MIN, f32::MIN),
223 }
224 }
225
226 pub fn is_empty(&self) -> bool {
227 self.min.x > self.max.x || self.min.y > self.max.y
228 }
229
230 pub fn grow(&mut self, other: AABB2D) {
231 self.min.x = self.min.x.min(other.min.x);
232 self.min.y = self.min.y.min(other.min.y);
233 self.max.x = self.max.x.max(other.max.x);
234 self.max.y = self.max.y.max(other.max.y);
235 }
236
237 pub fn to_int(&self) -> (Vec2<i32>, Vec2<i32>) {
238 let min_int = Vec2::new(self.min.x.floor() as i32, self.min.y.floor() as i32);
239 let max_int = Vec2::new(self.max.x.ceil() as i32, self.max.y.ceil() as i32);
240 (min_int, max_int)
241 }
242
243 pub fn to_tiles(&self) -> Vec<Vec2<i32>> {
244 let (min_int, max_int) = self.to_int();
245 let mut tiles = Vec::new();
246
247 for x in min_int.x..=max_int.x {
248 for y in min_int.y..=max_int.y {
249 tiles.push(Vec2::new(x, y));
250 }
251 }
252
253 tiles
254 }
255}
256
257pub fn do_intersect(p1: (i32, i32), q1: (i32, i32), p2: (i32, i32), q2: (i32, i32)) -> bool {
259 fn on_segment(p: (i32, i32), q: (i32, i32), r: (i32, i32)) -> bool {
262 q.0 <= std::cmp::max(p.0, r.0)
263 && q.0 >= std::cmp::min(p.0, r.0)
264 && q.1 <= std::cmp::max(p.1, r.1)
265 && q.1 >= std::cmp::min(p.1, r.1)
266 }
267
268 fn orientation(p: (i32, i32), q: (i32, i32), r: (i32, i32)) -> i32 {
274 let val = (q.1 - p.1) * (r.0 - q.0) - (q.0 - p.0) * (r.1 - q.1);
275 if val == 0 {
276 return 0;
277 } if val > 0 { 1 } else { 2 } }
280
281 let o1 = orientation(p1, q1, p2);
283 let o2 = orientation(p1, q1, q2);
284 let o3 = orientation(p2, q2, p1);
285 let o4 = orientation(p2, q2, q1);
286
287 if o1 != o2 && o3 != o4 {
289 return true;
290 }
291
292 if o1 == 0 && on_segment(p1, p2, q1) {
295 return true;
296 }
297
298 if o2 == 0 && on_segment(p1, q2, q1) {
300 return true;
301 }
302
303 if o3 == 0 && on_segment(p2, p1, q2) {
305 return true;
306 }
307
308 if o4 == 0 && on_segment(p2, q1, q2) {
310 return true;
311 }
312
313 false
315}
316
317#[derive(Serialize, Deserialize, Clone, Debug)]
318pub struct RenderTile {
319 pub x: usize,
320 pub y: usize,
321 pub width: usize,
322 pub height: usize,
323}
324
325impl RenderTile {
326 pub fn new(x: usize, y: usize, width: usize, height: usize) -> Self {
327 Self {
328 x,
329 y,
330 width,
331 height,
332 }
333 }
334
335 pub fn create_tiles(
336 image_width: usize,
337 image_height: usize,
338 tile_width: usize,
339 tile_height: usize,
340 ) -> Vec<Self> {
341 let mut tiles = Vec::new();
344 let mut x = 0;
345 let mut y = 0;
346 while x < image_width && y < image_height {
347 let tile = Self {
348 x,
349 y,
350 width: tile_width,
351 height: tile_height,
352 };
353 tiles.push(tile);
354 x += tile_width;
355 if x >= image_width {
356 x = 0;
357 y += tile_height;
358 }
359 }
360
361 tiles
362 }
363}