use serde::{Deserialize, Serialize};
use crate::ecs::transform::LocalTransform;
use super::asset_uuid::AssetUuid;
use super::material::SceneMaterial;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SceneInstancedMesh {
#[serde(default)]
pub mesh_uuid: Option<AssetUuid>,
#[serde(default)]
pub mesh_name: Option<String>,
pub instances: Vec<SceneMeshInstance>,
#[serde(default)]
pub material: Option<SceneMaterial>,
}
impl SceneInstancedMesh {
pub fn from_name(name: impl Into<String>, instances: Vec<SceneMeshInstance>) -> Self {
Self {
mesh_uuid: None,
mesh_name: Some(name.into()),
instances,
material: None,
}
}
pub fn from_uuid(uuid: AssetUuid, instances: Vec<SceneMeshInstance>) -> Self {
Self {
mesh_uuid: Some(uuid),
mesh_name: None,
instances,
material: None,
}
}
pub fn with_material(mut self, material: SceneMaterial) -> Self {
self.material = Some(material);
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SceneMeshInstance {
pub translation: [f32; 3],
pub rotation: [f32; 4],
pub scale: [f32; 3],
#[serde(default)]
pub color: Option<[f32; 4]>,
}
impl SceneMeshInstance {
pub fn new(translation: [f32; 3]) -> Self {
Self {
translation,
rotation: [0.0, 0.0, 0.0, 1.0],
scale: [1.0, 1.0, 1.0],
color: None,
}
}
pub fn with_rotation(mut self, rotation: [f32; 4]) -> Self {
self.rotation = rotation;
self
}
pub fn with_scale(mut self, scale: [f32; 3]) -> Self {
self.scale = scale;
self
}
pub fn with_uniform_scale(mut self, scale: f32) -> Self {
self.scale = [scale, scale, scale];
self
}
pub fn with_color(mut self, color: [f32; 4]) -> Self {
self.color = Some(color);
self
}
pub fn to_local_transform(&self) -> LocalTransform {
LocalTransform {
translation: nalgebra_glm::Vec3::new(
self.translation[0],
self.translation[1],
self.translation[2],
),
rotation: nalgebra_glm::Quat::new(
self.rotation[3],
self.rotation[0],
self.rotation[1],
self.rotation[2],
),
scale: nalgebra_glm::Vec3::new(self.scale[0], self.scale[1], self.scale[2]),
}
}
}
impl From<LocalTransform> for SceneMeshInstance {
fn from(transform: LocalTransform) -> Self {
Self {
translation: [
transform.translation.x,
transform.translation.y,
transform.translation.z,
],
rotation: [
transform.rotation.i,
transform.rotation.j,
transform.rotation.k,
transform.rotation.w,
],
scale: [transform.scale.x, transform.scale.y, transform.scale.z],
color: None,
}
}
}