fbxcel_dom/v7400/data/mesh/layer/
normal.rs1use anyhow::{bail, format_err, Error};
4use mint::Vector3;
5
6use crate::v7400::data::mesh::{
7 layer::{
8 LayerContentIndex, LayerElementHandle, MappingMode, ReferenceInformation, ReferenceMode,
9 },
10 TriangleVertexIndex, TriangleVertices,
11};
12
13#[derive(Debug, Clone, Copy)]
15pub struct LayerElementNormalHandle<'a> {
16 node: LayerElementHandle<'a>,
18}
19
20impl<'a> LayerElementNormalHandle<'a> {
21 pub fn new(node: LayerElementHandle<'a>) -> Self {
23 Self { node }
24 }
25
26 pub fn normals(&self) -> Result<Normals<'a>, Error> {
28 Normals::new(self)
29 }
30
31 fn normals_vec3_slice(&self) -> Result<&'a [f64], Error> {
33 self.children_by_name("Normals")
34 .next()
35 .ok_or_else(|| format_err!("No `Normals` found for `LayerElementNormal` node"))?
36 .attributes()
37 .get(0)
38 .ok_or_else(|| format_err!("No attributes found for `Normals` node"))?
39 .get_arr_f64_or_type()
40 .map_err(|ty| format_err!("Expected `[f64]` as normals, but got {:?}", ty))
41 }
42
43 fn normals_norm_slice(&self) -> Result<Option<&'a [f64]>, Error> {
49 let normals_w_node = match self.children_by_name("NormalsW").next() {
50 Some(v) => v,
51 None => return Ok(None),
52 };
53 normals_w_node
54 .attributes()
55 .get(0)
56 .ok_or_else(|| format_err!("No attributes found for `NormalsW` node"))?
57 .get_arr_f64_or_type()
58 .map(Some)
59 .map_err(|ty| format_err!("Expected `[f64]` as normals W, but got {:?}", ty))
60 }
61}
62
63impl<'a> std::ops::Deref for LayerElementNormalHandle<'a> {
64 type Target = LayerElementHandle<'a>;
65
66 fn deref(&self) -> &Self::Target {
67 &self.node
68 }
69}
70
71#[derive(Debug, Clone, Copy)]
73pub struct Normals<'a> {
74 normals: &'a [f64],
76 #[allow(dead_code)] normals_w: Option<&'a [f64]>,
79 mapping_mode: MappingMode,
81}
82
83impl<'a> Normals<'a> {
84 fn new(handle: &LayerElementNormalHandle<'a>) -> Result<Self, Error> {
86 let normals = handle.normals_vec3_slice()?;
87 let normals_w = handle.normals_norm_slice()?;
88 let mapping_mode = handle.mapping_mode()?;
89 let reference_mode = handle.reference_mode()?;
90 if reference_mode != ReferenceMode::Direct {
91 bail!(
92 "Unsupported reference mode for normals: {:?}",
93 reference_mode
94 );
95 }
96 Ok(Self {
97 normals,
98 normals_w,
99 mapping_mode,
100 })
101 }
102
103 pub fn normal(
106 &self,
107 tris: &TriangleVertices<'a>,
108 tri_vi: TriangleVertexIndex,
109 ) -> Result<Vector3<f64>, Error> {
110 let i = LayerContentIndex::control_point_data_from_triangle_vertices(
111 ReferenceInformation::Direct,
112 self.mapping_mode,
113 tris,
114 self.normals.len() / 3,
115 tri_vi,
116 )?;
117 Ok(Vector3::from_slice(&self.normals[(i.get() * 3)..]))
118 }
119}