use super::assets::AssetId;
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum PrimitiveShape {
Plane {
width: f32,
depth: f32,
segments_x: u32,
segments_z: u32,
},
Box {
dims: [f32; 3],
},
Sphere {
radius: f32,
segments_long: u32,
segments_lat: u32,
},
Cylinder {
radius: f32,
height: f32,
radial_segments: u32,
},
Cone {
radius: f32,
height: f32,
radial_segments: u32,
},
Torus {
radius: f32,
thickness: f32,
segments_major: u32,
segments_minor: u32,
},
}
impl PrimitiveShape {
pub fn default_plane() -> Self {
Self::Plane {
width: 10.0,
depth: 10.0,
segments_x: 1,
segments_z: 1,
}
}
pub fn default_box() -> Self {
Self::Box {
dims: [1.0, 1.0, 1.0],
}
}
pub fn default_sphere() -> Self {
Self::Sphere {
radius: 0.5,
segments_long: 24,
segments_lat: 16,
}
}
pub fn default_cylinder() -> Self {
Self::Cylinder {
radius: 0.5,
height: 1.0,
radial_segments: 24,
}
}
pub fn default_cone() -> Self {
Self::Cone {
radius: 0.5,
height: 1.0,
radial_segments: 24,
}
}
pub fn default_torus() -> Self {
Self::Torus {
radius: 0.5,
thickness: 0.1,
segments_major: 24,
segments_minor: 12,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct TextureRef {
pub asset: AssetId,
#[serde(default, skip_serializing_if = "is_zero_u32")]
pub uv_index: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub transform: Option<TextureTransform>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub sampler: Option<TextureSampler>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub flow: Option<[f32; 2]>,
}
impl TextureRef {
pub fn new(asset: AssetId) -> Self {
Self {
asset,
uv_index: 0,
transform: None,
sampler: None,
flow: None,
}
}
}
impl From<AssetId> for TextureRef {
fn from(asset: AssetId) -> Self {
Self::new(asset)
}
}
impl<'de> serde::Deserialize<'de> for TextureRef {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
#[derive(serde::Deserialize)]
#[serde(untagged)]
enum Repr {
Bare(AssetId),
Full {
asset: AssetId,
#[serde(default)]
uv_index: u32,
#[serde(default)]
transform: Option<TextureTransform>,
#[serde(default)]
sampler: Option<TextureSampler>,
#[serde(default)]
flow: Option<[f32; 2]>,
},
}
Ok(match Repr::deserialize(d)? {
Repr::Bare(asset) => TextureRef::new(asset),
Repr::Full {
asset,
uv_index,
transform,
sampler,
flow,
} => TextureRef {
asset,
uv_index,
transform,
sampler,
flow,
},
})
}
}
fn is_zero_u32(v: &u32) -> bool {
*v == 0
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum TextureWrap {
#[default]
Repeat,
ClampToEdge,
MirroredRepeat,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum TextureFilter {
#[default]
Linear,
Nearest,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct TextureSampler {
#[serde(default)]
pub wrap_u: TextureWrap,
#[serde(default)]
pub wrap_v: TextureWrap,
#[serde(default)]
pub mag_filter: TextureFilter,
#[serde(default)]
pub min_filter: TextureFilter,
#[serde(default)]
pub mipmap_filter: TextureFilter,
}
#[derive(Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct TextureTransform {
#[serde(default)]
pub offset: [f32; 2],
#[serde(default)]
pub rotation: f32,
#[serde(default = "default_uv_scale")]
pub scale: [f32; 2],
}
impl Default for TextureTransform {
fn default() -> Self {
Self {
offset: [0.0, 0.0],
rotation: 0.0,
scale: [1.0, 1.0],
}
}
}
fn default_uv_scale() -> [f32; 2] {
[1.0, 1.0]
}
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
#[derive(Eq, Hash, Copy)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct MeshRef(pub AssetId);
impl std::fmt::Display for TextureRef {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(&self.asset, f)
}
}
impl std::fmt::Display for MeshRef {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(&self.0, f)
}
}