use crate::application_io::{ImageTexture, TextureFrameTable}; use crate::raster::image::{Image, ImageFrameTable}; use crate::raster::Pixel; use crate::transform::{Transform, TransformMut}; use crate::vector::{InstanceId, VectorData, VectorDataTable}; use crate::{AlphaBlending, GraphicElement, GraphicGroup, GraphicGroupTable, RasterFrame}; use dyn_any::StaticType; use glam::{DAffine2, DVec2}; use std::hash::Hash; #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct Instances where T: Into + StaticType + 'static, { id: Vec, #[serde(alias = "instances")] instance: Vec, #[serde(default = "one_daffine2_default")] transform: Vec, #[serde(default = "one_alpha_blending_default")] alpha_blending: Vec, } impl + StaticType + 'static> Instances { pub fn new(instance: T) -> Self { Self { id: vec![InstanceId::generate()], instance: vec![instance], transform: vec![DAffine2::IDENTITY], alpha_blending: vec![AlphaBlending::default()], } } pub fn one_instance(&self) -> Instance { Instance { id: self.id.first().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", self.instance.len())), instance: self.instance.first().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", self.instance.len())), transform: self.transform.first().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", self.instance.len())), alpha_blending: self.alpha_blending.first().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", self.instance.len())), } } pub fn one_instance_mut(&mut self) -> InstanceMut { let length = self.instance.len(); InstanceMut { id: self.id.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", length)), instance: self.instance.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", length)), transform: self.transform.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", length)), alpha_blending: self.alpha_blending.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", length)), } } pub fn instances(&self) -> impl Iterator> { assert!(self.instance.len() == 1, "ONE INSTANCE EXPECTED, FOUND {} (instances)", self.instance.len()); self.id .iter() .zip(self.instance.iter()) .zip(self.transform.iter()) .zip(self.alpha_blending.iter()) .map(|(((id, instance), transform), alpha_blending)| Instance { id, instance, transform, alpha_blending, }) } pub fn instances_mut(&mut self) -> impl Iterator> { assert!(self.instance.len() == 1, "ONE INSTANCE EXPECTED, FOUND {} (instances_mut)", self.instance.len()); self.id .iter_mut() .zip(self.instance.iter_mut()) .zip(self.transform.iter_mut()) .zip(self.alpha_blending.iter_mut()) .map(|(((id, instance), transform), alpha_blending)| InstanceMut { id, instance, transform, alpha_blending, }) } } impl + Default + Hash + StaticType + 'static> Default for Instances { fn default() -> Self { Self::new(T::default()) } } impl + Hash + StaticType + 'static> core::hash::Hash for Instances { fn hash(&self, state: &mut H) { self.id.hash(state); for instance in &self.instance { instance.hash(state); } } } impl + PartialEq + StaticType + 'static> PartialEq for Instances { fn eq(&self, other: &Self) -> bool { self.id == other.id && self.instance.len() == other.instance.len() && { self.instance.iter().zip(other.instance.iter()).all(|(a, b)| a == b) } } } unsafe impl + StaticType + 'static> dyn_any::StaticType for Instances { type Static = Instances; } fn one_daffine2_default() -> Vec { vec![DAffine2::IDENTITY] } fn one_alpha_blending_default() -> Vec { vec![AlphaBlending::default()] } #[derive(Copy, Clone, Debug)] pub struct Instance<'a, T> { pub id: &'a InstanceId, pub instance: &'a T, pub transform: &'a DAffine2, pub alpha_blending: &'a AlphaBlending, } #[derive(Debug)] pub struct InstanceMut<'a, T> { pub id: &'a mut InstanceId, pub instance: &'a mut T, pub transform: &'a mut DAffine2, pub alpha_blending: &'a mut AlphaBlending, } // GRAPHIC ELEMENT impl Transform for GraphicElement { fn transform(&self) -> DAffine2 { match self { GraphicElement::GraphicGroup(group) => group.transform(), GraphicElement::VectorData(vector_data) => vector_data.transform(), GraphicElement::RasterFrame(frame) => frame.transform(), } } } impl TransformMut for GraphicElement { fn transform_mut(&mut self) -> &mut DAffine2 { match self { GraphicElement::GraphicGroup(group) => group.transform_mut(), GraphicElement::VectorData(vector_data) => vector_data.transform_mut(), GraphicElement::RasterFrame(frame) => frame.transform_mut(), } } } // GRAPHIC GROUP impl Transform for Instance<'_, GraphicGroup> { fn transform(&self) -> DAffine2 { *self.transform } } impl Transform for InstanceMut<'_, GraphicGroup> { fn transform(&self) -> DAffine2 { *self.transform } } impl TransformMut for InstanceMut<'_, GraphicGroup> { fn transform_mut(&mut self) -> &mut DAffine2 { self.transform } } // GRAPHIC GROUP TABLE impl Transform for GraphicGroupTable { fn transform(&self) -> DAffine2 { self.one_instance().transform() } } impl TransformMut for GraphicGroupTable { fn transform_mut(&mut self) -> &mut DAffine2 { self.transform.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED")) } } // IMAGE TEXTURE impl Transform for Instance<'_, ImageTexture> { fn transform(&self) -> DAffine2 { *self.transform } } impl Transform for InstanceMut<'_, ImageTexture> { fn transform(&self) -> DAffine2 { *self.transform } } impl TransformMut for InstanceMut<'_, ImageTexture> { fn transform_mut(&mut self) -> &mut DAffine2 { self.transform } } // TEXTURE FRAME TABLE impl Transform for TextureFrameTable { fn transform(&self) -> DAffine2 { self.one_instance().transform() } } impl TransformMut for TextureFrameTable { fn transform_mut(&mut self) -> &mut DAffine2 { self.transform.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED")) } } // IMAGE impl Transform for Instance<'_, Image

> { fn transform(&self) -> DAffine2 { *self.transform } fn local_pivot(&self, pivot: DVec2) -> DVec2 { self.transform.transform_point2(pivot) } } impl Transform for InstanceMut<'_, Image

> { fn transform(&self) -> DAffine2 { *self.transform } fn local_pivot(&self, pivot: DVec2) -> DVec2 { self.transform.transform_point2(pivot) } } impl TransformMut for InstanceMut<'_, Image

> { fn transform_mut(&mut self) -> &mut DAffine2 { self.transform } } // IMAGE FRAME TABLE impl Transform for ImageFrameTable

where P: dyn_any::StaticType, P::Static: Pixel, GraphicElement: From>, { fn transform(&self) -> DAffine2 { self.one_instance().transform() } } impl TransformMut for ImageFrameTable

where P: dyn_any::StaticType, P::Static: Pixel, GraphicElement: From>, { fn transform_mut(&mut self) -> &mut DAffine2 { self.transform.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED")) } } // VECTOR DATA impl Transform for Instance<'_, VectorData> { fn transform(&self) -> DAffine2 { *self.transform } fn local_pivot(&self, pivot: DVec2) -> DVec2 { self.transform.transform_point2(self.instance.layerspace_pivot(pivot)) } } impl Transform for InstanceMut<'_, VectorData> { fn transform(&self) -> DAffine2 { *self.transform } fn local_pivot(&self, pivot: DVec2) -> DVec2 { self.transform.transform_point2(self.instance.layerspace_pivot(pivot)) } } impl TransformMut for InstanceMut<'_, VectorData> { fn transform_mut(&mut self) -> &mut DAffine2 { self.transform } } // VECTOR DATA TABLE impl Transform for VectorDataTable { fn transform(&self) -> DAffine2 { self.one_instance().transform() } } impl TransformMut for VectorDataTable { fn transform_mut(&mut self) -> &mut DAffine2 { self.transform.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED")) } } // RASTER FRAME impl Transform for RasterFrame { fn transform(&self) -> DAffine2 { match self { RasterFrame::ImageFrame(image_frame) => image_frame.transform(), RasterFrame::TextureFrame(texture_frame) => texture_frame.transform(), } } } impl TransformMut for RasterFrame { fn transform_mut(&mut self) -> &mut DAffine2 { match self { RasterFrame::ImageFrame(image_frame) => image_frame.transform.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED")), RasterFrame::TextureFrame(texture_frame) => texture_frame.transform.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED")), } } }