Skip to main content

gltf_kun/graph/gltf/primitive/
morph_target.rs

1use gltf::Semantic;
2use petgraph::{Direction, graph::NodeIndex, visit::EdgeRef};
3use thiserror::Error;
4
5use crate::graph::{
6    Edge, Extensions, Graph, GraphNodeEdges, Weight,
7    gltf::{Accessor, GltfEdge, GltfWeight, accessor::iter::AccessorIterCreateError},
8};
9
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub enum MorphTargetEdge {
12    Attribute(Semantic),
13}
14
15impl<'a> TryFrom<&'a Edge> for &'a MorphTargetEdge {
16    type Error = ();
17    fn try_from(value: &'a Edge) -> Result<Self, Self::Error> {
18        match value {
19            Edge::Gltf(GltfEdge::MorphTarget(edge)) => Ok(edge),
20            _ => Err(()),
21        }
22    }
23}
24
25impl From<MorphTargetEdge> for Edge {
26    fn from(edge: MorphTargetEdge) -> Self {
27        Self::Gltf(GltfEdge::MorphTarget(edge))
28    }
29}
30
31#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
32pub struct MorphTarget(pub NodeIndex);
33
34impl From<NodeIndex> for MorphTarget {
35    fn from(index: NodeIndex) -> Self {
36        Self(index)
37    }
38}
39
40impl From<MorphTarget> for NodeIndex {
41    fn from(primitive: MorphTarget) -> Self {
42        primitive.0
43    }
44}
45
46impl GraphNodeEdges for MorphTarget {}
47impl Extensions for MorphTarget {}
48
49impl MorphTarget {
50    pub fn new(graph: &mut Graph) -> Self {
51        Self(graph.add_node(Weight::Gltf(GltfWeight::MorphTarget)))
52    }
53
54    pub fn attributes(&self, graph: &Graph) -> Vec<(Semantic, Accessor)> {
55        graph
56            .edges_directed(self.0, Direction::Outgoing)
57            .filter_map(|edge| {
58                if let Edge::Gltf(GltfEdge::MorphTarget(MorphTargetEdge::Attribute(semantic))) =
59                    edge.weight()
60                {
61                    Some((semantic.clone(), Accessor(edge.target())))
62                } else {
63                    None
64                }
65            })
66            .collect()
67    }
68    pub fn attribute(&self, graph: &Graph, semantic: Semantic) -> Option<Accessor> {
69        self.find_edge_target(graph, &MorphTargetEdge::Attribute(semantic))
70    }
71    pub fn set_attribute(&self, graph: &mut Graph, semantic: Semantic, accessor: Option<Accessor>) {
72        self.set_edge_target(graph, MorphTargetEdge::Attribute(semantic), accessor);
73    }
74}
75
76#[derive(Debug, Error)]
77pub enum MorphTargetIterError {
78    #[error(transparent)]
79    AccessorIterCreateError(#[from] AccessorIterCreateError),
80}