re_types/archetypes/
instance_poses3d.rs

1// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/rust/api.rs
2// Based on "crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs".
3
4#![allow(unused_imports)]
5#![allow(unused_parens)]
6#![allow(clippy::clone_on_copy)]
7#![allow(clippy::cloned_instead_of_copied)]
8#![allow(clippy::map_flatten)]
9#![allow(clippy::needless_question_mark)]
10#![allow(clippy::new_without_default)]
11#![allow(clippy::redundant_closure)]
12#![allow(clippy::too_many_arguments)]
13#![allow(clippy::too_many_lines)]
14
15use ::re_types_core::try_serialize_field;
16use ::re_types_core::SerializationResult;
17use ::re_types_core::{ComponentBatch as _, SerializedComponentBatch};
18use ::re_types_core::{ComponentDescriptor, ComponentName};
19use ::re_types_core::{DeserializationError, DeserializationResult};
20
21/// **Archetype**: One or more transforms between the current entity and its parent. Unlike [`archetypes::Transform3D`][crate::archetypes::Transform3D], it is *not* propagated in the transform hierarchy.
22///
23/// If both [`archetypes::InstancePoses3D`][crate::archetypes::InstancePoses3D] and [`archetypes::Transform3D`][crate::archetypes::Transform3D] are present,
24/// first the tree propagating [`archetypes::Transform3D`][crate::archetypes::Transform3D] is applied, then [`archetypes::InstancePoses3D`][crate::archetypes::InstancePoses3D].
25///
26/// From the point of view of the entity's coordinate system,
27/// all components are applied in the inverse order they are listed here.
28/// E.g. if both a translation and a max3x3 transform are present,
29/// the 3x3 matrix is applied first, followed by the translation.
30///
31/// Currently, many visualizers support only a single instance transform per entity.
32/// Check archetype documentations for details - if not otherwise specified, only the first instance transform is applied.
33/// Some visualizers like the mesh visualizer used for [`archetypes::Mesh3D`][crate::archetypes::Mesh3D],
34/// will draw an object for every pose, a behavior also known as "instancing".
35///
36/// ## Example
37///
38/// ### Regular & instance transforms in tandem
39/// ```ignore
40/// use rerun::{
41///     demo_util::grid,
42///     external::{anyhow, glam},
43/// };
44///
45/// fn main() -> anyhow::Result<()> {
46///     let rec =
47///         rerun::RecordingStreamBuilder::new("rerun_example_instance_pose3d_combined").spawn()?;
48///
49///     rec.set_time_sequence("frame", 0);
50///
51///     // Log a box and points further down in the hierarchy.
52///     rec.log(
53///         "world/box",
54///         &rerun::Boxes3D::from_half_sizes([[1.0, 1.0, 1.0]]),
55///     )?;
56///     rec.log(
57///         "world/box/points",
58///         &rerun::Points3D::new(grid(glam::Vec3::splat(-10.0), glam::Vec3::splat(10.0), 10)),
59///     )?;
60///
61///     for i in 0..180 {
62///         rec.set_time_sequence("frame", i);
63///
64///         // Log a regular transform which affects both the box and the points.
65///         rec.log(
66///             "world/box",
67///             &rerun::Transform3D::from_rotation(rerun::RotationAxisAngle {
68///                 axis: [0.0, 0.0, 1.0].into(),
69///                 angle: rerun::Angle::from_degrees(i as f32 * 2.0),
70///             }),
71///         )?;
72///
73///         // Log an instance pose which affects only the box.
74///         let translation = [0.0, 0.0, (i as f32 * 0.1 - 5.0).abs() - 5.0];
75///         rec.log(
76///             "world/box",
77///             &rerun::InstancePoses3D::new().with_translations([translation]),
78///         )?;
79///     }
80///
81///     Ok(())
82/// }
83/// ```
84/// <center>
85/// <picture>
86///   <source media="(max-width: 480px)" srcset="https://static.rerun.io/leaf_transform3d/41674f0082d6de489f8a1cd1583f60f6b5820ddf/480w.png">
87///   <source media="(max-width: 768px)" srcset="https://static.rerun.io/leaf_transform3d/41674f0082d6de489f8a1cd1583f60f6b5820ddf/768w.png">
88///   <source media="(max-width: 1024px)" srcset="https://static.rerun.io/leaf_transform3d/41674f0082d6de489f8a1cd1583f60f6b5820ddf/1024w.png">
89///   <source media="(max-width: 1200px)" srcset="https://static.rerun.io/leaf_transform3d/41674f0082d6de489f8a1cd1583f60f6b5820ddf/1200w.png">
90///   <img src="https://static.rerun.io/leaf_transform3d/41674f0082d6de489f8a1cd1583f60f6b5820ddf/full.png" width="640">
91/// </picture>
92/// </center>
93#[derive(Clone, Debug, PartialEq, Default)]
94pub struct InstancePoses3D {
95    /// Translation vectors.
96    pub translations: Option<SerializedComponentBatch>,
97
98    /// Rotations via axis + angle.
99    pub rotation_axis_angles: Option<SerializedComponentBatch>,
100
101    /// Rotations via quaternion.
102    pub quaternions: Option<SerializedComponentBatch>,
103
104    /// Scaling factors.
105    pub scales: Option<SerializedComponentBatch>,
106
107    /// 3x3 transformation matrices.
108    pub mat3x3: Option<SerializedComponentBatch>,
109}
110
111impl InstancePoses3D {
112    /// Returns the [`ComponentDescriptor`] for [`Self::translations`].
113    #[inline]
114    pub fn descriptor_translations() -> ComponentDescriptor {
115        ComponentDescriptor {
116            archetype_name: Some("rerun.archetypes.InstancePoses3D".into()),
117            component_name: "rerun.components.PoseTranslation3D".into(),
118            archetype_field_name: Some("translations".into()),
119        }
120    }
121
122    /// Returns the [`ComponentDescriptor`] for [`Self::rotation_axis_angles`].
123    #[inline]
124    pub fn descriptor_rotation_axis_angles() -> ComponentDescriptor {
125        ComponentDescriptor {
126            archetype_name: Some("rerun.archetypes.InstancePoses3D".into()),
127            component_name: "rerun.components.PoseRotationAxisAngle".into(),
128            archetype_field_name: Some("rotation_axis_angles".into()),
129        }
130    }
131
132    /// Returns the [`ComponentDescriptor`] for [`Self::quaternions`].
133    #[inline]
134    pub fn descriptor_quaternions() -> ComponentDescriptor {
135        ComponentDescriptor {
136            archetype_name: Some("rerun.archetypes.InstancePoses3D".into()),
137            component_name: "rerun.components.PoseRotationQuat".into(),
138            archetype_field_name: Some("quaternions".into()),
139        }
140    }
141
142    /// Returns the [`ComponentDescriptor`] for [`Self::scales`].
143    #[inline]
144    pub fn descriptor_scales() -> ComponentDescriptor {
145        ComponentDescriptor {
146            archetype_name: Some("rerun.archetypes.InstancePoses3D".into()),
147            component_name: "rerun.components.PoseScale3D".into(),
148            archetype_field_name: Some("scales".into()),
149        }
150    }
151
152    /// Returns the [`ComponentDescriptor`] for [`Self::mat3x3`].
153    #[inline]
154    pub fn descriptor_mat3x3() -> ComponentDescriptor {
155        ComponentDescriptor {
156            archetype_name: Some("rerun.archetypes.InstancePoses3D".into()),
157            component_name: "rerun.components.PoseTransformMat3x3".into(),
158            archetype_field_name: Some("mat3x3".into()),
159        }
160    }
161
162    /// Returns the [`ComponentDescriptor`] for the associated indicator component.
163    #[inline]
164    pub fn descriptor_indicator() -> ComponentDescriptor {
165        ComponentDescriptor {
166            archetype_name: Some("rerun.archetypes.InstancePoses3D".into()),
167            component_name: "rerun.components.InstancePoses3DIndicator".into(),
168            archetype_field_name: None,
169        }
170    }
171}
172
173static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> =
174    once_cell::sync::Lazy::new(|| []);
175
176static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> =
177    once_cell::sync::Lazy::new(|| [InstancePoses3D::descriptor_indicator()]);
178
179static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> =
180    once_cell::sync::Lazy::new(|| {
181        [
182            InstancePoses3D::descriptor_translations(),
183            InstancePoses3D::descriptor_rotation_axis_angles(),
184            InstancePoses3D::descriptor_quaternions(),
185            InstancePoses3D::descriptor_scales(),
186            InstancePoses3D::descriptor_mat3x3(),
187        ]
188    });
189
190static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 6usize]> =
191    once_cell::sync::Lazy::new(|| {
192        [
193            InstancePoses3D::descriptor_indicator(),
194            InstancePoses3D::descriptor_translations(),
195            InstancePoses3D::descriptor_rotation_axis_angles(),
196            InstancePoses3D::descriptor_quaternions(),
197            InstancePoses3D::descriptor_scales(),
198            InstancePoses3D::descriptor_mat3x3(),
199        ]
200    });
201
202impl InstancePoses3D {
203    /// The total number of components in the archetype: 0 required, 1 recommended, 5 optional
204    pub const NUM_COMPONENTS: usize = 6usize;
205}
206
207/// Indicator component for the [`InstancePoses3D`] [`::re_types_core::Archetype`]
208pub type InstancePoses3DIndicator = ::re_types_core::GenericIndicatorComponent<InstancePoses3D>;
209
210impl ::re_types_core::Archetype for InstancePoses3D {
211    type Indicator = InstancePoses3DIndicator;
212
213    #[inline]
214    fn name() -> ::re_types_core::ArchetypeName {
215        "rerun.archetypes.InstancePoses3D".into()
216    }
217
218    #[inline]
219    fn display_name() -> &'static str {
220        "Instance poses 3D"
221    }
222
223    #[inline]
224    fn indicator() -> SerializedComponentBatch {
225        #[allow(clippy::unwrap_used)]
226        InstancePoses3DIndicator::DEFAULT.serialized().unwrap()
227    }
228
229    #[inline]
230    fn required_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
231        REQUIRED_COMPONENTS.as_slice().into()
232    }
233
234    #[inline]
235    fn recommended_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
236        RECOMMENDED_COMPONENTS.as_slice().into()
237    }
238
239    #[inline]
240    fn optional_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
241        OPTIONAL_COMPONENTS.as_slice().into()
242    }
243
244    #[inline]
245    fn all_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
246        ALL_COMPONENTS.as_slice().into()
247    }
248
249    #[inline]
250    fn from_arrow_components(
251        arrow_data: impl IntoIterator<Item = (ComponentDescriptor, arrow::array::ArrayRef)>,
252    ) -> DeserializationResult<Self> {
253        re_tracing::profile_function!();
254        use ::re_types_core::{Loggable as _, ResultExt as _};
255        let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect();
256        let translations = arrays_by_descr
257            .get(&Self::descriptor_translations())
258            .map(|array| {
259                SerializedComponentBatch::new(array.clone(), Self::descriptor_translations())
260            });
261        let rotation_axis_angles = arrays_by_descr
262            .get(&Self::descriptor_rotation_axis_angles())
263            .map(|array| {
264                SerializedComponentBatch::new(
265                    array.clone(),
266                    Self::descriptor_rotation_axis_angles(),
267                )
268            });
269        let quaternions = arrays_by_descr
270            .get(&Self::descriptor_quaternions())
271            .map(|array| {
272                SerializedComponentBatch::new(array.clone(), Self::descriptor_quaternions())
273            });
274        let scales = arrays_by_descr
275            .get(&Self::descriptor_scales())
276            .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_scales()));
277        let mat3x3 = arrays_by_descr
278            .get(&Self::descriptor_mat3x3())
279            .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_mat3x3()));
280        Ok(Self {
281            translations,
282            rotation_axis_angles,
283            quaternions,
284            scales,
285            mat3x3,
286        })
287    }
288}
289
290impl ::re_types_core::AsComponents for InstancePoses3D {
291    #[inline]
292    fn as_serialized_batches(&self) -> Vec<SerializedComponentBatch> {
293        use ::re_types_core::Archetype as _;
294        [
295            Some(Self::indicator()),
296            self.translations.clone(),
297            self.rotation_axis_angles.clone(),
298            self.quaternions.clone(),
299            self.scales.clone(),
300            self.mat3x3.clone(),
301        ]
302        .into_iter()
303        .flatten()
304        .collect()
305    }
306}
307
308impl ::re_types_core::ArchetypeReflectionMarker for InstancePoses3D {}
309
310impl InstancePoses3D {
311    /// Create a new `InstancePoses3D`.
312    #[inline]
313    pub fn new() -> Self {
314        Self {
315            translations: None,
316            rotation_axis_angles: None,
317            quaternions: None,
318            scales: None,
319            mat3x3: None,
320        }
321    }
322
323    /// Update only some specific fields of a `InstancePoses3D`.
324    #[inline]
325    pub fn update_fields() -> Self {
326        Self::default()
327    }
328
329    /// Clear all the fields of a `InstancePoses3D`.
330    #[inline]
331    pub fn clear_fields() -> Self {
332        use ::re_types_core::Loggable as _;
333        Self {
334            translations: Some(SerializedComponentBatch::new(
335                crate::components::PoseTranslation3D::arrow_empty(),
336                Self::descriptor_translations(),
337            )),
338            rotation_axis_angles: Some(SerializedComponentBatch::new(
339                crate::components::PoseRotationAxisAngle::arrow_empty(),
340                Self::descriptor_rotation_axis_angles(),
341            )),
342            quaternions: Some(SerializedComponentBatch::new(
343                crate::components::PoseRotationQuat::arrow_empty(),
344                Self::descriptor_quaternions(),
345            )),
346            scales: Some(SerializedComponentBatch::new(
347                crate::components::PoseScale3D::arrow_empty(),
348                Self::descriptor_scales(),
349            )),
350            mat3x3: Some(SerializedComponentBatch::new(
351                crate::components::PoseTransformMat3x3::arrow_empty(),
352                Self::descriptor_mat3x3(),
353            )),
354        }
355    }
356
357    /// Partitions the component data into multiple sub-batches.
358    ///
359    /// Specifically, this transforms the existing [`SerializedComponentBatch`]es data into [`SerializedComponentColumn`]s
360    /// instead, via [`SerializedComponentBatch::partitioned`].
361    ///
362    /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun.
363    ///
364    /// The specified `lengths` must sum to the total length of the component batch.
365    ///
366    /// [`SerializedComponentColumn`]: [::re_types_core::SerializedComponentColumn]
367    #[inline]
368    pub fn columns<I>(
369        self,
370        _lengths: I,
371    ) -> SerializationResult<impl Iterator<Item = ::re_types_core::SerializedComponentColumn>>
372    where
373        I: IntoIterator<Item = usize> + Clone,
374    {
375        let columns = [
376            self.translations
377                .map(|translations| translations.partitioned(_lengths.clone()))
378                .transpose()?,
379            self.rotation_axis_angles
380                .map(|rotation_axis_angles| rotation_axis_angles.partitioned(_lengths.clone()))
381                .transpose()?,
382            self.quaternions
383                .map(|quaternions| quaternions.partitioned(_lengths.clone()))
384                .transpose()?,
385            self.scales
386                .map(|scales| scales.partitioned(_lengths.clone()))
387                .transpose()?,
388            self.mat3x3
389                .map(|mat3x3| mat3x3.partitioned(_lengths.clone()))
390                .transpose()?,
391        ];
392        Ok(columns
393            .into_iter()
394            .flatten()
395            .chain([::re_types_core::indicator_column::<Self>(
396                _lengths.into_iter().count(),
397            )?]))
398    }
399
400    /// Helper to partition the component data into unit-length sub-batches.
401    ///
402    /// This is semantically similar to calling [`Self::columns`] with `std::iter::take(1).repeat(n)`,
403    /// where `n` is automatically guessed.
404    #[inline]
405    pub fn columns_of_unit_batches(
406        self,
407    ) -> SerializationResult<impl Iterator<Item = ::re_types_core::SerializedComponentColumn>> {
408        let len_translations = self.translations.as_ref().map(|b| b.array.len());
409        let len_rotation_axis_angles = self.rotation_axis_angles.as_ref().map(|b| b.array.len());
410        let len_quaternions = self.quaternions.as_ref().map(|b| b.array.len());
411        let len_scales = self.scales.as_ref().map(|b| b.array.len());
412        let len_mat3x3 = self.mat3x3.as_ref().map(|b| b.array.len());
413        let len = None
414            .or(len_translations)
415            .or(len_rotation_axis_angles)
416            .or(len_quaternions)
417            .or(len_scales)
418            .or(len_mat3x3)
419            .unwrap_or(0);
420        self.columns(std::iter::repeat(1).take(len))
421    }
422
423    /// Translation vectors.
424    #[inline]
425    pub fn with_translations(
426        mut self,
427        translations: impl IntoIterator<Item = impl Into<crate::components::PoseTranslation3D>>,
428    ) -> Self {
429        self.translations = try_serialize_field(Self::descriptor_translations(), translations);
430        self
431    }
432
433    /// Rotations via axis + angle.
434    #[inline]
435    pub fn with_rotation_axis_angles(
436        mut self,
437        rotation_axis_angles: impl IntoIterator<
438            Item = impl Into<crate::components::PoseRotationAxisAngle>,
439        >,
440    ) -> Self {
441        self.rotation_axis_angles = try_serialize_field(
442            Self::descriptor_rotation_axis_angles(),
443            rotation_axis_angles,
444        );
445        self
446    }
447
448    /// Rotations via quaternion.
449    #[inline]
450    pub fn with_quaternions(
451        mut self,
452        quaternions: impl IntoIterator<Item = impl Into<crate::components::PoseRotationQuat>>,
453    ) -> Self {
454        self.quaternions = try_serialize_field(Self::descriptor_quaternions(), quaternions);
455        self
456    }
457
458    /// Scaling factors.
459    #[inline]
460    pub fn with_scales(
461        mut self,
462        scales: impl IntoIterator<Item = impl Into<crate::components::PoseScale3D>>,
463    ) -> Self {
464        self.scales = try_serialize_field(Self::descriptor_scales(), scales);
465        self
466    }
467
468    /// 3x3 transformation matrices.
469    #[inline]
470    pub fn with_mat3x3(
471        mut self,
472        mat3x3: impl IntoIterator<Item = impl Into<crate::components::PoseTransformMat3x3>>,
473    ) -> Self {
474        self.mat3x3 = try_serialize_field(Self::descriptor_mat3x3(), mat3x3);
475        self
476    }
477}
478
479impl ::re_byte_size::SizeBytes for InstancePoses3D {
480    #[inline]
481    fn heap_size_bytes(&self) -> u64 {
482        self.translations.heap_size_bytes()
483            + self.rotation_axis_angles.heap_size_bytes()
484            + self.quaternions.heap_size_bytes()
485            + self.scales.heap_size_bytes()
486            + self.mat3x3.heap_size_bytes()
487    }
488}