use serde::{Deserialize, Serialize};
use super::asset_uuid::AssetUuid;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SceneAudioSource {
#[serde(default)]
pub audio_uuid: Option<AssetUuid>,
#[serde(default)]
pub audio_name: Option<String>,
#[serde(default = "default_volume")]
pub volume: f32,
#[serde(default)]
pub looping: bool,
#[serde(default)]
pub playing: bool,
#[serde(default)]
pub spatial: bool,
#[serde(default)]
pub reverb: bool,
}
fn default_volume() -> f32 {
1.0
}
impl SceneAudioSource {
pub fn from_name(name: impl Into<String>) -> Self {
Self {
audio_uuid: None,
audio_name: Some(name.into()),
volume: 1.0,
looping: false,
playing: false,
spatial: false,
reverb: false,
}
}
pub fn from_uuid(uuid: AssetUuid) -> Self {
Self {
audio_uuid: Some(uuid),
audio_name: None,
volume: 1.0,
looping: false,
playing: false,
spatial: false,
reverb: false,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScenePrefabInstance {
#[serde(default)]
pub prefab_uuid: Option<AssetUuid>,
#[serde(default)]
pub prefab_path: Option<String>,
#[serde(default)]
pub prefab_name: Option<String>,
}
impl ScenePrefabInstance {
pub fn from_uuid(uuid: AssetUuid) -> Self {
Self {
prefab_uuid: Some(uuid),
prefab_path: None,
prefab_name: None,
}
}
pub fn from_path(path: impl Into<String>) -> Self {
Self {
prefab_uuid: None,
prefab_path: Some(path.into()),
prefab_name: None,
}
}
pub fn from_name(name: impl Into<String>) -> Self {
Self {
prefab_uuid: None,
prefab_path: None,
prefab_name: Some(name.into()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum EmbeddedTexture {
Rgba {
#[serde(with = "base64_bytes")]
rgba_data: Vec<u8>,
width: u32,
height: u32,
},
Png {
#[serde(with = "base64_bytes")]
png_data: Vec<u8>,
},
}
mod base64_bytes {
use base64::{Engine, engine::general_purpose::STANDARD};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub fn serialize<S: Serializer>(data: &[u8], serializer: S) -> Result<S::Ok, S::Error> {
STANDARD.encode(data).serialize(serializer)
}
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
let string = String::deserialize(deserializer)?;
STANDARD.decode(&string).map_err(serde::de::Error::custom)
}
}
impl EmbeddedTexture {
pub fn from_rgba(rgba_data: Vec<u8>, width: u32, height: u32) -> Self {
Self::Rgba {
rgba_data,
width,
height,
}
}
pub fn from_png(png_data: Vec<u8>) -> Self {
Self::Png { png_data }
}
pub fn to_rgba(&self) -> Option<(Vec<u8>, u32, u32)> {
match self {
Self::Rgba {
rgba_data,
width,
height,
} => Some((rgba_data.clone(), *width, *height)),
Self::Png { png_data } => {
if let Ok(img) = image::load_from_memory(png_data) {
let rgba = img.to_rgba8();
let (width, height) = rgba.dimensions();
Some((rgba.into_raw(), width, height))
} else {
None
}
}
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmbeddedAudio {
#[serde(with = "base64_bytes")]
pub data: Vec<u8>,
}
impl EmbeddedAudio {
pub fn from_bytes(data: Vec<u8>) -> Self {
Self { data }
}
pub fn data(&self) -> &[u8] {
&self.data
}
}