Skip to content

Commit

Permalink
Fix handling unnormalized axis for (Pose)RotationAxisAngle (#8341)
Browse files Browse the repository at this point in the history
As well as dodging associated debug-assertions for
* unnormalized/zero axis for rotation axis angle
* non-invertible transforms (which may be the case for all sort of
reasons)
  • Loading branch information
Wumpf authored Dec 6, 2024
1 parent 003b00c commit f8bd31d
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ impl PoseRotationAxisAngle {
impl From<PoseRotationAxisAngle> for glam::Affine3A {
#[inline]
fn from(val: PoseRotationAxisAngle) -> Self {
Self::from_axis_angle(val.0.axis.into(), val.0.angle.radians())
if let Some(normalized) = glam::Vec3::from(val.0.axis).try_normalize() {
Self::from_axis_angle(normalized, val.0.angle.radians())
} else {
// If the axis is zero length, we can't normalize it, so we just use the identity rotation.
Self::IDENTITY
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ impl RotationAxisAngle {
impl From<RotationAxisAngle> for glam::Affine3A {
#[inline]
fn from(val: RotationAxisAngle) -> Self {
Self::from_axis_angle(val.0.axis.into(), val.0.angle.radians())
if let Some(normalized) = glam::Vec3::from(val.0.axis).try_normalize() {
Self::from_axis_angle(normalized, val.0.angle.radians())
} else {
// If the axis is zero length, we can't normalize it, so we just use the identity rotation.
Self::IDENTITY
}
}
}
9 changes: 8 additions & 1 deletion crates/viewer/re_renderer/src/renderer/mesh_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,15 @@ impl MeshDrawData {
count_with_outlines += instance.outline_mask_ids.is_some() as u32;

let world_from_mesh_mat3 = instance.world_from_mesh.matrix3;
// If the matrix is not invertible the draw result is likely invalid as well.
// However, at this point it's really hard to bail out!
// Also, by skipping drawing here, we'd make the result worse as there would be no mesh draw calls that could be debugged.
let world_from_mesh_normal =
instance.world_from_mesh.matrix3.inverse().transpose();
if instance.world_from_mesh.matrix3.determinant() != 0.0 {
instance.world_from_mesh.matrix3.inverse().transpose()
} else {
glam::Mat3A::ZERO
};
instance_buffer_staging.push(gpu_data::InstanceData {
world_from_mesh_row_0: world_from_mesh_mat3
.row(0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -555,8 +555,14 @@ fn query_and_resolve_tree_transform_at_entity(
if let Some(mat3x3) = result.component_instance::<TransformMat3x3>(0) {
transform *= glam::Affine3A::from(mat3x3);
}

if result.component_instance::<TransformRelation>(0) == Some(TransformRelation::ChildFromParent)
{
if transform.matrix3.determinant() != 0.0 {
// TODO(andreas): Should we warn? This might be intentionally caused by zero scale.
transform = transform.inverse();
}

transform = transform.inverse();
}

Expand Down

0 comments on commit f8bd31d

Please sign in to comment.