1mod animation_curve;
18mod animation_curve_node;
19mod animation_layer;
20mod animation_stack;
21mod blend_shape;
22mod blend_shape_channel;
23mod camera;
24mod camera_switcher;
25mod cluster;
26mod extract;
27mod global_settings;
28mod layered_texture;
29mod light;
30mod limb_node;
31mod line_geometry;
32mod material;
33mod mesh_geometry;
34mod model;
35mod null_node;
36mod shape_geometry;
37mod skin;
38mod texture;
39mod video;
40
41pub use animation_curve::AnimationCurve;
42pub use animation_curve_node::AnimationCurveNode;
43pub use animation_layer::AnimationLayer;
44pub use animation_stack::AnimationStack;
45pub use blend_shape::BlendShape;
46pub use blend_shape_channel::BlendShapeChannel;
47pub use camera::Camera;
48pub use camera_switcher::CameraSwitcher;
49pub use cluster::Cluster;
50pub use extract::AttrExtractor;
51pub use extract::AttrExtractorExt;
52pub use extract::AttrExtractorParseExt;
53pub use global_settings::OwnedGlobalSettings;
54pub use layered_texture::LayeredTexture;
55pub use light::Light;
56pub use light::LightDecay;
57pub use light::LightType;
58pub use limb_node::LimbNode;
59pub use line_geometry::LineGeometry;
60pub use material::Material;
61pub use mesh_geometry::MeshGeometry;
62pub use model::Model;
63pub use model::ModelRotationOrder;
64pub use model::ModelTransformInheritance;
65pub use null_node::NullNode;
66pub use shape_geometry::ShapeGeometry;
67pub use skin::Skin;
68pub use texture::Texture;
69pub use video::Video;
70
71use crate::OwnedObject;
72
73#[derive(Clone, Copy, Debug, PartialEq)]
75pub enum NodeAttributeRef<'a> {
76 Camera(&'a Camera),
77 CameraSwitcher(&'a CameraSwitcher),
78 Light(&'a Light),
79 NullNode(&'a NullNode),
80 LimbNode(&'a LimbNode),
81 Unknown(&'a OwnedObject),
82}
83
84impl<'a> NodeAttributeRef<'a> {
85 pub fn inner(self) -> &'a OwnedObject {
86 match self {
87 NodeAttributeRef::Camera(x) => x.inner(),
88 NodeAttributeRef::CameraSwitcher(x) => x.inner(),
89 NodeAttributeRef::Light(x) => x.inner(),
90 NodeAttributeRef::NullNode(x) => x.inner(),
91 NodeAttributeRef::LimbNode(x) => x.inner(),
92 NodeAttributeRef::Unknown(x) => x,
93 }
94 }
95}
96
97#[derive(Clone, Copy, Debug, PartialEq)]
99pub enum ModelGeometryRef<'a> {
100 Mesh(&'a MeshGeometry),
101 Line(&'a LineGeometry),
102 Shape(&'a ShapeGeometry),
103 Unknown(&'a OwnedObject),
104}
105
106impl<'a> ModelGeometryRef<'a> {
107 pub fn inner(self) -> &'a OwnedObject {
108 match self {
109 ModelGeometryRef::Mesh(x) => x.inner(),
110 ModelGeometryRef::Line(x) => x.inner(),
111 ModelGeometryRef::Shape(x) => x.inner(),
112 ModelGeometryRef::Unknown(x) => x,
113 }
114 }
115}
116
117pub const MODEL_TYPE_NAME: &str = "Model";
120pub const MODEL_IK_EFFECTOR_CLASS_NAME: &str = "IKEffector";
121pub const MODEL_FK_EFFECTOR_CLASS_NAME: &str = "FKEffector";
122
123pub const GEOMETRY_TYPE_NAME: &str = "Geometry";
124pub const GEOMETRY_MESH_CLASS_NAME: &str = "Mesh";
125pub const GEOMETRY_LINE_CLASS_NAME: &str = "Line";
126pub const GEOMETRY_SHAPE_CLASS_NAME: &str = "Shape";
127
128pub const NODE_ATTRIBUTE_TYPE_NAME: &str = "NodeAttribute";
129pub const NODE_ATTRIBUTE_CAMERA_CLASS_NAME: &str = "Camera";
130pub const NODE_ATTRIBUTE_CAMERA_SWITCHER_CLASS_NAME: &str = "CameraSwitcher";
131pub const NODE_ATTRIBUTE_LIGHT_CLASS_NAME: &str = "Light";
132pub const NODE_ATTRIBUTE_NULL_CLASS_NAME: &str = "Null";
133pub const NODE_ATTRIBUTE_LIMB_NODE_CLASS_NAME: &str = "LimbNode";
134
135pub const MATERIAL_TYPE_NAME: &str = "Material";
136pub const MATERIAL_CLASS_NAME: &str = "Material";
137
138pub const TEXTURE_TYPE_NAME: &str = "Texture";
139pub const TEXTURE_CLASS_NAME: &str = "Texture";
140
141pub const LAYERED_TEXTURE_TYPE_NAME: &str = "LayeredTexture";
142pub const LAYERED_TEXTURE_CLASS_NAME: &str = "LayeredTexture";
143
144pub const VIDEO_TYPE_NAME: &str = "Video";
145pub const VIDEO_CLASS_NAME: &str = "Video";
146
147pub const DEFORMER_TYPE_NAME: &str = "Deformer";
148pub const DEFORMER_CLUSTER_CLASS_NAME: &str = "Cluster";
149pub const DEFORMER_SKIN_CLASS_NAME: &str = "Skin";
150pub const DEFORMER_BLEND_SHAPE_CLASS_NAME: &str = "BlendShape";
151pub const DEFORMER_BLEND_SHAPE_CHANNEL_CLASS_NAME: &str = "BlendShapeChannel";
152
153pub const ANIMATION_STACK_TYPE_NAME: &str = "AnimationStack";
154pub const ANIMATION_STACK_CLASS_NAME: &str = "AnimationStack";
155
156pub const ANIMATION_LAYER_TYPE_NAME: &str = "AnimationLayer";
157pub const ANIMATION_LAYER_CLASS_NAME: &str = "AnimationLayer";
158
159pub const ANIMATION_CURVE_TYPE_NAME: &str = "AnimationCurve";
160pub const ANIMATION_CURVE_CLASS_NAME: &str = "AnimationCurve";
161
162pub const ANIMATION_CURVE_NODE_TYPE_NAME: &str = "AnimationCurveNode";
163pub const ANIMATION_CURVE_NODE_CLASS_NAME: &str = "AnimationCurveNode";
164
165#[derive(Debug, Clone, PartialEq, Eq)]
167pub enum FbxTryFromReason {
168 WrongObjectKind {
170 expected: String,
171 got_type_name: String,
172 got_class_name: String,
173 },
174 MissingAttribute { name: String },
176 InvalidAttributeFormat { name: String, detail: String },
178}
179
180#[derive(Debug, PartialEq)]
182pub struct FbxTypeMismatch {
183 pub object: OwnedObject,
184 pub reason: FbxTryFromReason,
185}
186
187impl FbxTypeMismatch {
188 fn new(o: OwnedObject, reason: FbxTryFromReason) -> FbxTypeMismatch {
189 FbxTypeMismatch { object: o, reason }
190 }
191
192 pub(crate) fn wrong_object_kind(o: OwnedObject, expected: String) -> FbxTypeMismatch {
193 let reason = FbxTryFromReason::WrongObjectKind {
194 expected,
195 got_type_name: o.type_name.clone(),
196 got_class_name: o.class_name.clone(),
197 };
198 FbxTypeMismatch { object: o, reason }
199 }
200}
201
202#[derive(Clone, Copy, Debug, Eq, PartialEq)]
204pub(crate) enum FbxObjectTag {
205 Model,
206 MeshGeometry,
207 LineGeometry,
208 ShapeGeometry,
209 UnknownGeometry,
210 Camera,
211 CameraSwitcher,
212 Light,
213 NullNode,
214 LimbNode,
215 UnknownNodeAttribute,
216 Material,
217 Texture,
218 LayeredTexture,
219 Video,
220 Cluster,
221 Skin,
222 BlendShape,
223 BlendShapeChannel,
224 UnknownDeformer,
225 AnimationStack,
226 AnimationLayer,
227 AnimationCurve,
228 AnimationCurveNode,
229 Unknown,
231}
232
233pub(crate) fn fbx_object_tag(o: &OwnedObject) -> FbxObjectTag {
240 let ty = o.type_name.as_str();
241 let cls = o.class_name.as_str();
242
243 match ty {
244 MODEL_TYPE_NAME => {
245 if cls == MODEL_IK_EFFECTOR_CLASS_NAME || cls == MODEL_FK_EFFECTOR_CLASS_NAME {
246 FbxObjectTag::Unknown
247 } else {
248 FbxObjectTag::Model
249 }
250 }
251
252 GEOMETRY_TYPE_NAME => match cls {
253 GEOMETRY_MESH_CLASS_NAME => FbxObjectTag::MeshGeometry,
254 GEOMETRY_LINE_CLASS_NAME => FbxObjectTag::LineGeometry,
255 GEOMETRY_SHAPE_CLASS_NAME => FbxObjectTag::ShapeGeometry,
256 _ => FbxObjectTag::UnknownGeometry,
257 },
258
259 NODE_ATTRIBUTE_TYPE_NAME => match cls {
260 NODE_ATTRIBUTE_CAMERA_CLASS_NAME => FbxObjectTag::Camera,
261 NODE_ATTRIBUTE_CAMERA_SWITCHER_CLASS_NAME => FbxObjectTag::CameraSwitcher,
262 NODE_ATTRIBUTE_LIGHT_CLASS_NAME => FbxObjectTag::Light,
263 NODE_ATTRIBUTE_NULL_CLASS_NAME => FbxObjectTag::NullNode,
264 NODE_ATTRIBUTE_LIMB_NODE_CLASS_NAME => FbxObjectTag::LimbNode,
265 _ => FbxObjectTag::UnknownNodeAttribute,
266 },
267
268 MATERIAL_TYPE_NAME => FbxObjectTag::Material,
269 TEXTURE_TYPE_NAME => FbxObjectTag::Texture,
270 LAYERED_TEXTURE_TYPE_NAME => FbxObjectTag::LayeredTexture,
271 VIDEO_TYPE_NAME => FbxObjectTag::Video,
272
273 DEFORMER_TYPE_NAME => match cls {
274 DEFORMER_CLUSTER_CLASS_NAME => FbxObjectTag::Cluster,
275 DEFORMER_SKIN_CLASS_NAME => FbxObjectTag::Skin,
276 DEFORMER_BLEND_SHAPE_CLASS_NAME => FbxObjectTag::BlendShape,
277 DEFORMER_BLEND_SHAPE_CHANNEL_CLASS_NAME => FbxObjectTag::BlendShapeChannel,
278 _ => FbxObjectTag::UnknownDeformer,
279 },
280
281 ANIMATION_STACK_TYPE_NAME => FbxObjectTag::AnimationStack,
282 ANIMATION_LAYER_TYPE_NAME => FbxObjectTag::AnimationLayer,
283 ANIMATION_CURVE_TYPE_NAME => FbxObjectTag::AnimationCurve,
284 ANIMATION_CURVE_NODE_TYPE_NAME => FbxObjectTag::AnimationCurveNode,
285
286 _ => FbxObjectTag::Unknown,
287 }
288}
289
290impl TryFrom<OwnedObject> for ClassifiedFbxObject {
291 type Error = FbxTypeMismatch;
292
293 fn try_from(o: OwnedObject) -> Result<Self, Self::Error> {
294 match fbx_object_tag(&o) {
295 FbxObjectTag::Model => Ok(ClassifiedFbxObject::Model(Model::try_from(o)?)),
296 FbxObjectTag::MeshGeometry => Ok(ClassifiedFbxObject::MeshGeometry(
297 MeshGeometry::try_from(o)?,
298 )),
299 FbxObjectTag::LineGeometry => Ok(ClassifiedFbxObject::LineGeometry(
300 LineGeometry::try_from(o)?,
301 )),
302 FbxObjectTag::ShapeGeometry => Ok(ClassifiedFbxObject::ShapeGeometry(
303 ShapeGeometry::try_from(o)?,
304 )),
305 FbxObjectTag::UnknownGeometry => Ok(ClassifiedFbxObject::UnknownGeometry(o)),
306 FbxObjectTag::Camera => Ok(ClassifiedFbxObject::Camera(Camera::try_from(o)?)),
307 FbxObjectTag::CameraSwitcher => Ok(ClassifiedFbxObject::CameraSwitcher(
308 CameraSwitcher::try_from(o)?,
309 )),
310 FbxObjectTag::Light => Ok(ClassifiedFbxObject::Light(Light::try_from(o)?)),
311 FbxObjectTag::NullNode => Ok(ClassifiedFbxObject::NullNode(NullNode::try_from(o)?)),
312 FbxObjectTag::LimbNode => Ok(ClassifiedFbxObject::LimbNode(LimbNode::try_from(o)?)),
313 FbxObjectTag::UnknownNodeAttribute => Ok(ClassifiedFbxObject::UnknownNodeAttribute(o)),
314 FbxObjectTag::Material => Ok(ClassifiedFbxObject::Material(Material::try_from(o)?)),
315 FbxObjectTag::Texture => Ok(ClassifiedFbxObject::Texture(Texture::try_from(o)?)),
316 FbxObjectTag::LayeredTexture => Ok(ClassifiedFbxObject::LayeredTexture(
317 LayeredTexture::try_from(o)?,
318 )),
319 FbxObjectTag::Video => Ok(ClassifiedFbxObject::Video(Video::try_from(o)?)),
320 FbxObjectTag::Cluster => Ok(ClassifiedFbxObject::Cluster(Cluster::try_from(o)?)),
321 FbxObjectTag::Skin => Ok(ClassifiedFbxObject::Skin(Skin::try_from(o)?)),
322 FbxObjectTag::BlendShape => {
323 Ok(ClassifiedFbxObject::BlendShape(BlendShape::try_from(o)?))
324 }
325 FbxObjectTag::BlendShapeChannel => Ok(ClassifiedFbxObject::BlendShapeChannel(
326 BlendShapeChannel::try_from(o)?,
327 )),
328 FbxObjectTag::UnknownDeformer => Ok(ClassifiedFbxObject::UnknownDeformer(o)),
329 FbxObjectTag::AnimationStack => Ok(ClassifiedFbxObject::AnimationStack(
330 AnimationStack::try_from(o)?,
331 )),
332 FbxObjectTag::AnimationLayer => Ok(ClassifiedFbxObject::AnimationLayer(
333 AnimationLayer::try_from(o)?,
334 )),
335 FbxObjectTag::AnimationCurve => Ok(ClassifiedFbxObject::AnimationCurve(
336 AnimationCurve::try_from(o)?,
337 )),
338 FbxObjectTag::AnimationCurveNode => Ok(ClassifiedFbxObject::AnimationCurveNode(
339 AnimationCurveNode::try_from(o)?,
340 )),
341 FbxObjectTag::Unknown => Ok(ClassifiedFbxObject::Unknown(o)),
342 }
343 }
344}
345
346#[derive(Debug, PartialEq)]
350pub enum ClassifiedFbxObject {
351 Model(Model),
352 MeshGeometry(MeshGeometry),
353 LineGeometry(LineGeometry),
354 ShapeGeometry(ShapeGeometry),
355 Camera(Camera),
356 CameraSwitcher(CameraSwitcher),
357 Light(Light),
358 NullNode(NullNode),
359 LimbNode(LimbNode),
360 Material(Material),
361 Texture(Texture),
362 LayeredTexture(LayeredTexture),
363 Video(Video),
364 Cluster(Cluster),
365 Skin(Skin),
366 BlendShape(BlendShape),
367 BlendShapeChannel(BlendShapeChannel),
368 AnimationStack(AnimationStack),
369 AnimationLayer(AnimationLayer),
370 AnimationCurve(AnimationCurve),
371 AnimationCurveNode(AnimationCurveNode),
372 UnknownDeformer(OwnedObject),
374 UnknownGeometry(OwnedObject),
376 UnknownNodeAttribute(OwnedObject),
378 Unknown(OwnedObject),
380}
381
382impl ClassifiedFbxObject {
383 pub fn object_index(&self) -> u64 {
384 self.inner().object_index
385 }
386
387 pub fn inner(&self) -> &OwnedObject {
388 match self {
389 ClassifiedFbxObject::Model(x) => x.inner(),
390 ClassifiedFbxObject::MeshGeometry(x) => x.inner(),
391 ClassifiedFbxObject::LineGeometry(x) => x.inner(),
392 ClassifiedFbxObject::ShapeGeometry(x) => x.inner(),
393 ClassifiedFbxObject::Camera(x) => x.inner(),
394 ClassifiedFbxObject::CameraSwitcher(x) => x.inner(),
395 ClassifiedFbxObject::Light(x) => x.inner(),
396 ClassifiedFbxObject::NullNode(x) => x.inner(),
397 ClassifiedFbxObject::LimbNode(x) => x.inner(),
398 ClassifiedFbxObject::Material(x) => x.inner(),
399 ClassifiedFbxObject::Texture(x) => x.inner(),
400 ClassifiedFbxObject::LayeredTexture(x) => x.inner(),
401 ClassifiedFbxObject::Video(x) => x.inner(),
402 ClassifiedFbxObject::Cluster(x) => x.inner(),
403 ClassifiedFbxObject::Skin(x) => x.inner(),
404 ClassifiedFbxObject::BlendShape(x) => x.inner(),
405 ClassifiedFbxObject::BlendShapeChannel(x) => x.inner(),
406 ClassifiedFbxObject::AnimationStack(x) => x.inner(),
407 ClassifiedFbxObject::AnimationLayer(x) => x.inner(),
408 ClassifiedFbxObject::AnimationCurve(x) => x.inner(),
409 ClassifiedFbxObject::AnimationCurveNode(x) => x.inner(),
410 ClassifiedFbxObject::UnknownDeformer(o) => o,
411 ClassifiedFbxObject::UnknownGeometry(o) => o,
412 ClassifiedFbxObject::UnknownNodeAttribute(o) => o,
413 ClassifiedFbxObject::Unknown(o) => o,
414 }
415 }
416}