use crate::model::{FontStyle, FontWeight, Property};
use crate::tree::TreeKey;
use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::vec::Vec;
use core::fmt;
use core::ops::{Add, Deref, DerefMut, Div, Mul, Sub};
#[derive(Clone, Default)]
pub struct Attributes {
pub(crate) backing: BTreeMap<String, Property>,
}
impl Deref for Attributes {
type Target = BTreeMap<String, Property>;
fn deref(&self) -> &Self::Target {
&self.backing
}
}
impl DerefMut for Attributes {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.backing
}
}
impl fmt::Debug for Attributes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.backing)
}
}
#[doc = doc_link!("datatype/UDim")]
#[derive(Debug, Clone, Default)]
pub struct UDim {
pub scale: f32,
pub offset: i32,
}
impl UDim {
#[must_use]
pub const fn new(scale: f32, offset: i32) -> UDim {
UDim { scale, offset }
}
}
#[doc = doc_link!("datatype/UDim2")]
#[derive(Debug, Clone, Default)]
pub struct UDim2 {
pub x: UDim,
pub y: UDim,
}
impl UDim2 {
#[must_use]
pub const fn new(x: UDim, y: UDim) -> UDim2 {
UDim2 { x, y }
}
#[must_use]
pub const fn new_components(x_scale: f32, x_offset: i32, y_scale: f32, y_offset: i32) -> UDim2 {
UDim2 {
x: UDim::new(x_scale, x_offset),
y: UDim::new(y_scale, y_offset),
}
}
}
#[doc = doc_link!("datatype/Ray")]
#[derive(Debug, Clone, Default)]
pub struct Ray {
pub origin: Vector3,
pub direction: Vector3,
}
impl Ray {
#[must_use]
pub fn new(origin: Vector3, direction: Vector3) -> Ray {
Ray {
origin,
direction: direction.unit(),
}
}
}
#[doc = doc_link!("datatype/Faces")]
#[derive(Debug, Clone, Default)]
pub struct Faces {
pub front: bool,
pub back: bool,
pub top: bool,
pub bottom: bool,
pub left: bool,
pub right: bool,
}
impl Faces {
#[must_use]
pub const fn none() -> Faces {
Faces {
front: false,
back: false,
top: false,
bottom: false,
left: false,
right: false,
}
}
#[must_use]
pub const fn front_back() -> Faces {
Faces {
front: true,
back: true,
..Faces::none()
}
}
#[must_use]
pub const fn top_bottom() -> Faces {
Faces {
top: true,
bottom: true,
..Faces::none()
}
}
#[must_use]
pub const fn left_right() -> Faces {
Faces {
left: true,
right: true,
..Faces::none()
}
}
#[must_use]
pub const fn all() -> Faces {
Faces {
front: true,
back: true,
top: true,
bottom: true,
left: true,
right: true,
}
}
}
#[doc = doc_link!("datatype/Axes")]
#[derive(Debug, Clone, Default)]
pub struct Axes {
pub x: bool,
pub y: bool,
pub z: bool,
}
impl Axes {
#[must_use]
pub const fn none() -> Axes {
Axes {
x: false,
y: false,
z: false,
}
}
#[must_use]
pub const fn all() -> Axes {
Axes {
x: true,
y: true,
z: true,
}
}
}
#[doc = doc_link!("datatype/BrickColor")]
#[derive(Debug, Clone, Default)]
pub struct BrickColor {
pub index: i32,
}
#[doc = doc_link!("datatype/Vector2")]
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Vector2 {
pub x: f32,
pub y: f32,
}
impl Vector2 {
pub const ZERO: Vector2 = Vector2::new(0.0, 0.0);
pub const UNIT_X: Vector2 = Vector2::new(1.0, 0.0);
pub const UNIT_Y: Vector2 = Vector2::new(0.0, 1.0);
pub const ONE: Vector2 = Vector2::new(1.0, 1.0);
#[must_use]
pub const fn new(x: f32, y: f32) -> Vector2 {
Vector2 { x, y }
}
#[must_use]
#[inline]
pub fn len(&self) -> f32 {
num::Float::sqrt(self.len_squared())
}
#[must_use]
#[inline]
pub fn len_squared(&self) -> f32 {
self.x * self.x + self.y * self.y
}
}
impl Add for Vector2 {
type Output = Vector2;
fn add(self, rhs: Self) -> Self::Output {
Vector2 {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
impl Sub for Vector2 {
type Output = Vector2;
fn sub(self, rhs: Self) -> Self::Output {
Vector2 {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
}
impl Mul for Vector2 {
type Output = Vector2;
fn mul(self, rhs: Self) -> Self::Output {
Vector2 {
x: self.x * rhs.x,
y: self.y * rhs.y,
}
}
}
impl Div for Vector2 {
type Output = Vector2;
fn div(self, rhs: Self) -> Self::Output {
Vector2 {
x: self.x / rhs.x,
y: self.y / rhs.y,
}
}
}
#[doc = doc_link!("datatype/Vector3")]
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Vector3 {
pub x: f32,
pub y: f32,
pub z: f32,
}
impl Vector3 {
pub const ZERO: Vector3 = Vector3::new(0.0, 0.0, 0.0);
pub const UNIT_X: Vector3 = Vector3::new(1.0, 0.0, 0.0);
pub const UNIT_Y: Vector3 = Vector3::new(0.0, 1.0, 0.0);
pub const UNIT_Z: Vector3 = Vector3::new(0.0, 0.0, 1.0);
pub const ONE: Vector3 = Vector3::new(1.0, 1.0, 1.0);
#[must_use]
pub const fn new(x: f32, y: f32, z: f32) -> Vector3 {
Vector3 { x, y, z }
}
#[must_use]
#[inline]
pub fn len(&self) -> f32 {
num::Float::sqrt(self.len_squared())
}
#[must_use]
#[inline]
pub fn len_squared(&self) -> f32 {
self.x * self.x + self.y * self.y + self.z * self.z
}
#[must_use]
pub fn unit(&self) -> Vector3 {
let len = self.len();
Vector3 {
x: self.x / len,
y: self.y / len,
z: self.z / len,
}
}
}
impl Add for Vector3 {
type Output = Vector3;
fn add(self, rhs: Self) -> Self::Output {
Vector3 {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z,
}
}
}
impl Sub for Vector3 {
type Output = Vector3;
fn sub(self, rhs: Self) -> Self::Output {
Vector3 {
x: self.x - rhs.x,
y: self.y - rhs.y,
z: self.z - rhs.z,
}
}
}
impl Mul for Vector3 {
type Output = Vector3;
fn mul(self, rhs: Self) -> Self::Output {
Vector3 {
x: self.x * rhs.x,
y: self.y * rhs.y,
z: self.z * rhs.z,
}
}
}
impl Div for Vector3 {
type Output = Vector3;
fn div(self, rhs: Self) -> Self::Output {
Vector3 {
x: self.x / rhs.x,
y: self.y / rhs.y,
z: self.z / rhs.z,
}
}
}
#[doc = doc_link!("datatype/CFrame")]
#[derive(Debug, Clone)]
pub struct CFrame {
pub position: Vector3,
pub angle: [[f32; 3]; 3],
}
impl CFrame {
#[must_use]
pub const fn new(position: Vector3, angle: [[f32; 3]; 3]) -> CFrame {
CFrame { position, angle }
}
}
impl Default for CFrame {
fn default() -> Self {
CFrame {
position: Vector3::default(),
angle: [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]],
}
}
}
#[derive(Debug, Clone)]
pub enum InstanceRef {
Null,
Item(TreeKey),
}
#[doc = doc_link!("datatype/Vector3int16")]
#[derive(Debug, Clone, Default)]
pub struct Vector3Int16 {
pub x: i16,
pub y: i16,
pub z: i16,
}
#[doc = doc_link!("datatype/NumberSequenceKeypoint")]
#[derive(Debug, Clone, Default)]
pub struct NumberKeypoint {
pub time: f32,
pub value: f32,
pub envelope: f32,
}
#[doc = doc_link!("datatype/NumberSequence")]
#[derive(Debug, Clone, Default)]
pub struct NumberSequence {
pub keypoints: Vec<NumberKeypoint>,
}
#[doc = doc_link!("datatype/ColorSequenceKeypoint")]
#[derive(Debug, Clone, Default)]
pub struct ColorKeypoint {
pub time: f32,
pub color: Color3,
pub envelope: f32,
}
#[doc = doc_link!("datatype/ColorSequence")]
#[derive(Debug, Clone, Default)]
pub struct ColorSequence {
pub keypoints: Vec<ColorKeypoint>,
}
#[doc = doc_link!("datatype/NumberRange")]
#[derive(Debug, Clone, Default)]
pub struct NumberRange {
pub low: f32,
pub high: f32,
}
#[doc = doc_link!("datatype/Rect")]
#[derive(Debug, Clone, Default)]
pub struct Rect {
pub top_left: Vector2,
pub bottom_right: Vector2,
}
#[doc = doc_link!("datatype/Color3")]
#[derive(Debug, Clone, Default)]
pub struct Color3 {
pub r: f32,
pub g: f32,
pub b: f32,
}
impl Color3 {
#[must_use]
pub fn new(r: f32, g: f32, b: f32) -> Color3 {
debug_assert!((0.0..=1.0).contains(&r), "r value not in (0.0..=1.0)");
debug_assert!((0.0..=1.0).contains(&g), "g value not in (0.0..=1.0)");
debug_assert!((0.0..=1.0).contains(&b), "b value not in (0.0..=1.0)");
Color3 { r, g, b }
}
}
impl From<Color3Uint8> for Color3 {
fn from(col: Color3Uint8) -> Self {
Color3 {
r: col.r as f32 / 255.,
g: col.g as f32 / 255.,
b: col.b as f32 / 255.,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct Color3Uint8 {
pub r: u8,
pub g: u8,
pub b: u8,
}
impl Color3Uint8 {
#[must_use]
pub const fn new(r: u8, g: u8, b: u8) -> Color3Uint8 {
Color3Uint8 { r, g, b }
}
}
impl From<Color3> for Color3Uint8 {
fn from(col: Color3) -> Self {
Color3Uint8 {
r: (col.r * 255.) as u8,
g: (col.g * 255.) as u8,
b: (col.b * 255.) as u8,
}
}
}
impl From<(u8, u8, u8)> for Color3Uint8 {
fn from((r, g, b): (u8, u8, u8)) -> Self {
Color3Uint8 { r, g, b }
}
}
#[derive(Debug, Clone, Default)]
pub struct Pivot {
pub cframe: CFrame,
pub unknown: u8,
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum PhysicalProperties {
Default,
Custom {
density: f32,
elasticity: f32,
elasticity_weight: f32,
friction: f32,
friction_weight: f32,
},
}
impl Default for PhysicalProperties {
fn default() -> Self {
PhysicalProperties::Default
}
}
#[derive(Debug, Clone)]
pub struct FontFace {
pub family: String,
pub weight: FontWeight,
pub style: FontStyle,
pub cached_face_id: String,
}
#[cfg(feature = "mesh-format")]
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum TriMesh {
Default,
Box,
Hull {
volume: f32,
center_of_gravity: Vector3,
inertia_tensor: [[f32; 3]; 3],
meshes: Vec<ConvexHull>,
},
}
#[cfg(feature = "mesh-format")]
impl Default for TriMesh {
fn default() -> Self {
TriMesh::Default
}
}
#[cfg(feature = "mesh-format")]
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct ConvexHull {
pub unknown_1: Vec<u8>,
pub unknown_2: Vec<u8>,
pub vertices: Vec<Vector3>,
pub faces: Vec<(usize, usize, usize)>,
}
#[cfg(feature = "mesh-format")]
impl ConvexHull {
pub fn new(vertices: Vec<Vector3>, faces: Vec<(usize, usize, usize)>) -> ConvexHull {
ConvexHull {
unknown_1: Vec::new(),
unknown_2: Vec::new(),
vertices,
faces,
}
}
}