diff --git a/crates/store/re_types/definitions/rerun/archetypes/transform3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/transform3d.fbs index bcd18db06dbb..bcf912b3f594 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/transform3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/transform3d.fbs @@ -8,33 +8,28 @@ namespace rerun.archetypes; /// E.g. if both a translation and a max3x3 transform are present, /// the 3x3 matrix is applied first, followed by the translation. /// -/// Each transform component can be listed multiple times, but transform tree propagation is only possible -/// if there's only one instance for each transform component. -/// TODO(#6831): write more about the exact interaction with the to be written `OutOfTreeTransform` component. -/// /// \example archetypes/transform3d_simple title="Variety of 3D transforms" image="https://static.rerun.io/transform3d_simple/141368b07360ce3fcb1553079258ae3f42bdb9ac/1200w.png" /// \example archetypes/transform3d_hierarchy title="Transform hierarchy" image="https://static.rerun.io/transform_hierarchy/cb7be7a5a31fcb2efc02ba38e434849248f87554/1200w.png" -// TODO(#6831): provide example with out of tree transform. table Transform3D ( "attr.rust.derive": "Default, PartialEq", "attr.rust.generate_field_info", "attr.docs.category": "Spatial 3D", "attr.docs.view_types": "Spatial3DView, Spatial2DView: if logged above active projection" ) { - /// Translation vectors. - translation: [rerun.components.Translation3D] ("attr.rerun.component_optional", nullable, order: 1100); + /// Translation vector. + translation: rerun.components.Translation3D ("attr.rerun.component_optional", nullable, order: 1100); /// Rotation via axis + angle. - rotation_axis_angle: [rerun.components.RotationAxisAngle] ("attr.rerun.component_optional", nullable, order: 1200); + rotation_axis_angle: rerun.components.RotationAxisAngle ("attr.rerun.component_optional", nullable, order: 1200); /// Rotation via quaternion. - quaternion: [rerun.components.RotationQuat] ("attr.rerun.component_optional", nullable, order: 1300); + quaternion: rerun.components.RotationQuat ("attr.rerun.component_optional", nullable, order: 1300); /// Scaling factor. - scale: [rerun.components.Scale3D] ("attr.rerun.component_optional", nullable, order: 1400); + scale: rerun.components.Scale3D ("attr.rerun.component_optional", nullable, order: 1400); - /// 3x3 transformation matrices. - mat3x3: [rerun.components.TransformMat3x3] ("attr.rerun.component_optional", nullable, order: 1500); + /// 3x3 transformation matrix. + mat3x3: rerun.components.TransformMat3x3 ("attr.rerun.component_optional", nullable, order: 1500); /// Specifies the relation this transform establishes between this entity and its parent. relation: rerun.components.TransformRelation ("attr.rerun.component_optional", nullable, order: 1600); diff --git a/crates/store/re_types/src/archetypes/transform3d.rs b/crates/store/re_types/src/archetypes/transform3d.rs index a9ffbb6630f2..b4b0b0208aa3 100644 --- a/crates/store/re_types/src/archetypes/transform3d.rs +++ b/crates/store/re_types/src/archetypes/transform3d.rs @@ -25,10 +25,6 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// E.g. if both a translation and a max3x3 transform are present, /// the 3x3 matrix is applied first, followed by the translation. /// -/// Each transform component can be listed multiple times, but transform tree propagation is only possible -/// if there's only one instance for each transform component. -/// TODO(#6831): write more about the exact interaction with the to be written `OutOfTreeTransform` component. -/// /// ## Examples /// /// ### Variety of 3D transforms @@ -166,20 +162,20 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// #[derive(Clone, Debug, Default, PartialEq)] pub struct Transform3D { - /// Translation vectors. - pub translation: Option>, + /// Translation vector. + pub translation: Option, /// Rotation via axis + angle. - pub rotation_axis_angle: Option>, + pub rotation_axis_angle: Option, /// Rotation via quaternion. - pub quaternion: Option>, + pub quaternion: Option, /// Scaling factor. - pub scale: Option>, + pub scale: Option, - /// 3x3 transformation matrices. - pub mat3x3: Option>, + /// 3x3 transformation matrix. + pub mat3x3: Option, /// Specifies the relation this transform establishes between this entity and its parent. pub relation: Option, @@ -205,11 +201,11 @@ impl ::re_types_core::SizeBytes for Transform3D { #[inline] fn is_pod() -> bool { - >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() + >::is_pod() + && >::is_pod() + && >::is_pod() + && >::is_pod() + && >::is_pod() && >::is_pod() && >::is_pod() } @@ -307,63 +303,48 @@ impl ::re_types_core::Archetype for Transform3D { .collect(); let translation = if let Some(array) = arrays_by_name.get("rerun.components.Translation3D") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Transform3D#translation")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Transform3D#translation")? - }) + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Transform3D#translation")? + .into_iter() + .next() + .flatten() } else { None }; let rotation_axis_angle = if let Some(array) = arrays_by_name.get("rerun.components.RotationAxisAngle") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Transform3D#rotation_axis_angle")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Transform3D#rotation_axis_angle")? - }) + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Transform3D#rotation_axis_angle")? + .into_iter() + .next() + .flatten() } else { None }; let quaternion = if let Some(array) = arrays_by_name.get("rerun.components.RotationQuat") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Transform3D#quaternion")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Transform3D#quaternion")? - }) + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Transform3D#quaternion")? + .into_iter() + .next() + .flatten() } else { None }; let scale = if let Some(array) = arrays_by_name.get("rerun.components.Scale3D") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Transform3D#scale")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Transform3D#scale")? - }) + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Transform3D#scale")? + .into_iter() + .next() + .flatten() } else { None }; let mat3x3 = if let Some(array) = arrays_by_name.get("rerun.components.TransformMat3x3") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Transform3D#mat3x3")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Transform3D#mat3x3")? - }) + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Transform3D#mat3x3")? + .into_iter() + .next() + .flatten() } else { None }; @@ -406,19 +387,19 @@ impl ::re_types_core::AsComponents for Transform3D { Some(Self::indicator()), self.translation .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch).into()), + .map(|comp| (comp as &dyn ComponentBatch).into()), self.rotation_axis_angle .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch).into()), + .map(|comp| (comp as &dyn ComponentBatch).into()), self.quaternion .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch).into()), + .map(|comp| (comp as &dyn ComponentBatch).into()), self.scale .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch).into()), + .map(|comp| (comp as &dyn ComponentBatch).into()), self.mat3x3 .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch).into()), + .map(|comp| (comp as &dyn ComponentBatch).into()), self.relation .as_ref() .map(|comp| (comp as &dyn ComponentBatch).into()), @@ -449,13 +430,13 @@ impl Transform3D { } } - /// Translation vectors. + /// Translation vector. #[inline] pub fn with_translation( mut self, - translation: impl IntoIterator>, + translation: impl Into, ) -> Self { - self.translation = Some(translation.into_iter().map(Into::into).collect()); + self.translation = Some(translation.into()); self } @@ -463,9 +444,9 @@ impl Transform3D { #[inline] pub fn with_rotation_axis_angle( mut self, - rotation_axis_angle: impl IntoIterator>, + rotation_axis_angle: impl Into, ) -> Self { - self.rotation_axis_angle = Some(rotation_axis_angle.into_iter().map(Into::into).collect()); + self.rotation_axis_angle = Some(rotation_axis_angle.into()); self } @@ -473,29 +454,23 @@ impl Transform3D { #[inline] pub fn with_quaternion( mut self, - quaternion: impl IntoIterator>, + quaternion: impl Into, ) -> Self { - self.quaternion = Some(quaternion.into_iter().map(Into::into).collect()); + self.quaternion = Some(quaternion.into()); self } /// Scaling factor. #[inline] - pub fn with_scale( - mut self, - scale: impl IntoIterator>, - ) -> Self { - self.scale = Some(scale.into_iter().map(Into::into).collect()); + pub fn with_scale(mut self, scale: impl Into) -> Self { + self.scale = Some(scale.into()); self } - /// 3x3 transformation matrices. + /// 3x3 transformation matrix. #[inline] - pub fn with_mat3x3( - mut self, - mat3x3: impl IntoIterator>, - ) -> Self { - self.mat3x3 = Some(mat3x3.into_iter().map(Into::into).collect()); + pub fn with_mat3x3(mut self, mat3x3: impl Into) -> Self { + self.mat3x3 = Some(mat3x3.into()); self } diff --git a/crates/store/re_types/src/archetypes/transform3d_ext.rs b/crates/store/re_types/src/archetypes/transform3d_ext.rs index 6be4ce58ca25..6d8d62ebcd47 100644 --- a/crates/store/re_types/src/archetypes/transform3d_ext.rs +++ b/crates/store/re_types/src/archetypes/transform3d_ext.rs @@ -11,11 +11,11 @@ impl Transform3D { pub fn with_rotation(self, rotation: impl Into) -> Self { match rotation.into() { Rotation3D::Quaternion(quaternion) => Self { - quaternion: Some(vec![quaternion]), + quaternion: Some(quaternion), ..self }, Rotation3D::AxisAngle(rotation_axis_angle) => Self { - rotation_axis_angle: Some(vec![rotation_axis_angle]), + rotation_axis_angle: Some(rotation_axis_angle), ..self }, } @@ -25,7 +25,7 @@ impl Transform3D { #[inline] pub fn from_translation(translation: impl Into) -> Self { Self { - translation: Some(vec![translation.into()]), + translation: Some(translation.into()), ..Self::default() } } @@ -34,7 +34,7 @@ impl Transform3D { #[inline] pub fn from_mat3x3(mat3x3: impl Into) -> Self { Self { - mat3x3: Some(vec![mat3x3.into()]), + mat3x3: Some(mat3x3.into()), ..Self::default() } } @@ -49,7 +49,7 @@ impl Transform3D { #[inline] pub fn from_scale(scale: impl Into) -> Self { Self { - scale: Some(vec![scale.into()]), + scale: Some(scale.into()), ..Self::default() } } @@ -61,7 +61,7 @@ impl Transform3D { rotation: impl Into, ) -> Self { Self { - translation: Some(vec![translation.into()]), + translation: Some(translation.into()), ..Self::default() } .with_rotation(rotation) @@ -74,8 +74,8 @@ impl Transform3D { mat3x3: impl Into, ) -> Self { Self { - mat3x3: Some(vec![mat3x3.into()]), - translation: Some(vec![translation.into()]), + mat3x3: Some(mat3x3.into()), + translation: Some(translation.into()), ..Self::default() } } @@ -87,8 +87,8 @@ impl Transform3D { scale: impl Into, ) -> Self { Self { - scale: Some(vec![scale.into()]), - translation: Some(vec![translation.into()]), + scale: Some(scale.into()), + translation: Some(translation.into()), ..Self::default() } } @@ -101,8 +101,8 @@ impl Transform3D { scale: impl Into, ) -> Self { Self { - scale: Some(vec![scale.into()]), - translation: Some(vec![translation.into()]), + scale: Some(scale.into()), + translation: Some(translation.into()), ..Self::default() } .with_rotation(rotation) @@ -112,7 +112,7 @@ impl Transform3D { #[inline] pub fn from_rotation_scale(rotation: impl Into, scale: impl Into) -> Self { Self { - scale: Some(vec![scale.into()]), + scale: Some(scale.into()), ..Self::default() } .with_rotation(rotation) diff --git a/crates/store/re_types/tests/transform3d.rs b/crates/store/re_types/tests/transform3d.rs index 246e5cfb74ba..97735cf8b234 100644 --- a/crates/store/re_types/tests/transform3d.rs +++ b/crates/store/re_types/tests/transform3d.rs @@ -12,40 +12,42 @@ fn roundtrip() { let all_expected = [ Transform3D::default(), Transform3D { - translation: Some(vec![Vec3D([1.0, 2.0, 3.0]).into()]), - scale: Some(vec![Scale3D::uniform(42.0)]), + translation: Some(Vec3D([1.0, 2.0, 3.0]).into()), + scale: Some(Scale3D::uniform(42.0)), relation: Some(TransformRelation::ChildFromParent), ..Default::default() }, // Transform3D { - translation: Some(vec![[1.0, 2.0, 3.0].into()]), - rotation_axis_angle: Some(vec![RotationAxisAngle { - axis: Vec3D([0.2, 0.2, 0.8]), - angle: Angle::from_radians(0.5 * TAU), - } - .into()]), + translation: Some([1.0, 2.0, 3.0].into()), + rotation_axis_angle: Some( + RotationAxisAngle { + axis: Vec3D([0.2, 0.2, 0.8]), + angle: Angle::from_radians(0.5 * TAU), + } + .into(), + ), ..Default::default() }, // Transform3D { - translation: Some(vec![Vec3D([1.0, 2.0, 3.0]).into()]), - rotation_axis_angle: Some(vec![RotationAxisAngle { - axis: Vec3D([0.2, 0.2, 0.8]), - angle: Angle::from_radians(0.5 * TAU), - } - .into()]), - scale: Some(vec![Scale3D::uniform(42.0)]), + translation: Some(Vec3D([1.0, 2.0, 3.0]).into()), + rotation_axis_angle: Some( + RotationAxisAngle { + axis: Vec3D([0.2, 0.2, 0.8]), + angle: Angle::from_radians(0.5 * TAU), + } + .into(), + ), + scale: Some(Scale3D::uniform(42.0)), relation: Some(TransformRelation::ChildFromParent), ..Default::default() }, // Transform3D { - translation: Some(vec![Vec3D([1.0, 2.0, 3.0]).into()]), + translation: Some(Vec3D([1.0, 2.0, 3.0]).into()), relation: Some(TransformRelation::ChildFromParent), ..Default::default() }, // Transform3D { - mat3x3: Some(vec![ - Mat3x3([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]).into() - ]), + mat3x3: Some(Mat3x3([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]).into()), relation: Some(TransformRelation::ParentFromChild), ..Default::default() }, // diff --git a/crates/viewer/re_viewer/src/reflection/mod.rs b/crates/viewer/re_viewer/src/reflection/mod.rs index 4c0a6860fdda..546aedc943b5 100644 --- a/crates/viewer/re_viewer/src/reflection/mod.rs +++ b/crates/viewer/re_viewer/src/reflection/mod.rs @@ -658,11 +658,11 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { ArchetypeName::new("rerun.archetypes.Transform3D"), ArchetypeReflection { display_name: "Transform 3D", - docstring_md: "A transform between two 3D spaces, i.e. a pose.\n\nFrom the point of view of the entity's coordinate system,\nall components are applied in the inverse order they are listed here.\nE.g. if both a translation and a max3x3 transform are present,\nthe 3x3 matrix is applied first, followed by the translation.\n\nEach transform component can be listed multiple times, but transform tree propagation is only possible\nif there's only one instance for each transform component.\nTODO(#6831): write more about the exact interaction with the to be written `OutOfTreeTransform` component.\n\n## Examples\n\n### Variety of 3D transforms\n```ignore\nuse std::f32::consts::TAU;\n\nfn main() -> Result<(), Box> {\n let rec = rerun::RecordingStreamBuilder::new(\"rerun_example_transform3d\").spawn()?;\n\n let arrow = rerun::Arrows3D::from_vectors([(0.0, 1.0, 0.0)]).with_origins([(0.0, 0.0, 0.0)]);\n\n rec.log(\"base\", &arrow)?;\n\n rec.log(\n \"base/translated\",\n &rerun::Transform3D::from_translation([1.0, 0.0, 0.0]),\n )?;\n\n rec.log(\"base/translated\", &arrow)?;\n\n rec.log(\n \"base/rotated_scaled\",\n &rerun::Transform3D::from_rotation_scale(\n rerun::RotationAxisAngle::new([0.0, 0.0, 1.0], rerun::Angle::from_radians(TAU / 8.0)),\n rerun::Scale3D::from(2.0),\n ),\n )?;\n\n rec.log(\"base/rotated_scaled\", &arrow)?;\n\n Ok(())\n}\n```\n
\n\n \n \n \n \n \n\n
\n\n### Transform hierarchy\n```ignore\nfn main() -> Result<(), Box> {\n let rec = rerun::RecordingStreamBuilder::new(\"rerun_example_transform3d_hierarchy\").spawn()?;\n\n // TODO(#5521): log two space views as in the python example\n\n rec.set_time_seconds(\"sim_time\", 0.0);\n\n // Planetary motion is typically in the XY plane.\n rec.log_static(\"/\", &rerun::ViewCoordinates::RIGHT_HAND_Z_UP)?;\n\n // Setup points, all are in the center of their own space:\n rec.log(\n \"sun\",\n &rerun::Points3D::new([[0.0, 0.0, 0.0]])\n .with_radii([1.0])\n .with_colors([rerun::Color::from_rgb(255, 200, 10)]),\n )?;\n rec.log(\n \"sun/planet\",\n &rerun::Points3D::new([[0.0, 0.0, 0.0]])\n .with_radii([0.4])\n .with_colors([rerun::Color::from_rgb(40, 80, 200)]),\n )?;\n rec.log(\n \"sun/planet/moon\",\n &rerun::Points3D::new([[0.0, 0.0, 0.0]])\n .with_radii([0.15])\n .with_colors([rerun::Color::from_rgb(180, 180, 180)]),\n )?;\n\n // Draw fixed paths where the planet & moon move.\n let d_planet = 6.0;\n let d_moon = 3.0;\n let angles = (0..=100).map(|i| i as f32 * 0.01 * std::f32::consts::TAU);\n let circle: Vec<_> = angles.map(|angle| [angle.sin(), angle.cos()]).collect();\n rec.log(\n \"sun/planet_path\",\n &rerun::LineStrips3D::new([rerun::LineStrip3D::from_iter(\n circle\n .iter()\n .map(|p| [p[0] * d_planet, p[1] * d_planet, 0.0]),\n )]),\n )?;\n rec.log(\n \"sun/planet/moon_path\",\n &rerun::LineStrips3D::new([rerun::LineStrip3D::from_iter(\n circle.iter().map(|p| [p[0] * d_moon, p[1] * d_moon, 0.0]),\n )]),\n )?;\n\n // Movement via transforms.\n for i in 0..(6 * 120) {\n let time = i as f32 / 120.0;\n rec.set_time_seconds(\"sim_time\", time);\n let r_moon = time * 5.0;\n let r_planet = time * 2.0;\n\n rec.log(\n \"sun/planet\",\n &rerun::Transform3D::from_translation_rotation(\n [r_planet.sin() * d_planet, r_planet.cos() * d_planet, 0.0],\n rerun::RotationAxisAngle {\n axis: [1.0, 0.0, 0.0].into(),\n angle: rerun::Angle::from_degrees(20.0),\n },\n ),\n )?;\n rec.log(\n \"sun/planet/moon\",\n &rerun::Transform3D::from_translation([\n r_moon.cos() * d_moon,\n r_moon.sin() * d_moon,\n 0.0,\n ])\n .with_relation(rerun::TransformRelation::ChildFromParent),\n )?;\n }\n\n Ok(())\n}\n```\n
\n\n \n \n \n \n \n\n
", + docstring_md: "A transform between two 3D spaces, i.e. a pose.\n\nFrom the point of view of the entity's coordinate system,\nall components are applied in the inverse order they are listed here.\nE.g. if both a translation and a max3x3 transform are present,\nthe 3x3 matrix is applied first, followed by the translation.\n\n## Examples\n\n### Variety of 3D transforms\n```ignore\nuse std::f32::consts::TAU;\n\nfn main() -> Result<(), Box> {\n let rec = rerun::RecordingStreamBuilder::new(\"rerun_example_transform3d\").spawn()?;\n\n let arrow = rerun::Arrows3D::from_vectors([(0.0, 1.0, 0.0)]).with_origins([(0.0, 0.0, 0.0)]);\n\n rec.log(\"base\", &arrow)?;\n\n rec.log(\n \"base/translated\",\n &rerun::Transform3D::from_translation([1.0, 0.0, 0.0]),\n )?;\n\n rec.log(\"base/translated\", &arrow)?;\n\n rec.log(\n \"base/rotated_scaled\",\n &rerun::Transform3D::from_rotation_scale(\n rerun::RotationAxisAngle::new([0.0, 0.0, 1.0], rerun::Angle::from_radians(TAU / 8.0)),\n rerun::Scale3D::from(2.0),\n ),\n )?;\n\n rec.log(\"base/rotated_scaled\", &arrow)?;\n\n Ok(())\n}\n```\n
\n\n \n \n \n \n \n\n
\n\n### Transform hierarchy\n```ignore\nfn main() -> Result<(), Box> {\n let rec = rerun::RecordingStreamBuilder::new(\"rerun_example_transform3d_hierarchy\").spawn()?;\n\n // TODO(#5521): log two space views as in the python example\n\n rec.set_time_seconds(\"sim_time\", 0.0);\n\n // Planetary motion is typically in the XY plane.\n rec.log_static(\"/\", &rerun::ViewCoordinates::RIGHT_HAND_Z_UP)?;\n\n // Setup points, all are in the center of their own space:\n rec.log(\n \"sun\",\n &rerun::Points3D::new([[0.0, 0.0, 0.0]])\n .with_radii([1.0])\n .with_colors([rerun::Color::from_rgb(255, 200, 10)]),\n )?;\n rec.log(\n \"sun/planet\",\n &rerun::Points3D::new([[0.0, 0.0, 0.0]])\n .with_radii([0.4])\n .with_colors([rerun::Color::from_rgb(40, 80, 200)]),\n )?;\n rec.log(\n \"sun/planet/moon\",\n &rerun::Points3D::new([[0.0, 0.0, 0.0]])\n .with_radii([0.15])\n .with_colors([rerun::Color::from_rgb(180, 180, 180)]),\n )?;\n\n // Draw fixed paths where the planet & moon move.\n let d_planet = 6.0;\n let d_moon = 3.0;\n let angles = (0..=100).map(|i| i as f32 * 0.01 * std::f32::consts::TAU);\n let circle: Vec<_> = angles.map(|angle| [angle.sin(), angle.cos()]).collect();\n rec.log(\n \"sun/planet_path\",\n &rerun::LineStrips3D::new([rerun::LineStrip3D::from_iter(\n circle\n .iter()\n .map(|p| [p[0] * d_planet, p[1] * d_planet, 0.0]),\n )]),\n )?;\n rec.log(\n \"sun/planet/moon_path\",\n &rerun::LineStrips3D::new([rerun::LineStrip3D::from_iter(\n circle.iter().map(|p| [p[0] * d_moon, p[1] * d_moon, 0.0]),\n )]),\n )?;\n\n // Movement via transforms.\n for i in 0..(6 * 120) {\n let time = i as f32 / 120.0;\n rec.set_time_seconds(\"sim_time\", time);\n let r_moon = time * 5.0;\n let r_planet = time * 2.0;\n\n rec.log(\n \"sun/planet\",\n &rerun::Transform3D::from_translation_rotation(\n [r_planet.sin() * d_planet, r_planet.cos() * d_planet, 0.0],\n rerun::RotationAxisAngle {\n axis: [1.0, 0.0, 0.0].into(),\n angle: rerun::Angle::from_degrees(20.0),\n },\n ),\n )?;\n rec.log(\n \"sun/planet/moon\",\n &rerun::Transform3D::from_translation([\n r_moon.cos() * d_moon,\n r_moon.sin() * d_moon,\n 0.0,\n ])\n .with_relation(rerun::TransformRelation::ChildFromParent),\n )?;\n }\n\n Ok(())\n}\n```\n
\n\n \n \n \n \n \n\n
", fields: vec![ ArchetypeFieldReflection { component_name : "rerun.components.Translation3D".into(), display_name : - "Translation", docstring_md : "Translation vectors.", }, + "Translation", docstring_md : "Translation vector.", }, ArchetypeFieldReflection { component_name : "rerun.components.RotationAxisAngle".into(), display_name : "Rotation axis angle", docstring_md : "Rotation via axis + angle.", @@ -674,7 +674,7 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { docstring_md : "Scaling factor.", }, ArchetypeFieldReflection { component_name : "rerun.components.TransformMat3x3".into(), display_name : "Mat 3x 3", docstring_md : - "3x3 transformation matrices.", }, ArchetypeFieldReflection { + "3x3 transformation matrix.", }, ArchetypeFieldReflection { component_name : "rerun.components.TransformRelation".into(), display_name : "Relation", docstring_md : "Specifies the relation this transform establishes between this entity and its parent.", diff --git a/docs/content/reference/migration/migration-0-18.md b/docs/content/reference/migration/migration-0-18.md index ed58daa2f201..830732fbd581 100644 --- a/docs/content/reference/migration/migration-0-18.md +++ b/docs/content/reference/migration/migration-0-18.md @@ -66,7 +66,7 @@ Other changes in data representation: * Angles (as used in `RotationAxisAngle`) are now always stored in radians, conversion functions for degrees are provided. Scaling no longer distinguishes uniform and 3D scaling in its data representation. Uniform scaling is now always expressed as 3 floats with the same value. -TODO(andreas): Write about OutOfTreeTransform changes and how `Transform3D` has now arrays of components. +TODO(andreas): Write about LeafTransforms3D #### Python @@ -87,7 +87,7 @@ rr.log("myentity", rr.Transform3D(translation=Vec3D([1, 2, 3]), relation=rr.Tran TODO(andreas): code example -TODO(andreas): Talk about OutOfTreeTransform +TODO(andreas): Talk about LeafTransforms3D TODO(andreas): … and Asset3D specifically @@ -129,7 +129,7 @@ let scale_uniform = rerun::Scale3D::uniform(2.0); let scale_y = rerun::Scale3D::from([1.0, 2.0, 1.0]); ``` -TODO(andreas): Talk about OutOfTreeTransform +TODO(andreas): Talk about LeafTransforms3D TODO(andreas): … and Asset3D specifically #### Rust @@ -181,5 +181,5 @@ Note that the order of the method calls does _not_ affect the order in which tra `rerun::Transform3D::IDENTITY` has been removed, sue `rerun::Transform3D::default()` to start out with an empty archetype instead that you can populate (e.g. `rerun::Transform3D::default().with_mat3x3(rerun::datatypes::Mat3x3::IDENTITY)`). -TODO(andreas): Talk about OutOfTreeTransform +TODO(andreas): Talk about LeafTransforms3D TODO(andreas): … and Asset3D specifically diff --git a/docs/content/reference/types/archetypes/transform3d.md b/docs/content/reference/types/archetypes/transform3d.md index 73a40c593262..289bfa36041b 100644 --- a/docs/content/reference/types/archetypes/transform3d.md +++ b/docs/content/reference/types/archetypes/transform3d.md @@ -10,10 +10,6 @@ all components are applied in the inverse order they are listed here. E.g. if both a translation and a max3x3 transform are present, the 3x3 matrix is applied first, followed by the translation. -Each transform component can be listed multiple times, but transform tree propagation is only possible -if there's only one instance for each transform component. -TODO(#6831): write more about the exact interaction with the to be written `OutOfTreeTransform` component. - ## Components **Optional**: [`Translation3D`](../components/translation3d.md), [`RotationAxisAngle`](../components/rotation_axis_angle.md), [`RotationQuat`](../components/rotation_quat.md), [`Scale3D`](../components/scale3d.md), [`TransformMat3x3`](../components/transform_mat3x3.md), [`TransformRelation`](../components/transform_relation.md), [`AxisLength`](../components/axis_length.md) diff --git a/rerun_cpp/src/rerun/archetypes/transform3d.hpp b/rerun_cpp/src/rerun/archetypes/transform3d.hpp index 7cb518cd8cb9..01f1e206dbe7 100644 --- a/rerun_cpp/src/rerun/archetypes/transform3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/transform3d.hpp @@ -31,10 +31,6 @@ namespace rerun::archetypes { /// E.g. if both a translation and a max3x3 transform are present, /// the 3x3 matrix is applied first, followed by the translation. /// - /// Each transform component can be listed multiple times, but transform tree propagation is only possible - /// if there's only one instance for each transform component. - /// TODO(#6831): write more about the exact interaction with the to be written `OutOfTreeTransform` component. - /// /// ## Examples /// /// ### Variety of 3D transforms @@ -149,20 +145,20 @@ namespace rerun::archetypes { /// } /// ``` struct Transform3D { - /// Translation vectors. - std::optional> translation; + /// Translation vector. + std::optional translation; /// Rotation via axis + angle. - std::optional> rotation_axis_angle; + std::optional rotation_axis_angle; /// Rotation via quaternion. - std::optional> quaternion; + std::optional quaternion; /// Scaling factor. - std::optional> scale; + std::optional scale; - /// 3x3 transformation matrices. - std::optional> mat3x3; + /// 3x3 transformation matrix. + std::optional mat3x3; /// Specifies the relation this transform establishes between this entity and its parent. std::optional relation; @@ -211,8 +207,7 @@ namespace rerun::archetypes { const components::Translation3D& translation_, const components::TransformMat3x3& mat3x3_, bool from_parent = false ) - : translation(Collection::take_ownership(translation_)), - mat3x3(Collection::take_ownership(mat3x3_)) { + : translation(translation_), mat3x3(mat3x3_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -246,7 +241,7 @@ namespace rerun::archetypes { /// \param translation_ \çopydoc Transform3D::translation /// \param from_parent If true, the transform relation to `TransformRelation::ChildFromParent`. Transform3D(const components::Translation3D& translation_, bool from_parent = false) - : translation(Collection::take_ownership(translation_)) { + : translation(translation_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -264,7 +259,7 @@ namespace rerun::archetypes { /// \param mat3x3_ \copydoc Transform3D::mat3x3 /// \param from_parent If true, the transform relation to `TransformRelation::ChildFromParent`. Transform3D(const components::TransformMat3x3& mat3x3_, bool from_parent = false) - : mat3x3(Collection::take_ownership(mat3x3_)) { + : mat3x3(mat3x3_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -301,8 +296,7 @@ namespace rerun::archetypes { const components::Translation3D& translation_, const Rotation3D& rotation, const components::Scale3D& scale_, bool from_parent = false ) - : translation(Collection::take_ownership(translation_)), - scale(Collection::take_ownership(scale_)) { + : translation(translation_), scale(scale_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -358,7 +352,7 @@ namespace rerun::archetypes { const components::Translation3D& translation_, const Rotation3D& rotation, bool from_parent = false ) - : translation(Collection::take_ownership(translation_)) { + : translation(translation_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -384,8 +378,7 @@ namespace rerun::archetypes { const components::Translation3D& translation_, const components::Scale3D& scale_, bool from_parent = false ) - : translation(Collection::take_ownership(translation_)), - scale(Collection::take_ownership(scale_)) { + : translation(translation_), scale(scale_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -423,7 +416,7 @@ namespace rerun::archetypes { Transform3D( const Rotation3D& rotation, const components::Scale3D& scale_, bool from_parent = false ) - : scale(Collection::take_ownership(scale_)) { + : scale(scale_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -481,8 +474,7 @@ namespace rerun::archetypes { /// /// \param scale_ If true, the transform relation to `TransformRelation::ChildFromParent`. /// \param from_parent \copydoc Transform3D::scale - Transform3D(const components::Scale3D& scale_, bool from_parent = false) - : scale(Collection::take_ownership(scale_)) { + Transform3D(const components::Scale3D& scale_, bool from_parent = false) : scale(scale_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -506,14 +498,11 @@ namespace rerun::archetypes { /// Set the rotation component of the transform using the `rerun::Rotation3D` utility. void set_rotation(const Rotation3D& rotation) { if (rotation.axis_angle.has_value()) { - rotation_axis_angle = Collection::take_ownership( - rotation.axis_angle.value() - ); + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(rotation_axis_angle = + rotation.axis_angle.value();) } if (rotation.quaternion.has_value()) { - quaternion = - Collection::take_ownership(rotation.quaternion.value() - ); + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(quaternion = rotation.quaternion.value();) } } @@ -521,8 +510,8 @@ namespace rerun::archetypes { Transform3D() = default; Transform3D(Transform3D&& other) = default; - /// Translation vectors. - Transform3D with_translation(Collection _translation) && { + /// Translation vector. + Transform3D with_translation(rerun::components::Translation3D _translation) && { translation = std::move(_translation); // See: https://github.com/rerun-io/rerun/issues/4027 RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) @@ -530,7 +519,7 @@ namespace rerun::archetypes { /// Rotation via axis + angle. Transform3D with_rotation_axis_angle( - Collection _rotation_axis_angle + rerun::components::RotationAxisAngle _rotation_axis_angle ) && { rotation_axis_angle = std::move(_rotation_axis_angle); // See: https://github.com/rerun-io/rerun/issues/4027 @@ -538,21 +527,21 @@ namespace rerun::archetypes { } /// Rotation via quaternion. - Transform3D with_quaternion(Collection _quaternion) && { + Transform3D with_quaternion(rerun::components::RotationQuat _quaternion) && { quaternion = std::move(_quaternion); // See: https://github.com/rerun-io/rerun/issues/4027 RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) } /// Scaling factor. - Transform3D with_scale(Collection _scale) && { + Transform3D with_scale(rerun::components::Scale3D _scale) && { scale = std::move(_scale); // See: https://github.com/rerun-io/rerun/issues/4027 RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) } - /// 3x3 transformation matrices. - Transform3D with_mat3x3(Collection _mat3x3) && { + /// 3x3 transformation matrix. + Transform3D with_mat3x3(rerun::components::TransformMat3x3 _mat3x3) && { mat3x3 = std::move(_mat3x3); // See: https://github.com/rerun-io/rerun/issues/4027 RR_WITH_MAYBE_UNINITIALIZED_DISABLED(return std::move(*this);) diff --git a/rerun_cpp/src/rerun/archetypes/transform3d_ext.cpp b/rerun_cpp/src/rerun/archetypes/transform3d_ext.cpp index 938c181ad445..27fccae48924 100644 --- a/rerun_cpp/src/rerun/archetypes/transform3d_ext.cpp +++ b/rerun_cpp/src/rerun/archetypes/transform3d_ext.cpp @@ -1,6 +1,7 @@ #include "transform3d.hpp" // +#include "../compiler_utils.hpp" #include "../rerun_sdk_export.hpp" #include "../rotation3d.hpp" @@ -38,8 +39,7 @@ namespace rerun::archetypes { const components::Translation3D& translation_, const components::TransformMat3x3& mat3x3_, bool from_parent = false ) - : translation(Collection::take_ownership(translation_)), - mat3x3(Collection::take_ownership(mat3x3_)) { + : translation(translation_), mat3x3(mat3x3_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -73,7 +73,7 @@ namespace rerun::archetypes { /// \param translation_ \çopydoc Transform3D::translation /// \param from_parent If true, the transform relation to `TransformRelation::ChildFromParent`. Transform3D(const components::Translation3D& translation_, bool from_parent = false) - : translation(Collection::take_ownership(translation_)) { + : translation(translation_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -91,7 +91,7 @@ namespace rerun::archetypes { /// \param mat3x3_ \copydoc Transform3D::mat3x3 /// \param from_parent If true, the transform relation to `TransformRelation::ChildFromParent`. Transform3D(const components::TransformMat3x3& mat3x3_, bool from_parent = false) - : mat3x3(Collection::take_ownership(mat3x3_)) { + : mat3x3(mat3x3_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -128,8 +128,7 @@ namespace rerun::archetypes { const components::Translation3D& translation_, const Rotation3D& rotation, const components::Scale3D& scale_, bool from_parent = false ) - : translation(Collection::take_ownership(translation_)), - scale(Collection::take_ownership(scale_)) { + : translation(translation_), scale(scale_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -184,7 +183,7 @@ namespace rerun::archetypes { const components::Translation3D& translation_, const Rotation3D& rotation, bool from_parent = false ) - : translation(Collection::take_ownership(translation_)) { + : translation(translation_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -210,8 +209,7 @@ namespace rerun::archetypes { const components::Translation3D& translation_, const components::Scale3D& scale_, bool from_parent = false ) - : translation(Collection::take_ownership(translation_)), - scale(Collection::take_ownership(scale_)) { + : translation(translation_), scale(scale_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -248,7 +246,7 @@ namespace rerun::archetypes { Transform3D( const Rotation3D& rotation, const components::Scale3D& scale_, bool from_parent = false ) - : scale(Collection::take_ownership(scale_)) { + : scale(scale_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -306,8 +304,7 @@ namespace rerun::archetypes { /// /// \param scale_ If true, the transform relation to `TransformRelation::ChildFromParent`. /// \param from_parent \copydoc Transform3D::scale - Transform3D(const components::Scale3D& scale_, bool from_parent = false) - : scale(Collection::take_ownership(scale_)) { + Transform3D(const components::Scale3D& scale_, bool from_parent = false) : scale(scale_) { if (from_parent) { relation = components::TransformRelation::ChildFromParent; } @@ -331,13 +328,10 @@ namespace rerun::archetypes { /// Set the rotation component of the transform using the `rerun::Rotation3D` utility. void set_rotation(const Rotation3D& rotation) { if (rotation.axis_angle.has_value()) { - rotation_axis_angle = Collection::take_ownership( - rotation.axis_angle.value() - ); + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(rotation_axis_angle = rotation.axis_angle.value();) } if (rotation.quaternion.has_value()) { - quaternion = - Collection::take_ownership(rotation.quaternion.value()); + RR_WITH_MAYBE_UNINITIALIZED_DISABLED(quaternion = rotation.quaternion.value();) } } diff --git a/rerun_py/rerun_sdk/rerun/archetypes/transform3d.py b/rerun_py/rerun_sdk/rerun/archetypes/transform3d.py index b6041e852f8c..e7b150a172cf 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/transform3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/transform3d.py @@ -26,10 +26,6 @@ class Transform3D(Transform3DExt, Archetype): E.g. if both a translation and a max3x3 transform are present, the 3x3 matrix is applied first, followed by the translation. - Each transform component can be listed multiple times, but transform tree propagation is only possible - if there's only one instance for each transform component. - TODO(#6831): write more about the exact interaction with the to be written `OutOfTreeTransform` component. - Examples -------- ### Variety of 3D transforms: @@ -159,7 +155,7 @@ def _clear(cls) -> Transform3D: default=None, converter=components.Translation3DBatch._optional, # type: ignore[misc] ) - # Translation vectors. + # Translation vector. # # (Docstring intentionally commented out to hide this field from the docs) @@ -195,7 +191,7 @@ def _clear(cls) -> Transform3D: default=None, converter=components.TransformMat3x3Batch._optional, # type: ignore[misc] ) - # 3x3 transformation matrices. + # 3x3 transformation matrix. # # (Docstring intentionally commented out to hide this field from the docs) diff --git a/rerun_py/rerun_sdk/rerun/archetypes/transform3d_ext.py b/rerun_py/rerun_sdk/rerun/archetypes/transform3d_ext.py index cd152e211b5a..7e59ca375224 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/transform3d_ext.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/transform3d_ext.py @@ -5,12 +5,12 @@ from rerun.components import Scale3D, TransformRelation, TransformRelationLike from rerun.datatypes import ( Float32Like, - Mat3x3ArrayLike, + Mat3x3Like, Quaternion, - QuaternionArrayLike, + QuaternionLike, RotationAxisAngle, - RotationAxisAngleArrayLike, - Vec3DArrayLike, + RotationAxisAngleLike, + Vec3DLike, ) from ..error_utils import catch_and_log_exceptions @@ -19,16 +19,15 @@ class Transform3DExt: """Extension for [Transform3D][rerun.archetypes.Transform3D].""" - # TODO(#6831): Most parameters should become `ArrayLike`. def __init__( self: Any, *, - translation: Vec3DArrayLike | None = None, - rotation: QuaternionArrayLike | RotationAxisAngleArrayLike | None = None, - rotation_axis_angle: RotationAxisAngleArrayLike | None = None, - quaternion: QuaternionArrayLike | None = None, - scale: Vec3DArrayLike | Float32Like | None = None, - mat3x3: Mat3x3ArrayLike | None = None, + translation: Vec3DLike | None = None, + rotation: QuaternionLike | RotationAxisAngleLike | None = None, + rotation_axis_angle: RotationAxisAngleLike | None = None, + quaternion: QuaternionLike | None = None, + scale: Vec3DLike | Float32Like | None = None, + mat3x3: Mat3x3Like | None = None, from_parent: bool | None = None, relation: TransformRelationLike | None = None, axis_length: Float32Like | None = None, diff --git a/rerun_py/tests/unit/test_transform3d.py b/rerun_py/tests/unit/test_transform3d.py index 9a066256dce2..2fcab0ab7668 100644 --- a/rerun_py/tests/unit/test_transform3d.py +++ b/rerun_py/tests/unit/test_transform3d.py @@ -93,8 +93,6 @@ def test_angle() -> None: def test_transform3d() -> None: - # TODO(#6831): Test with arrays of all fields. - rotation_axis_angle = [None, RotationAxisAngle([1, 2, 3], rr.Angle(deg=10))] quaternion_arrays = [None, Quaternion(xyzw=[1, 2, 3, 4])] scale_arrays = [None, 1.0, 1, [1.0, 2.0, 3.0]]