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