fbx_dom/objects/
animation_layer.rs1use std::collections::HashMap;
7use std::convert::TryFrom;
8
9use crate::Property;
10use crate::{OwnedDocument, OwnedObject};
11
12use super::{AnimationCurveNode, FbxObjectTag, FbxTypeMismatch, fbx_object_tag};
13
14#[derive(Debug, PartialEq)]
15pub struct AnimationLayer(pub OwnedObject);
16
17impl AnimationLayer {
18 pub fn inner(&self) -> &OwnedObject {
19 &self.0
20 }
21
22 pub fn into_inner(self) -> OwnedObject {
23 self.0
24 }
25
26 pub fn properties(&self) -> &HashMap<String, Property> {
27 &self.0.properties
28 }
29
30 pub fn property(&self, name: &str) -> Option<&Property> {
31 self.0.properties.get(name)
32 }
33
34 pub fn weight(&self) -> f32 {
36 match self.property("Weight") {
37 Some(Property::Float(v)) => *v,
38 _ => 100.0,
39 }
40 }
41
42 pub fn mute(&self) -> bool {
43 match self.property("Mute") {
44 Some(Property::Bool(v)) => *v,
45 _ => false,
46 }
47 }
48
49 pub fn solo(&self) -> bool {
50 match self.property("Solo") {
51 Some(Property::Bool(v)) => *v,
52 _ => false,
53 }
54 }
55
56 pub fn get_animation_curve_nodes<'a>(
58 &'a self,
59 document: &'a OwnedDocument,
60 ) -> Vec<&'a AnimationCurveNode> {
61 let layer_id = self.inner().object_index;
62 document
63 .animation_curve_nodes
64 .iter()
65 .filter(|node| node.inner().connected_object_ids.contains(&layer_id))
66 .collect()
67 }
68}
69
70impl TryFrom<OwnedObject> for AnimationLayer {
71 type Error = FbxTypeMismatch;
72
73 fn try_from(o: OwnedObject) -> Result<Self, Self::Error> {
74 match fbx_object_tag(&o) {
75 FbxObjectTag::AnimationLayer => Ok(AnimationLayer(o)),
76 _ => Err(FbxTypeMismatch::wrong_object_kind(
77 o,
78 "AnimationLayer".to_string(),
79 )),
80 }
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use std::collections::HashMap;
87 use std::convert::TryFrom;
88
89 use crate::objects::{
90 ANIMATION_CURVE_NODE_CLASS_NAME, ANIMATION_CURVE_NODE_TYPE_NAME,
91 ANIMATION_LAYER_CLASS_NAME, ANIMATION_LAYER_TYPE_NAME, AnimationCurveNode,
92 };
93 use crate::{OwnedDocument, OwnedObject, Property};
94
95 use super::AnimationLayer;
96
97 #[test]
98 fn layer_weight_mute_solo_defaults_and_properties() {
99 let o_empty = OwnedObject {
100 object_index: 3,
101 name: "AnimLayer::L0".into(),
102 type_name: ANIMATION_LAYER_TYPE_NAME.into(),
103 class_name: ANIMATION_LAYER_CLASS_NAME.into(),
104 properties: HashMap::new(),
105 attributes: HashMap::new(),
106 connected_object_ids: vec![],
107 object_property_targets: vec![],
108 pp_property_targets: HashMap::new(),
109 };
110 let layer = AnimationLayer::try_from(o_empty).unwrap();
111 assert_eq!(layer.weight(), 100.0);
112 assert_eq!(layer.mute(), false);
113 assert_eq!(layer.solo(), false);
114
115 let mut properties = HashMap::new();
116 properties.insert("Weight".to_string(), Property::Float(50.0));
117 properties.insert("Mute".to_string(), Property::Bool(true));
118 properties.insert("Solo".to_string(), Property::Bool(true));
119 let o = OwnedObject {
120 object_index: 4,
121 name: "AnimLayer::L1".into(),
122 type_name: ANIMATION_LAYER_TYPE_NAME.into(),
123 class_name: ANIMATION_LAYER_CLASS_NAME.into(),
124 properties,
125 attributes: HashMap::new(),
126 connected_object_ids: vec![],
127 object_property_targets: vec![],
128 pp_property_targets: HashMap::new(),
129 };
130 let layer = AnimationLayer::try_from(o).unwrap();
131 assert_eq!(layer.weight(), 50.0);
132 assert_eq!(layer.mute(), true);
133 assert_eq!(layer.solo(), true);
134 }
135
136 #[test]
137 fn resolves_animation_curve_node_links() {
138 let layer = AnimationLayer::try_from(OwnedObject {
139 object_index: 2000,
140 name: "AnimLayer::Layer0".into(),
141 type_name: ANIMATION_LAYER_TYPE_NAME.into(),
142 class_name: ANIMATION_LAYER_CLASS_NAME.into(),
143 properties: HashMap::new(),
144 attributes: HashMap::new(),
145 connected_object_ids: vec![],
146 object_property_targets: vec![],
147 pp_property_targets: HashMap::new(),
148 })
149 .unwrap();
150 let node = AnimationCurveNode::try_from(OwnedObject {
151 object_index: 2001,
152 name: "AnimCurveNode::T".into(),
153 type_name: ANIMATION_CURVE_NODE_TYPE_NAME.into(),
154 class_name: ANIMATION_CURVE_NODE_CLASS_NAME.into(),
155 properties: HashMap::new(),
156 attributes: HashMap::new(),
157 connected_object_ids: vec![2000],
158 object_property_targets: vec![],
159 pp_property_targets: HashMap::new(),
160 })
161 .unwrap();
162 let mut owned = OwnedDocument::default();
163 owned.animation_curve_nodes = vec![node];
164 let links = layer.get_animation_curve_nodes(&owned);
165 assert_eq!(links.len(), 1);
166 assert_eq!(links[0].inner().object_index, 2001);
167 }
168}