1use crate::{Affine2, Affine3, Affine3A, Dir2, Dir3, Mat3, Mat3A, Quat, Rot2, Vec2, Vec3, Vec3A};
4use core::ops::Mul;
5
6#[cfg(feature = "approx")]
7use approx::{AbsDiffEq, RelativeEq, UlpsEq};
8
9#[cfg(feature = "bevy_reflect")]
10use bevy_reflect::{std_traits::ReflectDefault, Reflect};
11#[cfg(all(feature = "bevy_reflect", feature = "serialize"))]
12use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
13
14#[derive(#[automatically_derived]
impl ::core::marker::Copy for Isometry2d { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Isometry2d {
#[inline]
fn clone(&self) -> Isometry2d {
let _: ::core::clone::AssertParamIsClone<Rot2>;
let _: ::core::clone::AssertParamIsClone<Vec2>;
*self
}
}Clone, #[automatically_derived]
impl ::core::default::Default for Isometry2d {
#[inline]
fn default() -> Isometry2d {
Isometry2d {
rotation: ::core::default::Default::default(),
translation: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl ::core::fmt::Debug for Isometry2d {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Isometry2d",
"rotation", &self.rotation, "translation", &&self.translation)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Isometry2d {
#[inline]
fn eq(&self, other: &Isometry2d) -> bool {
self.rotation == other.rotation &&
self.translation == other.translation
}
}PartialEq)]
87#[cfg_attr(feature = "serialize", derive(#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
{
#[allow(unused_extern_crates, clippy :: useless_attribute)]
extern crate serde as _serde;
;
#[automatically_derived]
impl _serde::Serialize for Isometry2d {
fn serialize<__S>(&self, __serializer: __S)
-> _serde::__private228::Result<__S::Ok, __S::Error> where
__S: _serde::Serializer {
let mut __serde_state =
_serde::Serializer::serialize_struct(__serializer,
"Isometry2d", false as usize + 1 + 1)?;
_serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
"rotation", &self.rotation)?;
_serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
"translation", &self.translation)?;
_serde::ser::SerializeStruct::end(__serde_state)
}
}
};serde::Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
{
#[allow(unused_extern_crates, clippy :: useless_attribute)]
extern crate serde as _serde;
;
#[automatically_derived]
impl<'de> _serde::Deserialize<'de> for Isometry2d {
fn deserialize<__D>(__deserializer: __D)
-> _serde::__private228::Result<Self, __D::Error> where
__D: _serde::Deserializer<'de> {
#[allow(non_camel_case_types)]
#[doc(hidden)]
enum __Field { __field0, __field1, __ignore, }
#[doc(hidden)]
struct __FieldVisitor;
#[automatically_derived]
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(&self,
__formatter: &mut _serde::__private228::Formatter)
-> _serde::__private228::fmt::Result {
_serde::__private228::Formatter::write_str(__formatter,
"field identifier")
}
fn visit_u64<__E>(self, __value: u64)
-> _serde::__private228::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
0u64 => _serde::__private228::Ok(__Field::__field0),
1u64 => _serde::__private228::Ok(__Field::__field1),
_ => _serde::__private228::Ok(__Field::__ignore),
}
}
fn visit_str<__E>(self, __value: &str)
-> _serde::__private228::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
"rotation" => _serde::__private228::Ok(__Field::__field0),
"translation" =>
_serde::__private228::Ok(__Field::__field1),
_ => { _serde::__private228::Ok(__Field::__ignore) }
}
}
fn visit_bytes<__E>(self, __value: &[u8])
-> _serde::__private228::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
b"rotation" => _serde::__private228::Ok(__Field::__field0),
b"translation" =>
_serde::__private228::Ok(__Field::__field1),
_ => { _serde::__private228::Ok(__Field::__ignore) }
}
}
}
#[automatically_derived]
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(__deserializer: __D)
-> _serde::__private228::Result<Self, __D::Error> where
__D: _serde::Deserializer<'de> {
_serde::Deserializer::deserialize_identifier(__deserializer,
__FieldVisitor)
}
}
#[doc(hidden)]
struct __Visitor<'de> {
marker: _serde::__private228::PhantomData<Isometry2d>,
lifetime: _serde::__private228::PhantomData<&'de ()>,
}
#[automatically_derived]
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Isometry2d;
fn expecting(&self,
__formatter: &mut _serde::__private228::Formatter)
-> _serde::__private228::fmt::Result {
_serde::__private228::Formatter::write_str(__formatter,
"struct Isometry2d")
}
#[inline]
fn visit_seq<__A>(self, mut __seq: __A)
-> _serde::__private228::Result<Self::Value, __A::Error>
where __A: _serde::de::SeqAccess<'de> {
let __field0 =
match _serde::de::SeqAccess::next_element::<Rot2>(&mut __seq)?
{
_serde::__private228::Some(__value) => __value,
_serde::__private228::None =>
return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
&"struct Isometry2d with 2 elements")),
};
let __field1 =
match _serde::de::SeqAccess::next_element::<Vec2>(&mut __seq)?
{
_serde::__private228::Some(__value) => __value,
_serde::__private228::None =>
return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
&"struct Isometry2d with 2 elements")),
};
_serde::__private228::Ok(Isometry2d {
rotation: __field0,
translation: __field1,
})
}
#[inline]
fn visit_map<__A>(self, mut __map: __A)
-> _serde::__private228::Result<Self::Value, __A::Error>
where __A: _serde::de::MapAccess<'de> {
let mut __field0: _serde::__private228::Option<Rot2> =
_serde::__private228::None;
let mut __field1: _serde::__private228::Option<Vec2> =
_serde::__private228::None;
while let _serde::__private228::Some(__key) =
_serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
match __key {
__Field::__field0 => {
if _serde::__private228::Option::is_some(&__field0) {
return _serde::__private228::Err(<__A::Error as
_serde::de::Error>::duplicate_field("rotation"));
}
__field0 =
_serde::__private228::Some(_serde::de::MapAccess::next_value::<Rot2>(&mut __map)?);
}
__Field::__field1 => {
if _serde::__private228::Option::is_some(&__field1) {
return _serde::__private228::Err(<__A::Error as
_serde::de::Error>::duplicate_field("translation"));
}
__field1 =
_serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec2>(&mut __map)?);
}
_ => {
let _ =
_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
}
}
}
let __field0 =
match __field0 {
_serde::__private228::Some(__field0) => __field0,
_serde::__private228::None =>
_serde::__private228::de::missing_field("rotation")?,
};
let __field1 =
match __field1 {
_serde::__private228::Some(__field1) => __field1,
_serde::__private228::None =>
_serde::__private228::de::missing_field("translation")?,
};
_serde::__private228::Ok(Isometry2d {
rotation: __field0,
translation: __field1,
})
}
}
#[doc(hidden)]
const FIELDS: &'static [&'static str] =
&["rotation", "translation"];
_serde::Deserializer::deserialize_struct(__deserializer,
"Isometry2d", FIELDS,
__Visitor {
marker: _serde::__private228::PhantomData::<Isometry2d>,
lifetime: _serde::__private228::PhantomData,
})
}
}
};serde::Deserialize))]
88#[cfg_attr(
89 feature = "bevy_reflect",
90 derive(const _: () =
{
impl bevy_reflect::GetTypeRegistration for Isometry2d where {
fn get_type_registration() -> bevy_reflect::TypeRegistration {
let mut registration =
bevy_reflect::TypeRegistration::of::<Self>();
registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
registration.register_type_data::<ReflectDefault, Self>();
registration.register_type_data::<ReflectSerialize, Self>();
registration.register_type_data::<ReflectDeserialize, Self>();
registration
}
#[inline(never)]
fn register_type_dependencies(registry:
&mut bevy_reflect::TypeRegistry) {
<Rot2 as
bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
<Vec2 as
bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
}
}
impl bevy_reflect::Typed for Isometry2d where {
#[inline]
fn type_info() -> &'static bevy_reflect::TypeInfo {
static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
bevy_reflect::utility::NonGenericTypeInfoCell::new();
CELL.get_or_set(||
{
bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Rot2>("rotation"),
bevy_reflect::NamedField::new::<Vec2>("translation")]))
})
}
}
#[allow(deprecated, reason =
"derives on a deprecated type shouldn't be considered a usage")]
impl bevy_reflect::TypePath for Isometry2d where {
fn type_path() -> &'static str {
"bevy_math::isometry::Isometry2d"
}
fn short_type_path() -> &'static str { "Isometry2d" }
fn type_ident() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("Isometry2d")
}
fn crate_name() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_math::isometry".split(':').next().unwrap())
}
fn module_path() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_math::isometry")
}
}
impl bevy_reflect::Reflect for Isometry2d where {
#[inline]
fn into_any(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
self
}
#[inline]
fn as_any(&self) -> &dyn ::core::any::Any { self }
#[inline]
fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
#[inline]
fn into_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
#[inline]
fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
self
}
#[inline]
fn set(&mut self,
value:
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
->
::core::result::Result<(),
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
*self = <dyn bevy_reflect::Reflect>::take(value)?;
::core::result::Result::Ok(())
}
}
impl bevy_reflect::structs::Struct for Isometry2d where {
fn field(&self, name: &str)
-> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
match name {
"rotation" => ::core::option::Option::Some(&self.rotation),
"translation" =>
::core::option::Option::Some(&self.translation),
_ => ::core::option::Option::None,
}
}
fn field_mut(&mut self, name: &str)
->
::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
match name {
"rotation" =>
::core::option::Option::Some(&mut self.rotation),
"translation" =>
::core::option::Option::Some(&mut self.translation),
_ => ::core::option::Option::None,
}
}
fn field_at(&self, index: usize)
-> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
match index {
0usize => ::core::option::Option::Some(&self.rotation),
1usize => ::core::option::Option::Some(&self.translation),
_ => ::core::option::Option::None,
}
}
fn field_at_mut(&mut self, index: usize)
->
::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
match index {
0usize => ::core::option::Option::Some(&mut self.rotation),
1usize =>
::core::option::Option::Some(&mut self.translation),
_ => ::core::option::Option::None,
}
}
fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
match index {
0usize => ::core::option::Option::Some("rotation"),
1usize => ::core::option::Option::Some("translation"),
_ => ::core::option::Option::None,
}
}
fn index_of_name(&self, name: &str)
-> ::core::option::Option<usize> {
match name {
"rotation" => ::core::option::Option::Some(0usize),
"translation" => ::core::option::Option::Some(1usize),
_ => ::core::option::Option::None,
}
}
fn field_len(&self) -> usize { 2usize }
fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
bevy_reflect::structs::FieldIter::new(self)
}
fn to_dynamic_struct(&self)
-> bevy_reflect::structs::DynamicStruct {
let mut dynamic: bevy_reflect::structs::DynamicStruct =
::core::default::Default::default();
dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
dynamic.insert_boxed("rotation",
bevy_reflect::PartialReflect::to_dynamic(&self.rotation));
dynamic.insert_boxed("translation",
bevy_reflect::PartialReflect::to_dynamic(&self.translation));
dynamic
}
}
impl bevy_reflect::PartialReflect for Isometry2d where {
#[inline]
fn get_represented_type_info(&self)
-> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
::core::option::Option::Some(<Self as
bevy_reflect::Typed>::type_info())
}
#[inline]
fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
-> ::core::result::Result<(), bevy_reflect::ApplyError> {
if let bevy_reflect::ReflectRef::Struct(struct_value) =
bevy_reflect::PartialReflect::reflect_ref(value) {
for (name, value) in
bevy_reflect::structs::Struct::iter_fields(struct_value) {
if let ::core::option::Option::Some(v) =
bevy_reflect::structs::Struct::field_mut(self, name) {
bevy_reflect::PartialReflect::try_apply(v, value)?;
}
}
} else {
return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
to_kind: bevy_reflect::ReflectKind::Struct,
});
}
::core::result::Result::Ok(())
}
#[inline]
fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
bevy_reflect::ReflectKind::Struct
}
#[inline]
fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
bevy_reflect::ReflectRef::Struct(self)
}
#[inline]
fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
bevy_reflect::ReflectMut::Struct(self)
}
#[inline]
fn reflect_owned(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
-> bevy_reflect::ReflectOwned {
bevy_reflect::ReflectOwned::Struct(self)
}
#[inline]
fn try_into_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
::core::result::Result::Ok(self)
}
#[inline]
fn try_as_reflect(&self)
-> ::core::option::Option<&dyn bevy_reflect::Reflect> {
::core::option::Option::Some(self)
}
#[inline]
fn try_as_reflect_mut(&mut self)
-> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
::core::option::Option::Some(self)
}
#[inline]
fn into_partial_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
self
}
#[inline]
fn as_partial_reflect(&self)
-> &dyn bevy_reflect::PartialReflect {
self
}
#[inline]
fn as_partial_reflect_mut(&mut self)
-> &mut dyn bevy_reflect::PartialReflect {
self
}
fn reflect_partial_eq(&self,
value: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<bool> {
let value =
<dyn bevy_reflect::PartialReflect>::try_downcast_ref::<Self>(value);
if let ::core::option::Option::Some(value) = value {
::core::option::Option::Some(::core::cmp::PartialEq::eq(self,
value))
} else { ::core::option::Option::Some(false) }
}
fn reflect_partial_cmp(&self,
value: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<::core::cmp::Ordering> {
(bevy_reflect::structs::struct_partial_cmp)(self, value)
}
fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
-> ::core::fmt::Result {
::core::fmt::Debug::fmt(self, f)
}
#[inline]
fn reflect_clone(&self)
->
::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
bevy_reflect::ReflectCloneError> {
::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
}
}
impl bevy_reflect::FromReflect for Isometry2d where {
fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<Self> {
if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
bevy_reflect::PartialReflect::reflect_ref(reflect) {
let mut __this =
<Self as ::core::default::Default>::default();
if let ::core::option::Option::Some(__field) =
(||
<Rot2 as
bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
"rotation")?))() {
__this.rotation = __field;
}
if let ::core::option::Option::Some(__field) =
(||
<Vec2 as
bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
"translation")?))() {
__this.translation = __field;
}
::core::option::Option::Some(__this)
} else { ::core::option::Option::None }
}
}
};Reflect),
91 reflect(Debug, PartialEq, Default, Clone)
92)]
93#[cfg_attr(
94 all(feature = "serialize", feature = "bevy_reflect"),
95 reflect(Serialize, Deserialize)
96)]
97pub struct Isometry2d {
98 pub rotation: Rot2,
100 pub translation: Vec2,
102}
103
104impl Isometry2d {
105 pub const IDENTITY: Self = Isometry2d {
107 rotation: Rot2::IDENTITY,
108 translation: Vec2::ZERO,
109 };
110
111 #[inline]
113 pub const fn new(translation: Vec2, rotation: Rot2) -> Self {
114 Isometry2d {
115 rotation,
116 translation,
117 }
118 }
119
120 #[inline]
122 pub const fn from_rotation(rotation: Rot2) -> Self {
123 Isometry2d {
124 rotation,
125 translation: Vec2::ZERO,
126 }
127 }
128
129 #[inline]
131 pub const fn from_translation(translation: Vec2) -> Self {
132 Isometry2d {
133 rotation: Rot2::IDENTITY,
134 translation,
135 }
136 }
137
138 #[inline]
140 pub const fn from_xy(x: f32, y: f32) -> Self {
141 Isometry2d {
142 rotation: Rot2::IDENTITY,
143 translation: Vec2::new(x, y),
144 }
145 }
146
147 #[inline]
149 pub fn inverse(&self) -> Self {
150 let inv_rot = self.rotation.inverse();
151 Isometry2d {
152 rotation: inv_rot,
153 translation: inv_rot * -self.translation,
154 }
155 }
156
157 #[inline]
162 pub fn inverse_mul(&self, rhs: Self) -> Self {
163 let inv_rot = self.rotation.inverse();
164 let delta_translation = rhs.translation - self.translation;
165 Self::new(inv_rot * delta_translation, inv_rot * rhs.rotation)
166 }
167
168 #[inline]
170 pub fn transform_point(&self, point: Vec2) -> Vec2 {
171 self.rotation * point + self.translation
172 }
173
174 #[inline]
180 pub fn inverse_transform_point(&self, point: Vec2) -> Vec2 {
181 self.rotation.inverse() * (point - self.translation)
182 }
183}
184
185impl From<Isometry2d> for Affine2 {
186 #[inline]
187 fn from(iso: Isometry2d) -> Self {
188 Affine2 {
189 matrix2: iso.rotation.into(),
190 translation: iso.translation,
191 }
192 }
193}
194
195impl From<Vec2> for Isometry2d {
196 #[inline]
197 fn from(translation: Vec2) -> Self {
198 Isometry2d::from_translation(translation)
199 }
200}
201
202impl From<Rot2> for Isometry2d {
203 #[inline]
204 fn from(rotation: Rot2) -> Self {
205 Isometry2d::from_rotation(rotation)
206 }
207}
208
209impl Mul for Isometry2d {
210 type Output = Self;
211
212 #[inline]
213 fn mul(self, rhs: Self) -> Self::Output {
214 Isometry2d {
215 rotation: self.rotation * rhs.rotation,
216 translation: self.rotation * rhs.translation + self.translation,
217 }
218 }
219}
220
221impl Mul<Vec2> for Isometry2d {
222 type Output = Vec2;
223
224 #[inline]
225 fn mul(self, rhs: Vec2) -> Self::Output {
226 self.transform_point(rhs)
227 }
228}
229
230impl Mul<Dir2> for Isometry2d {
231 type Output = Dir2;
232
233 #[inline]
234 fn mul(self, rhs: Dir2) -> Self::Output {
235 self.rotation * rhs
236 }
237}
238
239#[cfg(feature = "approx")]
240impl AbsDiffEq for Isometry2d {
241 type Epsilon = <f32 as AbsDiffEq>::Epsilon;
242
243 fn default_epsilon() -> Self::Epsilon {
244 f32::default_epsilon()
245 }
246
247 fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
248 self.rotation.abs_diff_eq(&other.rotation, epsilon)
249 && self.translation.abs_diff_eq(other.translation, epsilon)
250 }
251}
252
253#[cfg(feature = "approx")]
254impl RelativeEq for Isometry2d {
255 fn default_max_relative() -> Self::Epsilon {
256 Self::default_epsilon()
257 }
258
259 fn relative_eq(
260 &self,
261 other: &Self,
262 epsilon: Self::Epsilon,
263 max_relative: Self::Epsilon,
264 ) -> bool {
265 self.rotation
266 .relative_eq(&other.rotation, epsilon, max_relative)
267 && self
268 .translation
269 .relative_eq(&other.translation, epsilon, max_relative)
270 }
271}
272
273#[cfg(feature = "approx")]
274impl UlpsEq for Isometry2d {
275 fn default_max_ulps() -> u32 {
276 4
277 }
278
279 fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
280 self.rotation.ulps_eq(&other.rotation, epsilon, max_ulps)
281 && self
282 .translation
283 .ulps_eq(&other.translation, epsilon, max_ulps)
284 }
285}
286
287#[derive(#[automatically_derived]
impl ::core::marker::Copy for Isometry3d { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Isometry3d {
#[inline]
fn clone(&self) -> Isometry3d {
let _: ::core::clone::AssertParamIsClone<Quat>;
let _: ::core::clone::AssertParamIsClone<Vec3A>;
*self
}
}Clone, #[automatically_derived]
impl ::core::default::Default for Isometry3d {
#[inline]
fn default() -> Isometry3d {
Isometry3d {
rotation: ::core::default::Default::default(),
translation: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl ::core::fmt::Debug for Isometry3d {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Isometry3d",
"rotation", &self.rotation, "translation", &&self.translation)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Isometry3d {
#[inline]
fn eq(&self, other: &Isometry3d) -> bool {
self.rotation == other.rotation &&
self.translation == other.translation
}
}PartialEq)]
365#[cfg_attr(feature = "serialize", derive(#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
{
#[allow(unused_extern_crates, clippy :: useless_attribute)]
extern crate serde as _serde;
;
#[automatically_derived]
impl _serde::Serialize for Isometry3d {
fn serialize<__S>(&self, __serializer: __S)
-> _serde::__private228::Result<__S::Ok, __S::Error> where
__S: _serde::Serializer {
let mut __serde_state =
_serde::Serializer::serialize_struct(__serializer,
"Isometry3d", false as usize + 1 + 1)?;
_serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
"rotation", &self.rotation)?;
_serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
"translation", &self.translation)?;
_serde::ser::SerializeStruct::end(__serde_state)
}
}
};serde::Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
{
#[allow(unused_extern_crates, clippy :: useless_attribute)]
extern crate serde as _serde;
;
#[automatically_derived]
impl<'de> _serde::Deserialize<'de> for Isometry3d {
fn deserialize<__D>(__deserializer: __D)
-> _serde::__private228::Result<Self, __D::Error> where
__D: _serde::Deserializer<'de> {
#[allow(non_camel_case_types)]
#[doc(hidden)]
enum __Field { __field0, __field1, __ignore, }
#[doc(hidden)]
struct __FieldVisitor;
#[automatically_derived]
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(&self,
__formatter: &mut _serde::__private228::Formatter)
-> _serde::__private228::fmt::Result {
_serde::__private228::Formatter::write_str(__formatter,
"field identifier")
}
fn visit_u64<__E>(self, __value: u64)
-> _serde::__private228::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
0u64 => _serde::__private228::Ok(__Field::__field0),
1u64 => _serde::__private228::Ok(__Field::__field1),
_ => _serde::__private228::Ok(__Field::__ignore),
}
}
fn visit_str<__E>(self, __value: &str)
-> _serde::__private228::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
"rotation" => _serde::__private228::Ok(__Field::__field0),
"translation" =>
_serde::__private228::Ok(__Field::__field1),
_ => { _serde::__private228::Ok(__Field::__ignore) }
}
}
fn visit_bytes<__E>(self, __value: &[u8])
-> _serde::__private228::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
b"rotation" => _serde::__private228::Ok(__Field::__field0),
b"translation" =>
_serde::__private228::Ok(__Field::__field1),
_ => { _serde::__private228::Ok(__Field::__ignore) }
}
}
}
#[automatically_derived]
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(__deserializer: __D)
-> _serde::__private228::Result<Self, __D::Error> where
__D: _serde::Deserializer<'de> {
_serde::Deserializer::deserialize_identifier(__deserializer,
__FieldVisitor)
}
}
#[doc(hidden)]
struct __Visitor<'de> {
marker: _serde::__private228::PhantomData<Isometry3d>,
lifetime: _serde::__private228::PhantomData<&'de ()>,
}
#[automatically_derived]
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Isometry3d;
fn expecting(&self,
__formatter: &mut _serde::__private228::Formatter)
-> _serde::__private228::fmt::Result {
_serde::__private228::Formatter::write_str(__formatter,
"struct Isometry3d")
}
#[inline]
fn visit_seq<__A>(self, mut __seq: __A)
-> _serde::__private228::Result<Self::Value, __A::Error>
where __A: _serde::de::SeqAccess<'de> {
let __field0 =
match _serde::de::SeqAccess::next_element::<Quat>(&mut __seq)?
{
_serde::__private228::Some(__value) => __value,
_serde::__private228::None =>
return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
&"struct Isometry3d with 2 elements")),
};
let __field1 =
match _serde::de::SeqAccess::next_element::<Vec3A>(&mut __seq)?
{
_serde::__private228::Some(__value) => __value,
_serde::__private228::None =>
return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
&"struct Isometry3d with 2 elements")),
};
_serde::__private228::Ok(Isometry3d {
rotation: __field0,
translation: __field1,
})
}
#[inline]
fn visit_map<__A>(self, mut __map: __A)
-> _serde::__private228::Result<Self::Value, __A::Error>
where __A: _serde::de::MapAccess<'de> {
let mut __field0: _serde::__private228::Option<Quat> =
_serde::__private228::None;
let mut __field1: _serde::__private228::Option<Vec3A> =
_serde::__private228::None;
while let _serde::__private228::Some(__key) =
_serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
match __key {
__Field::__field0 => {
if _serde::__private228::Option::is_some(&__field0) {
return _serde::__private228::Err(<__A::Error as
_serde::de::Error>::duplicate_field("rotation"));
}
__field0 =
_serde::__private228::Some(_serde::de::MapAccess::next_value::<Quat>(&mut __map)?);
}
__Field::__field1 => {
if _serde::__private228::Option::is_some(&__field1) {
return _serde::__private228::Err(<__A::Error as
_serde::de::Error>::duplicate_field("translation"));
}
__field1 =
_serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec3A>(&mut __map)?);
}
_ => {
let _ =
_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
}
}
}
let __field0 =
match __field0 {
_serde::__private228::Some(__field0) => __field0,
_serde::__private228::None =>
_serde::__private228::de::missing_field("rotation")?,
};
let __field1 =
match __field1 {
_serde::__private228::Some(__field1) => __field1,
_serde::__private228::None =>
_serde::__private228::de::missing_field("translation")?,
};
_serde::__private228::Ok(Isometry3d {
rotation: __field0,
translation: __field1,
})
}
}
#[doc(hidden)]
const FIELDS: &'static [&'static str] =
&["rotation", "translation"];
_serde::Deserializer::deserialize_struct(__deserializer,
"Isometry3d", FIELDS,
__Visitor {
marker: _serde::__private228::PhantomData::<Isometry3d>,
lifetime: _serde::__private228::PhantomData,
})
}
}
};serde::Deserialize))]
366#[cfg_attr(
367 feature = "bevy_reflect",
368 derive(const _: () =
{
impl bevy_reflect::GetTypeRegistration for Isometry3d where {
fn get_type_registration() -> bevy_reflect::TypeRegistration {
let mut registration =
bevy_reflect::TypeRegistration::of::<Self>();
registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
registration.register_type_data::<ReflectDefault, Self>();
registration.register_type_data::<ReflectSerialize, Self>();
registration.register_type_data::<ReflectDeserialize, Self>();
registration
}
#[inline(never)]
fn register_type_dependencies(registry:
&mut bevy_reflect::TypeRegistry) {
<Quat as
bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
<Vec3A as
bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
}
}
impl bevy_reflect::Typed for Isometry3d where {
#[inline]
fn type_info() -> &'static bevy_reflect::TypeInfo {
static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
bevy_reflect::utility::NonGenericTypeInfoCell::new();
CELL.get_or_set(||
{
bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Quat>("rotation"),
bevy_reflect::NamedField::new::<Vec3A>("translation")]))
})
}
}
#[allow(deprecated, reason =
"derives on a deprecated type shouldn't be considered a usage")]
impl bevy_reflect::TypePath for Isometry3d where {
fn type_path() -> &'static str {
"bevy_math::isometry::Isometry3d"
}
fn short_type_path() -> &'static str { "Isometry3d" }
fn type_ident() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("Isometry3d")
}
fn crate_name() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_math::isometry".split(':').next().unwrap())
}
fn module_path() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_math::isometry")
}
}
impl bevy_reflect::Reflect for Isometry3d where {
#[inline]
fn into_any(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
self
}
#[inline]
fn as_any(&self) -> &dyn ::core::any::Any { self }
#[inline]
fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
#[inline]
fn into_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
#[inline]
fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
self
}
#[inline]
fn set(&mut self,
value:
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
->
::core::result::Result<(),
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
*self = <dyn bevy_reflect::Reflect>::take(value)?;
::core::result::Result::Ok(())
}
}
impl bevy_reflect::structs::Struct for Isometry3d where {
fn field(&self, name: &str)
-> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
match name {
"rotation" => ::core::option::Option::Some(&self.rotation),
"translation" =>
::core::option::Option::Some(&self.translation),
_ => ::core::option::Option::None,
}
}
fn field_mut(&mut self, name: &str)
->
::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
match name {
"rotation" =>
::core::option::Option::Some(&mut self.rotation),
"translation" =>
::core::option::Option::Some(&mut self.translation),
_ => ::core::option::Option::None,
}
}
fn field_at(&self, index: usize)
-> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
match index {
0usize => ::core::option::Option::Some(&self.rotation),
1usize => ::core::option::Option::Some(&self.translation),
_ => ::core::option::Option::None,
}
}
fn field_at_mut(&mut self, index: usize)
->
::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
match index {
0usize => ::core::option::Option::Some(&mut self.rotation),
1usize =>
::core::option::Option::Some(&mut self.translation),
_ => ::core::option::Option::None,
}
}
fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
match index {
0usize => ::core::option::Option::Some("rotation"),
1usize => ::core::option::Option::Some("translation"),
_ => ::core::option::Option::None,
}
}
fn index_of_name(&self, name: &str)
-> ::core::option::Option<usize> {
match name {
"rotation" => ::core::option::Option::Some(0usize),
"translation" => ::core::option::Option::Some(1usize),
_ => ::core::option::Option::None,
}
}
fn field_len(&self) -> usize { 2usize }
fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
bevy_reflect::structs::FieldIter::new(self)
}
fn to_dynamic_struct(&self)
-> bevy_reflect::structs::DynamicStruct {
let mut dynamic: bevy_reflect::structs::DynamicStruct =
::core::default::Default::default();
dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
dynamic.insert_boxed("rotation",
bevy_reflect::PartialReflect::to_dynamic(&self.rotation));
dynamic.insert_boxed("translation",
bevy_reflect::PartialReflect::to_dynamic(&self.translation));
dynamic
}
}
impl bevy_reflect::PartialReflect for Isometry3d where {
#[inline]
fn get_represented_type_info(&self)
-> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
::core::option::Option::Some(<Self as
bevy_reflect::Typed>::type_info())
}
#[inline]
fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
-> ::core::result::Result<(), bevy_reflect::ApplyError> {
if let bevy_reflect::ReflectRef::Struct(struct_value) =
bevy_reflect::PartialReflect::reflect_ref(value) {
for (name, value) in
bevy_reflect::structs::Struct::iter_fields(struct_value) {
if let ::core::option::Option::Some(v) =
bevy_reflect::structs::Struct::field_mut(self, name) {
bevy_reflect::PartialReflect::try_apply(v, value)?;
}
}
} else {
return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
to_kind: bevy_reflect::ReflectKind::Struct,
});
}
::core::result::Result::Ok(())
}
#[inline]
fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
bevy_reflect::ReflectKind::Struct
}
#[inline]
fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
bevy_reflect::ReflectRef::Struct(self)
}
#[inline]
fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
bevy_reflect::ReflectMut::Struct(self)
}
#[inline]
fn reflect_owned(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
-> bevy_reflect::ReflectOwned {
bevy_reflect::ReflectOwned::Struct(self)
}
#[inline]
fn try_into_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
::core::result::Result::Ok(self)
}
#[inline]
fn try_as_reflect(&self)
-> ::core::option::Option<&dyn bevy_reflect::Reflect> {
::core::option::Option::Some(self)
}
#[inline]
fn try_as_reflect_mut(&mut self)
-> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
::core::option::Option::Some(self)
}
#[inline]
fn into_partial_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
self
}
#[inline]
fn as_partial_reflect(&self)
-> &dyn bevy_reflect::PartialReflect {
self
}
#[inline]
fn as_partial_reflect_mut(&mut self)
-> &mut dyn bevy_reflect::PartialReflect {
self
}
fn reflect_partial_eq(&self,
value: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<bool> {
let value =
<dyn bevy_reflect::PartialReflect>::try_downcast_ref::<Self>(value);
if let ::core::option::Option::Some(value) = value {
::core::option::Option::Some(::core::cmp::PartialEq::eq(self,
value))
} else { ::core::option::Option::Some(false) }
}
fn reflect_partial_cmp(&self,
value: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<::core::cmp::Ordering> {
(bevy_reflect::structs::struct_partial_cmp)(self, value)
}
fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
-> ::core::fmt::Result {
::core::fmt::Debug::fmt(self, f)
}
#[inline]
fn reflect_clone(&self)
->
::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
bevy_reflect::ReflectCloneError> {
::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
}
}
impl bevy_reflect::FromReflect for Isometry3d where {
fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<Self> {
if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
bevy_reflect::PartialReflect::reflect_ref(reflect) {
let mut __this =
<Self as ::core::default::Default>::default();
if let ::core::option::Option::Some(__field) =
(||
<Quat as
bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
"rotation")?))() {
__this.rotation = __field;
}
if let ::core::option::Option::Some(__field) =
(||
<Vec3A as
bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
"translation")?))() {
__this.translation = __field;
}
::core::option::Option::Some(__this)
} else { ::core::option::Option::None }
}
}
};Reflect),
369 reflect(Debug, PartialEq, Default, Clone)
370)]
371#[cfg_attr(
372 all(feature = "serialize", feature = "bevy_reflect"),
373 reflect(Serialize, Deserialize)
374)]
375pub struct Isometry3d {
376 pub rotation: Quat,
378 pub translation: Vec3A,
380}
381
382impl Isometry3d {
383 pub const IDENTITY: Self = Isometry3d {
385 rotation: Quat::IDENTITY,
386 translation: Vec3A::ZERO,
387 };
388
389 #[inline]
391 pub fn new(translation: impl Into<Vec3A>, rotation: Quat) -> Self {
392 Isometry3d {
393 rotation,
394 translation: translation.into(),
395 }
396 }
397
398 #[inline]
400 pub const fn from_rotation(rotation: Quat) -> Self {
401 Isometry3d {
402 rotation,
403 translation: Vec3A::ZERO,
404 }
405 }
406
407 #[inline]
409 pub fn from_translation(translation: impl Into<Vec3A>) -> Self {
410 Isometry3d {
411 rotation: Quat::IDENTITY,
412 translation: translation.into(),
413 }
414 }
415
416 #[inline]
418 pub const fn from_xyz(x: f32, y: f32, z: f32) -> Self {
419 Isometry3d {
420 rotation: Quat::IDENTITY,
421 translation: Vec3A::new(x, y, z),
422 }
423 }
424
425 #[inline]
427 pub fn inverse(&self) -> Self {
428 let inv_rot = self.rotation.inverse();
429 Isometry3d {
430 rotation: inv_rot,
431 translation: inv_rot * -self.translation,
432 }
433 }
434
435 #[inline]
440 pub fn inverse_mul(&self, rhs: Self) -> Self {
441 let inv_rot = self.rotation.inverse();
442 let delta_translation = rhs.translation - self.translation;
443 Self::new(inv_rot * delta_translation, inv_rot * rhs.rotation)
444 }
445
446 #[inline]
448 pub fn transform_point(&self, point: impl Into<Vec3A>) -> Vec3A {
449 self.rotation * point.into() + self.translation
450 }
451
452 #[inline]
458 pub fn inverse_transform_point(&self, point: impl Into<Vec3A>) -> Vec3A {
459 self.rotation.inverse() * (point.into() - self.translation)
460 }
461}
462
463impl From<Isometry3d> for Affine3 {
464 #[inline]
465 fn from(iso: Isometry3d) -> Self {
466 Affine3 {
467 matrix3: Mat3::from_quat(iso.rotation),
468 translation: iso.translation.into(),
469 }
470 }
471}
472
473impl From<Isometry3d> for Affine3A {
474 #[inline]
475 fn from(iso: Isometry3d) -> Self {
476 Affine3A {
477 matrix3: Mat3A::from_quat(iso.rotation),
478 translation: iso.translation,
479 }
480 }
481}
482
483impl From<Vec3> for Isometry3d {
484 #[inline]
485 fn from(translation: Vec3) -> Self {
486 Isometry3d::from_translation(translation)
487 }
488}
489
490impl From<Vec3A> for Isometry3d {
491 #[inline]
492 fn from(translation: Vec3A) -> Self {
493 Isometry3d::from_translation(translation)
494 }
495}
496
497impl From<Quat> for Isometry3d {
498 #[inline]
499 fn from(rotation: Quat) -> Self {
500 Isometry3d::from_rotation(rotation)
501 }
502}
503
504impl Mul for Isometry3d {
505 type Output = Self;
506
507 #[inline]
508 fn mul(self, rhs: Self) -> Self::Output {
509 Isometry3d {
510 rotation: self.rotation * rhs.rotation,
511 translation: self.rotation * rhs.translation + self.translation,
512 }
513 }
514}
515
516impl Mul<Vec3A> for Isometry3d {
517 type Output = Vec3A;
518
519 #[inline]
520 fn mul(self, rhs: Vec3A) -> Self::Output {
521 self.transform_point(rhs)
522 }
523}
524
525impl Mul<Vec3> for Isometry3d {
526 type Output = Vec3;
527
528 #[inline]
529 fn mul(self, rhs: Vec3) -> Self::Output {
530 self.transform_point(rhs).into()
531 }
532}
533
534impl Mul<Dir3> for Isometry3d {
535 type Output = Dir3;
536
537 #[inline]
538 fn mul(self, rhs: Dir3) -> Self::Output {
539 self.rotation * rhs
540 }
541}
542
543#[cfg(feature = "approx")]
544impl AbsDiffEq for Isometry3d {
545 type Epsilon = <f32 as AbsDiffEq>::Epsilon;
546
547 fn default_epsilon() -> Self::Epsilon {
548 f32::default_epsilon()
549 }
550
551 fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
552 self.rotation.abs_diff_eq(other.rotation, epsilon)
553 && self.translation.abs_diff_eq(other.translation, epsilon)
554 }
555}
556
557#[cfg(feature = "approx")]
558impl RelativeEq for Isometry3d {
559 fn default_max_relative() -> Self::Epsilon {
560 Self::default_epsilon()
561 }
562
563 fn relative_eq(
564 &self,
565 other: &Self,
566 epsilon: Self::Epsilon,
567 max_relative: Self::Epsilon,
568 ) -> bool {
569 self.rotation
570 .relative_eq(&other.rotation, epsilon, max_relative)
571 && self
572 .translation
573 .relative_eq(&other.translation, epsilon, max_relative)
574 }
575}
576
577#[cfg(feature = "approx")]
578impl UlpsEq for Isometry3d {
579 fn default_max_ulps() -> u32 {
580 4
581 }
582
583 fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
584 self.rotation.ulps_eq(&other.rotation, epsilon, max_ulps)
585 && self
586 .translation
587 .ulps_eq(&other.translation, epsilon, max_ulps)
588 }
589}
590
591#[cfg(test)]
592#[cfg(feature = "approx")]
593mod tests {
594 use super::*;
595 use crate::{vec2, vec3, vec3a};
596 use approx::assert_abs_diff_eq;
597 use core::f32::consts::{FRAC_PI_2, FRAC_PI_3};
598
599 #[test]
600 fn mul_2d() {
601 let iso1 = Isometry2d::new(vec2(1.0, 0.0), Rot2::FRAC_PI_2);
602 let iso2 = Isometry2d::new(vec2(0.0, 1.0), Rot2::FRAC_PI_2);
603 let expected = Isometry2d::new(vec2(0.0, 0.0), Rot2::PI);
604 assert_abs_diff_eq!(iso1 * iso2, expected);
605 }
606
607 #[test]
608 fn inverse_mul_2d() {
609 let iso1 = Isometry2d::new(vec2(1.0, 0.0), Rot2::FRAC_PI_2);
610 let iso2 = Isometry2d::new(vec2(0.0, 0.0), Rot2::PI);
611 let expected = Isometry2d::new(vec2(0.0, 1.0), Rot2::FRAC_PI_2);
612 assert_abs_diff_eq!(iso1.inverse_mul(iso2), expected);
613 }
614
615 #[test]
616 fn mul_3d() {
617 let iso1 = Isometry3d::new(vec3(1.0, 0.0, 0.0), Quat::from_rotation_x(FRAC_PI_2));
618 let iso2 = Isometry3d::new(vec3(0.0, 1.0, 0.0), Quat::IDENTITY);
619 let expected = Isometry3d::new(vec3(1.0, 0.0, 1.0), Quat::from_rotation_x(FRAC_PI_2));
620 assert_abs_diff_eq!(iso1 * iso2, expected);
621 }
622
623 #[test]
624 fn inverse_mul_3d() {
625 let iso1 = Isometry3d::new(vec3(1.0, 0.0, 0.0), Quat::from_rotation_x(FRAC_PI_2));
626 let iso2 = Isometry3d::new(vec3(1.0, 0.0, 1.0), Quat::from_rotation_x(FRAC_PI_2));
627 let expected = Isometry3d::new(vec3(0.0, 1.0, 0.0), Quat::IDENTITY);
628 assert_abs_diff_eq!(iso1.inverse_mul(iso2), expected);
629 }
630
631 #[test]
632 fn identity_2d() {
633 let iso = Isometry2d::new(vec2(-1.0, -0.5), Rot2::degrees(75.0));
634 assert_abs_diff_eq!(Isometry2d::IDENTITY * iso, iso);
635 assert_abs_diff_eq!(iso * Isometry2d::IDENTITY, iso);
636 }
637
638 #[test]
639 fn identity_3d() {
640 let iso = Isometry3d::new(vec3(-1.0, 2.5, 3.3), Quat::from_rotation_z(FRAC_PI_3));
641 assert_abs_diff_eq!(Isometry3d::IDENTITY * iso, iso);
642 assert_abs_diff_eq!(iso * Isometry3d::IDENTITY, iso);
643 }
644
645 #[test]
646 fn inverse_2d() {
647 let iso = Isometry2d::new(vec2(-1.0, -0.5), Rot2::degrees(75.0));
648 let inv = iso.inverse();
649 assert_abs_diff_eq!(iso * inv, Isometry2d::IDENTITY);
650 assert_abs_diff_eq!(inv * iso, Isometry2d::IDENTITY);
651 }
652
653 #[test]
654 fn inverse_3d() {
655 let iso = Isometry3d::new(vec3(-1.0, 2.5, 3.3), Quat::from_rotation_z(FRAC_PI_3));
656 let inv = iso.inverse();
657 assert_abs_diff_eq!(iso * inv, Isometry3d::IDENTITY);
658 assert_abs_diff_eq!(inv * iso, Isometry3d::IDENTITY);
659 }
660
661 #[test]
662 fn transform_2d() {
663 let iso = Isometry2d::new(vec2(0.5, -0.5), Rot2::FRAC_PI_2);
664 let point = vec2(1.0, 1.0);
665 assert_abs_diff_eq!(vec2(-0.5, 0.5), iso * point);
666 }
667
668 #[test]
669 fn inverse_transform_2d() {
670 let iso = Isometry2d::new(vec2(0.5, -0.5), Rot2::FRAC_PI_2);
671 let point = vec2(-0.5, 0.5);
672 assert_abs_diff_eq!(vec2(1.0, 1.0), iso.inverse_transform_point(point));
673 }
674
675 #[test]
676 fn transform_3d() {
677 let iso = Isometry3d::new(vec3(1.0, 0.0, 0.0), Quat::from_rotation_y(FRAC_PI_2));
678 let point = vec3(1.0, 1.0, 1.0);
679 assert_abs_diff_eq!(vec3(2.0, 1.0, -1.0), iso * point);
680 }
681
682 #[test]
683 fn inverse_transform_3d() {
684 let iso = Isometry3d::new(vec3(1.0, 0.0, 0.0), Quat::from_rotation_y(FRAC_PI_2));
685 let point = vec3(2.0, 1.0, -1.0);
686 assert_abs_diff_eq!(vec3a(1.0, 1.0, 1.0), iso.inverse_transform_point(point));
687 }
688}